summaryrefslogtreecommitdiff
path: root/sys/src/cmd/python/Modules
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-05-03 11:25:13 +0000
committercinap_lenrek <cinap_lenrek@localhost>2011-05-03 11:25:13 +0000
commit458120dd40db6b4df55a4e96b650e16798ef06a0 (patch)
tree8f82685be24fef97e715c6f5ca4c68d34d5074ee /sys/src/cmd/python/Modules
parent3a742c699f6806c1145aea5149bf15de15a0afd7 (diff)
add hg and python
Diffstat (limited to 'sys/src/cmd/python/Modules')
-rw-r--r--sys/src/cmd/python/Modules/Setup488
-rw-r--r--sys/src/cmd/python/Modules/Setup.config13
-rw-r--r--sys/src/cmd/python/Modules/Setup.config.in13
-rw-r--r--sys/src/cmd/python/Modules/Setup.dist487
-rw-r--r--sys/src/cmd/python/Modules/Setup.local1
-rw-r--r--sys/src/cmd/python/Modules/_bisectmodule.c235
-rw-r--r--sys/src/cmd/python/Modules/_bsddb.c6047
-rw-r--r--sys/src/cmd/python/Modules/_codecsmodule.c934
-rw-r--r--sys/src/cmd/python/Modules/_csv.c1604
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/_ctypes.c4859
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/_ctypes_test.c548
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/_ctypes_test.h1
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/callbacks.c499
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/callproc.c1581
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/cfield.c1668
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/ctypes.h407
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/ctypes_dlfcn.h31
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/darwin/LICENSE31
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/darwin/README95
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes11
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h84
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn_simple.c272
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/LICENSE20
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/README500
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/aclocal.m492
-rwxr-xr-xsys/src/cmd/python/Modules/_ctypes/libffi/config.guess1453
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/config.sub1569
-rwxr-xr-xsys/src/cmd/python/Modules/_ctypes/libffi/configure6864
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/configure.ac243
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.h.in148
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.py.in45
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi.h.in313
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi_common.h95
-rwxr-xr-xsys/src/cmd/python/Modules/_ctypes/libffi/install-sh294
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffi.c252
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffitarget.h48
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/osf.S359
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffi.c185
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffitarget.h47
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/sysv.S209
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffi.c381
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffitarget.h50
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/sysv.S215
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/darwin/ffitarget.h25
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/eabi.S130
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffi.c287
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffitarget.h60
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffi.c562
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffitarget.h49
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ia64_flags.h39
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/unix.S555
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffi.c247
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffitarget.h48
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/sysv.S121
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffi.c176
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffitarget.h47
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/sysv.S97
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffi.c648
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffitarget.h167
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/n32.S320
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/o32.S377
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffi.c625
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffitarget.h59
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/linux.S307
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix.S225
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix_closure.S247
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/asm.h125
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin.S247
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S319
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi.c1249
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c771
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffitarget.h100
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64.S180
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S206
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S323
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/sysv.S217
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/prep_cif.c210
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffi.c751
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffitarget.h59
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/sysv.S429
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffi.c728
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffitarget.h48
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/sysv.S845
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffi.c451
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffitarget.h52
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/sysv.S525
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffi.c608
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffitarget.h65
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v8.S267
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v9.S302
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/darwin.S243
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi.c469
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi64.c569
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi_darwin.c594
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffitarget.h81
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/sysv.S382
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/unix64.S412
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/win32.S373
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/debug.c59
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.c310
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.h317
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi_common.h111
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/fficonfig.h152
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffitarget.h49
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/prep_cif.c175
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/sysv.asm228
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/LICENSE20
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README500
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README.ctypes7
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.c394
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.h317
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi_common.h77
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/fficonfig.h96
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffitarget.h79
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/prep_cif.c175
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/types.c104
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.S243
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.c267
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/malloc_closure.c110
-rw-r--r--sys/src/cmd/python/Modules/_ctypes/stgdict.c494
-rw-r--r--sys/src/cmd/python/Modules/_curses_panel.c480
-rw-r--r--sys/src/cmd/python/Modules/_cursesmodule.c2760
-rw-r--r--sys/src/cmd/python/Modules/_elementtree.c2815
-rw-r--r--sys/src/cmd/python/Modules/_functoolsmodule.c277
-rw-r--r--sys/src/cmd/python/Modules/_hashopenssl.c487
-rw-r--r--sys/src/cmd/python/Modules/_heapqmodule.c619
-rw-r--r--sys/src/cmd/python/Modules/_hotshot.c1647
-rw-r--r--sys/src/cmd/python/Modules/_localemodule.c788
-rw-r--r--sys/src/cmd/python/Modules/_lsprof.c875
-rw-r--r--sys/src/cmd/python/Modules/_randommodule.c580
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/cache.c375
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/cache.h73
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/connection.c1255
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/connection.h129
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/cursor.c1057
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/cursor.h71
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/microprotocols.c142
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/microprotocols.h59
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/module.c409
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/module.h57
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c84
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h41
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/row.c202
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/row.h39
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h34
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/statement.c432
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/statement.h59
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/util.c96
-rw-r--r--sys/src/cmd/python/Modules/_sqlite/util.h38
-rw-r--r--sys/src/cmd/python/Modules/_sre.c3429
-rw-r--r--sys/src/cmd/python/Modules/_ssl.c726
-rw-r--r--sys/src/cmd/python/Modules/_struct.c1896
-rw-r--r--sys/src/cmd/python/Modules/_testcapimodule.c898
-rw-r--r--sys/src/cmd/python/Modules/_tkinter.c3165
-rw-r--r--sys/src/cmd/python/Modules/_typesmodule.c94
-rw-r--r--sys/src/cmd/python/Modules/_weakref.c112
-rw-r--r--sys/src/cmd/python/Modules/addrinfo.h176
-rw-r--r--sys/src/cmd/python/Modules/almodule.c3226
-rwxr-xr-xsys/src/cmd/python/Modules/ar_beos73
-rw-r--r--sys/src/cmd/python/Modules/arraymodule.c2141
-rw-r--r--sys/src/cmd/python/Modules/audioop.c1612
-rw-r--r--sys/src/cmd/python/Modules/binascii.c1350
-rw-r--r--sys/src/cmd/python/Modules/bsddbmodule.c858
-rw-r--r--sys/src/cmd/python/Modules/bz2module.c2230
-rw-r--r--sys/src/cmd/python/Modules/cPickle.c5757
-rw-r--r--sys/src/cmd/python/Modules/cStringIO.c745
-rw-r--r--sys/src/cmd/python/Modules/cdmodule.c796
-rw-r--r--sys/src/cmd/python/Modules/cgen.py520
-rw-r--r--sys/src/cmd/python/Modules/cgensupport.c310
-rw-r--r--sys/src/cmd/python/Modules/cgensupport.h64
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/README79
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/_codecs_cn.c443
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/_codecs_hk.c143
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/_codecs_iso2022.c1131
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/_codecs_jp.c731
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/_codecs_kr.c355
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/_codecs_tw.c132
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/alg_jisx0201.h24
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/cjkcodecs.h398
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/emu_jisx0213_2000.h43
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/mappings_cn.h4103
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/mappings_hk.h2340
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/mappings_jisx0213_pair.h59
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/mappings_jp.h4765
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/mappings_kr.h3251
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/mappings_tw.h2633
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.c1793
-rw-r--r--sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.h138
-rw-r--r--sys/src/cmd/python/Modules/clmodule.c2559
-rw-r--r--sys/src/cmd/python/Modules/cmathmodule.c426
-rw-r--r--sys/src/cmd/python/Modules/collectionsmodule.c1370
-rw-r--r--sys/src/cmd/python/Modules/config54
-rw-r--r--sys/src/cmd/python/Modules/config.c.in66
-rw-r--r--sys/src/cmd/python/Modules/cryptmodule.c49
-rw-r--r--sys/src/cmd/python/Modules/cstubs1364
-rw-r--r--sys/src/cmd/python/Modules/datetimemodule.c4988
-rw-r--r--sys/src/cmd/python/Modules/dbmmodule.c370
-rw-r--r--sys/src/cmd/python/Modules/dlmodule.c278
-rw-r--r--sys/src/cmd/python/Modules/errnomodule.c788
-rw-r--r--sys/src/cmd/python/Modules/expat/amigaconfig.h96
-rw-r--r--sys/src/cmd/python/Modules/expat/ascii.h85
-rw-r--r--sys/src/cmd/python/Modules/expat/asciitab.h36
-rw-r--r--sys/src/cmd/python/Modules/expat/expat.h1013
-rw-r--r--sys/src/cmd/python/Modules/expat/expat_config.h19
-rw-r--r--sys/src/cmd/python/Modules/expat/expat_external.h119
-rw-r--r--sys/src/cmd/python/Modules/expat/iasciitab.h37
-rw-r--r--sys/src/cmd/python/Modules/expat/internal.h73
-rw-r--r--sys/src/cmd/python/Modules/expat/latin1tab.h36
-rw-r--r--sys/src/cmd/python/Modules/expat/macconfig.h53
-rw-r--r--sys/src/cmd/python/Modules/expat/nametab.h150
-rw-r--r--sys/src/cmd/python/Modules/expat/pyexpatns.h124
-rw-r--r--sys/src/cmd/python/Modules/expat/utf8tab.h37
-rw-r--r--sys/src/cmd/python/Modules/expat/winconfig.h30
-rw-r--r--sys/src/cmd/python/Modules/expat/xmlparse.c6268
-rw-r--r--sys/src/cmd/python/Modules/expat/xmlrole.c1330
-rw-r--r--sys/src/cmd/python/Modules/expat/xmlrole.h114
-rw-r--r--sys/src/cmd/python/Modules/expat/xmltok.c1639
-rw-r--r--sys/src/cmd/python/Modules/expat/xmltok.h316
-rw-r--r--sys/src/cmd/python/Modules/expat/xmltok_impl.c1779
-rw-r--r--sys/src/cmd/python/Modules/expat/xmltok_impl.h46
-rw-r--r--sys/src/cmd/python/Modules/expat/xmltok_ns.c106
-rw-r--r--sys/src/cmd/python/Modules/fcntlmodule.c607
-rw-r--r--sys/src/cmd/python/Modules/flmodule.c2139
-rw-r--r--sys/src/cmd/python/Modules/fmmodule.c264
-rw-r--r--sys/src/cmd/python/Modules/fpectlmodule.c303
-rw-r--r--sys/src/cmd/python/Modules/fpetestmodule.c186
-rw-r--r--sys/src/cmd/python/Modules/gc_weakref.txt219
-rw-r--r--sys/src/cmd/python/Modules/gcmodule.c1390
-rw-r--r--sys/src/cmd/python/Modules/gdbmmodule.c515
-rw-r--r--sys/src/cmd/python/Modules/getaddrinfo.c638
-rw-r--r--sys/src/cmd/python/Modules/getbuildinfo.c48
-rw-r--r--sys/src/cmd/python/Modules/getnameinfo.c214
-rw-r--r--sys/src/cmd/python/Modules/getpath.c694
-rw-r--r--sys/src/cmd/python/Modules/glmodule.c7628
-rw-r--r--sys/src/cmd/python/Modules/grpmodule.c194
-rw-r--r--sys/src/cmd/python/Modules/imageop.c785
-rw-r--r--sys/src/cmd/python/Modules/imgfile.c504
-rw-r--r--sys/src/cmd/python/Modules/itertoolsmodule.c2550
-rwxr-xr-xsys/src/cmd/python/Modules/ld_so_aix187
-rwxr-xr-xsys/src/cmd/python/Modules/ld_so_beos78
-rw-r--r--sys/src/cmd/python/Modules/linuxaudiodev.c502
-rw-r--r--sys/src/cmd/python/Modules/main.c584
-rwxr-xr-xsys/src/cmd/python/Modules/makesetup297
-rwxr-xr-xsys/src/cmd/python/Modules/makexp_aix81
-rw-r--r--sys/src/cmd/python/Modules/mathmodule.c376
-rw-r--r--sys/src/cmd/python/Modules/md5.c381
-rw-r--r--sys/src/cmd/python/Modules/md5.h91
-rw-r--r--sys/src/cmd/python/Modules/md5module.c312
-rw-r--r--sys/src/cmd/python/Modules/mkfile135
-rw-r--r--sys/src/cmd/python/Modules/mmapmodule.c1186
-rw-r--r--sys/src/cmd/python/Modules/nismodule.c444
-rw-r--r--sys/src/cmd/python/Modules/operator.c602
-rw-r--r--sys/src/cmd/python/Modules/ossaudiodev.c1138
-rw-r--r--sys/src/cmd/python/Modules/parsermodule.c3279
-rw-r--r--sys/src/cmd/python/Modules/posixmodule.c8752
-rw-r--r--sys/src/cmd/python/Modules/puremodule.c988
-rw-r--r--sys/src/cmd/python/Modules/pwdmodule.c198
-rw-r--r--sys/src/cmd/python/Modules/pyexpat.c2149
-rw-r--r--sys/src/cmd/python/Modules/python.c24
-rw-r--r--sys/src/cmd/python/Modules/readline.c941
-rw-r--r--sys/src/cmd/python/Modules/resource.c325
-rw-r--r--sys/src/cmd/python/Modules/rgbimgmodule.c780
-rw-r--r--sys/src/cmd/python/Modules/rotatingtree.c121
-rw-r--r--sys/src/cmd/python/Modules/rotatingtree.h27
-rw-r--r--sys/src/cmd/python/Modules/selectmodule.c734
-rw-r--r--sys/src/cmd/python/Modules/sgimodule.c55
-rw-r--r--sys/src/cmd/python/Modules/sha256module.c701
-rw-r--r--sys/src/cmd/python/Modules/sha512module.c769
-rw-r--r--sys/src/cmd/python/Modules/shamodule.c593
-rw-r--r--sys/src/cmd/python/Modules/signalmodule.c676
-rw-r--r--sys/src/cmd/python/Modules/socketmodule.c5100
-rw-r--r--sys/src/cmd/python/Modules/socketmodule.h252
-rw-r--r--sys/src/cmd/python/Modules/spwdmodule.c183
-rw-r--r--sys/src/cmd/python/Modules/sre.h94
-rw-r--r--sys/src/cmd/python/Modules/sre_constants.h86
-rw-r--r--sys/src/cmd/python/Modules/stropmodule.c1248
-rw-r--r--sys/src/cmd/python/Modules/sunaudiodev.c465
-rw-r--r--sys/src/cmd/python/Modules/svmodule.c966
-rw-r--r--sys/src/cmd/python/Modules/symtablemodule.c84
-rw-r--r--sys/src/cmd/python/Modules/syslogmodule.c223
-rw-r--r--sys/src/cmd/python/Modules/termios.c926
-rw-r--r--sys/src/cmd/python/Modules/testcapi_long.h166
-rw-r--r--sys/src/cmd/python/Modules/threadmodule.c720
-rw-r--r--sys/src/cmd/python/Modules/timemodule.c1030
-rw-r--r--sys/src/cmd/python/Modules/timing.h67
-rw-r--r--sys/src/cmd/python/Modules/timingmodule.c58
-rw-r--r--sys/src/cmd/python/Modules/tkappinit.c149
-rw-r--r--sys/src/cmd/python/Modules/unicodedata.c1223
-rw-r--r--sys/src/cmd/python/Modules/unicodedata_db.h5135
-rw-r--r--sys/src/cmd/python/Modules/unicodename_db.h12543
-rw-r--r--sys/src/cmd/python/Modules/xxmodule.c376
-rw-r--r--sys/src/cmd/python/Modules/xxsubtype.c299
-rw-r--r--sys/src/cmd/python/Modules/yuv.h99
-rw-r--r--sys/src/cmd/python/Modules/yuvconvert.c118
-rw-r--r--sys/src/cmd/python/Modules/zipimport.c1191
-rw-r--r--sys/src/cmd/python/Modules/zlib/ChangeLog855
-rw-r--r--sys/src/cmd/python/Modules/zlib/FAQ339
-rw-r--r--sys/src/cmd/python/Modules/zlib/INDEX51
-rw-r--r--sys/src/cmd/python/Modules/zlib/Makefile154
-rw-r--r--sys/src/cmd/python/Modules/zlib/Makefile.in154
-rw-r--r--sys/src/cmd/python/Modules/zlib/README125
-rw-r--r--sys/src/cmd/python/Modules/zlib/adler32.c149
-rw-r--r--sys/src/cmd/python/Modules/zlib/algorithm.txt209
-rw-r--r--sys/src/cmd/python/Modules/zlib/compress.c79
-rwxr-xr-xsys/src/cmd/python/Modules/zlib/configure459
-rw-r--r--sys/src/cmd/python/Modules/zlib/crc32.c423
-rw-r--r--sys/src/cmd/python/Modules/zlib/crc32.h441
-rw-r--r--sys/src/cmd/python/Modules/zlib/deflate.c1736
-rw-r--r--sys/src/cmd/python/Modules/zlib/deflate.h331
-rw-r--r--sys/src/cmd/python/Modules/zlib/example.c565
-rw-r--r--sys/src/cmd/python/Modules/zlib/gzio.c1026
-rw-r--r--sys/src/cmd/python/Modules/zlib/infback.c623
-rw-r--r--sys/src/cmd/python/Modules/zlib/inffast.c318
-rw-r--r--sys/src/cmd/python/Modules/zlib/inffast.h11
-rw-r--r--sys/src/cmd/python/Modules/zlib/inffixed.h94
-rw-r--r--sys/src/cmd/python/Modules/zlib/inflate.c1368
-rw-r--r--sys/src/cmd/python/Modules/zlib/inflate.h115
-rw-r--r--sys/src/cmd/python/Modules/zlib/inftrees.c329
-rw-r--r--sys/src/cmd/python/Modules/zlib/inftrees.h55
-rw-r--r--sys/src/cmd/python/Modules/zlib/make_vms.com461
-rw-r--r--sys/src/cmd/python/Modules/zlib/minigzip.c322
-rw-r--r--sys/src/cmd/python/Modules/zlib/trees.c1219
-rw-r--r--sys/src/cmd/python/Modules/zlib/trees.h128
-rw-r--r--sys/src/cmd/python/Modules/zlib/uncompr.c61
-rw-r--r--sys/src/cmd/python/Modules/zlib/zconf.h332
-rw-r--r--sys/src/cmd/python/Modules/zlib/zconf.in.h332
-rw-r--r--sys/src/cmd/python/Modules/zlib/zlib.3159
-rw-r--r--sys/src/cmd/python/Modules/zlib/zlib.h1357
-rw-r--r--sys/src/cmd/python/Modules/zlib/zutil.c318
-rw-r--r--sys/src/cmd/python/Modules/zlib/zutil.h269
-rw-r--r--sys/src/cmd/python/Modules/zlibmodule.c1027
331 files changed, 244909 insertions, 0 deletions
diff --git a/sys/src/cmd/python/Modules/Setup b/sys/src/cmd/python/Modules/Setup
new file mode 100644
index 000000000..93aac7057
--- /dev/null
+++ b/sys/src/cmd/python/Modules/Setup
@@ -0,0 +1,488 @@
+# -*- makefile -*-
+# The file Setup is used by the makesetup script to construct the files
+# Makefile and config.c, from Makefile.pre and config.c.in,
+# respectively. The file Setup itself is initially copied from
+# Setup.dist; once it exists it will not be overwritten, so you can edit
+# Setup to your heart's content. Note that Makefile.pre is created
+# from Makefile.pre.in by the toplevel configure script.
+
+# (VPATH notes: Setup and Makefile.pre are in the build directory, as
+# are Makefile and config.c; the *.in and *.dist files are in the source
+# directory.)
+
+# Each line in this file describes one or more optional modules.
+# Modules enabled here will not be compiled by the setup.py script,
+# so the file can be used to override setup.py's behavior.
+
+# Lines have the following structure:
+#
+# <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
+#
+# <sourcefile> is anything ending in .c (.C, .cc, .c++ are C++ files)
+# <cpparg> is anything starting with -I, -D, -U or -C
+# <library> is anything ending in .a or beginning with -l or -L
+# <module> is anything else but should be a valid Python
+# identifier (letters, digits, underscores, beginning with non-digit)
+#
+# (As the makesetup script changes, it may recognize some other
+# arguments as well, e.g. *.so and *.sl as libraries. See the big
+# case statement in the makesetup script.)
+#
+# Lines can also have the form
+#
+# <name> = <value>
+#
+# which defines a Make variable definition inserted into Makefile.in
+#
+# Finally, if a line contains just the word "*shared*" (without the
+# quotes but with the stars), then the following modules will not be
+# built statically. The build process works like this:
+#
+# 1. Build all modules that are declared as static in Modules/Setup,
+# combine them into libpythonxy.a, combine that into python.
+# 2. Build all modules that are listed as shared in Modules/Setup.
+# 3. Invoke setup.py. That builds all modules that
+# a) are not builtin, and
+# b) are not listed in Modules/Setup, and
+# c) can be build on the target
+#
+# Therefore, modules declared to be shared will not be
+# included in the config.c file, nor in the list of objects to be
+# added to the library archive, and their linker options won't be
+# added to the linker options. Rules to create their .o files and
+# their shared libraries will still be added to the Makefile, and
+# their names will be collected in the Make variable SHAREDMODS. This
+# is used to build modules as shared libraries. (They can be
+# installed using "make sharedinstall", which is implied by the
+# toplevel "make install" target.) (For compatibility,
+# *noconfig* has the same effect as *shared*.)
+#
+# In addition, *static* explicitly declares the following modules to
+# be static. Lines containing "*static*" and "*shared*" may thus
+# alternate throughout this file.
+
+# NOTE: As a standard policy, as many modules as can be supported by a
+# platform should be present. The distribution comes with all modules
+# enabled that are supported by most platforms and don't require you
+# to ftp sources from elsewhere.
+
+
+# Some special rules to define PYTHONPATH.
+# Edit the definitions below to indicate which options you are using.
+# Don't add any whitespace or comments!
+
+# Directories where library files get installed.
+# DESTLIB is for Python modules; MACHDESTLIB for shared libraries.
+DESTLIB=$(LIBDEST)
+MACHDESTLIB=$(BINLIBDEST)
+
+# NOTE: all the paths are now relative to the prefix that is computed
+# at run time!
+
+# Standard path -- don't edit.
+# No leading colon since this is the first entry.
+# Empty since this is now just the runtime prefix.
+DESTPATH=
+
+# Site specific path components -- should begin with : if non-empty
+SITEPATH=
+
+# Standard path components for test modules
+TESTPATH=
+
+# Path components for machine- or system-dependent modules and shared libraries
+MACHDEPPATH=:plat-$(MACHDEP)
+EXTRAMACHDEPPATH=
+
+# Path component for the Tkinter-related modules
+# The TKPATH variable is always enabled, to save you the effort.
+TKPATH=:lib-tk
+
+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
+PYTHONPATH=$(COREPYTHONPATH)
+
+
+# The modules listed here can't be built as shared libraries for
+# various reasons; therefore they are listed here instead of in the
+# normal order.
+
+# This only contains the minimal set of modules required to run the
+# setup.py script in the root of the Python source tree.
+
+posix posixmodule.c # posix (UNIX) system calls
+errno errnomodule.c # posix (UNIX) errno values
+pwd pwdmodule.c # this is needed to find out the user's home dir
+ # if $HOME is not set
+_sre _sre.c # Fredrik Lundh's new regular expressions
+_codecs _codecsmodule.c # access to the builtin codecs and codec registry
+_ssl _ssl.c
+
+# The zipimport module is always imported at startup. Having it as a
+# builtin module avoids some bootstrapping problems and reduces overhead.
+zipimport zipimport.c
+
+# The rest of the modules listed in this file are all commented out by
+# default. Usually they can be detected and built as dynamically
+# loaded modules by the new setup.py script added in Python 2.1. If
+# you're on a platform that doesn't support dynamic loading, want to
+# compile modules statically into the Python binary, or need to
+# specify some odd set of compiler switches, you can uncomment the
+# appropriate lines below.
+
+# ======================================================================
+
+# The Python symtable module depends on .h files that setup.py doesn't track
+_symtable symtablemodule.c
+
+# The SGI specific GL module:
+
+GLHACK=-Dclear=__GLclear
+#gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11
+
+# Pure module. Cannot be linked dynamically.
+# -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE
+#WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE
+#PURE_INCLS=-I/usr/local/include
+#PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs
+#pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS)
+
+# Uncommenting the following line tells makesetup that all following
+# modules are to be built as shared libraries (see above for more
+# detail; also note that *static* reverses this effect):
+
+#*shared*
+
+# GNU readline. Unlike previous Python incarnations, GNU readline is
+# now incorporated in an optional module, configured in the Setup file
+# instead of by a configure script switch. You may have to insert a
+# -L option pointing to the directory where libreadline.* lives,
+# and you may have to change -ltermcap to -ltermlib or perhaps remove
+# it, depending on your system -- see the GNU readline instructions.
+# It's okay for this to be a shared library, too.
+
+#readline readline.c -lreadline -ltermcap
+
+
+# Modules that should always be present (non UNIX dependent):
+
+#array arraymodule.c # array objects
+#cmath cmathmodule.c # -lm # complex math library functions
+#math mathmodule.c # -lm # math library functions, e.g. sin()
+#_struct _struct.c # binary structure packing/unpacking
+#time timemodule.c # -lm # time operations and variables
+#operator operator.c # operator.add() and similar goodies
+#_weakref _weakref.c # basic weak reference support
+#_testcapi _testcapimodule.c # Python C API test module
+#_random _randommodule.c # Random number generator
+#collections collectionsmodule.c # Container types
+#itertools itertoolsmodule.c # Functions creating iterators for efficient looping
+#strop stropmodule.c # String manipulations
+
+#unicodedata unicodedata.c # static Unicode character database
+
+# access to ISO C locale support
+#_locale _localemodule.c # -lintl
+
+
+# Modules with some UNIX dependencies -- on by default:
+# (If you have a really backward UNIX, select and socket may not be
+# supported...)
+
+#fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
+#spwd spwdmodule.c # spwd(3)
+#grp grpmodule.c # grp(3)
+#select selectmodule.c # select(2); not on ancient System V
+
+# Memory-mapped files (also works on Win32).
+#mmap mmapmodule.c
+
+# CSV file helper
+#_csv _csv.c
+
+# Socket module helper for socket(2)
+#_socket socketmodule.c
+
+# Socket module helper for SSL support; you must comment out the other
+# socket line above, and possibly edit the SSL variable:
+#SSL=/usr/local/ssl
+#_ssl _ssl.c \
+# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+# -L$(SSL)/lib -lssl -lcrypto
+
+# The crypt module is now disabled by default because it breaks builds
+# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
+
+
+# Some more UNIX dependent modules -- off by default, since these
+# are not supported by all UNIX systems:
+
+#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere
+#termios termios.c # Steen Lumholt's termios module
+#resource resource.c # Jeremy Hylton's rlimit interface
+
+
+# Multimedia modules -- off by default.
+# These don't work for 64-bit platforms!!!
+# #993173 says audioop works on 64-bit platforms, though.
+# These represent audio samples or images as strings:
+
+#audioop audioop.c # Operations on audio samples
+#imageop imageop.c # Operations on images
+#rgbimg rgbimgmodule.c # Read SGI RGB image files (but coded portably)
+
+
+# Note that the _md5 and _sha modules are normally only built if the
+# system does not have the OpenSSL libs containing an optimized version.
+
+# The _md5 module implements the RSA Data Security, Inc. MD5
+# Message-Digest Algorithm, described in RFC 1321. The necessary files
+# md5.c and md5.h are included here.
+
+#_md5 md5module.c md5.c
+
+
+# The _sha module implements the SHA checksum algorithm.
+# (NIST's Secure Hash Algorithm.)
+#_sha shamodule.c
+
+
+# SGI IRIX specific modules -- off by default.
+
+# These module work on any SGI machine:
+
+# *** gl must be enabled higher up in this file ***
+#fm fmmodule.c $(GLHACK) -lfm -lgl # Font Manager
+#sgi sgimodule.c # sgi.nap() and a few more
+
+# This module requires the header file
+# /usr/people/4Dgifts/iristools/include/izoom.h:
+#imgfile imgfile.c -limage -lgutil -lgl -lm # Image Processing Utilities
+
+
+# These modules require the Multimedia Development Option (I think):
+
+#al almodule.c -laudio # Audio Library
+#cd cdmodule.c -lcdaudio -lds -lmediad # CD Audio Library
+#cl clmodule.c -lcl -lawareaudio # Compression Library
+#sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11 # Starter Video
+
+
+# The FORMS library, by Mark Overmars, implements user interface
+# components such as dialogs and buttons using SGI's GL and FM
+# libraries. You must ftp the FORMS library separately from
+# ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a.
+# NOTE: if you want to be able to use FORMS and curses simultaneously
+# (or both link them statically into the same binary), you must
+# compile all of FORMS with the cc option "-Dclear=__GLclear".
+
+# The FORMS variable must point to the FORMS subdirectory of the forms
+# toplevel directory:
+
+#FORMS=/ufs/guido/src/forms/FORMS
+#fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl
+
+
+# SunOS specific modules -- off by default:
+
+#sunaudiodev sunaudiodev.c
+
+
+# A Linux specific module -- off by default; this may also work on
+# some *BSDs.
+
+#linuxaudiodev linuxaudiodev.c
+
+
+# George Neville-Neil's timing module:
+
+#timing timingmodule.c
+
+
+# The _tkinter module.
+#
+# The command for _tkinter is long and site specific. Please
+# uncomment and/or edit those parts as indicated. If you don't have a
+# specific extension (e.g. Tix or BLT), leave the corresponding line
+# commented out. (Leave the trailing backslashes in! If you
+# experience strange errors, you may want to join all uncommented
+# lines and remove the backslashes -- the backslash interpretation is
+# done by the shell's "read" command and it may not be implemented on
+# every system.
+
+# *** Always uncomment this (leave the leading underscore in!):
+# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
+# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
+# -L/usr/local/lib \
+# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
+# -I/usr/local/include \
+# *** Uncomment and edit to reflect where your X11 header files are:
+# -I/usr/X11R6/include \
+# *** Or uncomment this for Solaris:
+# -I/usr/openwin/include \
+# *** Uncomment and edit for Tix extension only:
+# -DWITH_TIX -ltix8.1.8.2 \
+# *** Uncomment and edit for BLT extension only:
+# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
+# *** Uncomment and edit for PIL (TkImaging) extension only:
+# (See http://www.pythonware.com/products/pil/ for more info)
+# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
+# *** Uncomment and edit for TOGL extension only:
+# -DWITH_TOGL togl.c \
+# *** Uncomment and edit to reflect your Tcl/Tk versions:
+# -ltk8.2 -ltcl8.2 \
+# *** Uncomment and edit to reflect where your X11 libraries are:
+# -L/usr/X11R6/lib \
+# *** Or uncomment this for Solaris:
+# -L/usr/openwin/lib \
+# *** Uncomment these for TOGL extension only:
+# -lGL -lGLU -lXext -lXmu \
+# *** Uncomment for AIX:
+# -lld \
+# *** Always uncomment this; X11 libraries to link with:
+# -lX11
+
+# Lance Ellinghaus's syslog module
+#syslog syslogmodule.c # syslog daemon interface
+
+
+# Curses support, requring the System V version of curses, often
+# provided by the ncurses library. e.g. on Linux, link with -lncurses
+# instead of -lcurses).
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#_curses _cursesmodule.c -lcurses -ltermcap
+# Wrapper for the panel library that's part of ncurses and SYSV curses.
+#_curses_panel _curses_panel.c -lpanel -lncurses
+
+
+# Generic (SunOS / SVR4) dynamic loading module.
+# This is not needed for dynamic loading of Python modules --
+# it is a highly experimental and dangerous device for calling
+# *arbitrary* C functions in *arbitrary* shared libraries:
+
+#dl dlmodule.c
+
+
+# Modules that provide persistent dictionary-like semantics. You will
+# probably want to arrange for at least one of them to be available on
+# your machine, though none are defined by default because of library
+# dependencies. The Python module anydbm.py provides an
+# implementation independent wrapper for these; dumbdbm.py provides
+# similar functionality (but slower of course) implemented in Python.
+
+# The standard Unix dbm module has been moved to Setup.config so that
+# it will be compiled as a shared library by default. Compiling it as
+# a built-in module causes conflicts with the pybsddb3 module since it
+# creates a static dependency on an out-of-date version of db.so.
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#dbm dbmmodule.c # dbm(3) may require -lndbm or similar
+
+# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
+
+
+# Sleepycat Berkeley DB interface.
+#
+# This requires the Sleepycat DB code, see http://www.sleepycat.com/
+# The earliest supported version of that library is 3.0, the latest
+# supported version is 4.0 (4.1 is specifically not supported, as that
+# changes the semantics of transactional databases). A list of available
+# releases can be found at
+#
+# http://www.sleepycat.com/update/index.html
+#
+# Edit the variables DB and DBLIBVERto point to the db top directory
+# and the subdirectory of PORT where you built it.
+#DB=/usr/local/BerkeleyDB.4.0
+#DBLIBVER=4.0
+#DBINC=$(DB)/include
+#DBLIB=$(DB)/lib
+#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
+
+# Historical Berkeley DB 1.85
+#
+# This module is deprecated; the 1.85 version of the Berkeley DB library has
+# bugs that can cause data corruption. If you can, use later versions of the
+# library instead, available from <http://www.sleepycat.com/>.
+
+#DB=/depot/sundry/src/berkeley-db/db.1.85
+#DBPORT=$(DB)/PORT/irix.5.3
+#bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a
+
+
+
+# Helper module for various ascii-encoders
+#binascii binascii.c
+
+# Fred Drake's interface to the Python parser
+#parser parsermodule.c
+
+# cStringIO and cPickle
+#cStringIO cStringIO.c
+#cPickle cPickle.c
+
+
+# Lee Busby's SIGFPE modules.
+# The library to link fpectl with is platform specific.
+# Choose *one* of the options below for fpectl:
+
+# For SGI IRIX (tested on 5.3):
+#fpectl fpectlmodule.c -lfpe
+
+# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
+# (Without the compiler you don't have -lsunmath.)
+#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
+
+# For other systems: see instructions in fpectlmodule.c.
+#fpectl fpectlmodule.c ...
+
+# Test module for fpectl. No extra libraries needed.
+#fpetest fpetestmodule.c
+
+# Andrew Kuchling's zlib module.
+# This require zlib 1.1.3 (or later).
+# See http://www.gzip.org/zlib/
+#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
+
+# Interface to the Expat XML parser
+#
+# Expat was written by James Clark and is now maintained by a group of
+# developers on SourceForge; see www.libexpat.org for more
+# information. The pyexpat module was written by Paul Prescod after a
+# prototype by Jack Jansen. Source of Expat 1.95.2 is included in
+# Modules/expat/. Usage of a system shared libexpat.so/expat.dll is
+# not advised.
+#
+# More information on Expat can be found at www.libexpat.org.
+#
+#EXPAT_DIR=/usr/local/src/expat-1.95.2
+#pyexpat pyexpat.c -DHAVE_EXPAT_H -I$(EXPAT_DIR)/lib -L$(EXPAT_DIR) -lexpat
+
+
+# Hye-Shik Chang's CJKCodecs
+
+# multibytecodec is required for all the other CJK codec modules
+#_multibytecodec cjkcodecs/multibytecodec.c
+
+#_codecs_cn cjkcodecs/_codecs_cn.c
+#_codecs_hk cjkcodecs/_codecs_hk.c
+#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
+#_codecs_jp cjkcodecs/_codecs_jp.c
+#_codecs_kr cjkcodecs/_codecs_kr.c
+#_codecs_tw cjkcodecs/_codecs_tw.c
+
+# Example -- included for reference only:
+# xx xxmodule.c
+
+# Another example -- the 'xxsubtype' module shows C-level subtyping in action
+xxsubtype xxsubtype.c
diff --git a/sys/src/cmd/python/Modules/Setup.config b/sys/src/cmd/python/Modules/Setup.config
new file mode 100644
index 000000000..7dde386a0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/Setup.config
@@ -0,0 +1,13 @@
+# This file is transmogrified into Setup.config by config.status.
+
+# The purpose of this file is to conditionally enable certain modules
+# based on configure-time options.
+
+# Threading
+#thread threadmodule.c
+
+# The signal module
+signal signalmodule.c
+
+# The rest of the modules previously listed in this file are built
+# by the setup.py script in Python 2.1 and later.
diff --git a/sys/src/cmd/python/Modules/Setup.config.in b/sys/src/cmd/python/Modules/Setup.config.in
new file mode 100644
index 000000000..fed62e9d8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/Setup.config.in
@@ -0,0 +1,13 @@
+# This file is transmogrified into Setup.config by config.status.
+
+# The purpose of this file is to conditionally enable certain modules
+# based on configure-time options.
+
+# Threading
+@USE_THREAD_MODULE@thread threadmodule.c
+
+# The signal module
+@USE_SIGNAL_MODULE@signal signalmodule.c
+
+# The rest of the modules previously listed in this file are built
+# by the setup.py script in Python 2.1 and later.
diff --git a/sys/src/cmd/python/Modules/Setup.dist b/sys/src/cmd/python/Modules/Setup.dist
new file mode 100644
index 000000000..46f4253e1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/Setup.dist
@@ -0,0 +1,487 @@
+# -*- makefile -*-
+# The file Setup is used by the makesetup script to construct the files
+# Makefile and config.c, from Makefile.pre and config.c.in,
+# respectively. The file Setup itself is initially copied from
+# Setup.dist; once it exists it will not be overwritten, so you can edit
+# Setup to your heart's content. Note that Makefile.pre is created
+# from Makefile.pre.in by the toplevel configure script.
+
+# (VPATH notes: Setup and Makefile.pre are in the build directory, as
+# are Makefile and config.c; the *.in and *.dist files are in the source
+# directory.)
+
+# Each line in this file describes one or more optional modules.
+# Modules enabled here will not be compiled by the setup.py script,
+# so the file can be used to override setup.py's behavior.
+
+# Lines have the following structure:
+#
+# <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
+#
+# <sourcefile> is anything ending in .c (.C, .cc, .c++ are C++ files)
+# <cpparg> is anything starting with -I, -D, -U or -C
+# <library> is anything ending in .a or beginning with -l or -L
+# <module> is anything else but should be a valid Python
+# identifier (letters, digits, underscores, beginning with non-digit)
+#
+# (As the makesetup script changes, it may recognize some other
+# arguments as well, e.g. *.so and *.sl as libraries. See the big
+# case statement in the makesetup script.)
+#
+# Lines can also have the form
+#
+# <name> = <value>
+#
+# which defines a Make variable definition inserted into Makefile.in
+#
+# Finally, if a line contains just the word "*shared*" (without the
+# quotes but with the stars), then the following modules will not be
+# built statically. The build process works like this:
+#
+# 1. Build all modules that are declared as static in Modules/Setup,
+# combine them into libpythonxy.a, combine that into python.
+# 2. Build all modules that are listed as shared in Modules/Setup.
+# 3. Invoke setup.py. That builds all modules that
+# a) are not builtin, and
+# b) are not listed in Modules/Setup, and
+# c) can be build on the target
+#
+# Therefore, modules declared to be shared will not be
+# included in the config.c file, nor in the list of objects to be
+# added to the library archive, and their linker options won't be
+# added to the linker options. Rules to create their .o files and
+# their shared libraries will still be added to the Makefile, and
+# their names will be collected in the Make variable SHAREDMODS. This
+# is used to build modules as shared libraries. (They can be
+# installed using "make sharedinstall", which is implied by the
+# toplevel "make install" target.) (For compatibility,
+# *noconfig* has the same effect as *shared*.)
+#
+# In addition, *static* explicitly declares the following modules to
+# be static. Lines containing "*static*" and "*shared*" may thus
+# alternate throughout this file.
+
+# NOTE: As a standard policy, as many modules as can be supported by a
+# platform should be present. The distribution comes with all modules
+# enabled that are supported by most platforms and don't require you
+# to ftp sources from elsewhere.
+
+
+# Some special rules to define PYTHONPATH.
+# Edit the definitions below to indicate which options you are using.
+# Don't add any whitespace or comments!
+
+# Directories where library files get installed.
+# DESTLIB is for Python modules; MACHDESTLIB for shared libraries.
+DESTLIB=$(LIBDEST)
+MACHDESTLIB=$(BINLIBDEST)
+
+# NOTE: all the paths are now relative to the prefix that is computed
+# at run time!
+
+# Standard path -- don't edit.
+# No leading colon since this is the first entry.
+# Empty since this is now just the runtime prefix.
+DESTPATH=
+
+# Site specific path components -- should begin with : if non-empty
+SITEPATH=
+
+# Standard path components for test modules
+TESTPATH=
+
+# Path components for machine- or system-dependent modules and shared libraries
+MACHDEPPATH=:plat-$(MACHDEP)
+EXTRAMACHDEPPATH=
+
+# Path component for the Tkinter-related modules
+# The TKPATH variable is always enabled, to save you the effort.
+TKPATH=:lib-tk
+
+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
+PYTHONPATH=$(COREPYTHONPATH)
+
+
+# The modules listed here can't be built as shared libraries for
+# various reasons; therefore they are listed here instead of in the
+# normal order.
+
+# This only contains the minimal set of modules required to run the
+# setup.py script in the root of the Python source tree.
+
+posix posixmodule.c # posix (UNIX) system calls
+errno errnomodule.c # posix (UNIX) errno values
+pwd pwdmodule.c # this is needed to find out the user's home dir
+ # if $HOME is not set
+_sre _sre.c # Fredrik Lundh's new regular expressions
+_codecs _codecsmodule.c # access to the builtin codecs and codec registry
+
+# The zipimport module is always imported at startup. Having it as a
+# builtin module avoids some bootstrapping problems and reduces overhead.
+zipimport zipimport.c
+
+# The rest of the modules listed in this file are all commented out by
+# default. Usually they can be detected and built as dynamically
+# loaded modules by the new setup.py script added in Python 2.1. If
+# you're on a platform that doesn't support dynamic loading, want to
+# compile modules statically into the Python binary, or need to
+# specify some odd set of compiler switches, you can uncomment the
+# appropriate lines below.
+
+# ======================================================================
+
+# The Python symtable module depends on .h files that setup.py doesn't track
+_symtable symtablemodule.c
+
+# The SGI specific GL module:
+
+GLHACK=-Dclear=__GLclear
+#gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11
+
+# Pure module. Cannot be linked dynamically.
+# -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE
+#WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE
+#PURE_INCLS=-I/usr/local/include
+#PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs
+#pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS)
+
+# Uncommenting the following line tells makesetup that all following
+# modules are to be built as shared libraries (see above for more
+# detail; also note that *static* reverses this effect):
+
+#*shared*
+
+# GNU readline. Unlike previous Python incarnations, GNU readline is
+# now incorporated in an optional module, configured in the Setup file
+# instead of by a configure script switch. You may have to insert a
+# -L option pointing to the directory where libreadline.* lives,
+# and you may have to change -ltermcap to -ltermlib or perhaps remove
+# it, depending on your system -- see the GNU readline instructions.
+# It's okay for this to be a shared library, too.
+
+#readline readline.c -lreadline -ltermcap
+
+
+# Modules that should always be present (non UNIX dependent):
+
+#array arraymodule.c # array objects
+#cmath cmathmodule.c # -lm # complex math library functions
+#math mathmodule.c # -lm # math library functions, e.g. sin()
+#_struct _struct.c # binary structure packing/unpacking
+#time timemodule.c # -lm # time operations and variables
+#operator operator.c # operator.add() and similar goodies
+#_weakref _weakref.c # basic weak reference support
+#_testcapi _testcapimodule.c # Python C API test module
+#_random _randommodule.c # Random number generator
+#collections collectionsmodule.c # Container types
+#itertools itertoolsmodule.c # Functions creating iterators for efficient looping
+#strop stropmodule.c # String manipulations
+
+#unicodedata unicodedata.c # static Unicode character database
+
+# access to ISO C locale support
+#_locale _localemodule.c # -lintl
+
+
+# Modules with some UNIX dependencies -- on by default:
+# (If you have a really backward UNIX, select and socket may not be
+# supported...)
+
+#fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
+#spwd spwdmodule.c # spwd(3)
+#grp grpmodule.c # grp(3)
+#select selectmodule.c # select(2); not on ancient System V
+
+# Memory-mapped files (also works on Win32).
+#mmap mmapmodule.c
+
+# CSV file helper
+#_csv _csv.c
+
+# Socket module helper for socket(2)
+#_socket socketmodule.c
+
+# Socket module helper for SSL support; you must comment out the other
+# socket line above, and possibly edit the SSL variable:
+#SSL=/usr/local/ssl
+#_ssl _ssl.c \
+# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+# -L$(SSL)/lib -lssl -lcrypto
+
+# The crypt module is now disabled by default because it breaks builds
+# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
+
+
+# Some more UNIX dependent modules -- off by default, since these
+# are not supported by all UNIX systems:
+
+#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere
+#termios termios.c # Steen Lumholt's termios module
+#resource resource.c # Jeremy Hylton's rlimit interface
+
+
+# Multimedia modules -- off by default.
+# These don't work for 64-bit platforms!!!
+# #993173 says audioop works on 64-bit platforms, though.
+# These represent audio samples or images as strings:
+
+#audioop audioop.c # Operations on audio samples
+#imageop imageop.c # Operations on images
+#rgbimg rgbimgmodule.c # Read SGI RGB image files (but coded portably)
+
+
+# Note that the _md5 and _sha modules are normally only built if the
+# system does not have the OpenSSL libs containing an optimized version.
+
+# The _md5 module implements the RSA Data Security, Inc. MD5
+# Message-Digest Algorithm, described in RFC 1321. The necessary files
+# md5.c and md5.h are included here.
+
+#_md5 md5module.c md5.c
+
+
+# The _sha module implements the SHA checksum algorithm.
+# (NIST's Secure Hash Algorithm.)
+#_sha shamodule.c
+
+
+# SGI IRIX specific modules -- off by default.
+
+# These module work on any SGI machine:
+
+# *** gl must be enabled higher up in this file ***
+#fm fmmodule.c $(GLHACK) -lfm -lgl # Font Manager
+#sgi sgimodule.c # sgi.nap() and a few more
+
+# This module requires the header file
+# /usr/people/4Dgifts/iristools/include/izoom.h:
+#imgfile imgfile.c -limage -lgutil -lgl -lm # Image Processing Utilities
+
+
+# These modules require the Multimedia Development Option (I think):
+
+#al almodule.c -laudio # Audio Library
+#cd cdmodule.c -lcdaudio -lds -lmediad # CD Audio Library
+#cl clmodule.c -lcl -lawareaudio # Compression Library
+#sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11 # Starter Video
+
+
+# The FORMS library, by Mark Overmars, implements user interface
+# components such as dialogs and buttons using SGI's GL and FM
+# libraries. You must ftp the FORMS library separately from
+# ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a.
+# NOTE: if you want to be able to use FORMS and curses simultaneously
+# (or both link them statically into the same binary), you must
+# compile all of FORMS with the cc option "-Dclear=__GLclear".
+
+# The FORMS variable must point to the FORMS subdirectory of the forms
+# toplevel directory:
+
+#FORMS=/ufs/guido/src/forms/FORMS
+#fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl
+
+
+# SunOS specific modules -- off by default:
+
+#sunaudiodev sunaudiodev.c
+
+
+# A Linux specific module -- off by default; this may also work on
+# some *BSDs.
+
+#linuxaudiodev linuxaudiodev.c
+
+
+# George Neville-Neil's timing module:
+
+#timing timingmodule.c
+
+
+# The _tkinter module.
+#
+# The command for _tkinter is long and site specific. Please
+# uncomment and/or edit those parts as indicated. If you don't have a
+# specific extension (e.g. Tix or BLT), leave the corresponding line
+# commented out. (Leave the trailing backslashes in! If you
+# experience strange errors, you may want to join all uncommented
+# lines and remove the backslashes -- the backslash interpretation is
+# done by the shell's "read" command and it may not be implemented on
+# every system.
+
+# *** Always uncomment this (leave the leading underscore in!):
+# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
+# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
+# -L/usr/local/lib \
+# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
+# -I/usr/local/include \
+# *** Uncomment and edit to reflect where your X11 header files are:
+# -I/usr/X11R6/include \
+# *** Or uncomment this for Solaris:
+# -I/usr/openwin/include \
+# *** Uncomment and edit for Tix extension only:
+# -DWITH_TIX -ltix8.1.8.2 \
+# *** Uncomment and edit for BLT extension only:
+# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
+# *** Uncomment and edit for PIL (TkImaging) extension only:
+# (See http://www.pythonware.com/products/pil/ for more info)
+# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
+# *** Uncomment and edit for TOGL extension only:
+# -DWITH_TOGL togl.c \
+# *** Uncomment and edit to reflect your Tcl/Tk versions:
+# -ltk8.2 -ltcl8.2 \
+# *** Uncomment and edit to reflect where your X11 libraries are:
+# -L/usr/X11R6/lib \
+# *** Or uncomment this for Solaris:
+# -L/usr/openwin/lib \
+# *** Uncomment these for TOGL extension only:
+# -lGL -lGLU -lXext -lXmu \
+# *** Uncomment for AIX:
+# -lld \
+# *** Always uncomment this; X11 libraries to link with:
+# -lX11
+
+# Lance Ellinghaus's syslog module
+#syslog syslogmodule.c # syslog daemon interface
+
+
+# Curses support, requring the System V version of curses, often
+# provided by the ncurses library. e.g. on Linux, link with -lncurses
+# instead of -lcurses).
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#_curses _cursesmodule.c -lcurses -ltermcap
+# Wrapper for the panel library that's part of ncurses and SYSV curses.
+#_curses_panel _curses_panel.c -lpanel -lncurses
+
+
+# Generic (SunOS / SVR4) dynamic loading module.
+# This is not needed for dynamic loading of Python modules --
+# it is a highly experimental and dangerous device for calling
+# *arbitrary* C functions in *arbitrary* shared libraries:
+
+#dl dlmodule.c
+
+
+# Modules that provide persistent dictionary-like semantics. You will
+# probably want to arrange for at least one of them to be available on
+# your machine, though none are defined by default because of library
+# dependencies. The Python module anydbm.py provides an
+# implementation independent wrapper for these; dumbdbm.py provides
+# similar functionality (but slower of course) implemented in Python.
+
+# The standard Unix dbm module has been moved to Setup.config so that
+# it will be compiled as a shared library by default. Compiling it as
+# a built-in module causes conflicts with the pybsddb3 module since it
+# creates a static dependency on an out-of-date version of db.so.
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#dbm dbmmodule.c # dbm(3) may require -lndbm or similar
+
+# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
+#
+# First, look at Setup.config; configure may have set this for you.
+
+#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
+
+
+# Sleepycat Berkeley DB interface.
+#
+# This requires the Sleepycat DB code, see http://www.sleepycat.com/
+# The earliest supported version of that library is 3.0, the latest
+# supported version is 4.0 (4.1 is specifically not supported, as that
+# changes the semantics of transactional databases). A list of available
+# releases can be found at
+#
+# http://www.sleepycat.com/update/index.html
+#
+# Edit the variables DB and DBLIBVERto point to the db top directory
+# and the subdirectory of PORT where you built it.
+#DB=/usr/local/BerkeleyDB.4.0
+#DBLIBVER=4.0
+#DBINC=$(DB)/include
+#DBLIB=$(DB)/lib
+#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
+
+# Historical Berkeley DB 1.85
+#
+# This module is deprecated; the 1.85 version of the Berkeley DB library has
+# bugs that can cause data corruption. If you can, use later versions of the
+# library instead, available from <http://www.sleepycat.com/>.
+
+#DB=/depot/sundry/src/berkeley-db/db.1.85
+#DBPORT=$(DB)/PORT/irix.5.3
+#bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a
+
+
+
+# Helper module for various ascii-encoders
+#binascii binascii.c
+
+# Fred Drake's interface to the Python parser
+#parser parsermodule.c
+
+# cStringIO and cPickle
+#cStringIO cStringIO.c
+#cPickle cPickle.c
+
+
+# Lee Busby's SIGFPE modules.
+# The library to link fpectl with is platform specific.
+# Choose *one* of the options below for fpectl:
+
+# For SGI IRIX (tested on 5.3):
+#fpectl fpectlmodule.c -lfpe
+
+# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
+# (Without the compiler you don't have -lsunmath.)
+#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
+
+# For other systems: see instructions in fpectlmodule.c.
+#fpectl fpectlmodule.c ...
+
+# Test module for fpectl. No extra libraries needed.
+#fpetest fpetestmodule.c
+
+# Andrew Kuchling's zlib module.
+# This require zlib 1.1.3 (or later).
+# See http://www.gzip.org/zlib/
+#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
+
+# Interface to the Expat XML parser
+#
+# Expat was written by James Clark and is now maintained by a group of
+# developers on SourceForge; see www.libexpat.org for more
+# information. The pyexpat module was written by Paul Prescod after a
+# prototype by Jack Jansen. Source of Expat 1.95.2 is included in
+# Modules/expat/. Usage of a system shared libexpat.so/expat.dll is
+# not advised.
+#
+# More information on Expat can be found at www.libexpat.org.
+#
+#EXPAT_DIR=/usr/local/src/expat-1.95.2
+#pyexpat pyexpat.c -DHAVE_EXPAT_H -I$(EXPAT_DIR)/lib -L$(EXPAT_DIR) -lexpat
+
+
+# Hye-Shik Chang's CJKCodecs
+
+# multibytecodec is required for all the other CJK codec modules
+#_multibytecodec cjkcodecs/multibytecodec.c
+
+#_codecs_cn cjkcodecs/_codecs_cn.c
+#_codecs_hk cjkcodecs/_codecs_hk.c
+#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
+#_codecs_jp cjkcodecs/_codecs_jp.c
+#_codecs_kr cjkcodecs/_codecs_kr.c
+#_codecs_tw cjkcodecs/_codecs_tw.c
+
+# Example -- included for reference only:
+# xx xxmodule.c
+
+# Another example -- the 'xxsubtype' module shows C-level subtyping in action
+xxsubtype xxsubtype.c
diff --git a/sys/src/cmd/python/Modules/Setup.local b/sys/src/cmd/python/Modules/Setup.local
new file mode 100644
index 000000000..ca2983e22
--- /dev/null
+++ b/sys/src/cmd/python/Modules/Setup.local
@@ -0,0 +1 @@
+# Edit this file for local setup changes
diff --git a/sys/src/cmd/python/Modules/_bisectmodule.c b/sys/src/cmd/python/Modules/_bisectmodule.c
new file mode 100644
index 000000000..f8d412aba
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_bisectmodule.c
@@ -0,0 +1,235 @@
+/* Bisection algorithms. Drop in replacement for bisect.py
+
+Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
+*/
+
+#include "Python.h"
+
+static int
+internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
+{
+ PyObject *litem;
+ Py_ssize_t mid, res;
+
+ if (hi == -1) {
+ hi = PySequence_Size(list);
+ if (hi < 0)
+ return -1;
+ }
+ while (lo < hi) {
+ mid = (lo + hi) / 2;
+ litem = PySequence_GetItem(list, mid);
+ if (litem == NULL)
+ return -1;
+ res = PyObject_RichCompareBool(item, litem, Py_LT);
+ Py_DECREF(litem);
+ if (res < 0)
+ return -1;
+ if (res)
+ hi = mid;
+ else
+ lo = mid + 1;
+ }
+ return lo;
+}
+
+static PyObject *
+bisect_right(PyObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *list, *item;
+ int lo = 0;
+ int hi = -1;
+ int index;
+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_right",
+ keywords, &list, &item, &lo, &hi))
+ return NULL;
+ index = internal_bisect_right(list, item, lo, hi);
+ if (index < 0)
+ return NULL;
+ return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(bisect_right_doc,
+"bisect_right(a, x[, lo[, hi]]) -> index\n\
+\n\
+Return the index where to insert item x in list a, assuming a is sorted.\n\
+\n\
+The return value i is such that all e in a[:i] have e <= x, and all e in\n\
+a[i:] have e > x. So if x already appears in the list, i points just\n\
+beyond the rightmost x already there\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+static PyObject *
+insort_right(PyObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *list, *item, *result;
+ int lo = 0;
+ int hi = -1;
+ int index;
+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_right",
+ keywords, &list, &item, &lo, &hi))
+ return NULL;
+ index = internal_bisect_right(list, item, lo, hi);
+ if (index < 0)
+ return NULL;
+ if (PyList_Check(list)) {
+ if (PyList_Insert(list, index, item) < 0)
+ return NULL;
+ } else {
+ result = PyObject_CallMethod(list, "insert", "iO",
+ index, item);
+ if (result == NULL)
+ return NULL;
+ Py_DECREF(result);
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(insort_right_doc,
+"insort_right(a, x[, lo[, hi]])\n\
+\n\
+Insert item x in list a, and keep it sorted assuming a is sorted.\n\
+\n\
+If x is already in a, insert it to the right of the rightmost x.\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+static int
+internal_bisect_left(PyObject *list, PyObject *item, int lo, int hi)
+{
+ PyObject *litem;
+ int mid, res;
+
+ if (hi == -1) {
+ hi = PySequence_Size(list);
+ if (hi < 0)
+ return -1;
+ }
+ while (lo < hi) {
+ mid = (lo + hi) / 2;
+ litem = PySequence_GetItem(list, mid);
+ if (litem == NULL)
+ return -1;
+ res = PyObject_RichCompareBool(litem, item, Py_LT);
+ Py_DECREF(litem);
+ if (res < 0)
+ return -1;
+ if (res)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+ return lo;
+}
+
+static PyObject *
+bisect_left(PyObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *list, *item;
+ int lo = 0;
+ int hi = -1;
+ int index;
+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_left",
+ keywords, &list, &item, &lo, &hi))
+ return NULL;
+ index = internal_bisect_left(list, item, lo, hi);
+ if (index < 0)
+ return NULL;
+ return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(bisect_left_doc,
+"bisect_left(a, x[, lo[, hi]]) -> index\n\
+\n\
+Return the index where to insert item x in list a, assuming a is sorted.\n\
+\n\
+The return value i is such that all e in a[:i] have e < x, and all e in\n\
+a[i:] have e >= x. So if x already appears in the list, i points just\n\
+before the leftmost x already there.\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+static PyObject *
+insort_left(PyObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *list, *item, *result;
+ int lo = 0;
+ int hi = -1;
+ int index;
+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_left",
+ keywords, &list, &item, &lo, &hi))
+ return NULL;
+ index = internal_bisect_left(list, item, lo, hi);
+ if (index < 0)
+ return NULL;
+ if (PyList_Check(list)) {
+ if (PyList_Insert(list, index, item) < 0)
+ return NULL;
+ } else {
+ result = PyObject_CallMethod(list, "insert", "iO",
+ index, item);
+ if (result == NULL)
+ return NULL;
+ Py_DECREF(result);
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(insort_left_doc,
+"insort_left(a, x[, lo[, hi]])\n\
+\n\
+Insert item x in list a, and keep it sorted assuming a is sorted.\n\
+\n\
+If x is already in a, insert it to the left of the leftmost x.\n\
+\n\
+Optional args lo (default 0) and hi (default len(a)) bound the\n\
+slice of a to be searched.\n");
+
+PyDoc_STRVAR(bisect_doc, "Alias for bisect_right().\n");
+PyDoc_STRVAR(insort_doc, "Alias for insort_right().\n");
+
+static PyMethodDef bisect_methods[] = {
+ {"bisect_right", (PyCFunction)bisect_right,
+ METH_VARARGS|METH_KEYWORDS, bisect_right_doc},
+ {"bisect", (PyCFunction)bisect_right,
+ METH_VARARGS|METH_KEYWORDS, bisect_doc},
+ {"insort_right", (PyCFunction)insort_right,
+ METH_VARARGS|METH_KEYWORDS, insort_right_doc},
+ {"insort", (PyCFunction)insort_right,
+ METH_VARARGS|METH_KEYWORDS, insort_doc},
+ {"bisect_left", (PyCFunction)bisect_left,
+ METH_VARARGS|METH_KEYWORDS, bisect_left_doc},
+ {"insort_left", (PyCFunction)insort_left,
+ METH_VARARGS|METH_KEYWORDS, insort_left_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"Bisection algorithms.\n\
+\n\
+This module provides support for maintaining a list in sorted order without\n\
+having to sort the list after each insertion. For long lists of items with\n\
+expensive comparison operations, this can be an improvement over the more\n\
+common approach.\n");
+
+PyMODINIT_FUNC
+init_bisect(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("_bisect", bisect_methods, module_doc);
+}
diff --git a/sys/src/cmd/python/Modules/_bsddb.c b/sys/src/cmd/python/Modules/_bsddb.c
new file mode 100644
index 000000000..b55c4e3eb
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_bsddb.c
@@ -0,0 +1,6047 @@
+/*----------------------------------------------------------------------
+ Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
+ and Andrew Kuchling. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ o Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the disclaimer that follows.
+
+ o Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ o Neither the name of Digital Creations nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
+ IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
+ CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+------------------------------------------------------------------------*/
+
+
+/*
+ * Handwritten code to wrap version 3.x of the Berkeley DB library,
+ * written to replace a SWIG-generated file. It has since been updated
+ * to compile with BerkeleyDB versions 3.2 through 4.2.
+ *
+ * This module was started by Andrew Kuchling to remove the dependency
+ * on SWIG in a package by Gregory P. Smith <greg@electricrain.com> who
+ * based his work on a similar package by Robin Dunn <robin@alldunn.com>
+ * which wrapped Berkeley DB 2.7.x.
+ *
+ * Development of this module then returned full circle back to Robin Dunn
+ * who worked on behalf of Digital Creations to complete the wrapping of
+ * the DB 3.x API and to build a solid unit test suite. Robin has
+ * since gone onto other projects (wxPython).
+ *
+ * Gregory P. Smith <greg@electricrain.com> is once again the maintainer.
+ *
+ * Use the pybsddb-users@lists.sf.net mailing list for all questions.
+ * Things can change faster than the header of this file is updated. This
+ * file is shared with the PyBSDDB project at SourceForge:
+ *
+ * http://pybsddb.sf.net
+ *
+ * This file should remain backward compatible with Python 2.1, but see PEP
+ * 291 for the most current backward compatibility requirements:
+ *
+ * http://www.python.org/peps/pep-0291.html
+ *
+ * This module contains 6 types:
+ *
+ * DB (Database)
+ * DBCursor (Database Cursor)
+ * DBEnv (database environment)
+ * DBTxn (An explicit database transaction)
+ * DBLock (A lock handle)
+ * DBSequence (Sequence)
+ *
+ */
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Portions of this module, associated unit tests and build scripts are the
+ * result of a contract with The Written Word (http://thewrittenword.com/)
+ * Many thanks go out to them for causing me to raise the bar on quality and
+ * functionality, resulting in a better bsddb3 package for all of us to use.
+ *
+ * --Robin
+ */
+
+/* --------------------------------------------------------------------- */
+
+#include <stddef.h> /* for offsetof() */
+#include <Python.h>
+#include <db.h>
+
+/* --------------------------------------------------------------------- */
+/* Various macro definitions */
+
+/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
+#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
+#if DB_VERSION_MINOR > 9
+#error "eek! DBVER can't handle minor versions > 9"
+#endif
+
+#define PY_BSDDB_VERSION "4.4.5.2"
+static char *rcs_id = "$Id: _bsddb.c 53254 2007-01-05 02:09:06Z gregory.p.smith $";
+
+
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+#ifdef WITH_THREAD
+
+/* These are for when calling Python --> C */
+#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
+#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
+
+/* For 2.3, use the PyGILState_ calls */
+#if (PY_VERSION_HEX >= 0x02030000)
+#define MYDB_USE_GILSTATE
+#endif
+
+/* and these are for calling C --> Python */
+#if defined(MYDB_USE_GILSTATE)
+#define MYDB_BEGIN_BLOCK_THREADS \
+ PyGILState_STATE __savestate = PyGILState_Ensure();
+#define MYDB_END_BLOCK_THREADS \
+ PyGILState_Release(__savestate);
+#else /* MYDB_USE_GILSTATE */
+/* Pre GILState API - do it the long old way */
+static PyInterpreterState* _db_interpreterState = NULL;
+#define MYDB_BEGIN_BLOCK_THREADS { \
+ PyThreadState* prevState; \
+ PyThreadState* newState; \
+ PyEval_AcquireLock(); \
+ newState = PyThreadState_New(_db_interpreterState); \
+ prevState = PyThreadState_Swap(newState);
+
+#define MYDB_END_BLOCK_THREADS \
+ newState = PyThreadState_Swap(prevState); \
+ PyThreadState_Clear(newState); \
+ PyEval_ReleaseLock(); \
+ PyThreadState_Delete(newState); \
+ }
+#endif /* MYDB_USE_GILSTATE */
+
+#else
+/* Compiled without threads - avoid all this cruft */
+#define MYDB_BEGIN_ALLOW_THREADS
+#define MYDB_END_ALLOW_THREADS
+#define MYDB_BEGIN_BLOCK_THREADS
+#define MYDB_END_BLOCK_THREADS
+
+#endif
+
+/* Should DB_INCOMPLETE be turned into a warning or an exception? */
+#define INCOMPLETE_IS_WARNING 1
+
+/* --------------------------------------------------------------------- */
+/* Exceptions */
+
+static PyObject* DBError; /* Base class, all others derive from this */
+static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
+static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
+static PyObject* DBKeyExistError; /* DB_KEYEXIST */
+static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
+static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
+static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
+static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
+static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
+static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
+static PyObject* DBNoServerError; /* DB_NOSERVER */
+static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
+static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
+#if (DBVER >= 33)
+static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
+static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
+#endif
+
+#if !INCOMPLETE_IS_WARNING
+static PyObject* DBIncompleteError; /* DB_INCOMPLETE */
+#endif
+
+static PyObject* DBInvalidArgError; /* EINVAL */
+static PyObject* DBAccessError; /* EACCES */
+static PyObject* DBNoSpaceError; /* ENOSPC */
+static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
+static PyObject* DBAgainError; /* EAGAIN */
+static PyObject* DBBusyError; /* EBUSY */
+static PyObject* DBFileExistsError; /* EEXIST */
+static PyObject* DBNoSuchFileError; /* ENOENT */
+static PyObject* DBPermissionsError; /* EPERM */
+
+#if (DBVER < 43)
+#define DB_BUFFER_SMALL ENOMEM
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* Structure definitions */
+
+#if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */
+#define HAVE_WEAKREF
+#else
+#undef HAVE_WEAKREF
+#endif
+
+/* if Python >= 2.1 better support warnings */
+#if PYTHON_API_VERSION >= 1010
+#define HAVE_WARNINGS
+#else
+#undef HAVE_WARNINGS
+#endif
+
+#if PYTHON_API_VERSION <= 1007
+ /* 1.5 compatibility */
+#define PyObject_New PyObject_NEW
+#define PyObject_Del PyMem_DEL
+#endif
+
+struct behaviourFlags {
+ /* What is the default behaviour when DB->get or DBCursor->get returns a
+ DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
+ unsigned int getReturnsNone : 1;
+ /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
+ * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
+ unsigned int cursorSetReturnsNone : 1;
+};
+
+#define DEFAULT_GET_RETURNS_NONE 1
+#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
+
+typedef struct {
+ PyObject_HEAD
+ DB_ENV* db_env;
+ u_int32_t flags; /* saved flags from open() */
+ int closed;
+ struct behaviourFlags moduleFlags;
+#ifdef HAVE_WEAKREF
+ PyObject *in_weakreflist; /* List of weak references */
+#endif
+} DBEnvObject;
+
+
+typedef struct {
+ PyObject_HEAD
+ DB* db;
+ DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */
+ u_int32_t flags; /* saved flags from open() */
+ u_int32_t setflags; /* saved flags from set_flags() */
+ int haveStat;
+ struct behaviourFlags moduleFlags;
+#if (DBVER >= 33)
+ PyObject* associateCallback;
+ PyObject* btCompareCallback;
+ int primaryDBType;
+#endif
+#ifdef HAVE_WEAKREF
+ PyObject *in_weakreflist; /* List of weak references */
+#endif
+} DBObject;
+
+
+typedef struct {
+ PyObject_HEAD
+ DBC* dbc;
+ DBObject* mydb;
+#ifdef HAVE_WEAKREF
+ PyObject *in_weakreflist; /* List of weak references */
+#endif
+} DBCursorObject;
+
+
+typedef struct {
+ PyObject_HEAD
+ DB_TXN* txn;
+ PyObject *env;
+#ifdef HAVE_WEAKREF
+ PyObject *in_weakreflist; /* List of weak references */
+#endif
+} DBTxnObject;
+
+
+typedef struct {
+ PyObject_HEAD
+ DB_LOCK lock;
+#ifdef HAVE_WEAKREF
+ PyObject *in_weakreflist; /* List of weak references */
+#endif
+} DBLockObject;
+
+#if (DBVER >= 43)
+typedef struct {
+ PyObject_HEAD
+ DB_SEQUENCE* sequence;
+ DBObject* mydb;
+#ifdef HAVE_WEAKREF
+ PyObject *in_weakreflist; /* List of weak references */
+#endif
+} DBSequenceObject;
+staticforward PyTypeObject DBSequence_Type;
+#endif
+
+staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
+
+#define DBObject_Check(v) ((v)->ob_type == &DB_Type)
+#define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
+#define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
+#define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
+#define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
+#if (DBVER >= 43)
+#define DBSequenceObject_Check(v) ((v)->ob_type == &DBSequence_Type)
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* Utility macros and functions */
+
+#define RETURN_IF_ERR() \
+ if (makeDBError(err)) { \
+ return NULL; \
+ }
+
+#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
+
+#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
+ if ((nonNull) == NULL) { \
+ PyObject *errTuple = NULL; \
+ errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
+ PyErr_SetObject((pyErrObj), errTuple); \
+ Py_DECREF(errTuple); \
+ return NULL; \
+ }
+
+#define CHECK_DB_NOT_CLOSED(dbobj) \
+ _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
+
+#define CHECK_ENV_NOT_CLOSED(env) \
+ _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
+
+#define CHECK_CURSOR_NOT_CLOSED(curs) \
+ _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
+
+#if (DBVER >= 43)
+#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
+ _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
+#endif
+
+#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
+ (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
+
+#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
+
+#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
+ dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
+
+
+static int makeDBError(int err);
+
+
+/* Return the access method type of the DBObject */
+static int _DB_get_type(DBObject* self)
+{
+#if (DBVER >= 33)
+ DBTYPE type;
+ int err;
+ err = self->db->get_type(self->db, &type);
+ if (makeDBError(err)) {
+ return -1;
+ }
+ return type;
+#else
+ return self->db->get_type(self->db);
+#endif
+}
+
+
+/* Create a DBT structure (containing key and data values) from Python
+ strings. Returns 1 on success, 0 on an error. */
+static int make_dbt(PyObject* obj, DBT* dbt)
+{
+ CLEAR_DBT(*dbt);
+ if (obj == Py_None) {
+ /* no need to do anything, the structure has already been zeroed */
+ }
+ else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Data values must be of type string or None.");
+ return 0;
+ }
+ return 1;
+}
+
+
+/* Recno and Queue DBs can have integer keys. This function figures out
+ what's been given, verifies that it's allowed, and then makes the DBT.
+
+ Caller MUST call FREE_DBT(key) when done. */
+static int
+make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
+{
+ db_recno_t recno;
+ int type;
+
+ CLEAR_DBT(*key);
+ if (keyobj == Py_None) {
+ type = _DB_get_type(self);
+ if (type == -1)
+ return 0;
+ if (type == DB_RECNO || type == DB_QUEUE) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "None keys not allowed for Recno and Queue DB's");
+ return 0;
+ }
+ /* no need to do anything, the structure has already been zeroed */
+ }
+
+ else if (PyString_Check(keyobj)) {
+ /* verify access method type */
+ type = _DB_get_type(self);
+ if (type == -1)
+ return 0;
+ if (type == DB_RECNO || type == DB_QUEUE) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "String keys not allowed for Recno and Queue DB's");
+ return 0;
+ }
+
+ key->data = PyString_AS_STRING(keyobj);
+ key->size = PyString_GET_SIZE(keyobj);
+ }
+
+ else if (PyInt_Check(keyobj)) {
+ /* verify access method type */
+ type = _DB_get_type(self);
+ if (type == -1)
+ return 0;
+ if (type == DB_BTREE && pflags != NULL) {
+ /* if BTREE then an Integer key is allowed with the
+ * DB_SET_RECNO flag */
+ *pflags |= DB_SET_RECNO;
+ }
+ else if (type != DB_RECNO && type != DB_QUEUE) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "Integer keys only allowed for Recno and Queue DB's");
+ return 0;
+ }
+
+ /* Make a key out of the requested recno, use allocated space so DB
+ * will be able to realloc room for the real key if needed. */
+ recno = PyInt_AS_LONG(keyobj);
+ key->data = malloc(sizeof(db_recno_t));
+ if (key->data == NULL) {
+ PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
+ return 0;
+ }
+ key->ulen = key->size = sizeof(db_recno_t);
+ memcpy(key->data, &recno, sizeof(db_recno_t));
+ key->flags = DB_DBT_REALLOC;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "String or Integer object expected for key, %s found",
+ keyobj->ob_type->tp_name);
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Add partial record access to an existing DBT data struct.
+ If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
+ and the data storage/retrieval will be done using dlen and doff. */
+static int add_partial_dbt(DBT* d, int dlen, int doff) {
+ /* if neither were set we do nothing (-1 is the default value) */
+ if ((dlen == -1) && (doff == -1)) {
+ return 1;
+ }
+
+ if ((dlen < 0) || (doff < 0)) {
+ PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
+ return 0;
+ }
+
+ d->flags = d->flags | DB_DBT_PARTIAL;
+ d->dlen = (unsigned int) dlen;
+ d->doff = (unsigned int) doff;
+ return 1;
+}
+
+/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
+/* TODO: make this use the native libc strlcpy() when available (BSD) */
+unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
+{
+ unsigned int srclen, copylen;
+
+ srclen = strlen(src);
+ if (n <= 0)
+ return srclen;
+ copylen = (srclen > n-1) ? n-1 : srclen;
+ /* populate dest[0] thru dest[copylen-1] */
+ memcpy(dest, src, copylen);
+ /* guarantee null termination */
+ dest[copylen] = 0;
+
+ return srclen;
+}
+
+/* Callback used to save away more information about errors from the DB
+ * library. */
+static char _db_errmsg[1024];
+#if (DBVER <= 42)
+static void _db_errorCallback(const char* prefix, char* msg)
+#else
+static void _db_errorCallback(const DB_ENV *db_env,
+ const char* prefix, const char* msg)
+#endif
+{
+ our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
+}
+
+
+/* make a nice exception object to raise for errors. */
+static int makeDBError(int err)
+{
+ char errTxt[2048]; /* really big, just in case... */
+ PyObject *errObj = NULL;
+ PyObject *errTuple = NULL;
+ int exceptionRaised = 0;
+ unsigned int bytes_left;
+
+ switch (err) {
+ case 0: /* successful, no error */ break;
+
+#if (DBVER < 41)
+ case DB_INCOMPLETE:
+#if INCOMPLETE_IS_WARNING
+ bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
+ /* Ensure that bytes_left never goes negative */
+ if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
+ bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
+ assert(bytes_left >= 0);
+ strcat(errTxt, " -- ");
+ strncat(errTxt, _db_errmsg, bytes_left);
+ }
+ _db_errmsg[0] = 0;
+#ifdef HAVE_WARNINGS
+ exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
+#else
+ fprintf(stderr, errTxt);
+ fprintf(stderr, "\n");
+#endif
+
+#else /* do an exception instead */
+ errObj = DBIncompleteError;
+#endif
+ break;
+#endif /* DBVER < 41 */
+
+ case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
+ case DB_KEYEXIST: errObj = DBKeyExistError; break;
+ case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
+ case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
+ case DB_NOTFOUND: errObj = DBNotFoundError; break;
+ case DB_OLD_VERSION: errObj = DBOldVersionError; break;
+ case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
+ case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
+ case DB_NOSERVER: errObj = DBNoServerError; break;
+ case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
+ case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
+#if (DBVER >= 33)
+ case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
+ case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
+#endif
+ case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
+
+#if (DBVER >= 43)
+ /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
+ case ENOMEM: errObj = PyExc_MemoryError; break;
+#endif
+ case EINVAL: errObj = DBInvalidArgError; break;
+ case EACCES: errObj = DBAccessError; break;
+ case ENOSPC: errObj = DBNoSpaceError; break;
+ case EAGAIN: errObj = DBAgainError; break;
+ case EBUSY : errObj = DBBusyError; break;
+ case EEXIST: errObj = DBFileExistsError; break;
+ case ENOENT: errObj = DBNoSuchFileError; break;
+ case EPERM : errObj = DBPermissionsError; break;
+
+ default: errObj = DBError; break;
+ }
+
+ if (errObj != NULL) {
+ bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
+ /* Ensure that bytes_left never goes negative */
+ if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
+ bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
+ assert(bytes_left >= 0);
+ strcat(errTxt, " -- ");
+ strncat(errTxt, _db_errmsg, bytes_left);
+ }
+ _db_errmsg[0] = 0;
+
+ errTuple = Py_BuildValue("(is)", err, errTxt);
+ PyErr_SetObject(errObj, errTuple);
+ Py_DECREF(errTuple);
+ }
+
+ return ((errObj != NULL) || exceptionRaised);
+}
+
+
+
+/* set a type exception */
+static void makeTypeError(char* expected, PyObject* found)
+{
+ PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
+ expected, found->ob_type->tp_name);
+}
+
+
+/* verify that an obj is either None or a DBTxn, and set the txn pointer */
+static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
+{
+ if (txnobj == Py_None || txnobj == NULL) {
+ *txn = NULL;
+ return 1;
+ }
+ if (DBTxnObject_Check(txnobj)) {
+ *txn = ((DBTxnObject*)txnobj)->txn;
+ return 1;
+ }
+ else
+ makeTypeError("DBTxn", txnobj);
+ return 0;
+}
+
+
+/* Delete a key from a database
+ Returns 0 on success, -1 on an error. */
+static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
+{
+ int err;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->del(self->db, txn, key, 0);
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ return -1;
+ }
+ self->haveStat = 0;
+ return 0;
+}
+
+
+/* Store a key into a database
+ Returns 0 on success, -1 on an error. */
+static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
+{
+ int err;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->put(self->db, txn, key, data, flags);
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ return -1;
+ }
+ self->haveStat = 0;
+ return 0;
+}
+
+/* Get a key/data pair from a cursor */
+static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
+ PyObject *args, PyObject *kwargs, char *format)
+{
+ int err;
+ PyObject* retval = NULL;
+ DBT key, data;
+ int dlen = -1;
+ int doff = -1;
+ int flags = 0;
+ static char* kwnames[] = { "flags", "dlen", "doff", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
+ &flags, &dlen, &doff))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ flags |= extra_flags;
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ key.flags = DB_DBT_MALLOC;
+ }
+ if (!add_partial_dbt(&data, dlen, doff))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else { /* otherwise, success! */
+
+ /* if Recno or Queue, return the key as an Int */
+ switch (_DB_get_type(self->mydb)) {
+ case -1:
+ retval = NULL;
+ break;
+
+ case DB_RECNO:
+ case DB_QUEUE:
+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
+ break;
+ case DB_HASH:
+ case DB_BTREE:
+ default:
+ retval = Py_BuildValue("s#s#", key.data, key.size,
+ data.data, data.size);
+ break;
+ }
+ }
+ if (!err) {
+ FREE_DBT(key);
+ FREE_DBT(data);
+ }
+ return retval;
+}
+
+
+/* add an integer to a dictionary using the given name as a key */
+static void _addIntToDict(PyObject* dict, char *name, int value)
+{
+ PyObject* v = PyInt_FromLong((long) value);
+ if (!v || PyDict_SetItemString(dict, name, v))
+ PyErr_Clear();
+
+ Py_XDECREF(v);
+}
+#if (DBVER >= 43)
+/* add an db_seq_t to a dictionary using the given name as a key */
+static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
+{
+ PyObject* v = PyLong_FromLongLong(value);
+ if (!v || PyDict_SetItemString(dict, name, v))
+ PyErr_Clear();
+
+ Py_XDECREF(v);
+}
+#endif
+
+
+
+/* --------------------------------------------------------------------- */
+/* Allocators and deallocators */
+
+static DBObject*
+newDBObject(DBEnvObject* arg, int flags)
+{
+ DBObject* self;
+ DB_ENV* db_env = NULL;
+ int err;
+
+ self = PyObject_New(DBObject, &DB_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->haveStat = 0;
+ self->flags = 0;
+ self->setflags = 0;
+ self->myenvobj = NULL;
+#if (DBVER >= 33)
+ self->associateCallback = NULL;
+ self->btCompareCallback = NULL;
+ self->primaryDBType = 0;
+#endif
+#ifdef HAVE_WEAKREF
+ self->in_weakreflist = NULL;
+#endif
+
+ /* keep a reference to our python DBEnv object */
+ if (arg) {
+ Py_INCREF(arg);
+ self->myenvobj = arg;
+ db_env = arg->db_env;
+ }
+
+ if (self->myenvobj)
+ self->moduleFlags = self->myenvobj->moduleFlags;
+ else
+ self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
+ self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = db_create(&self->db, db_env, flags);
+ if (self->db != NULL) {
+ self->db->set_errcall(self->db, _db_errorCallback);
+#if (DBVER >= 33)
+ self->db->app_private = (void*)self;
+#endif
+ }
+ MYDB_END_ALLOW_THREADS;
+ /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
+ * list so that a DBEnv can refuse to close without aborting any open
+ * DBTxns and closing any open DBs first. */
+ if (makeDBError(err)) {
+ if (self->myenvobj) {
+ Py_DECREF(self->myenvobj);
+ self->myenvobj = NULL;
+ }
+ PyObject_Del(self);
+ self = NULL;
+ }
+ return self;
+}
+
+
+static void
+DB_dealloc(DBObject* self)
+{
+ if (self->db != NULL) {
+ /* avoid closing a DB when its DBEnv has been closed out from under
+ * it */
+ if (!self->myenvobj ||
+ (self->myenvobj && self->myenvobj->db_env))
+ {
+ MYDB_BEGIN_ALLOW_THREADS;
+ self->db->close(self->db, 0);
+ MYDB_END_ALLOW_THREADS;
+#ifdef HAVE_WARNINGS
+ } else {
+ PyErr_Warn(PyExc_RuntimeWarning,
+ "DB could not be closed in destructor: DBEnv already closed");
+#endif
+ }
+ self->db = NULL;
+ }
+#ifdef HAVE_WEAKREF
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *) self);
+ }
+#endif
+ if (self->myenvobj) {
+ Py_DECREF(self->myenvobj);
+ self->myenvobj = NULL;
+ }
+#if (DBVER >= 33)
+ if (self->associateCallback != NULL) {
+ Py_DECREF(self->associateCallback);
+ self->associateCallback = NULL;
+ }
+ if (self->btCompareCallback != NULL) {
+ Py_DECREF(self->btCompareCallback);
+ self->btCompareCallback = NULL;
+ }
+#endif
+ PyObject_Del(self);
+}
+
+
+static DBCursorObject*
+newDBCursorObject(DBC* dbc, DBObject* db)
+{
+ DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->dbc = dbc;
+ self->mydb = db;
+#ifdef HAVE_WEAKREF
+ self->in_weakreflist = NULL;
+#endif
+ Py_INCREF(self->mydb);
+ return self;
+}
+
+
+static void
+DBCursor_dealloc(DBCursorObject* self)
+{
+ int err;
+
+#ifdef HAVE_WEAKREF
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *) self);
+ }
+#endif
+
+ if (self->dbc != NULL) {
+ MYDB_BEGIN_ALLOW_THREADS;
+ /* If the underlying database has been closed, we don't
+ need to do anything. If the environment has been closed
+ we need to leak, as BerkeleyDB will crash trying to access
+ the environment. There was an exception when the
+ user closed the environment even though there still was
+ a database open. */
+ if (self->mydb->db && self->mydb->myenvobj &&
+ !self->mydb->myenvobj->closed)
+ err = self->dbc->c_close(self->dbc);
+ self->dbc = NULL;
+ MYDB_END_ALLOW_THREADS;
+ }
+ Py_XDECREF( self->mydb );
+ PyObject_Del(self);
+}
+
+
+static DBEnvObject*
+newDBEnvObject(int flags)
+{
+ int err;
+ DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->closed = 1;
+ self->flags = flags;
+ self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
+ self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
+#ifdef HAVE_WEAKREF
+ self->in_weakreflist = NULL;
+#endif
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = db_env_create(&self->db_env, flags);
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ PyObject_Del(self);
+ self = NULL;
+ }
+ else {
+ self->db_env->set_errcall(self->db_env, _db_errorCallback);
+ }
+ return self;
+}
+
+
+static void
+DBEnv_dealloc(DBEnvObject* self)
+{
+#ifdef HAVE_WEAKREF
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *) self);
+ }
+#endif
+
+ if (self->db_env && !self->closed) {
+ MYDB_BEGIN_ALLOW_THREADS;
+ self->db_env->close(self->db_env, 0);
+ MYDB_END_ALLOW_THREADS;
+ }
+ PyObject_Del(self);
+}
+
+
+static DBTxnObject*
+newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
+{
+ int err;
+ DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
+ if (self == NULL)
+ return NULL;
+ Py_INCREF(myenv);
+ self->env = (PyObject*)myenv;
+#ifdef HAVE_WEAKREF
+ self->in_weakreflist = NULL;
+#endif
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = myenv->db_env->txn_begin(myenv->db_env, parent, &(self->txn), flags);
+#else
+ err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ Py_DECREF(self->env);
+ PyObject_Del(self);
+ self = NULL;
+ }
+ return self;
+}
+
+
+static void
+DBTxn_dealloc(DBTxnObject* self)
+{
+#ifdef HAVE_WEAKREF
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *) self);
+ }
+#endif
+
+#ifdef HAVE_WARNINGS
+ if (self->txn) {
+ /* it hasn't been finalized, abort it! */
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ self->txn->abort(self->txn);
+#else
+ txn_abort(self->txn);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ PyErr_Warn(PyExc_RuntimeWarning,
+ "DBTxn aborted in destructor. No prior commit() or abort().");
+ }
+#endif
+
+ Py_DECREF(self->env);
+ PyObject_Del(self);
+}
+
+
+static DBLockObject*
+newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
+ db_lockmode_t lock_mode, int flags)
+{
+ int err;
+ DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
+ if (self == NULL)
+ return NULL;
+#ifdef HAVE_WEAKREF
+ self->in_weakreflist = NULL;
+#endif
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
+ &self->lock);
+#else
+ err = lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ PyObject_Del(self);
+ self = NULL;
+ }
+
+ return self;
+}
+
+
+static void
+DBLock_dealloc(DBLockObject* self)
+{
+#ifdef HAVE_WEAKREF
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *) self);
+ }
+#endif
+ /* TODO: is this lock held? should we release it? */
+
+ PyObject_Del(self);
+}
+
+
+#if (DBVER >= 43)
+static DBSequenceObject*
+newDBSequenceObject(DBObject* mydb, int flags)
+{
+ int err;
+ DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
+ if (self == NULL)
+ return NULL;
+ Py_INCREF(mydb);
+ self->mydb = mydb;
+#ifdef HAVE_WEAKREF
+ self->in_weakreflist = NULL;
+#endif
+
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = db_sequence_create(&self->sequence, self->mydb->db, flags);
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ Py_DECREF(self->mydb);
+ PyObject_Del(self);
+ self = NULL;
+ }
+
+ return self;
+}
+
+
+static void
+DBSequence_dealloc(DBSequenceObject* self)
+{
+#ifdef HAVE_WEAKREF
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject *) self);
+ }
+#endif
+
+ Py_DECREF(self->mydb);
+ PyObject_Del(self);
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+/* DB methods */
+
+static PyObject*
+DB_append(DBObject* self, PyObject* args)
+{
+ PyObject* txnobj = NULL;
+ PyObject* dataobj;
+ db_recno_t recno;
+ DBT key, data;
+ DB_TXN *txn = NULL;
+
+ if (!PyArg_UnpackTuple(args, "append", 1, 2, &dataobj, &txnobj))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+
+ /* make a dummy key out of a recno */
+ recno = 0;
+ CLEAR_DBT(key);
+ key.data = &recno;
+ key.size = sizeof(recno);
+ key.ulen = key.size;
+ key.flags = DB_DBT_USERMEM;
+
+ if (!make_dbt(dataobj, &data)) return NULL;
+ if (!checkTxnObj(txnobj, &txn)) return NULL;
+
+ if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
+ return NULL;
+
+ return PyInt_FromLong(recno);
+}
+
+
+#if (DBVER >= 33)
+
+static int
+_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
+ DBT* secKey)
+{
+ int retval = DB_DONOTINDEX;
+ DBObject* secondaryDB = (DBObject*)db->app_private;
+ PyObject* callback = secondaryDB->associateCallback;
+ int type = secondaryDB->primaryDBType;
+ PyObject* args;
+ PyObject* result = NULL;
+
+
+ if (callback != NULL) {
+ MYDB_BEGIN_BLOCK_THREADS;
+
+ if (type == DB_RECNO || type == DB_QUEUE)
+ args = Py_BuildValue("(ls#)", *((db_recno_t*)priKey->data),
+ priData->data, priData->size);
+ else
+ args = Py_BuildValue("(s#s#)", priKey->data, priKey->size,
+ priData->data, priData->size);
+ if (args != NULL) {
+ result = PyEval_CallObject(callback, args);
+ }
+ if (args == NULL || result == NULL) {
+ PyErr_Print();
+ }
+ else if (result == Py_None) {
+ retval = DB_DONOTINDEX;
+ }
+ else if (PyInt_Check(result)) {
+ retval = PyInt_AsLong(result);
+ }
+ else if (PyString_Check(result)) {
+ char* data;
+ Py_ssize_t size;
+
+ CLEAR_DBT(*secKey);
+#if PYTHON_API_VERSION <= 1007
+ /* 1.5 compatibility */
+ size = PyString_Size(result);
+ data = PyString_AsString(result);
+#else
+ PyString_AsStringAndSize(result, &data, &size);
+#endif
+ secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
+ secKey->data = malloc(size); /* TODO, check this */
+ if (secKey->data) {
+ memcpy(secKey->data, data, size);
+ secKey->size = size;
+ retval = 0;
+ }
+ else {
+ PyErr_SetString(PyExc_MemoryError,
+ "malloc failed in _db_associateCallback");
+ PyErr_Print();
+ }
+ }
+ else {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "DB associate callback should return DB_DONOTINDEX or string.");
+ PyErr_Print();
+ }
+
+ Py_XDECREF(args);
+ Py_XDECREF(result);
+
+ MYDB_END_BLOCK_THREADS;
+ }
+ return retval;
+}
+
+
+static PyObject*
+DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ DBObject* secondaryDB;
+ PyObject* callback;
+#if (DBVER >= 41)
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
+ NULL};
+#else
+ static char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
+#endif
+
+#if (DBVER >= 41)
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
+ &secondaryDB, &callback, &flags,
+ &txnobj)) {
+#else
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:associate", kwnames,
+ &secondaryDB, &callback, &flags)) {
+#endif
+ return NULL;
+ }
+
+#if (DBVER >= 41)
+ if (!checkTxnObj(txnobj, &txn)) return NULL;
+#endif
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (!DBObject_Check(secondaryDB)) {
+ makeTypeError("DB", (PyObject*)secondaryDB);
+ return NULL;
+ }
+ CHECK_DB_NOT_CLOSED(secondaryDB);
+ if (callback == Py_None) {
+ callback = NULL;
+ }
+ else if (!PyCallable_Check(callback)) {
+ makeTypeError("Callable", callback);
+ return NULL;
+ }
+
+ /* Save a reference to the callback in the secondary DB. */
+ Py_XDECREF(secondaryDB->associateCallback);
+ Py_XINCREF(callback);
+ secondaryDB->associateCallback = callback;
+ secondaryDB->primaryDBType = _DB_get_type(self);
+
+ /* PyEval_InitThreads is called here due to a quirk in python 1.5
+ * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
+ * The global interepreter lock is not initialized until the first
+ * thread is created using thread.start_new_thread() or fork() is
+ * called. that would cause the ALLOW_THREADS here to segfault due
+ * to a null pointer reference if no threads or child processes
+ * have been created. This works around that and is a no-op if
+ * threads have already been initialized.
+ * (see pybsddb-users mailing list post on 2002-08-07)
+ */
+#ifdef WITH_THREAD
+ PyEval_InitThreads();
+#endif
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 41)
+ err = self->db->associate(self->db,
+ txn,
+ secondaryDB->db,
+ _db_associateCallback,
+ flags);
+#else
+ err = self->db->associate(self->db,
+ secondaryDB->db,
+ _db_associateCallback,
+ flags);
+#endif
+ MYDB_END_ALLOW_THREADS;
+
+ if (err) {
+ Py_XDECREF(secondaryDB->associateCallback);
+ secondaryDB->associateCallback = NULL;
+ secondaryDB->primaryDBType = 0;
+ }
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+#endif
+
+
+static PyObject*
+DB_close(DBObject* self, PyObject* args)
+{
+ int err, flags=0;
+ if (!PyArg_ParseTuple(args,"|i:close", &flags))
+ return NULL;
+ if (self->db != NULL) {
+ if (self->myenvobj)
+ CHECK_ENV_NOT_CLOSED(self->myenvobj);
+ err = self->db->close(self->db, flags);
+ self->db = NULL;
+ RETURN_IF_ERR();
+ }
+ RETURN_NONE();
+}
+
+
+#if (DBVER >= 32)
+static PyObject*
+_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
+{
+ int err, flags=0, type;
+ PyObject* txnobj = NULL;
+ PyObject* retval = NULL;
+ DBT key, data;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
+ &txnobj, &flags))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ type = _DB_get_type(self);
+ if (type == -1)
+ return NULL;
+ if (type != DB_QUEUE) {
+ PyErr_SetString(PyExc_TypeError,
+ "Consume methods only allowed for Queue DB's");
+ return NULL;
+ }
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ key.flags = DB_DBT_MALLOC;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
+ err = 0;
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (!err) {
+ retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
+ data.size);
+ FREE_DBT(key);
+ FREE_DBT(data);
+ }
+
+ RETURN_IF_ERR();
+ return retval;
+}
+
+static PyObject*
+DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
+{
+ return _DB_consume(self, args, kwargs, DB_CONSUME);
+}
+
+static PyObject*
+DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
+ int consume_flag)
+{
+ return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
+}
+#endif
+
+
+
+static PyObject*
+DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ DBC* dbc;
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
+ &txnobj, &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->cursor(self->db, txn, &dbc, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return (PyObject*) newDBCursorObject(dbc, self);
+}
+
+
+static PyObject*
+DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* txnobj = NULL;
+ int flags = 0;
+ PyObject* keyobj;
+ DBT key;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "key", "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
+ &keyobj, &txnobj, &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, NULL))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ if (-1 == _DB_delete(self, txn, &key, 0)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ FREE_DBT(key);
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_fd(DBObject* self, PyObject* args)
+{
+ int err, the_fd;
+
+ if (!PyArg_ParseTuple(args,":fd"))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->fd(self->db, &the_fd);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(the_fd);
+}
+
+
+static PyObject*
+DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ PyObject* txnobj = NULL;
+ PyObject* keyobj;
+ PyObject* dfltobj = NULL;
+ PyObject* retval = NULL;
+ int dlen = -1;
+ int doff = -1;
+ DBT key, data;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
+ "doff", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
+ &keyobj, &dfltobj, &txnobj, &flags, &dlen,
+ &doff))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, &flags))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ }
+ if (!add_partial_dbt(&data, dlen, doff)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get(self->db, txn, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
+ err = 0;
+ Py_INCREF(dfltobj);
+ retval = dfltobj;
+ }
+ else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
+ err = 0;
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (!err) {
+ if (flags & DB_SET_RECNO) /* return both key and data */
+ retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
+ data.size);
+ else /* return just the data */
+ retval = PyString_FromStringAndSize((char*)data.data, data.size);
+ FREE_DBT(data);
+ }
+ FREE_DBT(key);
+
+ RETURN_IF_ERR();
+ return retval;
+}
+
+#if (DBVER >= 33)
+static PyObject*
+DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ PyObject* txnobj = NULL;
+ PyObject* keyobj;
+ PyObject* dfltobj = NULL;
+ PyObject* retval = NULL;
+ int dlen = -1;
+ int doff = -1;
+ DBT key, pkey, data;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
+ "doff", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
+ &keyobj, &dfltobj, &txnobj, &flags, &dlen,
+ &doff))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, &flags))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ }
+ if (!add_partial_dbt(&data, dlen, doff)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ CLEAR_DBT(pkey);
+ pkey.flags = DB_DBT_MALLOC;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
+ err = 0;
+ Py_INCREF(dfltobj);
+ retval = dfltobj;
+ }
+ else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
+ err = 0;
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (!err) {
+ PyObject *pkeyObj;
+ PyObject *dataObj;
+ dataObj = PyString_FromStringAndSize(data.data, data.size);
+
+ if (self->primaryDBType == DB_RECNO ||
+ self->primaryDBType == DB_QUEUE)
+ pkeyObj = PyInt_FromLong(*(int *)pkey.data);
+ else
+ pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
+
+ if (flags & DB_SET_RECNO) /* return key , pkey and data */
+ {
+ PyObject *keyObj;
+ int type = _DB_get_type(self);
+ if (type == DB_RECNO || type == DB_QUEUE)
+ keyObj = PyInt_FromLong(*(int *)key.data);
+ else
+ keyObj = PyString_FromStringAndSize(key.data, key.size);
+#if (PY_VERSION_HEX >= 0x02040000)
+ retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
+#else
+ retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
+#endif
+ Py_DECREF(keyObj);
+ }
+ else /* return just the pkey and data */
+ {
+#if (PY_VERSION_HEX >= 0x02040000)
+ retval = PyTuple_Pack(2, pkeyObj, dataObj);
+#else
+ retval = Py_BuildValue("OO", pkeyObj, dataObj);
+#endif
+ }
+ Py_DECREF(dataObj);
+ Py_DECREF(pkeyObj);
+ FREE_DBT(pkey);
+ FREE_DBT(data);
+ }
+ FREE_DBT(key);
+
+ RETURN_IF_ERR();
+ return retval;
+}
+#endif
+
+
+/* Return size of entry */
+static PyObject*
+DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ PyObject* txnobj = NULL;
+ PyObject* keyobj;
+ PyObject* retval = NULL;
+ DBT key, data;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "key", "txn", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
+ &keyobj, &txnobj))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, &flags))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+ CLEAR_DBT(data);
+
+ /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
+ thus getting the record size. */
+ data.flags = DB_DBT_USERMEM;
+ data.ulen = 0;
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get(self->db, txn, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+ if (err == DB_BUFFER_SMALL) {
+ retval = PyInt_FromLong((long)data.size);
+ err = 0;
+ }
+
+ FREE_DBT(key);
+ FREE_DBT(data);
+ RETURN_IF_ERR();
+ return retval;
+}
+
+
+static PyObject*
+DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ PyObject* txnobj = NULL;
+ PyObject* keyobj;
+ PyObject* dataobj;
+ PyObject* retval = NULL;
+ DBT key, data;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
+
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
+ &keyobj, &dataobj, &txnobj, &flags))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, NULL))
+ return NULL;
+ if ( !make_dbt(dataobj, &data) ||
+ !checkTxnObj(txnobj, &txn) )
+ {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ flags |= DB_GET_BOTH;
+
+ if (CHECK_DBFLAG(self, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ /* TODO: Is this flag needed? We're passing a data object that should
+ match what's in the DB, so there should be no need to malloc.
+ We run the risk of freeing something twice! Check this. */
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get(self->db, txn, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
+ err = 0;
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (!err) {
+ retval = PyString_FromStringAndSize((char*)data.data, data.size);
+ FREE_DBT(data); /* Only if retrieval was successful */
+ }
+
+ FREE_DBT(key);
+ RETURN_IF_ERR();
+ return retval;
+}
+
+
+static PyObject*
+DB_get_byteswapped(DBObject* self, PyObject* args)
+{
+#if (DBVER >= 33)
+ int err = 0;
+#endif
+ int retval = -1;
+
+ if (!PyArg_ParseTuple(args,":get_byteswapped"))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+#if (DBVER >= 33)
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get_byteswapped(self->db, &retval);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+#else
+ MYDB_BEGIN_ALLOW_THREADS;
+ retval = self->db->get_byteswapped(self->db);
+ MYDB_END_ALLOW_THREADS;
+#endif
+ return PyInt_FromLong(retval);
+}
+
+
+static PyObject*
+DB_get_type(DBObject* self, PyObject* args)
+{
+ int type;
+
+ if (!PyArg_ParseTuple(args,":get_type"))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ type = _DB_get_type(self);
+ if (type == -1)
+ return NULL;
+ return PyInt_FromLong(type);
+}
+
+
+static PyObject*
+DB_join(DBObject* self, PyObject* args)
+{
+ int err, flags=0;
+ int length, x;
+ PyObject* cursorsObj;
+ DBC** cursors;
+ DBC* dbc;
+
+ if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+
+ if (!PySequence_Check(cursorsObj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Sequence of DBCursor objects expected");
+ return NULL;
+ }
+
+ length = PyObject_Length(cursorsObj);
+ cursors = malloc((length+1) * sizeof(DBC*));
+ if (!cursors) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ cursors[length] = NULL;
+ for (x=0; x<length; x++) {
+ PyObject* item = PySequence_GetItem(cursorsObj, x);
+ if (item == NULL) {
+ free(cursors);
+ return NULL;
+ }
+ if (!DBCursorObject_Check(item)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Sequence of DBCursor objects expected");
+ free(cursors);
+ return NULL;
+ }
+ cursors[x] = ((DBCursorObject*)item)->dbc;
+ Py_DECREF(item);
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->join(self->db, cursors, &dbc, flags);
+ MYDB_END_ALLOW_THREADS;
+ free(cursors);
+ RETURN_IF_ERR();
+
+ /* FIXME: this is a buggy interface. The returned cursor
+ contains internal references to the passed in cursors
+ but does not hold python references to them or prevent
+ them from being closed prematurely. This can cause
+ python to crash when things are done in the wrong order. */
+ return (PyObject*) newDBCursorObject(dbc, self);
+}
+
+
+static PyObject*
+DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ PyObject* txnobj = NULL;
+ PyObject* keyobj;
+ DBT key;
+ DB_TXN *txn = NULL;
+ DB_KEY_RANGE range;
+ static char* kwnames[] = { "key", "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
+ &keyobj, &txnobj, &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_dbt(keyobj, &key))
+ /* BTree only, don't need to allow for an int key */
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->key_range(self->db, txn, &key, &range, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ RETURN_IF_ERR();
+ return Py_BuildValue("ddd", range.less, range.equal, range.greater);
+}
+
+
+static PyObject*
+DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, type = DB_UNKNOWN, flags=0, mode=0660;
+ char* filename = NULL;
+ char* dbname = NULL;
+#if (DBVER >= 41)
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ /* with dbname */
+ static char* kwnames[] = {
+ "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
+ /* without dbname */
+ static char* kwnames_basic[] = {
+ "filename", "dbtype", "flags", "mode", "txn", NULL};
+#else
+ /* with dbname */
+ static char* kwnames[] = {
+ "filename", "dbname", "dbtype", "flags", "mode", NULL};
+ /* without dbname */
+ static char* kwnames_basic[] = {
+ "filename", "dbtype", "flags", "mode", NULL};
+#endif
+
+#if (DBVER >= 41)
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
+ &filename, &dbname, &type, &flags, &mode,
+ &txnobj))
+#else
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziii:open", kwnames,
+ &filename, &dbname, &type, &flags,
+ &mode))
+#endif
+ {
+ PyErr_Clear();
+ type = DB_UNKNOWN; flags = 0; mode = 0660;
+ filename = NULL; dbname = NULL;
+#if (DBVER >= 41)
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
+ kwnames_basic,
+ &filename, &type, &flags, &mode,
+ &txnobj))
+ return NULL;
+#else
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open",
+ kwnames_basic,
+ &filename, &type, &flags, &mode))
+ return NULL;
+#endif
+ }
+
+#if (DBVER >= 41)
+ if (!checkTxnObj(txnobj, &txn)) return NULL;
+#endif
+
+ if (NULL == self->db) {
+ PyObject *t = Py_BuildValue("(is)", 0,
+ "Cannot call open() twice for DB object");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return NULL;
+ }
+
+#if 0 && (DBVER >= 41)
+ if ((!txn) && (txnobj != Py_None) && self->myenvobj
+ && (self->myenvobj->flags & DB_INIT_TXN))
+ {
+ /* If no 'txn' parameter was supplied (no DbTxn object and None was not
+ * explicitly passed) but we are in a transaction ready environment:
+ * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
+ * to work on BerkeleyDB 4.1 without needing to modify their
+ * DBEnv or DB open calls.
+ * TODO make this behaviour of the library configurable.
+ */
+ flags |= DB_AUTO_COMMIT;
+ }
+#endif
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 41)
+ err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
+#else
+ err = self->db->open(self->db, filename, dbname, type, flags, mode);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ self->db->close(self->db, 0);
+ self->db = NULL;
+ return NULL;
+ }
+
+ self->flags = flags;
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int flags=0;
+ PyObject* txnobj = NULL;
+ int dlen = -1;
+ int doff = -1;
+ PyObject* keyobj, *dataobj, *retval;
+ DBT key, data;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
+ "doff", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
+ &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, NULL))
+ return NULL;
+ if ( !make_dbt(dataobj, &data) ||
+ !add_partial_dbt(&data, dlen, doff) ||
+ !checkTxnObj(txnobj, &txn) )
+ {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ if (-1 == _DB_put(self, txn, &key, &data, flags)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ if (flags & DB_APPEND)
+ retval = PyInt_FromLong(*((db_recno_t*)key.data));
+ else {
+ retval = Py_None;
+ Py_INCREF(retval);
+ }
+ FREE_DBT(key);
+ return retval;
+}
+
+
+
+static PyObject*
+DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ char* filename;
+ char* database = NULL;
+ int err, flags=0;
+ static char* kwnames[] = { "filename", "dbname", "flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
+ &filename, &database, &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ err = self->db->remove(self->db, filename, database, flags);
+ self->db = NULL;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+
+static PyObject*
+DB_rename(DBObject* self, PyObject* args)
+{
+ char* filename;
+ char* database;
+ char* newname;
+ int err, flags=0;
+
+ if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
+ &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->rename(self->db, filename, database, newname, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_bt_minkey(DBObject* self, PyObject* args)
+{
+ int err, minkey;
+
+ if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey ))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_bt_minkey(self->db, minkey);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+#if (DBVER >= 33)
+static int
+_default_cmp(const DBT *leftKey,
+ const DBT *rightKey)
+{
+ int res;
+ int lsize = leftKey->size, rsize = rightKey->size;
+
+ res = memcmp(leftKey->data, rightKey->data,
+ lsize < rsize ? lsize : rsize);
+
+ if (res == 0) {
+ if (lsize < rsize) {
+ res = -1;
+ }
+ else if (lsize > rsize) {
+ res = 1;
+ }
+ }
+ return res;
+}
+
+static int
+_db_compareCallback(DB* db,
+ const DBT *leftKey,
+ const DBT *rightKey)
+{
+ int res = 0;
+ PyObject *args;
+ PyObject *result = NULL;
+ DBObject *self = (DBObject *)db->app_private;
+
+ if (self == NULL || self->btCompareCallback == NULL) {
+ MYDB_BEGIN_BLOCK_THREADS;
+ PyErr_SetString(PyExc_TypeError,
+ (self == 0
+ ? "DB_bt_compare db is NULL."
+ : "DB_bt_compare callback is NULL."));
+ /* we're in a callback within the DB code, we can't raise */
+ PyErr_Print();
+ res = _default_cmp(leftKey, rightKey);
+ MYDB_END_BLOCK_THREADS;
+ } else {
+ MYDB_BEGIN_BLOCK_THREADS;
+
+ args = Py_BuildValue("s#s#", leftKey->data, leftKey->size,
+ rightKey->data, rightKey->size);
+ if (args != NULL) {
+ /* XXX(twouters) I highly doubt this INCREF is correct */
+ Py_INCREF(self);
+ result = PyEval_CallObject(self->btCompareCallback, args);
+ }
+ if (args == NULL || result == NULL) {
+ /* we're in a callback within the DB code, we can't raise */
+ PyErr_Print();
+ res = _default_cmp(leftKey, rightKey);
+ } else if (PyInt_Check(result)) {
+ res = PyInt_AsLong(result);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "DB_bt_compare callback MUST return an int.");
+ /* we're in a callback within the DB code, we can't raise */
+ PyErr_Print();
+ res = _default_cmp(leftKey, rightKey);
+ }
+
+ Py_XDECREF(args);
+ Py_XDECREF(result);
+
+ MYDB_END_BLOCK_THREADS;
+ }
+ return res;
+}
+
+static PyObject*
+DB_set_bt_compare(DBObject* self, PyObject* args)
+{
+ int err;
+ PyObject *comparator;
+ PyObject *tuple, *result;
+
+ if (!PyArg_ParseTuple(args, "O:set_bt_compare", &comparator))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+
+ if (!PyCallable_Check(comparator)) {
+ makeTypeError("Callable", comparator);
+ return NULL;
+ }
+
+ /*
+ * Perform a test call of the comparator function with two empty
+ * string objects here. verify that it returns an int (0).
+ * err if not.
+ */
+ tuple = Py_BuildValue("(ss)", "", "");
+ result = PyEval_CallObject(comparator, tuple);
+ Py_DECREF(tuple);
+ if (result == NULL)
+ return NULL;
+ if (!PyInt_Check(result)) {
+ PyErr_SetString(PyExc_TypeError,
+ "callback MUST return an int");
+ return NULL;
+ } else if (PyInt_AsLong(result) != 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "callback failed to return 0 on two empty strings");
+ return NULL;
+ }
+ Py_DECREF(result);
+
+ /* We don't accept multiple set_bt_compare operations, in order to
+ * simplify the code. This would have no real use, as one cannot
+ * change the function once the db is opened anyway */
+ if (self->btCompareCallback != NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
+ return NULL;
+ }
+
+ Py_INCREF(comparator);
+ self->btCompareCallback = comparator;
+
+ /* This is to workaround a problem with un-initialized threads (see
+ comment in DB_associate) */
+#ifdef WITH_THREAD
+ PyEval_InitThreads();
+#endif
+
+ err = self->db->set_bt_compare(self->db, _db_compareCallback);
+
+ if (err) {
+ /* restore the old state in case of error */
+ Py_DECREF(comparator);
+ self->btCompareCallback = NULL;
+ }
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif /* DBVER >= 33 */
+
+
+static PyObject*
+DB_set_cachesize(DBObject* self, PyObject* args)
+{
+ int err;
+ int gbytes = 0, bytes = 0, ncache = 0;
+
+ if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
+ &gbytes,&bytes,&ncache))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_flags(DBObject* self, PyObject* args)
+{
+ int err, flags;
+
+ if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_flags(self->db, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ self->setflags |= flags;
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_h_ffactor(DBObject* self, PyObject* args)
+{
+ int err, ffactor;
+
+ if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_h_ffactor(self->db, ffactor);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_h_nelem(DBObject* self, PyObject* args)
+{
+ int err, nelem;
+
+ if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_h_nelem(self->db, nelem);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_lorder(DBObject* self, PyObject* args)
+{
+ int err, lorder;
+
+ if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_lorder(self->db, lorder);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_pagesize(DBObject* self, PyObject* args)
+{
+ int err, pagesize;
+
+ if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_pagesize(self->db, pagesize);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_re_delim(DBObject* self, PyObject* args)
+{
+ int err;
+ char delim;
+
+ if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
+ return NULL;
+ }
+
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_re_delim(self->db, delim);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DB_set_re_len(DBObject* self, PyObject* args)
+{
+ int err, len;
+
+ if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_re_len(self->db, len);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_re_pad(DBObject* self, PyObject* args)
+{
+ int err;
+ char pad;
+
+ if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
+ return NULL;
+ }
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_re_pad(self->db, pad);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_re_source(DBObject* self, PyObject* args)
+{
+ int err;
+ char *re_source;
+
+ if (!PyArg_ParseTuple(args,"s:set_re_source", &re_source))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_re_source(self->db, re_source);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+#if (DBVER >= 32)
+static PyObject*
+DB_set_q_extentsize(DBObject* self, PyObject* args)
+{
+ int err;
+ int extentsize;
+
+ if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_q_extentsize(self->db, extentsize);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+static PyObject*
+DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0, type;
+ void* sp;
+ PyObject* d;
+#if (DBVER >= 43)
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "flags", "txn", NULL };
+#else
+ static char* kwnames[] = { "flags", NULL };
+#endif
+
+#if (DBVER >= 43)
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
+ &flags, &txnobj))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+#else
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
+ return NULL;
+#endif
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 43)
+ err = self->db->stat(self->db, txn, &sp, flags);
+#elif (DBVER >= 33)
+ err = self->db->stat(self->db, &sp, flags);
+#else
+ err = self->db->stat(self->db, &sp, NULL, flags);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ self->haveStat = 1;
+
+ /* Turn the stat structure into a dictionary */
+ type = _DB_get_type(self);
+ if ((type == -1) || ((d = PyDict_New()) == NULL)) {
+ free(sp);
+ return NULL;
+ }
+
+#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
+#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
+#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
+
+ switch (type) {
+ case DB_HASH:
+ MAKE_HASH_ENTRY(magic);
+ MAKE_HASH_ENTRY(version);
+ MAKE_HASH_ENTRY(nkeys);
+ MAKE_HASH_ENTRY(ndata);
+ MAKE_HASH_ENTRY(pagesize);
+#if (DBVER < 41)
+ MAKE_HASH_ENTRY(nelem);
+#endif
+ MAKE_HASH_ENTRY(ffactor);
+ MAKE_HASH_ENTRY(buckets);
+ MAKE_HASH_ENTRY(free);
+ MAKE_HASH_ENTRY(bfree);
+ MAKE_HASH_ENTRY(bigpages);
+ MAKE_HASH_ENTRY(big_bfree);
+ MAKE_HASH_ENTRY(overflows);
+ MAKE_HASH_ENTRY(ovfl_free);
+ MAKE_HASH_ENTRY(dup);
+ MAKE_HASH_ENTRY(dup_free);
+ break;
+
+ case DB_BTREE:
+ case DB_RECNO:
+ MAKE_BT_ENTRY(magic);
+ MAKE_BT_ENTRY(version);
+ MAKE_BT_ENTRY(nkeys);
+ MAKE_BT_ENTRY(ndata);
+ MAKE_BT_ENTRY(pagesize);
+ MAKE_BT_ENTRY(minkey);
+ MAKE_BT_ENTRY(re_len);
+ MAKE_BT_ENTRY(re_pad);
+ MAKE_BT_ENTRY(levels);
+ MAKE_BT_ENTRY(int_pg);
+ MAKE_BT_ENTRY(leaf_pg);
+ MAKE_BT_ENTRY(dup_pg);
+ MAKE_BT_ENTRY(over_pg);
+ MAKE_BT_ENTRY(free);
+ MAKE_BT_ENTRY(int_pgfree);
+ MAKE_BT_ENTRY(leaf_pgfree);
+ MAKE_BT_ENTRY(dup_pgfree);
+ MAKE_BT_ENTRY(over_pgfree);
+ break;
+
+ case DB_QUEUE:
+ MAKE_QUEUE_ENTRY(magic);
+ MAKE_QUEUE_ENTRY(version);
+ MAKE_QUEUE_ENTRY(nkeys);
+ MAKE_QUEUE_ENTRY(ndata);
+ MAKE_QUEUE_ENTRY(pagesize);
+ MAKE_QUEUE_ENTRY(pages);
+ MAKE_QUEUE_ENTRY(re_len);
+ MAKE_QUEUE_ENTRY(re_pad);
+ MAKE_QUEUE_ENTRY(pgfree);
+#if (DBVER == 31)
+ MAKE_QUEUE_ENTRY(start);
+#endif
+ MAKE_QUEUE_ENTRY(first_recno);
+ MAKE_QUEUE_ENTRY(cur_recno);
+ break;
+
+ default:
+ PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
+ Py_DECREF(d);
+ d = NULL;
+ }
+
+#undef MAKE_HASH_ENTRY
+#undef MAKE_BT_ENTRY
+#undef MAKE_QUEUE_ENTRY
+
+ free(sp);
+ return d;
+}
+
+static PyObject*
+DB_sync(DBObject* self, PyObject* args)
+{
+ int err;
+ int flags = 0;
+
+ if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->sync(self->db, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+#if (DBVER >= 33)
+static PyObject*
+DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ u_int32_t count=0;
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
+ &txnobj, &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->truncate(self->db, txn, &count, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(count);
+}
+#endif
+
+
+static PyObject*
+DB_upgrade(DBObject* self, PyObject* args)
+{
+ int err, flags=0;
+ char *filename;
+
+ if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->upgrade(self->db, filename, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags=0;
+ char* fileName;
+ char* dbName=NULL;
+ char* outFileName=NULL;
+ FILE* outFile=NULL;
+ static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
+ NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
+ &fileName, &dbName, &outFileName, &flags))
+ return NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (outFileName)
+ outFile = fopen(outFileName, "w");
+ /* XXX(nnorwitz): it should probably be an exception if outFile
+ can't be opened. */
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->verify(self->db, fileName, dbName, outFile, flags);
+ MYDB_END_ALLOW_THREADS;
+ if (outFile)
+ fclose(outFile);
+
+ /* DB.verify acts as a DB handle destructor (like close); this was
+ * documented in BerkeleyDB 4.2 but had the undocumented effect
+ * of not being safe in prior versions while still requiring an explicit
+ * DB.close call afterwards. Lets call close for the user to emulate
+ * the safe 4.2 behaviour. */
+#if (DBVER <= 41)
+ self->db->close(self->db, 0);
+#endif
+ self->db = NULL;
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DB_set_get_returns_none(DBObject* self, PyObject* args)
+{
+ int flags=0;
+ int oldValue=0;
+
+ if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+
+ if (self->moduleFlags.getReturnsNone)
+ ++oldValue;
+ if (self->moduleFlags.cursorSetReturnsNone)
+ ++oldValue;
+ self->moduleFlags.getReturnsNone = (flags >= 1);
+ self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
+ return PyInt_FromLong(oldValue);
+}
+
+#if (DBVER >= 41)
+static PyObject*
+DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ u_int32_t flags=0;
+ char *passwd = NULL;
+ static char* kwnames[] = { "passwd", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
+ &passwd, &flags)) {
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->set_encrypt(self->db, passwd, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif /* DBVER >= 41 */
+
+
+/*-------------------------------------------------------------- */
+/* Mapping and Dictionary-like access routines */
+
+Py_ssize_t DB_length(PyObject* _self)
+{
+ int err;
+ Py_ssize_t size = 0;
+ int flags = 0;
+ void* sp;
+ DBObject* self = (DBObject*)_self;
+
+ if (self->db == NULL) {
+ PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return -1;
+ }
+
+ if (self->haveStat) { /* Has the stat function been called recently? If
+ so, we can use the cached value. */
+ flags = DB_FAST_STAT;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+redo_stat_for_length:
+#if (DBVER >= 43)
+ err = self->db->stat(self->db, /*txnid*/ NULL, &sp, flags);
+#elif (DBVER >= 33)
+ err = self->db->stat(self->db, &sp, flags);
+#else
+ err = self->db->stat(self->db, &sp, NULL, flags);
+#endif
+
+ /* All the stat structures have matching fields upto the ndata field,
+ so we can use any of them for the type cast */
+ size = ((DB_BTREE_STAT*)sp)->bt_ndata;
+
+ /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
+ * redo a full stat to make sure.
+ * Fixes SF python bug 1493322, pybsddb bug 1184012
+ */
+ if (size == 0 && (flags & DB_FAST_STAT)) {
+ flags = 0;
+ if (!err)
+ free(sp);
+ goto redo_stat_for_length;
+ }
+
+ MYDB_END_ALLOW_THREADS;
+
+ if (err)
+ return -1;
+
+ self->haveStat = 1;
+
+ free(sp);
+ return size;
+}
+
+
+PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
+{
+ int err;
+ PyObject* retval;
+ DBT key;
+ DBT data;
+
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, NULL))
+ return NULL;
+
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ }
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get(self->db, NULL, &key, &data, 0);
+ MYDB_END_ALLOW_THREADS;
+ if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
+ PyErr_SetObject(PyExc_KeyError, keyobj);
+ retval = NULL;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ retval = PyString_FromStringAndSize((char*)data.data, data.size);
+ FREE_DBT(data);
+ }
+
+ FREE_DBT(key);
+ return retval;
+}
+
+
+static int
+DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
+{
+ DBT key, data;
+ int retval;
+ int flags = 0;
+
+ if (self->db == NULL) {
+ PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return -1;
+ }
+
+ if (!make_key_dbt(self, keyobj, &key, NULL))
+ return -1;
+
+ if (dataobj != NULL) {
+ if (!make_dbt(dataobj, &data))
+ retval = -1;
+ else {
+ if (self->setflags & (DB_DUP|DB_DUPSORT))
+ /* dictionaries shouldn't have duplicate keys */
+ flags = DB_NOOVERWRITE;
+ retval = _DB_put(self, NULL, &key, &data, flags);
+
+ if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
+ /* try deleting any old record that matches and then PUT it
+ * again... */
+ _DB_delete(self, NULL, &key, 0);
+ PyErr_Clear();
+ retval = _DB_put(self, NULL, &key, &data, flags);
+ }
+ }
+ }
+ else {
+ /* dataobj == NULL, so delete the key */
+ retval = _DB_delete(self, NULL, &key, 0);
+ }
+ FREE_DBT(key);
+ return retval;
+}
+
+
+static PyObject*
+DB_has_key(DBObject* self, PyObject* args)
+{
+ int err;
+ PyObject* keyobj;
+ DBT key, data;
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+
+ if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
+ return NULL;
+ CHECK_DB_NOT_CLOSED(self);
+ if (!make_key_dbt(self, keyobj, &key, NULL))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
+ it has a record but can't allocate a buffer for the data. This saves
+ having to deal with data we won't be using.
+ */
+ CLEAR_DBT(data);
+ data.flags = DB_DBT_USERMEM;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->get(self->db, txn, &key, &data, 0);
+ MYDB_END_ALLOW_THREADS;
+ FREE_DBT(key);
+
+ if (err == DB_BUFFER_SMALL || err == 0) {
+ return PyInt_FromLong(1);
+ } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
+ return PyInt_FromLong(0);
+ }
+
+ makeDBError(err);
+ return NULL;
+}
+
+
+#define _KEYS_LIST 1
+#define _VALUES_LIST 2
+#define _ITEMS_LIST 3
+
+static PyObject*
+_DB_make_list(DBObject* self, DB_TXN* txn, int type)
+{
+ int err, dbtype;
+ DBT key;
+ DBT data;
+ DBC *cursor;
+ PyObject* list;
+ PyObject* item = NULL;
+
+ CHECK_DB_NOT_CLOSED(self);
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+
+ dbtype = _DB_get_type(self);
+ if (dbtype == -1)
+ return NULL;
+
+ list = PyList_New(0);
+ if (list == NULL)
+ return NULL;
+
+ /* get a cursor */
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db->cursor(self->db, txn, &cursor, 0);
+ MYDB_END_ALLOW_THREADS;
+ if (makeDBError(err)) {
+ Py_DECREF(list);
+ return NULL;
+ }
+
+ if (CHECK_DBFLAG(self, DB_THREAD)) {
+ key.flags = DB_DBT_REALLOC;
+ data.flags = DB_DBT_REALLOC;
+ }
+
+ while (1) { /* use the cursor to traverse the DB, collecting items */
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = cursor->c_get(cursor, &key, &data, DB_NEXT);
+ MYDB_END_ALLOW_THREADS;
+
+ if (err) {
+ /* for any error, break out of the loop */
+ break;
+ }
+
+ switch (type) {
+ case _KEYS_LIST:
+ switch(dbtype) {
+ case DB_BTREE:
+ case DB_HASH:
+ default:
+ item = PyString_FromStringAndSize((char*)key.data, key.size);
+ break;
+ case DB_RECNO:
+ case DB_QUEUE:
+ item = PyInt_FromLong(*((db_recno_t*)key.data));
+ break;
+ }
+ break;
+
+ case _VALUES_LIST:
+ item = PyString_FromStringAndSize((char*)data.data, data.size);
+ break;
+
+ case _ITEMS_LIST:
+ switch(dbtype) {
+ case DB_BTREE:
+ case DB_HASH:
+ default:
+ item = Py_BuildValue("s#s#", key.data, key.size, data.data,
+ data.size);
+ break;
+ case DB_RECNO:
+ case DB_QUEUE:
+ item = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
+ break;
+ }
+ break;
+ default:
+ PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
+ item = NULL;
+ break;
+ }
+ if (item == NULL) {
+ Py_DECREF(list);
+ list = NULL;
+ goto done;
+ }
+ PyList_Append(list, item);
+ Py_DECREF(item);
+ }
+
+ /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
+ if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
+ Py_DECREF(list);
+ list = NULL;
+ }
+
+ done:
+ FREE_DBT(key);
+ FREE_DBT(data);
+ MYDB_BEGIN_ALLOW_THREADS;
+ cursor->c_close(cursor);
+ MYDB_END_ALLOW_THREADS;
+ return list;
+}
+
+
+static PyObject*
+DB_keys(DBObject* self, PyObject* args)
+{
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+
+ if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+ return _DB_make_list(self, txn, _KEYS_LIST);
+}
+
+
+static PyObject*
+DB_items(DBObject* self, PyObject* args)
+{
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+
+ if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+ return _DB_make_list(self, txn, _ITEMS_LIST);
+}
+
+
+static PyObject*
+DB_values(DBObject* self, PyObject* args)
+{
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+
+ if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
+ return NULL;
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+ return _DB_make_list(self, txn, _VALUES_LIST);
+}
+
+/* --------------------------------------------------------------------- */
+/* DBCursor methods */
+
+
+static PyObject*
+DBC_close(DBCursorObject* self, PyObject* args)
+{
+ int err = 0;
+
+ if (!PyArg_ParseTuple(args, ":close"))
+ return NULL;
+
+ if (self->dbc != NULL) {
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_close(self->dbc);
+ self->dbc = NULL;
+ MYDB_END_ALLOW_THREADS;
+ }
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBC_count(DBCursorObject* self, PyObject* args)
+{
+ int err = 0;
+ db_recno_t count;
+ int flags = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:count", &flags))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_count(self->dbc, &count, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ return PyInt_FromLong(count);
+}
+
+
+static PyObject*
+DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
+}
+
+
+static PyObject*
+DBC_delete(DBCursorObject* self, PyObject* args)
+{
+ int err, flags=0;
+
+ if (!PyArg_ParseTuple(args, "|i:delete", &flags))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_del(self->dbc, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ self->mydb->haveStat = 0;
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBC_dup(DBCursorObject* self, PyObject* args)
+{
+ int err, flags =0;
+ DBC* dbc = NULL;
+
+ if (!PyArg_ParseTuple(args, "|i:dup", &flags))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_dup(self->dbc, &dbc, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ return (PyObject*) newDBCursorObject(dbc, self->mydb);
+}
+
+static PyObject*
+DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
+{
+ return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
+}
+
+
+static PyObject*
+DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ int err, flags=0;
+ PyObject* keyobj = NULL;
+ PyObject* dataobj = NULL;
+ PyObject* retval = NULL;
+ int dlen = -1;
+ int doff = -1;
+ DBT key, data;
+ static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
+ NULL };
+
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
+ &flags, &dlen, &doff))
+ {
+ PyErr_Clear();
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
+ &kwnames[1],
+ &keyobj, &flags, &dlen, &doff))
+ {
+ PyErr_Clear();
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
+ kwnames, &keyobj, &dataobj,
+ &flags, &dlen, &doff))
+ {
+ return NULL;
+ }
+ }
+ }
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+ if ( (dataobj && !make_dbt(dataobj, &data)) ||
+ (!add_partial_dbt(&data, dlen, doff)) )
+ {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ data.flags = DB_DBT_MALLOC;
+ if (!(key.flags & DB_DBT_REALLOC)) {
+ key.flags |= DB_DBT_MALLOC;
+ }
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ switch (_DB_get_type(self->mydb)) {
+ case -1:
+ retval = NULL;
+ break;
+ case DB_BTREE:
+ case DB_HASH:
+ default:
+ retval = Py_BuildValue("s#s#", key.data, key.size,
+ data.data, data.size);
+ break;
+ case DB_RECNO:
+ case DB_QUEUE:
+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
+ break;
+ }
+ FREE_DBT(data);
+ }
+ FREE_DBT(key);
+ return retval;
+}
+
+#if (DBVER >= 33)
+static PyObject*
+DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ int err, flags=0;
+ PyObject* keyobj = NULL;
+ PyObject* dataobj = NULL;
+ PyObject* retval = NULL;
+ int dlen = -1;
+ int doff = -1;
+ DBT key, pkey, data;
+ static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
+ static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
+
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
+ &flags, &dlen, &doff))
+ {
+ PyErr_Clear();
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
+ kwnames_keyOnly,
+ &keyobj, &flags, &dlen, &doff))
+ {
+ PyErr_Clear();
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
+ kwnames, &keyobj, &dataobj,
+ &flags, &dlen, &doff))
+ {
+ return NULL;
+ }
+ }
+ }
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+ if ( (dataobj && !make_dbt(dataobj, &data)) ||
+ (!add_partial_dbt(&data, dlen, doff)) ) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ data.flags = DB_DBT_MALLOC;
+ if (!(key.flags & DB_DBT_REALLOC)) {
+ key.flags |= DB_DBT_MALLOC;
+ }
+ }
+
+ CLEAR_DBT(pkey);
+ pkey.flags = DB_DBT_MALLOC;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ PyObject *pkeyObj;
+ PyObject *dataObj;
+ dataObj = PyString_FromStringAndSize(data.data, data.size);
+
+ if (self->mydb->primaryDBType == DB_RECNO ||
+ self->mydb->primaryDBType == DB_QUEUE)
+ pkeyObj = PyInt_FromLong(*(int *)pkey.data);
+ else
+ pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
+
+ if (key.data && key.size) /* return key, pkey and data */
+ {
+ PyObject *keyObj;
+ int type = _DB_get_type(self->mydb);
+ if (type == DB_RECNO || type == DB_QUEUE)
+ keyObj = PyInt_FromLong(*(int *)key.data);
+ else
+ keyObj = PyString_FromStringAndSize(key.data, key.size);
+#if (PY_VERSION_HEX >= 0x02040000)
+ retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
+#else
+ retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
+#endif
+ Py_DECREF(keyObj);
+ FREE_DBT(key);
+ }
+ else /* return just the pkey and data */
+ {
+#if (PY_VERSION_HEX >= 0x02040000)
+ retval = PyTuple_Pack(2, pkeyObj, dataObj);
+#else
+ retval = Py_BuildValue("OO", pkeyObj, dataObj);
+#endif
+ }
+ Py_DECREF(dataObj);
+ Py_DECREF(pkeyObj);
+ FREE_DBT(pkey);
+ FREE_DBT(data);
+ }
+ /* the only time REALLOC should be set is if we used an integer
+ * key that make_key_dbt malloc'd for us. always free these. */
+ if (key.flags & DB_DBT_REALLOC) {
+ FREE_DBT(key);
+ }
+ return retval;
+}
+#endif
+
+
+static PyObject*
+DBC_get_recno(DBCursorObject* self, PyObject* args)
+{
+ int err;
+ db_recno_t recno;
+ DBT key;
+ DBT data;
+
+ if (!PyArg_ParseTuple(args, ":get_recno"))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ key.flags = DB_DBT_MALLOC;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, DB_GET_RECNO);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ recno = *((db_recno_t*)data.data);
+ FREE_DBT(key);
+ FREE_DBT(data);
+ return PyInt_FromLong(recno);
+}
+
+
+static PyObject*
+DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
+}
+
+
+static PyObject*
+DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
+}
+
+
+static PyObject*
+DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
+}
+
+
+static PyObject*
+DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0;
+ PyObject* keyobj, *dataobj;
+ DBT key, data;
+ static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
+ NULL };
+ int dlen = -1;
+ int doff = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
+ &keyobj, &dataobj, &flags, &dlen, &doff))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+ if (!make_dbt(dataobj, &data) ||
+ !add_partial_dbt(&data, dlen, doff) )
+ {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_put(self->dbc, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+ FREE_DBT(key);
+ RETURN_IF_ERR();
+ self->mydb->haveStat = 0;
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ int err, flags = 0;
+ DBT key, data;
+ PyObject* retval, *keyobj;
+ static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
+ int dlen = -1;
+ int doff = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
+ &keyobj, &flags, &dlen, &doff))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ }
+ if (!add_partial_dbt(&data, dlen, doff)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
+ MYDB_END_ALLOW_THREADS;
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ switch (_DB_get_type(self->mydb)) {
+ case -1:
+ retval = NULL;
+ break;
+ case DB_BTREE:
+ case DB_HASH:
+ default:
+ retval = Py_BuildValue("s#s#", key.data, key.size,
+ data.data, data.size);
+ break;
+ case DB_RECNO:
+ case DB_QUEUE:
+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
+ break;
+ }
+ FREE_DBT(data);
+ FREE_DBT(key);
+ }
+ /* the only time REALLOC should be set is if we used an integer
+ * key that make_key_dbt malloc'd for us. always free these. */
+ if (key.flags & DB_DBT_REALLOC) {
+ FREE_DBT(key);
+ }
+
+ return retval;
+}
+
+
+static PyObject*
+DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0;
+ DBT key, data;
+ PyObject* retval, *keyobj;
+ static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
+ int dlen = -1;
+ int doff = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
+ &keyobj, &flags, &dlen, &doff))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+
+ CLEAR_DBT(data);
+ if (!add_partial_dbt(&data, dlen, doff)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags |= DB_DBT_MALLOC;
+ /* only BTREE databases will return anything in the key */
+ if (!(key.flags & DB_DBT_REALLOC) && _DB_get_type(self->mydb) == DB_BTREE) {
+ key.flags |= DB_DBT_MALLOC;
+ }
+ }
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
+ MYDB_END_ALLOW_THREADS;
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ switch (_DB_get_type(self->mydb)) {
+ case -1:
+ retval = NULL;
+ break;
+ case DB_BTREE:
+ case DB_HASH:
+ default:
+ retval = Py_BuildValue("s#s#", key.data, key.size,
+ data.data, data.size);
+ break;
+ case DB_RECNO:
+ case DB_QUEUE:
+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
+ break;
+ }
+ FREE_DBT(key);
+ FREE_DBT(data);
+ }
+ /* the only time REALLOC should be set is if we used an integer
+ * key that make_key_dbt malloc'd for us. always free these. */
+ if (key.flags & DB_DBT_REALLOC) {
+ FREE_DBT(key);
+ }
+
+ return retval;
+}
+
+static PyObject*
+_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
+ int flags, unsigned int returnsNone)
+{
+ int err;
+ DBT key, data;
+ PyObject* retval;
+
+ /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+ if (!make_dbt(dataobj, &data)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
+ MYDB_END_ALLOW_THREADS;
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ switch (_DB_get_type(self->mydb)) {
+ case -1:
+ retval = NULL;
+ break;
+ case DB_BTREE:
+ case DB_HASH:
+ default:
+ retval = Py_BuildValue("s#s#", key.data, key.size,
+ data.data, data.size);
+ break;
+ case DB_RECNO:
+ case DB_QUEUE:
+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
+ break;
+ }
+ }
+
+ FREE_DBT(key);
+ return retval;
+}
+
+static PyObject*
+DBC_get_both(DBCursorObject* self, PyObject* args)
+{
+ int flags=0;
+ PyObject *keyobj, *dataobj;
+
+ if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
+ return NULL;
+
+ /* if the cursor is closed, self->mydb may be invalid */
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ return _DBC_get_set_both(self, keyobj, dataobj, flags,
+ self->mydb->moduleFlags.getReturnsNone);
+}
+
+/* Return size of entry */
+static PyObject*
+DBC_get_current_size(DBCursorObject* self, PyObject* args)
+{
+ int err, flags=DB_CURRENT;
+ PyObject* retval = NULL;
+ DBT key, data;
+
+ if (!PyArg_ParseTuple(args, ":get_current_size"))
+ return NULL;
+ CHECK_CURSOR_NOT_CLOSED(self);
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+
+ /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
+ getting the record size. */
+ data.flags = DB_DBT_USERMEM;
+ data.ulen = 0;
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags);
+ MYDB_END_ALLOW_THREADS;
+ if (err == DB_BUFFER_SMALL || !err) {
+ /* DB_BUFFER_SMALL means positive size, !err means zero length value */
+ retval = PyInt_FromLong((long)data.size);
+ err = 0;
+ }
+
+ FREE_DBT(key);
+ FREE_DBT(data);
+ RETURN_IF_ERR();
+ return retval;
+}
+
+static PyObject*
+DBC_set_both(DBCursorObject* self, PyObject* args)
+{
+ int flags=0;
+ PyObject *keyobj, *dataobj;
+
+ if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
+ return NULL;
+
+ /* if the cursor is closed, self->mydb may be invalid */
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ return _DBC_get_set_both(self, keyobj, dataobj, flags,
+ self->mydb->moduleFlags.cursorSetReturnsNone);
+}
+
+
+static PyObject*
+DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ int err, irecno, flags=0;
+ db_recno_t recno;
+ DBT key, data;
+ PyObject* retval;
+ int dlen = -1;
+ int doff = -1;
+ static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
+ &irecno, &flags, &dlen, &doff))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ CLEAR_DBT(key);
+ recno = (db_recno_t) irecno;
+ /* use allocated space so DB will be able to realloc room for the real
+ * key */
+ key.data = malloc(sizeof(db_recno_t));
+ if (key.data == NULL) {
+ PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
+ return NULL;
+ }
+ key.size = sizeof(db_recno_t);
+ key.ulen = key.size;
+ memcpy(key.data, &recno, sizeof(db_recno_t));
+ key.flags = DB_DBT_REALLOC;
+
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ data.flags = DB_DBT_MALLOC;
+ }
+ if (!add_partial_dbt(&data, dlen, doff)) {
+ FREE_DBT(key);
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
+ MYDB_END_ALLOW_THREADS;
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else { /* Can only be used for BTrees, so no need to return int key */
+ retval = Py_BuildValue("s#s#", key.data, key.size,
+ data.data, data.size);
+ FREE_DBT(data);
+ }
+ FREE_DBT(key);
+
+ return retval;
+}
+
+
+static PyObject*
+DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
+}
+
+
+static PyObject*
+DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
+}
+
+
+static PyObject*
+DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
+}
+
+
+static PyObject*
+DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
+{
+ return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
+}
+
+
+static PyObject*
+DBC_join_item(DBCursorObject* self, PyObject* args)
+{
+ int err, flags=0;
+ DBT key, data;
+ PyObject* retval;
+
+ if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
+ return NULL;
+
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ CLEAR_DBT(key);
+ CLEAR_DBT(data);
+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ key.flags = DB_DBT_MALLOC;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
+ MYDB_END_ALLOW_THREADS;
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+ else if (makeDBError(err)) {
+ retval = NULL;
+ }
+ else {
+ retval = Py_BuildValue("s#", key.data, key.size);
+ FREE_DBT(key);
+ }
+
+ return retval;
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* DBEnv methods */
+
+
+static PyObject*
+DBEnv_close(DBEnvObject* self, PyObject* args)
+{
+ int err, flags = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:close", &flags))
+ return NULL;
+ if (!self->closed) { /* Don't close more than once */
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->close(self->db_env, flags);
+ MYDB_END_ALLOW_THREADS;
+ /* after calling DBEnv->close, regardless of error, this DBEnv
+ * may not be accessed again (BerkeleyDB docs). */
+ self->closed = 1;
+ self->db_env = NULL;
+ RETURN_IF_ERR();
+ }
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_open(DBEnvObject* self, PyObject* args)
+{
+ int err, flags=0, mode=0660;
+ char *db_home;
+
+ if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
+ return NULL;
+
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->open(self->db_env, db_home, flags, mode);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ self->closed = 0;
+ self->flags = flags;
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_remove(DBEnvObject* self, PyObject* args)
+{
+ int err, flags=0;
+ char *db_home;
+
+ if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->remove(self->db_env, db_home, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+#if (DBVER >= 41)
+static PyObject*
+DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ u_int32_t flags=0;
+ char *file = NULL;
+ char *database = NULL;
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "file", "database", "txn", "flags",
+ NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
+ &file, &database, &txnobj, &flags)) {
+ return NULL;
+ }
+ if (!checkTxnObj(txnobj, &txn)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ u_int32_t flags=0;
+ char *file = NULL;
+ char *database = NULL;
+ char *newname = NULL;
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "file", "database", "newname", "txn",
+ "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
+ &file, &database, &newname, &txnobj, &flags)) {
+ return NULL;
+ }
+ if (!checkTxnObj(txnobj, &txn)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
+ flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ u_int32_t flags=0;
+ char *passwd = NULL;
+ static char* kwnames[] = { "passwd", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
+ &passwd, &flags)) {
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_encrypt(self->db_env, passwd, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif /* DBVER >= 41 */
+
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ u_int32_t flags=0;
+ u_int32_t timeout = 0;
+ static char* kwnames[] = { "timeout", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
+ &timeout, &flags)) {
+ return NULL;
+ }
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
+ MYDB_END_ALLOW_THREADS;
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif /* DBVER >= 40 */
+
+static PyObject*
+DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ long shm_key = 0;
+
+ if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ err = self->db_env->set_shm_key(self->db_env, shm_key);
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
+{
+ int err, gbytes=0, bytes=0, ncache=0;
+
+ if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
+ &gbytes, &bytes, &ncache))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+#if (DBVER >= 32)
+static PyObject*
+DBEnv_set_flags(DBEnvObject* self, PyObject* args)
+{
+ int err, flags=0, onoff=0;
+
+ if (!PyArg_ParseTuple(args, "ii:set_flags",
+ &flags, &onoff))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_flags(self->db_env, flags, onoff);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+
+static PyObject*
+DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ char *dir;
+
+ if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_data_dir(self->db_env, dir);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
+{
+ int err, lg_bsize;
+
+ if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ char *dir;
+
+ if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lg_dir(self->db_env, dir);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
+{
+ int err, lg_max;
+
+ if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lg_max(self->db_env, lg_max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+#if (DBVER >= 33)
+static PyObject*
+DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
+{
+ int err, lg_max;
+
+ if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+
+static PyObject*
+DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
+{
+ int err, lk_detect;
+
+ if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lk_detect(self->db_env, lk_detect);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+#if (DBVER < 45)
+static PyObject*
+DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
+{
+ int err, max;
+
+ if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lk_max(self->db_env, max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+
+#if (DBVER >= 32)
+
+static PyObject*
+DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
+{
+ int err, max;
+
+ if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lk_max_locks(self->db_env, max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
+{
+ int err, max;
+
+ if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lk_max_lockers(self->db_env, max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
+{
+ int err, max;
+
+ if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_lk_max_objects(self->db_env, max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+#endif
+
+
+static PyObject*
+DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
+{
+ int err, mp_mmapsize;
+
+ if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ char *dir;
+
+ if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_tmp_dir(self->db_env, dir);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int flags = 0;
+ PyObject* txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = { "parent", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
+ &txnobj, &flags))
+ return NULL;
+
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ return (PyObject*)newDBTxnObject(self, txn, flags);
+}
+
+
+static PyObject*
+DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
+{
+ int err, kbyte=0, min=0, flags=0;
+
+ if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
+#else
+ err = txn_checkpoint(self->db_env, kbyte, min, flags);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
+{
+ int err, max;
+
+ if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ err = self->db_env->set_tx_max(self->db_env, max);
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ long stamp;
+ time_t timestamp;
+
+ if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+ timestamp = (time_t)stamp;
+ err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
+{
+ int err, atype, flags=0;
+ int aborted = 0;
+
+ if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
+#else
+ err = lock_detect(self->db_env, flags, atype, &aborted);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(aborted);
+}
+
+
+static PyObject*
+DBEnv_lock_get(DBEnvObject* self, PyObject* args)
+{
+ int flags=0;
+ int locker, lock_mode;
+ DBT obj;
+ PyObject* objobj;
+
+ if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
+ return NULL;
+
+
+ if (!make_dbt(objobj, &obj))
+ return NULL;
+
+ return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
+}
+
+
+static PyObject*
+DBEnv_lock_id(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ u_int32_t theID;
+
+ if (!PyArg_ParseTuple(args, ":lock_id"))
+ return NULL;
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->lock_id(self->db_env, &theID);
+#else
+ err = lock_id(self->db_env, &theID);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ return PyInt_FromLong((long)theID);
+}
+
+
+static PyObject*
+DBEnv_lock_put(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ DBLockObject* dblockobj;
+
+ if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
+ return NULL;
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
+#else
+ err = lock_put(self->db_env, &dblockobj->lock);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+#if (DBVER >= 44)
+static PyObject*
+DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ char *file;
+ u_int32_t flags = 0;
+ static char* kwnames[] = { "file", "flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
+ &file, &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->lsn_reset(self->db_env, file, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif /* DBVER >= 4.4 */
+
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_log_stat(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ DB_LOG_STAT* statp = NULL;
+ PyObject* d = NULL;
+ u_int32_t flags = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->log_stat(self->db_env, &statp, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ /* Turn the stat structure into a dictionary */
+ d = PyDict_New();
+ if (d == NULL) {
+ if (statp)
+ free(statp);
+ return NULL;
+ }
+
+#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
+
+ MAKE_ENTRY(magic);
+ MAKE_ENTRY(version);
+ MAKE_ENTRY(mode);
+ MAKE_ENTRY(lg_bsize);
+#if (DBVER >= 44)
+ MAKE_ENTRY(lg_size);
+ MAKE_ENTRY(record);
+#endif
+#if (DBVER <= 40)
+ MAKE_ENTRY(lg_max);
+#endif
+ MAKE_ENTRY(w_mbytes);
+ MAKE_ENTRY(w_bytes);
+ MAKE_ENTRY(wc_mbytes);
+ MAKE_ENTRY(wc_bytes);
+ MAKE_ENTRY(wcount);
+ MAKE_ENTRY(wcount_fill);
+#if (DBVER >= 44)
+ MAKE_ENTRY(rcount);
+#endif
+ MAKE_ENTRY(scount);
+ MAKE_ENTRY(cur_file);
+ MAKE_ENTRY(cur_offset);
+ MAKE_ENTRY(disk_file);
+ MAKE_ENTRY(disk_offset);
+ MAKE_ENTRY(maxcommitperflush);
+ MAKE_ENTRY(mincommitperflush);
+ MAKE_ENTRY(regsize);
+ MAKE_ENTRY(region_wait);
+ MAKE_ENTRY(region_nowait);
+
+#undef MAKE_ENTRY
+ free(statp);
+ return d;
+} /* DBEnv_log_stat */
+#endif /* DBVER >= 4.0 for log_stat method */
+
+
+static PyObject*
+DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ DB_LOCK_STAT* sp;
+ PyObject* d = NULL;
+ u_int32_t flags = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->lock_stat(self->db_env, &sp, flags);
+#else
+#if (DBVER >= 33)
+ err = lock_stat(self->db_env, &sp);
+#else
+ err = lock_stat(self->db_env, &sp, NULL);
+#endif
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ /* Turn the stat structure into a dictionary */
+ d = PyDict_New();
+ if (d == NULL) {
+ free(sp);
+ return NULL;
+ }
+
+#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
+
+#if (DBVER < 41)
+ MAKE_ENTRY(lastid);
+#endif
+ MAKE_ENTRY(nmodes);
+#if (DBVER >= 32)
+ MAKE_ENTRY(maxlocks);
+ MAKE_ENTRY(maxlockers);
+ MAKE_ENTRY(maxobjects);
+ MAKE_ENTRY(nlocks);
+ MAKE_ENTRY(maxnlocks);
+#endif
+ MAKE_ENTRY(nlockers);
+ MAKE_ENTRY(maxnlockers);
+#if (DBVER >= 32)
+ MAKE_ENTRY(nobjects);
+ MAKE_ENTRY(maxnobjects);
+#endif
+ MAKE_ENTRY(nrequests);
+ MAKE_ENTRY(nreleases);
+#if (DBVER < 44)
+ MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
+ MAKE_ENTRY(nconflicts);
+#else
+ MAKE_ENTRY(lock_nowait);
+ MAKE_ENTRY(lock_wait);
+#endif
+ MAKE_ENTRY(ndeadlocks);
+ MAKE_ENTRY(regsize);
+ MAKE_ENTRY(region_wait);
+ MAKE_ENTRY(region_nowait);
+
+#undef MAKE_ENTRY
+ free(sp);
+ return d;
+}
+
+
+static PyObject*
+DBEnv_log_archive(DBEnvObject* self, PyObject* args)
+{
+ int flags=0;
+ int err;
+ char **log_list = NULL;
+ PyObject* list;
+ PyObject* item = NULL;
+
+ if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
+ return NULL;
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->log_archive(self->db_env, &log_list, flags);
+#elif (DBVER == 33)
+ err = log_archive(self->db_env, &log_list, flags);
+#else
+ err = log_archive(self->db_env, &log_list, flags, NULL);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ list = PyList_New(0);
+ if (list == NULL) {
+ if (log_list)
+ free(log_list);
+ return NULL;
+ }
+
+ if (log_list) {
+ char **log_list_start;
+ for (log_list_start = log_list; *log_list != NULL; ++log_list) {
+ item = PyString_FromString (*log_list);
+ if (item == NULL) {
+ Py_DECREF(list);
+ list = NULL;
+ break;
+ }
+ PyList_Append(list, item);
+ Py_DECREF(item);
+ }
+ free(log_list_start);
+ }
+ return list;
+}
+
+
+static PyObject*
+DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ DB_TXN_STAT* sp;
+ PyObject* d = NULL;
+ u_int32_t flags=0;
+
+ if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->txn_stat(self->db_env, &sp, flags);
+#elif (DBVER == 33)
+ err = txn_stat(self->db_env, &sp);
+#else
+ err = txn_stat(self->db_env, &sp, NULL);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ /* Turn the stat structure into a dictionary */
+ d = PyDict_New();
+ if (d == NULL) {
+ free(sp);
+ return NULL;
+ }
+
+#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
+
+ MAKE_ENTRY(time_ckp);
+ MAKE_ENTRY(last_txnid);
+ MAKE_ENTRY(maxtxns);
+ MAKE_ENTRY(nactive);
+ MAKE_ENTRY(maxnactive);
+ MAKE_ENTRY(nbegins);
+ MAKE_ENTRY(naborts);
+ MAKE_ENTRY(ncommits);
+ MAKE_ENTRY(regsize);
+ MAKE_ENTRY(region_wait);
+ MAKE_ENTRY(region_nowait);
+
+#undef MAKE_ENTRY
+ free(sp);
+ return d;
+}
+
+
+static PyObject*
+DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
+{
+ int flags=0;
+ int oldValue=0;
+
+ if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ if (self->moduleFlags.getReturnsNone)
+ ++oldValue;
+ if (self->moduleFlags.cursorSetReturnsNone)
+ ++oldValue;
+ self->moduleFlags.getReturnsNone = (flags >= 1);
+ self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
+ return PyInt_FromLong(oldValue);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* DBTxn methods */
+
+
+static PyObject*
+DBTxn_commit(DBTxnObject* self, PyObject* args)
+{
+ int flags=0, err;
+ DB_TXN *txn;
+
+ if (!PyArg_ParseTuple(args, "|i:commit", &flags))
+ return NULL;
+
+ if (!self->txn) {
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return NULL;
+ }
+ txn = self->txn;
+ self->txn = NULL; /* this DB_TXN is no longer valid after this call */
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = txn->commit(txn, flags);
+#else
+ err = txn_commit(txn, flags);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBTxn_prepare(DBTxnObject* self, PyObject* args)
+{
+#if (DBVER >= 33)
+ int err;
+ char* gid=NULL;
+ int gid_size=0;
+
+ if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
+ return NULL;
+
+ if (gid_size != DB_XIDDATASIZE) {
+ PyErr_SetString(PyExc_TypeError,
+ "gid must be DB_XIDDATASIZE bytes long");
+ return NULL;
+ }
+
+ if (!self->txn) {
+ PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return NULL;
+ }
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->txn->prepare(self->txn, (u_int8_t*)gid);
+#else
+ err = txn_prepare(self->txn, (u_int8_t*)gid);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+#else
+ int err;
+
+ if (!PyArg_ParseTuple(args, ":prepare"))
+ return NULL;
+
+ if (!self->txn) {
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return NULL;
+ }
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = txn_prepare(self->txn);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+#endif
+}
+
+
+static PyObject*
+DBTxn_abort(DBTxnObject* self, PyObject* args)
+{
+ int err;
+ DB_TXN *txn;
+
+ if (!PyArg_ParseTuple(args, ":abort"))
+ return NULL;
+
+ if (!self->txn) {
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return NULL;
+ }
+ txn = self->txn;
+ self->txn = NULL; /* this DB_TXN is no longer valid after this call */
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = txn->abort(txn);
+#else
+ err = txn_abort(txn);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBTxn_id(DBTxnObject* self, PyObject* args)
+{
+ int id;
+
+ if (!PyArg_ParseTuple(args, ":id"))
+ return NULL;
+
+ if (!self->txn) {
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ return NULL;
+ }
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ id = self->txn->id(self->txn);
+#else
+ id = txn_id(self->txn);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ return PyInt_FromLong(id);
+}
+
+#if (DBVER >= 43)
+/* --------------------------------------------------------------------- */
+/* DBSequence methods */
+
+
+static PyObject*
+DBSequence_close(DBSequenceObject* self, PyObject* args)
+{
+ int err, flags=0;
+ if (!PyArg_ParseTuple(args,"|i:close", &flags))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->close(self->sequence, flags);
+ self->sequence = NULL;
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+
+ RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0;
+ int delta = 1;
+ db_seq_t value;
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ static char* kwnames[] = {"delta", "txn", "flags", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->get(self->sequence, txn, delta, &value, flags);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ return PyLong_FromLongLong(value);
+
+}
+
+static PyObject*
+DBSequence_get_dbp(DBSequenceObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args,":get_dbp"))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+ Py_INCREF(self->mydb);
+ return (PyObject* )self->mydb;
+}
+
+static PyObject*
+DBSequence_get_key(DBSequenceObject* self, PyObject* args)
+{
+ int err;
+ DBT key;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->get_key(self->sequence, &key);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+
+ return PyString_FromStringAndSize(key.data, key.size);
+}
+
+static PyObject*
+DBSequence_init_value(DBSequenceObject* self, PyObject* args)
+{
+ int err;
+ db_seq_t value;
+ if (!PyArg_ParseTuple(args,"L:init_value", &value))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->initial_value(self->sequence, value);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+
+ RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0;
+ PyObject* keyobj;
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ DBT key;
+
+ static char* kwnames[] = {"key", "txn", "flags", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
+ return NULL;
+
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->open(self->sequence, txn, &key, flags);
+ MYDB_END_ALLOW_THREADS
+
+ CLEAR_DBT(key);
+ RETURN_IF_ERR();
+
+ RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0;
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+
+ static char* kwnames[] = {"txn", "flags", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
+ return NULL;
+
+ if (!checkTxnObj(txnobj, &txn))
+ return NULL;
+
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->remove(self->sequence, txn, flags);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
+{
+ int err, size;
+ if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->set_cachesize(self->sequence, size);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_get_cachesize(DBSequenceObject* self, PyObject* args)
+{
+ int err, size;
+ if (!PyArg_ParseTuple(args,":get_cachesize"))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->get_cachesize(self->sequence, &size);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ return PyInt_FromLong(size);
+}
+
+static PyObject*
+DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
+{
+ int err, flags = 0;
+ if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->set_flags(self->sequence, flags);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+
+}
+
+static PyObject*
+DBSequence_get_flags(DBSequenceObject* self, PyObject* args)
+{
+ unsigned int flags;
+ int err;
+ if (!PyArg_ParseTuple(args,":get_flags"))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->get_flags(self->sequence, &flags);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ return PyInt_FromLong((int)flags);
+}
+
+static PyObject*
+DBSequence_set_range(DBSequenceObject* self, PyObject* args)
+{
+ int err;
+ db_seq_t min, max;
+ if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->set_range(self->sequence, min, max);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBSequence_get_range(DBSequenceObject* self, PyObject* args)
+{
+ int err;
+ db_seq_t min, max;
+ if (!PyArg_ParseTuple(args,":get_range"))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self)
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->get_range(self->sequence, &min, &max);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ return Py_BuildValue("(LL)", min, max);
+}
+
+static PyObject*
+DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err, flags = 0;
+ DB_SEQUENCE_STAT* sp = NULL;
+ PyObject* dict_stat;
+ static char* kwnames[] = {"flags", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
+ return NULL;
+ CHECK_SEQUENCE_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->sequence->stat(self->sequence, &sp, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ if ((dict_stat = PyDict_New()) == NULL) {
+ free(sp);
+ return NULL;
+ }
+
+
+#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
+#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
+
+ MAKE_INT_ENTRY(wait);
+ MAKE_INT_ENTRY(nowait);
+ MAKE_LONG_LONG_ENTRY(current);
+ MAKE_LONG_LONG_ENTRY(value);
+ MAKE_LONG_LONG_ENTRY(last_value);
+ MAKE_LONG_LONG_ENTRY(min);
+ MAKE_LONG_LONG_ENTRY(max);
+ MAKE_INT_ENTRY(cache_size);
+ MAKE_INT_ENTRY(flags);
+
+#undef MAKE_INT_ENTRY
+#undef MAKE_LONG_LONG_ENTRY
+
+ free(sp);
+ return dict_stat;
+}
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* Method definition tables and type objects */
+
+static PyMethodDef DB_methods[] = {
+ {"append", (PyCFunction)DB_append, METH_VARARGS},
+#if (DBVER >= 33)
+ {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"close", (PyCFunction)DB_close, METH_VARARGS},
+#if (DBVER >= 32)
+ {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
+ {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
+ {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
+ {"fd", (PyCFunction)DB_fd, METH_VARARGS},
+ {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
+#if (DBVER >= 33)
+ {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
+ {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_VARARGS},
+ {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
+ {"get_type", (PyCFunction)DB_get_type, METH_VARARGS},
+ {"join", (PyCFunction)DB_join, METH_VARARGS},
+ {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
+ {"has_key", (PyCFunction)DB_has_key, METH_VARARGS},
+ {"items", (PyCFunction)DB_items, METH_VARARGS},
+ {"keys", (PyCFunction)DB_keys, METH_VARARGS},
+ {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
+ {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
+ {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
+ {"rename", (PyCFunction)DB_rename, METH_VARARGS},
+ {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
+#if (DBVER >= 33)
+ {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_VARARGS},
+#endif
+ {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
+#if (DBVER >= 41)
+ {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
+ {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
+ {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
+ {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
+ {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
+ {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
+ {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
+ {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
+ {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
+#if (DBVER >= 32)
+ {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
+#endif
+ {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
+ {"sync", (PyCFunction)DB_sync, METH_VARARGS},
+#if (DBVER >= 33)
+ {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"type", (PyCFunction)DB_get_type, METH_VARARGS},
+ {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
+ {"values", (PyCFunction)DB_values, METH_VARARGS},
+ {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
+ {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static PyMappingMethods DB_mapping = {
+ DB_length, /*mp_length*/
+ (binaryfunc)DB_subscript, /*mp_subscript*/
+ (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
+};
+
+
+static PyMethodDef DBCursor_methods[] = {
+ {"close", (PyCFunction)DBC_close, METH_VARARGS},
+ {"count", (PyCFunction)DBC_count, METH_VARARGS},
+ {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
+ {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
+ {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
+ {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
+ {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
+#if (DBVER >= 33)
+ {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"get_recno", (PyCFunction)DBC_get_recno, METH_VARARGS},
+ {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
+ {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
+ {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
+ {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
+ {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
+ {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
+ {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
+ {"get_current_size",(PyCFunction)DBC_get_current_size, METH_VARARGS},
+ {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
+ {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
+ {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
+ {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
+ {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
+ {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
+ {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static PyMethodDef DBEnv_methods[] = {
+ {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
+ {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
+ {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
+#if (DBVER >= 41)
+ {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
+ {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
+ {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
+#endif
+#if (DBVER >= 40)
+ {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
+ {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
+ {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
+#if (DBVER >= 32)
+ {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
+#endif
+ {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
+ {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
+ {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
+#if (DBVER >= 33)
+ {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
+#endif
+ {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
+#if (DBVER < 45)
+ {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
+#endif
+#if (DBVER >= 32)
+ {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
+ {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
+ {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
+#endif
+ {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
+ {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
+ {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
+ {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
+ {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
+ {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
+ {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
+ {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
+ {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
+ {"lock_id", (PyCFunction)DBEnv_lock_id, METH_VARARGS},
+ {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
+ {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
+ {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
+#if (DBVER >= 40)
+ {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
+#endif
+#if (DBVER >= 44)
+ {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static PyMethodDef DBTxn_methods[] = {
+ {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
+ {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
+ {"abort", (PyCFunction)DBTxn_abort, METH_VARARGS},
+ {"id", (PyCFunction)DBTxn_id, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+#if (DBVER >= 43)
+static PyMethodDef DBSequence_methods[] = {
+ {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
+ {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
+ {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_VARARGS},
+ {"get_key", (PyCFunction)DBSequence_get_key, METH_VARARGS},
+ {"init_value", (PyCFunction)DBSequence_init_value, METH_VARARGS},
+ {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
+ {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
+ {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
+ {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_VARARGS},
+ {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
+ {"get_flags", (PyCFunction)DBSequence_get_flags, METH_VARARGS},
+ {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
+ {"get_range", (PyCFunction)DBSequence_get_range, METH_VARARGS},
+ {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
+ {NULL, NULL} /* sentinel */
+};
+#endif
+
+
+static PyObject*
+DB_getattr(DBObject* self, char *name)
+{
+ return Py_FindMethod(DB_methods, (PyObject* )self, name);
+}
+
+
+static PyObject*
+DBEnv_getattr(DBEnvObject* self, char *name)
+{
+ if (!strcmp(name, "db_home")) {
+ CHECK_ENV_NOT_CLOSED(self);
+ if (self->db_env->db_home == NULL) {
+ RETURN_NONE();
+ }
+ return PyString_FromString(self->db_env->db_home);
+ }
+
+ return Py_FindMethod(DBEnv_methods, (PyObject* )self, name);
+}
+
+
+static PyObject*
+DBCursor_getattr(DBCursorObject* self, char *name)
+{
+ return Py_FindMethod(DBCursor_methods, (PyObject* )self, name);
+}
+
+static PyObject*
+DBTxn_getattr(DBTxnObject* self, char *name)
+{
+ return Py_FindMethod(DBTxn_methods, (PyObject* )self, name);
+}
+
+static PyObject*
+DBLock_getattr(DBLockObject* self, char *name)
+{
+ return NULL;
+}
+
+#if (DBVER >= 43)
+static PyObject*
+DBSequence_getattr(DBSequenceObject* self, char *name)
+{
+ return Py_FindMethod(DBSequence_methods, (PyObject* )self, name);
+}
+#endif
+
+statichere PyTypeObject DB_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "DB", /*tp_name*/
+ sizeof(DBObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)DB_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)DB_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &DB_mapping,/*tp_as_mapping*/
+ 0, /*tp_hash*/
+#ifdef HAVE_WEAKREF
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
+#endif
+};
+
+
+statichere PyTypeObject DBCursor_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "DBCursor", /*tp_name*/
+ sizeof(DBCursorObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)DBCursor_dealloc,/*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)DBCursor_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+#ifdef HAVE_WEAKREF
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
+#endif
+};
+
+
+statichere PyTypeObject DBEnv_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "DBEnv", /*tp_name*/
+ sizeof(DBEnvObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)DBEnv_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)DBEnv_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+#ifdef HAVE_WEAKREF
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
+#endif
+};
+
+statichere PyTypeObject DBTxn_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "DBTxn", /*tp_name*/
+ sizeof(DBTxnObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)DBTxn_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)DBTxn_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+#ifdef HAVE_WEAKREF
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
+#endif
+};
+
+
+statichere PyTypeObject DBLock_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "DBLock", /*tp_name*/
+ sizeof(DBLockObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)DBLock_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)DBLock_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+#ifdef HAVE_WEAKREF
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
+#endif
+};
+
+#if (DBVER >= 43)
+statichere PyTypeObject DBSequence_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "DBSequence", /*tp_name*/
+ sizeof(DBSequenceObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)DBSequence_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)DBSequence_getattr,/*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+#ifdef HAVE_WEAKREF
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
+#endif
+};
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Module-level functions */
+
+static PyObject*
+DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* dbenvobj = NULL;
+ int flags = 0;
+ static char* kwnames[] = { "dbEnv", "flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
+ &dbenvobj, &flags))
+ return NULL;
+ if (dbenvobj == Py_None)
+ dbenvobj = NULL;
+ else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
+ makeTypeError("DBEnv", dbenvobj);
+ return NULL;
+ }
+
+ return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
+}
+
+
+static PyObject*
+DBEnv_construct(PyObject* self, PyObject* args)
+{
+ int flags = 0;
+ if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
+ return (PyObject* )newDBEnvObject(flags);
+}
+
+#if (DBVER >= 43)
+static PyObject*
+DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* dbobj;
+ int flags = 0;
+ static char* kwnames[] = { "db", "flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
+ return NULL;
+ if (!DBObject_Check(dbobj)) {
+ makeTypeError("DB", dbobj);
+ return NULL;
+ }
+ return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
+}
+#endif
+
+static char bsddb_version_doc[] =
+"Returns a tuple of major, minor, and patch release numbers of the\n\
+underlying DB library.";
+
+static PyObject*
+bsddb_version(PyObject* self, PyObject* args)
+{
+ int major, minor, patch;
+
+ if (!PyArg_ParseTuple(args, ":version"))
+ return NULL;
+ db_version(&major, &minor, &patch);
+ return Py_BuildValue("(iii)", major, minor, patch);
+}
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef bsddb_methods[] = {
+ {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
+ {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
+#if (DBVER >= 43)
+ {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
+#endif
+ {"version", (PyCFunction)bsddb_version, METH_VARARGS, bsddb_version_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* --------------------------------------------------------------------- */
+/* Module initialization */
+
+
+/* Convenience routine to export an integer value.
+ * Errors are silently ignored, for better or for worse...
+ */
+#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
+
+#define MODULE_NAME_MAX_LEN 11
+static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
+
+DL_EXPORT(void) init_bsddb(void)
+{
+ PyObject* m;
+ PyObject* d;
+ PyObject* pybsddb_version_s = PyString_FromString( PY_BSDDB_VERSION );
+ PyObject* db_version_s = PyString_FromString( DB_VERSION_STRING );
+ PyObject* cvsid_s = PyString_FromString( rcs_id );
+
+ /* Initialize the type of the new type objects here; doing it here
+ is required for portability to Windows without requiring C++. */
+ DB_Type.ob_type = &PyType_Type;
+ DBCursor_Type.ob_type = &PyType_Type;
+ DBEnv_Type.ob_type = &PyType_Type;
+ DBTxn_Type.ob_type = &PyType_Type;
+ DBLock_Type.ob_type = &PyType_Type;
+#if (DBVER >= 43)
+ DBSequence_Type.ob_type = &PyType_Type;
+#endif
+
+
+#if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
+ /* Save the current interpreter, so callbacks can do the right thing. */
+ _db_interpreterState = PyThreadState_GET()->interp;
+#endif
+
+ /* Create the module and add the functions */
+ m = Py_InitModule(_bsddbModuleName, bsddb_methods);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ PyDict_SetItemString(d, "__version__", pybsddb_version_s);
+ PyDict_SetItemString(d, "cvsid", cvsid_s);
+ PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
+ Py_DECREF(pybsddb_version_s);
+ pybsddb_version_s = NULL;
+ Py_DECREF(cvsid_s);
+ cvsid_s = NULL;
+ Py_DECREF(db_version_s);
+ db_version_s = NULL;
+
+ ADD_INT(d, DB_VERSION_MAJOR);
+ ADD_INT(d, DB_VERSION_MINOR);
+ ADD_INT(d, DB_VERSION_PATCH);
+
+ ADD_INT(d, DB_MAX_PAGES);
+ ADD_INT(d, DB_MAX_RECORDS);
+
+#if (DBVER >= 42)
+ ADD_INT(d, DB_RPCCLIENT);
+#else
+ ADD_INT(d, DB_CLIENT);
+ /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
+ _addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
+#endif
+ ADD_INT(d, DB_XA_CREATE);
+
+ ADD_INT(d, DB_CREATE);
+ ADD_INT(d, DB_NOMMAP);
+ ADD_INT(d, DB_THREAD);
+
+ ADD_INT(d, DB_FORCE);
+ ADD_INT(d, DB_INIT_CDB);
+ ADD_INT(d, DB_INIT_LOCK);
+ ADD_INT(d, DB_INIT_LOG);
+ ADD_INT(d, DB_INIT_MPOOL);
+ ADD_INT(d, DB_INIT_TXN);
+#if (DBVER >= 32)
+ ADD_INT(d, DB_JOINENV);
+#endif
+
+ ADD_INT(d, DB_RECOVER);
+ ADD_INT(d, DB_RECOVER_FATAL);
+ ADD_INT(d, DB_TXN_NOSYNC);
+ ADD_INT(d, DB_USE_ENVIRON);
+ ADD_INT(d, DB_USE_ENVIRON_ROOT);
+
+ ADD_INT(d, DB_LOCKDOWN);
+ ADD_INT(d, DB_PRIVATE);
+ ADD_INT(d, DB_SYSTEM_MEM);
+
+ ADD_INT(d, DB_TXN_SYNC);
+ ADD_INT(d, DB_TXN_NOWAIT);
+
+ ADD_INT(d, DB_EXCL);
+ ADD_INT(d, DB_FCNTL_LOCKING);
+ ADD_INT(d, DB_ODDFILESIZE);
+ ADD_INT(d, DB_RDWRMASTER);
+ ADD_INT(d, DB_RDONLY);
+ ADD_INT(d, DB_TRUNCATE);
+#if (DBVER >= 32)
+ ADD_INT(d, DB_EXTENT);
+ ADD_INT(d, DB_CDB_ALLDB);
+ ADD_INT(d, DB_VERIFY);
+#endif
+ ADD_INT(d, DB_UPGRADE);
+
+ ADD_INT(d, DB_AGGRESSIVE);
+ ADD_INT(d, DB_NOORDERCHK);
+ ADD_INT(d, DB_ORDERCHKONLY);
+ ADD_INT(d, DB_PR_PAGE);
+#if ! (DBVER >= 33)
+ ADD_INT(d, DB_VRFY_FLAGMASK);
+ ADD_INT(d, DB_PR_HEADERS);
+#endif
+ ADD_INT(d, DB_PR_RECOVERYTEST);
+ ADD_INT(d, DB_SALVAGE);
+
+ ADD_INT(d, DB_LOCK_NORUN);
+ ADD_INT(d, DB_LOCK_DEFAULT);
+ ADD_INT(d, DB_LOCK_OLDEST);
+ ADD_INT(d, DB_LOCK_RANDOM);
+ ADD_INT(d, DB_LOCK_YOUNGEST);
+#if (DBVER >= 33)
+ ADD_INT(d, DB_LOCK_MAXLOCKS);
+ ADD_INT(d, DB_LOCK_MINLOCKS);
+ ADD_INT(d, DB_LOCK_MINWRITE);
+#endif
+
+
+#if (DBVER >= 33)
+ /* docs say to use zero instead */
+ _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
+#else
+ ADD_INT(d, DB_LOCK_CONFLICT);
+#endif
+
+ ADD_INT(d, DB_LOCK_DUMP);
+ ADD_INT(d, DB_LOCK_GET);
+ ADD_INT(d, DB_LOCK_INHERIT);
+ ADD_INT(d, DB_LOCK_PUT);
+ ADD_INT(d, DB_LOCK_PUT_ALL);
+ ADD_INT(d, DB_LOCK_PUT_OBJ);
+
+ ADD_INT(d, DB_LOCK_NG);
+ ADD_INT(d, DB_LOCK_READ);
+ ADD_INT(d, DB_LOCK_WRITE);
+ ADD_INT(d, DB_LOCK_NOWAIT);
+#if (DBVER >= 32)
+ ADD_INT(d, DB_LOCK_WAIT);
+#endif
+ ADD_INT(d, DB_LOCK_IWRITE);
+ ADD_INT(d, DB_LOCK_IREAD);
+ ADD_INT(d, DB_LOCK_IWR);
+#if (DBVER >= 33)
+#if (DBVER < 44)
+ ADD_INT(d, DB_LOCK_DIRTY);
+#else
+ ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
+#endif
+ ADD_INT(d, DB_LOCK_WWRITE);
+#endif
+
+ ADD_INT(d, DB_LOCK_RECORD);
+ ADD_INT(d, DB_LOCK_UPGRADE);
+#if (DBVER >= 32)
+ ADD_INT(d, DB_LOCK_SWITCH);
+#endif
+#if (DBVER >= 33)
+ ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
+#endif
+
+ ADD_INT(d, DB_LOCK_NOWAIT);
+ ADD_INT(d, DB_LOCK_RECORD);
+ ADD_INT(d, DB_LOCK_UPGRADE);
+
+#if (DBVER >= 33)
+ ADD_INT(d, DB_LSTAT_ABORTED);
+#if (DBVER < 43)
+ ADD_INT(d, DB_LSTAT_ERR);
+#endif
+ ADD_INT(d, DB_LSTAT_FREE);
+ ADD_INT(d, DB_LSTAT_HELD);
+#if (DBVER == 33)
+ ADD_INT(d, DB_LSTAT_NOGRANT);
+#endif
+ ADD_INT(d, DB_LSTAT_PENDING);
+ ADD_INT(d, DB_LSTAT_WAITING);
+#endif
+
+ ADD_INT(d, DB_ARCH_ABS);
+ ADD_INT(d, DB_ARCH_DATA);
+ ADD_INT(d, DB_ARCH_LOG);
+#if (DBVER >= 42)
+ ADD_INT(d, DB_ARCH_REMOVE);
+#endif
+
+ ADD_INT(d, DB_BTREE);
+ ADD_INT(d, DB_HASH);
+ ADD_INT(d, DB_RECNO);
+ ADD_INT(d, DB_QUEUE);
+ ADD_INT(d, DB_UNKNOWN);
+
+ ADD_INT(d, DB_DUP);
+ ADD_INT(d, DB_DUPSORT);
+ ADD_INT(d, DB_RECNUM);
+ ADD_INT(d, DB_RENUMBER);
+ ADD_INT(d, DB_REVSPLITOFF);
+ ADD_INT(d, DB_SNAPSHOT);
+
+ ADD_INT(d, DB_JOIN_NOSORT);
+
+ ADD_INT(d, DB_AFTER);
+ ADD_INT(d, DB_APPEND);
+ ADD_INT(d, DB_BEFORE);
+#if (DBVER < 45)
+ ADD_INT(d, DB_CACHED_COUNTS);
+#endif
+#if (DBVER >= 41)
+ _addIntToDict(d, "DB_CHECKPOINT", 0);
+#else
+ ADD_INT(d, DB_CHECKPOINT);
+ ADD_INT(d, DB_CURLSN);
+#endif
+#if ((DBVER >= 33) && (DBVER <= 41))
+ ADD_INT(d, DB_COMMIT);
+#endif
+ ADD_INT(d, DB_CONSUME);
+#if (DBVER >= 32)
+ ADD_INT(d, DB_CONSUME_WAIT);
+#endif
+ ADD_INT(d, DB_CURRENT);
+#if (DBVER >= 33)
+ ADD_INT(d, DB_FAST_STAT);
+#endif
+ ADD_INT(d, DB_FIRST);
+ ADD_INT(d, DB_FLUSH);
+ ADD_INT(d, DB_GET_BOTH);
+ ADD_INT(d, DB_GET_RECNO);
+ ADD_INT(d, DB_JOIN_ITEM);
+ ADD_INT(d, DB_KEYFIRST);
+ ADD_INT(d, DB_KEYLAST);
+ ADD_INT(d, DB_LAST);
+ ADD_INT(d, DB_NEXT);
+ ADD_INT(d, DB_NEXT_DUP);
+ ADD_INT(d, DB_NEXT_NODUP);
+ ADD_INT(d, DB_NODUPDATA);
+ ADD_INT(d, DB_NOOVERWRITE);
+ ADD_INT(d, DB_NOSYNC);
+ ADD_INT(d, DB_POSITION);
+ ADD_INT(d, DB_PREV);
+ ADD_INT(d, DB_PREV_NODUP);
+#if (DBVER < 45)
+ ADD_INT(d, DB_RECORDCOUNT);
+#endif
+ ADD_INT(d, DB_SET);
+ ADD_INT(d, DB_SET_RANGE);
+ ADD_INT(d, DB_SET_RECNO);
+ ADD_INT(d, DB_WRITECURSOR);
+
+ ADD_INT(d, DB_OPFLAGS_MASK);
+ ADD_INT(d, DB_RMW);
+#if (DBVER >= 33)
+ ADD_INT(d, DB_DIRTY_READ);
+ ADD_INT(d, DB_MULTIPLE);
+ ADD_INT(d, DB_MULTIPLE_KEY);
+#endif
+
+#if (DBVER >= 44)
+ ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
+ ADD_INT(d, DB_READ_COMMITTED);
+#endif
+
+#if (DBVER >= 33)
+ ADD_INT(d, DB_DONOTINDEX);
+#endif
+
+#if (DBVER >= 41)
+ _addIntToDict(d, "DB_INCOMPLETE", 0);
+#else
+ ADD_INT(d, DB_INCOMPLETE);
+#endif
+ ADD_INT(d, DB_KEYEMPTY);
+ ADD_INT(d, DB_KEYEXIST);
+ ADD_INT(d, DB_LOCK_DEADLOCK);
+ ADD_INT(d, DB_LOCK_NOTGRANTED);
+ ADD_INT(d, DB_NOSERVER);
+ ADD_INT(d, DB_NOSERVER_HOME);
+ ADD_INT(d, DB_NOSERVER_ID);
+ ADD_INT(d, DB_NOTFOUND);
+ ADD_INT(d, DB_OLD_VERSION);
+ ADD_INT(d, DB_RUNRECOVERY);
+ ADD_INT(d, DB_VERIFY_BAD);
+#if (DBVER >= 33)
+ ADD_INT(d, DB_PAGE_NOTFOUND);
+ ADD_INT(d, DB_SECONDARY_BAD);
+#endif
+#if (DBVER >= 40)
+ ADD_INT(d, DB_STAT_CLEAR);
+ ADD_INT(d, DB_REGION_INIT);
+ ADD_INT(d, DB_NOLOCKING);
+ ADD_INT(d, DB_YIELDCPU);
+ ADD_INT(d, DB_PANIC_ENVIRONMENT);
+ ADD_INT(d, DB_NOPANIC);
+#endif
+
+#if (DBVER >= 42)
+ ADD_INT(d, DB_TIME_NOTGRANTED);
+ ADD_INT(d, DB_TXN_NOT_DURABLE);
+ ADD_INT(d, DB_TXN_WRITE_NOSYNC);
+ ADD_INT(d, DB_LOG_AUTOREMOVE);
+ ADD_INT(d, DB_DIRECT_LOG);
+ ADD_INT(d, DB_DIRECT_DB);
+ ADD_INT(d, DB_INIT_REP);
+ ADD_INT(d, DB_ENCRYPT);
+ ADD_INT(d, DB_CHKSUM);
+#endif
+
+#if (DBVER >= 43)
+ ADD_INT(d, DB_LOG_INMEMORY);
+ ADD_INT(d, DB_BUFFER_SMALL);
+ ADD_INT(d, DB_SEQ_DEC);
+ ADD_INT(d, DB_SEQ_INC);
+ ADD_INT(d, DB_SEQ_WRAP);
+#endif
+
+#if (DBVER >= 41)
+ ADD_INT(d, DB_ENCRYPT_AES);
+ ADD_INT(d, DB_AUTO_COMMIT);
+#else
+ /* allow berkeleydb 4.1 aware apps to run on older versions */
+ _addIntToDict(d, "DB_AUTO_COMMIT", 0);
+#endif
+
+ ADD_INT(d, EINVAL);
+ ADD_INT(d, EACCES);
+ ADD_INT(d, ENOSPC);
+ ADD_INT(d, ENOMEM);
+ ADD_INT(d, EAGAIN);
+ ADD_INT(d, EBUSY);
+ ADD_INT(d, EEXIST);
+ ADD_INT(d, ENOENT);
+ ADD_INT(d, EPERM);
+
+#if (DBVER >= 40)
+ ADD_INT(d, DB_SET_LOCK_TIMEOUT);
+ ADD_INT(d, DB_SET_TXN_TIMEOUT);
+#endif
+
+ /* The exception name must be correct for pickled exception *
+ * objects to unpickle properly. */
+#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
+#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
+#else
+#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
+#endif
+
+ /* All the rest of the exceptions derive only from DBError */
+#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
+ PyDict_SetItemString(d, #name, name)
+
+ /* The base exception class is DBError */
+ DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
+ MAKE_EX(DBError);
+
+ /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
+ * from both DBError and KeyError, since the API only supports
+ * using one base class. */
+ PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
+ PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
+ "class DBKeyEmptyError(DBError, KeyError): pass",
+ Py_file_input, d, d);
+ DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
+ DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
+ PyDict_DelItemString(d, "KeyError");
+
+
+#if !INCOMPLETE_IS_WARNING
+ MAKE_EX(DBIncompleteError);
+#endif
+ MAKE_EX(DBCursorClosedError);
+ MAKE_EX(DBKeyEmptyError);
+ MAKE_EX(DBKeyExistError);
+ MAKE_EX(DBLockDeadlockError);
+ MAKE_EX(DBLockNotGrantedError);
+ MAKE_EX(DBOldVersionError);
+ MAKE_EX(DBRunRecoveryError);
+ MAKE_EX(DBVerifyBadError);
+ MAKE_EX(DBNoServerError);
+ MAKE_EX(DBNoServerHomeError);
+ MAKE_EX(DBNoServerIDError);
+#if (DBVER >= 33)
+ MAKE_EX(DBPageNotFoundError);
+ MAKE_EX(DBSecondaryBadError);
+#endif
+
+ MAKE_EX(DBInvalidArgError);
+ MAKE_EX(DBAccessError);
+ MAKE_EX(DBNoSpaceError);
+ MAKE_EX(DBNoMemoryError);
+ MAKE_EX(DBAgainError);
+ MAKE_EX(DBBusyError);
+ MAKE_EX(DBFileExistsError);
+ MAKE_EX(DBNoSuchFileError);
+ MAKE_EX(DBPermissionsError);
+
+#undef MAKE_EX
+
+ /* Check for errors */
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ Py_FatalError("can't initialize module _bsddb");
+ }
+}
+
+/* allow this module to be named _pybsddb so that it can be installed
+ * and imported on top of python >= 2.3 that includes its own older
+ * copy of the library named _bsddb without importing the old version. */
+DL_EXPORT(void) init_pybsddb(void)
+{
+ strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
+ init_bsddb();
+}
diff --git a/sys/src/cmd/python/Modules/_codecsmodule.c b/sys/src/cmd/python/Modules/_codecsmodule.c
new file mode 100644
index 000000000..4dbceb78b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_codecsmodule.c
@@ -0,0 +1,934 @@
+/* ------------------------------------------------------------------------
+
+ _codecs -- Provides access to the codec registry and the builtin
+ codecs.
+
+ This module should never be imported directly. The standard library
+ module "codecs" wraps this builtin module for use within Python.
+
+ The codec registry is accessible via:
+
+ register(search_function) -> None
+
+ lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)
+
+ The builtin Unicode codecs use the following interface:
+
+ <encoding>_encode(Unicode_object[,errors='strict']) ->
+ (string object, bytes consumed)
+
+ <encoding>_decode(char_buffer_obj[,errors='strict']) ->
+ (Unicode object, bytes consumed)
+
+ <encoding>_encode() interfaces also accept non-Unicode object as
+ input. The objects are then converted to Unicode using
+ PyUnicode_FromObject() prior to applying the conversion.
+
+ These <encoding>s are available: utf_8, unicode_escape,
+ raw_unicode_escape, unicode_internal, latin_1, ascii (7-bit),
+ mbcs (on win32).
+
+
+Written by Marc-Andre Lemburg (mal@lemburg.com).
+
+Copyright (c) Corporation for National Research Initiatives.
+
+ ------------------------------------------------------------------------ */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+/* --- Registry ----------------------------------------------------------- */
+
+PyDoc_STRVAR(register__doc__,
+"register(search_function)\n\
+\n\
+Register a codec search function. Search functions are expected to take\n\
+one argument, the encoding name in all lower case letters, and return\n\
+a tuple of functions (encoder, decoder, stream_reader, stream_writer).");
+
+static
+PyObject *codec_register(PyObject *self, PyObject *search_function)
+{
+ if (PyCodec_Register(search_function))
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(lookup__doc__,
+"lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)\n\
+\n\
+Looks up a codec tuple in the Python codec registry and returns\n\
+a tuple of functions.");
+
+static
+PyObject *codec_lookup(PyObject *self, PyObject *args)
+{
+ char *encoding;
+
+ if (!PyArg_ParseTuple(args, "s:lookup", &encoding))
+ return NULL;
+
+ return _PyCodec_Lookup(encoding);
+}
+
+PyDoc_STRVAR(encode__doc__,
+"encode(obj, [encoding[,errors]]) -> object\n\
+\n\
+Encodes obj using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a ValueError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that can handle ValueErrors.");
+
+static PyObject *
+codec_encode(PyObject *self, PyObject *args)
+{
+ const char *encoding = NULL;
+ const char *errors = NULL;
+ PyObject *v;
+
+ if (!PyArg_ParseTuple(args, "O|ss:encode", &v, &encoding, &errors))
+ return NULL;
+
+#ifdef Py_USING_UNICODE
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+#else
+ if (encoding == NULL) {
+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
+ return NULL;
+ }
+#endif
+
+ /* Encode via the codec registry */
+ return PyCodec_Encode(v, encoding, errors);
+}
+
+PyDoc_STRVAR(decode__doc__,
+"decode(obj, [encoding[,errors]]) -> object\n\
+\n\
+Decodes obj using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a ValueError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registerd with codecs.register_error that is\n\
+able to handle ValueErrors.");
+
+static PyObject *
+codec_decode(PyObject *self, PyObject *args)
+{
+ const char *encoding = NULL;
+ const char *errors = NULL;
+ PyObject *v;
+
+ if (!PyArg_ParseTuple(args, "O|ss:decode", &v, &encoding, &errors))
+ return NULL;
+
+#ifdef Py_USING_UNICODE
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+#else
+ if (encoding == NULL) {
+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
+ return NULL;
+ }
+#endif
+
+ /* Decode via the codec registry */
+ return PyCodec_Decode(v, encoding, errors);
+}
+
+/* --- Helpers ------------------------------------------------------------ */
+
+static
+PyObject *codec_tuple(PyObject *unicode,
+ Py_ssize_t len)
+{
+ PyObject *v;
+ if (unicode == NULL)
+ return NULL;
+ v = Py_BuildValue("On", unicode, len);
+ Py_DECREF(unicode);
+ return v;
+}
+
+/* --- String codecs ------------------------------------------------------ */
+static PyObject *
+escape_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *errors = NULL;
+ const char *data;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args, "s#|z:escape_decode",
+ &data, &size, &errors))
+ return NULL;
+ return codec_tuple(PyString_DecodeEscape(data, size, errors, 0, NULL),
+ size);
+}
+
+static PyObject *
+escape_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str;
+ const char *errors = NULL;
+ char *buf;
+ Py_ssize_t len;
+
+ if (!PyArg_ParseTuple(args, "O!|z:escape_encode",
+ &PyString_Type, &str, &errors))
+ return NULL;
+
+ str = PyString_Repr(str, 0);
+ if (!str)
+ return NULL;
+
+ /* The string will be quoted. Unquote, similar to unicode-escape. */
+ buf = PyString_AS_STRING (str);
+ len = PyString_GET_SIZE (str);
+ memmove(buf, buf+1, len-2);
+ if (_PyString_Resize(&str, len-2) < 0)
+ return NULL;
+
+ return codec_tuple(str, PyString_Size(str));
+}
+
+#ifdef Py_USING_UNICODE
+/* --- Decoder ------------------------------------------------------------ */
+
+static PyObject *
+unicode_internal_decode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *obj;
+ const char *errors = NULL;
+ const char *data;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode",
+ &obj, &errors))
+ return NULL;
+
+ if (PyUnicode_Check(obj)) {
+ Py_INCREF(obj);
+ return codec_tuple(obj, PyUnicode_GET_SIZE(obj));
+ }
+ else {
+ if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
+ return NULL;
+
+ return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors),
+ size);
+ }
+}
+
+static PyObject *
+utf_7_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|z:utf_7_decode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyUnicode_DecodeUTF7(data, size, errors),
+ size);
+}
+
+static PyObject *
+utf_8_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+ int final = 0;
+ Py_ssize_t consumed;
+ PyObject *decoded = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
+ &data, &size, &errors, &final))
+ return NULL;
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative argument");
+ return 0;
+ }
+ consumed = size;
+
+ decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
+ final ? NULL : &consumed);
+ if (decoded == NULL)
+ return NULL;
+ return codec_tuple(decoded, consumed);
+}
+
+static PyObject *
+utf_16_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+ int byteorder = 0;
+ int final = 0;
+ Py_ssize_t consumed;
+ PyObject *decoded;
+
+ if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
+ &data, &size, &errors, &final))
+ return NULL;
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative argument");
+ return 0;
+ }
+ consumed = size; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
+ final ? NULL : &consumed);
+ if (decoded == NULL)
+ return NULL;
+ return codec_tuple(decoded, consumed);
+}
+
+static PyObject *
+utf_16_le_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+ int byteorder = -1;
+ int final = 0;
+ Py_ssize_t consumed;
+ PyObject *decoded = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
+ &data, &size, &errors, &final))
+ return NULL;
+
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative argument");
+ return 0;
+ }
+ consumed = size; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+ &byteorder, final ? NULL : &consumed);
+ if (decoded == NULL)
+ return NULL;
+ return codec_tuple(decoded, consumed);
+
+}
+
+static PyObject *
+utf_16_be_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+ int byteorder = 1;
+ int final = 0;
+ Py_ssize_t consumed;
+ PyObject *decoded = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
+ &data, &size, &errors, &final))
+ return NULL;
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative argument");
+ return 0;
+ }
+ consumed = size; /* This is overwritten unless final is true. */
+ decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
+ &byteorder, final ? NULL : &consumed);
+ if (decoded == NULL)
+ return NULL;
+ return codec_tuple(decoded, consumed);
+}
+
+/* This non-standard version also provides access to the byteorder
+ parameter of the builtin UTF-16 codec.
+
+ It returns a tuple (unicode, bytesread, byteorder) with byteorder
+ being the value in effect at the end of data.
+
+*/
+
+static PyObject *
+utf_16_ex_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+ int byteorder = 0;
+ PyObject *unicode, *tuple;
+ int final = 0;
+ Py_ssize_t consumed;
+
+ if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
+ &data, &size, &errors, &byteorder, &final))
+ return NULL;
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative argument");
+ return 0;
+ }
+ consumed = size; /* This is overwritten unless final is true. */
+ unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
+ final ? NULL : &consumed);
+ if (unicode == NULL)
+ return NULL;
+ tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
+ Py_DECREF(unicode);
+ return tuple;
+}
+
+static PyObject *
+unicode_escape_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
+ size);
+}
+
+static PyObject *
+raw_unicode_escape_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
+ size);
+}
+
+static PyObject *
+latin_1_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
+ size);
+}
+
+static PyObject *
+ascii_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
+ size);
+}
+
+static PyObject *
+charmap_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+ PyObject *mapping = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
+ &data, &size, &errors, &mapping))
+ return NULL;
+ if (mapping == Py_None)
+ mapping = NULL;
+
+ return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
+ size);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+static PyObject *
+mbcs_decode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size, consumed;
+ const char *errors = NULL;
+ int final = 0;
+ PyObject *decoded;
+
+ if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
+ &data, &size, &errors, &final))
+ return NULL;
+
+ decoded = PyUnicode_DecodeMBCSStateful(
+ data, size, errors, final ? NULL : &consumed);
+ if (!decoded)
+ return NULL;
+ return codec_tuple(decoded, final ? size : consumed);
+}
+
+#endif /* MS_WINDOWS */
+
+/* --- Encoder ------------------------------------------------------------ */
+
+static PyObject *
+readbuffer_encode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyString_FromStringAndSize(data, size),
+ size);
+}
+
+static PyObject *
+charbuffer_encode(PyObject *self,
+ PyObject *args)
+{
+ const char *data;
+ Py_ssize_t size;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode",
+ &data, &size, &errors))
+ return NULL;
+
+ return codec_tuple(PyString_FromStringAndSize(data, size),
+ size);
+}
+
+static PyObject *
+unicode_internal_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *obj;
+ const char *errors = NULL;
+ const char *data;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args, "O|z:unicode_internal_encode",
+ &obj, &errors))
+ return NULL;
+
+ if (PyUnicode_Check(obj)) {
+ data = PyUnicode_AS_DATA(obj);
+ size = PyUnicode_GET_DATA_SIZE(obj);
+ return codec_tuple(PyString_FromStringAndSize(data, size),
+ size);
+ }
+ else {
+ if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
+ return NULL;
+ return codec_tuple(PyString_FromStringAndSize(data, size),
+ size);
+ }
+}
+
+static PyObject *
+utf_7_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:utf_7_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeUTF7(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ 0,
+ 0,
+ errors),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+utf_8_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:utf_8_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+/* This version provides access to the byteorder parameter of the
+ builtin UTF-16 codecs as optional third argument. It defaults to 0
+ which means: use the native byte order and prepend the data with a
+ BOM mark.
+
+*/
+
+static PyObject *
+utf_16_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+ int byteorder = 0;
+
+ if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode",
+ &str, &errors, &byteorder))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors,
+ byteorder),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+utf_16_le_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors,
+ -1),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+utf_16_be_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors,
+ +1),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+unicode_escape_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str)),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+raw_unicode_escape_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeRawUnicodeEscape(
+ PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str)),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+latin_1_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:latin_1_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeLatin1(
+ PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+ascii_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:ascii_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeASCII(
+ PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject *
+charmap_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+ PyObject *mapping = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|zO:charmap_encode",
+ &str, &errors, &mapping))
+ return NULL;
+ if (mapping == Py_None)
+ mapping = NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeCharmap(
+ PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ mapping,
+ errors),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+static PyObject*
+charmap_build(PyObject *self, PyObject *args)
+{
+ PyObject *map;
+ if (!PyArg_ParseTuple(args, "U:charmap_build", &map))
+ return NULL;
+ return PyUnicode_BuildEncodingMap(map);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+static PyObject *
+mbcs_encode(PyObject *self,
+ PyObject *args)
+{
+ PyObject *str, *v;
+ const char *errors = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|z:mbcs_encode",
+ &str, &errors))
+ return NULL;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return NULL;
+ v = codec_tuple(PyUnicode_EncodeMBCS(
+ PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ errors),
+ PyUnicode_GET_SIZE(str));
+ Py_DECREF(str);
+ return v;
+}
+
+#endif /* MS_WINDOWS */
+#endif /* Py_USING_UNICODE */
+
+/* --- Error handler registry --------------------------------------------- */
+
+PyDoc_STRVAR(register_error__doc__,
+"register_error(errors, handler)\n\
+\n\
+Register the specified error handler under the name\n\
+errors. handler must be a callable object, that\n\
+will be called with an exception instance containing\n\
+information about the location of the encoding/decoding\n\
+error and must return a (replacement, new position) tuple.");
+
+static PyObject *register_error(PyObject *self, PyObject *args)
+{
+ const char *name;
+ PyObject *handler;
+
+ if (!PyArg_ParseTuple(args, "sO:register_error",
+ &name, &handler))
+ return NULL;
+ if (PyCodec_RegisterError(name, handler))
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(lookup_error__doc__,
+"lookup_error(errors) -> handler\n\
+\n\
+Return the error handler for the specified error handling name\n\
+or raise a LookupError, if no handler exists under this name.");
+
+static PyObject *lookup_error(PyObject *self, PyObject *args)
+{
+ const char *name;
+
+ if (!PyArg_ParseTuple(args, "s:lookup_error",
+ &name))
+ return NULL;
+ return PyCodec_LookupError(name);
+}
+
+/* --- Module API --------------------------------------------------------- */
+
+static PyMethodDef _codecs_functions[] = {
+ {"register", codec_register, METH_O,
+ register__doc__},
+ {"lookup", codec_lookup, METH_VARARGS,
+ lookup__doc__},
+ {"encode", codec_encode, METH_VARARGS,
+ encode__doc__},
+ {"decode", codec_decode, METH_VARARGS,
+ decode__doc__},
+ {"escape_encode", escape_encode, METH_VARARGS},
+ {"escape_decode", escape_decode, METH_VARARGS},
+#ifdef Py_USING_UNICODE
+ {"utf_8_encode", utf_8_encode, METH_VARARGS},
+ {"utf_8_decode", utf_8_decode, METH_VARARGS},
+ {"utf_7_encode", utf_7_encode, METH_VARARGS},
+ {"utf_7_decode", utf_7_decode, METH_VARARGS},
+ {"utf_16_encode", utf_16_encode, METH_VARARGS},
+ {"utf_16_le_encode", utf_16_le_encode, METH_VARARGS},
+ {"utf_16_be_encode", utf_16_be_encode, METH_VARARGS},
+ {"utf_16_decode", utf_16_decode, METH_VARARGS},
+ {"utf_16_le_decode", utf_16_le_decode, METH_VARARGS},
+ {"utf_16_be_decode", utf_16_be_decode, METH_VARARGS},
+ {"utf_16_ex_decode", utf_16_ex_decode, METH_VARARGS},
+ {"unicode_escape_encode", unicode_escape_encode, METH_VARARGS},
+ {"unicode_escape_decode", unicode_escape_decode, METH_VARARGS},
+ {"unicode_internal_encode", unicode_internal_encode, METH_VARARGS},
+ {"unicode_internal_decode", unicode_internal_decode, METH_VARARGS},
+ {"raw_unicode_escape_encode", raw_unicode_escape_encode, METH_VARARGS},
+ {"raw_unicode_escape_decode", raw_unicode_escape_decode, METH_VARARGS},
+ {"latin_1_encode", latin_1_encode, METH_VARARGS},
+ {"latin_1_decode", latin_1_decode, METH_VARARGS},
+ {"ascii_encode", ascii_encode, METH_VARARGS},
+ {"ascii_decode", ascii_decode, METH_VARARGS},
+ {"charmap_encode", charmap_encode, METH_VARARGS},
+ {"charmap_decode", charmap_decode, METH_VARARGS},
+ {"charmap_build", charmap_build, METH_VARARGS},
+ {"readbuffer_encode", readbuffer_encode, METH_VARARGS},
+ {"charbuffer_encode", charbuffer_encode, METH_VARARGS},
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+ {"mbcs_encode", mbcs_encode, METH_VARARGS},
+ {"mbcs_decode", mbcs_decode, METH_VARARGS},
+#endif
+#endif /* Py_USING_UNICODE */
+ {"register_error", register_error, METH_VARARGS,
+ register_error__doc__},
+ {"lookup_error", lookup_error, METH_VARARGS,
+ lookup_error__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+init_codecs(void)
+{
+ Py_InitModule("_codecs", _codecs_functions);
+}
diff --git a/sys/src/cmd/python/Modules/_csv.c b/sys/src/cmd/python/Modules/_csv.c
new file mode 100644
index 000000000..5e0363559
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_csv.c
@@ -0,0 +1,1604 @@
+/* csv module */
+
+/*
+
+This module provides the low-level underpinnings of a CSV reading/writing
+module. Users should not use this module directly, but import the csv.py
+module instead.
+
+**** For people modifying this code, please note that as of this writing
+**** (2003-03-23), it is intended that this code should work with Python
+**** 2.2.
+
+*/
+
+#define MODULE_VERSION "1.0"
+
+#include "Python.h"
+#include "structmember.h"
+
+
+/* begin 2.2 compatibility macros */
+#ifndef PyDoc_STRVAR
+/* Define macros for inline documentation. */
+#define PyDoc_VAR(name) static char name[]
+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
+#ifdef WITH_DOC_STRINGS
+#define PyDoc_STR(str) str
+#else
+#define PyDoc_STR(str) ""
+#endif
+#endif /* ifndef PyDoc_STRVAR */
+
+#ifndef PyMODINIT_FUNC
+# if defined(__cplusplus)
+# define PyMODINIT_FUNC extern "C" void
+# else /* __cplusplus */
+# define PyMODINIT_FUNC void
+# endif /* __cplusplus */
+#endif
+
+#ifndef Py_CLEAR
+#define Py_CLEAR(op) \
+ do { \
+ if (op) { \
+ PyObject *tmp = (PyObject *)(op); \
+ (op) = NULL; \
+ Py_DECREF(tmp); \
+ } \
+ } while (0)
+#endif
+#ifndef Py_VISIT
+#define Py_VISIT(op) \
+ do { \
+ if (op) { \
+ int vret = visit((PyObject *)(op), arg); \
+ if (vret) \
+ return vret; \
+ } \
+ } while (0)
+#endif
+
+/* end 2.2 compatibility macros */
+
+#define IS_BASESTRING(o) \
+ PyObject_TypeCheck(o, &PyBaseString_Type)
+
+static PyObject *error_obj; /* CSV exception */
+static PyObject *dialects; /* Dialect registry */
+static long field_limit = 128 * 1024; /* max parsed field size */
+
+typedef enum {
+ START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
+ IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
+ EAT_CRNL
+} ParserState;
+
+typedef enum {
+ QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
+} QuoteStyle;
+
+typedef struct {
+ QuoteStyle style;
+ char *name;
+} StyleDesc;
+
+static StyleDesc quote_styles[] = {
+ { QUOTE_MINIMAL, "QUOTE_MINIMAL" },
+ { QUOTE_ALL, "QUOTE_ALL" },
+ { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
+ { QUOTE_NONE, "QUOTE_NONE" },
+ { 0 }
+};
+
+typedef struct {
+ PyObject_HEAD
+
+ int doublequote; /* is " represented by ""? */
+ char delimiter; /* field separator */
+ char quotechar; /* quote character */
+ char escapechar; /* escape character */
+ int skipinitialspace; /* ignore spaces following delimiter? */
+ PyObject *lineterminator; /* string to write between records */
+ int quoting; /* style of quoting to write */
+
+ int strict; /* raise exception on bad CSV */
+} DialectObj;
+
+staticforward PyTypeObject Dialect_Type;
+
+typedef struct {
+ PyObject_HEAD
+
+ PyObject *input_iter; /* iterate over this for input lines */
+
+ DialectObj *dialect; /* parsing dialect */
+
+ PyObject *fields; /* field list for current record */
+ ParserState state; /* current CSV parse state */
+ char *field; /* build current field in here */
+ int field_size; /* size of allocated buffer */
+ int field_len; /* length of current field */
+ int numeric_field; /* treat field as numeric */
+ unsigned long line_num; /* Source-file line number */
+} ReaderObj;
+
+staticforward PyTypeObject Reader_Type;
+
+#define ReaderObject_Check(v) ((v)->ob_type == &Reader_Type)
+
+typedef struct {
+ PyObject_HEAD
+
+ PyObject *writeline; /* write output lines to this file */
+
+ DialectObj *dialect; /* parsing dialect */
+
+ char *rec; /* buffer for parser.join */
+ int rec_size; /* size of allocated record */
+ int rec_len; /* length of record */
+ int num_fields; /* number of fields in record */
+} WriterObj;
+
+staticforward PyTypeObject Writer_Type;
+
+/*
+ * DIALECT class
+ */
+
+static PyObject *
+get_dialect_from_registry(PyObject * name_obj)
+{
+ PyObject *dialect_obj;
+
+ dialect_obj = PyDict_GetItem(dialects, name_obj);
+ if (dialect_obj == NULL) {
+ if (!PyErr_Occurred())
+ PyErr_Format(error_obj, "unknown dialect");
+ }
+ else
+ Py_INCREF(dialect_obj);
+ return dialect_obj;
+}
+
+static PyObject *
+get_string(PyObject *str)
+{
+ Py_XINCREF(str);
+ return str;
+}
+
+static PyObject *
+get_nullchar_as_None(char c)
+{
+ if (c == '\0') {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ return PyString_FromStringAndSize((char*)&c, 1);
+}
+
+static PyObject *
+Dialect_get_lineterminator(DialectObj *self)
+{
+ return get_string(self->lineterminator);
+}
+
+static PyObject *
+Dialect_get_escapechar(DialectObj *self)
+{
+ return get_nullchar_as_None(self->escapechar);
+}
+
+static PyObject *
+Dialect_get_quotechar(DialectObj *self)
+{
+ return get_nullchar_as_None(self->quotechar);
+}
+
+static PyObject *
+Dialect_get_quoting(DialectObj *self)
+{
+ return PyInt_FromLong(self->quoting);
+}
+
+static int
+_set_bool(const char *name, int *target, PyObject *src, int dflt)
+{
+ if (src == NULL)
+ *target = dflt;
+ else
+ *target = PyObject_IsTrue(src);
+ return 0;
+}
+
+static int
+_set_int(const char *name, int *target, PyObject *src, int dflt)
+{
+ if (src == NULL)
+ *target = dflt;
+ else {
+ if (!PyInt_Check(src)) {
+ PyErr_Format(PyExc_TypeError,
+ "\"%s\" must be an integer", name);
+ return -1;
+ }
+ *target = PyInt_AsLong(src);
+ }
+ return 0;
+}
+
+static int
+_set_char(const char *name, char *target, PyObject *src, char dflt)
+{
+ if (src == NULL)
+ *target = dflt;
+ else {
+ if (src == Py_None || PyString_Size(src) == 0)
+ *target = '\0';
+ else if (!PyString_Check(src) || PyString_Size(src) != 1) {
+ PyErr_Format(PyExc_TypeError,
+ "\"%s\" must be an 1-character string",
+ name);
+ return -1;
+ }
+ else {
+ char *s = PyString_AsString(src);
+ if (s == NULL)
+ return -1;
+ *target = s[0];
+ }
+ }
+ return 0;
+}
+
+static int
+_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
+{
+ if (src == NULL)
+ *target = PyString_FromString(dflt);
+ else {
+ if (src == Py_None)
+ *target = NULL;
+ else if (!IS_BASESTRING(src)) {
+ PyErr_Format(PyExc_TypeError,
+ "\"%s\" must be an string", name);
+ return -1;
+ }
+ else {
+ Py_XDECREF(*target);
+ Py_INCREF(src);
+ *target = src;
+ }
+ }
+ return 0;
+}
+
+static int
+dialect_check_quoting(int quoting)
+{
+ StyleDesc *qs = quote_styles;
+
+ for (qs = quote_styles; qs->name; qs++) {
+ if (qs->style == quoting)
+ return 0;
+ }
+ PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
+ return -1;
+}
+
+#define D_OFF(x) offsetof(DialectObj, x)
+
+static struct PyMemberDef Dialect_memberlist[] = {
+ { "delimiter", T_CHAR, D_OFF(delimiter), READONLY },
+ { "skipinitialspace", T_INT, D_OFF(skipinitialspace), READONLY },
+ { "doublequote", T_INT, D_OFF(doublequote), READONLY },
+ { "strict", T_INT, D_OFF(strict), READONLY },
+ { NULL }
+};
+
+static PyGetSetDef Dialect_getsetlist[] = {
+ { "escapechar", (getter)Dialect_get_escapechar},
+ { "lineterminator", (getter)Dialect_get_lineterminator},
+ { "quotechar", (getter)Dialect_get_quotechar},
+ { "quoting", (getter)Dialect_get_quoting},
+ {NULL},
+};
+
+static void
+Dialect_dealloc(DialectObj *self)
+{
+ Py_XDECREF(self->lineterminator);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static char *dialect_kws[] = {
+ "dialect",
+ "delimiter",
+ "doublequote",
+ "escapechar",
+ "lineterminator",
+ "quotechar",
+ "quoting",
+ "skipinitialspace",
+ "strict",
+ NULL
+};
+
+static PyObject *
+dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ DialectObj *self;
+ PyObject *ret = NULL;
+ PyObject *dialect = NULL;
+ PyObject *delimiter = NULL;
+ PyObject *doublequote = NULL;
+ PyObject *escapechar = NULL;
+ PyObject *lineterminator = NULL;
+ PyObject *quotechar = NULL;
+ PyObject *quoting = NULL;
+ PyObject *skipinitialspace = NULL;
+ PyObject *strict = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|OOOOOOOOO", dialect_kws,
+ &dialect,
+ &delimiter,
+ &doublequote,
+ &escapechar,
+ &lineterminator,
+ &quotechar,
+ &quoting,
+ &skipinitialspace,
+ &strict))
+ return NULL;
+
+ if (dialect != NULL) {
+ if (IS_BASESTRING(dialect)) {
+ dialect = get_dialect_from_registry(dialect);
+ if (dialect == NULL)
+ return NULL;
+ }
+ else
+ Py_INCREF(dialect);
+ /* Can we reuse this instance? */
+ if (PyObject_TypeCheck(dialect, &Dialect_Type) &&
+ delimiter == 0 &&
+ doublequote == 0 &&
+ escapechar == 0 &&
+ lineterminator == 0 &&
+ quotechar == 0 &&
+ quoting == 0 &&
+ skipinitialspace == 0 &&
+ strict == 0)
+ return dialect;
+ }
+
+ self = (DialectObj *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ Py_XDECREF(dialect);
+ return NULL;
+ }
+ self->lineterminator = NULL;
+
+ Py_XINCREF(delimiter);
+ Py_XINCREF(doublequote);
+ Py_XINCREF(escapechar);
+ Py_XINCREF(lineterminator);
+ Py_XINCREF(quotechar);
+ Py_XINCREF(quoting);
+ Py_XINCREF(skipinitialspace);
+ Py_XINCREF(strict);
+ if (dialect != NULL) {
+#define DIALECT_GETATTR(v, n) \
+ if (v == NULL) \
+ v = PyObject_GetAttrString(dialect, n)
+ DIALECT_GETATTR(delimiter, "delimiter");
+ DIALECT_GETATTR(doublequote, "doublequote");
+ DIALECT_GETATTR(escapechar, "escapechar");
+ DIALECT_GETATTR(lineterminator, "lineterminator");
+ DIALECT_GETATTR(quotechar, "quotechar");
+ DIALECT_GETATTR(quoting, "quoting");
+ DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
+ DIALECT_GETATTR(strict, "strict");
+ PyErr_Clear();
+ }
+
+ /* check types and convert to C values */
+#define DIASET(meth, name, target, src, dflt) \
+ if (meth(name, target, src, dflt)) \
+ goto err
+ DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
+ DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, 1);
+ DIASET(_set_char, "escapechar", &self->escapechar, escapechar, 0);
+ DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
+ DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"');
+ DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
+ DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, 0);
+ DIASET(_set_bool, "strict", &self->strict, strict, 0);
+
+ /* validate options */
+ if (dialect_check_quoting(self->quoting))
+ goto err;
+ if (self->delimiter == 0) {
+ PyErr_SetString(PyExc_TypeError, "delimiter must be set");
+ goto err;
+ }
+ if (quotechar == Py_None && quoting == NULL)
+ self->quoting = QUOTE_NONE;
+ if (self->quoting != QUOTE_NONE && self->quotechar == 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "quotechar must be set if quoting enabled");
+ goto err;
+ }
+ if (self->lineterminator == 0) {
+ PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
+ goto err;
+ }
+
+ ret = (PyObject *)self;
+ Py_INCREF(self);
+err:
+ Py_XDECREF(self);
+ Py_XDECREF(dialect);
+ Py_XDECREF(delimiter);
+ Py_XDECREF(doublequote);
+ Py_XDECREF(escapechar);
+ Py_XDECREF(lineterminator);
+ Py_XDECREF(quotechar);
+ Py_XDECREF(quoting);
+ Py_XDECREF(skipinitialspace);
+ Py_XDECREF(strict);
+ return ret;
+}
+
+
+PyDoc_STRVAR(Dialect_Type_doc,
+"CSV dialect\n"
+"\n"
+"The Dialect type records CSV parsing and generation options.\n");
+
+static PyTypeObject Dialect_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_csv.Dialect", /* tp_name */
+ sizeof(DialectObj), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)Dialect_dealloc, /* tp_dealloc */
+ (printfunc)0, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)0, /* tp_compare */
+ (reprfunc)0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Dialect_Type_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ Dialect_memberlist, /* tp_members */
+ Dialect_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ dialect_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/*
+ * Return an instance of the dialect type, given a Python instance or kwarg
+ * description of the dialect
+ */
+static PyObject *
+_call_dialect(PyObject *dialect_inst, PyObject *kwargs)
+{
+ PyObject *ctor_args;
+ PyObject *dialect;
+
+ ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);
+ if (ctor_args == NULL)
+ return NULL;
+ dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);
+ Py_DECREF(ctor_args);
+ return dialect;
+}
+
+/*
+ * READER
+ */
+static int
+parse_save_field(ReaderObj *self)
+{
+ PyObject *field;
+
+ field = PyString_FromStringAndSize(self->field, self->field_len);
+ if (field == NULL)
+ return -1;
+ self->field_len = 0;
+ if (self->numeric_field) {
+ PyObject *tmp;
+
+ self->numeric_field = 0;
+ tmp = PyNumber_Float(field);
+ if (tmp == NULL) {
+ Py_DECREF(field);
+ return -1;
+ }
+ Py_DECREF(field);
+ field = tmp;
+ }
+ PyList_Append(self->fields, field);
+ Py_DECREF(field);
+ return 0;
+}
+
+static int
+parse_grow_buff(ReaderObj *self)
+{
+ if (self->field_size == 0) {
+ self->field_size = 4096;
+ if (self->field != NULL)
+ PyMem_Free(self->field);
+ self->field = PyMem_Malloc(self->field_size);
+ }
+ else {
+ self->field_size *= 2;
+ self->field = PyMem_Realloc(self->field, self->field_size);
+ }
+ if (self->field == NULL) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ return 1;
+}
+
+static int
+parse_add_char(ReaderObj *self, char c)
+{
+ if (self->field_len >= field_limit) {
+ PyErr_Format(error_obj, "field larger than field limit (%ld)",
+ field_limit);
+ return -1;
+ }
+ if (self->field_len == self->field_size && !parse_grow_buff(self))
+ return -1;
+ self->field[self->field_len++] = c;
+ return 0;
+}
+
+static int
+parse_process_char(ReaderObj *self, char c)
+{
+ DialectObj *dialect = self->dialect;
+
+ switch (self->state) {
+ case START_RECORD:
+ /* start of record */
+ if (c == '\0')
+ /* empty line - return [] */
+ break;
+ else if (c == '\n' || c == '\r') {
+ self->state = EAT_CRNL;
+ break;
+ }
+ /* normal character - handle as START_FIELD */
+ self->state = START_FIELD;
+ /* fallthru */
+ case START_FIELD:
+ /* expecting field */
+ if (c == '\n' || c == '\r' || c == '\0') {
+ /* save empty field - return [fields] */
+ if (parse_save_field(self) < 0)
+ return -1;
+ self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
+ }
+ else if (c == dialect->quotechar &&
+ dialect->quoting != QUOTE_NONE) {
+ /* start quoted field */
+ self->state = IN_QUOTED_FIELD;
+ }
+ else if (c == dialect->escapechar) {
+ /* possible escaped character */
+ self->state = ESCAPED_CHAR;
+ }
+ else if (c == ' ' && dialect->skipinitialspace)
+ /* ignore space at start of field */
+ ;
+ else if (c == dialect->delimiter) {
+ /* save empty field */
+ if (parse_save_field(self) < 0)
+ return -1;
+ }
+ else {
+ /* begin new unquoted field */
+ if (dialect->quoting == QUOTE_NONNUMERIC)
+ self->numeric_field = 1;
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ self->state = IN_FIELD;
+ }
+ break;
+
+ case ESCAPED_CHAR:
+ if (c == '\0')
+ c = '\n';
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ self->state = IN_FIELD;
+ break;
+
+ case IN_FIELD:
+ /* in unquoted field */
+ if (c == '\n' || c == '\r' || c == '\0') {
+ /* end of line - return [fields] */
+ if (parse_save_field(self) < 0)
+ return -1;
+ self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
+ }
+ else if (c == dialect->escapechar) {
+ /* possible escaped character */
+ self->state = ESCAPED_CHAR;
+ }
+ else if (c == dialect->delimiter) {
+ /* save field - wait for new field */
+ if (parse_save_field(self) < 0)
+ return -1;
+ self->state = START_FIELD;
+ }
+ else {
+ /* normal character - save in field */
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ }
+ break;
+
+ case IN_QUOTED_FIELD:
+ /* in quoted field */
+ if (c == '\0')
+ ;
+ else if (c == dialect->escapechar) {
+ /* Possible escape character */
+ self->state = ESCAPE_IN_QUOTED_FIELD;
+ }
+ else if (c == dialect->quotechar &&
+ dialect->quoting != QUOTE_NONE) {
+ if (dialect->doublequote) {
+ /* doublequote; " represented by "" */
+ self->state = QUOTE_IN_QUOTED_FIELD;
+ }
+ else {
+ /* end of quote part of field */
+ self->state = IN_FIELD;
+ }
+ }
+ else {
+ /* normal character - save in field */
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ }
+ break;
+
+ case ESCAPE_IN_QUOTED_FIELD:
+ if (c == '\0')
+ c = '\n';
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ self->state = IN_QUOTED_FIELD;
+ break;
+
+ case QUOTE_IN_QUOTED_FIELD:
+ /* doublequote - seen a quote in an quoted field */
+ if (dialect->quoting != QUOTE_NONE &&
+ c == dialect->quotechar) {
+ /* save "" as " */
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ self->state = IN_QUOTED_FIELD;
+ }
+ else if (c == dialect->delimiter) {
+ /* save field - wait for new field */
+ if (parse_save_field(self) < 0)
+ return -1;
+ self->state = START_FIELD;
+ }
+ else if (c == '\n' || c == '\r' || c == '\0') {
+ /* end of line - return [fields] */
+ if (parse_save_field(self) < 0)
+ return -1;
+ self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
+ }
+ else if (!dialect->strict) {
+ if (parse_add_char(self, c) < 0)
+ return -1;
+ self->state = IN_FIELD;
+ }
+ else {
+ /* illegal */
+ PyErr_Format(error_obj, "'%c' expected after '%c'",
+ dialect->delimiter,
+ dialect->quotechar);
+ return -1;
+ }
+ break;
+
+ case EAT_CRNL:
+ if (c == '\n' || c == '\r')
+ ;
+ else if (c == '\0')
+ self->state = START_RECORD;
+ else {
+ PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
+ return -1;
+ }
+ break;
+
+ }
+ return 0;
+}
+
+static int
+parse_reset(ReaderObj *self)
+{
+ Py_XDECREF(self->fields);
+ self->fields = PyList_New(0);
+ if (self->fields == NULL)
+ return -1;
+ self->field_len = 0;
+ self->state = START_RECORD;
+ self->numeric_field = 0;
+ return 0;
+}
+
+static PyObject *
+Reader_iternext(ReaderObj *self)
+{
+ PyObject *lineobj;
+ PyObject *fields = NULL;
+ char *line, c;
+ int linelen;
+
+ if (parse_reset(self) < 0)
+ return NULL;
+ do {
+ lineobj = PyIter_Next(self->input_iter);
+ if (lineobj == NULL) {
+ /* End of input OR exception */
+ if (!PyErr_Occurred() && self->field_len != 0)
+ PyErr_Format(error_obj,
+ "newline inside string");
+ return NULL;
+ }
+ ++self->line_num;
+
+ line = PyString_AsString(lineobj);
+ linelen = PyString_Size(lineobj);
+
+ if (line == NULL || linelen < 0) {
+ Py_DECREF(lineobj);
+ return NULL;
+ }
+ while (linelen--) {
+ c = *line++;
+ if (c == '\0') {
+ Py_DECREF(lineobj);
+ PyErr_Format(error_obj,
+ "line contains NULL byte");
+ goto err;
+ }
+ if (parse_process_char(self, c) < 0) {
+ Py_DECREF(lineobj);
+ goto err;
+ }
+ }
+ Py_DECREF(lineobj);
+ if (parse_process_char(self, 0) < 0)
+ goto err;
+ } while (self->state != START_RECORD);
+
+ fields = self->fields;
+ self->fields = NULL;
+err:
+ return fields;
+}
+
+static void
+Reader_dealloc(ReaderObj *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->dialect);
+ Py_XDECREF(self->input_iter);
+ Py_XDECREF(self->fields);
+ if (self->field != NULL)
+ PyMem_Free(self->field);
+ PyObject_GC_Del(self);
+}
+
+static int
+Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->dialect);
+ Py_VISIT(self->input_iter);
+ Py_VISIT(self->fields);
+ return 0;
+}
+
+static int
+Reader_clear(ReaderObj *self)
+{
+ Py_CLEAR(self->dialect);
+ Py_CLEAR(self->input_iter);
+ Py_CLEAR(self->fields);
+ return 0;
+}
+
+PyDoc_STRVAR(Reader_Type_doc,
+"CSV reader\n"
+"\n"
+"Reader objects are responsible for reading and parsing tabular data\n"
+"in CSV format.\n"
+);
+
+static struct PyMethodDef Reader_methods[] = {
+ { NULL, NULL }
+};
+#define R_OFF(x) offsetof(ReaderObj, x)
+
+static struct PyMemberDef Reader_memberlist[] = {
+ { "dialect", T_OBJECT, R_OFF(dialect), RO },
+ { "line_num", T_ULONG, R_OFF(line_num), RO },
+ { NULL }
+};
+
+
+static PyTypeObject Reader_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_csv.reader", /*tp_name*/
+ sizeof(ReaderObj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)Reader_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ Reader_Type_doc, /*tp_doc*/
+ (traverseproc)Reader_traverse, /*tp_traverse*/
+ (inquiry)Reader_clear, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ PyObject_SelfIter, /*tp_iter*/
+ (getiterfunc)Reader_iternext, /*tp_iternext*/
+ Reader_methods, /*tp_methods*/
+ Reader_memberlist, /*tp_members*/
+ 0, /*tp_getset*/
+
+};
+
+static PyObject *
+csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
+{
+ PyObject * iterator, * dialect = NULL;
+ ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
+
+ if (!self)
+ return NULL;
+
+ self->dialect = NULL;
+ self->fields = NULL;
+ self->input_iter = NULL;
+ self->field = NULL;
+ self->field_size = 0;
+ self->line_num = 0;
+
+ if (parse_reset(self) < 0) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->input_iter = PyObject_GetIter(iterator);
+ if (self->input_iter == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument 1 must be an iterator");
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
+ if (self->dialect == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ PyObject_GC_Track(self);
+ return (PyObject *)self;
+}
+
+/*
+ * WRITER
+ */
+/* ---------------------------------------------------------------- */
+static void
+join_reset(WriterObj *self)
+{
+ self->rec_len = 0;
+ self->num_fields = 0;
+}
+
+#define MEM_INCR 32768
+
+/* Calculate new record length or append field to record. Return new
+ * record length.
+ */
+static int
+join_append_data(WriterObj *self, char *field, int quote_empty,
+ int *quoted, int copy_phase)
+{
+ DialectObj *dialect = self->dialect;
+ int i, rec_len;
+ char *lineterm;
+
+#define ADDCH(c) \
+ do {\
+ if (copy_phase) \
+ self->rec[rec_len] = c;\
+ rec_len++;\
+ } while(0)
+
+ lineterm = PyString_AsString(dialect->lineterminator);
+ if (lineterm == NULL)
+ return -1;
+
+ rec_len = self->rec_len;
+
+ /* If this is not the first field we need a field separator */
+ if (self->num_fields > 0)
+ ADDCH(dialect->delimiter);
+
+ /* Handle preceding quote */
+ if (copy_phase && *quoted)
+ ADDCH(dialect->quotechar);
+
+ /* Copy/count field data */
+ for (i = 0;; i++) {
+ char c = field[i];
+ int want_escape = 0;
+
+ if (c == '\0')
+ break;
+
+ if (c == dialect->delimiter ||
+ c == dialect->escapechar ||
+ c == dialect->quotechar ||
+ strchr(lineterm, c)) {
+ if (dialect->quoting == QUOTE_NONE)
+ want_escape = 1;
+ else {
+ if (c == dialect->quotechar) {
+ if (dialect->doublequote)
+ ADDCH(dialect->quotechar);
+ else
+ want_escape = 1;
+ }
+ if (!want_escape)
+ *quoted = 1;
+ }
+ if (want_escape) {
+ if (!dialect->escapechar) {
+ PyErr_Format(error_obj,
+ "need to escape, but no escapechar set");
+ return -1;
+ }
+ ADDCH(dialect->escapechar);
+ }
+ }
+ /* Copy field character into record buffer.
+ */
+ ADDCH(c);
+ }
+
+ /* If field is empty check if it needs to be quoted.
+ */
+ if (i == 0 && quote_empty) {
+ if (dialect->quoting == QUOTE_NONE) {
+ PyErr_Format(error_obj,
+ "single empty field record must be quoted");
+ return -1;
+ }
+ else
+ *quoted = 1;
+ }
+
+ if (*quoted) {
+ if (copy_phase)
+ ADDCH(dialect->quotechar);
+ else
+ rec_len += 2;
+ }
+ return rec_len;
+#undef ADDCH
+}
+
+static int
+join_check_rec_size(WriterObj *self, int rec_len)
+{
+ if (rec_len > self->rec_size) {
+ if (self->rec_size == 0) {
+ self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
+ if (self->rec != NULL)
+ PyMem_Free(self->rec);
+ self->rec = PyMem_Malloc(self->rec_size);
+ }
+ else {
+ char *old_rec = self->rec;
+
+ self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
+ self->rec = PyMem_Realloc(self->rec, self->rec_size);
+ if (self->rec == NULL)
+ PyMem_Free(old_rec);
+ }
+ if (self->rec == NULL) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
+{
+ int rec_len;
+
+ rec_len = join_append_data(self, field, quote_empty, quoted, 0);
+ if (rec_len < 0)
+ return 0;
+
+ /* grow record buffer if necessary */
+ if (!join_check_rec_size(self, rec_len))
+ return 0;
+
+ self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
+ self->num_fields++;
+
+ return 1;
+}
+
+static int
+join_append_lineterminator(WriterObj *self)
+{
+ int terminator_len;
+ char *terminator;
+
+ terminator_len = PyString_Size(self->dialect->lineterminator);
+ if (terminator_len == -1)
+ return 0;
+
+ /* grow record buffer if necessary */
+ if (!join_check_rec_size(self, self->rec_len + terminator_len))
+ return 0;
+
+ terminator = PyString_AsString(self->dialect->lineterminator);
+ if (terminator == NULL)
+ return 0;
+ memmove(self->rec + self->rec_len, terminator, terminator_len);
+ self->rec_len += terminator_len;
+
+ return 1;
+}
+
+PyDoc_STRVAR(csv_writerow_doc,
+"writerow(sequence)\n"
+"\n"
+"Construct and write a CSV record from a sequence of fields. Non-string\n"
+"elements will be converted to string.");
+
+static PyObject *
+csv_writerow(WriterObj *self, PyObject *seq)
+{
+ DialectObj *dialect = self->dialect;
+ int len, i;
+
+ if (!PySequence_Check(seq))
+ return PyErr_Format(error_obj, "sequence expected");
+
+ len = PySequence_Length(seq);
+ if (len < 0)
+ return NULL;
+
+ /* Join all fields in internal buffer.
+ */
+ join_reset(self);
+ for (i = 0; i < len; i++) {
+ PyObject *field;
+ int append_ok;
+ int quoted;
+
+ field = PySequence_GetItem(seq, i);
+ if (field == NULL)
+ return NULL;
+
+ switch (dialect->quoting) {
+ case QUOTE_NONNUMERIC:
+ quoted = !PyNumber_Check(field);
+ break;
+ case QUOTE_ALL:
+ quoted = 1;
+ break;
+ default:
+ quoted = 0;
+ break;
+ }
+
+ if (PyString_Check(field)) {
+ append_ok = join_append(self,
+ PyString_AS_STRING(field),
+ &quoted, len == 1);
+ Py_DECREF(field);
+ }
+ else if (field == Py_None) {
+ append_ok = join_append(self, "", &quoted, len == 1);
+ Py_DECREF(field);
+ }
+ else {
+ PyObject *str;
+
+ str = PyObject_Str(field);
+ Py_DECREF(field);
+ if (str == NULL)
+ return NULL;
+
+ append_ok = join_append(self, PyString_AS_STRING(str),
+ &quoted, len == 1);
+ Py_DECREF(str);
+ }
+ if (!append_ok)
+ return NULL;
+ }
+
+ /* Add line terminator.
+ */
+ if (!join_append_lineterminator(self))
+ return 0;
+
+ return PyObject_CallFunction(self->writeline,
+ "(s#)", self->rec, self->rec_len);
+}
+
+PyDoc_STRVAR(csv_writerows_doc,
+"writerows(sequence of sequences)\n"
+"\n"
+"Construct and write a series of sequences to a csv file. Non-string\n"
+"elements will be converted to string.");
+
+static PyObject *
+csv_writerows(WriterObj *self, PyObject *seqseq)
+{
+ PyObject *row_iter, *row_obj, *result;
+
+ row_iter = PyObject_GetIter(seqseq);
+ if (row_iter == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "writerows() argument must be iterable");
+ return NULL;
+ }
+ while ((row_obj = PyIter_Next(row_iter))) {
+ result = csv_writerow(self, row_obj);
+ Py_DECREF(row_obj);
+ if (!result) {
+ Py_DECREF(row_iter);
+ return NULL;
+ }
+ else
+ Py_DECREF(result);
+ }
+ Py_DECREF(row_iter);
+ if (PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static struct PyMethodDef Writer_methods[] = {
+ { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
+ { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
+ { NULL, NULL }
+};
+
+#define W_OFF(x) offsetof(WriterObj, x)
+
+static struct PyMemberDef Writer_memberlist[] = {
+ { "dialect", T_OBJECT, W_OFF(dialect), RO },
+ { NULL }
+};
+
+static void
+Writer_dealloc(WriterObj *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->dialect);
+ Py_XDECREF(self->writeline);
+ if (self->rec != NULL)
+ PyMem_Free(self->rec);
+ PyObject_GC_Del(self);
+}
+
+static int
+Writer_traverse(WriterObj *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->dialect);
+ Py_VISIT(self->writeline);
+ return 0;
+}
+
+static int
+Writer_clear(WriterObj *self)
+{
+ Py_CLEAR(self->dialect);
+ Py_CLEAR(self->writeline);
+ return 0;
+}
+
+PyDoc_STRVAR(Writer_Type_doc,
+"CSV writer\n"
+"\n"
+"Writer objects are responsible for generating tabular data\n"
+"in CSV format from sequence input.\n"
+);
+
+static PyTypeObject Writer_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_csv.writer", /*tp_name*/
+ sizeof(WriterObj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)Writer_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ Writer_Type_doc,
+ (traverseproc)Writer_traverse, /*tp_traverse*/
+ (inquiry)Writer_clear, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ (getiterfunc)0, /*tp_iter*/
+ (getiterfunc)0, /*tp_iternext*/
+ Writer_methods, /*tp_methods*/
+ Writer_memberlist, /*tp_members*/
+ 0, /*tp_getset*/
+};
+
+static PyObject *
+csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
+{
+ PyObject * output_file, * dialect = NULL;
+ WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
+
+ if (!self)
+ return NULL;
+
+ self->dialect = NULL;
+ self->writeline = NULL;
+
+ self->rec = NULL;
+ self->rec_size = 0;
+ self->rec_len = 0;
+ self->num_fields = 0;
+
+ if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->writeline = PyObject_GetAttrString(output_file, "write");
+ if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument 1 must have a \"write\" method");
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
+ if (self->dialect == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ PyObject_GC_Track(self);
+ return (PyObject *)self;
+}
+
+/*
+ * DIALECT REGISTRY
+ */
+static PyObject *
+csv_list_dialects(PyObject *module, PyObject *args)
+{
+ return PyDict_Keys(dialects);
+}
+
+static PyObject *
+csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
+{
+ PyObject *name_obj, *dialect_obj = NULL;
+ PyObject *dialect;
+
+ if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
+ return NULL;
+ if (!IS_BASESTRING(name_obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "dialect name must be a string or unicode");
+ return NULL;
+ }
+ dialect = _call_dialect(dialect_obj, kwargs);
+ if (dialect == NULL)
+ return NULL;
+ if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
+ Py_DECREF(dialect);
+ return NULL;
+ }
+ Py_DECREF(dialect);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+csv_unregister_dialect(PyObject *module, PyObject *name_obj)
+{
+ if (PyDict_DelItem(dialects, name_obj) < 0)
+ return PyErr_Format(error_obj, "unknown dialect");
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+csv_get_dialect(PyObject *module, PyObject *name_obj)
+{
+ return get_dialect_from_registry(name_obj);
+}
+
+static PyObject *
+csv_field_size_limit(PyObject *module, PyObject *args)
+{
+ PyObject *new_limit = NULL;
+ long old_limit = field_limit;
+
+ if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
+ return NULL;
+ if (new_limit != NULL) {
+ if (!PyInt_Check(new_limit)) {
+ PyErr_Format(PyExc_TypeError,
+ "limit must be an integer");
+ return NULL;
+ }
+ field_limit = PyInt_AsLong(new_limit);
+ }
+ return PyInt_FromLong(old_limit);
+}
+
+/*
+ * MODULE
+ */
+
+PyDoc_STRVAR(csv_module_doc,
+"CSV parsing and writing.\n"
+"\n"
+"This module provides classes that assist in the reading and writing\n"
+"of Comma Separated Value (CSV) files, and implements the interface\n"
+"described by PEP 305. Although many CSV files are simple to parse,\n"
+"the format is not formally defined by a stable specification and\n"
+"is subtle enough that parsing lines of a CSV file with something\n"
+"like line.split(\",\") is bound to fail. The module supports three\n"
+"basic APIs: reading, writing, and registration of dialects.\n"
+"\n"
+"\n"
+"DIALECT REGISTRATION:\n"
+"\n"
+"Readers and writers support a dialect argument, which is a convenient\n"
+"handle on a group of settings. When the dialect argument is a string,\n"
+"it identifies one of the dialects previously registered with the module.\n"
+"If it is a class or instance, the attributes of the argument are used as\n"
+"the settings for the reader or writer:\n"
+"\n"
+" class excel:\n"
+" delimiter = ','\n"
+" quotechar = '\"'\n"
+" escapechar = None\n"
+" doublequote = True\n"
+" skipinitialspace = False\n"
+" lineterminator = '\\r\\n'\n"
+" quoting = QUOTE_MINIMAL\n"
+"\n"
+"SETTINGS:\n"
+"\n"
+" * quotechar - specifies a one-character string to use as the \n"
+" quoting character. It defaults to '\"'.\n"
+" * delimiter - specifies a one-character string to use as the \n"
+" field separator. It defaults to ','.\n"
+" * skipinitialspace - specifies how to interpret whitespace which\n"
+" immediately follows a delimiter. It defaults to False, which\n"
+" means that whitespace immediately following a delimiter is part\n"
+" of the following field.\n"
+" * lineterminator - specifies the character sequence which should \n"
+" terminate rows.\n"
+" * quoting - controls when quotes should be generated by the writer.\n"
+" It can take on any of the following module constants:\n"
+"\n"
+" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
+" field contains either the quotechar or the delimiter\n"
+" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
+" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
+" fields which do not parse as integers or floating point\n"
+" numbers.\n"
+" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
+" * escapechar - specifies a one-character string used to escape \n"
+" the delimiter when quoting is set to QUOTE_NONE.\n"
+" * doublequote - controls the handling of quotes inside fields. When\n"
+" True, two consecutive quotes are interpreted as one during read,\n"
+" and when writing, each quote character embedded in the data is\n"
+" written as two quotes\n");
+
+PyDoc_STRVAR(csv_reader_doc,
+" csv_reader = reader(iterable [, dialect='excel']\n"
+" [optional keyword args])\n"
+" for row in csv_reader:\n"
+" process(row)\n"
+"\n"
+"The \"iterable\" argument can be any object that returns a line\n"
+"of input for each iteration, such as a file object or a list. The\n"
+"optional \"dialect\" parameter is discussed below. The function\n"
+"also accepts optional keyword arguments which override settings\n"
+"provided by the dialect.\n"
+"\n"
+"The returned object is an iterator. Each iteration returns a row\n"
+"of the CSV file (which can span multiple input lines):\n");
+
+PyDoc_STRVAR(csv_writer_doc,
+" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
+" [optional keyword args])\n"
+" for row in sequence:\n"
+" csv_writer.writerow(row)\n"
+"\n"
+" [or]\n"
+"\n"
+" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
+" [optional keyword args])\n"
+" csv_writer.writerows(rows)\n"
+"\n"
+"The \"fileobj\" argument can be any object that supports the file API.\n");
+
+PyDoc_STRVAR(csv_list_dialects_doc,
+"Return a list of all know dialect names.\n"
+" names = csv.list_dialects()");
+
+PyDoc_STRVAR(csv_get_dialect_doc,
+"Return the dialect instance associated with name.\n"
+" dialect = csv.get_dialect(name)");
+
+PyDoc_STRVAR(csv_register_dialect_doc,
+"Create a mapping from a string name to a dialect class.\n"
+" dialect = csv.register_dialect(name, dialect)");
+
+PyDoc_STRVAR(csv_unregister_dialect_doc,
+"Delete the name/dialect mapping associated with a string name.\n"
+" csv.unregister_dialect(name)");
+
+PyDoc_STRVAR(csv_field_size_limit_doc,
+"Sets an upper limit on parsed fields.\n"
+" csv.field_size_limit([limit])\n"
+"\n"
+"Returns old limit. If limit is not given, no new limit is set and\n"
+"the old limit is returned");
+
+static struct PyMethodDef csv_methods[] = {
+ { "reader", (PyCFunction)csv_reader,
+ METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
+ { "writer", (PyCFunction)csv_writer,
+ METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
+ { "list_dialects", (PyCFunction)csv_list_dialects,
+ METH_NOARGS, csv_list_dialects_doc},
+ { "register_dialect", (PyCFunction)csv_register_dialect,
+ METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
+ { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
+ METH_O, csv_unregister_dialect_doc},
+ { "get_dialect", (PyCFunction)csv_get_dialect,
+ METH_O, csv_get_dialect_doc},
+ { "field_size_limit", (PyCFunction)csv_field_size_limit,
+ METH_VARARGS, csv_field_size_limit_doc},
+ { NULL, NULL }
+};
+
+PyMODINIT_FUNC
+init_csv(void)
+{
+ PyObject *module;
+ StyleDesc *style;
+
+ if (PyType_Ready(&Dialect_Type) < 0)
+ return;
+
+ if (PyType_Ready(&Reader_Type) < 0)
+ return;
+
+ if (PyType_Ready(&Writer_Type) < 0)
+ return;
+
+ /* Create the module and add the functions */
+ module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
+ if (module == NULL)
+ return;
+
+ /* Add version to the module. */
+ if (PyModule_AddStringConstant(module, "__version__",
+ MODULE_VERSION) == -1)
+ return;
+
+ /* Add _dialects dictionary */
+ dialects = PyDict_New();
+ if (dialects == NULL)
+ return;
+ if (PyModule_AddObject(module, "_dialects", dialects))
+ return;
+
+ /* Add quote styles into dictionary */
+ for (style = quote_styles; style->name; style++) {
+ if (PyModule_AddIntConstant(module, style->name,
+ style->style) == -1)
+ return;
+ }
+
+ /* Add the Dialect type */
+ Py_INCREF(&Dialect_Type);
+ if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
+ return;
+
+ /* Add the CSV exception object to the module. */
+ error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
+ if (error_obj == NULL)
+ return;
+ PyModule_AddObject(module, "Error", error_obj);
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/_ctypes.c b/sys/src/cmd/python/Modules/_ctypes/_ctypes.c
new file mode 100644
index 000000000..4dd35c233
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/_ctypes.c
@@ -0,0 +1,4859 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+
+/*
+ ToDo:
+
+ Get rid of the checker (and also the converters) field in CFuncPtrObject and
+ StgDictObject, and replace them by slot functions in StgDictObject.
+
+ think about a buffer-like object (memory? bytes?)
+
+ Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
+ What about c_char and c_wchar arrays then?
+
+ Add from_mmap, from_file, from_string metaclass methods.
+
+ Maybe we can get away with from_file (calls read) and with a from_buffer
+ method?
+
+ And what about the to_mmap, to_file, to_str(?) methods? They would clobber
+ the namespace, probably. So, functions instead? And we already have memmove...
+*/
+
+/*
+
+Name methods, members, getsets
+==============================================================================
+
+StructType_Type __new__(), from_address(), __mul__(), from_param()
+UnionType_Type __new__(), from_address(), __mul__(), from_param()
+PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
+ArrayType_Type __new__(), from_address(), __mul__(), from_param()
+SimpleType_Type __new__(), from_address(), __mul__(), from_param()
+
+CData_Type
+ Struct_Type __new__(), __init__()
+ Pointer_Type __new__(), __init__(), _as_parameter_, contents
+ Array_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
+ Simple_Type __new__(), __init__(), _as_parameter_
+
+CField_Type
+StgDict_Type
+
+==============================================================================
+
+class methods
+-------------
+
+It has some similarity to the byref() construct compared to pointer()
+from_address(addr)
+ - construct an instance from a given memory block (sharing this memory block)
+
+from_param(obj)
+ - typecheck and convert a Python object into a C function call parameter
+ the result may be an instance of the type, or an integer or tuple
+ (typecode, value[, obj])
+
+instance methods/properties
+---------------------------
+
+_as_parameter_
+ - convert self into a C function call parameter
+ This is either an integer, or a 3-tuple (typecode, value, obj)
+
+functions
+---------
+
+sizeof(cdata)
+ - return the number of bytes the buffer contains
+
+sizeof(ctype)
+ - return the number of bytes the buffer of an instance would contain
+
+byref(cdata)
+
+addressof(cdata)
+
+pointer(cdata)
+
+POINTER(ctype)
+
+bytes(cdata)
+ - return the buffer contents as a sequence of bytes (which is currently a string)
+
+*/
+
+/*
+ * StgDict_Type
+ * StructType_Type
+ * UnionType_Type
+ * PointerType_Type
+ * ArrayType_Type
+ * SimpleType_Type
+ *
+ * CData_Type
+ * Struct_Type
+ * Union_Type
+ * Array_Type
+ * Simple_Type
+ * Pointer_Type
+ * CField_Type
+ *
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#include <malloc.h>
+#ifndef IS_INTRESOURCE
+#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
+#endif
+# ifdef _WIN32_WCE
+/* Unlike desktop Windows, WinCE has both W and A variants of
+ GetProcAddress, but the default W version is not what we want */
+# undef GetProcAddress
+# define GetProcAddress GetProcAddressA
+# endif
+#else
+#include "ctypes_dlfcn.h"
+#endif
+#include "ctypes.h"
+
+PyObject *PyExc_ArgError;
+static PyTypeObject Simple_Type;
+
+char *conversion_mode_encoding = NULL;
+char *conversion_mode_errors = NULL;
+
+
+/******************************************************************/
+/*
+ StructType_Type - a meta type/class. Creating a new class using this one as
+ __metaclass__ will call the contructor StructUnionType_new. It replaces the
+ tp_dict member with a new instance of StgDict, and initializes the C
+ accessible fields somehow.
+*/
+
+static PyCArgObject *
+StructUnionType_paramfunc(CDataObject *self)
+{
+ PyCArgObject *parg;
+ StgDictObject *stgdict;
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+
+ parg->tag = 'V';
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for structure/union instances */
+ parg->pffi_type = &stgdict->ffi_type_pointer;
+ /* For structure parameters (by value), parg->value doesn't contain the structure
+ data itself, instead parg->value.p *points* to the structure's data
+ See also _ctypes.c, function _call_function_pointer().
+ */
+ parg->value.p = self->b_ptr;
+ parg->size = self->b_size;
+ Py_INCREF(self);
+ parg->obj = (PyObject *)self;
+ return parg;
+}
+
+static PyObject *
+StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
+{
+ PyTypeObject *result;
+ PyObject *fields;
+ StgDictObject *dict;
+
+ /* create the new instance (which is a class,
+ since we are a metatype!) */
+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+ if (!result)
+ return NULL;
+
+ /* keep this for bw compatibility */
+ if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
+ return (PyObject *)result;
+
+ dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL);
+ if (!dict) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ /* replace the class dict by our updated stgdict, which holds info
+ about storage requirements of the instances */
+ if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
+ Py_DECREF(result);
+ Py_DECREF((PyObject *)dict);
+ return NULL;
+ }
+ Py_DECREF(result->tp_dict);
+ result->tp_dict = (PyObject *)dict;
+
+ dict->paramfunc = StructUnionType_paramfunc;
+
+ fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
+ if (!fields) {
+ StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
+
+ if (basedict == NULL)
+ return (PyObject *)result;
+ /* copy base dict */
+ if (-1 == StgDict_clone(dict, basedict)) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
+ basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
+ return (PyObject *)result;
+ }
+
+ if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ return (PyObject *)result;
+}
+
+static PyObject *
+StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ return StructUnionType_new(type, args, kwds, 1);
+}
+
+static PyObject *
+UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ return StructUnionType_new(type, args, kwds, 0);
+}
+
+static char from_address_doc[] =
+"C.from_address(integer) -> C instance\naccess a C instance at the specified address";
+
+static PyObject *
+CDataType_from_address(PyObject *type, PyObject *value)
+{
+ void *buf;
+ if (!PyInt_Check(value) && !PyLong_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer expected");
+ return NULL;
+ }
+ buf = (void *)PyLong_AsVoidPtr(value);
+ if (PyErr_Occurred())
+ return NULL;
+ return CData_AtAddress(type, buf);
+}
+
+static char in_dll_doc[] =
+"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
+
+static PyObject *
+CDataType_in_dll(PyObject *type, PyObject *args)
+{
+ PyObject *dll;
+ char *name;
+ PyObject *obj;
+ void *handle;
+ void *address;
+
+ if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
+ return NULL;
+
+ obj = PyObject_GetAttrString(dll, "_handle");
+ if (!obj)
+ return NULL;
+ if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "the _handle attribute of the second argument must be an integer");
+ Py_DECREF(obj);
+ return NULL;
+ }
+ handle = (void *)PyLong_AsVoidPtr(obj);
+ Py_DECREF(obj);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ValueError,
+ "could not convert the _handle attribute to a pointer");
+ return NULL;
+ }
+
+#ifdef MS_WIN32
+ address = (void *)GetProcAddress(handle, name);
+ if (!address) {
+ PyErr_Format(PyExc_ValueError,
+ "symbol '%s' not found",
+ name);
+ return NULL;
+ }
+#else
+ address = (void *)ctypes_dlsym(handle, name);
+ if (!address) {
+ PyErr_Format(PyExc_ValueError,
+#ifdef __CYGWIN__
+/* dlerror() isn't very helpful on cygwin */
+ "symbol '%s' not found (%s) ",
+ name,
+#endif
+ ctypes_dlerror());
+ return NULL;
+ }
+#endif
+ return CData_AtAddress(type, address);
+}
+
+static char from_param_doc[] =
+"Convert a Python object into a function call parameter.";
+
+static PyObject *
+CDataType_from_param(PyObject *type, PyObject *value)
+{
+ PyObject *as_parameter;
+ if (1 == PyObject_IsInstance(value, type)) {
+ Py_INCREF(value);
+ return value;
+ }
+ if (PyCArg_CheckExact(value)) {
+ PyCArgObject *p = (PyCArgObject *)value;
+ PyObject *ob = p->obj;
+ const char *ob_name;
+ StgDictObject *dict;
+ dict = PyType_stgdict(type);
+
+ /* If we got a PyCArgObject, we must check if the object packed in it
+ is an instance of the type's dict->proto */
+ if(dict && ob
+ && PyObject_IsInstance(ob, dict->proto)) {
+ Py_INCREF(value);
+ return value;
+ }
+ ob_name = (ob) ? ob->ob_type->tp_name : "???";
+ PyErr_Format(PyExc_TypeError,
+ "expected %s instance instead of pointer to %s",
+ ((PyTypeObject *)type)->tp_name, ob_name);
+ return NULL;
+ }
+
+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+ if (as_parameter) {
+ value = CDataType_from_param(type, as_parameter);
+ Py_DECREF(as_parameter);
+ return value;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "expected %s instance instead of %s",
+ ((PyTypeObject *)type)->tp_name,
+ value->ob_type->tp_name);
+ return NULL;
+}
+
+static PyMethodDef CDataType_methods[] = {
+ { "from_param", CDataType_from_param, METH_O, from_param_doc },
+ { "from_address", CDataType_from_address, METH_O, from_address_doc },
+ { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
+ { NULL, NULL },
+};
+
+static PyObject *
+CDataType_repeat(PyObject *self, Py_ssize_t length)
+{
+ if (length < 0)
+ return PyErr_Format(PyExc_ValueError,
+#if (PY_VERSION_HEX < 0x02050000)
+ "Array length must be >= 0, not %d",
+#else
+ "Array length must be >= 0, not %zd",
+#endif
+ length);
+ return CreateArrayType(self, length);
+}
+
+static PySequenceMethods CDataType_as_sequence = {
+ 0, /* inquiry sq_length; */
+ 0, /* binaryfunc sq_concat; */
+ CDataType_repeat, /* intargfunc sq_repeat; */
+ 0, /* intargfunc sq_item; */
+ 0, /* intintargfunc sq_slice; */
+ 0, /* intobjargproc sq_ass_item; */
+ 0, /* intintobjargproc sq_ass_slice; */
+ 0, /* objobjproc sq_contains; */
+
+ 0, /* binaryfunc sq_inplace_concat; */
+ 0, /* intargfunc sq_inplace_repeat; */
+};
+
+static int
+CDataType_clear(PyTypeObject *self)
+{
+ StgDictObject *dict = PyType_stgdict((PyObject *)self);
+ if (dict)
+ Py_CLEAR(dict->proto);
+ return PyType_Type.tp_clear((PyObject *)self);
+}
+
+static int
+CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
+{
+ StgDictObject *dict = PyType_stgdict((PyObject *)self);
+ if (dict)
+ Py_VISIT(dict->proto);
+ return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
+}
+
+static int
+StructType_setattro(PyObject *self, PyObject *key, PyObject *value)
+{
+ /* XXX Should we disallow deleting _fields_? */
+ if (-1 == PyObject_GenericSetAttr(self, key, value))
+ return -1;
+
+ if (value && PyString_Check(key) &&
+ 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
+ return StructUnionType_update_stgdict(self, value, 1);
+ return 0;
+}
+
+
+static int
+UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
+{
+ /* XXX Should we disallow deleting _fields_? */
+ if (-1 == PyObject_GenericSetAttr(self, key, value))
+ return -1;
+
+ if (PyString_Check(key) &&
+ 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
+ return StructUnionType_update_stgdict(self, value, 0);
+ return 0;
+}
+
+
+PyTypeObject StructType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.StructType", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &CDataType_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ StructType_setattro, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ "metatype for the CData Objects", /* tp_doc */
+ (traverseproc)CDataType_traverse, /* tp_traverse */
+ (inquiry)CDataType_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ CDataType_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ StructType_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+static PyTypeObject UnionType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.UnionType", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &CDataType_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ UnionType_setattro, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ "metatype for the CData Objects", /* tp_doc */
+ (traverseproc)CDataType_traverse, /* tp_traverse */
+ (inquiry)CDataType_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ CDataType_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ UnionType_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/******************************************************************/
+
+/*
+
+The PointerType_Type metaclass must ensure that the subclass of Pointer can be
+created. It must check for a _type_ attribute in the class. Since are no
+runtime created properties, a CField is probably *not* needed ?
+
+class IntPointer(Pointer):
+ _type_ = "i"
+
+The Pointer_Type provides the functionality: a contents method/property, a
+size property/method, and the sequence protocol.
+
+*/
+
+static int
+PointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
+{
+ if (!proto || !PyType_Check(proto)) {
+ PyErr_SetString(PyExc_TypeError,
+ "_type_ must be a type");
+ return -1;
+ }
+ if (!PyType_stgdict(proto)) {
+ PyErr_SetString(PyExc_TypeError,
+ "_type_ must have storage info");
+ return -1;
+ }
+ Py_INCREF(proto);
+ Py_XDECREF(stgdict->proto);
+ stgdict->proto = proto;
+ return 0;
+}
+
+static PyCArgObject *
+PointerType_paramfunc(CDataObject *self)
+{
+ PyCArgObject *parg;
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+
+ parg->tag = 'P';
+ parg->pffi_type = &ffi_type_pointer;
+ Py_INCREF(self);
+ parg->obj = (PyObject *)self;
+ parg->value.p = *(void **)self->b_ptr;
+ return parg;
+}
+
+static PyObject *
+PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyTypeObject *result;
+ StgDictObject *stgdict;
+ PyObject *proto;
+ PyObject *typedict;
+
+ typedict = PyTuple_GetItem(args, 2);
+ if (!typedict)
+ return NULL;
+/*
+ stgdict items size, align, length contain info about pointers itself,
+ stgdict->proto has info about the pointed to type!
+*/
+ stgdict = (StgDictObject *)PyObject_CallObject(
+ (PyObject *)&StgDict_Type, NULL);
+ if (!stgdict)
+ return NULL;
+ stgdict->size = sizeof(void *);
+ stgdict->align = getentry("P")->pffi_type->alignment;
+ stgdict->length = 1;
+ stgdict->ffi_type_pointer = ffi_type_pointer;
+ stgdict->paramfunc = PointerType_paramfunc;
+
+ proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
+ if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+
+ /* create the new instance (which is a class,
+ since we are a metatype!) */
+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+ if (result == NULL) {
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+
+ /* replace the class dict by our updated spam dict */
+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+ Py_DECREF(result);
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+ Py_DECREF(result->tp_dict);
+ result->tp_dict = (PyObject *)stgdict;
+
+ return (PyObject *)result;
+}
+
+
+static PyObject *
+PointerType_set_type(PyTypeObject *self, PyObject *type)
+{
+ StgDictObject *dict;
+
+ dict = PyType_stgdict((PyObject *)self);
+ assert(dict);
+
+ if (-1 == PointerType_SetProto(dict, type))
+ return NULL;
+
+ if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+staticforward PyObject *_byref(PyObject *);
+
+static PyObject *
+PointerType_from_param(PyObject *type, PyObject *value)
+{
+ StgDictObject *typedict;
+
+ if (value == Py_None)
+ return PyInt_FromLong(0); /* NULL pointer */
+
+ typedict = PyType_stgdict(type);
+ assert(typedict); /* Cannot be NULL for pointer types */
+
+ /* If we expect POINTER(<type>), but receive a <type> instance, accept
+ it by calling byref(<type>).
+ */
+ switch (PyObject_IsInstance(value, typedict->proto)) {
+ case 1:
+ Py_INCREF(value); /* _byref steals a refcount */
+ return _byref(value);
+ case -1:
+ PyErr_Clear();
+ break;
+ default:
+ break;
+ }
+
+ if (PointerObject_Check(value) || ArrayObject_Check(value)) {
+ /* Array instances are also pointers when
+ the item types are the same.
+ */
+ StgDictObject *v = PyObject_stgdict(value);
+ assert(v); /* Cannot be NULL for pointer or array objects */
+ if (PyObject_IsSubclass(v->proto, typedict->proto)) {
+ Py_INCREF(value);
+ return value;
+ }
+ }
+ return CDataType_from_param(type, value);
+}
+
+static PyMethodDef PointerType_methods[] = {
+ { "from_address", CDataType_from_address, METH_O, from_address_doc },
+ { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
+ { "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc},
+ { "set_type", (PyCFunction)PointerType_set_type, METH_O },
+ { NULL, NULL },
+};
+
+PyTypeObject PointerType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.PointerType", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &CDataType_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ "metatype for the Pointer Objects", /* tp_doc */
+ (traverseproc)CDataType_traverse, /* tp_traverse */
+ (inquiry)CDataType_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ PointerType_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ PointerType_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/******************************************************************/
+/*
+ ArrayType_Type
+*/
+/*
+ ArrayType_new ensures that the new Array subclass created has a _length_
+ attribute, and a _type_ attribute.
+*/
+
+static int
+CharArray_set_raw(CDataObject *self, PyObject *value)
+{
+ char *ptr;
+ Py_ssize_t size;
+ if (PyBuffer_Check(value)) {
+ size = value->ob_type->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
+ if (size < 0)
+ return -1;
+ } else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
+ return -1;
+ }
+ if (size > self->b_size) {
+ PyErr_SetString(PyExc_ValueError,
+ "string too long");
+ return -1;
+ }
+
+ memcpy(self->b_ptr, ptr, size);
+
+ return 0;
+}
+
+static PyObject *
+CharArray_get_raw(CDataObject *self)
+{
+ return PyString_FromStringAndSize(self->b_ptr, self->b_size);
+}
+
+static PyObject *
+CharArray_get_value(CDataObject *self)
+{
+ int i;
+ char *ptr = self->b_ptr;
+ for (i = 0; i < self->b_size; ++i)
+ if (*ptr++ == '\0')
+ break;
+ return PyString_FromStringAndSize(self->b_ptr, i);
+}
+
+static int
+CharArray_set_value(CDataObject *self, PyObject *value)
+{
+ char *ptr;
+ int size;
+
+ if (PyUnicode_Check(value)) {
+ value = PyUnicode_AsEncodedString(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (!value)
+ return -1;
+ } else if (!PyString_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "string expected instead of %s instance",
+ value->ob_type->tp_name);
+ return -1;
+ } else
+ Py_INCREF(value);
+ size = PyString_GET_SIZE(value);
+ if (size > self->b_size) {
+ PyErr_SetString(PyExc_ValueError,
+ "string too long");
+ Py_DECREF(value);
+ return -1;
+ }
+
+ ptr = PyString_AS_STRING(value);
+ memcpy(self->b_ptr, ptr, size);
+ if (size < self->b_size)
+ self->b_ptr[size] = '\0';
+ Py_DECREF(value);
+
+ return 0;
+}
+
+static PyGetSetDef CharArray_getsets[] = {
+ { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
+ "value", NULL },
+ { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
+ "string value"},
+ { NULL, NULL }
+};
+
+#ifdef CTYPES_UNICODE
+static PyObject *
+WCharArray_get_value(CDataObject *self)
+{
+ unsigned int i;
+ wchar_t *ptr = (wchar_t *)self->b_ptr;
+ for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
+ if (*ptr++ == (wchar_t)0)
+ break;
+ return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
+}
+
+static int
+WCharArray_set_value(CDataObject *self, PyObject *value)
+{
+ int result = 0;
+
+ if (PyString_Check(value)) {
+ value = PyUnicode_FromEncodedObject(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (!value)
+ return -1;
+ } else if (!PyUnicode_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "unicode string expected instead of %s instance",
+ value->ob_type->tp_name);
+ return -1;
+ } else
+ Py_INCREF(value);
+ if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
+ PyErr_SetString(PyExc_ValueError,
+ "string too long");
+ result = -1;
+ goto done;
+ }
+ result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
+ (wchar_t *)self->b_ptr,
+ self->b_size/sizeof(wchar_t));
+ if (result >= 0 && (unsigned)result < self->b_size/sizeof(wchar_t))
+ ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
+ if (result > 0)
+ result = 0;
+ done:
+ Py_DECREF(value);
+
+ return result;
+}
+
+static PyGetSetDef WCharArray_getsets[] = {
+ { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
+ "string value"},
+ { NULL, NULL }
+};
+#endif
+
+/*
+ The next three functions copied from Python's typeobject.c.
+
+ They are used to attach methods, members, or getsets to a type *after* it
+ has been created: Arrays of characters have additional getsets to treat them
+ as strings.
+ */
+/*
+static int
+add_methods(PyTypeObject *type, PyMethodDef *meth)
+{
+ PyObject *dict = type->tp_dict;
+ for (; meth->ml_name != NULL; meth++) {
+ PyObject *descr;
+ descr = PyDescr_NewMethod(type, meth);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ return 0;
+}
+
+static int
+add_members(PyTypeObject *type, PyMemberDef *memb)
+{
+ PyObject *dict = type->tp_dict;
+ for (; memb->name != NULL; memb++) {
+ PyObject *descr;
+ descr = PyDescr_NewMember(type, memb);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict, memb->name, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ return 0;
+}
+*/
+
+static int
+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
+{
+ PyObject *dict = type->tp_dict;
+ for (; gsp->name != NULL; gsp++) {
+ PyObject *descr;
+ descr = PyDescr_NewGetSet(type, gsp);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ return 0;
+}
+
+static PyCArgObject *
+ArrayType_paramfunc(CDataObject *self)
+{
+ PyCArgObject *p = new_CArgObject();
+ if (p == NULL)
+ return NULL;
+ p->tag = 'P';
+ p->pffi_type = &ffi_type_pointer;
+ p->value.p = (char *)self->b_ptr;
+ Py_INCREF(self);
+ p->obj = (PyObject *)self;
+ return p;
+}
+
+static PyObject *
+ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyTypeObject *result;
+ StgDictObject *stgdict;
+ StgDictObject *itemdict;
+ PyObject *proto;
+ PyObject *typedict;
+ int length;
+
+ int itemsize, itemalign;
+
+ typedict = PyTuple_GetItem(args, 2);
+ if (!typedict)
+ return NULL;
+
+ proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
+ if (!proto || !PyInt_Check(proto)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "class must define a '_length_' attribute, "
+ "which must be a positive integer");
+ return NULL;
+ }
+ length = PyInt_AS_LONG(proto);
+
+ proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
+ if (!proto) {
+ PyErr_SetString(PyExc_AttributeError,
+ "class must define a '_type_' attribute");
+ return NULL;
+ }
+
+ stgdict = (StgDictObject *)PyObject_CallObject(
+ (PyObject *)&StgDict_Type, NULL);
+ if (!stgdict)
+ return NULL;
+
+ itemdict = PyType_stgdict(proto);
+ if (!itemdict) {
+ PyErr_SetString(PyExc_TypeError,
+ "_type_ must have storage info");
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+
+ itemsize = itemdict->size;
+ if (length * itemsize < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "array too large");
+ return NULL;
+ }
+
+ itemalign = itemdict->align;
+
+ stgdict->size = itemsize * length;
+ stgdict->align = itemalign;
+ stgdict->length = length;
+ Py_INCREF(proto);
+ stgdict->proto = proto;
+
+ stgdict->paramfunc = &ArrayType_paramfunc;
+
+ /* Arrays are passed as pointers to function calls. */
+ stgdict->ffi_type_pointer = ffi_type_pointer;
+
+ /* create the new instance (which is a class,
+ since we are a metatype!) */
+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+ if (result == NULL)
+ return NULL;
+
+ /* replace the class dict by our updated spam dict */
+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+ Py_DECREF(result);
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+ Py_DECREF(result->tp_dict);
+ result->tp_dict = (PyObject *)stgdict;
+
+ /* Special case for character arrays.
+ A permanent annoyance: char arrays are also strings!
+ */
+ if (itemdict->getfunc == getentry("c")->getfunc) {
+ if (-1 == add_getset(result, CharArray_getsets))
+ return NULL;
+#ifdef CTYPES_UNICODE
+ } else if (itemdict->getfunc == getentry("u")->getfunc) {
+ if (-1 == add_getset(result, WCharArray_getsets))
+ return NULL;
+#endif
+ }
+
+ return (PyObject *)result;
+}
+
+PyTypeObject ArrayType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.ArrayType", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &CDataType_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "metatype for the Array Objects", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ CDataType_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ArrayType_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/******************************************************************/
+/*
+ SimpleType_Type
+*/
+/*
+
+SimpleType_new ensures that the new Simple_Type subclass created has a valid
+_type_ attribute.
+
+*/
+
+static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv";
+
+static PyObject *
+c_wchar_p_from_param(PyObject *type, PyObject *value)
+{
+ PyObject *as_parameter;
+#if (PYTHON_API_VERSION < 1012)
+# error not supported
+#endif
+ if (value == Py_None) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (PyUnicode_Check(value) || PyString_Check(value)) {
+ PyCArgObject *parg;
+ struct fielddesc *fd = getentry("Z");
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'Z';
+ parg->obj = fd->setfunc(&parg->value, value, 0);
+ if (parg->obj == NULL) {
+ Py_DECREF(parg);
+ return NULL;
+ }
+ return (PyObject *)parg;
+ }
+ if (PyObject_IsInstance(value, type)) {
+ Py_INCREF(value);
+ return value;
+ }
+ if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+ /* c_wchar array instance or pointer(c_wchar(...)) */
+ StgDictObject *dt = PyObject_stgdict(value);
+ StgDictObject *dict;
+ assert(dt); /* Cannot be NULL for pointer or array objects */
+ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
+ if (dict && (dict->setfunc == getentry("u")->setfunc)) {
+ Py_INCREF(value);
+ return value;
+ }
+ }
+ if (PyCArg_CheckExact(value)) {
+ /* byref(c_char(...)) */
+ PyCArgObject *a = (PyCArgObject *)value;
+ StgDictObject *dict = PyObject_stgdict(a->obj);
+ if (dict && (dict->setfunc == getentry("u")->setfunc)) {
+ Py_INCREF(value);
+ return value;
+ }
+ }
+
+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+ if (as_parameter) {
+ value = c_wchar_p_from_param(type, as_parameter);
+ Py_DECREF(as_parameter);
+ return value;
+ }
+ /* XXX better message */
+ PyErr_SetString(PyExc_TypeError,
+ "wrong type");
+ return NULL;
+}
+
+static PyObject *
+c_char_p_from_param(PyObject *type, PyObject *value)
+{
+ PyObject *as_parameter;
+#if (PYTHON_API_VERSION < 1012)
+# error not supported
+#endif
+ if (value == Py_None) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (PyString_Check(value) || PyUnicode_Check(value)) {
+ PyCArgObject *parg;
+ struct fielddesc *fd = getentry("z");
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'z';
+ parg->obj = fd->setfunc(&parg->value, value, 0);
+ if (parg->obj == NULL) {
+ Py_DECREF(parg);
+ return NULL;
+ }
+ return (PyObject *)parg;
+ }
+ if (PyObject_IsInstance(value, type)) {
+ Py_INCREF(value);
+ return value;
+ }
+ if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+ /* c_char array instance or pointer(c_char(...)) */
+ StgDictObject *dt = PyObject_stgdict(value);
+ StgDictObject *dict;
+ assert(dt); /* Cannot be NULL for pointer or array objects */
+ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
+ if (dict && (dict->setfunc == getentry("c")->setfunc)) {
+ Py_INCREF(value);
+ return value;
+ }
+ }
+ if (PyCArg_CheckExact(value)) {
+ /* byref(c_char(...)) */
+ PyCArgObject *a = (PyCArgObject *)value;
+ StgDictObject *dict = PyObject_stgdict(a->obj);
+ if (dict && (dict->setfunc == getentry("c")->setfunc)) {
+ Py_INCREF(value);
+ return value;
+ }
+ }
+
+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+ if (as_parameter) {
+ value = c_char_p_from_param(type, as_parameter);
+ Py_DECREF(as_parameter);
+ return value;
+ }
+ /* XXX better message */
+ PyErr_SetString(PyExc_TypeError,
+ "wrong type");
+ return NULL;
+}
+
+static PyObject *
+c_void_p_from_param(PyObject *type, PyObject *value)
+{
+ StgDictObject *stgd;
+ PyObject *as_parameter;
+#if (PYTHON_API_VERSION < 1012)
+# error not supported
+#endif
+
+/* None */
+ if (value == Py_None) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ /* Should probably allow buffer interface as well */
+/* int, long */
+ if (PyInt_Check(value) || PyLong_Check(value)) {
+ PyCArgObject *parg;
+ struct fielddesc *fd = getentry("P");
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'P';
+ parg->obj = fd->setfunc(&parg->value, value, 0);
+ if (parg->obj == NULL) {
+ Py_DECREF(parg);
+ return NULL;
+ }
+ return (PyObject *)parg;
+ }
+/* string */
+ if (PyString_Check(value)) {
+ PyCArgObject *parg;
+ struct fielddesc *fd = getentry("z");
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'z';
+ parg->obj = fd->setfunc(&parg->value, value, 0);
+ if (parg->obj == NULL) {
+ Py_DECREF(parg);
+ return NULL;
+ }
+ return (PyObject *)parg;
+ }
+/* unicode */
+ if (PyUnicode_Check(value)) {
+ PyCArgObject *parg;
+ struct fielddesc *fd = getentry("Z");
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'Z';
+ parg->obj = fd->setfunc(&parg->value, value, 0);
+ if (parg->obj == NULL) {
+ Py_DECREF(parg);
+ return NULL;
+ }
+ return (PyObject *)parg;
+ }
+/* c_void_p instance (or subclass) */
+ if (PyObject_IsInstance(value, type)) {
+ /* c_void_p instances */
+ Py_INCREF(value);
+ return value;
+ }
+/* ctypes array or pointer instance */
+ if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+ /* Any array or pointer is accepted */
+ Py_INCREF(value);
+ return value;
+ }
+/* byref(...) */
+ if (PyCArg_CheckExact(value)) {
+ /* byref(c_xxx()) */
+ PyCArgObject *a = (PyCArgObject *)value;
+ if (a->tag == 'P') {
+ Py_INCREF(value);
+ return value;
+ }
+ }
+/* function pointer */
+ if (CFuncPtrObject_Check(value)) {
+ PyCArgObject *parg;
+ CFuncPtrObject *func;
+ func = (CFuncPtrObject *)value;
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'P';
+ Py_INCREF(value);
+ parg->value.p = *(void **)func->b_ptr;
+ parg->obj = value;
+ return (PyObject *)parg;
+ }
+/* c_char_p, c_wchar_p */
+ stgd = PyObject_stgdict(value);
+ if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
+ PyCArgObject *parg;
+
+ switch (PyString_AS_STRING(stgd->proto)[0]) {
+ case 'z': /* c_char_p */
+ case 'Z': /* c_wchar_p */
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'Z';
+ Py_INCREF(value);
+ parg->obj = value;
+ /* Remember: b_ptr points to where the pointer is stored! */
+ parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
+ return (PyObject *)parg;
+ }
+ }
+
+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+ if (as_parameter) {
+ value = c_void_p_from_param(type, as_parameter);
+ Py_DECREF(as_parameter);
+ return value;
+ }
+ /* XXX better message */
+ PyErr_SetString(PyExc_TypeError,
+ "wrong type");
+ return NULL;
+}
+#if (PYTHON_API_VERSION >= 1012)
+
+static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
+static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
+static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
+
+#else
+#error
+static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
+static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
+static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
+
+#endif
+
+static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
+ PyObject *proto, struct fielddesc *fmt)
+{
+ PyTypeObject *result;
+ StgDictObject *stgdict;
+ PyObject *name = PyTuple_GET_ITEM(args, 0);
+ PyObject *swapped_args;
+ static PyObject *suffix;
+ Py_ssize_t i;
+
+ swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
+ if (!swapped_args)
+ return NULL;
+
+ if (suffix == NULL)
+#ifdef WORDS_BIGENDIAN
+ suffix = PyString_FromString("_le");
+#else
+ suffix = PyString_FromString("_be");
+#endif
+
+ Py_INCREF(name);
+ PyString_Concat(&name, suffix);
+ if (name == NULL)
+ return NULL;
+
+ PyTuple_SET_ITEM(swapped_args, 0, name);
+ for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
+ PyObject *v = PyTuple_GET_ITEM(args, i);
+ Py_INCREF(v);
+ PyTuple_SET_ITEM(swapped_args, i, v);
+ }
+
+ /* create the new instance (which is a class,
+ since we are a metatype!) */
+ result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
+ Py_DECREF(swapped_args);
+ if (result == NULL)
+ return NULL;
+
+ stgdict = (StgDictObject *)PyObject_CallObject(
+ (PyObject *)&StgDict_Type, NULL);
+ if (!stgdict) /* XXX leaks result! */
+ return NULL;
+
+ stgdict->ffi_type_pointer = *fmt->pffi_type;
+ stgdict->align = fmt->pffi_type->alignment;
+ stgdict->length = 0;
+ stgdict->size = fmt->pffi_type->size;
+ stgdict->setfunc = fmt->setfunc_swapped;
+ stgdict->getfunc = fmt->getfunc_swapped;
+
+ Py_INCREF(proto);
+ stgdict->proto = proto;
+
+ /* replace the class dict by our updated spam dict */
+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+ Py_DECREF(result);
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+ Py_DECREF(result->tp_dict);
+ result->tp_dict = (PyObject *)stgdict;
+
+ return (PyObject *)result;
+}
+
+static PyCArgObject *
+SimpleType_paramfunc(CDataObject *self)
+{
+ StgDictObject *dict;
+ char *fmt;
+ PyCArgObject *parg;
+ struct fielddesc *fd;
+
+ dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
+ fmt = PyString_AsString(dict->proto);
+ assert(fmt);
+
+ fd = getentry(fmt);
+ assert(fd);
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+
+ parg->tag = fmt[0];
+ parg->pffi_type = fd->pffi_type;
+ Py_INCREF(self);
+ parg->obj = (PyObject *)self;
+ memcpy(&parg->value, self->b_ptr, self->b_size);
+ return parg;
+}
+
+static PyObject *
+SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyTypeObject *result;
+ StgDictObject *stgdict;
+ PyObject *proto;
+ PyMethodDef *ml;
+ struct fielddesc *fmt;
+
+ /* create the new instance (which is a class,
+ since we are a metatype!) */
+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+ if (result == NULL)
+ return NULL;
+
+ proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
+ if (!proto
+ || !PyString_Check(proto)
+ || 1 != strlen(PyString_AS_STRING(proto))
+ || !strchr(SIMPLE_TYPE_CHARS, PyString_AS_STRING(proto)[0])) {
+ PyErr_Format(PyExc_AttributeError,
+ "class must define a '_type_' attribute which must be\n"
+ "a single character string containing one of '%s'.",
+ SIMPLE_TYPE_CHARS);
+ Py_XDECREF(proto);
+ Py_DECREF(result);
+ return NULL;
+ }
+ fmt = getentry(PyString_AS_STRING(proto));
+ if (fmt == NULL) {
+ Py_DECREF(result);
+ PyErr_Format(PyExc_ValueError,
+ "_type_ '%s' not supported",
+ PyString_AS_STRING(proto));
+ return NULL;
+ }
+
+ stgdict = (StgDictObject *)PyObject_CallObject(
+ (PyObject *)&StgDict_Type, NULL);
+ if (!stgdict)
+ return NULL;
+
+ stgdict->ffi_type_pointer = *fmt->pffi_type;
+ stgdict->align = fmt->pffi_type->alignment;
+ stgdict->length = 0;
+ stgdict->size = fmt->pffi_type->size;
+ stgdict->setfunc = fmt->setfunc;
+ stgdict->getfunc = fmt->getfunc;
+
+ stgdict->paramfunc = SimpleType_paramfunc;
+/*
+ if (result->tp_base != &Simple_Type) {
+ stgdict->setfunc = NULL;
+ stgdict->getfunc = NULL;
+ }
+*/
+
+ /* This consumes the refcount on proto which we have */
+ stgdict->proto = proto;
+
+ /* replace the class dict by our updated spam dict */
+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+ Py_DECREF(result);
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+ Py_DECREF(result->tp_dict);
+ result->tp_dict = (PyObject *)stgdict;
+
+ /* Install from_param class methods in ctypes base classes.
+ Overrides the SimpleType_from_param generic method.
+ */
+ if (result->tp_base == &Simple_Type) {
+ switch (PyString_AS_STRING(proto)[0]) {
+ case 'z': /* c_char_p */
+ ml = &c_char_p_method;
+ break;
+ case 'Z': /* c_wchar_p */
+ ml = &c_wchar_p_method;
+ break;
+ case 'P': /* c_void_p */
+ ml = &c_void_p_method;
+ break;
+ default:
+ ml = NULL;
+ break;
+ }
+
+ if (ml) {
+#if (PYTHON_API_VERSION >= 1012)
+ PyObject *meth;
+ int x;
+ meth = PyDescr_NewClassMethod(result, ml);
+ if (!meth)
+ return NULL;
+#else
+#error
+ PyObject *meth, *func;
+ int x;
+ func = PyCFunction_New(ml, NULL);
+ if (!func)
+ return NULL;
+ meth = PyObject_CallFunctionObjArgs(
+ (PyObject *)&PyClassMethod_Type,
+ func, NULL);
+ Py_DECREF(func);
+ if (!meth) {
+ return NULL;
+ }
+#endif
+ x = PyDict_SetItemString(result->tp_dict,
+ ml->ml_name,
+ meth);
+ Py_DECREF(meth);
+ if (x == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ }
+
+ if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
+ PyObject *swapped = CreateSwappedType(type, args, kwds,
+ proto, fmt);
+ if (swapped == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+#ifdef WORDS_BIGENDIAN
+ PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
+ PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
+ PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
+ PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
+#else
+ PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
+ PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
+ PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
+ PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
+#endif
+ Py_DECREF(swapped);
+ };
+
+ return (PyObject *)result;
+}
+
+/*
+ * This is a *class method*.
+ * Convert a parameter into something that ConvParam can handle.
+ */
+static PyObject *
+SimpleType_from_param(PyObject *type, PyObject *value)
+{
+ StgDictObject *dict;
+ char *fmt;
+ PyCArgObject *parg;
+ struct fielddesc *fd;
+ PyObject *as_parameter;
+
+ /* If the value is already an instance of the requested type,
+ we can use it as is */
+ if (1 == PyObject_IsInstance(value, type)) {
+ Py_INCREF(value);
+ return value;
+ }
+
+ dict = PyType_stgdict(type);
+ assert(dict);
+
+ /* I think we can rely on this being a one-character string */
+ fmt = PyString_AsString(dict->proto);
+ assert(fmt);
+
+ fd = getentry(fmt);
+ assert(fd);
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+
+ parg->tag = fmt[0];
+ parg->pffi_type = fd->pffi_type;
+ parg->obj = fd->setfunc(&parg->value, value, 0);
+ if (parg->obj)
+ return (PyObject *)parg;
+ PyErr_Clear();
+ Py_DECREF(parg);
+
+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
+ if (as_parameter) {
+ value = SimpleType_from_param(type, as_parameter);
+ Py_DECREF(as_parameter);
+ return value;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "wrong type");
+ return NULL;
+}
+
+static PyMethodDef SimpleType_methods[] = {
+ { "from_param", SimpleType_from_param, METH_O, from_param_doc },
+ { "from_address", CDataType_from_address, METH_O, from_address_doc },
+ { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
+ { NULL, NULL },
+};
+
+PyTypeObject SimpleType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.SimpleType", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &CDataType_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "metatype for the SimpleType Objects", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ SimpleType_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ SimpleType_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/******************************************************************/
+/*
+ CFuncPtrType_Type
+ */
+
+static PyObject *
+converters_from_argtypes(PyObject *ob)
+{
+ PyObject *converters;
+ int i;
+ int nArgs;
+
+ ob = PySequence_Tuple(ob); /* new reference */
+ if (!ob) {
+ PyErr_SetString(PyExc_TypeError,
+ "_argtypes_ must be a sequence of types");
+ return NULL;
+ }
+
+ nArgs = PyTuple_GET_SIZE(ob);
+ converters = PyTuple_New(nArgs);
+ if (!converters)
+ return NULL;
+
+ /* I have to check if this is correct. Using c_char, which has a size
+ of 1, will be assumed to be pushed as only one byte!
+ Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
+ */
+
+ for (i = 0; i < nArgs; ++i) {
+ PyObject *tp = PyTuple_GET_ITEM(ob, i);
+ PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
+ if (!cnv)
+ goto argtypes_error_1;
+ PyTuple_SET_ITEM(converters, i, cnv);
+ }
+ Py_DECREF(ob);
+ return converters;
+
+ argtypes_error_1:
+ Py_XDECREF(converters);
+ Py_DECREF(ob);
+ PyErr_Format(PyExc_TypeError,
+ "item %d in _argtypes_ has no from_param method", i+1);
+ return NULL;
+}
+
+static int
+make_funcptrtype_dict(StgDictObject *stgdict)
+{
+ PyObject *ob;
+ PyObject *converters = NULL;
+
+ stgdict->align = getentry("P")->pffi_type->alignment;
+ stgdict->length = 1;
+ stgdict->size = sizeof(void *);
+ stgdict->setfunc = NULL;
+ stgdict->getfunc = NULL;
+ stgdict->ffi_type_pointer = ffi_type_pointer;
+
+ ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
+ if (!ob || !PyInt_Check(ob)) {
+ PyErr_SetString(PyExc_TypeError,
+ "class must define _flags_ which must be an integer");
+ return -1;
+ }
+ stgdict->flags = PyInt_AS_LONG(ob);
+
+ /* _argtypes_ is optional... */
+ ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
+ if (ob) {
+ converters = converters_from_argtypes(ob);
+ if (!converters)
+ goto error;
+ Py_INCREF(ob);
+ stgdict->argtypes = ob;
+ stgdict->converters = converters;
+ }
+
+ ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
+ if (ob) {
+ if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
+ PyErr_SetString(PyExc_TypeError,
+ "_restype_ must be a type, a callable, or None");
+ return -1;
+ }
+ Py_INCREF(ob);
+ stgdict->restype = ob;
+ stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
+ if (stgdict->checker == NULL)
+ PyErr_Clear();
+ }
+/* XXX later, maybe.
+ ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
+ if (ob) {
+ if (!PyCallable_Check(ob)) {
+ PyErr_SetString(PyExc_TypeError,
+ "_errcheck_ must be callable");
+ return -1;
+ }
+ Py_INCREF(ob);
+ stgdict->errcheck = ob;
+ }
+*/
+ return 0;
+
+ error:
+ Py_XDECREF(converters);
+ return -1;
+
+}
+
+static PyCArgObject *
+CFuncPtrType_paramfunc(CDataObject *self)
+{
+ PyCArgObject *parg;
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+
+ parg->tag = 'P';
+ parg->pffi_type = &ffi_type_pointer;
+ Py_INCREF(self);
+ parg->obj = (PyObject *)self;
+ parg->value.p = *(void **)self->b_ptr;
+ return parg;
+}
+
+static PyObject *
+CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyTypeObject *result;
+ StgDictObject *stgdict;
+
+ stgdict = (StgDictObject *)PyObject_CallObject(
+ (PyObject *)&StgDict_Type, NULL);
+ if (!stgdict)
+ return NULL;
+
+ stgdict->paramfunc = CFuncPtrType_paramfunc;
+
+ /* create the new instance (which is a class,
+ since we are a metatype!) */
+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
+ if (result == NULL) {
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+
+ /* replace the class dict by our updated storage dict */
+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
+ Py_DECREF(result);
+ Py_DECREF((PyObject *)stgdict);
+ return NULL;
+ }
+ Py_DECREF(result->tp_dict);
+ result->tp_dict = (PyObject *)stgdict;
+
+ if (-1 == make_funcptrtype_dict(stgdict)) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return (PyObject *)result;
+}
+
+PyTypeObject CFuncPtrType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.CFuncPtrType", /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &CDataType_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ "metatype for C function pointers", /* tp_doc */
+ (traverseproc)CDataType_traverse, /* tp_traverse */
+ (inquiry)CDataType_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ CDataType_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ CFuncPtrType_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/*****************************************************************
+ * Code to keep needed objects alive
+ */
+
+static CDataObject *
+CData_GetContainer(CDataObject *self)
+{
+ while (self->b_base)
+ self = self->b_base;
+ if (self->b_objects == NULL) {
+ if (self->b_length) {
+ self->b_objects = PyDict_New();
+ } else {
+ Py_INCREF(Py_None);
+ self->b_objects = Py_None;
+ }
+ }
+ return self;
+}
+
+static PyObject *
+GetKeepedObjects(CDataObject *target)
+{
+ return CData_GetContainer(target)->b_objects;
+}
+
+static PyObject *
+unique_key(CDataObject *target, Py_ssize_t index)
+{
+ char string[256];
+ char *cp = string;
+ size_t bytes_left;
+
+ assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
+#if (PY_VERSION_HEX < 0x02050000)
+ cp += sprintf(cp, "%x", index);
+#else
+ cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
+#endif
+ while (target->b_base) {
+ bytes_left = sizeof(string) - (cp - string) - 1;
+ /* Hex format needs 2 characters per byte */
+ if (bytes_left < sizeof(Py_ssize_t) * 2) {
+ PyErr_SetString(PyExc_ValueError,
+ "ctypes object structure too deep");
+ return NULL;
+ }
+#if (PY_VERSION_HEX < 0x02050000)
+ cp += sprintf(cp, ":%x", (int)target->b_index);
+#else
+ cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
+#endif
+ target = target->b_base;
+ }
+ return PyString_FromStringAndSize(string, cp-string);
+}
+
+/*
+ * Keep a reference to 'keep' in the 'target', at index 'index'.
+ *
+ * If 'keep' is None, do nothing.
+ *
+ * Otherwise create a dictionary (if it does not yet exist) id the root
+ * objects 'b_objects' item, which will store the 'keep' object under a unique
+ * key.
+ *
+ * The unique_key helper travels the target's b_base pointer down to the root,
+ * building a string containing hex-formatted indexes found during traversal,
+ * separated by colons.
+ *
+ * The index tuple is used as a key into the root object's b_objects dict.
+ *
+ * Note: This function steals a refcount of the third argument, even if it
+ * fails!
+ */
+static int
+KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
+{
+ int result;
+ CDataObject *ob;
+ PyObject *key;
+
+/* Optimization: no need to store None */
+ if (keep == Py_None) {
+ Py_DECREF(Py_None);
+ return 0;
+ }
+ ob = CData_GetContainer(target);
+ if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) {
+ Py_XDECREF(ob->b_objects);
+ ob->b_objects = keep; /* refcount consumed */
+ return 0;
+ }
+ key = unique_key(target, index);
+ if (key == NULL) {
+ Py_DECREF(keep);
+ return -1;
+ }
+ result = PyDict_SetItem(ob->b_objects, key, keep);
+ Py_DECREF(key);
+ Py_DECREF(keep);
+ return result;
+}
+
+/******************************************************************/
+/*
+ CData_Type
+ */
+static int
+CData_traverse(CDataObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->b_objects);
+ Py_VISIT((PyObject *)self->b_base);
+ return 0;
+}
+
+static int
+CData_clear(CDataObject *self)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
+ Py_CLEAR(self->b_objects);
+ if ((self->b_needsfree)
+ && ((size_t)dict->size > sizeof(self->b_value)))
+ PyMem_Free(self->b_ptr);
+ self->b_ptr = NULL;
+ Py_CLEAR(self->b_base);
+ return 0;
+}
+
+static void
+CData_dealloc(PyObject *self)
+{
+ CData_clear((CDataObject *)self);
+ self->ob_type->tp_free(self);
+}
+
+static PyMemberDef CData_members[] = {
+ { "_b_base_", T_OBJECT,
+ offsetof(CDataObject, b_base), READONLY,
+ "the base object" },
+ { "_b_needsfree_", T_INT,
+ offsetof(CDataObject, b_needsfree), READONLY,
+ "whether the object owns the memory or not" },
+ { "_objects", T_OBJECT,
+ offsetof(CDataObject, b_objects), READONLY,
+ "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
+ { NULL },
+};
+
+static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
+{
+ CDataObject *self = (CDataObject *)_self;
+ if (seg != 0) {
+ /* Hm. Must this set an exception? */
+ return -1;
+ }
+ *pptr = self->b_ptr;
+ return self->b_size;
+}
+
+static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
+{
+ if (lenp)
+ *lenp = 1;
+ return 1;
+}
+
+static PyBufferProcs CData_as_buffer = {
+ CData_GetBuffer,
+ CData_GetBuffer,
+ CData_GetSegcount,
+ NULL,
+};
+
+/*
+ * CData objects are mutable, so they cannot be hashable!
+ */
+static long
+CData_nohash(PyObject *self)
+{
+ PyErr_SetString(PyExc_TypeError, "unhashable type");
+ return -1;
+}
+
+/*
+ * default __ctypes_from_outparam__ method returns self.
+ */
+static PyObject *
+CData_from_outparam(PyObject *self, PyObject *args)
+{
+ Py_INCREF(self);
+ return self;
+}
+
+static PyMethodDef CData_methods[] = {
+ { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
+ { NULL, NULL },
+};
+
+PyTypeObject CData_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes._CData",
+ sizeof(CDataObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ CData_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ CData_nohash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "XXX to be provided", /* tp_doc */
+ (traverseproc)CData_traverse, /* tp_traverse */
+ (inquiry)CData_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ CData_methods, /* tp_methods */
+ CData_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+};
+
+static int CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
+{
+ if ((size_t)dict->size <= sizeof(obj->b_value)) {
+ /* No need to call malloc, can use the default buffer */
+ obj->b_ptr = (char *)&obj->b_value;
+ /* The b_needsfree flag does not mean that we actually did
+ call PyMem_Malloc to allocate the memory block; instead it
+ means we are the *owner* of the memory and are responsible
+ for freeing resources associated with the memory. This is
+ also the reason that b_needsfree is exposed to Python.
+ */
+ obj->b_needsfree = 1;
+ } else {
+ /* In python 2.4, and ctypes 0.9.6, the malloc call took about
+ 33% of the creation time for c_int().
+ */
+ obj->b_ptr = (char *)PyMem_Malloc(dict->size);
+ if (obj->b_ptr == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ obj->b_needsfree = 1;
+ memset(obj->b_ptr, 0, dict->size);
+ }
+ obj->b_size = dict->size;
+ return 0;
+}
+
+PyObject *
+CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
+{
+ CDataObject *cmem;
+ StgDictObject *dict;
+
+ assert(PyType_Check(type));
+ dict = PyType_stgdict(type);
+ if (!dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "abstract class");
+ return NULL;
+ }
+ dict->flags |= DICTFLAG_FINAL;
+ cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
+ if (cmem == NULL)
+ return NULL;
+ assert(CDataObject_Check(cmem));
+
+ cmem->b_length = dict->length;
+ cmem->b_size = dict->size;
+ if (base) { /* use base's buffer */
+ assert(CDataObject_Check(base));
+ cmem->b_ptr = adr;
+ cmem->b_needsfree = 0;
+ Py_INCREF(base);
+ cmem->b_base = (CDataObject *)base;
+ cmem->b_index = index;
+ } else { /* copy contents of adr */
+ if (-1 == CData_MallocBuffer(cmem, dict)) {
+ return NULL;
+ Py_DECREF(cmem);
+ }
+ memcpy(cmem->b_ptr, adr, dict->size);
+ cmem->b_index = index;
+ }
+ return (PyObject *)cmem;
+}
+
+/*
+ Box a memory block into a CData instance.
+*/
+PyObject *
+CData_AtAddress(PyObject *type, void *buf)
+{
+ CDataObject *pd;
+ StgDictObject *dict;
+
+ assert(PyType_Check(type));
+ dict = PyType_stgdict(type);
+ if (!dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "abstract class");
+ return NULL;
+ }
+ dict->flags |= DICTFLAG_FINAL;
+
+ pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
+ if (!pd)
+ return NULL;
+ assert(CDataObject_Check(pd));
+ pd->b_ptr = (char *)buf;
+ pd->b_length = dict->length;
+ pd->b_size = dict->size;
+ return (PyObject *)pd;
+}
+
+/*
+ This function returns TRUE for c_int, c_void_p, and these kind of
+ classes. FALSE otherwise FALSE also for subclasses of c_int and
+ such.
+*/
+int IsSimpleSubType(PyObject *obj)
+{
+ PyTypeObject *type = (PyTypeObject *)obj;
+
+ if (SimpleTypeObject_Check(type))
+ return type->tp_base != &Simple_Type;
+ return 0;
+}
+
+PyObject *
+CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
+ Py_ssize_t index, Py_ssize_t size, char *adr)
+{
+ StgDictObject *dict;
+ if (getfunc)
+ return getfunc(adr, size);
+ assert(type);
+ dict = PyType_stgdict(type);
+ if (dict && dict->getfunc && !IsSimpleSubType(type))
+ return dict->getfunc(adr, size);
+ return CData_FromBaseObj(type, src, index, adr);
+}
+
+/*
+ Helper function for CData_set below.
+*/
+static PyObject *
+_CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
+ Py_ssize_t size, char *ptr)
+{
+ CDataObject *src;
+
+ if (setfunc)
+ return setfunc(ptr, value, size);
+
+ if (!CDataObject_Check(value)) {
+ StgDictObject *dict = PyType_stgdict(type);
+ if (dict && dict->setfunc)
+ return dict->setfunc(ptr, value, size);
+ /*
+ If value is a tuple, we try to call the type with the tuple
+ and use the result!
+ */
+ assert(PyType_Check(type));
+ if (PyTuple_Check(value)) {
+ PyObject *ob;
+ PyObject *result;
+ ob = PyObject_CallObject(type, value);
+ if (ob == NULL) {
+ Extend_Error_Info(PyExc_RuntimeError, "(%s) ",
+ ((PyTypeObject *)type)->tp_name);
+ return NULL;
+ }
+ result = _CData_set(dst, type, setfunc, ob,
+ size, ptr);
+ Py_DECREF(ob);
+ return result;
+ } else if (value == Py_None && PointerTypeObject_Check(type)) {
+ *(void **)ptr = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ PyErr_Format(PyExc_TypeError,
+ "expected %s instance, got %s",
+ ((PyTypeObject *)type)->tp_name,
+ value->ob_type->tp_name);
+ return NULL;
+ }
+ }
+ src = (CDataObject *)value;
+
+ if (PyObject_IsInstance(value, type)) {
+ memcpy(ptr,
+ src->b_ptr,
+ size);
+
+ if (PointerTypeObject_Check(type))
+ /* XXX */;
+
+ value = GetKeepedObjects(src);
+ Py_INCREF(value);
+ return value;
+ }
+
+ if (PointerTypeObject_Check(type)
+ && ArrayObject_Check(value)) {
+ StgDictObject *p1, *p2;
+ PyObject *keep;
+ p1 = PyObject_stgdict(value);
+ assert(p1); /* Cannot be NULL for array instances */
+ p2 = PyType_stgdict(type);
+ assert(p2); /* Cannot be NULL for pointer types */
+
+ if (p1->proto != p2->proto) {
+ PyErr_Format(PyExc_TypeError,
+ "incompatible types, %s instance instead of %s instance",
+ value->ob_type->tp_name,
+ ((PyTypeObject *)type)->tp_name);
+ return NULL;
+ }
+ *(void **)ptr = src->b_ptr;
+
+ keep = GetKeepedObjects(src);
+ /*
+ We are assigning an array object to a field which represents
+ a pointer. This has the same effect as converting an array
+ into a pointer. So, again, we have to keep the whole object
+ pointed to (which is the array in this case) alive, and not
+ only it's object list. So we create a tuple, containing
+ b_objects list PLUS the array itself, and return that!
+ */
+ return Py_BuildValue("(OO)", keep, value);
+ }
+ PyErr_Format(PyExc_TypeError,
+ "incompatible types, %s instance instead of %s instance",
+ value->ob_type->tp_name,
+ ((PyTypeObject *)type)->tp_name);
+ return NULL;
+}
+
+/*
+ * Set a slice in object 'dst', which has the type 'type',
+ * to the value 'value'.
+ */
+int
+CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
+ Py_ssize_t index, Py_ssize_t size, char *ptr)
+{
+ CDataObject *mem = (CDataObject *)dst;
+ PyObject *result;
+
+ if (!CDataObject_Check(dst)) {
+ PyErr_SetString(PyExc_TypeError,
+ "not a ctype instance");
+ return -1;
+ }
+
+ result = _CData_set(mem, type, setfunc, value,
+ size, ptr);
+ if (result == NULL)
+ return -1;
+
+ /* KeepRef steals a refcount from it's last argument */
+ /* If KeepRef fails, we are stumped. The dst memory block has already
+ been changed */
+ return KeepRef(mem, index, result);
+}
+
+
+/******************************************************************/
+static PyObject *
+GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CDataObject *obj;
+ StgDictObject *dict;
+
+ dict = PyType_stgdict((PyObject *)type);
+ if (!dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "abstract class");
+ return NULL;
+ }
+ dict->flags |= DICTFLAG_FINAL;
+
+ obj = (CDataObject *)type->tp_alloc(type, 0);
+ if (!obj)
+ return NULL;
+
+ obj->b_base = NULL;
+ obj->b_index = 0;
+ obj->b_objects = NULL;
+ obj->b_length = dict->length;
+
+ if (-1 == CData_MallocBuffer(obj, dict)) {
+ Py_DECREF(obj);
+ return NULL;
+ }
+ return (PyObject *)obj;
+}
+/*****************************************************************/
+/*
+ CFuncPtr_Type
+*/
+
+static int
+CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob)
+{
+ if (ob && !PyCallable_Check(ob)) {
+ PyErr_SetString(PyExc_TypeError,
+ "the errcheck attribute must be callable");
+ return -1;
+ }
+ Py_XDECREF(self->errcheck);
+ Py_XINCREF(ob);
+ self->errcheck = ob;
+ return 0;
+}
+
+static PyObject *
+CFuncPtr_get_errcheck(CFuncPtrObject *self)
+{
+ if (self->errcheck) {
+ Py_INCREF(self->errcheck);
+ return self->errcheck;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int
+CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob)
+{
+ if (ob == NULL) {
+ Py_XDECREF(self->restype);
+ self->restype = NULL;
+ Py_XDECREF(self->checker);
+ self->checker = NULL;
+ return 0;
+ }
+ if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
+ PyErr_SetString(PyExc_TypeError,
+ "restype must be a type, a callable, or None");
+ return -1;
+ }
+ Py_XDECREF(self->checker);
+ Py_XDECREF(self->restype);
+ Py_INCREF(ob);
+ self->restype = ob;
+ self->checker = PyObject_GetAttrString(ob, "_check_retval_");
+ if (self->checker == NULL)
+ PyErr_Clear();
+ return 0;
+}
+
+static PyObject *
+CFuncPtr_get_restype(CFuncPtrObject *self)
+{
+ StgDictObject *dict;
+ if (self->restype) {
+ Py_INCREF(self->restype);
+ return self->restype;
+ }
+ dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
+ if (dict->restype) {
+ Py_INCREF(dict->restype);
+ return dict->restype;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static int
+CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob)
+{
+ PyObject *converters;
+
+ if (ob == NULL || ob == Py_None) {
+ Py_XDECREF(self->converters);
+ self->converters = NULL;
+ Py_XDECREF(self->argtypes);
+ self->argtypes = NULL;
+ } else {
+ converters = converters_from_argtypes(ob);
+ if (!converters)
+ return -1;
+ Py_XDECREF(self->converters);
+ self->converters = converters;
+ Py_XDECREF(self->argtypes);
+ Py_INCREF(ob);
+ self->argtypes = ob;
+ }
+ return 0;
+}
+
+static PyObject *
+CFuncPtr_get_argtypes(CFuncPtrObject *self)
+{
+ StgDictObject *dict;
+ if (self->argtypes) {
+ Py_INCREF(self->argtypes);
+ return self->argtypes;
+ }
+ dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
+ if (dict->argtypes) {
+ Py_INCREF(dict->argtypes);
+ return dict->argtypes;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static PyGetSetDef CFuncPtr_getsets[] = {
+ { "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck,
+ "a function to check for errors", NULL },
+ { "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype,
+ "specify the result type", NULL },
+ { "argtypes", (getter)CFuncPtr_get_argtypes,
+ (setter)CFuncPtr_set_argtypes,
+ "specify the argument types", NULL },
+ { NULL, NULL }
+};
+
+#ifdef MS_WIN32
+static PPROC FindAddress(void *handle, char *name, PyObject *type)
+{
+ PPROC address;
+ char *mangled_name;
+ int i;
+ StgDictObject *dict = PyType_stgdict((PyObject *)type);
+
+ address = (PPROC)GetProcAddress(handle, name);
+ if (address)
+ return address;
+
+ if (((size_t)name & ~0xFFFF) == 0) {
+ return NULL;
+ }
+
+ /* It should not happen that dict is NULL, but better be safe */
+ if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
+ return address;
+
+ /* for stdcall, try mangled names:
+ funcname -> _funcname@<n>
+ where n is 0, 4, 8, 12, ..., 128
+ */
+ mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
+ if (!mangled_name)
+ return NULL;
+ for (i = 0; i < 32; ++i) {
+ sprintf(mangled_name, "_%s@%d", name, i*4);
+ address = (PPROC)GetProcAddress(handle, mangled_name);
+ if (address)
+ return address;
+ }
+ return NULL;
+}
+#endif
+
+/* Return 1 if usable, 0 else and exception set. */
+static int
+_check_outarg_type(PyObject *arg, int index)
+{
+ StgDictObject *dict;
+
+ if (PointerTypeObject_Check(arg))
+ return 1;
+
+ if (ArrayTypeObject_Check(arg))
+ return 1;
+
+ dict = PyType_stgdict(arg);
+ if (dict
+ /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
+ && PyString_Check(dict->proto)
+/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
+ && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
+ return 1;
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "'out' parameter %d must be a pointer type, not %s",
+ index,
+ PyType_Check(arg) ?
+ ((PyTypeObject *)arg)->tp_name :
+ arg->ob_type->tp_name);
+ return 0;
+}
+
+/* Returns 1 on success, 0 on error */
+static int
+_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
+{
+ int i, len;
+ StgDictObject *dict;
+ PyObject *argtypes;
+
+ dict = PyType_stgdict((PyObject *)type);
+ assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */
+ argtypes = dict->argtypes;
+
+ if (paramflags == NULL || dict->argtypes == NULL)
+ return 1;
+
+ if (!PyTuple_Check(paramflags)) {
+ PyErr_SetString(PyExc_TypeError,
+ "paramflags must be a tuple or None");
+ return 0;
+ }
+
+ len = PyTuple_GET_SIZE(paramflags);
+ if (len != PyTuple_GET_SIZE(dict->argtypes)) {
+ PyErr_SetString(PyExc_ValueError,
+ "paramflags must have the same length as argtypes");
+ return 0;
+ }
+
+ for (i = 0; i < len; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(paramflags, i);
+ int flag;
+ char *name;
+ PyObject *defval;
+ PyObject *typ;
+ if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
+ PyErr_SetString(PyExc_TypeError,
+ "paramflags must be a sequence of (int [,string [,value]]) tuples");
+ return 0;
+ }
+ typ = PyTuple_GET_ITEM(argtypes, i);
+ switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
+ case 0:
+ case PARAMFLAG_FIN:
+ case PARAMFLAG_FIN | PARAMFLAG_FLCID:
+ case PARAMFLAG_FIN | PARAMFLAG_FOUT:
+ break;
+ case PARAMFLAG_FOUT:
+ if (!_check_outarg_type(typ, i+1))
+ return 0;
+ break;
+ default:
+ PyErr_Format(PyExc_TypeError,
+ "paramflag value %d not supported",
+ flag);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+_get_name(PyObject *obj, char **pname)
+{
+#ifdef MS_WIN32
+ if (PyInt_Check(obj) || PyLong_Check(obj)) {
+ /* We have to use MAKEINTRESOURCEA for Windows CE.
+ Works on Windows as well, of course.
+ */
+ *pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
+ return 1;
+ }
+#endif
+ if (PyString_Check(obj) || PyUnicode_Check(obj)) {
+ *pname = PyString_AsString(obj);
+ return *pname ? 1 : 0;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "function name must be string or integer");
+ return 0;
+}
+
+
+static PyObject *
+CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ char *name;
+ int (* address)(void);
+ PyObject *dll;
+ PyObject *obj;
+ CFuncPtrObject *self;
+ void *handle;
+ PyObject *paramflags = NULL;
+
+ if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
+ return NULL;
+ if (paramflags == Py_None)
+ paramflags = NULL;
+
+ obj = PyObject_GetAttrString(dll, "_handle");
+ if (!obj)
+ return NULL;
+ if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "the _handle attribute of the second argument must be an integer");
+ Py_DECREF(obj);
+ return NULL;
+ }
+ handle = (void *)PyLong_AsVoidPtr(obj);
+ Py_DECREF(obj);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ValueError,
+ "could not convert the _handle attribute to a pointer");
+ return NULL;
+ }
+
+#ifdef MS_WIN32
+ address = FindAddress(handle, name, (PyObject *)type);
+ if (!address) {
+ if (!IS_INTRESOURCE(name))
+ PyErr_Format(PyExc_AttributeError,
+ "function '%s' not found",
+ name);
+ else
+ PyErr_Format(PyExc_AttributeError,
+ "function ordinal %d not found",
+ (WORD)(size_t)name);
+ return NULL;
+ }
+#else
+ address = (PPROC)ctypes_dlsym(handle, name);
+ if (!address) {
+ PyErr_Format(PyExc_AttributeError,
+#ifdef __CYGWIN__
+/* dlerror() isn't very helpful on cygwin */
+ "function '%s' not found (%s) ",
+ name,
+#endif
+ ctypes_dlerror());
+ return NULL;
+ }
+#endif
+ if (!_validate_paramflags(type, paramflags))
+ return NULL;
+
+ self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
+ if (!self)
+ return NULL;
+
+ Py_XINCREF(paramflags);
+ self->paramflags = paramflags;
+
+ *(void **)self->b_ptr = address;
+
+ Py_INCREF((PyObject *)dll); /* for KeepRef */
+ if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
+ Py_DECREF((PyObject *)self);
+ return NULL;
+ }
+
+ Py_INCREF(self);
+ self->callable = (PyObject *)self;
+ return (PyObject *)self;
+}
+
+#ifdef MS_WIN32
+static PyObject *
+CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CFuncPtrObject *self;
+ int index;
+ char *name = NULL;
+ PyObject *paramflags = NULL;
+ GUID *iid = NULL;
+ int iid_len = 0;
+
+ if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
+ return NULL;
+ if (paramflags == Py_None)
+ paramflags = NULL;
+
+ if (!_validate_paramflags(type, paramflags))
+ return NULL;
+
+ self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
+ self->index = index + 0x1000;
+ Py_XINCREF(paramflags);
+ self->paramflags = paramflags;
+ if (iid_len == sizeof(GUID))
+ self->iid = iid;
+ return (PyObject *)self;
+}
+#endif
+
+/*
+ CFuncPtr_new accepts different argument lists in addition to the standard
+ _basespec_ keyword arg:
+
+ one argument form
+ "i" - function address
+ "O" - must be a callable, creates a C callable function
+
+ two or more argument forms (the third argument is a paramflags tuple)
+ "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
+ "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
+ "is|..." - vtable index, method name, creates callable calling COM vtbl
+*/
+static PyObject *
+CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CFuncPtrObject *self;
+ PyObject *callable;
+ StgDictObject *dict;
+ ffi_info *thunk;
+
+ if (PyTuple_GET_SIZE(args) == 0)
+ return GenericCData_new(type, args, kwds);
+
+ if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
+ return CFuncPtr_FromDll(type, args, kwds);
+
+#ifdef MS_WIN32
+ if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
+ return CFuncPtr_FromVtblIndex(type, args, kwds);
+#endif
+
+ if (1 == PyTuple_GET_SIZE(args)
+ && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
+ || PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
+ CDataObject *ob;
+ void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
+ if (ptr == NULL)
+ return NULL;
+ ob = (CDataObject *)GenericCData_new(type, args, kwds);
+ if (ob == NULL)
+ return NULL;
+ *(void **)ob->b_ptr = ptr;
+ return (PyObject *)ob;
+ }
+
+ if (!PyArg_ParseTuple(args, "O", &callable))
+ return NULL;
+ if (!PyCallable_Check(callable)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument must be callable or integer function address");
+ return NULL;
+ }
+
+ /* XXX XXX This would allow to pass additional options. For COM
+ method *implementations*, we would probably want different
+ behaviour than in 'normal' callback functions: return a HRESULT if
+ an exception occurrs in the callback, and print the traceback not
+ only on the console, but also to OutputDebugString() or something
+ like that.
+ */
+/*
+ if (kwds && PyDict_GetItemString(kwds, "options")) {
+ ...
+ }
+*/
+
+ dict = PyType_stgdict((PyObject *)type);
+ /* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */
+ if (!dict || !dict->argtypes) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot construct instance of this class:"
+ " no argtypes");
+ return NULL;
+ }
+
+ /*****************************************************************/
+ /* The thunk keeps unowned references to callable and dict->argtypes
+ so we have to keep them alive somewhere else: callable is kept in self,
+ dict->argtypes is in the type's stgdict.
+ */
+ thunk = AllocFunctionCallback(callable,
+ dict->argtypes,
+ dict->restype,
+ dict->flags & FUNCFLAG_CDECL);
+ if (!thunk)
+ return NULL;
+
+ self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
+ if (self == NULL)
+ return NULL;
+
+ Py_INCREF(callable);
+ self->callable = callable;
+
+ self->thunk = thunk;
+ *(void **)self->b_ptr = *(void **)thunk;
+
+ /* We store ourself in self->b_objects[0], because the whole instance
+ must be kept alive if stored in a structure field, for example.
+ Cycle GC to the rescue! And we have a unittest proving that this works
+ correctly...
+ */
+
+ Py_INCREF((PyObject *)self); /* for KeepRef */
+ if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) {
+ Py_DECREF((PyObject *)self);
+ return NULL;
+ }
+
+ return (PyObject *)self;
+}
+
+
+/*
+ _byref consumes a refcount to its argument
+*/
+static PyObject *
+_byref(PyObject *obj)
+{
+ PyCArgObject *parg;
+ if (!CDataObject_Check(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected CData instance");
+ return NULL;
+ }
+
+ parg = new_CArgObject();
+ if (parg == NULL) {
+ Py_DECREF(obj);
+ return NULL;
+ }
+
+ parg->tag = 'P';
+ parg->pffi_type = &ffi_type_pointer;
+ parg->obj = obj;
+ parg->value.p = ((CDataObject *)obj)->b_ptr;
+ return (PyObject *)parg;
+}
+
+static PyObject *
+_get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
+{
+ PyObject *v;
+
+ if (*pindex < PyTuple_GET_SIZE(inargs)) {
+ v = PyTuple_GET_ITEM(inargs, *pindex);
+ ++*pindex;
+ Py_INCREF(v);
+ return v;
+ }
+ if (kwds && (v = PyDict_GetItemString(kwds, name))) {
+ ++*pindex;
+ Py_INCREF(v);
+ return v;
+ }
+ if (defval) {
+ Py_INCREF(defval);
+ return defval;
+ }
+ /* we can't currently emit a better error message */
+ if (name)
+ PyErr_Format(PyExc_TypeError,
+ "required argument '%s' missing", name);
+ else
+ PyErr_Format(PyExc_TypeError,
+ "not enough arguments");
+ return NULL;
+}
+
+/*
+ This function implements higher level functionality plus the ability to call
+ functions with keyword arguments by looking at parameter flags. parameter
+ flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
+ specifying the direction of the data transfer for this parameter - 'in',
+ 'out' or 'inout' (zero means the same as 'in'). The second entry is the
+ parameter name, and the third is the default value if the parameter is
+ missing in the function call.
+
+ This function builds and returns a new tuple 'callargs' which contains the
+ parameters to use in the call. Items on this tuple are copied from the
+ 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
+ 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
+ is the number of return values for the function, outmask/inoutmask are
+ bitmasks containing indexes into the callargs tuple specifying which
+ parameters have to be returned. _build_result builds the return value of the
+ function.
+*/
+static PyObject *
+_build_callargs(CFuncPtrObject *self, PyObject *argtypes,
+ PyObject *inargs, PyObject *kwds,
+ int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
+{
+ PyObject *paramflags = self->paramflags;
+ PyObject *callargs;
+ StgDictObject *dict;
+ int i, len;
+ int inargs_index = 0;
+ /* It's a little bit difficult to determine how many arguments the
+ function call requires/accepts. For simplicity, we count the consumed
+ args and compare this to the number of supplied args. */
+ int actual_args;
+
+ *poutmask = 0;
+ *pinoutmask = 0;
+ *pnumretvals = 0;
+
+ /* Trivial cases, where we either return inargs itself, or a slice of it. */
+ if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
+#ifdef MS_WIN32
+ if (self->index)
+ return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
+#endif
+ Py_INCREF(inargs);
+ return inargs;
+ }
+
+ len = PyTuple_GET_SIZE(argtypes);
+ callargs = PyTuple_New(len); /* the argument tuple we build */
+ if (callargs == NULL)
+ return NULL;
+
+#ifdef MS_WIN32
+ /* For a COM method, skip the first arg */
+ if (self->index) {
+ inargs_index = 1;
+ }
+#endif
+ for (i = 0; i < len; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(paramflags, i);
+ PyObject *ob;
+ int flag;
+ char *name = NULL;
+ PyObject *defval = NULL;
+
+ /* This way seems to be ~2 us faster than the PyArg_ParseTuple
+ calls below. */
+ /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
+ int tsize = PyTuple_GET_SIZE(item);
+ flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
+ name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
+ defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
+
+ switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
+ case PARAMFLAG_FIN | PARAMFLAG_FLCID:
+ /* ['in', 'lcid'] parameter. Always taken from defval,
+ if given, else the integer 0. */
+ if (defval == NULL) {
+ defval = PyInt_FromLong(0);
+ if (defval == NULL)
+ goto error;
+ } else
+ Py_INCREF(defval);
+ PyTuple_SET_ITEM(callargs, i, defval);
+ break;
+ case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
+ *pinoutmask |= (1 << i); /* mark as inout arg */
+ (*pnumretvals)++;
+ /* fall through to PARAMFLAG_FIN... */
+ case 0:
+ case PARAMFLAG_FIN:
+ /* 'in' parameter. Copy it from inargs. */
+ ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
+ if (ob == NULL)
+ goto error;
+ PyTuple_SET_ITEM(callargs, i, ob);
+ break;
+ case PARAMFLAG_FOUT:
+ /* XXX Refactor this code into a separate function. */
+ /* 'out' parameter.
+ argtypes[i] must be a POINTER to a c type.
+
+ Cannot by supplied in inargs, but a defval will be used
+ if available. XXX Should we support getting it from kwds?
+ */
+ if (defval) {
+ /* XXX Using mutable objects as defval will
+ make the function non-threadsafe, unless we
+ copy the object in each invocation */
+ Py_INCREF(defval);
+ PyTuple_SET_ITEM(callargs, i, defval);
+ *poutmask |= (1 << i); /* mark as out arg */
+ (*pnumretvals)++;
+ break;
+ }
+ ob = PyTuple_GET_ITEM(argtypes, i);
+ dict = PyType_stgdict(ob);
+ if (dict == NULL) {
+ /* Cannot happen: _validate_paramflags()
+ would not accept such an object */
+ PyErr_Format(PyExc_RuntimeError,
+ "NULL stgdict unexpected");
+ goto error;
+ }
+ if (PyString_Check(dict->proto)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s 'out' parameter must be passed as default value",
+ ((PyTypeObject *)ob)->tp_name);
+ goto error;
+ }
+ if (ArrayTypeObject_Check(ob))
+ ob = PyObject_CallObject(ob, NULL);
+ else
+ /* Create an instance of the pointed-to type */
+ ob = PyObject_CallObject(dict->proto, NULL);
+ /*
+ XXX Is the following correct any longer?
+ We must not pass a byref() to the array then but
+ the array instance itself. Then, we cannot retrive
+ the result from the PyCArgObject.
+ */
+ if (ob == NULL)
+ goto error;
+ /* The .from_param call that will ocurr later will pass this
+ as a byref parameter. */
+ PyTuple_SET_ITEM(callargs, i, ob);
+ *poutmask |= (1 << i); /* mark as out arg */
+ (*pnumretvals)++;
+ break;
+ default:
+ PyErr_Format(PyExc_ValueError,
+ "paramflag %d not yet implemented", flag);
+ goto error;
+ break;
+ }
+ }
+
+ /* We have counted the arguments we have consumed in 'inargs_index'. This
+ must be the same as len(inargs) + len(kwds), otherwise we have
+ either too much or not enough arguments. */
+
+ actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
+ if (actual_args != inargs_index) {
+ /* When we have default values or named parameters, this error
+ message is misleading. See unittests/test_paramflags.py
+ */
+ PyErr_Format(PyExc_TypeError,
+ "call takes exactly %d arguments (%d given)",
+ inargs_index, actual_args);
+ goto error;
+ }
+
+ /* outmask is a bitmask containing indexes into callargs. Items at
+ these indexes contain values to return.
+ */
+ return callargs;
+ error:
+ Py_DECREF(callargs);
+ return NULL;
+}
+
+/* See also:
+ http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
+*/
+/*
+ Build return value of a function.
+
+ Consumes the refcount on result and callargs.
+*/
+static PyObject *
+_build_result(PyObject *result, PyObject *callargs,
+ int outmask, int inoutmask, unsigned int numretvals)
+{
+ unsigned int i, index;
+ int bit;
+ PyObject *tup = NULL;
+
+ if (callargs == NULL)
+ return result;
+ if (result == NULL || numretvals == 0) {
+ Py_DECREF(callargs);
+ return result;
+ }
+ Py_DECREF(result);
+
+ /* tup will not be allocated if numretvals == 1 */
+ /* allocate tuple to hold the result */
+ if (numretvals > 1) {
+ tup = PyTuple_New(numretvals);
+ if (tup == NULL) {
+ Py_DECREF(callargs);
+ return NULL;
+ }
+ }
+
+ index = 0;
+ for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
+ PyObject *v;
+ if (bit & inoutmask) {
+ v = PyTuple_GET_ITEM(callargs, i);
+ Py_INCREF(v);
+ if (numretvals == 1) {
+ Py_DECREF(callargs);
+ return v;
+ }
+ PyTuple_SET_ITEM(tup, index, v);
+ index++;
+ } else if (bit & outmask) {
+ v = PyTuple_GET_ITEM(callargs, i);
+ v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
+ if (v == NULL || numretvals == 1) {
+ Py_DECREF(callargs);
+ return v;
+ }
+ PyTuple_SET_ITEM(tup, index, v);
+ index++;
+ }
+ if (index == numretvals)
+ break;
+ }
+
+ Py_DECREF(callargs);
+ return tup;
+}
+
+static PyObject *
+CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
+{
+ PyObject *restype;
+ PyObject *converters;
+ PyObject *checker;
+ PyObject *argtypes;
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ PyObject *result;
+ PyObject *callargs;
+ PyObject *errcheck;
+#ifdef MS_WIN32
+ IUnknown *piunk = NULL;
+#endif
+ void *pProc = NULL;
+
+ int inoutmask;
+ int outmask;
+ unsigned int numretvals;
+
+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
+ restype = self->restype ? self->restype : dict->restype;
+ converters = self->converters ? self->converters : dict->converters;
+ checker = self->checker ? self->checker : dict->checker;
+ argtypes = self->argtypes ? self->argtypes : dict->argtypes;
+/* later, we probably want to have an errcheck field in stgdict */
+ errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
+
+
+ pProc = *(void **)self->b_ptr;
+#ifdef MS_WIN32
+ if (self->index) {
+ /* It's a COM method */
+ CDataObject *this;
+ this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
+ if (!this) {
+ PyErr_SetString(PyExc_ValueError,
+ "native com method call without 'this' parameter");
+ return NULL;
+ }
+ if (!CDataObject_Check(this)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Expected a COM this pointer as first argument");
+ return NULL;
+ }
+ /* there should be more checks? No, in Python */
+ /* First arg is an pointer to an interface instance */
+ if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "NULL COM pointer access");
+ return NULL;
+ }
+ piunk = *(IUnknown **)this->b_ptr;
+ if (NULL == piunk->lpVtbl) {
+ PyErr_SetString(PyExc_ValueError,
+ "COM method call without VTable");
+ return NULL;
+ }
+ pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
+ }
+#endif
+ callargs = _build_callargs(self, argtypes,
+ inargs, kwds,
+ &outmask, &inoutmask, &numretvals);
+ if (callargs == NULL)
+ return NULL;
+
+ if (converters) {
+ int required = PyTuple_GET_SIZE(converters);
+ int actual = PyTuple_GET_SIZE(callargs);
+
+ if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
+ /* For cdecl functions, we allow more actual arguments
+ than the length of the argtypes tuple.
+ */
+ if (required > actual) {
+ Py_DECREF(callargs);
+ PyErr_Format(PyExc_TypeError,
+ "this function takes at least %d argument%s (%d given)",
+ required,
+ required == 1 ? "" : "s",
+ actual);
+ return NULL;
+ }
+ } else if (required != actual) {
+ Py_DECREF(callargs);
+ PyErr_Format(PyExc_TypeError,
+ "this function takes %d argument%s (%d given)",
+ required,
+ required == 1 ? "" : "s",
+ actual);
+ return NULL;
+ }
+ }
+
+ result = _CallProc(pProc,
+ callargs,
+#ifdef MS_WIN32
+ piunk,
+ self->iid,
+#endif
+ dict->flags,
+ converters,
+ restype,
+ checker);
+/* The 'errcheck' protocol */
+ if (result != NULL && errcheck) {
+ PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
+ result,
+ self,
+ callargs,
+ NULL);
+ /* If the errcheck funtion failed, return NULL.
+ If the errcheck function returned callargs unchanged,
+ continue normal processing.
+ If the errcheck function returned something else,
+ use that as result.
+ */
+ if (v == NULL || v != callargs) {
+ Py_DECREF(result);
+ Py_DECREF(callargs);
+ return v;
+ }
+ Py_DECREF(v);
+ }
+
+ return _build_result(result, callargs,
+ outmask, inoutmask, numretvals);
+}
+
+static int
+CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->callable);
+ Py_VISIT(self->restype);
+ Py_VISIT(self->checker);
+ Py_VISIT(self->errcheck);
+ Py_VISIT(self->argtypes);
+ Py_VISIT(self->converters);
+ Py_VISIT(self->paramflags);
+ return CData_traverse((CDataObject *)self, visit, arg);
+}
+
+static int
+CFuncPtr_clear(CFuncPtrObject *self)
+{
+ Py_CLEAR(self->callable);
+ Py_CLEAR(self->restype);
+ Py_CLEAR(self->checker);
+ Py_CLEAR(self->errcheck);
+ Py_CLEAR(self->argtypes);
+ Py_CLEAR(self->converters);
+ Py_CLEAR(self->paramflags);
+
+ if (self->thunk) {
+ FreeClosure(self->thunk->pcl);
+ PyMem_Free(self->thunk);
+ self->thunk = NULL;
+ }
+
+ return CData_clear((CDataObject *)self);
+}
+
+static void
+CFuncPtr_dealloc(CFuncPtrObject *self)
+{
+ CFuncPtr_clear(self);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+CFuncPtr_repr(CFuncPtrObject *self)
+{
+#ifdef MS_WIN32
+ if (self->index)
+ return PyString_FromFormat("<COM method offset %d: %s at %p>",
+ self->index - 0x1000,
+ self->ob_type->tp_name,
+ self);
+#endif
+ return PyString_FromFormat("<%s object at %p>",
+ self->ob_type->tp_name,
+ self);
+}
+
+PyTypeObject CFuncPtr_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes.CFuncPtr",
+ sizeof(CFuncPtrObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)CFuncPtr_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)CFuncPtr_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)CFuncPtr_call, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Function Pointer", /* tp_doc */
+ (traverseproc)CFuncPtr_traverse, /* tp_traverse */
+ (inquiry)CFuncPtr_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ CFuncPtr_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ CFuncPtr_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/*****************************************************************/
+/*
+ Struct_Type
+*/
+static int
+IBUG(char *msg)
+{
+ PyErr_Format(PyExc_RuntimeError,
+ "inconsistent state in CDataObject (%s)", msg);
+ return -1;
+}
+
+static int
+Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int i;
+ PyObject *fields;
+
+/* Optimization possible: Store the attribute names _fields_[x][0]
+ * in C accessible fields somewhere ?
+ */
+
+/* Check this code again for correctness! */
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "args not a tuple?");
+ return -1;
+ }
+ if (PyTuple_GET_SIZE(args)) {
+ fields = PyObject_GetAttrString(self, "_fields_");
+ if (!fields) {
+ PyErr_Clear();
+ fields = PyTuple_New(0);
+ if (!fields)
+ return -1;
+ }
+
+ if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) {
+ Py_DECREF(fields);
+ PyErr_SetString(PyExc_ValueError,
+ "too many initializers");
+ return -1;
+ }
+
+ for (i = 0; i < PyTuple_GET_SIZE(args); ++i) {
+ PyObject *pair = PySequence_GetItem(fields, i);
+ PyObject *name;
+ PyObject *val;
+ if (!pair) {
+ Py_DECREF(fields);
+ return IBUG("_fields_[i] failed");
+ }
+
+ name = PySequence_GetItem(pair, 0);
+ if (!name) {
+ Py_DECREF(pair);
+ Py_DECREF(fields);
+ return IBUG("_fields_[i][0] failed");
+ }
+
+ val = PyTuple_GET_ITEM(args, i);
+ if (-1 == PyObject_SetAttr(self, name, val)) {
+ Py_DECREF(pair);
+ Py_DECREF(name);
+ Py_DECREF(fields);
+ return -1;
+ }
+
+ Py_DECREF(name);
+ Py_DECREF(pair);
+ }
+ Py_DECREF(fields);
+ }
+
+ if (kwds) {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while(PyDict_Next(kwds, &pos, &key, &value)) {
+ if (-1 == PyObject_SetAttr(self, key, value))
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static PyTypeObject Struct_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes.Structure",
+ sizeof(CDataObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Structure base class", /* tp_doc */
+ (traverseproc)CData_traverse, /* tp_traverse */
+ (inquiry)CData_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ Struct_init, /* tp_init */
+ 0, /* tp_alloc */
+ GenericCData_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+static PyTypeObject Union_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes.Union",
+ sizeof(CDataObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "Union base class", /* tp_doc */
+ (traverseproc)CData_traverse, /* tp_traverse */
+ (inquiry)CData_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ Struct_init, /* tp_init */
+ 0, /* tp_alloc */
+ GenericCData_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/******************************************************************/
+/*
+ Array_Type
+*/
+static int
+Array_init(CDataObject *self, PyObject *args, PyObject *kw)
+{
+ int i;
+ int n;
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "args not a tuple?");
+ return -1;
+ }
+ n = PyTuple_GET_SIZE(args);
+ for (i = 0; i < n; ++i) {
+ PyObject *v;
+ v = PyTuple_GET_ITEM(args, i);
+ if (-1 == PySequence_SetItem((PyObject *)self, i, v))
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+Array_item(PyObject *_self, Py_ssize_t index)
+{
+ CDataObject *self = (CDataObject *)_self;
+ int offset, size;
+ StgDictObject *stgdict;
+
+
+ if (index < 0 || index >= self->b_length) {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid index");
+ return NULL;
+ }
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for array instances */
+ /* Would it be clearer if we got the item size from
+ stgdict->proto's stgdict?
+ */
+ size = stgdict->size / stgdict->length;
+ offset = index * size;
+
+ return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
+ index, size, self->b_ptr + offset);
+}
+
+static PyObject *
+Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+ CDataObject *self = (CDataObject *)_self;
+ StgDictObject *stgdict, *itemdict;
+ PyObject *proto;
+ PyListObject *np;
+ Py_ssize_t i, len;
+
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > self->b_length)
+ ilow = self->b_length;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > self->b_length)
+ ihigh = self->b_length;
+ len = ihigh - ilow;
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for array object instances */
+ proto = stgdict->proto;
+ itemdict = PyType_stgdict(proto);
+ assert(itemdict); /* proto is the item type of the array, a ctypes
+ type, so this cannot be NULL */
+ if (itemdict->getfunc == getentry("c")->getfunc) {
+ char *ptr = (char *)self->b_ptr;
+ return PyString_FromStringAndSize(ptr + ilow, len);
+#ifdef CTYPES_UNICODE
+ } else if (itemdict->getfunc == getentry("u")->getfunc) {
+ wchar_t *ptr = (wchar_t *)self->b_ptr;
+ return PyUnicode_FromWideChar(ptr + ilow, len);
+#endif
+ }
+
+ np = (PyListObject *) PyList_New(len);
+ if (np == NULL)
+ return NULL;
+
+ for (i = 0; i < len; i++) {
+ PyObject *v = Array_item(_self, i+ilow);
+ PyList_SET_ITEM(np, i, v);
+ }
+ return (PyObject *)np;
+}
+
+static int
+Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
+{
+ CDataObject *self = (CDataObject *)_self;
+ int size, offset;
+ StgDictObject *stgdict;
+ char *ptr;
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Array does not support item deletion");
+ return -1;
+ }
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for array object instances */
+ if (index < 0 || index >= stgdict->length) {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid index");
+ return -1;
+ }
+ size = stgdict->size / stgdict->length;
+ offset = index * size;
+ ptr = self->b_ptr + offset;
+
+ return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
+ index, size, ptr);
+}
+
+static int
+Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
+{
+ CDataObject *self = (CDataObject *)_self;
+ int i, len;
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Array does not support item deletion");
+ return -1;
+ }
+
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > self->b_length)
+ ilow = self->b_length;
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > self->b_length)
+ ihigh = self->b_length;
+
+ len = PySequence_Length(value);
+ if (len != ihigh - ilow) {
+ PyErr_SetString(PyExc_ValueError,
+ "Can only assign sequence of same size");
+ return -1;
+ }
+ for (i = 0; i < len; i++) {
+ PyObject *item = PySequence_GetItem(value, i);
+ int result;
+ if (item == NULL)
+ return -1;
+ result = Array_ass_item(_self, i+ilow, item);
+ Py_DECREF(item);
+ if (result == -1)
+ return -1;
+ }
+ return 0;
+}
+
+static Py_ssize_t
+Array_length(PyObject *_self)
+{
+ CDataObject *self = (CDataObject *)_self;
+ return self->b_length;
+}
+
+static PySequenceMethods Array_as_sequence = {
+ Array_length, /* sq_length; */
+ 0, /* sq_concat; */
+ 0, /* sq_repeat; */
+ Array_item, /* sq_item; */
+ Array_slice, /* sq_slice; */
+ Array_ass_item, /* sq_ass_item; */
+ Array_ass_slice, /* sq_ass_slice; */
+ 0, /* sq_contains; */
+
+ 0, /* sq_inplace_concat; */
+ 0, /* sq_inplace_repeat; */
+};
+
+PyTypeObject Array_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes.Array",
+ sizeof(CDataObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &Array_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "XXX to be provided", /* tp_doc */
+ (traverseproc)CData_traverse, /* tp_traverse */
+ (inquiry)CData_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)Array_init, /* tp_init */
+ 0, /* tp_alloc */
+ GenericCData_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+PyObject *
+CreateArrayType(PyObject *itemtype, Py_ssize_t length)
+{
+ static PyObject *cache;
+ PyObject *key;
+ PyObject *result;
+ char name[256];
+
+ if (cache == NULL) {
+ cache = PyDict_New();
+ if (cache == NULL)
+ return NULL;
+ }
+#if (PY_VERSION_HEX < 0x02050000)
+ key = Py_BuildValue("(Oi)", itemtype, length);
+#else
+ key = Py_BuildValue("(On)", itemtype, length);
+#endif
+ if (!key)
+ return NULL;
+ result = PyDict_GetItem(cache, key);
+ if (result) {
+ Py_INCREF(result);
+ Py_DECREF(key);
+ return result;
+ }
+
+ if (!PyType_Check(itemtype)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Expected a type object");
+ return NULL;
+ }
+#ifdef MS_WIN64
+ sprintf(name, "%.200s_Array_%Id",
+ ((PyTypeObject *)itemtype)->tp_name, length);
+#else
+ sprintf(name, "%.200s_Array_%ld",
+ ((PyTypeObject *)itemtype)->tp_name, (long)length);
+#endif
+
+ result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
+#if (PY_VERSION_HEX < 0x02050000)
+ "s(O){s:i,s:O}",
+#else
+ "s(O){s:n,s:O}",
+#endif
+ name,
+ &Array_Type,
+ "_length_",
+ length,
+ "_type_",
+ itemtype
+ );
+ if (!result)
+ return NULL;
+ PyDict_SetItem(cache, key, result);
+ Py_DECREF(key);
+ return result;
+}
+
+
+/******************************************************************/
+/*
+ Simple_Type
+*/
+
+static int
+Simple_set_value(CDataObject *self, PyObject *value)
+{
+ PyObject *result;
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+
+ assert(dict); /* Cannot be NULL for CDataObject instances */
+ assert(dict->setfunc);
+ result = dict->setfunc(self->b_ptr, value, dict->size);
+ if (!result)
+ return -1;
+
+ /* consumes the refcount the setfunc returns */
+ return KeepRef(self, 0, result);
+}
+
+static int
+Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *value = NULL;
+ if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
+ return -1;
+ if (value)
+ return Simple_set_value(self, value);
+ return 0;
+}
+
+static PyObject *
+Simple_get_value(CDataObject *self)
+{
+ StgDictObject *dict;
+ dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for CDataObject instances */
+ assert(dict->getfunc);
+ return dict->getfunc(self->b_ptr, self->b_size);
+}
+
+static PyGetSetDef Simple_getsets[] = {
+ { "value", (getter)Simple_get_value, (setter)Simple_set_value,
+ "current value", NULL },
+ { NULL, NULL }
+};
+
+static PyObject *
+Simple_from_outparm(PyObject *self, PyObject *args)
+{
+ if (IsSimpleSubType((PyObject *)self->ob_type)) {
+ Py_INCREF(self);
+ return self;
+ }
+ /* call stgdict->getfunc */
+ return Simple_get_value((CDataObject *)self);
+}
+
+static PyMethodDef Simple_methods[] = {
+ { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
+ { NULL, NULL },
+};
+
+static int Simple_nonzero(CDataObject *self)
+{
+ return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
+}
+
+static PyNumberMethods Simple_as_number = {
+ 0, /* nb_add */
+ 0, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ (inquiry)Simple_nonzero, /* nb_nonzero */
+};
+
+#if (PY_VERSION_HEX < 0x02040000)
+/* Only in Python 2.4 and up */
+static PyObject *
+PyTuple_Pack(int n, ...)
+{
+ int i;
+ PyObject *o;
+ PyObject *result;
+ PyObject **items;
+ va_list vargs;
+
+ va_start(vargs, n);
+ result = PyTuple_New(n);
+ if (result == NULL)
+ return NULL;
+ items = ((PyTupleObject *)result)->ob_item;
+ for (i = 0; i < n; i++) {
+ o = va_arg(vargs, PyObject *);
+ Py_INCREF(o);
+ items[i] = o;
+ }
+ va_end(vargs);
+ return result;
+}
+#endif
+
+/* "%s(%s)" % (self.__class__.__name__, self.value) */
+static PyObject *
+Simple_repr(CDataObject *self)
+{
+ PyObject *val, *name, *args, *result;
+ static PyObject *format;
+
+ if (self->ob_type->tp_base != &Simple_Type) {
+ return PyString_FromFormat("<%s object at %p>",
+ self->ob_type->tp_name, self);
+ }
+
+ if (format == NULL) {
+ format = PyString_FromString("%s(%r)");
+ if (format == NULL)
+ return NULL;
+ }
+
+ val = Simple_get_value(self);
+ if (val == NULL)
+ return NULL;
+
+ name = PyString_FromString(self->ob_type->tp_name);
+ if (name == NULL) {
+ Py_DECREF(val);
+ return NULL;
+ }
+
+ args = PyTuple_Pack(2, name, val);
+ Py_DECREF(name);
+ Py_DECREF(val);
+ if (args == NULL)
+ return NULL;
+
+ result = PyString_Format(format, args);
+ Py_DECREF(args);
+ return result;
+}
+
+static PyTypeObject Simple_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes._SimpleCData",
+ sizeof(CDataObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)&Simple_repr, /* tp_repr */
+ &Simple_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "XXX to be provided", /* tp_doc */
+ (traverseproc)CData_traverse, /* tp_traverse */
+ (inquiry)CData_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Simple_methods, /* tp_methods */
+ 0, /* tp_members */
+ Simple_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)Simple_init, /* tp_init */
+ 0, /* tp_alloc */
+ GenericCData_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/******************************************************************/
+/*
+ Pointer_Type
+*/
+static PyObject *
+Pointer_item(PyObject *_self, Py_ssize_t index)
+{
+ CDataObject *self = (CDataObject *)_self;
+ int size;
+ Py_ssize_t offset;
+ StgDictObject *stgdict, *itemdict;
+ PyObject *proto;
+
+ if (*(void **)self->b_ptr == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "NULL pointer access");
+ return NULL;
+ }
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL for pointer object instances */
+
+ proto = stgdict->proto;
+ assert(proto);
+ itemdict = PyType_stgdict(proto);
+ assert(itemdict); /* proto is the item type of the pointer, a ctypes
+ type, so this cannot be NULL */
+
+ size = itemdict->size;
+ offset = index * itemdict->size;
+
+ return CData_get(proto, stgdict->getfunc, (PyObject *)self,
+ index, size, (*(char **)self->b_ptr) + offset);
+}
+
+static int
+Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
+{
+ CDataObject *self = (CDataObject *)_self;
+ int size;
+ Py_ssize_t offset;
+ StgDictObject *stgdict, *itemdict;
+ PyObject *proto;
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Pointer does not support item deletion");
+ return -1;
+ }
+
+ if (*(void **)self->b_ptr == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "NULL pointer access");
+ return -1;
+ }
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
+
+ proto = stgdict->proto;
+ assert(proto);
+
+ itemdict = PyType_stgdict(proto);
+ assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
+ is always a ctypes type */
+
+ size = itemdict->size;
+ offset = index * itemdict->size;
+
+ return CData_set((PyObject *)self, proto, stgdict->setfunc, value,
+ index, size, (*(char **)self->b_ptr) + offset);
+}
+
+static PyObject *
+Pointer_get_contents(CDataObject *self, void *closure)
+{
+ StgDictObject *stgdict;
+
+ if (*(void **)self->b_ptr == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "NULL pointer access");
+ return NULL;
+ }
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
+ return CData_FromBaseObj(stgdict->proto,
+ (PyObject *)self, 0,
+ *(void **)self->b_ptr);
+}
+
+static int
+Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
+{
+ StgDictObject *stgdict;
+ CDataObject *dst;
+ PyObject *keep;
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Pointer does not support item deletion");
+ return -1;
+ }
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
+ assert(stgdict->proto);
+ if (!CDataObject_Check(value)
+ || 0 == PyObject_IsInstance(value, stgdict->proto)) {
+ /* XXX PyObject_IsInstance could return -1! */
+ PyErr_Format(PyExc_TypeError,
+ "expected %s instead of %s",
+ ((PyTypeObject *)(stgdict->proto))->tp_name,
+ value->ob_type->tp_name);
+ return -1;
+ }
+
+ dst = (CDataObject *)value;
+ *(void **)self->b_ptr = dst->b_ptr;
+
+ /*
+ A Pointer instance must keep a the value it points to alive. So, a
+ pointer instance has b_length set to 2 instead of 1, and we set
+ 'value' itself as the second item of the b_objects list, additionally.
+ */
+ Py_INCREF(value);
+ if (-1 == KeepRef(self, 1, value))
+ return -1;
+
+ keep = GetKeepedObjects(dst);
+ Py_INCREF(keep);
+ return KeepRef(self, 0, keep);
+}
+
+static PyGetSetDef Pointer_getsets[] = {
+ { "contents", (getter)Pointer_get_contents,
+ (setter)Pointer_set_contents,
+ "the object this pointer points to (read-write)", NULL },
+ { NULL, NULL }
+};
+
+static int
+Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *value = NULL;
+
+ if (!PyArg_ParseTuple(args, "|O:POINTER", &value))
+ return -1;
+ if (value == NULL)
+ return 0;
+ return Pointer_set_contents(self, value, NULL);
+}
+
+static PyObject *
+Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ StgDictObject *dict = PyType_stgdict((PyObject *)type);
+ if (!dict || !dict->proto) {
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot create instance: has no _type_");
+ return NULL;
+ }
+ return GenericCData_new(type, args, kw);
+}
+
+static PyObject *
+Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+ CDataObject *self = (CDataObject *)_self;
+ PyListObject *np;
+ StgDictObject *stgdict, *itemdict;
+ PyObject *proto;
+ Py_ssize_t i, len;
+
+ if (ilow < 0)
+ ilow = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ len = ihigh - ilow;
+
+ stgdict = PyObject_stgdict((PyObject *)self);
+ assert(stgdict); /* Cannot be NULL fr pointer instances */
+ proto = stgdict->proto;
+ assert(proto);
+ itemdict = PyType_stgdict(proto);
+ assert(itemdict);
+ if (itemdict->getfunc == getentry("c")->getfunc) {
+ char *ptr = *(char **)self->b_ptr;
+ return PyString_FromStringAndSize(ptr + ilow, len);
+#ifdef CTYPES_UNICODE
+ } else if (itemdict->getfunc == getentry("u")->getfunc) {
+ wchar_t *ptr = *(wchar_t **)self->b_ptr;
+ return PyUnicode_FromWideChar(ptr + ilow, len);
+#endif
+ }
+
+ np = (PyListObject *) PyList_New(len);
+ if (np == NULL)
+ return NULL;
+
+ for (i = 0; i < len; i++) {
+ PyObject *v = Pointer_item(_self, i+ilow);
+ PyList_SET_ITEM(np, i, v);
+ }
+ return (PyObject *)np;
+}
+
+static PySequenceMethods Pointer_as_sequence = {
+ 0, /* inquiry sq_length; */
+ 0, /* binaryfunc sq_concat; */
+ 0, /* intargfunc sq_repeat; */
+ Pointer_item, /* intargfunc sq_item; */
+ Pointer_slice, /* intintargfunc sq_slice; */
+ Pointer_ass_item, /* intobjargproc sq_ass_item; */
+ 0, /* intintobjargproc sq_ass_slice; */
+ 0, /* objobjproc sq_contains; */
+ /* Added in release 2.0 */
+ 0, /* binaryfunc sq_inplace_concat; */
+ 0, /* intargfunc sq_inplace_repeat; */
+};
+
+static int
+Pointer_nonzero(CDataObject *self)
+{
+ return *(void **)self->b_ptr != NULL;
+}
+
+static PyNumberMethods Pointer_as_number = {
+ 0, /* nb_add */
+ 0, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ (inquiry)Pointer_nonzero, /* nb_nonzero */
+};
+
+PyTypeObject Pointer_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "_ctypes._Pointer",
+ sizeof(CDataObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ &Pointer_as_number, /* tp_as_number */
+ &Pointer_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &CData_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "XXX to be provided", /* tp_doc */
+ (traverseproc)CData_traverse, /* tp_traverse */
+ (inquiry)CData_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ Pointer_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)Pointer_init, /* tp_init */
+ 0, /* tp_alloc */
+ Pointer_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/******************************************************************/
+/*
+ * Module initialization.
+ */
+
+static char *module_docs =
+"Create and manipulate C compatible data types in Python.";
+
+#ifdef MS_WIN32
+
+static char comerror_doc[] = "Raised when a COM method call failed.";
+
+static PyObject *
+comerror_str(PyObject *ignored, PyObject *self)
+{
+ PyObject *args = PyObject_GetAttrString(self, "args");
+ PyObject *result;
+ if (args == NULL)
+ return NULL;
+ result = PyObject_Str(args);
+ Py_DECREF(args);
+ return result;
+}
+
+static PyObject *
+comerror_init(PyObject *self, PyObject *args)
+{
+ PyObject *hresult, *text, *details;
+ PyObject *a;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
+ return NULL;
+
+ a = PySequence_GetSlice(args, 1, PySequence_Size(args));
+ if (!a)
+ return NULL;
+ status = PyObject_SetAttrString(self, "args", a);
+ Py_DECREF(a);
+ if (status < 0)
+ return NULL;
+
+ if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
+ return NULL;
+
+ if (PyObject_SetAttrString(self, "text", text) < 0)
+ return NULL;
+
+ if (PyObject_SetAttrString(self, "details", details) < 0)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef comerror_methods[] = {
+ { "__str__", comerror_str, METH_O },
+ { "__init__", comerror_init, METH_VARARGS },
+ { NULL, NULL },
+};
+
+PyObject *COMError;
+
+static int
+create_comerror(void)
+{
+ PyObject *dict = PyDict_New();
+ PyMethodDef *methods = comerror_methods;
+ PyObject *s;
+ int status;
+
+ ComError = PyErr_NewException("_ctypes.COMError",
+ NULL,
+ dict);
+ if (ComError == NULL)
+ return -1;
+ while (methods->ml_name) {
+ /* get a wrapper for the built-in function */
+ PyObject *func = PyCFunction_New(methods, NULL);
+ PyObject *meth;
+ if (func == NULL)
+ return -1;
+ meth = PyMethod_New(func, NULL, ComError);
+ Py_DECREF(func);
+ if (meth == NULL)
+ return -1;
+ PyDict_SetItemString(dict, methods->ml_name, meth);
+ Py_DECREF(meth);
+ ++methods;
+ }
+ Py_INCREF(ComError);
+ s = PyString_FromString(comerror_doc);
+ if (s == NULL)
+ return -1;
+ status = PyDict_SetItemString(dict, "__doc__", s);
+ Py_DECREF(s);
+ return status;
+}
+
+#endif
+
+static PyObject *
+string_at(const char *ptr, int size)
+{
+ if (size == -1)
+ return PyString_FromString(ptr);
+ return PyString_FromStringAndSize(ptr, size);
+}
+
+static int
+cast_check_pointertype(PyObject *arg)
+{
+ StgDictObject *dict;
+
+ if (PointerTypeObject_Check(arg))
+ return 1;
+ if (CFuncPtrTypeObject_Check(arg))
+ return 1;
+ dict = PyType_stgdict(arg);
+ if (dict) {
+ if (PyString_Check(dict->proto)
+ && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
+ /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
+ return 1;
+ }
+ }
+ PyErr_Format(PyExc_TypeError,
+ "cast() argument 2 must be a pointer type, not %s",
+ PyType_Check(arg)
+ ? ((PyTypeObject *)arg)->tp_name
+ : arg->ob_type->tp_name);
+ return 0;
+}
+
+static PyObject *
+cast(void *ptr, PyObject *src, PyObject *ctype)
+{
+ CDataObject *result;
+ if (0 == cast_check_pointertype(ctype))
+ return NULL;
+ result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
+ if (result == NULL)
+ return NULL;
+
+ /*
+ The casted objects '_objects' member:
+
+ It must certainly contain the source objects one.
+ It must contain the source object itself.
+ */
+ if (CDataObject_Check(src)) {
+ CDataObject *obj = (CDataObject *)src;
+ /* CData_GetContainer will initialize src.b_objects, we need
+ this so it can be shared */
+ CData_GetContainer(obj);
+ /* But we need a dictionary! */
+ if (obj->b_objects == Py_None) {
+ Py_DECREF(Py_None);
+ obj->b_objects = PyDict_New();
+ if (obj->b_objects == NULL)
+ goto failed;
+ }
+ Py_XINCREF(obj->b_objects);
+ result->b_objects = obj->b_objects;
+ if (result->b_objects && PyDict_Check(result->b_objects)) {
+ PyObject *index;
+ int rc;
+ index = PyLong_FromVoidPtr((void *)src);
+ if (index == NULL)
+ goto failed;
+ rc = PyDict_SetItem(result->b_objects, index, src);
+ Py_DECREF(index);
+ if (rc == -1)
+ goto failed;
+ }
+ }
+ /* Should we assert that result is a pointer type? */
+ memcpy(result->b_ptr, &ptr, sizeof(void *));
+ return (PyObject *)result;
+
+ failed:
+ Py_DECREF(result);
+ return NULL;
+}
+
+#ifdef CTYPES_UNICODE
+static PyObject *
+wstring_at(const wchar_t *ptr, int size)
+{
+ if (size == -1)
+ size = wcslen(ptr);
+ return PyUnicode_FromWideChar(ptr, size);
+}
+#endif
+
+PyMODINIT_FUNC
+init_ctypes(void)
+{
+ PyObject *m;
+
+/* Note:
+ ob_type is the metatype (the 'type'), defaults to PyType_Type,
+ tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
+*/
+#ifdef WITH_THREAD
+ PyEval_InitThreads();
+#endif
+ m = Py_InitModule3("_ctypes", module_methods, module_docs);
+ if (!m)
+ return;
+
+ if (PyType_Ready(&PyCArg_Type) < 0)
+ return;
+
+ /* StgDict is derived from PyDict_Type */
+ StgDict_Type.tp_base = &PyDict_Type;
+ if (PyType_Ready(&StgDict_Type) < 0)
+ return;
+
+ /*************************************************
+ *
+ * Metaclasses
+ */
+
+ StructType_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&StructType_Type) < 0)
+ return;
+
+ UnionType_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&UnionType_Type) < 0)
+ return;
+
+ PointerType_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&PointerType_Type) < 0)
+ return;
+
+ ArrayType_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&ArrayType_Type) < 0)
+ return;
+
+ SimpleType_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&SimpleType_Type) < 0)
+ return;
+
+ CFuncPtrType_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&CFuncPtrType_Type) < 0)
+ return;
+
+ /*************************************************
+ *
+ * Classes using a custom metaclass
+ */
+
+ if (PyType_Ready(&CData_Type) < 0)
+ return;
+
+ Struct_Type.ob_type = &StructType_Type;
+ Struct_Type.tp_base = &CData_Type;
+ if (PyType_Ready(&Struct_Type) < 0)
+ return;
+ PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
+
+ Union_Type.ob_type = &UnionType_Type;
+ Union_Type.tp_base = &CData_Type;
+ if (PyType_Ready(&Union_Type) < 0)
+ return;
+ PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
+
+ Pointer_Type.ob_type = &PointerType_Type;
+ Pointer_Type.tp_base = &CData_Type;
+ if (PyType_Ready(&Pointer_Type) < 0)
+ return;
+ PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
+
+ Array_Type.ob_type = &ArrayType_Type;
+ Array_Type.tp_base = &CData_Type;
+ if (PyType_Ready(&Array_Type) < 0)
+ return;
+ PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
+
+ Simple_Type.ob_type = &SimpleType_Type;
+ Simple_Type.tp_base = &CData_Type;
+ if (PyType_Ready(&Simple_Type) < 0)
+ return;
+ PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
+
+ CFuncPtr_Type.ob_type = &CFuncPtrType_Type;
+ CFuncPtr_Type.tp_base = &CData_Type;
+ if (PyType_Ready(&CFuncPtr_Type) < 0)
+ return;
+ PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
+
+ /*************************************************
+ *
+ * Simple classes
+ */
+
+ /* CField_Type is derived from PyBaseObject_Type */
+ if (PyType_Ready(&CField_Type) < 0)
+ return;
+
+ /*************************************************
+ *
+ * Other stuff
+ */
+
+#ifdef MS_WIN32
+ if (create_comerror() < 0)
+ return;
+ PyModule_AddObject(m, "COMError", ComError);
+
+ PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
+ PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
+#endif
+ PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
+ PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
+ PyModule_AddStringConstant(m, "__version__", "1.0.2");
+
+ PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
+ PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
+ PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
+ PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
+#ifdef CTYPES_UNICODE
+ PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
+#endif
+
+/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
+ RTLD_LOCAL.
+*/
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL RTLD_LOCAL
+#endif
+
+ PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
+ PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
+
+ PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
+ if (PyExc_ArgError) {
+ Py_INCREF(PyExc_ArgError);
+ PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
+ }
+ /*************************************************
+ *
+ * Others...
+ */
+ init_callbacks_in_module(m);
+}
+
+/*****************************************************************
+ * replacements for broken Python api functions (in Python 2.3).
+ * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
+ */
+
+#ifdef HAVE_WCHAR_H
+
+PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
+ Py_ssize_t size)
+{
+ PyUnicodeObject *unicode;
+
+ if (w == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
+ if (!unicode)
+ return NULL;
+
+ /* Copy the wchar_t data into the new object */
+#ifdef HAVE_USABLE_WCHAR_T
+ memcpy(unicode->str, w, size * sizeof(wchar_t));
+#else
+ {
+ register Py_UNICODE *u;
+ register int i;
+ u = PyUnicode_AS_UNICODE(unicode);
+ /* In Python, the following line has a one-off error */
+ for (i = size; i > 0; i--)
+ *u++ = *w++;
+ }
+#endif
+
+ return (PyObject *)unicode;
+}
+
+int My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
+ register wchar_t *w,
+ Py_ssize_t size)
+{
+ if (unicode == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (size > PyUnicode_GET_SIZE(unicode))
+ size = PyUnicode_GET_SIZE(unicode);
+#ifdef HAVE_USABLE_WCHAR_T
+ memcpy(w, unicode->str, size * sizeof(wchar_t));
+#else
+ {
+ register Py_UNICODE *u;
+ register int i;
+ u = PyUnicode_AS_UNICODE(unicode);
+ /* In Python, the following line has a one-off error */
+ for (i = size; i > 0; i--)
+ *w++ = *u++;
+ }
+#endif
+
+ return size;
+}
+
+#endif
+
+/*
+ Local Variables:
+ compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
+ End:
+*/
diff --git a/sys/src/cmd/python/Modules/_ctypes/_ctypes_test.c b/sys/src/cmd/python/Modules/_ctypes/_ctypes_test.c
new file mode 100644
index 000000000..c10da0d99
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/_ctypes_test.c
@@ -0,0 +1,548 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+
+#include <Python.h>
+
+/*
+ Backwards compatibility:
+ Python2.2 used LONG_LONG instead of PY_LONG_LONG
+*/
+#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
+#define PY_LONG_LONG LONG_LONG
+#endif
+
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+
+#if defined(MS_WIN32) || defined(__CYGWIN__)
+#define EXPORT(x) __declspec(dllexport) x
+#else
+#define EXPORT(x) x
+#endif
+
+/* some functions handy for testing */
+
+EXPORT(char *)my_strtok(char *token, const char *delim)
+{
+ return strtok(token, delim);
+}
+
+EXPORT(char *)my_strchr(const char *s, int c)
+{
+ return strchr(s, c);
+}
+
+
+EXPORT(double) my_sqrt(double a)
+{
+ return sqrt(a);
+}
+
+EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
+{
+ qsort(base, num, width, compare);
+}
+
+EXPORT(int *) _testfunc_ai8(int a[8])
+{
+ return a;
+}
+
+EXPORT(void) _testfunc_v(int a, int b, int *presult)
+{
+ *presult = a + b;
+}
+
+EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+/* printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
+ b, h, i, l, f, d);
+*/
+ return (int)(b + h + i + l + f + d);
+}
+
+EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+/* printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
+ b, h, i, l, f, d);
+*/
+ return (float)(b + h + i + l + f + d);
+}
+
+EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+/* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
+ b, h, i, l, f, d);
+*/
+ return (double)(b + h + i + l + f + d);
+}
+
+EXPORT(char *) _testfunc_p_p(void *s)
+{
+ return (char *)s;
+}
+
+EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
+{
+ return argv[(*argcp)-1];
+}
+
+EXPORT(void *) get_strchr(void)
+{
+ return (void *)strchr;
+}
+
+EXPORT(char *) my_strdup(char *src)
+{
+ char *dst = (char *)malloc(strlen(src)+1);
+ if (!dst)
+ return NULL;
+ strcpy(dst, src);
+ return dst;
+}
+
+EXPORT(void)my_free(void *ptr)
+{
+ free(ptr);
+}
+
+#ifdef HAVE_WCHAR_H
+EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
+{
+ size_t len = wcslen(src);
+ wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
+ if (ptr == NULL)
+ return NULL;
+ memcpy(ptr, src, (len+1) * sizeof(wchar_t));
+ return ptr;
+}
+
+EXPORT(size_t) my_wcslen(wchar_t *src)
+{
+ return wcslen(src);
+}
+#endif
+
+#ifndef MS_WIN32
+# ifndef __stdcall
+# define __stdcall /* */
+# endif
+#endif
+
+typedef struct {
+ int (*c)(int, int);
+ int (__stdcall *s)(int, int);
+} FUNCS;
+
+EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
+{
+ fp->c(1, 2);
+ fp->s(3, 4);
+ return 0;
+}
+
+EXPORT(int) _testfunc_deref_pointer(int *pi)
+{
+ return *pi;
+}
+
+#ifdef MS_WIN32
+EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
+{
+ piunk->lpVtbl->AddRef(piunk);
+ return piunk->lpVtbl->Release(piunk);
+}
+#endif
+
+EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
+{
+ int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+ return (*func)(table);
+}
+
+#ifdef HAVE_LONG_LONG
+EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
+ double d, PY_LONG_LONG q)
+{
+ return (PY_LONG_LONG)(b + h + i + l + f + d + q);
+}
+
+EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
+{
+ return (PY_LONG_LONG)(b + h + i + l + f + d);
+}
+
+EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
+{
+ int sum = 0;
+ while (value != 0) {
+ sum += func(value);
+ value /= 2;
+ }
+ return sum;
+}
+
+EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value,
+ PY_LONG_LONG (*func)(PY_LONG_LONG))
+{
+ PY_LONG_LONG sum = 0;
+
+ while (value != 0) {
+ sum += func(value);
+ value /= 2;
+ }
+ return sum;
+}
+
+#endif
+
+typedef struct {
+ char *name;
+ char *value;
+} SPAM;
+
+typedef struct {
+ char *name;
+ int num_spams;
+ SPAM *spams;
+} EGG;
+
+SPAM my_spams[2] = {
+ { "name1", "value1" },
+ { "name2", "value2" },
+};
+
+EGG my_eggs[1] = {
+ { "first egg", 1, my_spams }
+};
+
+EXPORT(int) getSPAMANDEGGS(EGG **eggs)
+{
+ *eggs = my_eggs;
+ return 1;
+}
+
+typedef struct tagpoint {
+ int x;
+ int y;
+} point;
+
+EXPORT(int) _testfunc_byval(point in, point *pout)
+{
+ if (pout) {
+ pout->x = in.x;
+ pout->y = in.y;
+ }
+ return in.x + in.y;
+}
+
+EXPORT (int) an_integer = 42;
+
+EXPORT(int) get_an_integer(void)
+{
+ return an_integer;
+}
+
+EXPORT(double)
+integrate(double a, double b, double (*f)(double), long nstep)
+{
+ double x, sum=0.0, dx=(b-a)/(double)nstep;
+ for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx)
+ sum += f(x);
+ return sum/(double)nstep;
+}
+
+typedef struct {
+ void (*initialize)(void *(*)(int), void(*)(void *));
+} xxx_library;
+
+static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
+{
+ void *ptr;
+
+ printf("_xxx_init got %p %p\n", Xalloc, Xfree);
+ printf("calling\n");
+ ptr = Xalloc(32);
+ Xfree(ptr);
+ printf("calls done, ptr was %p\n", ptr);
+}
+
+xxx_library _xxx_lib = {
+ _xxx_init
+};
+
+EXPORT(xxx_library) *library_get(void)
+{
+ return &_xxx_lib;
+}
+
+#ifdef MS_WIN32
+/* See Don Box (german), pp 79ff. */
+EXPORT(void) GetString(BSTR *pbstr)
+{
+ *pbstr = SysAllocString(L"Goodbye!");
+}
+#endif
+
+/*
+ * Some do-nothing functions, for speed tests
+ */
+PyObject *py_func_si(PyObject *self, PyObject *args)
+{
+ char *name;
+ int i;
+ if (!PyArg_ParseTuple(args, "si", &name, &i))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+EXPORT(void) _py_func_si(char *s, int i)
+{
+}
+
+PyObject *py_func(PyObject *self, PyObject *args)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+EXPORT(void) _py_func(void)
+{
+}
+
+EXPORT(PY_LONG_LONG) last_tf_arg_s;
+EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u;
+
+struct BITS {
+ int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
+ short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7;
+};
+
+DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value)
+{
+ switch (name) {
+ case 'A': bits->A = value; break;
+ case 'B': bits->B = value; break;
+ case 'C': bits->C = value; break;
+ case 'D': bits->D = value; break;
+ case 'E': bits->E = value; break;
+ case 'F': bits->F = value; break;
+ case 'G': bits->G = value; break;
+ case 'H': bits->H = value; break;
+ case 'I': bits->I = value; break;
+
+ case 'M': bits->M = value; break;
+ case 'N': bits->N = value; break;
+ case 'O': bits->O = value; break;
+ case 'P': bits->P = value; break;
+ case 'Q': bits->Q = value; break;
+ case 'R': bits->R = value; break;
+ case 'S': bits->S = value; break;
+ }
+}
+
+DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
+{
+ switch (name) {
+ case 'A': return bits->A;
+ case 'B': return bits->B;
+ case 'C': return bits->C;
+ case 'D': return bits->D;
+ case 'E': return bits->E;
+ case 'F': return bits->F;
+ case 'G': return bits->G;
+ case 'H': return bits->H;
+ case 'I': return bits->I;
+
+ case 'M': return bits->M;
+ case 'N': return bits->N;
+ case 'O': return bits->O;
+ case 'P': return bits->P;
+ case 'Q': return bits->Q;
+ case 'R': return bits->R;
+ case 'S': return bits->S;
+ }
+ return 0;
+}
+
+PyMethodDef module_methods[] = {
+/* {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
+ {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
+*/
+ {"func_si", py_func_si, METH_VARARGS},
+ {"func", py_func, METH_NOARGS},
+ { NULL, NULL, 0, NULL},
+};
+
+#define S last_tf_arg_s = (PY_LONG_LONG)c
+#define U last_tf_arg_u = (unsigned PY_LONG_LONG)c
+
+EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
+EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
+EXPORT(short) tf_h(short c) { S; return c/3; }
+EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
+EXPORT(int) tf_i(int c) { S; return c/3; }
+EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
+EXPORT(long) tf_l(long c) { S; return c/3; }
+EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) tf_f(float c) { S; return c/3; }
+EXPORT(double) tf_d(double c) { S; return c/3; }
+
+#ifdef MS_WIN32
+EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
+EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
+EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
+EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
+EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
+EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
+EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
+EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
+EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
+#endif
+/*******/
+
+EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
+EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
+EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
+EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
+EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
+EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
+EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
+EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
+EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
+EXPORT(void) tv_i(int c) { S; return; }
+
+#ifdef MS_WIN32
+EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
+EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
+EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
+EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
+EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
+EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
+EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
+EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
+EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
+EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
+EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
+EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
+EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
+#endif
+
+/********/
+
+#ifndef MS_WIN32
+
+typedef struct {
+ long x;
+ long y;
+} POINT;
+
+typedef struct {
+ long left;
+ long top;
+ long right;
+ long bottom;
+} RECT;
+
+#endif
+
+EXPORT(int) PointInRect(RECT *prc, POINT pt)
+{
+ if (pt.x < prc->left)
+ return 0;
+ if (pt.x > prc->right)
+ return 0;
+ if (pt.y < prc->top)
+ return 0;
+ if (pt.y > prc->bottom)
+ return 0;
+ return 1;
+}
+
+typedef struct {
+ short x;
+ short y;
+} S2H;
+
+EXPORT(S2H) ret_2h_func(S2H inp)
+{
+ inp.x *= 2;
+ inp.y *= 3;
+ return inp;
+}
+
+typedef struct {
+ int a, b, c, d, e, f, g, h;
+} S8I;
+
+EXPORT(S8I) ret_8i_func(S8I inp)
+{
+ inp.a *= 2;
+ inp.b *= 3;
+ inp.c *= 4;
+ inp.d *= 5;
+ inp.e *= 6;
+ inp.f *= 7;
+ inp.g *= 8;
+ inp.h *= 9;
+ return inp;
+}
+
+EXPORT(int) GetRectangle(int flag, RECT *prect)
+{
+ if (flag == 0)
+ return 0;
+ prect->left = (int)flag;
+ prect->top = (int)flag + 1;
+ prect->right = (int)flag + 2;
+ prect->bottom = (int)flag + 3;
+ return 1;
+}
+
+EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
+{
+ *pi += a;
+ *pj += b;
+}
+
+#ifdef MS_WIN32
+EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
+EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
+#endif
+
+#ifdef MS_WIN32
+/* Should port this */
+#include <stdlib.h>
+#include <search.h>
+
+EXPORT (HRESULT) KeepObject(IUnknown *punk)
+{
+ static IUnknown *pobj;
+ if (punk)
+ punk->lpVtbl->AddRef(punk);
+ if (pobj)
+ pobj->lpVtbl->Release(pobj);
+ pobj = punk;
+ return S_OK;
+}
+
+#endif
+
+DL_EXPORT(void)
+init_ctypes_test(void)
+{
+ Py_InitModule("_ctypes_test", module_methods);
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/_ctypes_test.h b/sys/src/cmd/python/Modules/_ctypes/_ctypes_test.h
new file mode 100644
index 000000000..060d4d69b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/_ctypes_test.h
@@ -0,0 +1 @@
+extern int _testfunc_i_bhilfd(char b, short h, int i, long l, float f, double d);
diff --git a/sys/src/cmd/python/Modules/_ctypes/callbacks.c b/sys/src/cmd/python/Modules/_ctypes/callbacks.c
new file mode 100644
index 000000000..e332f00e8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/callbacks.c
@@ -0,0 +1,499 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include "Python.h"
+#include "compile.h" /* required only for 2.3, as it seems */
+#include "frameobject.h"
+
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+#include "ctypes.h"
+
+static void
+PrintError(char *msg, ...)
+{
+ char buf[512];
+ PyObject *f = PySys_GetObject("stderr");
+ va_list marker;
+
+ va_start(marker, msg);
+ vsnprintf(buf, sizeof(buf), msg, marker);
+ va_end(marker);
+ if (f)
+ PyFile_WriteString(buf, f);
+ PyErr_Print();
+}
+
+
+/* after code that pyrex generates */
+void _AddTraceback(char *funcname, char *filename, int lineno)
+{
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ PyObject *py_globals = 0;
+ PyObject *empty_tuple = 0;
+ PyObject *empty_string = 0;
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+
+ py_srcfile = PyString_FromString(filename);
+ if (!py_srcfile) goto bad;
+ py_funcname = PyString_FromString(funcname);
+ if (!py_funcname) goto bad;
+ py_globals = PyDict_New();
+ if (!py_globals) goto bad;
+ empty_tuple = PyTuple_New(0);
+ if (!empty_tuple) goto bad;
+ empty_string = PyString_FromString("");
+ if (!empty_string) goto bad;
+ py_code = PyCode_New(
+ 0, /*int argcount,*/
+ 0, /*int nlocals,*/
+ 0, /*int stacksize,*/
+ 0, /*int flags,*/
+ empty_string, /*PyObject *code,*/
+ empty_tuple, /*PyObject *consts,*/
+ empty_tuple, /*PyObject *names,*/
+ empty_tuple, /*PyObject *varnames,*/
+ empty_tuple, /*PyObject *freevars,*/
+ empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ lineno, /*int firstlineno,*/
+ empty_string /*PyObject *lnotab*/
+ );
+ if (!py_code) goto bad;
+ py_frame = PyFrame_New(
+ PyThreadState_Get(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ py_globals, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = lineno;
+ PyTraceBack_Here(py_frame);
+ bad:
+ Py_XDECREF(py_globals);
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ Py_XDECREF(empty_tuple);
+ Py_XDECREF(empty_string);
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#ifdef MS_WIN32
+/*
+ * We must call AddRef() on non-NULL COM pointers we receive as arguments
+ * to callback functions - these functions are COM method implementations.
+ * The Python instances we create have a __del__ method which calls Release().
+ *
+ * The presence of a class attribute named '_needs_com_addref_' triggers this
+ * behaviour. It would also be possible to call the AddRef() Python method,
+ * after checking for PyObject_IsTrue(), but this would probably be somewhat
+ * slower.
+ */
+static void
+TryAddRef(StgDictObject *dict, CDataObject *obj)
+{
+ IUnknown *punk;
+
+ if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
+ return;
+
+ punk = *(IUnknown **)obj->b_ptr;
+ if (punk)
+ punk->lpVtbl->AddRef(punk);
+ return;
+}
+#endif
+
+/******************************************************************************
+ *
+ * Call the python object with all arguments
+ *
+ */
+static void _CallPythonObject(void *mem,
+ ffi_type *restype,
+ SETFUNC setfunc,
+ PyObject *callable,
+ PyObject *converters,
+ void **pArgs)
+{
+ int i;
+ PyObject *result;
+ PyObject *arglist = NULL;
+ int nArgs;
+#ifdef WITH_THREAD
+ PyGILState_STATE state = PyGILState_Ensure();
+#endif
+
+ nArgs = PySequence_Length(converters);
+ /* Hm. What to return in case of error?
+ For COM, 0xFFFFFFFF seems better than 0.
+ */
+ if (nArgs < 0) {
+ PrintError("BUG: PySequence_Length");
+ goto Done;
+ }
+
+ arglist = PyTuple_New(nArgs);
+ if (!arglist) {
+ PrintError("PyTuple_New()");
+ goto Done;
+ }
+ for (i = 0; i < nArgs; ++i) {
+ /* Note: new reference! */
+ PyObject *cnv = PySequence_GetItem(converters, i);
+ StgDictObject *dict;
+ if (cnv)
+ dict = PyType_stgdict(cnv);
+ else {
+ PrintError("Getting argument converter %d\n", i);
+ goto Done;
+ }
+
+ if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
+ PyObject *v = dict->getfunc(*pArgs, dict->size);
+ if (!v) {
+ PrintError("create argument %d:\n", i);
+ Py_DECREF(cnv);
+ goto Done;
+ }
+ PyTuple_SET_ITEM(arglist, i, v);
+ /* XXX XXX XX
+ We have the problem that c_byte or c_short have dict->size of
+ 1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
+ BTW, the same problem occurrs when they are pushed as parameters
+ */
+ } else if (dict) {
+ /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
+ CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
+ if (!obj) {
+ PrintError("create argument %d:\n", i);
+ Py_DECREF(cnv);
+ goto Done;
+ }
+ if (!CDataObject_Check(obj)) {
+ Py_DECREF(obj);
+ Py_DECREF(cnv);
+ PrintError("unexpected result of create argument %d:\n", i);
+ goto Done;
+ }
+ memcpy(obj->b_ptr, *pArgs, dict->size);
+ PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
+#ifdef MS_WIN32
+ TryAddRef(dict, obj);
+#endif
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot build parameter");
+ PrintError("Parsing argument %d\n", i);
+ Py_DECREF(cnv);
+ goto Done;
+ }
+ Py_DECREF(cnv);
+ /* XXX error handling! */
+ pArgs++;
+ }
+
+#define CHECK(what, x) \
+if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
+
+ result = PyObject_CallObject(callable, arglist);
+ CHECK("'calling callback function'", result);
+ if ((restype != &ffi_type_void) && result) {
+ PyObject *keep;
+ assert(setfunc);
+#ifdef WORDS_BIGENDIAN
+ /* See the corresponding code in callproc.c, around line 961 */
+ if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
+ mem = (char *)mem + sizeof(ffi_arg) - restype->size;
+#endif
+ keep = setfunc(mem, result, 0);
+ CHECK("'converting callback result'", keep);
+ /* keep is an object we have to keep alive so that the result
+ stays valid. If there is no such object, the setfunc will
+ have returned Py_None.
+
+ If there is such an object, we have no choice than to keep
+ it alive forever - but a refcount and/or memory leak will
+ be the result. EXCEPT when restype is py_object - Python
+ itself knows how to manage the refcount of these objects.
+ */
+ if (keep == NULL) /* Could not convert callback result. */
+ PyErr_WriteUnraisable(callable);
+ else if (keep == Py_None) /* Nothing to keep */
+ Py_DECREF(keep);
+ else if (setfunc != getentry("O")->setfunc) {
+ if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
+ "memory leak in callback function."))
+ PyErr_WriteUnraisable(callable);
+ }
+ }
+ Py_XDECREF(result);
+ Done:
+ Py_XDECREF(arglist);
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+}
+
+static void closure_fcn(ffi_cif *cif,
+ void *resp,
+ void **args,
+ void *userdata)
+{
+ ffi_info *p = userdata;
+
+ _CallPythonObject(resp,
+ p->restype,
+ p->setfunc,
+ p->callable,
+ p->converters,
+ args);
+}
+
+ffi_info *AllocFunctionCallback(PyObject *callable,
+ PyObject *converters,
+ PyObject *restype,
+ int is_cdecl)
+{
+ int result;
+ ffi_info *p;
+ int nArgs, i;
+ ffi_abi cc;
+
+ nArgs = PySequence_Size(converters);
+ p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
+ if (p == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ p->pcl = MallocClosure();
+ if (p->pcl == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+
+ for (i = 0; i < nArgs; ++i) {
+ PyObject *cnv = PySequence_GetItem(converters, i);
+ if (cnv == NULL)
+ goto error;
+ p->atypes[i] = GetType(cnv);
+ Py_DECREF(cnv);
+ }
+ p->atypes[i] = NULL;
+
+ if (restype == Py_None) {
+ p->setfunc = NULL;
+ p->restype = &ffi_type_void;
+ } else {
+ StgDictObject *dict = PyType_stgdict(restype);
+ if (dict == NULL || dict->setfunc == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "invalid result type for callback function");
+ goto error;
+ }
+ p->setfunc = dict->setfunc;
+ p->restype = &dict->ffi_type_pointer;
+ }
+
+ cc = FFI_DEFAULT_ABI;
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+ if (is_cdecl == 0)
+ cc = FFI_STDCALL;
+#endif
+ result = ffi_prep_cif(&p->cif, cc, nArgs,
+ GetType(restype),
+ &p->atypes[0]);
+ if (result != FFI_OK) {
+ PyErr_Format(PyExc_RuntimeError,
+ "ffi_prep_cif failed with %d", result);
+ goto error;
+ }
+ result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
+ if (result != FFI_OK) {
+ PyErr_Format(PyExc_RuntimeError,
+ "ffi_prep_closure failed with %d", result);
+ goto error;
+ }
+
+ p->converters = converters;
+ p->callable = callable;
+ return p;
+
+ error:
+ if (p) {
+ if (p->pcl)
+ FreeClosure(p->pcl);
+ PyMem_Free(p);
+ }
+ return NULL;
+}
+
+/****************************************************************************
+ *
+ * callback objects: initialization
+ */
+
+void init_callbacks_in_module(PyObject *m)
+{
+ if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
+ return;
+}
+
+#ifdef MS_WIN32
+
+static void LoadPython(void)
+{
+ if (!Py_IsInitialized()) {
+#ifdef WITH_THREAD
+ PyEval_InitThreads();
+#endif
+ Py_Initialize();
+ }
+}
+
+/******************************************************************/
+
+long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ PyObject *mod, *func, *result;
+ long retval;
+ static PyObject *context;
+
+ if (context == NULL)
+ context = PyString_FromString("_ctypes.DllGetClassObject");
+
+ mod = PyImport_ImportModule("ctypes");
+ if (!mod) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ /* There has been a warning before about this already */
+ return E_FAIL;
+ }
+
+ func = PyObject_GetAttrString(mod, "DllGetClassObject");
+ Py_DECREF(mod);
+ if (!func) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ return E_FAIL;
+ }
+
+ result = PyObject_CallFunction(func,
+ "iii", rclsid, riid, ppv);
+ Py_DECREF(func);
+ if (!result) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ return E_FAIL;
+ }
+
+ retval = PyInt_AsLong(result);
+ if (PyErr_Occurred()) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ retval = E_FAIL;
+ }
+ Py_DECREF(result);
+ return retval;
+}
+
+STDAPI DllGetClassObject(REFCLSID rclsid,
+ REFIID riid,
+ LPVOID *ppv)
+{
+ long result;
+#ifdef WITH_THREAD
+ PyGILState_STATE state;
+#endif
+
+ LoadPython();
+#ifdef WITH_THREAD
+ state = PyGILState_Ensure();
+#endif
+ result = Call_GetClassObject(rclsid, riid, ppv);
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+ return result;
+}
+
+long Call_CanUnloadNow(void)
+{
+ PyObject *mod, *func, *result;
+ long retval;
+ static PyObject *context;
+
+ if (context == NULL)
+ context = PyString_FromString("_ctypes.DllCanUnloadNow");
+
+ mod = PyImport_ImportModule("ctypes");
+ if (!mod) {
+/* OutputDebugString("Could not import ctypes"); */
+ /* We assume that this error can only occur when shutting
+ down, so we silently ignore it */
+ PyErr_Clear();
+ return E_FAIL;
+ }
+ /* Other errors cannot be raised, but are printed to stderr */
+ func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
+ Py_DECREF(mod);
+ if (!func) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ return E_FAIL;
+ }
+
+ result = PyObject_CallFunction(func, NULL);
+ Py_DECREF(func);
+ if (!result) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ return E_FAIL;
+ }
+
+ retval = PyInt_AsLong(result);
+ if (PyErr_Occurred()) {
+ PyErr_WriteUnraisable(context ? context : Py_None);
+ retval = E_FAIL;
+ }
+ Py_DECREF(result);
+ return retval;
+}
+
+/*
+ DllRegisterServer and DllUnregisterServer still missing
+*/
+
+STDAPI DllCanUnloadNow(void)
+{
+ long result;
+#ifdef WITH_THREAD
+ PyGILState_STATE state = PyGILState_Ensure();
+#endif
+ result = Call_CanUnloadNow();
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+ return result;
+}
+
+#ifndef Py_NO_ENABLE_SHARED
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
+{
+ switch(fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ break;
+ }
+ return TRUE;
+}
+#endif
+
+#endif
+
+/*
+ Local Variables:
+ compile-command: "cd .. && python setup.py -q build_ext"
+ End:
+*/
diff --git a/sys/src/cmd/python/Modules/_ctypes/callproc.c b/sys/src/cmd/python/Modules/_ctypes/callproc.c
new file mode 100644
index 000000000..e0765e917
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/callproc.c
@@ -0,0 +1,1581 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+
+/*
+ * History: First version dated from 3/97, derived from my SCMLIB version
+ * for win16.
+ */
+/*
+ * Related Work:
+ * - calldll http://www.nightmare.com/software.html
+ * - libffi http://sourceware.cygnus.com/libffi/
+ * - ffcall http://clisp.cons.org/~haible/packages-ffcall.html
+ * and, of course, Don Beaudry's MESS package, but this is more ctypes
+ * related.
+ */
+
+
+/*
+ How are functions called, and how are parameters converted to C ?
+
+ 1. _ctypes.c::CFuncPtr_call receives an argument tuple 'inargs' and a
+ keyword dictionary 'kwds'.
+
+ 2. After several checks, _build_callargs() is called which returns another
+ tuple 'callargs'. This may be the same tuple as 'inargs', a slice of
+ 'inargs', or a completely fresh tuple, depending on several things (is is a
+ COM method, are 'paramflags' available).
+
+ 3. _build_callargs also calculates bitarrays containing indexes into
+ the callargs tuple, specifying how to build the return value(s) of
+ the function.
+
+ 4. _CallProc is then called with the 'callargs' tuple. _CallProc first
+ allocates two arrays. The first is an array of 'struct argument' items, the
+ second array has 'void *' entried.
+
+ 5. If 'converters' are present (converters is a sequence of argtypes'
+ from_param methods), for each item in 'callargs' converter is called and the
+ result passed to ConvParam. If 'converters' are not present, each argument
+ is directly passed to ConvParm.
+
+ 6. For each arg, ConvParam stores the contained C data (or a pointer to it,
+ for structures) into the 'struct argument' array.
+
+ 7. Finally, a loop fills the 'void *' array so that each item points to the
+ data contained in or pointed to by the 'struct argument' array.
+
+ 8. The 'void *' argument array is what _call_function_pointer
+ expects. _call_function_pointer then has very little to do - only some
+ libffi specific stuff, then it calls ffi_call.
+
+ So, there are 4 data structures holding processed arguments:
+ - the inargs tuple (in CFuncPtr_call)
+ - the callargs tuple (in CFuncPtr_call)
+ - the 'struct argguments' array
+ - the 'void *' array
+
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef MS_WIN32
+#include <windows.h>
+#else
+#include "ctypes_dlfcn.h"
+#endif
+
+#ifdef MS_WIN32
+#include <malloc.h>
+#endif
+
+#include <ffi.h>
+#include "ctypes.h"
+
+#if defined(_DEBUG) || defined(__MINGW32__)
+/* Don't use structured exception handling on Windows if this is defined.
+ MingW, AFAIK, doesn't support it.
+*/
+#define DONT_USE_SEH
+#endif
+
+#ifdef MS_WIN32
+PyObject *ComError;
+
+static TCHAR *FormatError(DWORD code)
+{
+ TCHAR *lpMsgBuf;
+ DWORD n;
+ n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ code,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL);
+ if (n) {
+ while (isspace(lpMsgBuf[n-1]))
+ --n;
+ lpMsgBuf[n] = '\0'; /* rstrip() */
+ }
+ return lpMsgBuf;
+}
+
+#ifndef DONT_USE_SEH
+void SetException(DWORD code, EXCEPTION_RECORD *pr)
+{
+ TCHAR *lpMsgBuf;
+ lpMsgBuf = FormatError(code);
+ if(lpMsgBuf) {
+ PyErr_SetFromWindowsErr(code);
+ LocalFree(lpMsgBuf);
+ } else {
+ switch (code) {
+ case EXCEPTION_ACCESS_VIOLATION:
+ /* The thread attempted to read from or write
+ to a virtual address for which it does not
+ have the appropriate access. */
+ if (pr->ExceptionInformation[0] == 0)
+ PyErr_Format(PyExc_WindowsError,
+ "exception: access violation reading %p",
+ pr->ExceptionInformation[1]);
+ else
+ PyErr_Format(PyExc_WindowsError,
+ "exception: access violation writing %p",
+ pr->ExceptionInformation[1]);
+ break;
+ case EXCEPTION_BREAKPOINT:
+ /* A breakpoint was encountered. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: breakpoint encountered");
+ break;
+
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ /* The thread attempted to read or write data that is
+ misaligned on hardware that does not provide
+ alignment. For example, 16-bit values must be
+ aligned on 2-byte boundaries, 32-bit values on
+ 4-byte boundaries, and so on. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: datatype misalignment");
+ break;
+
+ case EXCEPTION_SINGLE_STEP:
+ /* A trace trap or other single-instruction mechanism
+ signaled that one instruction has been executed. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: single step");
+ break;
+
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ /* The thread attempted to access an array element
+ that is out of bounds, and the underlying hardware
+ supports bounds checking. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: array bounds exceeded");
+ break;
+
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ /* One of the operands in a floating-point operation
+ is denormal. A denormal value is one that is too
+ small to represent as a standard floating-point
+ value. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: floating-point operand denormal");
+ break;
+
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ /* The thread attempted to divide a floating-point
+ value by a floating-point divisor of zero. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: float divide by zero");
+ break;
+
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ /* The result of a floating-point operation cannot be
+ represented exactly as a decimal fraction. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: float inexact");
+ break;
+
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ /* This exception represents any floating-point
+ exception not included in this list. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: float invalid operation");
+ break;
+
+ case EXCEPTION_FLT_OVERFLOW:
+ /* The exponent of a floating-point operation is
+ greater than the magnitude allowed by the
+ corresponding type. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: float overflow");
+ break;
+
+ case EXCEPTION_FLT_STACK_CHECK:
+ /* The stack overflowed or underflowed as the result
+ of a floating-point operation. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: stack over/underflow");
+ break;
+
+ case EXCEPTION_STACK_OVERFLOW:
+ /* The stack overflowed or underflowed as the result
+ of a floating-point operation. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: stack overflow");
+ break;
+
+ case EXCEPTION_FLT_UNDERFLOW:
+ /* The exponent of a floating-point operation is less
+ than the magnitude allowed by the corresponding
+ type. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: float underflow");
+ break;
+
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ /* The thread attempted to divide an integer value by
+ an integer divisor of zero. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: integer divide by zero");
+ break;
+
+ case EXCEPTION_INT_OVERFLOW:
+ /* The result of an integer operation caused a carry
+ out of the most significant bit of the result. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: integer overflow");
+ break;
+
+ case EXCEPTION_PRIV_INSTRUCTION:
+ /* The thread attempted to execute an instruction
+ whose operation is not allowed in the current
+ machine mode. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: priviledged instruction");
+ break;
+
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ /* The thread attempted to continue execution after a
+ noncontinuable exception occurred. */
+ PyErr_SetString(PyExc_WindowsError,
+ "exception: nocontinuable");
+ break;
+ default:
+ printf("error %d\n", code);
+ PyErr_Format(PyExc_WindowsError,
+ "exception code 0x%08x",
+ code);
+ break;
+ }
+ }
+}
+
+static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
+ DWORD *pdw, EXCEPTION_RECORD *record)
+{
+ *pdw = ptrs->ExceptionRecord->ExceptionCode;
+ *record = *ptrs->ExceptionRecord;
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif
+
+static PyObject *
+check_hresult(PyObject *self, PyObject *args)
+{
+ HRESULT hr;
+ if (!PyArg_ParseTuple(args, "i", &hr))
+ return NULL;
+ if (FAILED(hr))
+ return PyErr_SetFromWindowsErr(hr);
+ return PyInt_FromLong(hr);
+}
+
+#endif
+
+/**************************************************************/
+
+PyCArgObject *
+new_CArgObject(void)
+{
+ PyCArgObject *p;
+ p = PyObject_New(PyCArgObject, &PyCArg_Type);
+ if (p == NULL)
+ return NULL;
+ p->pffi_type = NULL;
+ p->tag = '\0';
+ p->obj = NULL;
+ memset(&p->value, 0, sizeof(p->value));
+ return p;
+}
+
+static void
+PyCArg_dealloc(PyCArgObject *self)
+{
+ Py_XDECREF(self->obj);
+ PyObject_Del(self);
+}
+
+static PyObject *
+PyCArg_repr(PyCArgObject *self)
+{
+ char buffer[256];
+ switch(self->tag) {
+ case 'b':
+ case 'B':
+ sprintf(buffer, "<cparam '%c' (%d)>",
+ self->tag, self->value.b);
+ break;
+ case 'h':
+ case 'H':
+ sprintf(buffer, "<cparam '%c' (%d)>",
+ self->tag, self->value.h);
+ break;
+ case 'i':
+ case 'I':
+ sprintf(buffer, "<cparam '%c' (%d)>",
+ self->tag, self->value.i);
+ break;
+ case 'l':
+ case 'L':
+ sprintf(buffer, "<cparam '%c' (%ld)>",
+ self->tag, self->value.l);
+ break;
+
+#ifdef HAVE_LONG_LONG
+ case 'q':
+ case 'Q':
+ sprintf(buffer,
+#ifdef MS_WIN32
+ "<cparam '%c' (%I64d)>",
+#else
+ "<cparam '%c' (%qd)>",
+#endif
+ self->tag, self->value.q);
+ break;
+#endif
+ case 'd':
+ sprintf(buffer, "<cparam '%c' (%f)>",
+ self->tag, self->value.d);
+ break;
+ case 'f':
+ sprintf(buffer, "<cparam '%c' (%f)>",
+ self->tag, self->value.f);
+ break;
+
+ case 'c':
+ sprintf(buffer, "<cparam '%c' (%c)>",
+ self->tag, self->value.c);
+ break;
+
+/* Hm, are these 'z' and 'Z' codes useful at all?
+ Shouldn't they be replaced by the functionality of c_string
+ and c_wstring ?
+*/
+ case 'z':
+ case 'Z':
+ case 'P':
+ sprintf(buffer, "<cparam '%c' (%08lx)>",
+ self->tag, (long)self->value.p);
+ break;
+
+ default:
+ sprintf(buffer, "<cparam '%c' at %08lx>",
+ self->tag, (long)self);
+ break;
+ }
+ return PyString_FromString(buffer);
+}
+
+static PyMemberDef PyCArgType_members[] = {
+ { "_obj", T_OBJECT,
+ offsetof(PyCArgObject, obj), READONLY,
+ "the wrapped object" },
+ { NULL },
+};
+
+PyTypeObject PyCArg_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "CArgObject",
+ sizeof(PyCArgObject),
+ 0,
+ (destructor)PyCArg_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)PyCArg_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ PyCArgType_members, /* tp_members */
+};
+
+/****************************************************************/
+/*
+ * Convert a PyObject * into a parameter suitable to pass to an
+ * C function call.
+ *
+ * 1. Python integers are converted to C int and passed by value.
+ *
+ * 2. 3-tuples are expected to have a format character in the first
+ * item, which must be 'i', 'f', 'd', 'q', or 'P'.
+ * The second item will have to be an integer, float, double, long long
+ * or integer (denoting an address void *), will be converted to the
+ * corresponding C data type and passed by value.
+ *
+ * 3. Other Python objects are tested for an '_as_parameter_' attribute.
+ * The value of this attribute must be an integer which will be passed
+ * by value, or a 2-tuple or 3-tuple which will be used according
+ * to point 2 above. The third item (if any), is ignored. It is normally
+ * used to keep the object alive where this parameter refers to.
+ * XXX This convention is dangerous - you can construct arbitrary tuples
+ * in Python and pass them. Would it be safer to use a custom container
+ * datatype instead of a tuple?
+ *
+ * 4. Other Python objects cannot be passed as parameters - an exception is raised.
+ *
+ * 5. ConvParam will store the converted result in a struct containing format
+ * and value.
+ */
+
+union result {
+ char c;
+ char b;
+ short h;
+ int i;
+ long l;
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG q;
+#endif
+ double d;
+ float f;
+ void *p;
+};
+
+struct argument {
+ ffi_type *ffi_type;
+ PyObject *keep;
+ union result value;
+};
+
+/*
+ * Convert a single Python object into a PyCArgObject and return it.
+ */
+static int ConvParam(PyObject *obj, int index, struct argument *pa)
+{
+ StgDictObject *dict;
+ pa->keep = NULL; /* so we cannot forget it later */
+
+ dict = PyObject_stgdict(obj);
+ if (dict) {
+ PyCArgObject *carg;
+ assert(dict->paramfunc);
+ /* If it has an stgdict, it is a CDataObject */
+ carg = dict->paramfunc((CDataObject *)obj);
+ pa->ffi_type = carg->pffi_type;
+ memcpy(&pa->value, &carg->value, sizeof(pa->value));
+ pa->keep = (PyObject *)carg;
+ return 0;
+ }
+
+ if (PyCArg_CheckExact(obj)) {
+ PyCArgObject *carg = (PyCArgObject *)obj;
+ pa->ffi_type = carg->pffi_type;
+ Py_INCREF(obj);
+ pa->keep = obj;
+ memcpy(&pa->value, &carg->value, sizeof(pa->value));
+ return 0;
+ }
+
+ /* check for None, integer, string or unicode and use directly if successful */
+ if (obj == Py_None) {
+ pa->ffi_type = &ffi_type_pointer;
+ pa->value.p = NULL;
+ return 0;
+ }
+
+ if (PyInt_Check(obj)) {
+ pa->ffi_type = &ffi_type_sint;
+ pa->value.i = PyInt_AS_LONG(obj);
+ return 0;
+ }
+
+ if (PyLong_Check(obj)) {
+ pa->ffi_type = &ffi_type_sint;
+ pa->value.i = (long)PyLong_AsUnsignedLong(obj);
+ if (pa->value.i == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ pa->value.i = PyLong_AsLong(obj);
+ if (pa->value.i == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long int too long to convert");
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ if (PyString_Check(obj)) {
+ pa->ffi_type = &ffi_type_pointer;
+ pa->value.p = PyString_AS_STRING(obj);
+ Py_INCREF(obj);
+ pa->keep = obj;
+ return 0;
+ }
+
+#ifdef CTYPES_UNICODE
+ if (PyUnicode_Check(obj)) {
+#ifdef HAVE_USABLE_WCHAR_T
+ pa->ffi_type = &ffi_type_pointer;
+ pa->value.p = PyUnicode_AS_UNICODE(obj);
+ Py_INCREF(obj);
+ pa->keep = obj;
+ return 0;
+#else
+ int size = PyUnicode_GET_SIZE(obj);
+ size += 1; /* terminating NUL */
+ size *= sizeof(wchar_t);
+ pa->value.p = PyMem_Malloc(size);
+ if (!pa->value.p)
+ return -1;
+ memset(pa->value.p, 0, size);
+ pa->keep = PyCObject_FromVoidPtr(pa->value.p, PyMem_Free);
+ if (!pa->keep) {
+ PyMem_Free(pa->value.p);
+ return -1;
+ }
+ if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)obj,
+ pa->value.p, PyUnicode_GET_SIZE(obj)))
+ return -1;
+ return 0;
+#endif
+ }
+#endif
+
+ {
+ PyObject *arg;
+ arg = PyObject_GetAttrString(obj, "_as_parameter_");
+ /* Which types should we exactly allow here?
+ integers are required for using Python classes
+ as parameters (they have to expose the '_as_parameter_'
+ attribute)
+ */
+ if (arg) {
+ int result;
+ result = ConvParam(arg, index, pa);
+ Py_DECREF(arg);
+ return result;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "Don't know how to convert parameter %d", index);
+ return -1;
+ }
+}
+
+
+ffi_type *GetType(PyObject *obj)
+{
+ StgDictObject *dict;
+ if (obj == NULL)
+ return &ffi_type_sint;
+ dict = PyType_stgdict(obj);
+ if (dict == NULL)
+ return &ffi_type_sint;
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+ /* This little trick works correctly with MSVC.
+ It returns small structures in registers
+ */
+ if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) {
+ if (dict->ffi_type_pointer.size <= 4)
+ return &ffi_type_sint32;
+ else if (dict->ffi_type_pointer.size <= 8)
+ return &ffi_type_sint64;
+ }
+#endif
+ return &dict->ffi_type_pointer;
+}
+
+
+/*
+ * libffi uses:
+ *
+ * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+ * unsigned int nargs,
+ * ffi_type *rtype,
+ * ffi_type **atypes);
+ *
+ * and then
+ *
+ * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+ */
+static int _call_function_pointer(int flags,
+ PPROC pProc,
+ void **avalues,
+ ffi_type **atypes,
+ ffi_type *restype,
+ void *resmem,
+ int argcount)
+{
+#ifdef WITH_THREAD
+ PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
+#endif
+ ffi_cif cif;
+ int cc;
+#ifdef MS_WIN32
+ int delta;
+#ifndef DONT_USE_SEH
+ DWORD dwExceptionCode = 0;
+ EXCEPTION_RECORD record;
+#endif
+#endif
+ /* XXX check before here */
+ if (restype == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "No ffi_type for result");
+ return -1;
+ }
+
+ cc = FFI_DEFAULT_ABI;
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+ if ((flags & FUNCFLAG_CDECL) == 0)
+ cc = FFI_STDCALL;
+#endif
+ if (FFI_OK != ffi_prep_cif(&cif,
+ cc,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif failed");
+ return -1;
+ }
+
+#ifdef WITH_THREAD
+ if ((flags & FUNCFLAG_PYTHONAPI) == 0)
+ Py_UNBLOCK_THREADS
+#endif
+#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
+ __try {
+#endif
+ delta =
+#endif
+ ffi_call(&cif, (void *)pProc, resmem, avalues);
+#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
+ }
+ __except (HandleException(GetExceptionInformation(),
+ &dwExceptionCode, &record)) {
+ ;
+ }
+#endif
+#endif
+#ifdef WITH_THREAD
+ if ((flags & FUNCFLAG_PYTHONAPI) == 0)
+ Py_BLOCK_THREADS
+#endif
+#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
+ if (dwExceptionCode) {
+ SetException(dwExceptionCode, &record);
+ return -1;
+ }
+#endif
+ if (delta < 0) {
+ if (flags & FUNCFLAG_CDECL)
+ PyErr_Format(PyExc_ValueError,
+ "Procedure called with not enough "
+ "arguments (%d bytes missing) "
+ "or wrong calling convention",
+ -delta);
+ else
+ PyErr_Format(PyExc_ValueError,
+ "Procedure probably called with not enough "
+ "arguments (%d bytes missing)",
+ -delta);
+ return -1;
+ } else if (delta > 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Procedure probably called with too many "
+ "arguments (%d bytes in excess)",
+ delta);
+ return -1;
+ }
+#endif
+ if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
+ return -1;
+ return 0;
+}
+
+/*
+ * Convert the C value in result into a Python object, depending on restype.
+ *
+ * - If restype is NULL, return a Python integer.
+ * - If restype is None, return None.
+ * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc,
+ * pass the result to checker and return the result.
+ * - If restype is another ctypes type, return an instance of that.
+ * - Otherwise, call restype and return the result.
+ */
+static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker)
+{
+ StgDictObject *dict;
+ PyObject *retval, *v;
+
+ if (restype == NULL)
+ return PyInt_FromLong(*(int *)result);
+
+ if (restype == Py_None) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ dict = PyType_stgdict(restype);
+ if (dict == NULL)
+ return PyObject_CallFunction(restype, "i", *(int *)result);
+
+ if (dict->getfunc && !IsSimpleSubType(restype)) {
+ retval = dict->getfunc(result, dict->size);
+ /* If restype is py_object (detected by comparing getfunc with
+ O_get), we have to call Py_DECREF because O_get has already
+ called Py_INCREF.
+ */
+ if (dict->getfunc == getentry("O")->getfunc) {
+ Py_DECREF(retval);
+ }
+ } else
+ retval = CData_FromBaseObj(restype, NULL, 0, result);
+
+ if (!checker || !retval)
+ return retval;
+
+ v = PyObject_CallFunctionObjArgs(checker, retval, NULL);
+ if (v == NULL)
+ _AddTraceback("GetResult", __FILE__, __LINE__-2);
+ Py_DECREF(retval);
+ return v;
+}
+
+/*
+ * Raise a new exception 'exc_class', adding additional text to the original
+ * exception string.
+ */
+void Extend_Error_Info(PyObject *exc_class, char *fmt, ...)
+{
+ va_list vargs;
+ PyObject *tp, *v, *tb, *s, *cls_str, *msg_str;
+
+ va_start(vargs, fmt);
+ s = PyString_FromFormatV(fmt, vargs);
+ va_end(vargs);
+ if (!s)
+ return;
+
+ PyErr_Fetch(&tp, &v, &tb);
+ PyErr_NormalizeException(&tp, &v, &tb);
+ cls_str = PyObject_Str(tp);
+ if (cls_str) {
+ PyString_ConcatAndDel(&s, cls_str);
+ PyString_ConcatAndDel(&s, PyString_FromString(": "));
+ if (s == NULL)
+ goto error;
+ } else
+ PyErr_Clear();
+ msg_str = PyObject_Str(v);
+ if (msg_str)
+ PyString_ConcatAndDel(&s, msg_str);
+ else {
+ PyErr_Clear();
+ PyString_ConcatAndDel(&s, PyString_FromString("???"));
+ if (s == NULL)
+ goto error;
+ }
+ PyErr_SetObject(exc_class, s);
+error:
+ Py_XDECREF(tp);
+ Py_XDECREF(v);
+ Py_XDECREF(tb);
+ Py_XDECREF(s);
+}
+
+
+#ifdef MS_WIN32
+
+static PyObject *
+GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
+{
+ HRESULT hr;
+ ISupportErrorInfo *psei = NULL;
+ IErrorInfo *pei = NULL;
+ BSTR descr=NULL, helpfile=NULL, source=NULL;
+ GUID guid;
+ DWORD helpcontext=0;
+ LPOLESTR progid;
+ PyObject *obj;
+ TCHAR *text;
+
+ /* We absolutely have to release the GIL during COM method calls,
+ otherwise we may get a deadlock!
+ */
+#ifdef WITH_THREAD
+ Py_BEGIN_ALLOW_THREADS
+#endif
+
+ hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
+ if (FAILED(hr))
+ goto failed;
+
+ hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid);
+ psei->lpVtbl->Release(psei);
+ if (FAILED(hr))
+ goto failed;
+
+ hr = GetErrorInfo(0, &pei);
+ if (hr != S_OK)
+ goto failed;
+
+ pei->lpVtbl->GetDescription(pei, &descr);
+ pei->lpVtbl->GetGUID(pei, &guid);
+ pei->lpVtbl->GetHelpContext(pei, &helpcontext);
+ pei->lpVtbl->GetHelpFile(pei, &helpfile);
+ pei->lpVtbl->GetSource(pei, &source);
+
+ pei->lpVtbl->Release(pei);
+
+ failed:
+#ifdef WITH_THREAD
+ Py_END_ALLOW_THREADS
+#endif
+
+ progid = NULL;
+ ProgIDFromCLSID(&guid, &progid);
+
+ text = FormatError(errcode);
+ obj = Py_BuildValue(
+#ifdef _UNICODE
+ "iu(uuuiu)",
+#else
+ "is(uuuiu)",
+#endif
+ errcode,
+ text,
+ descr, source, helpfile, helpcontext,
+ progid);
+ if (obj) {
+ PyErr_SetObject(ComError, obj);
+ Py_DECREF(obj);
+ }
+ LocalFree(text);
+
+ if (descr)
+ SysFreeString(descr);
+ if (helpfile)
+ SysFreeString(helpfile);
+ if (source)
+ SysFreeString(source);
+
+ return NULL;
+}
+#endif
+
+/*
+ * Requirements, must be ensured by the caller:
+ * - argtuple is tuple of arguments
+ * - argtypes is either NULL, or a tuple of the same size as argtuple
+ *
+ * - XXX various requirements for restype, not yet collected
+ */
+PyObject *_CallProc(PPROC pProc,
+ PyObject *argtuple,
+#ifdef MS_WIN32
+ IUnknown *pIunk,
+ GUID *iid,
+#endif
+ int flags,
+ PyObject *argtypes, /* misleading name: This is a tuple of
+ methods, not types: the .from_param
+ class methods of the types */
+ PyObject *restype,
+ PyObject *checker)
+{
+ int i, n, argcount, argtype_count;
+ void *resbuf;
+ struct argument *args, *pa;
+ ffi_type **atypes;
+ ffi_type *rtype;
+ void **avalues;
+ PyObject *retval = NULL;
+
+ n = argcount = PyTuple_GET_SIZE(argtuple);
+#ifdef MS_WIN32
+ /* an optional COM object this pointer */
+ if (pIunk)
+ ++argcount;
+#endif
+
+ args = (struct argument *)alloca(sizeof(struct argument) * argcount);
+ if (!args) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(args, 0, sizeof(struct argument) * argcount);
+ argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0;
+#ifdef MS_WIN32
+ if (pIunk) {
+ args[0].ffi_type = &ffi_type_pointer;
+ args[0].value.p = pIunk;
+ pa = &args[1];
+ } else
+#endif
+ pa = &args[0];
+
+ /* Convert the arguments */
+ for (i = 0; i < n; ++i, ++pa) {
+ PyObject *converter;
+ PyObject *arg;
+ int err;
+
+ arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */
+ /* For cdecl functions, we allow more actual arguments
+ than the length of the argtypes tuple.
+ This is checked in _ctypes::CFuncPtr_Call
+ */
+ if (argtypes && argtype_count > i) {
+ PyObject *v;
+ converter = PyTuple_GET_ITEM(argtypes, i);
+ v = PyObject_CallFunctionObjArgs(converter,
+ arg,
+ NULL);
+ if (v == NULL) {
+ Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
+ goto cleanup;
+ }
+
+ err = ConvParam(v, i+1, pa);
+ Py_DECREF(v);
+ if (-1 == err) {
+ Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
+ goto cleanup;
+ }
+ } else {
+ err = ConvParam(arg, i+1, pa);
+ if (-1 == err) {
+ Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
+ goto cleanup; /* leaking ? */
+ }
+ }
+ }
+
+ rtype = GetType(restype);
+ resbuf = alloca(max(rtype->size, sizeof(ffi_arg)));
+
+ avalues = (void **)alloca(sizeof(void *) * argcount);
+ atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount);
+ if (!resbuf || !avalues || !atypes) {
+ PyErr_NoMemory();
+ goto cleanup;
+ }
+ for (i = 0; i < argcount; ++i) {
+ atypes[i] = args[i].ffi_type;
+ if (atypes[i]->type == FFI_TYPE_STRUCT)
+ avalues[i] = (void *)args[i].value.p;
+ else
+ avalues[i] = (void *)&args[i].value;
+ }
+
+ if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
+ rtype, resbuf, argcount))
+ goto cleanup;
+
+#ifdef WORDS_BIGENDIAN
+ /* libffi returns the result in a buffer with sizeof(ffi_arg). This
+ causes problems on big endian machines, since the result buffer
+ address cannot simply be used as result pointer, instead we must
+ adjust the pointer value:
+ */
+ /*
+ XXX I should find out and clarify why this is needed at all,
+ especially why adjusting for ffi_type_float must be avoided on
+ 64-bit platforms.
+ */
+ if (rtype->type != FFI_TYPE_FLOAT
+ && rtype->type != FFI_TYPE_STRUCT
+ && rtype->size < sizeof(ffi_arg))
+ resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
+#endif
+
+#ifdef MS_WIN32
+ if (iid && pIunk) {
+ if (*(int *)resbuf & 0x80000000)
+ retval = GetComError(*(HRESULT *)resbuf, iid, pIunk);
+ else
+ retval = PyInt_FromLong(*(int *)resbuf);
+ } else if (flags & FUNCFLAG_HRESULT) {
+ if (*(int *)resbuf & 0x80000000)
+ retval = PyErr_SetFromWindowsErr(*(int *)resbuf);
+ else
+ retval = PyInt_FromLong(*(int *)resbuf);
+ } else
+#endif
+ retval = GetResult(restype, resbuf, checker);
+ cleanup:
+ for (i = 0; i < argcount; ++i)
+ Py_XDECREF(args[i].keep);
+ return retval;
+}
+
+#ifdef MS_WIN32
+
+#ifdef _UNICODE
+# define PYBUILD_TSTR "u"
+#else
+# define PYBUILD_TSTR "s"
+# ifndef _T
+# define _T(text) text
+# endif
+#endif
+
+static char format_error_doc[] =
+"FormatError([integer]) -> string\n\
+\n\
+Convert a win32 error code into a string. If the error code is not\n\
+given, the return value of a call to GetLastError() is used.\n";
+static PyObject *format_error(PyObject *self, PyObject *args)
+{
+ PyObject *result;
+ TCHAR *lpMsgBuf;
+ DWORD code = 0;
+ if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
+ return NULL;
+ if (code == 0)
+ code = GetLastError();
+ lpMsgBuf = FormatError(code);
+ if (lpMsgBuf) {
+ result = Py_BuildValue(PYBUILD_TSTR, lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ } else {
+ result = Py_BuildValue("s", "<no description>");
+ }
+ return result;
+}
+
+static char load_library_doc[] =
+"LoadLibrary(name) -> handle\n\
+\n\
+Load an executable (usually a DLL), and return a handle to it.\n\
+The handle may be used to locate exported functions in this\n\
+module.\n";
+static PyObject *load_library(PyObject *self, PyObject *args)
+{
+ TCHAR *name;
+ PyObject *nameobj;
+ PyObject *ignored;
+ HMODULE hMod;
+ if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored))
+ return NULL;
+#ifdef _UNICODE
+ name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR));
+ if (!name) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ {
+ int r;
+ char *aname = PyString_AsString(nameobj);
+ if(!aname)
+ return NULL;
+ r = MultiByteToWideChar(CP_ACP, 0, aname, -1, name, PyString_Size(nameobj) + 1);
+ name[r] = 0;
+ }
+#else
+ name = PyString_AsString(nameobj);
+ if(!name)
+ return NULL;
+#endif
+
+ hMod = LoadLibrary(name);
+ if (!hMod)
+ return PyErr_SetFromWindowsErr(GetLastError());
+ return Py_BuildValue("i", hMod);
+}
+
+static char free_library_doc[] =
+"FreeLibrary(handle) -> void\n\
+\n\
+Free the handle of an executable previously loaded by LoadLibrary.\n";
+static PyObject *free_library(PyObject *self, PyObject *args)
+{
+ HMODULE hMod;
+ if (!PyArg_ParseTuple(args, "i:FreeLibrary", &hMod))
+ return NULL;
+ if (!FreeLibrary(hMod))
+ return PyErr_SetFromWindowsErr(GetLastError());
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* obsolete, should be removed */
+/* Only used by sample code (in samples\Windows\COM.py) */
+static PyObject *
+call_commethod(PyObject *self, PyObject *args)
+{
+ IUnknown *pIunk;
+ int index;
+ PyObject *arguments;
+ PPROC *lpVtbl;
+ PyObject *result;
+ CDataObject *pcom;
+ PyObject *argtypes = NULL;
+
+ if (!PyArg_ParseTuple(args,
+ "OiO!|O!",
+ &pcom, &index,
+ &PyTuple_Type, &arguments,
+ &PyTuple_Type, &argtypes))
+ return NULL;
+
+ if (argtypes && (PyTuple_GET_SIZE(arguments) != PyTuple_GET_SIZE(argtypes))) {
+ PyErr_Format(PyExc_TypeError,
+ "Method takes %d arguments (%d given)",
+ PyTuple_GET_SIZE(argtypes), PyTuple_GET_SIZE(arguments));
+ return NULL;
+ }
+
+ if (!CDataObject_Check(pcom) || (pcom->b_size != sizeof(void *))) {
+ PyErr_Format(PyExc_TypeError,
+ "COM Pointer expected instead of %s instance",
+ pcom->ob_type->tp_name);
+ return NULL;
+ }
+
+ if ((*(void **)(pcom->b_ptr)) == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "The COM 'this' pointer is NULL");
+ return NULL;
+ }
+
+ pIunk = (IUnknown *)(*(void **)(pcom->b_ptr));
+ lpVtbl = (PPROC *)(pIunk->lpVtbl);
+
+ result = _CallProc(lpVtbl[index],
+ arguments,
+#ifdef MS_WIN32
+ pIunk,
+ NULL,
+#endif
+ FUNCFLAG_HRESULT, /* flags */
+ argtypes, /* self->argtypes */
+ NULL, /* self->restype */
+ NULL); /* checker */
+ return result;
+}
+
+static char copy_com_pointer_doc[] =
+"CopyComPointer(src, dst) -> HRESULT value\n";
+
+static PyObject *
+copy_com_pointer(PyObject *self, PyObject *args)
+{
+ PyObject *p1, *p2, *r = NULL;
+ struct argument a, b;
+ IUnknown *src, **pdst;
+ if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2))
+ return NULL;
+ a.keep = b.keep = NULL;
+
+ if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b))
+ goto done;
+ src = (IUnknown *)a.value.p;
+ pdst = (IUnknown **)b.value.p;
+
+ if (pdst == NULL)
+ r = PyInt_FromLong(E_POINTER);
+ else {
+ if (src)
+ src->lpVtbl->AddRef(src);
+ *pdst = src;
+ r = PyInt_FromLong(S_OK);
+ }
+ done:
+ Py_XDECREF(a.keep);
+ Py_XDECREF(b.keep);
+ return r;
+}
+#else
+
+static PyObject *py_dl_open(PyObject *self, PyObject *args)
+{
+ char *name;
+ void * handle;
+#ifdef RTLD_LOCAL
+ int mode = RTLD_NOW | RTLD_LOCAL;
+#else
+ /* cygwin doesn't define RTLD_LOCAL */
+ int mode = RTLD_NOW;
+#endif
+ if (!PyArg_ParseTuple(args, "z|i:dlopen", &name, &mode))
+ return NULL;
+ mode |= RTLD_NOW;
+ handle = ctypes_dlopen(name, mode);
+ if (!handle) {
+ PyErr_SetString(PyExc_OSError,
+ ctypes_dlerror());
+ return NULL;
+ }
+ return PyLong_FromVoidPtr(handle);
+}
+
+static PyObject *py_dl_close(PyObject *self, PyObject *args)
+{
+ void * handle;
+
+ if (!PyArg_ParseTuple(args, "i:dlclose", &handle))
+ return NULL;
+ if (dlclose(handle)) {
+ PyErr_SetString(PyExc_OSError,
+ ctypes_dlerror());
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *py_dl_sym(PyObject *self, PyObject *args)
+{
+ char *name;
+ void *handle;
+ void *ptr;
+
+ if (!PyArg_ParseTuple(args, "is:dlsym", &handle, &name))
+ return NULL;
+ ptr = ctypes_dlsym(handle, name);
+ if (!ptr) {
+ PyErr_SetString(PyExc_OSError,
+ ctypes_dlerror());
+ return NULL;
+ }
+ return Py_BuildValue("i", ptr);
+}
+#endif
+
+/*
+ * Only for debugging so far: So that we can call CFunction instances
+ *
+ * XXX Needs to accept more arguments: flags, argtypes, restype
+ */
+static PyObject *
+call_function(PyObject *self, PyObject *args)
+{
+ PPROC func;
+ PyObject *arguments;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args,
+ "iO!",
+ &func,
+ &PyTuple_Type, &arguments))
+ return NULL;
+
+ result = _CallProc(func,
+ arguments,
+#ifdef MS_WIN32
+ NULL,
+ NULL,
+#endif
+ 0, /* flags */
+ NULL, /* self->argtypes */
+ NULL, /* self->restype */
+ NULL); /* checker */
+ return result;
+}
+
+/*
+ * Only for debugging so far: So that we can call CFunction instances
+ *
+ * XXX Needs to accept more arguments: flags, argtypes, restype
+ */
+static PyObject *
+call_cdeclfunction(PyObject *self, PyObject *args)
+{
+ PPROC func;
+ PyObject *arguments;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args,
+ "iO!",
+ &func,
+ &PyTuple_Type, &arguments))
+ return NULL;
+
+ result = _CallProc(func,
+ arguments,
+#ifdef MS_WIN32
+ NULL,
+ NULL,
+#endif
+ FUNCFLAG_CDECL, /* flags */
+ NULL, /* self->argtypes */
+ NULL, /* self->restype */
+ NULL); /* checker */
+ return result;
+}
+
+/*****************************************************************
+ * functions
+ */
+static char sizeof_doc[] =
+"sizeof(C type) -> integer\n"
+"sizeof(C instance) -> integer\n"
+"Return the size in bytes of a C instance";
+
+static PyObject *
+sizeof_func(PyObject *self, PyObject *obj)
+{
+ StgDictObject *dict;
+
+ dict = PyType_stgdict(obj);
+ if (dict)
+ return PyInt_FromLong(dict->size);
+
+ if (CDataObject_Check(obj))
+ return PyInt_FromLong(((CDataObject *)obj)->b_size);
+ PyErr_SetString(PyExc_TypeError,
+ "this type has no size");
+ return NULL;
+}
+
+static char alignment_doc[] =
+"alignment(C type) -> integer\n"
+"alignment(C instance) -> integer\n"
+"Return the alignment requirements of a C instance";
+
+static PyObject *
+align_func(PyObject *self, PyObject *obj)
+{
+ StgDictObject *dict;
+
+ dict = PyType_stgdict(obj);
+ if (dict)
+ return PyInt_FromLong(dict->align);
+
+ dict = PyObject_stgdict(obj);
+ if (dict)
+ return PyInt_FromLong(dict->align);
+
+ PyErr_SetString(PyExc_TypeError,
+ "no alignment info");
+ return NULL;
+}
+
+static char byref_doc[] =
+"byref(C instance) -> byref-object\n"
+"Return a pointer lookalike to a C instance, only usable\n"
+"as function argument";
+
+/*
+ * We must return something which can be converted to a parameter,
+ * but still has a reference to self.
+ */
+static PyObject *
+byref(PyObject *self, PyObject *obj)
+{
+ PyCArgObject *parg;
+ if (!CDataObject_Check(obj)) {
+ PyErr_Format(PyExc_TypeError,
+ "byref() argument must be a ctypes instance, not '%s'",
+ obj->ob_type->tp_name);
+ return NULL;
+ }
+
+ parg = new_CArgObject();
+ if (parg == NULL)
+ return NULL;
+
+ parg->tag = 'P';
+ parg->pffi_type = &ffi_type_pointer;
+ Py_INCREF(obj);
+ parg->obj = obj;
+ parg->value.p = ((CDataObject *)obj)->b_ptr;
+ return (PyObject *)parg;
+}
+
+static char addressof_doc[] =
+"addressof(C instance) -> integer\n"
+"Return the address of the C instance internal buffer";
+
+static PyObject *
+addressof(PyObject *self, PyObject *obj)
+{
+ if (CDataObject_Check(obj))
+ return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr);
+ PyErr_SetString(PyExc_TypeError,
+ "invalid type");
+ return NULL;
+}
+
+static int
+converter(PyObject *obj, void **address)
+{
+ *address = PyLong_AsVoidPtr(obj);
+ return *address != NULL;
+}
+
+static PyObject *
+My_PyObj_FromPtr(PyObject *self, PyObject *args)
+{
+ PyObject *ob;
+ if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob))
+ return NULL;
+ Py_INCREF(ob);
+ return ob;
+}
+
+static PyObject *
+My_Py_INCREF(PyObject *self, PyObject *arg)
+{
+ Py_INCREF(arg); /* that's what this function is for */
+ Py_INCREF(arg); /* that for returning it */
+ return arg;
+}
+
+static PyObject *
+My_Py_DECREF(PyObject *self, PyObject *arg)
+{
+ Py_DECREF(arg); /* that's what this function is for */
+ Py_INCREF(arg); /* that's for returning it */
+ return arg;
+}
+
+#ifdef CTYPES_UNICODE
+
+static char set_conversion_mode_doc[] =
+"set_conversion_mode(encoding, errors) -> (previous-encoding, previous-errors)\n\
+\n\
+Set the encoding and error handling ctypes uses when converting\n\
+between unicode and strings. Returns the previous values.\n";
+
+static PyObject *
+set_conversion_mode(PyObject *self, PyObject *args)
+{
+ char *coding, *mode;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "zs:set_conversion_mode", &coding, &mode))
+ return NULL;
+ result = Py_BuildValue("(zz)", conversion_mode_encoding, conversion_mode_errors);
+ if (coding) {
+ PyMem_Free(conversion_mode_encoding);
+ conversion_mode_encoding = PyMem_Malloc(strlen(coding) + 1);
+ strcpy(conversion_mode_encoding, coding);
+ } else {
+ conversion_mode_encoding = NULL;
+ }
+ PyMem_Free(conversion_mode_errors);
+ conversion_mode_errors = PyMem_Malloc(strlen(mode) + 1);
+ strcpy(conversion_mode_errors, mode);
+ return result;
+}
+#endif
+
+static PyObject *
+resize(PyObject *self, PyObject *args)
+{
+ CDataObject *obj;
+ StgDictObject *dict;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args,
+#if (PY_VERSION_HEX < 0x02050000)
+ "Oi:resize",
+#else
+ "On:resize",
+#endif
+ (PyObject *)&obj, &size))
+ return NULL;
+
+ dict = PyObject_stgdict((PyObject *)obj);
+ if (dict == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "excepted ctypes instance");
+ return NULL;
+ }
+ if (size < dict->size) {
+ PyErr_Format(PyExc_ValueError,
+#if PY_VERSION_HEX < 0x02050000
+ "minimum size is %d",
+#else
+ "minimum size is %zd",
+#endif
+ dict->size);
+ return NULL;
+ }
+ if (obj->b_needsfree == 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Memory cannot be resized because this object doesn't own it");
+ return NULL;
+ }
+ if (size <= sizeof(obj->b_value)) {
+ /* internal default buffer is large enough */
+ obj->b_size = size;
+ goto done;
+ }
+ if (obj->b_size <= sizeof(obj->b_value)) {
+ /* We are currently using the objects default buffer, but it
+ isn't large enough any more. */
+ void *ptr = PyMem_Malloc(size);
+ if (ptr == NULL)
+ return PyErr_NoMemory();
+ memset(ptr, 0, size);
+ memmove(ptr, obj->b_ptr, obj->b_size);
+ obj->b_ptr = ptr;
+ obj->b_size = size;
+ } else {
+ void * ptr = PyMem_Realloc(obj->b_ptr, size);
+ if (ptr == NULL)
+ return PyErr_NoMemory();
+ obj->b_ptr = ptr;
+ obj->b_size = size;
+ }
+ done:
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyMethodDef module_methods[] = {
+ {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
+#ifdef CTYPES_UNICODE
+ {"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
+#endif
+#ifdef MS_WIN32
+ {"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc},
+ {"FormatError", format_error, METH_VARARGS, format_error_doc},
+ {"LoadLibrary", load_library, METH_VARARGS, load_library_doc},
+ {"FreeLibrary", free_library, METH_VARARGS, free_library_doc},
+ {"call_commethod", call_commethod, METH_VARARGS },
+ {"_check_HRESULT", check_hresult, METH_VARARGS},
+#else
+ {"dlopen", py_dl_open, METH_VARARGS,
+ "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"},
+ {"dlclose", py_dl_close, METH_VARARGS, "dlclose a library"},
+ {"dlsym", py_dl_sym, METH_VARARGS, "find symbol in shared library"},
+#endif
+ {"alignment", align_func, METH_O, alignment_doc},
+ {"sizeof", sizeof_func, METH_O, sizeof_doc},
+ {"byref", byref, METH_O, byref_doc},
+ {"addressof", addressof, METH_O, addressof_doc},
+ {"call_function", call_function, METH_VARARGS },
+ {"call_cdeclfunction", call_cdeclfunction, METH_VARARGS },
+ {"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS },
+ {"Py_INCREF", My_Py_INCREF, METH_O },
+ {"Py_DECREF", My_Py_DECREF, METH_O },
+ {NULL, NULL} /* Sentinel */
+};
+
+/*
+ Local Variables:
+ compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
+ End:
+*/
diff --git a/sys/src/cmd/python/Modules/_ctypes/cfield.c b/sys/src/cmd/python/Modules/_ctypes/cfield.c
new file mode 100644
index 000000000..c16a38746
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/cfield.c
@@ -0,0 +1,1668 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include "Python.h"
+
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+#include "ctypes.h"
+
+/******************************************************************/
+/*
+ CField_Type
+*/
+static PyObject *
+CField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CFieldObject *obj;
+ obj = (CFieldObject *)type->tp_alloc(type, 0);
+ return (PyObject *)obj;
+}
+
+/*
+ * Expects the size, index and offset for the current field in *psize and
+ * *poffset, stores the total size so far in *psize, the offset for the next
+ * field in *poffset, the alignment requirements for the current field in
+ * *palign, and returns a field desriptor for this field.
+ */
+/*
+ * bitfields extension:
+ * bitsize != 0: this is a bit field.
+ * pbitofs points to the current bit offset, this will be updated.
+ * prev_desc points to the type of the previous bitfield, if any.
+ */
+PyObject *
+CField_FromDesc(PyObject *desc, int index,
+ int *pfield_size, int bitsize, int *pbitofs,
+ int *psize, int *poffset, int *palign,
+ int pack, int big_endian)
+{
+ CFieldObject *self;
+ PyObject *proto;
+ int size, align, length;
+ SETFUNC setfunc = NULL;
+ GETFUNC getfunc = NULL;
+ StgDictObject *dict;
+ int fieldtype;
+#define NO_BITFIELD 0
+#define NEW_BITFIELD 1
+#define CONT_BITFIELD 2
+#define EXPAND_BITFIELD 3
+
+ self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type,
+ NULL);
+ if (self == NULL)
+ return NULL;
+ dict = PyType_stgdict(desc);
+ if (!dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "has no _stginfo_");
+ Py_DECREF(self);
+ return NULL;
+ }
+ if (bitsize /* this is a bitfield request */
+ && *pfield_size /* we have a bitfield open */
+#if defined(MS_WIN32) && !defined(__MINGW32__)
+ && dict->size * 8 == *pfield_size /* MSVC */
+#else
+ && dict->size * 8 <= *pfield_size /* GCC, MINGW */
+#endif
+ && (*pbitofs + bitsize) <= *pfield_size) {
+ /* continue bit field */
+ fieldtype = CONT_BITFIELD;
+#ifndef MS_WIN32
+ } else if (bitsize /* this is a bitfield request */
+ && *pfield_size /* we have a bitfield open */
+ && dict->size * 8 >= *pfield_size
+ && (*pbitofs + bitsize) <= dict->size * 8) {
+ /* expand bit field */
+ fieldtype = EXPAND_BITFIELD;
+#endif
+ } else if (bitsize) {
+ /* start new bitfield */
+ fieldtype = NEW_BITFIELD;
+ *pbitofs = 0;
+ *pfield_size = dict->size * 8;
+ } else {
+ /* not a bit field */
+ fieldtype = NO_BITFIELD;
+ *pbitofs = 0;
+ *pfield_size = 0;
+ }
+
+ size = dict->size;
+ length = dict->length;
+ proto = desc;
+
+ /* Field descriptors for 'c_char * n' are be scpecial cased to
+ return a Python string instead of an Array object instance...
+ */
+ if (ArrayTypeObject_Check(proto)) {
+ StgDictObject *adict = PyType_stgdict(proto);
+ StgDictObject *idict;
+ if (adict && adict->proto) {
+ idict = PyType_stgdict(adict->proto);
+ if (!idict) {
+ PyErr_SetString(PyExc_TypeError,
+ "has no _stginfo_");
+ Py_DECREF(self);
+ return NULL;
+ }
+ if (idict->getfunc == getentry("c")->getfunc) {
+ struct fielddesc *fd = getentry("s");
+ getfunc = fd->getfunc;
+ setfunc = fd->setfunc;
+ }
+#ifdef CTYPES_UNICODE
+ if (idict->getfunc == getentry("u")->getfunc) {
+ struct fielddesc *fd = getentry("U");
+ getfunc = fd->getfunc;
+ setfunc = fd->setfunc;
+ }
+#endif
+ }
+ }
+
+ self->setfunc = setfunc;
+ self->getfunc = getfunc;
+ self->index = index;
+
+ Py_INCREF(proto);
+ self->proto = proto;
+
+ switch (fieldtype) {
+ case NEW_BITFIELD:
+ if (big_endian)
+ self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
+ else
+ self->size = (bitsize << 16) + *pbitofs;
+ *pbitofs = bitsize;
+ /* fall through */
+ case NO_BITFIELD:
+ if (pack)
+ align = min(pack, dict->align);
+ else
+ align = dict->align;
+ if (align && *poffset % align) {
+ int delta = align - (*poffset % align);
+ *psize += delta;
+ *poffset += delta;
+ }
+
+ if (bitsize == 0)
+ self->size = size;
+ *psize += size;
+
+ self->offset = *poffset;
+ *poffset += size;
+
+ *palign = align;
+ break;
+
+ case EXPAND_BITFIELD:
+ /* XXX needs more */
+ *psize += dict->size - *pfield_size/8;
+
+ *pfield_size = dict->size * 8;
+
+ if (big_endian)
+ self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
+ else
+ self->size = (bitsize << 16) + *pbitofs;
+
+ self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
+ *pbitofs += bitsize;
+ break;
+
+ case CONT_BITFIELD:
+ if (big_endian)
+ self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
+ else
+ self->size = (bitsize << 16) + *pbitofs;
+
+ self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
+ *pbitofs += bitsize;
+ break;
+ }
+
+ return (PyObject *)self;
+}
+
+static int
+CField_set(CFieldObject *self, PyObject *inst, PyObject *value)
+{
+ CDataObject *dst;
+ char *ptr;
+ assert(CDataObject_Check(inst));
+ dst = (CDataObject *)inst;
+ ptr = dst->b_ptr + self->offset;
+ return CData_set(inst, self->proto, self->setfunc, value,
+ self->index, self->size, ptr);
+}
+
+static PyObject *
+CField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
+{
+ CDataObject *src;
+ if (inst == NULL) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ assert(CDataObject_Check(inst));
+ src = (CDataObject *)inst;
+ return CData_get(self->proto, self->getfunc, inst,
+ self->index, self->size, src->b_ptr + self->offset);
+}
+
+static PyObject *
+CField_get_offset(PyObject *self, void *data)
+{
+#if (PY_VERSION_HEX < 0x02050000)
+ return PyInt_FromLong(((CFieldObject *)self)->offset);
+#else
+ return PyInt_FromSsize_t(((CFieldObject *)self)->offset);
+#endif
+}
+
+static PyObject *
+CField_get_size(PyObject *self, void *data)
+{
+#if (PY_VERSION_HEX < 0x02050000)
+ return PyInt_FromLong(((CFieldObject *)self)->size);
+#else
+ return PyInt_FromSsize_t(((CFieldObject *)self)->size);
+#endif
+}
+
+static PyGetSetDef CField_getset[] = {
+ { "offset", CField_get_offset, NULL, "offset in bytes of this field" },
+ { "size", CField_get_size, NULL, "size in bytes of this field" },
+ { NULL, NULL, NULL, NULL },
+};
+
+static int
+CField_traverse(CFieldObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->proto);
+ return 0;
+}
+
+static int
+CField_clear(CFieldObject *self)
+{
+ Py_CLEAR(self->proto);
+ return 0;
+}
+
+static void
+CField_dealloc(PyObject *self)
+{
+ CField_clear((CFieldObject *)self);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+CField_repr(CFieldObject *self)
+{
+ PyObject *result;
+ int bits = self->size >> 16;
+ int size = self->size & 0xFFFF;
+ const char *name;
+
+ name = ((PyTypeObject *)self->proto)->tp_name;
+
+ if (bits)
+ result = PyString_FromFormat(
+#if (PY_VERSION_HEX < 0x02050000)
+ "<Field type=%s, ofs=%d:%d, bits=%d>",
+#else
+ "<Field type=%s, ofs=%zd:%d, bits=%d>",
+#endif
+ name, self->offset, size, bits);
+ else
+ result = PyString_FromFormat(
+#if (PY_VERSION_HEX < 0x02050000)
+ "<Field type=%s, ofs=%d, size=%d>",
+#else
+ "<Field type=%s, ofs=%zd, size=%d>",
+#endif
+ name, self->offset, size);
+ return result;
+}
+
+PyTypeObject CField_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_ctypes.CField", /* tp_name */
+ sizeof(CFieldObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ CField_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)CField_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ "Structure/Union member", /* tp_doc */
+ (traverseproc)CField_traverse, /* tp_traverse */
+ (inquiry)CField_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ CField_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)CField_get, /* tp_descr_get */
+ (descrsetfunc)CField_set, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ CField_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/******************************************************************/
+/*
+ Accessor functions
+*/
+
+/* Derived from Modules/structmodule.c:
+ Helper routine to get a Python integer and raise the appropriate error
+ if it isn't one */
+
+static int
+get_long(PyObject *v, long *p)
+{
+ long x;
+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "int expected instead of %s instance",
+ v->ob_type->tp_name);
+ return -1;
+ }
+ x = PyInt_AsUnsignedLongMask(v);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+}
+
+/* Same, but handling unsigned long */
+
+static int
+get_ulong(PyObject *v, unsigned long *p)
+{
+ unsigned long x;
+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "int expected instead of %s instance",
+ v->ob_type->tp_name);
+ return -1;
+ }
+ x = PyInt_AsUnsignedLongMask(v);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Same, but handling native long long. */
+
+static int
+get_longlong(PyObject *v, PY_LONG_LONG *p)
+{
+ PY_LONG_LONG x;
+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "int expected instead of %s instance",
+ v->ob_type->tp_name);
+ return -1;
+ }
+ x = PyInt_AsUnsignedLongLongMask(v);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+}
+
+/* Same, but handling native unsigned long long. */
+
+static int
+get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
+{
+ unsigned PY_LONG_LONG x;
+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "int expected instead of %s instance",
+ v->ob_type->tp_name);
+ return -1;
+ }
+ x = PyInt_AsUnsignedLongLongMask(v);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+}
+
+#endif
+
+/*****************************************************************
+ * Integer fields, with bitfield support
+ */
+
+/* how to decode the size field, for integer get/set functions */
+#define LOW_BIT(x) ((x) & 0xFFFF)
+#define NUM_BITS(x) ((x) >> 16)
+
+/* This seems nore a compiler issue than a Windows/non-Windows one */
+#ifdef MS_WIN32
+# define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
+#else
+# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
+#endif
+
+/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
+ we must first shift left, then right.
+*/
+#define GET_BITFIELD(v, size) \
+ if (NUM_BITS(size)) { \
+ v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
+ v >>= (sizeof(v)*8 - NUM_BITS(size)); \
+ }
+
+/* This macro RETURNS the first parameter with the bit field CHANGED. */
+#define SET(x, v, size) \
+ (NUM_BITS(size) ? \
+ ( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \
+ : v)
+
+/* byte swapping macros */
+#define SWAP_2(v) \
+ ( ( (v >> 8) & 0x00FF) | \
+ ( (v << 8) & 0xFF00) )
+
+#define SWAP_4(v) \
+ ( ( (v & 0x000000FF) << 24 ) | \
+ ( (v & 0x0000FF00) << 8 ) | \
+ ( (v & 0x00FF0000) >> 8 ) | \
+ ( ((v >> 24) & 0xFF)) )
+
+#ifdef _MSC_VER
+#define SWAP_8(v) \
+ ( ( (v & 0x00000000000000FFL) << 56 ) | \
+ ( (v & 0x000000000000FF00L) << 40 ) | \
+ ( (v & 0x0000000000FF0000L) << 24 ) | \
+ ( (v & 0x00000000FF000000L) << 8 ) | \
+ ( (v & 0x000000FF00000000L) >> 8 ) | \
+ ( (v & 0x0000FF0000000000L) >> 24 ) | \
+ ( (v & 0x00FF000000000000L) >> 40 ) | \
+ ( ((v >> 56) & 0xFF)) )
+#else
+#define SWAP_8(v) \
+ ( ( (v & 0x00000000000000FFLL) << 56 ) | \
+ ( (v & 0x000000000000FF00LL) << 40 ) | \
+ ( (v & 0x0000000000FF0000LL) << 24 ) | \
+ ( (v & 0x00000000FF000000LL) << 8 ) | \
+ ( (v & 0x000000FF00000000LL) >> 8 ) | \
+ ( (v & 0x0000FF0000000000LL) >> 24 ) | \
+ ( (v & 0x00FF000000000000LL) >> 40 ) | \
+ ( ((v >> 56) & 0xFF)) )
+#endif
+
+#define SWAP_INT SWAP_4
+
+#if SIZEOF_LONG == 4
+# define SWAP_LONG SWAP_4
+#elif SIZEOF_LONG == 8
+# define SWAP_LONG SWAP_8
+#endif
+/*****************************************************************
+ * The setter methods return an object which must be kept alive, to keep the
+ * data valid which has been stored in the memory block. The ctypes object
+ * instance inserts this object into its 'b_objects' list.
+ *
+ * For simple Python types like integers or characters, there is nothing that
+ * has to been kept alive, so Py_None is returned in these cases. But this
+ * makes inspecting the 'b_objects' list, which is accessible from Python for
+ * debugging, less useful.
+ *
+ * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
+ * instead of Py_None.
+ */
+
+#ifdef _CTYPES_DEBUG_KEEP
+#define _RET(x) Py_INCREF(x); return x
+#else
+#define _RET(X) Py_INCREF(Py_None); return Py_None
+#endif
+
+/*****************************************************************
+ * integer accessor methods, supporting bit fields
+ */
+
+static PyObject *
+b_set(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ *(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
+ _RET(value);
+}
+
+
+static PyObject *
+b_get(void *ptr, unsigned size)
+{
+ signed char val = *(signed char *)ptr;
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+B_set(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr,
+ (unsigned short)val, size);
+ _RET(value);
+}
+
+
+static PyObject *
+B_get(void *ptr, unsigned size)
+{
+ unsigned char val = *(unsigned char *)ptr;
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+h_set(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ short x;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, (short)val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+
+static PyObject *
+h_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ short field;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_2(field);
+ field = SET(field, (short)val, size);
+ field = SWAP_2(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+static PyObject *
+h_get(void *ptr, unsigned size)
+{
+ short val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong((long)val);
+}
+
+static PyObject *
+h_get_sw(void *ptr, unsigned size)
+{
+ short val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_2(val);
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+H_set(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ unsigned short x;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, (unsigned short)val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+H_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ unsigned short field;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_2(field);
+ field = SET(field, (unsigned short)val, size);
+ field = SWAP_2(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+
+static PyObject *
+H_get(void *ptr, unsigned size)
+{
+ unsigned short val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+H_get_sw(void *ptr, unsigned size)
+{
+ unsigned short val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_2(val);
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+i_set(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ int x;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, (int)val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+i_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ int field;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_INT(field);
+ field = SET(field, (int)val, size);
+ field = SWAP_INT(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+
+static PyObject *
+i_get(void *ptr, unsigned size)
+{
+ int val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+i_get_sw(void *ptr, unsigned size)
+{
+ int val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_INT(val);
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+#ifdef MS_WIN32
+/* short BOOL - VARIANT_BOOL */
+static PyObject *
+vBOOL_set(void *ptr, PyObject *value, unsigned size)
+{
+ switch (PyObject_IsTrue(value)) {
+ case -1:
+ return NULL;
+ case 0:
+ *(short int *)ptr = VARIANT_FALSE;
+ _RET(value);
+ default:
+ *(short int *)ptr = VARIANT_TRUE;
+ _RET(value);
+ }
+}
+
+static PyObject *
+vBOOL_get(void *ptr, unsigned size)
+{
+ return PyBool_FromLong((long)*(short int *)ptr);
+}
+#endif
+
+static PyObject *
+I_set(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ unsigned int x;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, (unsigned int)val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+I_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ unsigned int field;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = (unsigned int)SET(field, (unsigned int)val, size);
+ field = SWAP_INT(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+
+static PyObject *
+I_get(void *ptr, unsigned size)
+{
+ unsigned int val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyLong_FromUnsignedLong(val);
+}
+
+static PyObject *
+I_get_sw(void *ptr, unsigned size)
+{
+ unsigned int val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_INT(val);
+ GET_BITFIELD(val, size);
+ return PyLong_FromUnsignedLong(val);
+}
+
+static PyObject *
+l_set(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ long x;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+l_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ long val;
+ long field;
+ if (get_long(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_LONG(field);
+ field = (long)SET(field, val, size);
+ field = SWAP_LONG(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+
+static PyObject *
+l_get(void *ptr, unsigned size)
+{
+ long val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+l_get_sw(void *ptr, unsigned size)
+{
+ long val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_LONG(val);
+ GET_BITFIELD(val, size);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+L_set(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ unsigned long x;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+L_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned long val;
+ unsigned long field;
+ if (get_ulong(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_LONG(field);
+ field = (unsigned long)SET(field, val, size);
+ field = SWAP_LONG(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+
+static PyObject *
+L_get(void *ptr, unsigned size)
+{
+ unsigned long val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyLong_FromUnsignedLong(val);
+}
+
+static PyObject *
+L_get_sw(void *ptr, unsigned size)
+{
+ unsigned long val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_LONG(val);
+ GET_BITFIELD(val, size);
+ return PyLong_FromUnsignedLong(val);
+}
+
+#ifdef HAVE_LONG_LONG
+static PyObject *
+q_set(void *ptr, PyObject *value, unsigned size)
+{
+ PY_LONG_LONG val;
+ PY_LONG_LONG x;
+ if (get_longlong(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+q_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ PY_LONG_LONG val;
+ PY_LONG_LONG field;
+ if (get_longlong(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_8(field);
+ field = (PY_LONG_LONG)SET(field, val, size);
+ field = SWAP_8(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+static PyObject *
+q_get(void *ptr, unsigned size)
+{
+ PY_LONG_LONG val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyLong_FromLongLong(val);
+}
+
+static PyObject *
+q_get_sw(void *ptr, unsigned size)
+{
+ PY_LONG_LONG val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_8(val);
+ GET_BITFIELD(val, size);
+ return PyLong_FromLongLong(val);
+}
+
+static PyObject *
+Q_set(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned PY_LONG_LONG val;
+ unsigned PY_LONG_LONG x;
+ if (get_ulonglong(value, &val) < 0)
+ return NULL;
+ memcpy(&x, ptr, sizeof(x));
+ x = SET(x, val, size);
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+Q_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ unsigned PY_LONG_LONG val;
+ unsigned PY_LONG_LONG field;
+ if (get_ulonglong(value, &val) < 0)
+ return NULL;
+ memcpy(&field, ptr, sizeof(field));
+ field = SWAP_8(field);
+ field = (unsigned PY_LONG_LONG)SET(field, val, size);
+ field = SWAP_8(field);
+ memcpy(ptr, &field, sizeof(field));
+ _RET(value);
+}
+
+static PyObject *
+Q_get(void *ptr, unsigned size)
+{
+ unsigned PY_LONG_LONG val;
+ memcpy(&val, ptr, sizeof(val));
+ GET_BITFIELD(val, size);
+ return PyLong_FromUnsignedLongLong(val);
+}
+
+static PyObject *
+Q_get_sw(void *ptr, unsigned size)
+{
+ unsigned PY_LONG_LONG val;
+ memcpy(&val, ptr, sizeof(val));
+ val = SWAP_8(val);
+ GET_BITFIELD(val, size);
+ return PyLong_FromUnsignedLongLong(val);
+}
+#endif
+
+/*****************************************************************
+ * non-integer accessor methods, not supporting bit fields
+ */
+
+
+
+static PyObject *
+d_set(void *ptr, PyObject *value, unsigned size)
+{
+ double x;
+
+ x = PyFloat_AsDouble(value);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ " float expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ }
+ memcpy(ptr, &x, sizeof(double));
+ _RET(value);
+}
+
+static PyObject *
+d_get(void *ptr, unsigned size)
+{
+ double val;
+ memcpy(&val, ptr, sizeof(val));
+ return PyFloat_FromDouble(val);
+}
+
+static PyObject *
+d_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ double x;
+
+ x = PyFloat_AsDouble(value);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ " float expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ }
+#ifdef WORDS_BIGENDIAN
+ if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
+ return NULL;
+#else
+ if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
+ return NULL;
+#endif
+ _RET(value);
+}
+
+static PyObject *
+d_get_sw(void *ptr, unsigned size)
+{
+#ifdef WORDS_BIGENDIAN
+ return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
+#else
+ return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
+#endif
+}
+
+static PyObject *
+f_set(void *ptr, PyObject *value, unsigned size)
+{
+ float x;
+
+ x = (float)PyFloat_AsDouble(value);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ " float expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ }
+ memcpy(ptr, &x, sizeof(x));
+ _RET(value);
+}
+
+static PyObject *
+f_get(void *ptr, unsigned size)
+{
+ float val;
+ memcpy(&val, ptr, sizeof(val));
+ return PyFloat_FromDouble(val);
+}
+
+static PyObject *
+f_set_sw(void *ptr, PyObject *value, unsigned size)
+{
+ float x;
+
+ x = (float)PyFloat_AsDouble(value);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ " float expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ }
+#ifdef WORDS_BIGENDIAN
+ if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
+ return NULL;
+#else
+ if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
+ return NULL;
+#endif
+ _RET(value);
+}
+
+static PyObject *
+f_get_sw(void *ptr, unsigned size)
+{
+#ifdef WORDS_BIGENDIAN
+ return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
+#else
+ return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
+#endif
+}
+
+/*
+ py_object refcounts:
+
+ 1. If we have a py_object instance, O_get must Py_INCREF the returned
+ object, of course. If O_get is called from a function result, no py_object
+ instance is created - so callproc.c::GetResult has to call Py_DECREF.
+
+ 2. The memory block in py_object owns a refcount. So, py_object must call
+ Py_DECREF on destruction. Maybe only when b_needsfree is non-zero.
+*/
+static PyObject *
+O_get(void *ptr, unsigned size)
+{
+ PyObject *ob = *(PyObject **)ptr;
+ if (ob == NULL) {
+ if (!PyErr_Occurred())
+ /* Set an error if not yet set */
+ PyErr_SetString(PyExc_ValueError,
+ "PyObject is NULL");
+ return NULL;
+ }
+ Py_INCREF(ob);
+ return ob;
+}
+
+static PyObject *
+O_set(void *ptr, PyObject *value, unsigned size)
+{
+ /* Hm, does the memory block need it's own refcount or not? */
+ *(PyObject **)ptr = value;
+ Py_INCREF(value);
+ return value;
+}
+
+
+static PyObject *
+c_set(void *ptr, PyObject *value, unsigned size)
+{
+ if (!PyString_Check(value) || (1 != PyString_Size(value))) {
+ PyErr_Format(PyExc_TypeError,
+ "one character string expected");
+ return NULL;
+ }
+ *(char *)ptr = PyString_AS_STRING(value)[0];
+ _RET(value);
+}
+
+
+static PyObject *
+c_get(void *ptr, unsigned size)
+{
+ return PyString_FromStringAndSize((char *)ptr, 1);
+}
+
+#ifdef CTYPES_UNICODE
+/* u - a single wchar_t character */
+static PyObject *
+u_set(void *ptr, PyObject *value, unsigned size)
+{
+ int len;
+
+ if (PyString_Check(value)) {
+ value = PyUnicode_FromEncodedObject(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (!value)
+ return NULL;
+ } else if (!PyUnicode_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "unicode string expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ } else
+ Py_INCREF(value);
+
+ len = PyUnicode_GET_SIZE(value);
+ if (len != 1) {
+ Py_DECREF(value);
+ PyErr_SetString(PyExc_TypeError,
+ "one character unicode string expected");
+ return NULL;
+ }
+
+ *(wchar_t *)ptr = PyUnicode_AS_UNICODE(value)[0];
+ Py_DECREF(value);
+
+ _RET(value);
+}
+
+
+static PyObject *
+u_get(void *ptr, unsigned size)
+{
+ return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
+}
+
+/* U - a unicode string */
+static PyObject *
+U_get(void *ptr, unsigned size)
+{
+ PyObject *result;
+ unsigned int len;
+ Py_UNICODE *p;
+
+ size /= sizeof(wchar_t); /* we count character units here, not bytes */
+
+ result = PyUnicode_FromWideChar((wchar_t *)ptr, size);
+ if (!result)
+ return NULL;
+ /* We need 'result' to be able to count the characters with wcslen,
+ since ptr may not be NUL terminated. If the length is smaller (if
+ it was actually NUL terminated, we construct a new one and throw
+ away the result.
+ */
+ /* chop off at the first NUL character, if any. */
+ p = PyUnicode_AS_UNICODE(result);
+ for (len = 0; len < size; ++len)
+ if (!p[len])
+ break;
+
+ if (len < size) {
+ PyObject *ob = PyUnicode_FromWideChar((wchar_t *)ptr, len);
+ Py_DECREF(result);
+ return ob;
+ }
+ return result;
+}
+
+static PyObject *
+U_set(void *ptr, PyObject *value, unsigned length)
+{
+ unsigned int size;
+
+ /* It's easier to calculate in characters than in bytes */
+ length /= sizeof(wchar_t);
+
+ if (PyString_Check(value)) {
+ value = PyUnicode_FromEncodedObject(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (!value)
+ return NULL;
+ } else if (!PyUnicode_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "unicode string expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ } else
+ Py_INCREF(value);
+ size = PyUnicode_GET_SIZE(value);
+ if (size > length) {
+ PyErr_Format(PyExc_ValueError,
+ "string too long (%d, maximum length %d)",
+ size, length);
+ Py_DECREF(value);
+ return NULL;
+ } else if (size < length-1)
+ /* copy terminating NUL character if there is space */
+ size += 1;
+ PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size);
+ return value;
+}
+
+#endif
+
+static PyObject *
+s_get(void *ptr, unsigned size)
+{
+ PyObject *result;
+
+ result = PyString_FromString((char *)ptr);
+ if (!result)
+ return NULL;
+ /* chop off at the first NUL character, if any.
+ * On error, result will be deallocated and set to NULL.
+ */
+ size = min(size, strlen(PyString_AS_STRING(result)));
+ if (result->ob_refcnt == 1) {
+ /* shorten the result */
+ _PyString_Resize(&result, size);
+ return result;
+ } else
+ /* cannot shorten the result */
+ return PyString_FromStringAndSize(ptr, size);
+}
+
+static PyObject *
+s_set(void *ptr, PyObject *value, unsigned length)
+{
+ char *data;
+ unsigned size;
+
+ data = PyString_AsString(value);
+ if (!data)
+ return NULL;
+ size = strlen(data);
+ if (size < length) {
+ /* This will copy the leading NUL character
+ * if there is space for it.
+ */
+ ++size;
+ } else if (size > length) {
+ PyErr_Format(PyExc_ValueError,
+ "string too long (%d, maximum length %d)",
+ size, length);
+ return NULL;
+ }
+ /* Also copy the terminating NUL character if there is space */
+ memcpy((char *)ptr, data, size);
+ _RET(value);
+}
+
+static PyObject *
+z_set(void *ptr, PyObject *value, unsigned size)
+{
+ if (value == Py_None) {
+ *(char **)ptr = NULL;
+ Py_INCREF(value);
+ return value;
+ }
+ if (PyString_Check(value)) {
+ *(char **)ptr = PyString_AS_STRING(value);
+ Py_INCREF(value);
+ return value;
+ } else if (PyUnicode_Check(value)) {
+ PyObject *str = PyUnicode_AsEncodedString(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (str == NULL)
+ return NULL;
+ *(char **)ptr = PyString_AS_STRING(str);
+ return str;
+ } else if (PyInt_Check(value) || PyLong_Check(value)) {
+ *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value);
+ _RET(value);
+ }
+ PyErr_Format(PyExc_TypeError,
+ "string or integer address expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+}
+
+static PyObject *
+z_get(void *ptr, unsigned size)
+{
+ /* XXX What about invalid pointers ??? */
+ if (*(void **)ptr) {
+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
+ if (IsBadStringPtrA(*(char **)ptr, -1)) {
+ PyErr_Format(PyExc_ValueError,
+ "invalid string pointer %p",
+ ptr);
+ return NULL;
+ }
+#endif
+ return PyString_FromString(*(char **)ptr);
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+#ifdef CTYPES_UNICODE
+static PyObject *
+Z_set(void *ptr, PyObject *value, unsigned size)
+{
+ if (value == Py_None) {
+ *(wchar_t **)ptr = NULL;
+ Py_INCREF(value);
+ return value;
+ }
+ if (PyString_Check(value)) {
+ value = PyUnicode_FromEncodedObject(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (!value)
+ return NULL;
+ } else if (PyInt_Check(value) || PyLong_Check(value)) {
+ *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value);
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else if (!PyUnicode_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "unicode string or integer address expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ } else
+ Py_INCREF(value);
+#ifdef HAVE_USABLE_WCHAR_T
+ /* HAVE_USABLE_WCHAR_T means that Py_UNICODE and wchar_t is the same
+ type. So we can copy directly. Hm, are unicode objects always NUL
+ terminated in Python, internally?
+ */
+ *(wchar_t **)ptr = PyUnicode_AS_UNICODE(value);
+ return value;
+#else
+ {
+ /* We must create a wchar_t* buffer from the unicode object,
+ and keep it alive */
+ PyObject *keep;
+ wchar_t *buffer;
+
+ int size = PyUnicode_GET_SIZE(value);
+ size += 1; /* terminating NUL */
+ size *= sizeof(wchar_t);
+ buffer = (wchar_t *)PyMem_Malloc(size);
+ if (!buffer)
+ return NULL;
+ memset(buffer, 0, size);
+ keep = PyCObject_FromVoidPtr(buffer, PyMem_Free);
+ if (!keep) {
+ PyMem_Free(buffer);
+ return NULL;
+ }
+ *(wchar_t **)ptr = (wchar_t *)buffer;
+ if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
+ buffer, PyUnicode_GET_SIZE(value))) {
+ Py_DECREF(value);
+ Py_DECREF(keep);
+ return NULL;
+ }
+ Py_DECREF(value);
+ return keep;
+ }
+#endif
+}
+
+static PyObject *
+Z_get(void *ptr, unsigned size)
+{
+ wchar_t *p;
+ p = *(wchar_t **)ptr;
+ if (p)
+ return PyUnicode_FromWideChar(p, wcslen(p));
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif
+
+#ifdef MS_WIN32
+static PyObject *
+BSTR_set(void *ptr, PyObject *value, unsigned size)
+{
+ BSTR bstr;
+
+ /* convert value into a PyUnicodeObject or NULL */
+ if (Py_None == value) {
+ value = NULL;
+ } else if (PyString_Check(value)) {
+ value = PyUnicode_FromEncodedObject(value,
+ conversion_mode_encoding,
+ conversion_mode_errors);
+ if (!value)
+ return NULL;
+ } else if (PyUnicode_Check(value)) {
+ Py_INCREF(value); /* for the descref below */
+ } else {
+ PyErr_Format(PyExc_TypeError,
+ "unicode string expected instead of %s instance",
+ value->ob_type->tp_name);
+ return NULL;
+ }
+
+ /* create a BSTR from value */
+ if (value) {
+ bstr = SysAllocStringLen(PyUnicode_AS_UNICODE(value),
+ PyUnicode_GET_SIZE(value));
+ Py_DECREF(value);
+ } else
+ bstr = NULL;
+
+ /* free the previous contents, if any */
+ if (*(BSTR *)ptr)
+ SysFreeString(*(BSTR *)ptr);
+
+ /* and store it */
+ *(BSTR *)ptr = bstr;
+
+ /* We don't need to keep any other object */
+ _RET(value);
+}
+
+
+static PyObject *
+BSTR_get(void *ptr, unsigned size)
+{
+ BSTR p;
+ p = *(BSTR *)ptr;
+ if (p)
+ return PyUnicode_FromWideChar(p, SysStringLen(p));
+ else {
+ /* Hm, it seems NULL pointer and zero length string are the
+ same in BSTR, see Don Box, p 81
+ */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif
+
+static PyObject *
+P_set(void *ptr, PyObject *value, unsigned size)
+{
+ void *v;
+ if (value == Py_None) {
+ *(void **)ptr = NULL;
+ _RET(value);
+ }
+
+ if (!PyInt_Check(value) && !PyLong_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot be converted to pointer");
+ return NULL;
+ }
+
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+ v = (void *)PyInt_AsUnsignedLongMask(value);
+#else
+#ifndef HAVE_LONG_LONG
+# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
+# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+ v = (void *)PyInt_AsUnsignedLongLongMask(value);
+#endif
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ *(void **)ptr = v;
+ _RET(value);
+}
+
+static PyObject *
+P_get(void *ptr, unsigned size)
+{
+ if (*(void **)ptr == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyLong_FromVoidPtr(*(void **)ptr);
+}
+
+static struct fielddesc formattable[] = {
+ { 's', s_set, s_get, &ffi_type_pointer},
+ { 'b', b_set, b_get, &ffi_type_schar},
+ { 'B', B_set, B_get, &ffi_type_uchar},
+ { 'c', c_set, c_get, &ffi_type_schar},
+ { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
+ { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
+ { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
+ { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
+ { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
+ { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
+/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
+/* As soon as we can get rid of the type codes, this is no longer a problem */
+#if SIZEOF_LONG == 4
+ { 'l', l_set, l_get, &ffi_type_sint, l_set_sw, l_get_sw},
+ { 'L', L_set, L_get, &ffi_type_uint, L_set_sw, L_get_sw},
+#elif SIZEOF_LONG == 8
+ { 'l', l_set, l_get, &ffi_type_slong, l_set_sw, l_get_sw},
+ { 'L', L_set, L_get, &ffi_type_ulong, L_set_sw, L_get_sw},
+#else
+# error
+#endif
+#ifdef HAVE_LONG_LONG
+ { 'q', q_set, q_get, &ffi_type_slong, q_set_sw, q_get_sw},
+ { 'Q', Q_set, Q_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
+#endif
+ { 'P', P_set, P_get, &ffi_type_pointer},
+ { 'z', z_set, z_get, &ffi_type_pointer},
+#ifdef CTYPES_UNICODE
+ { 'u', u_set, u_get, NULL}, /* ffi_type set later */
+ { 'U', U_set, U_get, &ffi_type_pointer},
+ { 'Z', Z_set, Z_get, &ffi_type_pointer},
+#endif
+#ifdef MS_WIN32
+ { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
+ { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
+#endif
+ { 'O', O_set, O_get, &ffi_type_pointer},
+ { 0, NULL, NULL, NULL},
+};
+
+/*
+ Ideas: Implement VARIANT in this table, using 'V' code.
+ Use '?' as code for BOOL.
+*/
+
+struct fielddesc *
+getentry(char *fmt)
+{
+ static int initialized = 0;
+ struct fielddesc *table = formattable;
+
+ if (!initialized) {
+ initialized = 1;
+#ifdef CTYPES_UNICODE
+ if (sizeof(wchar_t) == sizeof(short))
+ getentry("u")->pffi_type = &ffi_type_sshort;
+ else if (sizeof(wchar_t) == sizeof(int))
+ getentry("u")->pffi_type = &ffi_type_sint;
+ else if (sizeof(wchar_t) == sizeof(long))
+ getentry("u")->pffi_type = &ffi_type_slong;
+#endif
+ }
+
+ for (; table->code; ++table) {
+ if (table->code == fmt[0])
+ return table;
+ }
+ return NULL;
+}
+
+typedef struct { char c; char x; } s_char;
+typedef struct { char c; short x; } s_short;
+typedef struct { char c; int x; } s_int;
+typedef struct { char c; long x; } s_long;
+typedef struct { char c; float x; } s_float;
+typedef struct { char c; double x; } s_double;
+typedef struct { char c; char *x; } s_char_p;
+typedef struct { char c; void *x; } s_void_p;
+
+/*
+#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
+#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
+#define INT_ALIGN (sizeof(s_int) - sizeof(int))
+#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
+*/
+#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
+#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
+/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
+#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
+
+/*
+#ifdef HAVE_USABLE_WCHAR_T
+typedef struct { char c; wchar_t x; } s_wchar;
+typedef struct { char c; wchar_t *x; } s_wchar_p;
+
+#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
+#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
+#endif
+*/
+
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } s_long_long;
+#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
+#endif
+
+/* from ffi.h:
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ struct _ffi_type **elements;
+} ffi_type;
+*/
+
+/* align and size are bogus for void, but they must not be zero */
+ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
+
+ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
+ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
+
+ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
+ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
+
+ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
+ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
+
+ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
+ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
+
+ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
+ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
+
+/* ffi_type ffi_type_longdouble */
+
+ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
+
+/*---------------- EOF ----------------*/
diff --git a/sys/src/cmd/python/Modules/_ctypes/ctypes.h b/sys/src/cmd/python/Modules/_ctypes/ctypes.h
new file mode 100644
index 000000000..0af785102
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/ctypes.h
@@ -0,0 +1,407 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+#ifndef MS_WIN32
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#define PARAMFLAG_FIN 0x1
+#define PARAMFLAG_FOUT 0x2
+#define PARAMFLAG_FLCID 0x4
+#endif
+
+/*
+ Backwards compatibility:
+ Python2.2 used LONG_LONG instead of PY_LONG_LONG
+*/
+#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
+#define PY_LONG_LONG LONG_LONG
+#endif
+
+typedef struct tagPyCArgObject PyCArgObject;
+typedef struct tagCDataObject CDataObject;
+typedef PyObject *(* GETFUNC)(void *, unsigned size);
+typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
+typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj);
+
+/* A default buffer in CDataObject, which can be used for small C types. If
+this buffer is too small, PyMem_Malloc will be called to create a larger one,
+and this one is not used.
+
+Making CDataObject a variable size object would be a better solution, but more
+difficult in the presence of CFuncPtrObject. Maybe later.
+*/
+union value {
+ char c[16];
+ short s;
+ int i;
+ long l;
+ float f;
+ double d;
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG ll;
+#endif
+};
+
+/*
+ Hm. Are there CDataObject's which do not need the b_objects member? In
+ this case we probably should introduce b_flags to mark it as present... If
+ b_objects is not present/unused b_length is unneeded as well.
+*/
+
+struct tagCDataObject {
+ PyObject_HEAD
+ char *b_ptr; /* pointer to memory block */
+ int b_needsfree; /* need _we_ free the memory? */
+ CDataObject *b_base; /* pointer to base object or NULL */
+ Py_ssize_t b_size; /* size of memory block in bytes */
+ Py_ssize_t b_length; /* number of references we need */
+ Py_ssize_t b_index; /* index of this object into base's
+ b_object list */
+ PyObject *b_objects; /* dictionary of references we need to keep, or Py_None */
+ union value b_value;
+};
+
+typedef struct {
+ ffi_closure *pcl; /* the C callable */
+ ffi_cif cif;
+ PyObject *converters;
+ PyObject *callable;
+ SETFUNC setfunc;
+ ffi_type *restype;
+ ffi_type *atypes[0];
+} ffi_info;
+
+typedef struct {
+ /* First part identical to tagCDataObject */
+ PyObject_HEAD
+ char *b_ptr; /* pointer to memory block */
+ int b_needsfree; /* need _we_ free the memory? */
+ CDataObject *b_base; /* pointer to base object or NULL */
+ Py_ssize_t b_size; /* size of memory block in bytes */
+ Py_ssize_t b_length; /* number of references we need */
+ Py_ssize_t b_index; /* index of this object into base's
+ b_object list */
+ PyObject *b_objects; /* list of references we need to keep */
+ union value b_value;
+ /* end of tagCDataObject, additional fields follow */
+
+ ffi_info *thunk;
+ PyObject *callable;
+
+ /* These two fields will override the ones in the type's stgdict if
+ they are set */
+ PyObject *converters;
+ PyObject *argtypes;
+ PyObject *restype;
+ PyObject *checker;
+ PyObject *errcheck;
+#ifdef MS_WIN32
+ int index;
+ GUID *iid;
+#endif
+ PyObject *paramflags;
+} CFuncPtrObject;
+
+extern PyTypeObject StgDict_Type;
+#define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type)
+#define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type)
+
+extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct);
+extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
+extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
+
+
+
+extern PyTypeObject CData_Type;
+#define CDataObject_CheckExact(v) ((v)->ob_type == &CData_Type)
+#define CDataObject_Check(v) PyObject_TypeCheck(v, &CData_Type)
+
+extern PyTypeObject SimpleType_Type;
+#define SimpleTypeObject_CheckExact(v) ((v)->ob_type == &SimpleType_Type)
+#define SimpleTypeObject_Check(v) PyObject_TypeCheck(v, &SimpleType_Type)
+
+extern PyTypeObject CField_Type;
+extern struct fielddesc *getentry(char *fmt);
+
+
+extern PyObject *
+CField_FromDesc(PyObject *desc, int index,
+ int *pfield_size, int bitsize, int *pbitofs,
+ int *psize, int *poffset, int *palign,
+ int pack, int is_big_endian);
+
+extern PyObject *CData_AtAddress(PyObject *type, void *buf);
+extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length);
+
+extern PyTypeObject ArrayType_Type;
+extern PyTypeObject Array_Type;
+extern PyTypeObject PointerType_Type;
+extern PyTypeObject Pointer_Type;
+extern PyTypeObject CFuncPtr_Type;
+extern PyTypeObject CFuncPtrType_Type;
+extern PyTypeObject StructType_Type;
+
+#define ArrayTypeObject_Check(v) PyObject_TypeCheck(v, &ArrayType_Type)
+#define ArrayObject_Check(v) PyObject_TypeCheck(v, &Array_Type)
+#define PointerObject_Check(v) PyObject_TypeCheck(v, &Pointer_Type)
+#define PointerTypeObject_Check(v) PyObject_TypeCheck(v, &PointerType_Type)
+#define CFuncPtrObject_Check(v) PyObject_TypeCheck(v, &CFuncPtr_Type)
+#define CFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &CFuncPtrType_Type)
+#define StructTypeObject_Check(v) PyObject_TypeCheck(v, &StructType_Type)
+
+extern PyObject *
+CreateArrayType(PyObject *itemtype, Py_ssize_t length);
+
+extern void init_callbacks_in_module(PyObject *m);
+
+extern PyMethodDef module_methods[];
+
+extern ffi_info *AllocFunctionCallback(PyObject *callable,
+ PyObject *converters,
+ PyObject *restype,
+ int stdcall);
+/* a table entry describing a predefined ctypes type */
+struct fielddesc {
+ char code;
+ SETFUNC setfunc;
+ GETFUNC getfunc;
+ ffi_type *pffi_type; /* always statically allocated */
+ SETFUNC setfunc_swapped;
+ GETFUNC getfunc_swapped;
+};
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t offset;
+ Py_ssize_t size;
+ Py_ssize_t index; /* Index into CDataObject's
+ object array */
+ PyObject *proto; /* a type or NULL */
+ GETFUNC getfunc; /* getter function if proto is NULL */
+ SETFUNC setfunc; /* setter function if proto is NULL */
+ int anonymous;
+} CFieldObject;
+
+/* A subclass of PyDictObject, used as the instance dictionary of ctypes
+ metatypes */
+typedef struct {
+ PyDictObject dict; /* first part identical to PyDictObject */
+/* The size and align fields are unneeded, they are in ffi_type as well. As
+ an experiment shows, it's trivial to get rid of them, the only thing to
+ remember is that in ArrayType_new the ffi_type fields must be filled in -
+ so far it was unneeded because libffi doesn't support arrays at all
+ (because they are passed as pointers to function calls anyway). But it's
+ too much risk to change that now, and there are other fields which doen't
+ belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?)
+*/
+ Py_ssize_t size; /* number of bytes */
+ Py_ssize_t align; /* alignment requirements */
+ Py_ssize_t length; /* number of fields */
+ ffi_type ffi_type_pointer;
+ PyObject *proto; /* Only for Pointer/ArrayObject */
+ SETFUNC setfunc; /* Only for simple objects */
+ GETFUNC getfunc; /* Only for simple objects */
+ PARAMFUNC paramfunc;
+
+ /* Following fields only used by CFuncPtrType_Type instances */
+ PyObject *argtypes; /* tuple of CDataObjects */
+ PyObject *converters; /* tuple([t.from_param for t in argtypes]) */
+ PyObject *restype; /* CDataObject or NULL */
+ PyObject *checker;
+ int flags; /* calling convention and such */
+} StgDictObject;
+
+/****************************************************************
+ StgDictObject fields
+
+ setfunc and getfunc is only set for simple data types, it is copied from the
+ corresponding fielddesc entry. These are functions to set and get the value
+ in a memory block.
+ They should probably by used by other types as well.
+
+ proto is only used for Pointer and Array types - it points to the item type
+ object.
+
+ Probably all the magic ctypes methods (like from_param) should have C
+ callable wrappers in the StgDictObject. For simple data type, for example,
+ the fielddesc table could have entries for C codec from_param functions or
+ other methods as well, if a subtype overrides this method in Python at
+ construction time, or assigns to it later, tp_setattro should update the
+ StgDictObject function to a generic one.
+
+ Currently, CFuncPtr types have 'converters' and 'checker' entries in their
+ type dict. They are only used to cache attributes from other entries, whihc
+ is wrong.
+
+ One use case is the .value attribute that all simple types have. But some
+ complex structures, like VARIANT, represent a single value also, and should
+ have this attribute.
+
+ Another use case is a _check_retval_ function, which is called when a ctypes
+ type is used as return type of a function to validate and compute the return
+ value.
+
+ Common ctypes protocol:
+
+ - setfunc: store a python value in a memory block
+ - getfunc: convert data from a memory block into a python value
+
+ - checkfunc: validate and convert a return value from a function call
+ - toparamfunc: convert a python value into a function argument
+
+*****************************************************************/
+
+/* May return NULL, but does not set an exception! */
+extern StgDictObject *PyType_stgdict(PyObject *obj);
+
+/* May return NULL, but does not set an exception! */
+extern StgDictObject *PyObject_stgdict(PyObject *self);
+
+extern int StgDict_clone(StgDictObject *src, StgDictObject *dst);
+
+typedef int(* PPROC)(void);
+
+PyObject *_CallProc(PPROC pProc,
+ PyObject *arguments,
+#ifdef MS_WIN32
+ IUnknown *pIUnk,
+ GUID *iid,
+#endif
+ int flags,
+ PyObject *argtypes,
+ PyObject *restype,
+ PyObject *checker);
+
+
+#define FUNCFLAG_STDCALL 0x0
+#define FUNCFLAG_CDECL 0x1
+#define FUNCFLAG_HRESULT 0x2
+#define FUNCFLAG_PYTHONAPI 0x4
+
+#define DICTFLAG_FINAL 0x1000
+
+struct tagPyCArgObject {
+ PyObject_HEAD
+ ffi_type *pffi_type;
+ char tag;
+ union {
+ char c;
+ char b;
+ short h;
+ int i;
+ long l;
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG q;
+#endif
+ double d;
+ float f;
+ void *p;
+ } value;
+ PyObject *obj;
+ int size; /* for the 'V' tag */
+};
+
+extern PyTypeObject PyCArg_Type;
+extern PyCArgObject *new_CArgObject(void);
+#define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type)
+extern PyCArgObject *new_CArgObject(void);
+
+extern PyObject *
+CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
+ Py_ssize_t index, Py_ssize_t size, char *ptr);
+
+extern int
+CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
+ Py_ssize_t index, Py_ssize_t size, char *ptr);
+
+extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...);
+
+struct basespec {
+ CDataObject *base;
+ Py_ssize_t index;
+ char *adr;
+};
+
+extern char basespec_string[];
+
+extern ffi_type *GetType(PyObject *obj);
+
+/* exception classes */
+extern PyObject *PyExc_ArgError;
+
+extern char *conversion_mode_encoding;
+extern char *conversion_mode_errors;
+
+/* Python 2.4 macros, which are not available in Python 2.3 */
+
+#ifndef Py_CLEAR
+#define Py_CLEAR(op) \
+ do { \
+ if (op) { \
+ PyObject *tmp = (PyObject *)(op); \
+ (op) = NULL; \
+ Py_DECREF(tmp); \
+ } \
+ } while (0)
+#endif
+
+#ifndef Py_VISIT
+/* Utility macro to help write tp_traverse functions.
+ * To use this macro, the tp_traverse function must name its arguments
+ * "visit" and "arg". This is intended to keep tp_traverse functions
+ * looking as much alike as possible.
+ */
+#define Py_VISIT(op) \
+ do { \
+ if (op) { \
+ int vret = visit((op), arg); \
+ if (vret) \
+ return vret; \
+ } \
+ } while (0)
+#endif
+
+/* Python's PyUnicode_*WideChar functions are broken ... */
+#if defined(Py_USING_UNICODE) && defined(HAVE_WCHAR_H)
+# define CTYPES_UNICODE
+#endif
+
+
+#ifdef CTYPES_UNICODE
+# undef PyUnicode_FromWideChar
+# define PyUnicode_FromWideChar My_PyUnicode_FromWideChar
+
+# undef PyUnicode_AsWideChar
+# define PyUnicode_AsWideChar My_PyUnicode_AsWideChar
+
+extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, Py_ssize_t);
+extern int My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, Py_ssize_t);
+
+#endif
+
+extern void FreeClosure(void *);
+extern void *MallocClosure(void);
+
+extern void _AddTraceback(char *, char *, int);
+
+extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
+
+/* XXX better name needed! */
+extern int IsSimpleSubType(PyObject *obj);
+
+
+#ifdef MS_WIN32
+extern PyObject *ComError;
+#endif
+
+/*
+ Local Variables:
+ compile-command: "python setup.py -q build install --home ~"
+ End:
+*/
diff --git a/sys/src/cmd/python/Modules/_ctypes/ctypes_dlfcn.h b/sys/src/cmd/python/Modules/_ctypes/ctypes_dlfcn.h
new file mode 100644
index 000000000..d8bf904be
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/ctypes_dlfcn.h
@@ -0,0 +1,31 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#ifndef _CTYPES_DLFCN_H_
+#define _CTYPES_DLFCN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef MS_WIN32
+
+#include <dlfcn.h>
+
+#ifndef CTYPES_DARWIN_DLFCN
+
+#define ctypes_dlsym dlsym
+#define ctypes_dlerror dlerror
+#define ctypes_dlopen dlopen
+#define ctypes_dlclose dlclose
+#define ctypes_dladdr dladdr
+
+#endif /* !CTYPES_DARWIN_DLFCN */
+
+#endif /* !MS_WIN32 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _CTYPES_DLFCN_H_ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/darwin/LICENSE b/sys/src/cmd/python/Modules/_ctypes/darwin/LICENSE
new file mode 100644
index 000000000..786fb5025
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/darwin/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
+ Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Portions may be copyright others, see the AUTHORS file included with this
+distribution.
+
+Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
+
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/darwin/README b/sys/src/cmd/python/Modules/_ctypes/darwin/README
new file mode 100644
index 000000000..4d63f3dfa
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/darwin/README
@@ -0,0 +1,95 @@
+dlcompat for Darwin
+=========================
+
+This is dlcompat, a small library that emulates the dlopen()
+interface on top of Darwin's dyld API.
+
+dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL
+flag isn't passed to dlopen()). It can be configured to yield a warning
+when trying to close it (dynamic libraries cannot currently be unloaded).
+
+It automatically searches for modules in several directories when no
+absolute path is specified and the module is not found in the current
+directory.
+
+The paths searched are those specified in the environment variables
+LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and
+/usr/lib or the path specified in the environment variable
+DYLD_FALLBACK_LIBRARY_PATH.
+
+In the default install the behavior of dlsym is to automatically prepend
+an underscore to passed in symbol names, this allows easier porting of
+applications which were written specifically for ELF based lifeforms.
+
+Installation
+--------------
+Type:
+ ./configure
+ make
+ sudo make install
+
+This will compile the source file, generate both a static and shared
+library called libdl and install it into /usr/local/lib. The header
+file dlfcn.h will be installed in /usr/local/include.
+
+If you want to place the files somewhere else, run
+
+ make clean
+ ./configure --prefix=<prefix>
+ make
+ sudo make install
+
+where <prefix> is the hierarchy you want to install into, e.g. /usr
+for /usr/lib and /usr/include (_NOT_ recommended!).
+
+To enable debugging output (useful for me), run
+
+ make clean
+ ./configure --enable-debug
+ make
+ sudo make install
+
+If you want old dlcompat style behavior of not prepending the underscore
+on calls to dlsym then type:
+
+ make clean
+ ./configure --enable-fink
+ make
+ sudo make install
+
+Usage
+-------
+Software that uses GNU autoconf will likely check for a library called
+libdl, that's why I named it that way. For software that doesn't find
+the library on its own, you must add a '-ldl' to the appropriate
+Makefile (or environment) variable, usually LIBS.
+
+If you installed dlcompat into a directory other than /usr/local/lib,
+you must tell the compiler where to find it. Add '-L<prefix>/lib' to
+LDFLAGS (or CFLAGS) and '-I<prefix>/include' to CPPFLAGS (or CFLAGS).
+
+Notes
+-----
+If you are writing new software and plan to have Mac OX X compatibility you
+should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than
+using dlcompat, using the native api's is the supported method of loading
+dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c,
+which should help get you started.
+
+Also note that the functions in dlcompat are not thread safe, and while it is not
+POSIX spec compliant, it is about as close to compliance as it is going to get though.
+
+You can always get the latest version from opendarwin cvs:
+
+ cvs -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od login
+ cvs -z3 -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od \
+ co -d dlcompat proj/dlcompat
+
+
+It is hoped that this library will be useful, and as bug free as possible, if you find
+any bugs please let us know about them so they can be fixed.
+
+Please send bug reports to Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Thanks.
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes b/sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes
new file mode 100644
index 000000000..8520b01f4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes
@@ -0,0 +1,11 @@
+The files in this directory are taken from
+http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/
+
+The LICENSE in this directory applies to these files.
+
+Thomas Heller, Jan 2003
+
+These files have been modified so they fall back to the system
+dlfcn calls if available in libSystem.
+
+Bob Ippolito, Feb 2006
diff --git a/sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h b/sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h
new file mode 100644
index 000000000..a2afc3eeb
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h
@@ -0,0 +1,84 @@
+/*
+Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
+ Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Portions may be copyright others, see the AUTHORS file included with this
+distribution.
+
+Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef _DLFCN_H_
+#define _DLFCN_H_
+
+#include <AvailabilityMacros.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Structure filled in by dladdr().
+ */
+
+typedef struct dl_info {
+ const char *dli_fname; /* Pathname of shared object */
+ void *dli_fbase; /* Base address of shared object */
+ const char *dli_sname; /* Name of nearest symbol */
+ void *dli_saddr; /* Address of nearest symbol */
+} Dl_info;
+
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2
+#warning CTYPES_DARWIN_DLFCN
+#define CTYPES_DARWIN_DLFCN
+extern void * (*ctypes_dlopen)(const char *path, int mode);
+extern void * (*ctypes_dlsym)(void * handle, const char *symbol);
+extern const char * (*ctypes_dlerror)(void);
+extern int (*ctypes_dlclose)(void * handle);
+extern int (*ctypes_dladdr)(const void *, Dl_info *);
+#else
+extern void * dlopen(const char *path, int mode);
+extern void * dlsym(void * handle, const char *symbol);
+extern const char * dlerror(void);
+extern int dlclose(void * handle);
+extern int dladdr(const void *, Dl_info *);
+#endif
+
+#define RTLD_LAZY 0x1
+#define RTLD_NOW 0x2
+#define RTLD_LOCAL 0x4
+#define RTLD_GLOBAL 0x8
+#define RTLD_NOLOAD 0x10
+#define RTLD_NODELETE 0x80
+
+/* These are from the Mac OS X 10.4 headers */
+#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
+#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DLFCN_H_ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn_simple.c b/sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn_simple.c
new file mode 100644
index 000000000..4b5532314
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn_simple.c
@@ -0,0 +1,272 @@
+/*
+Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+/* Just to prove that it isn't that hard to add Mac calls to your code :)
+ This works with pretty much everything, including kde3 xemacs and the gimp,
+ I'd guess that it'd work in at least 95% of cases, use this as your starting
+ point, rather than the mess that is dlfcn.c, assuming that your code does not
+ require ref counting or symbol lookups in dependent libraries
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <mach-o/dyld.h>
+#include <AvailabilityMacros.h>
+#include "dlfcn.h"
+
+#ifdef CTYPES_DARWIN_DLFCN
+
+#define ERR_STR_LEN 256
+
+#ifndef MAC_OS_X_VERSION_10_3
+#define MAC_OS_X_VERSION_10_3 1030
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
+#define DARWIN_HAS_DLOPEN
+extern void * dlopen(const char *path, int mode) __attribute__((weak_import));
+extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import));
+extern const char * dlerror(void) __attribute__((weak_import));
+extern int dlclose(void * handle) __attribute__((weak_import));
+extern int dladdr(const void *, Dl_info *) __attribute__((weak_import));
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */
+
+#ifndef DARWIN_HAS_DLOPEN
+#define dlopen darwin_dlopen
+#define dlsym darwin_dlsym
+#define dlerror darwin_dlerror
+#define dlclose darwin_dlclose
+#define dladdr darwin_dladdr
+#endif
+
+void * (*ctypes_dlopen)(const char *path, int mode);
+void * (*ctypes_dlsym)(void * handle, const char *symbol);
+const char * (*ctypes_dlerror)(void);
+int (*ctypes_dlclose)(void * handle);
+int (*ctypes_dladdr)(const void *, Dl_info *);
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
+/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */
+
+static void *dlsymIntern(void *handle, const char *symbol);
+
+static const char *error(int setget, const char *str, ...);
+
+/* Set and get the error string for use by dlerror */
+static const char *error(int setget, const char *str, ...)
+{
+ static char errstr[ERR_STR_LEN];
+ static int err_filled = 0;
+ const char *retval;
+ va_list arg;
+ if (setget == 0)
+ {
+ va_start(arg, str);
+ strncpy(errstr, "dlcompat: ", ERR_STR_LEN);
+ vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
+ va_end(arg);
+ err_filled = 1;
+ retval = NULL;
+ }
+ else
+ {
+ if (!err_filled)
+ retval = NULL;
+ else
+ retval = errstr;
+ err_filled = 0;
+ }
+ return retval;
+}
+
+/* darwin_dlopen */
+static void *darwin_dlopen(const char *path, int mode)
+{
+ void *module = 0;
+ NSObjectFileImage ofi = 0;
+ NSObjectFileImageReturnCode ofirc;
+
+ /* If we got no path, the app wants the global namespace, use -1 as the marker
+ in this case */
+ if (!path)
+ return (void *)-1;
+
+ /* Create the object file image, works for things linked with the -bundle arg to ld */
+ ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
+ switch (ofirc)
+ {
+ case NSObjectFileImageSuccess:
+ /* It was okay, so use NSLinkModule to link in the image */
+ module = NSLinkModule(ofi, path,
+ NSLINKMODULE_OPTION_RETURN_ON_ERROR
+ | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE
+ | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
+ NSDestroyObjectFileImage(ofi);
+ break;
+ case NSObjectFileImageInappropriateFile:
+ /* It may have been a dynamic library rather than a bundle, try to load it */
+ module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+ break;
+ default:
+ /* God knows what we got */
+ error(0, "Can not open \"%s\"", path);
+ return 0;
+ }
+ if (!module)
+ error(0, "Can not open \"%s\"", path);
+ return module;
+
+}
+
+/* dlsymIntern is used by dlsym to find the symbol */
+static void *dlsymIntern(void *handle, const char *symbol)
+{
+ NSSymbol nssym = 0;
+ /* If the handle is -1, if is the app global context */
+ if (handle == (void *)-1)
+ {
+ /* Global context, use NSLookupAndBindSymbol */
+ if (NSIsSymbolNameDefined(symbol))
+ {
+ nssym = NSLookupAndBindSymbol(symbol);
+ }
+
+ }
+ /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image
+ for libraries, and NSLookupSymbolInModule for bundles */
+ else
+ {
+ /* Check for both possible magic numbers depending on x86/ppc byte order */
+ if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
+ (((struct mach_header *)handle)->magic == MH_CIGAM))
+ {
+ if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol))
+ {
+ nssym = NSLookupSymbolInImage((struct mach_header *)handle,
+ symbol,
+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
+ | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
+ }
+
+ }
+ else
+ {
+ nssym = NSLookupSymbolInModule(handle, symbol);
+ }
+ }
+ if (!nssym)
+ {
+ error(0, "Symbol \"%s\" Not found", symbol);
+ return NULL;
+ }
+ return NSAddressOfSymbol(nssym);
+}
+
+static const char *darwin_dlerror(void)
+{
+ return error(1, (char *)NULL);
+}
+
+static int darwin_dlclose(void *handle)
+{
+ if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
+ (((struct mach_header *)handle)->magic == MH_CIGAM))
+ {
+ error(0, "Can't remove dynamic libraries on darwin");
+ return 0;
+ }
+ if (!NSUnLinkModule(handle, 0))
+ {
+ error(0, "unable to unlink module %s", NSNameOfModule(handle));
+ return 1;
+ }
+ return 0;
+}
+
+
+/* dlsym, prepend the underscore and call dlsymIntern */
+static void *darwin_dlsym(void *handle, const char *symbol)
+{
+ static char undersym[257]; /* Saves calls to malloc(3) */
+ int sym_len = strlen(symbol);
+ void *value = NULL;
+ char *malloc_sym = NULL;
+
+ if (sym_len < 256)
+ {
+ snprintf(undersym, 256, "_%s", symbol);
+ value = dlsymIntern(handle, undersym);
+ }
+ else
+ {
+ malloc_sym = malloc(sym_len + 2);
+ if (malloc_sym)
+ {
+ sprintf(malloc_sym, "_%s", symbol);
+ value = dlsymIntern(handle, malloc_sym);
+ free(malloc_sym);
+ }
+ else
+ {
+ error(0, "Unable to allocate memory");
+ }
+ }
+ return value;
+}
+
+static int darwin_dladdr(const void *handle, Dl_info *info) {
+ return 0;
+}
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
+
+#if __GNUC__ < 4
+#pragma CALL_ON_LOAD ctypes_dlfcn_init
+#else
+static void __attribute__ ((constructor)) ctypes_dlfcn_init(void);
+static
+#endif
+void ctypes_dlfcn_init(void) {
+ if (dlopen != NULL) {
+ ctypes_dlsym = dlsym;
+ ctypes_dlopen = dlopen;
+ ctypes_dlerror = dlerror;
+ ctypes_dlclose = dlclose;
+ ctypes_dladdr = dladdr;
+ } else {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
+ ctypes_dlsym = darwin_dlsym;
+ ctypes_dlopen = darwin_dlopen;
+ ctypes_dlerror = darwin_dlerror;
+ ctypes_dlclose = darwin_dlclose;
+ ctypes_dladdr = darwin_dladdr;
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
+ }
+}
+
+#endif /* CTYPES_DARWIN_DLFCN */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/LICENSE b/sys/src/cmd/python/Modules/_ctypes/libffi/LICENSE
new file mode 100644
index 000000000..f59179515
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/LICENSE
@@ -0,0 +1,20 @@
+libffi - Copyright (c) 1996-2003 Red Hat, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/README b/sys/src/cmd/python/Modules/_ctypes/libffi/README
new file mode 100644
index 000000000..1fc27470d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/README
@@ -0,0 +1,500 @@
+This directory contains the libffi package, which is not part of GCC but
+shipped with GCC as convenience.
+
+Status
+======
+
+libffi-2.00 has not been released yet! This is a development snapshot!
+
+libffi-1.20 was released on October 5, 1998. Check the libffi web
+page for updates: <URL:http://sources.redhat.com/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.
+
+Ffi stands for Foreign Function Interface. A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms and Prerequisites
+=====================================
+
+Libffi has been ported to:
+
+ SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
+
+ Irix 5.3 & 6.2 (System V/o32 & n32)
+
+ Intel x86 - Linux (System V ABI)
+
+ Alpha - Linux and OSF/1
+
+ m68k - Linux (System V ABI)
+
+ PowerPC - Linux (System V ABI, Darwin, AIX)
+
+ ARM - Linux (System V ABI)
+
+Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
+that other versions will work. Libffi has also been built and tested
+with the SGI compiler tools.
+
+On PowerPC, the tests failed (see the note below).
+
+You must use GNU make to build libffi. SGI's make will not work.
+Sun's probably won't either.
+
+If you port libffi to another platform, please let me know! I assume
+that some will be easy (x86 NetBSD), and others will be more difficult
+(HP).
+
+
+Installing libffi
+=================
+
+[Note: before actually performing any of these installation steps,
+ you may wish to read the "Platform Specific Notes" below.]
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the --prefix configure switch. Libffi
+will install under /usr/local by default.
+
+If you want to enable extra run-time debugging checks use the the
+--enable-debug configure switch. This is useful when your program dies
+mysteriously while using libffi.
+
+Another useful configure switch is --enable-purify-safety. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using
+Purify, as it will slow down the library.
+
+Configure has many other options. Use "configure --help" to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make. SGI's make will not work. Sun's probably won't either.
+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+
+To ensure that libffi is working as advertised, type "make test".
+
+To install the library and header files, type "make install".
+
+
+Using libffi
+============
+
+ The Basics
+ ----------
+
+Libffi assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it,
+as well as the return type of the function.
+
+The first thing you must do is create an ffi_cif object that matches
+the signature of the function you wish to call. The cif in ffi_cif
+stands for Call InterFace. To prepare a call interface object, use the
+following function:
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+ unsigned int nargs,
+ ffi_type *rtype, ffi_type **atypes);
+
+ CIF is a pointer to the call interface object you wish
+ to initialize.
+
+ ABI is an enum that specifies the calling convention
+ to use for the call. FFI_DEFAULT_ABI defaults
+ to the system's native calling convention. Other
+ ABI's may be used with care. They are system
+ specific.
+
+ NARGS is the number of arguments this function accepts.
+ libffi does not yet support vararg functions.
+
+ RTYPE is a pointer to an ffi_type structure that represents
+ the return type of the function. Ffi_type objects
+ describe the types of values. libffi provides
+ ffi_type objects for many of the native C types:
+ signed int, unsigned int, signed char, unsigned char,
+ etc. There is also a pointer ffi_type object and
+ a void ffi_type. Use &ffi_type_void for functions that
+ don't return values.
+
+ ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
+ If NARGS is 0, this is ignored.
+
+
+ffi_prep_cif will return a status code that you are responsible
+for checking. It will be one of the following:
+
+ FFI_OK - All is good.
+
+ FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
+ came across is bad.
+
+
+Before making the call, the VALUES vector should be initialized
+with pointers to the appropriate argument values.
+
+To call the the function using the initialized ffi_cif, use the
+ffi_call function:
+
+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+
+ CIF is a pointer to the ffi_cif initialized specifically
+ for this function.
+
+ FN is a pointer to the function you want to call.
+
+ RVALUE is a pointer to a chunk of memory that is to hold the
+ result of the function call. Currently, it must be
+ at least one word in size (except for the n32 version
+ under Irix 6.x, which must be a pointer to an 8 byte
+ aligned value (a long long). It must also be at least
+ word aligned (depending on the return type, and the
+ system's alignment requirements). If RTYPE is
+ &ffi_type_void, this is ignored. If RVALUE is NULL,
+ the return value is discarded.
+
+ AVALUES is a vector of void* that point to the memory locations
+ holding the argument values for a call.
+ If NARGS is 0, this is ignored.
+
+
+If you are expecting a return value from FN it will have been stored
+at RVALUE.
+
+
+
+ An Example
+ ----------
+
+Here is a trivial example that calls puts() a few times.
+
+ #include <stdio.h>
+ #include <ffi.h>
+
+ int main()
+ {
+ ffi_cif cif;
+ ffi_type *args[1];
+ void *values[1];
+ char *s;
+ int rc;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_uint;
+ values[0] = &s;
+
+ /* Initialize the cif */
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, args) == FFI_OK)
+ {
+ s = "Hello World!";
+ ffi_call(&cif, puts, &rc, values);
+ /* rc now holds the result of the call to puts */
+
+ /* values holds a pointer to the function's arg, so to
+ call puts() again all we need to do is change the
+ value of s */
+ s = "This is cool!";
+ ffi_call(&cif, puts, &rc, values);
+ }
+
+ return 0;
+ }
+
+
+
+ Aggregate Types
+ ---------------
+
+Although libffi has no special support for unions or bit-fields, it is
+perfectly happy passing structures back and forth. You must first
+describe the structure to libffi by creating a new ffi_type object
+for it. Here is the definition of ffi_type:
+
+ typedef struct _ffi_type
+ {
+ unsigned size;
+ short alignment;
+ short type;
+ struct _ffi_type **elements;
+ } ffi_type;
+
+All structures must have type set to FFI_TYPE_STRUCT. You may set
+size and alignment to 0. These will be calculated and reset to the
+appropriate values by ffi_prep_cif().
+
+elements is a NULL terminated array of pointers to ffi_type objects
+that describe the type of the structure elements. These may, in turn,
+be structure elements.
+
+The following example initializes a ffi_type object representing the
+tm struct from Linux's time.h:
+
+ struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ /* Those are for future use. */
+ long int __tm_gmtoff__;
+ __const char *__tm_zone__;
+ };
+
+ {
+ ffi_type tm_type;
+ ffi_type *tm_type_elements[12];
+ int i;
+
+ tm_type.size = tm_type.alignment = 0;
+ tm_type.elements = &tm_type_elements;
+
+ for (i = 0; i < 9; i++)
+ tm_type_elements[i] = &ffi_type_sint;
+
+ tm_type_elements[9] = &ffi_type_slong;
+ tm_type_elements[10] = &ffi_type_pointer;
+ tm_type_elements[11] = NULL;
+
+ /* tm_type can now be used to represent tm argument types and
+ return types for ffi_prep_cif() */
+ }
+
+
+
+Platform Specific Notes
+=======================
+
+ Intel x86
+ ---------
+
+There are no known problems with the x86 port.
+
+ Sun SPARC - SunOS 4.1.3 & Solaris 2.x
+ -------------------------------------
+
+You must use GNU Make to build libffi on Sun platforms.
+
+ MIPS - Irix 5.3 & 6.x
+ ---------------------
+
+Irix 6.2 and better supports three different calling conventions: o32,
+n32 and n64. Currently, libffi only supports both o32 and n32 under
+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
+configured for whichever calling convention it was built for.
+
+By default, the configure script will try to build libffi with the GNU
+development tools. To build libffi with the SGI development tools, set
+the environment variable CC to either "cc -32" or "cc -n32" before
+running configure under Irix 6.x (depending on whether you want an o32
+or n32 library), or just "cc" for Irix 5.3.
+
+With the n32 calling convention, when returning structures smaller
+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
+Here's one way of forcing this:
+
+ double struct_storage[2];
+ my_small_struct *s = (my_small_struct *) struct_storage;
+ /* Use s for RVALUE */
+
+If you don't do this you are liable to get spurious bus errors.
+
+"long long" values are not supported yet.
+
+You must use GNU Make to build libffi on SGI platforms.
+
+ ARM - System V ABI
+ ------------------
+
+The ARM port was performed on a NetWinder running ARM Linux ELF
+(2.0.31) and gcc 2.8.1.
+
+
+
+ PowerPC System V ABI
+ --------------------
+
+There are two `System V ABI's which libffi implements for PowerPC.
+They differ only in how small structures are returned from functions.
+
+In the FFI_SYSV version, structures that are 8 bytes or smaller are
+returned in registers. This is what GCC does when it is configured
+for solaris, and is what the System V ABI I have (dated September
+1995) says.
+
+In the FFI_GCC_SYSV version, all structures are returned the same way:
+by passing a pointer as the first argument to the function. This is
+what GCC does when it is configured for linux or a generic sysv
+target.
+
+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
+inconsistency with the SysV ABI: When a procedure is called with many
+floating-point arguments, some of them get put on the stack. They are
+all supposed to be stored in double-precision format, even if they are
+only single-precision, but EGCS stores single-precision arguments as
+single-precision anyway. This causes one test to fail (the `many
+arguments' test).
+
+
+What's With The Crazy Comments?
+===============================
+
+You might notice a number of cryptic comments in the code, delimited
+by /*@ and @*/. These are annotations read by the program LCLint, a
+tool for statically checking C programs. You can read all about it at
+<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
+
+
+History
+=======
+
+1.20 Oct-5-98
+ Raffaele Sena produces ARM port.
+
+1.19 Oct-5-98
+ Fixed x86 long double and long long return support.
+ m68k bug fixes from Andreas Schwab.
+ Patch for DU assembler compatibility for the Alpha from Richard
+ Henderson.
+
+1.18 Apr-17-98
+ Bug fixes and MIPS configuration changes.
+
+1.17 Feb-24-98
+ Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+ Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+
+1.16 Feb-11-98
+ Richard Henderson produces Alpha port.
+
+1.15 Dec-4-97
+ Fixed an n32 ABI bug. New libtool, auto* support.
+
+1.14 May-13-97
+ libtool is now used to generate shared and static libraries.
+ Fixed a minor portability problem reported by Russ McManus
+ <mcmanr@eq.gs.com>.
+
+1.13 Dec-2-96
+ Added --enable-purify-safety to keep Purify from complaining
+ about certain low level code.
+ Sparc fix for calling functions with < 6 args.
+ Linux x86 a.out fix.
+
+1.12 Nov-22-96
+ Added missing ffi_type_void, needed for supporting void return
+ types. Fixed test case for non MIPS machines. Cygnus Support
+ is now Cygnus Solutions.
+
+1.11 Oct-30-96
+ Added notes about GNU make.
+
+1.10 Oct-29-96
+ Added configuration fix for non GNU compilers.
+
+1.09 Oct-29-96
+ Added --enable-debug configure switch. Clean-ups based on LCLint
+ feedback. ffi_mips.h is always installed. Many configuration
+ fixes. Fixed ffitest.c for sparc builds.
+
+1.08 Oct-15-96
+ Fixed n32 problem. Many clean-ups.
+
+1.07 Oct-14-96
+ Gordon Irlam rewrites v8.S again. Bug fixes.
+
+1.06 Oct-14-96
+ Gordon Irlam improved the sparc port.
+
+1.05 Oct-14-96
+ Interface changes based on feedback.
+
+1.04 Oct-11-96
+ Sparc port complete (modulo struct passing bug).
+
+1.03 Oct-10-96
+ Passing struct args, and returning struct values works for
+ all architectures/calling conventions. Expanded tests.
+
+1.02 Oct-9-96
+ Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+ Added "make test".
+
+1.01 Oct-8-96
+ Fixed float passing bug in mips version. Restructured some
+ of the code. Builds cleanly with SGI tools.
+
+1.00 Oct-7-96
+ First release. No public announcement.
+
+
+Authors & Credits
+=================
+
+libffi was written by Anthony Green <green@cygnus.com>.
+
+Portions of libffi were derived from Gianni Mariani's free gencall
+library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented by Kresten Krab
+Thorup.
+
+The Sparc port was derived from code contributed by the fine folks at
+Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
+made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
+
+The Alpha port was written by Richard Henderson at Cygnus Solutions.
+
+Andreas Schwab ported libffi to m68k Linux and provided a number of
+bug fixes.
+
+Geoffrey Keating ported libffi to the PowerPC.
+
+Raffaele Sena ported libffi to the ARM.
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes and configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+If you have a problem, or have found a bug, please send a note to
+green@cygnus.com.
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/aclocal.m4 b/sys/src/cmd/python/Modules/_ctypes/libffi/aclocal.m4
new file mode 100644
index 000000000..3e8f8ba57
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/aclocal.m4
@@ -0,0 +1,92 @@
+# mmap(2) blacklisting. Some platforms provide the mmap library routine
+# but don't support all of the features we need from it.
+AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
+[
+AC_CHECK_HEADER([sys/mman.h],
+ [libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
+AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
+if test "$libffi_header_sys_mman_h" != yes \
+ || test "$libffi_func_mmap" != yes; then
+ ac_cv_func_mmap_file=no
+ ac_cv_func_mmap_dev_zero=no
+ ac_cv_func_mmap_anon=no
+else
+ AC_CACHE_CHECK([whether read-only mmap of a plain file works],
+ ac_cv_func_mmap_file,
+ [# Add a system to this blacklist if
+ # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
+ # memory area containing the same data that you'd get if you applied
+ # read() to the same fd. The only system known to have a problem here
+ # is VMS, where text files have record structure.
+ case "$host_os" in
+ vms* | ultrix*)
+ ac_cv_func_mmap_file=no ;;
+ *)
+ ac_cv_func_mmap_file=yes;;
+ esac])
+ AC_CACHE_CHECK([whether mmap from /dev/zero works],
+ ac_cv_func_mmap_dev_zero,
+ [# Add a system to this blacklist if it has mmap() but /dev/zero
+ # does not exist, or if mmapping /dev/zero does not give anonymous
+ # zeroed pages with both the following properties:
+ # 1. If you map N consecutive pages in with one call, and then
+ # unmap any subset of those pages, the pages that were not
+ # explicitly unmapped remain accessible.
+ # 2. If you map two adjacent blocks of memory and then unmap them
+ # both at once, they must both go away.
+ # Systems known to be in this category are Windows (all variants),
+ # VMS, and Darwin.
+ case "$host_os" in
+ vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+ ac_cv_func_mmap_dev_zero=no ;;
+ *)
+ ac_cv_func_mmap_dev_zero=yes;;
+ esac])
+
+ # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
+ AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
+ [AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+],
+[int n = MAP_ANONYMOUS;],
+ ac_cv_decl_map_anon=yes,
+ ac_cv_decl_map_anon=no)])
+
+ if test $ac_cv_decl_map_anon = no; then
+ ac_cv_func_mmap_anon=no
+ else
+ AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
+ ac_cv_func_mmap_anon,
+ [# Add a system to this blacklist if it has mmap() and MAP_ANON or
+ # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+ # doesn't give anonymous zeroed pages with the same properties listed
+ # above for use of /dev/zero.
+ # Systems known to be in this category are Windows, VMS, and SCO Unix.
+ case "$host_os" in
+ vms* | cygwin* | pe | mingw* | sco* | udk* )
+ ac_cv_func_mmap_anon=no ;;
+ *)
+ ac_cv_func_mmap_anon=yes;;
+ esac])
+ fi
+fi
+
+if test $ac_cv_func_mmap_file = yes; then
+ AC_DEFINE(HAVE_MMAP_FILE, 1,
+ [Define if read-only mmap of a plain file works.])
+fi
+if test $ac_cv_func_mmap_dev_zero = yes; then
+ AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
+ [Define if mmap of /dev/zero works.])
+fi
+if test $ac_cv_func_mmap_anon = yes; then
+ AC_DEFINE(HAVE_MMAP_ANON, 1,
+ [Define if mmap with MAP_ANON(YMOUS) works.])
+fi
+])
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/config.guess b/sys/src/cmd/python/Modules/_ctypes/libffi/config.guess
new file mode 100755
index 000000000..822947132
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/config.guess
@@ -0,0 +1,1453 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-11-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ amd64:OpenBSD:*:*)
+ echo x86_64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ cats:OpenBSD:*:*)
+ echo arm-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ luna88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit 0 ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit 0 ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7 && exit 0 ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && exit 0
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ # avoid double evaluation of $set_cc_for_build
+ test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+ exit 0 ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit 0 ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit 0 ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit 0 ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit 0 ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ *86) UNAME_PROCESSOR=i686 ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit 0 ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms && exit 0 ;;
+ I*) echo ia64-dec-vms && exit 0 ;;
+ V*) echo vax-dec-vms && exit 0 ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/config.sub b/sys/src/cmd/python/Modules/_ctypes/libffi/config.sub
new file mode 100644
index 000000000..04aeffed5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/config.sub
@@ -0,0 +1,1569 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-04-22'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | msp430 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | msp430-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -plan9* | -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/configure b/sys/src/cmd/python/Modules/_ctypes/libffi/configure
new file mode 100755
index 000000000..9808384ce
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/configure
@@ -0,0 +1,6864 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for libffi 2.1.
+#
+# Report bugs to <http://gcc.gnu.org/bugs.html>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='libffi'
+PACKAGE_TARNAME='libffi'
+PACKAGE_VERSION='2.1'
+PACKAGE_STRING='libffi 2.1'
+PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html'
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC ac_ct_CC EXEEXT OBJEXT CFLAGS CPP CPPFLAGS EGREP ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR MKTARGET LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures libffi 2.1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of libffi 2.1:";;
+ esac
+ cat <<\_ACEOF
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://gcc.gnu.org/bugs.html>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd "$ac_popdir"
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+libffi configure 2.1
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by libffi $as_me 2.1, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_headers="$ac_config_headers fficonfig.h"
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+ ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+ ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+ ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+target_alias=${target_alias-$host_alias}
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in sys/mman.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------- ##
+## Report this to http://gcc.gnu.org/bugs.html ##
+## ------------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in mmap
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+if test "${ac_cv_header_sys_mman_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for sys/mman.h" >&5
+echo $ECHO_N "checking for sys/mman.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_mman_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_mman_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_mman_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/mman.h usability" >&5
+echo $ECHO_N "checking sys/mman.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <sys/mman.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/mman.h presence" >&5
+echo $ECHO_N "checking sys/mman.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/mman.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/mman.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/mman.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/mman.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/mman.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/mman.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/mman.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/mman.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/mman.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/mman.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------- ##
+## Report this to http://gcc.gnu.org/bugs.html ##
+## ------------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for sys/mman.h" >&5
+echo $ECHO_N "checking for sys/mman.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_mman_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_sys_mman_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_mman_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_mman_h" >&6
+
+fi
+if test $ac_cv_header_sys_mman_h = yes; then
+ libffi_header_sys_mman_h=yes
+else
+ libffi_header_sys_mman_h=no
+fi
+
+
+echo "$as_me:$LINENO: checking for mmap" >&5
+echo $ECHO_N "checking for mmap... $ECHO_C" >&6
+if test "${ac_cv_func_mmap+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define mmap to an innocuous variant, in case <limits.h> declares mmap.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define mmap innocuous_mmap
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char mmap (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef mmap
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char mmap ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_mmap) || defined (__stub___mmap)
+choke me
+#else
+char (*f) () = mmap;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != mmap;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_mmap=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_mmap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap" >&5
+echo "${ECHO_T}$ac_cv_func_mmap" >&6
+if test $ac_cv_func_mmap = yes; then
+ libffi_func_mmap=yes
+else
+ libffi_func_mmap=no
+fi
+
+if test "$libffi_header_sys_mman_h" != yes \
+ || test "$libffi_func_mmap" != yes; then
+ ac_cv_func_mmap_file=no
+ ac_cv_func_mmap_dev_zero=no
+ ac_cv_func_mmap_anon=no
+else
+ echo "$as_me:$LINENO: checking whether read-only mmap of a plain file works" >&5
+echo $ECHO_N "checking whether read-only mmap of a plain file works... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_file+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Add a system to this blacklist if
+ # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
+ # memory area containing the same data that you'd get if you applied
+ # read() to the same fd. The only system known to have a problem here
+ # is VMS, where text files have record structure.
+ case "$host_os" in
+ vms* | ultrix*)
+ ac_cv_func_mmap_file=no ;;
+ *)
+ ac_cv_func_mmap_file=yes;;
+ esac
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_file" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_file" >&6
+ echo "$as_me:$LINENO: checking whether mmap from /dev/zero works" >&5
+echo $ECHO_N "checking whether mmap from /dev/zero works... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_dev_zero+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Add a system to this blacklist if it has mmap() but /dev/zero
+ # does not exist, or if mmapping /dev/zero does not give anonymous
+ # zeroed pages with both the following properties:
+ # 1. If you map N consecutive pages in with one call, and then
+ # unmap any subset of those pages, the pages that were not
+ # explicitly unmapped remain accessible.
+ # 2. If you map two adjacent blocks of memory and then unmap them
+ # both at once, they must both go away.
+ # Systems known to be in this category are Windows (all variants),
+ # VMS, and Darwin.
+ case "$host_os" in
+ vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+ ac_cv_func_mmap_dev_zero=no ;;
+ *)
+ ac_cv_func_mmap_dev_zero=yes;;
+ esac
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_dev_zero" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_dev_zero" >&6
+
+ # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
+ echo "$as_me:$LINENO: checking for MAP_ANON(YMOUS)" >&5
+echo $ECHO_N "checking for MAP_ANON(YMOUS)... $ECHO_C" >&6
+if test "${ac_cv_decl_map_anon+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+int
+main ()
+{
+int n = MAP_ANONYMOUS;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_decl_map_anon=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_decl_map_anon=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_decl_map_anon" >&5
+echo "${ECHO_T}$ac_cv_decl_map_anon" >&6
+
+ if test $ac_cv_decl_map_anon = no; then
+ ac_cv_func_mmap_anon=no
+ else
+ echo "$as_me:$LINENO: checking whether mmap with MAP_ANON(YMOUS) works" >&5
+echo $ECHO_N "checking whether mmap with MAP_ANON(YMOUS) works... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_anon+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Add a system to this blacklist if it has mmap() and MAP_ANON or
+ # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+ # doesn't give anonymous zeroed pages with the same properties listed
+ # above for use of /dev/zero.
+ # Systems known to be in this category are Windows, VMS, and SCO Unix.
+ case "$host_os" in
+ vms* | cygwin* | pe | mingw* | sco* | udk* )
+ ac_cv_func_mmap_anon=no ;;
+ *)
+ ac_cv_func_mmap_anon=yes;;
+ esac
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_anon" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_anon" >&6
+ fi
+fi
+
+if test $ac_cv_func_mmap_file = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP_FILE 1
+_ACEOF
+
+fi
+if test $ac_cv_func_mmap_dev_zero = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP_DEV_ZERO 1
+_ACEOF
+
+fi
+if test $ac_cv_func_mmap_anon = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP_ANON 1
+_ACEOF
+
+fi
+
+
+TARGETDIR="unknown"
+case "$host" in
+x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;;
+mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;;
+sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-openbsd*) TARGET=ALPHA; TARGETDIR=alpha;;
+m68k-*-openbsd*) TARGET=M68K; TARGETDIR=m68k;;
+powerpc-*-openbsd*) TARGET=POWERPC; TARGETDIR=powerpc;;
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
+i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;;
+i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
+i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
+i*86-*-openbsd*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
+i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;
+i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;;
+frv-*-*) TARGET=FRV; TARGETDIR=frv;;
+sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
+sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;;
+ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
+m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;;
+m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
+mips64*-*);;
+mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;;
+mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;;
+powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
+powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
+powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
+powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;;
+powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;;
+rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;;
+arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;;
+cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;;
+s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;;
+sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
+sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
+sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
+hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;;
+esac
+
+if test $TARGETDIR = unknown; then
+ { { echo "$as_me:$LINENO: error: \"libffi has not been ported to $host.\"" >&5
+echo "$as_me: error: \"libffi has not been ported to $host.\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+MKTARGET=$TARGET
+
+case x$TARGET in
+ xMIPS*) TARGET=MIPS ;;
+ *) ;;
+esac
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+for ac_func in memcpy
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_working_alloca_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_alloca_works=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+ exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_stack_direction=1
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+echo "$as_me:$LINENO: checking for double" >&5
+echo $ECHO_N "checking for double... $ECHO_C" >&6
+if test "${ac_cv_type_double+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((double *) 0)
+ return 0;
+if (sizeof (double))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_double=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_double=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_double" >&5
+echo "${ECHO_T}$ac_cv_type_double" >&6
+
+echo "$as_me:$LINENO: checking size of double" >&5
+echo $ECHO_N "checking size of double... $ECHO_C" >&6
+if test "${ac_cv_sizeof_double+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_double" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_double=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (double)); }
+unsigned long ulongval () { return (long) (sizeof (double)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (double))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (double))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (double))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_double=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_double=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_double" >&5
+echo "${ECHO_T}$ac_cv_sizeof_double" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long double" >&5
+echo $ECHO_N "checking for long double... $ECHO_C" >&6
+if test "${ac_cv_type_long_double+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((long double *) 0)
+ return 0;
+if (sizeof (long double))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_long_double=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long_double=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_double" >&5
+echo "${ECHO_T}$ac_cv_type_long_double" >&6
+
+echo "$as_me:$LINENO: checking size of long double" >&5
+echo $ECHO_N "checking size of long double... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long_double+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_long_double" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long double))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long double))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long double))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long double))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long double))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long_double=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long double), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long double), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (long double)); }
+unsigned long ulongval () { return (long) (sizeof (long double)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (long double))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (long double))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (long double))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_long_double=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long double), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long double), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_long_double=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_double" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_double" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+_ACEOF
+
+
+
+# Also AC_SUBST this variable for ffi.h.
+HAVE_LONG_DOUBLE=0
+if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
+ if test $ac_cv_sizeof_long_double != 0; then
+ HAVE_LONG_DOUBLE=1
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LONG_DOUBLE 1
+_ACEOF
+
+ fi
+fi
+
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+ # try to guess the endianness by grepping values into an object file
+ ac_cv_c_bigendian=unknown
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+ ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=no
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+ yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+ no)
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
+
+
+
+
+if test x$TARGET = xSPARC; then
+ echo "$as_me:$LINENO: checking assembler and linker support unaligned pc related relocs" >&5
+echo $ECHO_N "checking assembler and linker support unaligned pc related relocs... $ECHO_C" >&6
+if test "${libffi_cv_as_sparc_ua_pcrel+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ save_CFLAGS="$CFLAGS"
+ save_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS -fpic"
+ LDFLAGS="$LDFLAGS -shared"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libffi_cv_as_sparc_ua_pcrel=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libffi_cv_as_sparc_ua_pcrel=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+fi
+echo "$as_me:$LINENO: result: $libffi_cv_as_sparc_ua_pcrel" >&5
+echo "${ECHO_T}$libffi_cv_as_sparc_ua_pcrel" >&6
+ if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_SPARC_UA_PCREL 1
+_ACEOF
+
+ fi
+
+ echo "$as_me:$LINENO: checking assembler .register pseudo-op support" >&5
+echo $ECHO_N "checking assembler .register pseudo-op support... $ECHO_C" >&6
+if test "${libffi_cv_as_register_pseudo_op+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ libffi_cv_as_register_pseudo_op=unknown
+ # Check if we have .register
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+asm (".register %g2, #scratch");
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libffi_cv_as_register_pseudo_op=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libffi_cv_as_register_pseudo_op=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $libffi_cv_as_register_pseudo_op" >&5
+echo "${ECHO_T}$libffi_cv_as_register_pseudo_op" >&6
+ if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_REGISTER_PSEUDO_OP 1
+_ACEOF
+
+ fi
+fi
+
+echo "$as_me:$LINENO: checking whether .eh_frame section should be read-only" >&5
+echo $ECHO_N "checking whether .eh_frame section should be read-only... $ECHO_C" >&6
+if test "${libffi_cv_ro_eh_frame+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ libffi_cv_ro_eh_frame=no
+ echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+ if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+ if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+ libffi_cv_ro_eh_frame=yes
+ elif grep '.section.*eh_frame.*#alloc' conftest.c \
+ | grep -v '#write' > /dev/null; then
+ libffi_cv_ro_eh_frame=yes
+ fi
+ fi
+ rm -f conftest.*
+
+fi
+echo "$as_me:$LINENO: result: $libffi_cv_ro_eh_frame" >&5
+echo "${ECHO_T}$libffi_cv_ro_eh_frame" >&6
+if test "x$libffi_cv_ro_eh_frame" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_RO_EH_FRAME 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define EH_FRAME_FLAGS "a"
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define EH_FRAME_FLAGS "aw"
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for __attribute__((visibility(\"hidden\")))" >&5
+echo $ECHO_N "checking for __attribute__((visibility(\"hidden\")))... $ECHO_C" >&6
+if test "${libffi_cv_hidden_visibility_attribute+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
+ libffi_cv_hidden_visibility_attribute=no
+ if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep '\.hidden.*foo' conftest.s >/dev/null; then
+ libffi_cv_hidden_visibility_attribute=yes
+ fi
+ fi
+ rm -f conftest.*
+
+fi
+echo "$as_me:$LINENO: result: $libffi_cv_hidden_visibility_attribute" >&5
+echo "${ECHO_T}$libffi_cv_hidden_visibility_attribute" >&6
+if test $libffi_cv_hidden_visibility_attribute = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define FFI_NO_RAW_API 1
+_ACEOF
+
+
+ ac_config_commands="$ac_config_commands include"
+
+ ac_config_commands="$ac_config_commands src"
+
+
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+ TARGETINCDIR="darwin"
+ ;;
+esac
+
+
+ ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h"
+
+ ac_config_links="$ac_config_links include/ffi_common.h:include/ffi_common.h"
+
+
+ ac_config_files="$ac_config_files include/ffi.h fficonfig.py"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by libffi $as_me 2.1, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+libffi config.status 2.1
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+TARGETDIR="$TARGETDIR"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "include/ffi.h" ) CONFIG_FILES="$CONFIG_FILES include/ffi.h" ;;
+ "fficonfig.py" ) CONFIG_FILES="$CONFIG_FILES fficonfig.py" ;;
+ "include/ffitarget.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h" ;;
+ "include/ffi_common.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffi_common.h:include/ffi_common.h" ;;
+ "include" ) CONFIG_COMMANDS="$CONFIG_COMMANDS include" ;;
+ "src" ) CONFIG_COMMANDS="$CONFIG_COMMANDS src" ;;
+ "fficonfig.h" ) CONFIG_HEADERS="$CONFIG_HEADERS fficonfig.h" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@CC@,$CC,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@CPP@,$CPP,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@EGREP@,$EGREP,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@HAVE_LONG_DOUBLE@,$HAVE_LONG_DOUBLE,;t t
+s,@TARGET@,$TARGET,;t t
+s,@TARGETDIR@,$TARGETDIR,;t t
+s,@MKTARGET@,$MKTARGET,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_LINKS section.
+#
+
+for ac_file in : $CONFIG_LINKS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+
+ { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_dest" >&5
+echo "$as_me: linking $srcdir/$ac_source to $ac_dest" >&6;}
+
+ if test ! -r $srcdir/$ac_source; then
+ { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5
+echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ rm -f $ac_dest
+
+ # Make relative symlinks.
+ ac_dest_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dest_dir"
+ else
+ as_dir="$ac_dest_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dest_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dest_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dest_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dest_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dest_dir";;
+*)
+ case "$ac_dest_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dest_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dest_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $srcdir in
+ [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;;
+ *) ac_rel_source=$ac_top_builddir$srcdir/$ac_source ;;
+ esac
+
+ # Try a symlink, then a hard link, then a copy.
+ ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+ ln $srcdir/$ac_source $ac_dest 2>/dev/null ||
+ cp -p $srcdir/$ac_source $ac_dest ||
+ { { echo "$as_me:$LINENO: error: cannot link or copy $srcdir/$ac_source to $ac_dest" >&5
+echo "$as_me: error: cannot link or copy $srcdir/$ac_source to $ac_dest" >&2;}
+ { (exit 1); exit 1; }; }
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ include ) test -d include || mkdir include ;;
+ src )
+test -d src || mkdir src
+test -d src/$TARGETDIR || mkdir src/$TARGETDIR
+ ;;
+ esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/configure.ac b/sys/src/cmd/python/Modules/_ctypes/libffi/configure.ac
new file mode 100644
index 000000000..1308034ac
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/configure.ac
@@ -0,0 +1,243 @@
+dnl Process this with autoconf to create configure
+
+AC_PREREQ(2.59)
+
+AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html])
+AC_CONFIG_HEADERS([fficonfig.h])
+
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
+
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_FUNCS(mmap)
+AC_FUNC_MMAP_BLACKLIST
+
+TARGETDIR="unknown"
+case "$host" in
+x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;;
+mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;;
+sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-openbsd*) TARGET=ALPHA; TARGETDIR=alpha;;
+m68k-*-openbsd*) TARGET=M68K; TARGETDIR=m68k;;
+powerpc-*-openbsd*) TARGET=POWERPC; TARGETDIR=powerpc;;
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
+i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;;
+i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
+i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
+i*86-*-openbsd*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
+i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;
+i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;;
+frv-*-*) TARGET=FRV; TARGETDIR=frv;;
+sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
+sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;;
+ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
+m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;;
+m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
+mips64*-*);;
+mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;;
+mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;;
+powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
+powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
+powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
+powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;;
+powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;;
+rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;;
+arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;;
+cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;;
+s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;;
+sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
+sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
+sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
+hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;;
+esac
+
+if test $TARGETDIR = unknown; then
+ AC_MSG_ERROR(["libffi has not been ported to $host."])
+fi
+
+dnl libffi changes TARGET for MIPS to define a such macro in the header
+dnl while MIPS_IRIX or MIPS_LINUX is separatedly used to decide which
+dnl files will be compiled. So, we need to keep the original decision
+dnl of TARGET to use in fficonfig.py.in.
+MKTARGET=$TARGET
+
+case x$TARGET in
+ xMIPS*) TARGET=MIPS ;;
+ *) ;;
+esac
+
+AC_HEADER_STDC
+AC_CHECK_FUNCS(memcpy)
+AC_FUNC_ALLOCA
+
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(long double)
+
+# Also AC_SUBST this variable for ffi.h.
+HAVE_LONG_DOUBLE=0
+if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
+ if test $ac_cv_sizeof_long_double != 0; then
+ HAVE_LONG_DOUBLE=1
+ AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
+ fi
+fi
+AC_SUBST(HAVE_LONG_DOUBLE)
+
+AC_C_BIGENDIAN
+AH_VERBATIM([WORDS_BIGENDIAN],
+[
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX).
+
+ The block below does compile-time checking for endianness on platforms
+ that use GCC and therefore allows compiling fat binaries on OSX by using
+ '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+ such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif])
+
+
+if test x$TARGET = xSPARC; then
+ AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
+ libffi_cv_as_sparc_ua_pcrel, [
+ save_CFLAGS="$CFLAGS"
+ save_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS -fpic"
+ LDFLAGS="$LDFLAGS -shared"
+ AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
+ [libffi_cv_as_sparc_ua_pcrel=yes],
+ [libffi_cv_as_sparc_ua_pcrel=no])
+ CFLAGS="$save_CFLAGS"
+ LDFLAGS="$save_LDFLAGS"])
+ if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
+ AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+ [Define if your assembler and linker support unaligned PC relative relocs.])
+ fi
+
+ AC_CACHE_CHECK([assembler .register pseudo-op support],
+ libffi_cv_as_register_pseudo_op, [
+ libffi_cv_as_register_pseudo_op=unknown
+ # Check if we have .register
+ AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
+ [libffi_cv_as_register_pseudo_op=yes],
+ [libffi_cv_as_register_pseudo_op=no])
+ ])
+ if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
+ AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
+ [Define if your assembler supports .register.])
+ fi
+fi
+
+AC_CACHE_CHECK([whether .eh_frame section should be read-only],
+ libffi_cv_ro_eh_frame, [
+ libffi_cv_ro_eh_frame=no
+ echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+ if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+ if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+ libffi_cv_ro_eh_frame=yes
+ elif grep '.section.*eh_frame.*#alloc' conftest.c \
+ | grep -v '#write' > /dev/null; then
+ libffi_cv_ro_eh_frame=yes
+ fi
+ fi
+ rm -f conftest.*
+ ])
+if test "x$libffi_cv_ro_eh_frame" = xyes; then
+ AC_DEFINE(HAVE_RO_EH_FRAME, 1,
+ [Define if .eh_frame sections should be read-only.])
+ AC_DEFINE(EH_FRAME_FLAGS, "a",
+ [Define to the flags needed for the .section .eh_frame directive.])
+else
+ AC_DEFINE(EH_FRAME_FLAGS, "aw",
+ [Define to the flags needed for the .section .eh_frame directive.])
+fi
+
+AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
+ libffi_cv_hidden_visibility_attribute, [
+ echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
+ libffi_cv_hidden_visibility_attribute=no
+ if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ if grep '\.hidden.*foo' conftest.s >/dev/null; then
+ libffi_cv_hidden_visibility_attribute=yes
+ fi
+ fi
+ rm -f conftest.*
+ ])
+if test $libffi_cv_hidden_visibility_attribute = yes; then
+ AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
+ [Define if __attribute__((visibility("hidden"))) is supported.])
+fi
+
+AH_BOTTOM([
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+])
+
+AC_SUBST(TARGET)
+AC_SUBST(TARGETDIR)
+AC_SUBST(MKTARGET)
+
+AC_SUBST(SHELL)
+
+AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
+
+AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
+AC_CONFIG_COMMANDS(src, [
+test -d src || mkdir src
+test -d src/$TARGETDIR || mkdir src/$TARGETDIR
+], [TARGETDIR="$TARGETDIR"])
+
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+ TARGETINCDIR="darwin"
+ ;;
+esac
+
+
+AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h)
+AC_CONFIG_LINKS(include/ffi_common.h:include/ffi_common.h)
+
+AC_CONFIG_FILES(include/ffi.h fficonfig.py)
+
+AC_OUTPUT
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.h.in b/sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.h.in
new file mode 100644
index 000000000..bcc5a58d4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.h.in
@@ -0,0 +1,148 @@
+/* fficonfig.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+#undef EH_FRAME_FLAGS
+
+/* Define this is you do not want support for the raw API. */
+#undef FFI_NO_RAW_API
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define if your assembler supports .register. */
+#undef HAVE_AS_REGISTER_PSEUDO_OP
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+ */
+#undef HAVE_AS_SPARC_UA_PCREL
+
+/* Define if __attribute__((visibility("hidden"))) is supported. */
+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the long double type and it is bigger than a double */
+#undef HAVE_LONG_DOUBLE
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+#undef HAVE_MMAP_ANON
+
+/* Define if mmap of /dev/zero works. */
+#undef HAVE_MMAP_DEV_ZERO
+
+/* Define if read-only mmap of a plain file works. */
+#undef HAVE_MMAP_FILE
+
+/* Define if .eh_frame sections should be read-only. */
+#undef HAVE_RO_EH_FRAME
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of a `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of a `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX).
+
+ The block below does compile-time checking for endianness on platforms
+ that use GCC and therefore allows compiling fat binaries on OSX by using
+ '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+ such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif
+
+
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.py.in b/sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.py.in
new file mode 100644
index 000000000..7a9821691
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.py.in
@@ -0,0 +1,45 @@
+ffi_sources = """
+src/prep_cif.c
+""".split()
+
+ffi_platforms = {
+ 'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'],
+ 'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'],
+ 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'],
+ 'X86_DARWIN': ['src/x86/ffi_darwin.c', 'src/x86/darwin.S'],
+ 'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'],
+ 'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'],
+ 'ALPHA': ['src/alpha/ffi.c', 'src/alpha/osf.S'],
+ 'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'],
+ 'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'],
+ 'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'],
+ 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'],
+ 'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'],
+ 'POWERPC_DARWIN': ['src/powerpc/ffi_darwin.c', 'src/powerpc/darwin.S', 'src/powerpc/darwin_closure.S'],
+ 'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'],
+ 'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'],
+ 'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'],
+ 'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'],
+ 'S390': ['src/s390/sysv.S', 'src/s390/ffi.c'],
+ 'X86_64': ['src/x86/ffi64.c', 'src/x86/unix64.S', 'src/x86/ffi.c', 'src/x86/sysv.S'],
+ 'SH': ['src/sh/sysv.S', 'src/sh/ffi.c'],
+ 'SH64': ['src/sh64/sysv.S', 'src/sh64/ffi.c'],
+ 'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
+}
+
+# Build all darwin related files on all supported darwin architectures, this
+# makes it easier to build universal binaries.
+if 1:
+ all_darwin = ('X86_DARWIN', 'POWERPC_DARWIN')
+ all_darwin_files = []
+ for pn in all_darwin:
+ all_darwin_files.extend(ffi_platforms[pn])
+ for pn in all_darwin:
+ ffi_platforms[pn] = all_darwin_files
+ del all_darwin, all_darwin_files, pn
+
+ffi_srcdir = '@srcdir@'
+ffi_sources += ffi_platforms['@MKTARGET@']
+ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources]
+
+ffi_cflags = '@CFLAGS@'
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi.h.in b/sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi.h.in
new file mode 100644
index 000000000..5ddda7901
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi.h.in
@@ -0,0 +1,313 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi @VERSION@ - Copyright (c) 1996-2003 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ The basic API is described in the README file.
+
+ The raw API is designed to bypass some of the argument packing
+ and unpacking on architectures for which it can be avoided.
+
+ The closure API allows interpreted functions to be packaged up
+ inside a C function pointer, so that they can be called as C functions,
+ with no understanding on the client side that they are interpreted.
+ It can also be used in other cases in which it is necessary to package
+ up a user specified parameter and a function pointer as a single
+ function pointer.
+
+ The closure API must be implemented in order to get its functionality,
+ e.g. for use by gij. Routines are provided to emulate the raw API
+ if the underlying platform doesn't allow faster implementation.
+
+ More details on the raw and cloure API can be found in:
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+ and
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+ -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#define @TARGET@
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+ But we can find it either under the correct ANSI name, or under GNU
+ C's internal name. */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+# define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+# ifdef __GNUC__
+# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+# endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar ffi_type_uint8
+# define ffi_type_schar ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort ffi_type_uint16
+# define ffi_type_sshort ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort ffi_type_uint32
+# define ffi_type_sshort ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint ffi_type_uint16
+# define ffi_type_sint ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint ffi_type_uint32
+# define ffi_type_sint ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint ffi_type_uint64
+# define ffi_type_sint ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong ffi_type_uint64
+#define ffi_type_slong ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t */
+/* can hold a pointer. */
+
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+ FFI_OK = 0,
+ FFI_BAD_TYPEDEF,
+ FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+ ffi_abi abi;
+ unsigned nargs;
+ /*@dependent@*/ ffi_type **arg_types;
+ /*@dependent@*/ ffi_type *rtype;
+ unsigned bytes;
+ unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+ FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+# define FFI_SIZEOF_ARG 4
+# elif LONG_MAX == 9223372036854775807
+# define FFI_SIZEOF_ARG 8
+# endif
+#endif
+
+typedef union {
+ ffi_sarg sint;
+ ffi_arg uint;
+ float flt;
+ char data[FFI_SIZEOF_ARG];
+ void* ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(void),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter */
+/* packing, even on 64-bit machines. I.e. on 64-bit machines */
+/* longs and doubles are followed by an empty 64-bit word. */
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(void),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+ void *user_data;
+} ffi_closure __attribute__((aligned (8)));
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data);
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* if this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the transaltion, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+ void *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes);
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(void),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID 0
+#define FFI_TYPE_INT 1
+#define FFI_TYPE_FLOAT 2
+#define FFI_TYPE_DOUBLE 3
+#if @HAVE_LONG_DOUBLE@
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8 5
+#define FFI_TYPE_SINT8 6
+#define FFI_TYPE_UINT16 7
+#define FFI_TYPE_SINT16 8
+#define FFI_TYPE_UINT32 9
+#define FFI_TYPE_SINT32 10
+#define FFI_TYPE_UINT64 11
+#define FFI_TYPE_SINT64 12
+#define FFI_TYPE_STRUCT 13
+#define FFI_TYPE_POINTER 14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi_common.h b/sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi_common.h
new file mode 100644
index 000000000..da15ab8ec
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi_common.h
@@ -0,0 +1,95 @@
+/* -----------------------------------------------------------------------
+ ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
+
+ Common internal definitions and macros. Only necessary for building
+ libffi.
+ ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+
+/* Do not move this. Some versions of AIX are very picky about where
+ this is positioned. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG)
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x)
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+ /*@dependent@*/ ffi_cif *cif;
+ /*@dependent@*/ void *rvalue;
+ /*@dependent@*/ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions. */
+typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
+typedef signed int SINT8 __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int SINT64 __attribute__((__mode__(__DI__)));
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/install-sh b/sys/src/cmd/python/Modules/_ctypes/libffi/install-sh
new file mode 100755
index 000000000..0ec27bcd4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/install-sh
@@ -0,0 +1,294 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd=$cpprog
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "$0: no input file specified" >&2
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d "$dst" ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f "$src" ] || [ -d "$src" ]
+ then
+ :
+ else
+ echo "$0: $src does not exist" >&2
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "$0: no destination specified" >&2
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d "$dst" ]
+ then
+ dst=$dst/`basename "$src"`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp=$pathcomp$1
+ shift
+
+ if [ ! -d "$pathcomp" ] ;
+ then
+ $mkdirprog "$pathcomp"
+ else
+ :
+ fi
+
+ pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd "$dst" &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ dstfile=`basename "$dst" $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ :
+ fi
+
+# Make a couple of temp file names in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+ rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+ trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location. We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons. In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+ if [ -f "$dstdir/$dstfile" ]
+ then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+ $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+ {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit
+ }
+ else
+ :
+ fi
+} &&
+
+# Now rename the file to the real destination.
+
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+ (exit 0); exit
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffi.c
new file mode 100644
index 000000000..00d337901
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffi.c
@@ -0,0 +1,252 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998, 2001 Red Hat, Inc.
+
+ Alpha Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)());
+extern void ffi_closure_osf(void);
+
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Adjust cif->bytes to represent a minimum 6 words for the temporary
+ register argument loading area. */
+ if (cif->bytes < 6*FFI_SIZEOF_ARG)
+ cif->bytes = 6*FFI_SIZEOF_ARG;
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = cif->rtype->type;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ unsigned long *stack, *argp;
+ long i, avn;
+ ffi_type **arg_types;
+
+ FFI_ASSERT (cif->abi == FFI_OSF);
+
+ /* If the return value is a struct and we don't have a return
+ value address then we need to make one. */
+ if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
+ rvalue = alloca(cif->rtype->size);
+
+ /* Allocate the space for the arguments, plus 4 words of temp
+ space for ffi_call_osf. */
+ argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
+
+ if (cif->flags == FFI_TYPE_STRUCT)
+ *(void **) argp++ = rvalue;
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ while (i < avn)
+ {
+ switch ((*arg_types)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(SINT64 *) argp = *(SINT8 *)(* avalue);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(SINT64 *) argp = *(UINT8 *)(* avalue);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(SINT64 *) argp = *(SINT16 *)(* avalue);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(SINT64 *) argp = *(UINT16 *)(* avalue);
+ break;
+
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ /* Note that unsigned 32-bit quantities are sign extended. */
+ *(SINT64 *) argp = *(SINT32 *)(* avalue);
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ *(UINT64 *) argp = *(UINT64 *)(* avalue);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (argp - stack < 6)
+ {
+ /* Note the conversion -- all the fp regs are loaded as
+ doubles. The in-register format is the same. */
+ *(double *) argp = *(float *)(* avalue);
+ }
+ else
+ *(float *) argp = *(float *)(* avalue);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ *(double *) argp = *(double *)(* avalue);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy(argp, *avalue, (*arg_types)->size);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ i++, arg_types++, avalue++;
+ }
+
+ ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
+}
+
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp;
+
+ FFI_ASSERT (cif->abi == FFI_OSF);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ tramp[0] = 0x47fb0401; /* mov $27,$1 */
+ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
+ tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */
+ tramp[3] = 0x47ff041f; /* nop */
+ *(void **) &tramp[4] = ffi_closure_osf;
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Flush the Icache.
+
+ Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
+ instead, since both Compaq as and gas can handle it.
+
+ 0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>. */
+ asm volatile ("call_pal 0x86" : : : "memory");
+
+ return FFI_OK;
+}
+
+int
+ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
+{
+ ffi_cif *cif;
+ void **avalue;
+ ffi_type **arg_types;
+ long i, avn, argn;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ argn = 0;
+
+ /* Copy the caller's structure return address to that the closure
+ returns the data directly to the caller. */
+ if (cif->flags == FFI_TYPE_STRUCT)
+ {
+ rvalue = (void *) argp[0];
+ argn = 1;
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_STRUCT:
+ avalue[i] = &argp[argn];
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (argn < 6)
+ {
+ /* Floats coming from registers need conversion from double
+ back to float format. */
+ *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
+ avalue[i] = &argp[argn - 6];
+ }
+ else
+ avalue[i] = &argp[argn];
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ i++;
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_osf how to perform return type promotions. */
+ return cif->rtype->type;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffitarget.h
new file mode 100644
index 000000000..00a121718
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffitarget.h
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for Alpha.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_OSF,
+ FFI_DEFAULT_ABI = FFI_OSF,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/osf.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/osf.S
new file mode 100644
index 000000000..95b30fae8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/osf.S
@@ -0,0 +1,359 @@
+/* -----------------------------------------------------------------------
+ osf.S - Copyright (c) 1998, 2001 Red Hat
+
+ Alpha/OSF Foreign Function Interface
+
+ $Id: osf.S,v 1.2 2006/03/03 20:24:26 theller Exp $
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .arch ev6
+ .text
+
+/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
+ void *raddr, void (*fnaddr)());
+
+ Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+ for this function. This has been allocated by ffi_call. We also
+ deallocate some of the stack that has been alloca'd. */
+
+ .align 3
+ .globl ffi_call_osf
+ .ent ffi_call_osf
+ffi_call_osf:
+ .frame $15, 32, $26, 0
+ .mask 0x4008000, -32
+$LFB1:
+ addq $16,$17,$1
+ mov $16, $30
+ stq $26, 0($1)
+ stq $15, 8($1)
+ stq $18, 16($1)
+ mov $1, $15
+$LCFI1:
+ .prologue 0
+
+ stq $19, 24($1)
+ mov $20, $27
+
+ # Load up all of the (potential) argument registers.
+ ldq $16, 0($30)
+ ldt $f16, 0($30)
+ ldt $f17, 8($30)
+ ldq $17, 8($30)
+ ldt $f18, 16($30)
+ ldq $18, 16($30)
+ ldt $f19, 24($30)
+ ldq $19, 24($30)
+ ldt $f20, 32($30)
+ ldq $20, 32($30)
+ ldt $f21, 40($30)
+ ldq $21, 40($30)
+
+ # Deallocate the register argument area.
+ lda $30, 48($30)
+
+ jsr $26, ($27), 0
+ ldgp $29, 0($26)
+
+ # If the return value pointer is NULL, assume no return value.
+ ldq $19, 24($15)
+ ldq $18, 16($15)
+ ldq $26, 0($15)
+$LCFI2:
+ beq $19, $noretval
+
+ # Store the return value out in the proper type.
+ cmpeq $18, FFI_TYPE_INT, $1
+ bne $1, $retint
+ cmpeq $18, FFI_TYPE_FLOAT, $2
+ bne $2, $retfloat
+ cmpeq $18, FFI_TYPE_DOUBLE, $3
+ bne $3, $retdouble
+
+ .align 3
+$noretval:
+ ldq $15, 8($15)
+ ret
+
+ .align 4
+$retint:
+ stq $0, 0($19)
+ nop
+ ldq $15, 8($15)
+ ret
+
+ .align 4
+$retfloat:
+ sts $f0, 0($19)
+ nop
+ ldq $15, 8($15)
+ ret
+
+ .align 4
+$retdouble:
+ stt $f0, 0($19)
+ nop
+ ldq $15, 8($15)
+ ret
+$LFE1:
+
+ .end ffi_call_osf
+
+/* ffi_closure_osf(...)
+
+ Receives the closure argument in $1. */
+
+ .align 3
+ .globl ffi_closure_osf
+ .ent ffi_closure_osf
+ffi_closure_osf:
+ .frame $30, 16*8, $26, 0
+ .mask 0x4000000, -16*8
+$LFB2:
+ ldgp $29, 0($27)
+ subq $30, 16*8, $30
+$LCFI5:
+ stq $26, 0($30)
+$LCFI6:
+ .prologue 1
+
+ # Store all of the potential argument registers in va_list format.
+ stt $f16, 4*8($30)
+ stt $f17, 5*8($30)
+ stt $f18, 6*8($30)
+ stt $f19, 7*8($30)
+ stt $f20, 8*8($30)
+ stt $f21, 9*8($30)
+ stq $16, 10*8($30)
+ stq $17, 11*8($30)
+ stq $18, 12*8($30)
+ stq $19, 13*8($30)
+ stq $20, 14*8($30)
+ stq $21, 15*8($30)
+
+ # Call ffi_closure_osf_inner to do the bulk of the work.
+ mov $1, $16
+ lda $17, 2*8($30)
+ lda $18, 10*8($30)
+ jsr $26, ffi_closure_osf_inner
+ ldgp $29, 0($26)
+ ldq $26, 0($30)
+
+ # Load up the return value in the proper type.
+ lda $1, $load_table
+ s4addq $0, $1, $1
+ ldl $1, 0($1)
+ addq $1, $29, $1
+ jmp $31, ($1), $load_32
+
+ .align 4
+$load_none:
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_float:
+ lds $f0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_double:
+ ldt $f0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_u8:
+#ifdef __alpha_bwx__
+ ldbu $0, 16($30)
+ nop
+#else
+ ldq $0, 16($30)
+ and $0, 255, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_s8:
+#ifdef __alpha_bwx__
+ ldbu $0, 16($30)
+ sextb $0, $0
+#else
+ ldq $0, 16($30)
+ sll $0, 56, $0
+ sra $0, 56, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_u16:
+#ifdef __alpha_bwx__
+ ldwu $0, 16($30)
+ nop
+#else
+ ldq $0, 16($30)
+ zapnot $0, 3, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_s16:
+#ifdef __alpha_bwx__
+ ldwu $0, 16($30)
+ sextw $0, $0
+#else
+ ldq $0, 16($30)
+ sll $0, 48, $0
+ sra $0, 48, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_32:
+ ldl $0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_64:
+ ldq $0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+$LFE2:
+
+ .end ffi_closure_osf
+
+#ifdef __ELF__
+.section .rodata
+#else
+.rdata
+#endif
+$load_table:
+ .gprel32 $load_none # FFI_TYPE_VOID
+ .gprel32 $load_32 # FFI_TYPE_INT
+ .gprel32 $load_float # FFI_TYPE_FLOAT
+ .gprel32 $load_double # FFI_TYPE_DOUBLE
+ .gprel32 $load_double # FFI_TYPE_LONGDOUBLE
+ .gprel32 $load_u8 # FFI_TYPE_UINT8
+ .gprel32 $load_s8 # FFI_TYPE_SINT8
+ .gprel32 $load_u16 # FFI_TYPE_UINT16
+ .gprel32 $load_s16 # FFI_TYPE_SINT16
+ .gprel32 $load_32 # FFI_TYPE_UINT32
+ .gprel32 $load_32 # FFI_TYPE_SINT32
+ .gprel32 $load_64 # FFI_TYPE_UINT64
+ .gprel32 $load_64 # FFI_TYPE_SINT64
+ .gprel32 $load_none # FFI_TYPE_STRUCT
+ .gprel32 $load_64 # FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h. */
+
+#if FFI_TYPE_FLOAT != 2 \
+ || FFI_TYPE_DOUBLE != 3 \
+ || FFI_TYPE_UINT8 != 5 \
+ || FFI_TYPE_SINT8 != 6 \
+ || FFI_TYPE_UINT16 != 7 \
+ || FFI_TYPE_SINT16 != 8 \
+ || FFI_TYPE_UINT32 != 9 \
+ || FFI_TYPE_SINT32 != 10 \
+ || FFI_TYPE_UINT64 != 11 \
+ || FFI_TYPE_SINT64 != 12 \
+ || FFI_TYPE_STRUCT != 13 \
+ || FFI_TYPE_POINTER != 14 \
+ || FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif
+
+#ifdef __ELF__
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+__FRAME_BEGIN__:
+ .4byte $LECIE1-$LSCIE1 # Length of Common Information Entry
+$LSCIE1:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x78 # sleb128 -8; CIE Data Alignment Factor
+ .byte 26 # CIE RA Column
+ .byte 0x1 # uleb128 0x1; Augmentation size
+ .byte 0x1b # FDE Encoding (pcrel sdata4)
+ .byte 0xc # DW_CFA_def_cfa
+ .byte 30 # uleb128 column 30
+ .byte 0 # uleb128 offset 0
+ .align 3
+$LECIE1:
+$LSFDE1:
+ .4byte $LEFDE1-$LASFDE1 # FDE Length
+$LASFDE1:
+ .4byte $LASFDE1-__FRAME_BEGIN__ # FDE CIE offset
+ .4byte $LFB1-. # FDE initial location
+ .4byte $LFE1-$LFB1 # FDE address range
+ .byte 0x0 # uleb128 0x0; Augmentation size
+
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI1-$LFB1
+ .byte 0x9a # DW_CFA_offset, column 26
+ .byte 4 # uleb128 4*-8
+ .byte 0x8f # DW_CFA_offset, column 15
+ .byte 0x3 # uleb128 3*-8
+ .byte 0xc # DW_CFA_def_cfa
+ .byte 15 # uleb128 column 15
+ .byte 32 # uleb128 offset 32
+
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI2-$LCFI1
+ .byte 0xda # DW_CFA_restore, column 26
+ .align 3
+$LEFDE1:
+
+$LSFDE3:
+ .4byte $LEFDE3-$LASFDE3 # FDE Length
+$LASFDE3:
+ .4byte $LASFDE3-__FRAME_BEGIN__ # FDE CIE offset
+ .4byte $LFB2-. # FDE initial location
+ .4byte $LFE2-$LFB2 # FDE address range
+ .byte 0x0 # uleb128 0x0; Augmentation size
+
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI5-$LFB2
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .byte 0x80,0x1 # uleb128 128
+
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI6-$LCFI5
+ .byte 0x9a # DW_CFA_offset, column 26
+ .byte 16 # uleb128 offset 16*-8
+ .align 3
+$LEFDE3:
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffi.c
new file mode 100644
index 000000000..1f58d93ef
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffi.c
@@ -0,0 +1,185 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Red Hat, Inc.
+
+ ARM Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+ }
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof(int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Round the stack up to a multiple of 8 bytes. This isn't needed
+ everywhere, but it is on some platforms, and it doesn't harm anything
+ when it isn't needed. */
+ cif->bytes = (cif->bytes + 7) & ~7;
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = (unsigned) FFI_TYPE_SINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffitarget.h
new file mode 100644
index 000000000..96f4bb2f2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffitarget.h
@@ -0,0 +1,47 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for ARM.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 0
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/sysv.S
new file mode 100644
index 000000000..c3471a8a2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/sysv.S
@@ -0,0 +1,209 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 1998 Red Hat, Inc.
+
+ ARM Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+#ifdef __USER_LABEL_PREFIX__
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels. */
+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#else
+#define CNAME(x) x
+#endif
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#ifdef __ELF__
+#define LSYM(x) .x
+#else
+#define LSYM(x) x
+#endif
+
+/* We need a better way of testing for this, but for now, this is all
+ we can do. */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 6
+#endif
+
+#if __ARM_ARCH__ >= 5
+# define call_reg(x) blx x
+#elif defined (__ARM_ARCH_4T__)
+# define call_reg(x) mov lr, pc ; bx x
+# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
+# define __INTERWORKING__
+# endif
+#else
+# define call_reg(x) mov lr, pc ; mov pc, x
+#endif
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro ARM_FUNC_START name
+ .text
+ .align 0
+ .thumb
+ .thumb_func
+ ENTRY(\name)
+ bx pc
+ nop
+ .arm
+/* A hook to tell gdb that we've switched to ARM mode. Also used to call
+ directly from other local arm routines. */
+_L__\name:
+.endm
+#else
+.macro ARM_FUNC_START name
+ .text
+ .align 0
+ .arm
+ ENTRY(\name)
+.endm
+#endif
+
+.macro RETLDM regs=, cond=, dirn=ia
+#if defined (__INTERWORKING__)
+ .ifc "\regs",""
+ ldr\cond lr, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, lr}
+ .endif
+ bx\cond lr
+#else
+ .ifc "\regs",""
+ ldr\cond pc, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}
+ .endif
+#endif
+.endm
+
+
+ @ r0: ffi_prep_args
+ @ r1: &ecif
+ @ r2: cif->bytes
+ @ r3: fig->flags
+ @ sp+0: ecif.rvalue
+ @ sp+4: fn
+
+ @ This assumes we are using gas.
+ARM_FUNC_START ffi_call_SYSV
+ @ Save registers
+ stmfd sp!, {r0-r3, fp, lr}
+ mov fp, sp
+
+ @ Make room for all of the new args.
+ sub sp, fp, r2
+
+ @ Place all of the ffi_prep_args in position
+ mov ip, r0
+ mov r0, sp
+ @ r1 already set
+
+ @ Call ffi_prep_args(stack, &ecif)
+ call_reg(ip)
+
+ @ move first 4 parameters in registers
+ ldmia sp, {r0-r3}
+
+ @ and adjust stack
+ ldr ip, [fp, #8]
+ cmp ip, #16
+ movhs ip, #16
+ add sp, sp, ip
+
+ @ call (fn) (...)
+ ldr ip, [fp, #28]
+ call_reg(ip)
+
+ @ Remove the space we pushed for the args
+ mov sp, fp
+
+ @ Load r2 with the pointer to storage for the return value
+ ldr r2, [sp, #24]
+
+ @ Load r3 with the return type code
+ ldr r3, [sp, #12]
+
+ @ If the return value pointer is NULL, assume no return value.
+ cmp r2, #0
+ beq LSYM(Lepilogue)
+
+@ return INT
+ cmp r3, #FFI_TYPE_INT
+#ifdef __SOFTFP__
+ cmpne r3, #FFI_TYPE_FLOAT
+#endif
+ streq r0, [r2]
+ beq LSYM(Lepilogue)
+
+ @ return INT64
+ cmp r3, #FFI_TYPE_SINT64
+#ifdef __SOFTFP__
+ cmpne r3, #FFI_TYPE_DOUBLE
+#endif
+ stmeqia r2, {r0, r1}
+
+#ifndef __SOFTFP__
+ beq LSYM(Lepilogue)
+
+@ return FLOAT
+ cmp r3, #FFI_TYPE_FLOAT
+ stfeqs f0, [r2]
+ beq LSYM(Lepilogue)
+
+@ return DOUBLE or LONGDOUBLE
+ cmp r3, #FFI_TYPE_DOUBLE
+ stfeqd f0, [r2]
+#endif
+
+LSYM(Lepilogue):
+ RETLDM "r0-r3,fp"
+
+.ffi_call_SYSV_end:
+ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffi.c
new file mode 100644
index 000000000..364c990f6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffi.c
@@ -0,0 +1,381 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Cygnus Solutions
+ Copyright (c) 2004 Simon Posnjak
+ Copyright (c) 2005 Axis Communications AB
+
+ CRIS Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+static ffi_status
+initialize_aggregate_packed_struct (ffi_type * arg)
+{
+ ffi_type **ptr;
+
+ FFI_ASSERT (arg != NULL);
+
+ FFI_ASSERT (arg->elements != NULL);
+ FFI_ASSERT (arg->size == 0);
+ FFI_ASSERT (arg->alignment == 0);
+
+ ptr = &(arg->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ if (((*ptr)->size == 0)
+ && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ FFI_ASSERT (ffi_type_test ((*ptr)));
+
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment : (*ptr)->alignment;
+
+ ptr++;
+ }
+
+ if (arg->size == 0)
+ return FFI_BAD_TYPEDEF;
+ else
+ return FFI_OK;
+}
+
+int
+ffi_prep_args (char *stack, extended_cif * ecif)
+{
+ unsigned int i;
+ unsigned int struct_count = 0;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ argp = stack;
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_STRUCT:
+ {
+ z = (*p_arg)->size;
+ if (z <= 4)
+ {
+ memcpy (argp, *p_argv, z);
+ z = 4;
+ }
+ else if (z <= 8)
+ {
+ memcpy (argp, *p_argv, z);
+ z = 8;
+ }
+ else
+ {
+ unsigned int uiLocOnStack;
+ z = sizeof (void *);
+ uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
+ struct_count = struct_count + (*p_arg)->size;
+ *(unsigned int *) argp =
+ (unsigned int) (UINT32 *) (stack + uiLocOnStack);
+ memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
+ }
+ break;
+ }
+ default:
+ z = (*p_arg)->size;
+ if (z < sizeof (int))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp =
+ (unsigned int) *(UINT8 *) (*p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp =
+ (unsigned int) *(UINT16 *) (*p_argv);
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ }
+ z = sizeof (int);
+ }
+ else if (z == sizeof (int))
+ *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
+ else
+ memcpy (argp, *p_argv, z);
+ break;
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return (struct_count);
+}
+
+ffi_status
+ffi_prep_cif (ffi_cif * cif,
+ ffi_abi abi, unsigned int nargs,
+ ffi_type * rtype, ffi_type ** atypes)
+{
+ unsigned bytes = 0;
+ unsigned int i;
+ ffi_type **ptr;
+
+ FFI_ASSERT (cif != NULL);
+ FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+ cif->abi = abi;
+ cif->arg_types = atypes;
+ cif->nargs = nargs;
+ cif->rtype = rtype;
+
+ cif->flags = 0;
+
+ if ((cif->rtype->size == 0)
+ && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ FFI_ASSERT_VALID_TYPE (cif->rtype);
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ if (((*ptr)->size == 0)
+ && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ FFI_ASSERT_VALID_TYPE (*ptr);
+
+ if (((*ptr)->alignment - 1) & bytes)
+ bytes = ALIGN (bytes, (*ptr)->alignment);
+ if ((*ptr)->type == FFI_TYPE_STRUCT)
+ {
+ if ((*ptr)->size > 8)
+ {
+ bytes += (*ptr)->size;
+ bytes += sizeof (void *);
+ }
+ else
+ {
+ if ((*ptr)->size > 4)
+ bytes += 8;
+ else
+ bytes += 4;
+ }
+ }
+ else
+ bytes += STACK_ARG_SIZE ((*ptr)->size);
+ }
+
+ cif->bytes = bytes;
+
+ return ffi_prep_cif_machdep (cif);
+}
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif * cif)
+{
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
+ extended_cif *,
+ unsigned, unsigned, unsigned *, void (*fn) ())
+ __attribute__ ((__visibility__ ("hidden")));
+
+void
+ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ ecif.rvalue = alloca (cif->rtype->size);
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+}
+
+/* Because the following variables are not exported outside libffi, we
+ mark them hidden. */
+
+/* Assembly code for the jump stub. */
+extern const char ffi_cris_trampoline_template[]
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* Offset into ffi_cris_trampoline_template of where to put the
+ ffi_prep_closure_inner function. */
+extern const int ffi_cris_trampoline_fn_offset
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* Offset into ffi_cris_trampoline_template of where to put the
+ closure data. */
+extern const int ffi_cris_trampoline_closure_offset
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* This function is sibling-called (jumped to) by the closure
+ trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
+ PARAMS[4] to simplify handling of a straddling parameter. A copy
+ of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are
+ put at the appropriate place in CLOSURE which is then executed and
+ the return value is passed back to the caller. */
+
+static unsigned long long
+ffi_prep_closure_inner (void **params, ffi_closure* closure)
+{
+ char *register_args = (char *) params;
+ void *struct_ret = params[5];
+ char *stack_args = params[6];
+ char *ptr = register_args;
+ ffi_cif *cif = closure->cif;
+ ffi_type **arg_types = cif->arg_types;
+
+ /* Max room needed is number of arguments as 64-bit values. */
+ void **avalue = alloca (closure->cif->nargs * sizeof(void *));
+ int i;
+ int doing_regs;
+ long long llret = 0;
+
+ /* Find the address of each argument. */
+ for (i = 0, doing_regs = 1; i < cif->nargs; i++)
+ {
+ /* Types up to and including 8 bytes go by-value. */
+ if (arg_types[i]->size <= 4)
+ {
+ avalue[i] = ptr;
+ ptr += 4;
+ }
+ else if (arg_types[i]->size <= 8)
+ {
+ avalue[i] = ptr;
+ ptr += 8;
+ }
+ else
+ {
+ FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
+
+ /* Passed by-reference, so copy the pointer. */
+ avalue[i] = *(void **) ptr;
+ ptr += 4;
+ }
+
+ /* If we've handled more arguments than fit in registers, start
+ looking at the those passed on the stack. Step over the
+ first one if we had a straddling parameter. */
+ if (doing_regs && ptr >= register_args + 4*4)
+ {
+ ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
+ doing_regs = 0;
+ }
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif,
+
+ cif->rtype->type == FFI_TYPE_STRUCT
+ /* The caller allocated space for the return
+ structure, and passed a pointer to this space in
+ R9. */
+ ? struct_ret
+
+ /* We take advantage of being able to ignore that
+ the high part isn't set if the return value is
+ not in R10:R11, but in R10 only. */
+ : (void *) &llret,
+
+ avalue, closure->user_data);
+
+ return llret;
+}
+
+/* API function: Prepare the trampoline. */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif *, void *, void **, void*),
+ void *user_data)
+{
+ void *innerfn = ffi_prep_closure_inner;
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+ memcpy (closure->tramp, ffi_cris_trampoline_template,
+ FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
+ memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
+ &innerfn, sizeof (void *));
+ memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
+ &closure, sizeof (void *));
+
+ return FFI_OK;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffitarget.h
new file mode 100644
index 000000000..3fb937c16
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffitarget.h
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for CRIS.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36
+#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)
+#define FFI_TRAMPOLINE_SIZE \
+ (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/sysv.S
new file mode 100644
index 000000000..79abaee4d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/sysv.S
@@ -0,0 +1,215 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2004 Simon Posnjak
+ Copyright (c) 2005 Axis Communications AB
+
+ CRIS Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#define CONCAT(x,y) x ## y
+#define XCONCAT(x,y) CONCAT (x, y)
+#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)
+
+ .text
+
+ ;; OK, when we get called we should have this (according to
+ ;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).
+ ;;
+ ;; R10: ffi_prep_args (func. pointer)
+ ;; R11: &ecif
+ ;; R12: cif->bytes
+ ;; R13: fig->flags
+ ;; sp+0: ecif.rvalue
+ ;; sp+4: fn (function pointer to the function that we need to call)
+
+ .globl L(ffi_call_SYSV)
+ .type L(ffi_call_SYSV),@function
+ .hidden L(ffi_call_SYSV)
+
+L(ffi_call_SYSV):
+ ;; Save the regs to the stack.
+ push $srp
+ ;; Used for stack pointer saving.
+ push $r6
+ ;; Used for function address pointer.
+ push $r7
+ ;; Used for stack pointer saving.
+ push $r8
+ ;; We save fig->flags to stack we will need them after we
+ ;; call The Function.
+ push $r13
+
+ ;; Saving current stack pointer.
+ move.d $sp,$r8
+ move.d $sp,$r6
+
+ ;; Move address of ffi_prep_args to r13.
+ move.d $r10,$r13
+
+ ;; Make room on the stack for the args of fn.
+ sub.d $r12,$sp
+
+ ;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:
+ ;; r10 <-- stack pointer
+ ;; r11 <-- &ecif (already there)
+ move.d $sp,$r10
+
+ ;; Call the function.
+ jsr $r13
+
+ ;; Save the size of the structures which are passed on stack.
+ move.d $r10,$r7
+
+ ;; Move first four args in to r10..r13.
+ move.d [$sp+0],$r10
+ move.d [$sp+4],$r11
+ move.d [$sp+8],$r12
+ move.d [$sp+12],$r13
+
+ ;; Adjust the stack and check if any parameters are given on stack.
+ addq 16,$sp
+ sub.d $r7,$r6
+ cmp.d $sp,$r6
+
+ bpl go_on
+ nop
+
+go_on_no_params_on_stack:
+ move.d $r6,$sp
+
+go_on:
+ ;; Discover if we need to put rval address in to r9.
+ move.d [$r8+0],$r7
+ cmpq FFI_TYPE_STRUCT,$r7
+ bne call_now
+ nop
+
+ ;; Move rval address to $r9.
+ move.d [$r8+20],$r9
+
+call_now:
+ ;; Move address of The Function in to r7.
+ move.d [$r8+24],$r7
+
+ ;; Call The Function.
+ jsr $r7
+
+ ;; Reset stack.
+ move.d $r8,$sp
+
+ ;; Load rval type (fig->flags) in to r13.
+ pop $r13
+
+ ;; Detect rval type.
+ cmpq FFI_TYPE_VOID,$r13
+ beq epilogue
+
+ cmpq FFI_TYPE_STRUCT,$r13
+ beq epilogue
+
+ cmpq FFI_TYPE_DOUBLE,$r13
+ beq return_double_or_longlong
+
+ cmpq FFI_TYPE_UINT64,$r13
+ beq return_double_or_longlong
+
+ cmpq FFI_TYPE_SINT64,$r13
+ beq return_double_or_longlong
+ nop
+
+ ;; Just return the 32 bit value.
+ ba return
+ nop
+
+return_double_or_longlong:
+ ;; Load half of the rval to r10 and the other half to r11.
+ move.d [$sp+16],$r13
+ move.d $r10,[$r13]
+ addq 4,$r13
+ move.d $r11,[$r13]
+ ba epilogue
+ nop
+
+return:
+ ;; Load the rval to r10.
+ move.d [$sp+16],$r13
+ move.d $r10,[$r13]
+
+epilogue:
+ pop $r8
+ pop $r7
+ pop $r6
+ Jump [$sp+]
+
+ .size ffi_call_SYSV,.-ffi_call_SYSV
+
+/* Save R10..R13 into an array, somewhat like varargs. Copy the next
+ argument too, to simplify handling of any straddling parameter.
+ Save R9 and SP after those. Jump to function handling the rest.
+ Since this is a template, copied and the main function filled in by
+ the user. */
+
+ .globl L(ffi_cris_trampoline_template)
+ .type L(ffi_cris_trampoline_template),@function
+ .hidden L(ffi_cris_trampoline_template)
+
+L(ffi_cris_trampoline_template):
+0:
+ /* The value we get for "PC" is right after the prefix instruction,
+ two bytes from the beginning, i.e. 0b+2. */
+ move.d $r10,[$pc+2f-(0b+2)]
+ move.d $pc,$r10
+1:
+ addq 2f-1b+4,$r10
+ move.d $r11,[$r10+]
+ move.d $r12,[$r10+]
+ move.d $r13,[$r10+]
+ move.d [$sp],$r11
+ move.d $r11,[$r10+]
+ move.d $r9,[$r10+]
+ move.d $sp,[$r10+]
+ subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10
+ move.d 0,$r11
+3:
+ jump 0
+2:
+ .size ffi_cris_trampoline_template,.-0b
+
+/* This macro create a constant usable as "extern const int \name" in
+ C from within libffi, when \name has no prefix decoration. */
+
+ .macro const name,value
+ .globl \name
+ .type \name,@object
+ .hidden \name
+\name:
+ .dword \value
+ .size \name,4
+ .endm
+
+/* Constants for offsets within the trampoline. We could do this with
+ just symbols, avoiding memory contents and memory accesses, but the
+ C usage code would look a bit stranger. */
+
+ const L(ffi_cris_trampoline_fn_offset),2b-4-0b
+ const L(ffi_cris_trampoline_closure_offset),3b-4-0b
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/darwin/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/darwin/ffitarget.h
new file mode 100644
index 000000000..2dc308ac3
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/darwin/ffitarget.h
@@ -0,0 +1,25 @@
+/*
+ * This file is for MacOSX only. Dispatch to the right architecture include
+ * file based on the current archictecture (instead of relying on a symlink
+ * created by configure). This makes is possible to build a univeral binary
+ * of ctypes in one go.
+ */
+#if defined(__i386__)
+
+#ifndef X86_DARWIN
+#define X86_DARWIN
+#endif
+#undef POWERPC_DARWIN
+
+#include "../src/x86/ffitarget.h"
+
+#elif defined(__ppc__)
+
+#ifndef POWERPC_DARWIN
+#define POWERPC_DARWIN
+#endif
+#undef X86_DARWIN
+
+#include "../src/powerpc/ffitarget.h"
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/eabi.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/eabi.S
new file mode 100644
index 000000000..9530ca52e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/eabi.S
@@ -0,0 +1,130 @@
+/* -----------------------------------------------------------------------
+ eabi.S - Copyright (c) 2004 Anthony Green
+
+ FR-V Assembly glue.
+
+ $Id: eabi.S,v 1.2 2006/03/03 20:24:46 theller Exp $
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .globl ffi_prep_args_EABI
+
+ .text
+ .p2align 4
+ .globl ffi_call_EABI
+ .type ffi_call_EABI, @function
+
+ # gr8 : ffi_prep_args
+ # gr9 : &ecif
+ # gr10: cif->bytes
+ # gr11: fig->flags
+ # gr12: ecif.rvalue
+ # gr13: fn
+
+ffi_call_EABI:
+ addi sp, #-80, sp
+ sti fp, @(sp, #24)
+ addi sp, #24, fp
+ movsg lr, gr5
+
+ /* Make room for the new arguments. */
+ /* subi sp, fp, gr10 */
+
+ /* Store return address and incoming args on stack. */
+ sti gr5, @(fp, #8)
+ sti gr8, @(fp, #-4)
+ sti gr9, @(fp, #-8)
+ sti gr10, @(fp, #-12)
+ sti gr11, @(fp, #-16)
+ sti gr12, @(fp, #-20)
+ sti gr13, @(fp, #-24)
+
+ sub sp, gr10, sp
+
+ /* Call ffi_prep_args. */
+ ldi @(fp, #-4), gr4
+ addi sp, #0, gr8
+ ldi @(fp, #-8), gr9
+#ifdef __FRV_FDPIC__
+ ldd @(gr4, gr0), gr14
+ calll @(gr14, gr0)
+#else
+ calll @(gr4, gr0)
+#endif
+
+ /* ffi_prep_args returns the new stack pointer. */
+ mov gr8, gr4
+
+ ldi @(sp, #0), gr8
+ ldi @(sp, #4), gr9
+ ldi @(sp, #8), gr10
+ ldi @(sp, #12), gr11
+ ldi @(sp, #16), gr12
+ ldi @(sp, #20), gr13
+
+ /* Always copy the return value pointer into the hidden
+ parameter register. This is only strictly necessary
+ when we're returning an aggregate type, but it doesn't
+ hurt to do this all the time, and it saves a branch. */
+ ldi @(fp, #-20), gr3
+
+ /* Use the ffi_prep_args return value for the new sp. */
+ mov gr4, sp
+
+ /* Call the target function. */
+ ldi @(fp, -24), gr4
+#ifdef __FRV_FDPIC__
+ ldd @(gr4, gr0), gr14
+ calll @(gr14, gr0)
+#else
+ calll @(gr4, gr0)
+#endif
+
+ /* Store the result. */
+ ldi @(fp, #-16), gr10 /* fig->flags */
+ ldi @(fp, #-20), gr4 /* ecif.rvalue */
+
+ /* Is the return value stored in two registers? */
+ cmpi gr10, #8, icc0
+ bne icc0, 0, .L2
+ /* Yes, save them. */
+ sti gr8, @(gr4, #0)
+ sti gr9, @(gr4, #4)
+ bra .L3
+.L2:
+ /* Is the return value a structure? */
+ cmpi gr10, #-1, icc0
+ beq icc0, 0, .L3
+ /* No, save a 4 byte return value. */
+ sti gr8, @(gr4, #0)
+.L3:
+
+ /* Restore the stack, and return. */
+ ldi @(fp, 8), gr5
+ ld @(fp, gr0), fp
+ addi sp,#80,sp
+ jmpl @(gr5,gr0)
+ .size ffi_call_EABI, .-ffi_call_EABI
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffi.c
new file mode 100644
index 000000000..6e2ac6873
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffi.c
@@ -0,0 +1,287 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2004 Anthony Green
+
+ FR-V Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+void *ffi_prep_args(char *stack, extended_cif *ecif)
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+ register int count = 0;
+
+ p_argv = ecif->avalue;
+ argp = stack;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
+ {
+ z = sizeof(void*);
+ *(void **) argp = *p_argv;
+ }
+ /* if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ if (count > 24)
+ {
+ // This is going on the stack. Turn it into a double.
+ *(double *) argp = (double) *(float*)(* p_argv);
+ z = sizeof(double);
+ }
+ else
+ *(void **) argp = *(void **)(* p_argv);
+ } */
+ else if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof(int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ count += z;
+ }
+
+ return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ cif->flags = -1;
+ else
+ cif->flags = cif->rtype->size;
+
+ cif->bytes = ALIGN (cif->bytes, 8);
+
+ return FFI_OK;
+}
+
+extern void ffi_call_EABI(void *(*)(char *, extended_cif *),
+ extended_cif *,
+ unsigned, unsigned,
+ unsigned *,
+ void (*fn)());
+
+void ffi_call(ffi_cif *cif,
+ void (*fn)(),
+ void *rvalue,
+ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ ecif.rvalue = alloca(cif->rtype->size);
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_EABI:
+ ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
+ unsigned arg4, unsigned arg5, unsigned arg6)
+{
+ /* This function is called by a trampoline. The trampoline stows a
+ pointer to the ffi_closure object in gr7. We must save this
+ pointer in a place that will persist while we do our work. */
+ register ffi_closure *creg __asm__ ("gr7");
+ ffi_closure *closure = creg;
+
+ /* Arguments that don't fit in registers are found on the stack
+ at a fixed offset above the current frame pointer. */
+ register char *frame_pointer __asm__ ("fp");
+ char *stack_args = frame_pointer + 16;
+
+ /* Lay the register arguments down in a continuous chunk of memory. */
+ unsigned register_args[6] =
+ { arg1, arg2, arg3, arg4, arg5, arg6 };
+
+ ffi_cif *cif = closure->cif;
+ ffi_type **arg_types = cif->arg_types;
+ void **avalue = alloca (cif->nargs * sizeof(void *));
+ char *ptr = (char *) register_args;
+ int i;
+
+ /* Find the address of each argument. */
+ for (i = 0; i < cif->nargs; i++)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = ptr + 3;
+ break;
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = ptr + 2;
+ break;
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_FLOAT:
+ avalue[i] = ptr;
+ break;
+ case FFI_TYPE_STRUCT:
+ avalue[i] = *(void**)ptr;
+ break;
+ default:
+ /* This is an 8-byte value. */
+ avalue[i] = ptr;
+ ptr += 4;
+ break;
+ }
+ ptr += 4;
+
+ /* If we've handled more arguments than fit in registers,
+ start looking at the those passed on the stack. */
+ if (ptr == ((char *)register_args + (6*4)))
+ ptr = stack_args;
+ }
+
+ /* Invoke the closure. */
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ /* The caller allocates space for the return structure, and
+ passes a pointer to this space in gr3. Use this value directly
+ as the return value. */
+ register void *return_struct_ptr __asm__("gr3");
+ (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
+ }
+ else
+ {
+ /* Allocate space for the return value and call the function. */
+ long long rvalue;
+ (closure->fun) (cif, &rvalue, avalue, closure->user_data);
+
+ /* Functions return 4-byte or smaller results in gr8. 8-byte
+ values also use gr9. We fill the both, even for small return
+ values, just to avoid a branch. */
+ asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue));
+ asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
+ }
+}
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+ unsigned long fn = (long) ffi_closure_eabi;
+ unsigned long cls = (long) closure;
+#ifdef __FRV_FDPIC__
+ register void *got __asm__("gr15");
+#endif
+ int i;
+
+ fn = (unsigned long) ffi_closure_eabi;
+
+#ifdef __FRV_FDPIC__
+ tramp[0] = &tramp[2];
+ tramp[1] = got;
+ tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
+ tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
+ tramp[4] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
+ tramp[5] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
+ tramp[6] = 0x9cc86000; /* ldi @(gr6, #0), gr14 */
+ tramp[7] = 0x8030e000; /* jmpl @(gr14, gr0) */
+#else
+ tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
+ tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
+ tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
+ tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
+ tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */
+#endif
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Cache flushing. */
+ for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
+ __asm__ volatile ("dcf @(%0,%1)\n\tici @(%0,%1)" :: "r" (tramp), "r" (i));
+
+ return FFI_OK;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffitarget.h
new file mode 100644
index 000000000..d235697d6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffitarget.h
@@ -0,0 +1,60 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2004 Red Hat, Inc.
+ Target configuration macros for FR-V
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+
+#ifdef FRV
+ FFI_EABI,
+ FFI_DEFAULT_ABI = FFI_EABI,
+#endif
+
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef __FRV_FDPIC__
+/* Trampolines are 8 4-byte instructions long. */
+#define FFI_TRAMPOLINE_SIZE (8*4)
+#else
+/* Trampolines are 5 4-byte instructions long. */
+#define FFI_TRAMPOLINE_SIZE (5*4)
+#endif
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffi.c
new file mode 100644
index 000000000..e810827a8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffi.c
@@ -0,0 +1,562 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Red Hat, Inc.
+ Copyright (c) 2000 Hewlett Packard Company
+
+ IA64 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <float.h>
+
+#include "ia64_flags.h"
+
+/* A 64-bit pointer value. In LP64 mode, this is effectively a plain
+ pointer. In ILP32 mode, it's a pointer that's been extended to
+ 64 bits by "addp4". */
+typedef void *PTR64 __attribute__((mode(DI)));
+
+/* Memory image of fp register contents. This is the implementation
+ specific format used by ldf.fill/stf.spill. All we care about is
+ that it wants a 16 byte aligned slot. */
+typedef struct
+{
+ UINT64 x[2] __attribute__((aligned(16)));
+} fpreg;
+
+
+/* The stack layout given to ffi_call_unix and ffi_closure_unix_inner. */
+
+struct ia64_args
+{
+ fpreg fp_regs[8]; /* Contents of 8 fp arg registers. */
+ UINT64 gp_regs[8]; /* Contents of 8 gp arg registers. */
+ UINT64 other_args[]; /* Arguments passed on stack, variable size. */
+};
+
+
+/* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes. */
+
+static inline void *
+endian_adjust (void *addr, size_t len)
+{
+#ifdef __BIG_ENDIAN__
+ return addr + (8 - len);
+#else
+ return addr;
+#endif
+}
+
+/* Store VALUE to ADDR in the current cpu implementation's fp spill format. */
+
+static inline void
+stf_spill(fpreg *addr, __float80 value)
+{
+ asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
+}
+
+/* Load a value from ADDR, which is in the current cpu implementation's
+ fp spill format. */
+
+static inline __float80
+ldf_fill(fpreg *addr)
+{
+ __float80 ret;
+ asm ("ldf.fill %0 = %1%P1" : "=f"(ret) : "m"(*addr));
+ return ret;
+}
+
+/* Return the size of the C type associated with with TYPE. Which will
+ be one of the FFI_IA64_TYPE_HFA_* values. */
+
+static size_t
+hfa_type_size (int type)
+{
+ switch (type)
+ {
+ case FFI_IA64_TYPE_HFA_FLOAT:
+ return sizeof(float);
+ case FFI_IA64_TYPE_HFA_DOUBLE:
+ return sizeof(double);
+ case FFI_IA64_TYPE_HFA_LDOUBLE:
+ return sizeof(__float80);
+ default:
+ abort ();
+ }
+}
+
+/* Load from ADDR a value indicated by TYPE. Which will be one of
+ the FFI_IA64_TYPE_HFA_* values. */
+
+static __float80
+hfa_type_load (int type, void *addr)
+{
+ switch (type)
+ {
+ case FFI_IA64_TYPE_HFA_FLOAT:
+ return *(float *) addr;
+ case FFI_IA64_TYPE_HFA_DOUBLE:
+ return *(double *) addr;
+ case FFI_IA64_TYPE_HFA_LDOUBLE:
+ return *(__float80 *) addr;
+ default:
+ abort ();
+ }
+}
+
+/* Load VALUE into ADDR as indicated by TYPE. Which will be one of
+ the FFI_IA64_TYPE_HFA_* values. */
+
+static void
+hfa_type_store (int type, void *addr, __float80 value)
+{
+ switch (type)
+ {
+ case FFI_IA64_TYPE_HFA_FLOAT:
+ *(float *) addr = value;
+ break;
+ case FFI_IA64_TYPE_HFA_DOUBLE:
+ *(double *) addr = value;
+ break;
+ case FFI_IA64_TYPE_HFA_LDOUBLE:
+ *(__float80 *) addr = value;
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Is TYPE a struct containing floats, doubles, or extended doubles,
+ all of the same fp type? If so, return the element type. Return
+ FFI_TYPE_VOID if not. */
+
+static int
+hfa_element_type (ffi_type *type, int nested)
+{
+ int element = FFI_TYPE_VOID;
+
+ switch (type->type)
+ {
+ case FFI_TYPE_FLOAT:
+ /* We want to return VOID for raw floating-point types, but the
+ synthetic HFA type if we're nested within an aggregate. */
+ if (nested)
+ element = FFI_IA64_TYPE_HFA_FLOAT;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ /* Similarly. */
+ if (nested)
+ element = FFI_IA64_TYPE_HFA_DOUBLE;
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ /* Similarly, except that that HFA is true for double extended,
+ but not quad precision. Both have sizeof == 16, so tell the
+ difference based on the precision. */
+ if (LDBL_MANT_DIG == 64 && nested)
+ element = FFI_IA64_TYPE_HFA_LDOUBLE;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ ffi_type **ptr = &type->elements[0];
+
+ for (ptr = &type->elements[0]; *ptr ; ptr++)
+ {
+ int sub_element = hfa_element_type (*ptr, 1);
+ if (sub_element == FFI_TYPE_VOID)
+ return FFI_TYPE_VOID;
+
+ if (element == FFI_TYPE_VOID)
+ element = sub_element;
+ else if (element != sub_element)
+ return FFI_TYPE_VOID;
+ }
+ }
+ break;
+
+ default:
+ return FFI_TYPE_VOID;
+ }
+
+ return element;
+}
+
+
+/* Perform machine dependent cif processing. */
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ int flags;
+
+ /* Adjust cif->bytes to include space for the bits of the ia64_args frame
+ that preceeds the integer register portion. The estimate that the
+ generic bits did for the argument space required is good enough for the
+ integer component. */
+ cif->bytes += offsetof(struct ia64_args, gp_regs[0]);
+ if (cif->bytes < sizeof(struct ia64_args))
+ cif->bytes = sizeof(struct ia64_args);
+
+ /* Set the return type flag. */
+ flags = cif->rtype->type;
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_LONGDOUBLE:
+ /* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision,
+ and encode quad precision as a two-word integer structure. */
+ if (LDBL_MANT_DIG != 64)
+ flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ size_t size = cif->rtype->size;
+ int hfa_type = hfa_element_type (cif->rtype, 0);
+
+ if (hfa_type != FFI_TYPE_VOID)
+ {
+ size_t nelts = size / hfa_type_size (hfa_type);
+ if (nelts <= 8)
+ flags = hfa_type | (size << 8);
+ }
+ else
+ {
+ if (size <= 32)
+ flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ cif->flags = flags;
+
+ return FFI_OK;
+}
+
+extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(), UINT64);
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ struct ia64_args *stack;
+ long i, avn, gpcount, fpcount;
+ ffi_type **p_arg;
+
+ FFI_ASSERT (cif->abi == FFI_UNIX);
+
+ /* If we have no spot for a return value, make one. */
+ if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID)
+ rvalue = alloca (cif->rtype->size);
+
+ /* Allocate the stack frame. */
+ stack = alloca (cif->bytes);
+
+ gpcount = fpcount = 0;
+ avn = cif->nargs;
+ for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i];
+ break;
+ case FFI_TYPE_UINT8:
+ stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i];
+ break;
+ case FFI_TYPE_SINT16:
+ stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i];
+ break;
+ case FFI_TYPE_UINT16:
+ stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i];
+ break;
+ case FFI_TYPE_SINT32:
+ stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i];
+ break;
+ case FFI_TYPE_UINT32:
+ stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
+ break;
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
+ break;
+
+ case FFI_TYPE_POINTER:
+ stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i];
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (gpcount < 8 && fpcount < 8)
+ stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]);
+ stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ if (gpcount < 8 && fpcount < 8)
+ stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]);
+ stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ if (gpcount & 1)
+ gpcount++;
+ if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
+ stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]);
+ memcpy (&stack->gp_regs[gpcount], avalue[i], 16);
+ gpcount += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ size_t size = (*p_arg)->size;
+ size_t align = (*p_arg)->alignment;
+ int hfa_type = hfa_element_type (*p_arg, 0);
+
+ FFI_ASSERT (align <= 16);
+ if (align == 16 && (gpcount & 1))
+ gpcount++;
+
+ if (hfa_type != FFI_TYPE_VOID)
+ {
+ size_t hfa_size = hfa_type_size (hfa_type);
+ size_t offset = 0;
+ size_t gp_offset = gpcount * 8;
+
+ while (fpcount < 8
+ && offset < size
+ && gp_offset < 8 * 8)
+ {
+ stf_spill (&stack->fp_regs[fpcount],
+ hfa_type_load (hfa_type, avalue[i] + offset));
+ offset += hfa_size;
+ gp_offset += hfa_size;
+ fpcount += 1;
+ }
+ }
+
+ memcpy (&stack->gp_regs[gpcount], avalue[i], size);
+ gpcount += (size + 7) / 8;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ ffi_call_unix (stack, rvalue, fn, cif->flags);
+}
+
+/* Closures represent a pair consisting of a function pointer, and
+ some user data. A closure is invoked by reinterpreting the closure
+ as a function pointer, and branching to it. Thus we can make an
+ interpreted function callable as a C function: We turn the
+ interpreter itself, together with a pointer specifying the
+ interpreted procedure, into a closure.
+
+ For IA64, function pointer are already pairs consisting of a code
+ pointer, and a gp pointer. The latter is needed to access global
+ variables. Here we set up such a pair as the first two words of
+ the closure (in the "trampoline" area), but we replace the gp
+ pointer with a pointer to the closure itself. We also add the real
+ gp pointer to the closure. This allows the function entry code to
+ both retrieve the user data, and to restire the correct gp pointer. */
+
+extern void ffi_closure_unix ();
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ /* The layout of a function descriptor. A C function pointer really
+ points to one of these. */
+ struct ia64_fd
+ {
+ UINT64 code_pointer;
+ UINT64 gp;
+ };
+
+ struct ffi_ia64_trampoline_struct
+ {
+ UINT64 code_pointer; /* Pointer to ffi_closure_unix. */
+ UINT64 fake_gp; /* Pointer to closure, installed as gp. */
+ UINT64 real_gp; /* Real gp value. */
+ };
+
+ struct ffi_ia64_trampoline_struct *tramp;
+ struct ia64_fd *fd;
+
+ FFI_ASSERT (cif->abi == FFI_UNIX);
+
+ tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp;
+ fd = (struct ia64_fd *)(void *)ffi_closure_unix;
+
+ tramp->code_pointer = fd->code_pointer;
+ tramp->real_gp = fd->gp;
+ tramp->fake_gp = (UINT64)(PTR64)closure;
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+
+UINT64
+ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
+ void *rvalue, void *r8)
+{
+ ffi_cif *cif;
+ void **avalue;
+ ffi_type **p_arg;
+ long i, avn, gpcount, fpcount;
+
+ cif = closure->cif;
+ avn = cif->nargs;
+ avalue = alloca (avn * sizeof (void *));
+
+ /* If the structure return value is passed in memory get that location
+ from r8 so as to pass the value directly back to the caller. */
+ if (cif->flags == FFI_TYPE_STRUCT)
+ rvalue = r8;
+
+ gpcount = fpcount = 0;
+ for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1);
+ break;
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2);
+ break;
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4);
+ break;
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ avalue[i] = &stack->gp_regs[gpcount++];
+ break;
+ case FFI_TYPE_POINTER:
+ avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*));
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (gpcount < 8 && fpcount < 8)
+ {
+ void *addr = &stack->fp_regs[fpcount++];
+ avalue[i] = addr;
+ *(float *)addr = ldf_fill (addr);
+ }
+ else
+ avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4);
+ gpcount++;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ if (gpcount < 8 && fpcount < 8)
+ {
+ void *addr = &stack->fp_regs[fpcount++];
+ avalue[i] = addr;
+ *(double *)addr = ldf_fill (addr);
+ }
+ else
+ avalue[i] = &stack->gp_regs[gpcount];
+ gpcount++;
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ if (gpcount & 1)
+ gpcount++;
+ if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
+ {
+ void *addr = &stack->fp_regs[fpcount++];
+ avalue[i] = addr;
+ *(__float80 *)addr = ldf_fill (addr);
+ }
+ else
+ avalue[i] = &stack->gp_regs[gpcount];
+ gpcount += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ size_t size = (*p_arg)->size;
+ size_t align = (*p_arg)->alignment;
+ int hfa_type = hfa_element_type (*p_arg, 0);
+
+ FFI_ASSERT (align <= 16);
+ if (align == 16 && (gpcount & 1))
+ gpcount++;
+
+ if (hfa_type != FFI_TYPE_VOID)
+ {
+ size_t hfa_size = hfa_type_size (hfa_type);
+ size_t offset = 0;
+ size_t gp_offset = gpcount * 8;
+ void *addr = alloca (size);
+
+ avalue[i] = addr;
+
+ while (fpcount < 8
+ && offset < size
+ && gp_offset < 8 * 8)
+ {
+ hfa_type_store (hfa_type, addr + offset,
+ ldf_fill (&stack->fp_regs[fpcount]));
+ offset += hfa_size;
+ gp_offset += hfa_size;
+ fpcount += 1;
+ }
+
+ if (offset < size)
+ memcpy (addr + offset, (char *)stack->gp_regs + gp_offset,
+ size - offset);
+ }
+ else
+ avalue[i] = &stack->gp_regs[gpcount];
+
+ gpcount += (size + 7) / 8;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ closure->fun (cif, rvalue, avalue, closure->user_data);
+
+ return cif->flags;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffitarget.h
new file mode 100644
index 000000000..0d820b3a5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffitarget.h
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for IA-64.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long long ffi_arg;
+typedef signed long long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_UNIX, /* Linux and all Unix variants use the same conventions */
+ FFI_DEFAULT_ABI = FFI_UNIX,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
+ /* can be interpreted as a C function */
+ /* descriptor: */
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ia64_flags.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ia64_flags.h
new file mode 100644
index 000000000..1dd6d7e3f
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ia64_flags.h
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------
+ ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company
+
+ IA64/unix Foreign Function Interface
+
+ Original author: Hans Boehm, HP Labs
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+/* "Type" codes used between assembly and C. When used as a part of
+ a cfi->flags value, the low byte will be these extra type codes,
+ and bits 8-31 will be the actual size of the type. */
+
+/* Small structures containing N words in integer registers. */
+#define FFI_IA64_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 1)
+
+/* Homogeneous Floating Point Aggregates (HFAs) which are returned
+ in FP registers. */
+#define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2)
+#define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3)
+#define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4)
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/unix.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/unix.S
new file mode 100644
index 000000000..45dabb74c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/unix.S
@@ -0,0 +1,555 @@
+/* -----------------------------------------------------------------------
+ unix.S - Copyright (c) 1998 Red Hat, Inc.
+ Copyright (c) 2000 Hewlett Packard Company
+
+ IA64/unix Foreign Function Interface
+
+ Primary author: Hans Boehm, HP Labs
+
+ Loosely modeled on Cygnus code for other platforms.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include "ia64_flags.h"
+
+ .pred.safe_across_calls p1-p5,p16-p63
+.text
+
+/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
+ void (*fn)(), int flags);
+ */
+
+ .align 16
+ .global ffi_call_unix
+ .proc ffi_call_unix
+ffi_call_unix:
+ .prologue
+ /* Bit o trickiness. We actually share a stack frame with ffi_call.
+ Rely on the fact that ffi_call uses a vframe and don't bother
+ tracking one here at all. */
+ .fframe 0
+ .save ar.pfs, r36 // loc0
+ alloc loc0 = ar.pfs, 4, 3, 8, 0
+ .save rp, loc1
+ mov loc1 = b0
+ .body
+ add r16 = 16, in0
+ mov loc2 = gp
+ mov r8 = in1
+ ;;
+
+ /* Load up all of the argument registers. */
+ ldf.fill f8 = [in0], 32
+ ldf.fill f9 = [r16], 32
+ ;;
+ ldf.fill f10 = [in0], 32
+ ldf.fill f11 = [r16], 32
+ ;;
+ ldf.fill f12 = [in0], 32
+ ldf.fill f13 = [r16], 32
+ ;;
+ ldf.fill f14 = [in0], 32
+ ldf.fill f15 = [r16], 24
+ ;;
+ ld8 out0 = [in0], 16
+ ld8 out1 = [r16], 16
+ ;;
+ ld8 out2 = [in0], 16
+ ld8 out3 = [r16], 16
+ ;;
+ ld8 out4 = [in0], 16
+ ld8 out5 = [r16], 16
+ ;;
+ ld8 out6 = [in0]
+ ld8 out7 = [r16]
+ ;;
+
+ /* Deallocate the register save area from the stack frame. */
+ mov sp = in0
+
+ /* Call the target function. */
+ ld8 r16 = [in2], 8
+ ;;
+ ld8 gp = [in2]
+ mov b6 = r16
+ br.call.sptk.many b0 = b6
+ ;;
+
+ /* Dispatch to handle return value. */
+ mov gp = loc2
+ zxt1 r16 = in3
+ ;;
+ mov ar.pfs = loc0
+ addl r18 = @ltoffx(.Lst_table), gp
+ ;;
+ ld8.mov r18 = [r18], .Lst_table
+ mov b0 = loc1
+ ;;
+ shladd r18 = r16, 3, r18
+ ;;
+ ld8 r17 = [r18]
+ shr in3 = in3, 8
+ ;;
+ add r17 = r17, r18
+ ;;
+ mov b6 = r17
+ br b6
+ ;;
+
+.Lst_void:
+ br.ret.sptk.many b0
+ ;;
+.Lst_uint8:
+ zxt1 r8 = r8
+ ;;
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_sint8:
+ sxt1 r8 = r8
+ ;;
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_uint16:
+ zxt2 r8 = r8
+ ;;
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_sint16:
+ sxt2 r8 = r8
+ ;;
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_uint32:
+ zxt4 r8 = r8
+ ;;
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_sint32:
+ sxt4 r8 = r8
+ ;;
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_int64:
+ st8 [in1] = r8
+ br.ret.sptk.many b0
+ ;;
+.Lst_float:
+ stfs [in1] = f8
+ br.ret.sptk.many b0
+ ;;
+.Lst_double:
+ stfd [in1] = f8
+ br.ret.sptk.many b0
+ ;;
+.Lst_ldouble:
+ stfe [in1] = f8
+ br.ret.sptk.many b0
+ ;;
+
+.Lst_small_struct:
+ add sp = -16, sp
+ cmp.lt p6, p0 = 8, in3
+ cmp.lt p7, p0 = 16, in3
+ cmp.lt p8, p0 = 24, in3
+ ;;
+ add r16 = 8, sp
+ add r17 = 16, sp
+ add r18 = 24, sp
+ ;;
+ st8 [sp] = r8
+(p6) st8 [r16] = r9
+ mov out0 = in1
+(p7) st8 [r17] = r10
+(p8) st8 [r18] = r11
+ mov out1 = sp
+ mov out2 = in3
+ br.call.sptk.many b0 = memcpy#
+ ;;
+ mov ar.pfs = loc0
+ mov b0 = loc1
+ mov gp = loc2
+ br.ret.sptk.many b0
+
+.Lst_hfa_float:
+ add r16 = 4, in1
+ cmp.lt p6, p0 = 4, in3
+ ;;
+ stfs [in1] = f8, 8
+(p6) stfs [r16] = f9, 8
+ cmp.lt p7, p0 = 8, in3
+ cmp.lt p8, p0 = 12, in3
+ ;;
+(p7) stfs [in1] = f10, 8
+(p8) stfs [r16] = f11, 8
+ cmp.lt p9, p0 = 16, in3
+ cmp.lt p10, p0 = 20, in3
+ ;;
+(p9) stfs [in1] = f12, 8
+(p10) stfs [r16] = f13, 8
+ cmp.lt p6, p0 = 24, in3
+ cmp.lt p7, p0 = 28, in3
+ ;;
+(p6) stfs [in1] = f14
+(p7) stfs [r16] = f15
+ br.ret.sptk.many b0
+ ;;
+
+.Lst_hfa_double:
+ add r16 = 8, in1
+ cmp.lt p6, p0 = 8, in3
+ ;;
+ stfd [in1] = f8, 16
+(p6) stfd [r16] = f9, 16
+ cmp.lt p7, p0 = 16, in3
+ cmp.lt p8, p0 = 24, in3
+ ;;
+(p7) stfd [in1] = f10, 16
+(p8) stfd [r16] = f11, 16
+ cmp.lt p9, p0 = 32, in3
+ cmp.lt p10, p0 = 40, in3
+ ;;
+(p9) stfd [in1] = f12, 16
+(p10) stfd [r16] = f13, 16
+ cmp.lt p6, p0 = 48, in3
+ cmp.lt p7, p0 = 56, in3
+ ;;
+(p6) stfd [in1] = f14
+(p7) stfd [r16] = f15
+ br.ret.sptk.many b0
+ ;;
+
+.Lst_hfa_ldouble:
+ add r16 = 16, in1
+ cmp.lt p6, p0 = 16, in3
+ ;;
+ stfe [in1] = f8, 32
+(p6) stfe [r16] = f9, 32
+ cmp.lt p7, p0 = 32, in3
+ cmp.lt p8, p0 = 48, in3
+ ;;
+(p7) stfe [in1] = f10, 32
+(p8) stfe [r16] = f11, 32
+ cmp.lt p9, p0 = 64, in3
+ cmp.lt p10, p0 = 80, in3
+ ;;
+(p9) stfe [in1] = f12, 32
+(p10) stfe [r16] = f13, 32
+ cmp.lt p6, p0 = 96, in3
+ cmp.lt p7, p0 = 112, in3
+ ;;
+(p6) stfe [in1] = f14
+(p7) stfe [r16] = f15
+ br.ret.sptk.many b0
+ ;;
+
+ .endp ffi_call_unix
+
+ .align 16
+ .global ffi_closure_unix
+ .proc ffi_closure_unix
+
+#define FRAME_SIZE (8*16 + 8*8 + 8*16)
+
+ffi_closure_unix:
+ .prologue
+ .save ar.pfs, r40 // loc0
+ alloc loc0 = ar.pfs, 8, 4, 4, 0
+ .fframe FRAME_SIZE
+ add r12 = -FRAME_SIZE, r12
+ .save rp, loc1
+ mov loc1 = b0
+ .save ar.unat, loc2
+ mov loc2 = ar.unat
+ .body
+
+ /* Retrieve closure pointer and real gp. */
+#ifdef _ILP32
+ addp4 out0 = 0, gp
+ addp4 gp = 16, gp
+#else
+ mov out0 = gp
+ add gp = 16, gp
+#endif
+ ;;
+ ld8 gp = [gp]
+
+ /* Spill all of the possible argument registers. */
+ add r16 = 16 + 8*16, sp
+ add r17 = 16 + 8*16 + 16, sp
+ ;;
+ stf.spill [r16] = f8, 32
+ stf.spill [r17] = f9, 32
+ mov loc3 = gp
+ ;;
+ stf.spill [r16] = f10, 32
+ stf.spill [r17] = f11, 32
+ ;;
+ stf.spill [r16] = f12, 32
+ stf.spill [r17] = f13, 32
+ ;;
+ stf.spill [r16] = f14, 32
+ stf.spill [r17] = f15, 24
+ ;;
+ .mem.offset 0, 0
+ st8.spill [r16] = in0, 16
+ .mem.offset 8, 0
+ st8.spill [r17] = in1, 16
+ add out1 = 16 + 8*16, sp
+ ;;
+ .mem.offset 0, 0
+ st8.spill [r16] = in2, 16
+ .mem.offset 8, 0
+ st8.spill [r17] = in3, 16
+ add out2 = 16, sp
+ ;;
+ .mem.offset 0, 0
+ st8.spill [r16] = in4, 16
+ .mem.offset 8, 0
+ st8.spill [r17] = in5, 16
+ mov out3 = r8
+ ;;
+ .mem.offset 0, 0
+ st8.spill [r16] = in6
+ .mem.offset 8, 0
+ st8.spill [r17] = in7
+
+ /* Invoke ffi_closure_unix_inner for the hard work. */
+ br.call.sptk.many b0 = ffi_closure_unix_inner
+ ;;
+
+ /* Dispatch to handle return value. */
+ mov gp = loc3
+ zxt1 r16 = r8
+ ;;
+ addl r18 = @ltoffx(.Lld_table), gp
+ mov ar.pfs = loc0
+ ;;
+ ld8.mov r18 = [r18], .Lld_table
+ mov b0 = loc1
+ ;;
+ shladd r18 = r16, 3, r18
+ mov ar.unat = loc2
+ ;;
+ ld8 r17 = [r18]
+ shr r8 = r8, 8
+ ;;
+ add r17 = r17, r18
+ add r16 = 16, sp
+ ;;
+ mov b6 = r17
+ br b6
+ ;;
+ .label_state 1
+
+.Lld_void:
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+.Lld_int:
+ .body
+ .copy_state 1
+ ld8 r8 = [r16]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+.Lld_float:
+ .body
+ .copy_state 1
+ ldfs f8 = [r16]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+.Lld_double:
+ .body
+ .copy_state 1
+ ldfd f8 = [r16]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+.Lld_ldouble:
+ .body
+ .copy_state 1
+ ldfe f8 = [r16]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+
+.Lld_small_struct:
+ .body
+ .copy_state 1
+ add r17 = 8, r16
+ cmp.lt p6, p0 = 8, r8
+ cmp.lt p7, p0 = 16, r8
+ cmp.lt p8, p0 = 24, r8
+ ;;
+ ld8 r8 = [r16], 16
+(p6) ld8 r9 = [r17], 16
+ ;;
+(p7) ld8 r10 = [r16]
+(p8) ld8 r11 = [r17]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+
+.Lld_hfa_float:
+ .body
+ .copy_state 1
+ add r17 = 4, r16
+ cmp.lt p6, p0 = 4, r8
+ ;;
+ ldfs f8 = [r16], 8
+(p6) ldfs f9 = [r17], 8
+ cmp.lt p7, p0 = 8, r8
+ cmp.lt p8, p0 = 12, r8
+ ;;
+(p7) ldfs f10 = [r16], 8
+(p8) ldfs f11 = [r17], 8
+ cmp.lt p9, p0 = 16, r8
+ cmp.lt p10, p0 = 20, r8
+ ;;
+(p9) ldfs f12 = [r16], 8
+(p10) ldfs f13 = [r17], 8
+ cmp.lt p6, p0 = 24, r8
+ cmp.lt p7, p0 = 28, r8
+ ;;
+(p6) ldfs f14 = [r16]
+(p7) ldfs f15 = [r17]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+
+.Lld_hfa_double:
+ .body
+ .copy_state 1
+ add r17 = 8, r16
+ cmp.lt p6, p0 = 8, r8
+ ;;
+ ldfd f8 = [r16], 16
+(p6) ldfd f9 = [r17], 16
+ cmp.lt p7, p0 = 16, r8
+ cmp.lt p8, p0 = 24, r8
+ ;;
+(p7) ldfd f10 = [r16], 16
+(p8) ldfd f11 = [r17], 16
+ cmp.lt p9, p0 = 32, r8
+ cmp.lt p10, p0 = 40, r8
+ ;;
+(p9) ldfd f12 = [r16], 16
+(p10) ldfd f13 = [r17], 16
+ cmp.lt p6, p0 = 48, r8
+ cmp.lt p7, p0 = 56, r8
+ ;;
+(p6) ldfd f14 = [r16]
+(p7) ldfd f15 = [r17]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+
+.Lld_hfa_ldouble:
+ .body
+ .copy_state 1
+ add r17 = 16, r16
+ cmp.lt p6, p0 = 16, r8
+ ;;
+ ldfe f8 = [r16], 32
+(p6) ldfe f9 = [r17], 32
+ cmp.lt p7, p0 = 32, r8
+ cmp.lt p8, p0 = 48, r8
+ ;;
+(p7) ldfe f10 = [r16], 32
+(p8) ldfe f11 = [r17], 32
+ cmp.lt p9, p0 = 64, r8
+ cmp.lt p10, p0 = 80, r8
+ ;;
+(p9) ldfe f12 = [r16], 32
+(p10) ldfe f13 = [r17], 32
+ cmp.lt p6, p0 = 96, r8
+ cmp.lt p7, p0 = 112, r8
+ ;;
+(p6) ldfe f14 = [r16]
+(p7) ldfe f15 = [r17]
+ .restore sp
+ add sp = FRAME_SIZE, sp
+ br.ret.sptk.many b0
+ ;;
+
+ .endp ffi_closure_unix
+
+ .section .rodata
+ .align 8
+.Lst_table:
+ data8 @pcrel(.Lst_void) // FFI_TYPE_VOID
+ data8 @pcrel(.Lst_sint32) // FFI_TYPE_INT
+ data8 @pcrel(.Lst_float) // FFI_TYPE_FLOAT
+ data8 @pcrel(.Lst_double) // FFI_TYPE_DOUBLE
+ data8 @pcrel(.Lst_ldouble) // FFI_TYPE_LONGDOUBLE
+ data8 @pcrel(.Lst_uint8) // FFI_TYPE_UINT8
+ data8 @pcrel(.Lst_sint8) // FFI_TYPE_SINT8
+ data8 @pcrel(.Lst_uint16) // FFI_TYPE_UINT16
+ data8 @pcrel(.Lst_sint16) // FFI_TYPE_SINT16
+ data8 @pcrel(.Lst_uint32) // FFI_TYPE_UINT32
+ data8 @pcrel(.Lst_sint32) // FFI_TYPE_SINT32
+ data8 @pcrel(.Lst_int64) // FFI_TYPE_UINT64
+ data8 @pcrel(.Lst_int64) // FFI_TYPE_SINT64
+ data8 @pcrel(.Lst_void) // FFI_TYPE_STRUCT
+ data8 @pcrel(.Lst_int64) // FFI_TYPE_POINTER
+ data8 @pcrel(.Lst_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT
+ data8 @pcrel(.Lst_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT
+ data8 @pcrel(.Lst_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE
+ data8 @pcrel(.Lst_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE
+
+.Lld_table:
+ data8 @pcrel(.Lld_void) // FFI_TYPE_VOID
+ data8 @pcrel(.Lld_int) // FFI_TYPE_INT
+ data8 @pcrel(.Lld_float) // FFI_TYPE_FLOAT
+ data8 @pcrel(.Lld_double) // FFI_TYPE_DOUBLE
+ data8 @pcrel(.Lld_ldouble) // FFI_TYPE_LONGDOUBLE
+ data8 @pcrel(.Lld_int) // FFI_TYPE_UINT8
+ data8 @pcrel(.Lld_int) // FFI_TYPE_SINT8
+ data8 @pcrel(.Lld_int) // FFI_TYPE_UINT16
+ data8 @pcrel(.Lld_int) // FFI_TYPE_SINT16
+ data8 @pcrel(.Lld_int) // FFI_TYPE_UINT32
+ data8 @pcrel(.Lld_int) // FFI_TYPE_SINT32
+ data8 @pcrel(.Lld_int) // FFI_TYPE_UINT64
+ data8 @pcrel(.Lld_int) // FFI_TYPE_SINT64
+ data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT
+ data8 @pcrel(.Lld_int) // FFI_TYPE_POINTER
+ data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT
+ data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT
+ data8 @pcrel(.Lld_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE
+ data8 @pcrel(.Lld_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffi.c
new file mode 100644
index 000000000..9a3b55095
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffi.c
@@ -0,0 +1,247 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2004 Renesas Technology
+
+ M32R Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack
+ space has been allocated for the function's arguments. */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ unsigned int i;
+ int tmp;
+ unsigned int avn;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ tmp = 0;
+ argp = stack;
+
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 8)
+ {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0) && (avn != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary. */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp)
+ argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+ if (avn != 0)
+ {
+ avn--;
+ z = (*p_arg)->size;
+ if (z < sizeof (int))
+ {
+ z = sizeof (int);
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ z = (*p_arg)->size;
+ if ((*p_arg)->alignment != 1)
+ memcpy (argp, *p_argv, z);
+ else
+ memcpy (argp + 4 - z, *p_argv, z);
+ z = sizeof (int);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof (int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
+ {
+ if (z > 8)
+ {
+ *(unsigned int *) argp = (unsigned int)(void *)(* p_argv);
+ z = sizeof(void *);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ z = 8;
+ }
+ }
+ else
+ {
+ /* Double or long long 64bit. */
+ memcpy (argp, *p_argv, z);
+ }
+ }
+ p_argv++;
+ argp += z;
+ }
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing. */
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag. */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size <= 4)
+ cif->flags = FFI_TYPE_INT;
+
+ else if (cif->rtype->size <= 8)
+ cif->flags = FFI_TYPE_DOUBLE;
+
+ else
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = FFI_TYPE_DOUBLE;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have
+ a return value address then we need to make one. */
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca (cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ int size = cif->rtype->size;
+ int align = cif->rtype->alignment;
+
+ if (size < 4)
+ {
+ if (align == 1)
+ *(unsigned long *)(ecif.rvalue) <<= (4 - size) * 8;
+ }
+ else if (4 < size && size < 8)
+ {
+ if (align == 1)
+ {
+ memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
+ }
+ else if (align == 2)
+ {
+ if (size & 1)
+ size += 1;
+
+ if (size != 8)
+ memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
+ }
+ }
+ }
+ /*@=usedef@*/
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffitarget.h
new file mode 100644
index 000000000..6a761f659
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffitarget.h
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 2004 Renesas Technology.
+ Target configuration macros for M32R.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi
+ {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+ } ffi_abi;
+#endif
+
+#define FFI_CLOSURES 0
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/sysv.S
new file mode 100644
index 000000000..06b75c226
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/sysv.S
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2004 Renesas Technology
+
+ M32R Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x):
+#endif
+
+.text
+
+ /* R0: ffi_prep_args */
+ /* R1: &ecif */
+ /* R2: cif->bytes */
+ /* R3: fig->flags */
+ /* sp+0: ecif.rvalue */
+ /* sp+4: fn */
+
+ /* This assumes we are using gas. */
+ENTRY(ffi_call_SYSV)
+ /* Save registers. */
+ push fp
+ push lr
+ push r3
+ push r2
+ push r1
+ push r0
+ mv fp, sp
+
+ /* Make room for all of the new args. */
+ sub sp, r2
+
+ /* Place all of the ffi_prep_args in position. */
+ mv lr, r0
+ mv r0, sp
+ /* R1 already set. */
+
+ /* And call. */
+ jl lr
+
+ /* Move first 4 parameters in registers... */
+ ld r0, @(0,sp)
+ ld r1, @(4,sp)
+ ld r2, @(8,sp)
+ ld r3, @(12,sp)
+
+ /* ...and adjust the stack. */
+ ld lr, @(8,fp)
+ cmpi lr, #16
+ bc adjust_stack
+ ldi lr, #16
+adjust_stack:
+ add sp, lr
+
+ /* Call the function. */
+ ld lr, @(28,fp)
+ jl lr
+
+ /* Remove the space we pushed for the args. */
+ mv sp, fp
+
+ /* Load R2 with the pointer to storage for the return value. */
+ ld r2, @(24,sp)
+
+ /* Load R3 with the return type code. */
+ ld r3, @(12,sp)
+
+ /* If the return value pointer is NULL, assume no return value. */
+ beqz r2, epilogue
+
+ /* Return INT. */
+ ldi r4, #FFI_TYPE_INT
+ bne r3, r4, return_double
+ st r0, @r2
+ bra epilogue
+
+return_double:
+ /* Return DOUBLE or LONGDOUBLE. */
+ ldi r4, #FFI_TYPE_DOUBLE
+ bne r3, r4, epilogue
+ st r0, @r2
+ st r1, @(4,r2)
+
+epilogue:
+ pop r0
+ pop r1
+ pop r2
+ pop r3
+ pop lr
+ pop fp
+ jmp lr
+
+.ffi_call_SYSV_end:
+ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffi.c
new file mode 100644
index 000000000..55f3a988b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffi.c
@@ -0,0 +1,176 @@
+/* -----------------------------------------------------------------------
+ ffi.c
+
+ m68k Foreign Function Interface
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space has
+ been allocated for the function's arguments. */
+
+static void *
+ffi_prep_args (void *stack, extended_cif *ecif)
+{
+ unsigned int i;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+ void *struct_value_ptr;
+
+ argp = stack;
+
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+ && ecif->cif->rtype->size > 8)
+ struct_value_ptr = ecif->rvalue;
+ else
+ struct_value_ptr = NULL;
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i != 0;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary. */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp)
+ argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+ z = (*p_arg)->size;
+ if (z < sizeof (int))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy (argp + sizeof (int) - z, *p_argv, z);
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ }
+ z = sizeof (int);
+ }
+ else
+ memcpy (argp, *p_argv, z);
+ p_argv++;
+ argp += z;
+ }
+
+ return struct_value_ptr;
+}
+
+#define CIF_FLAGS_INT 1
+#define CIF_FLAGS_DINT 2
+#define CIF_FLAGS_FLOAT 4
+#define CIF_FLAGS_DOUBLE 8
+#define CIF_FLAGS_LDOUBLE 16
+#define CIF_FLAGS_POINTER 32
+#define CIF_FLAGS_STRUCT 64
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ cif->flags = 0;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size > 4 && cif->rtype->size <= 8)
+ cif->flags = CIF_FLAGS_DINT;
+ else if (cif->rtype->size <= 4)
+ cif->flags = CIF_FLAGS_STRUCT;
+ else
+ cif->flags = 0;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ cif->flags = CIF_FLAGS_FLOAT;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ cif->flags = CIF_FLAGS_DOUBLE;
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = CIF_FLAGS_LDOUBLE;
+ break;
+
+ case FFI_TYPE_POINTER:
+ cif->flags = CIF_FLAGS_POINTER;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = CIF_FLAGS_DINT;
+ break;
+
+ default:
+ cif->flags = CIF_FLAGS_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
+ extended_cif *,
+ unsigned, unsigned, unsigned,
+ void *, void (*fn) ());
+
+void
+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return value
+ address then we need to make one. */
+
+ if (rvalue == NULL
+ && cif->rtype->type == FFI_TYPE_STRUCT
+ && cif->rtype->size > 8)
+ ecif.rvalue = alloca (cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, cif->rtype->size * 8,
+ ecif.rvalue, fn);
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffitarget.h
new file mode 100644
index 000000000..aca7facc5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffitarget.h
@@ -0,0 +1,47 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for Motorola 68K.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 0
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/sysv.S
new file mode 100644
index 000000000..d019a377e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/sysv.S
@@ -0,0 +1,97 @@
+/* -----------------------------------------------------------------------
+ sysv.S
+
+ m68k Foreign Function Interface
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .text
+
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+ link %fp,#0
+ move.l %d2,-(%sp)
+
+ | Make room for all of the new args.
+ sub.l 16(%fp),%sp
+
+ | Call ffi_prep_args
+ move.l 12(%fp),-(%sp)
+ pea 4(%sp)
+ move.l 8(%fp),%a0
+ jsr (%a0)
+ addq.l #8,%sp
+
+ | Pass pointer to struct value, if any
+ move.l %a0,%a1
+
+ | Call the function
+ move.l 32(%fp),%a0
+ jsr (%a0)
+
+ | Remove the space we pushed for the args
+ add.l 16(%fp),%sp
+
+ | Load the pointer to storage for the return value
+ move.l 28(%fp),%a1
+
+ | Load the return type code
+ move.l 20(%fp),%d2
+
+ | If the return value pointer is NULL, assume no return value.
+ tst.l %a1
+ jbeq noretval
+
+ btst #0,%d2
+ jbeq retlongint
+ move.l %d0,(%a1)
+ jbra epilogue
+
+retlongint:
+ btst #1,%d2
+ jbeq retfloat
+ move.l %d0,(%a1)
+ move.l %d1,4(%a1)
+ jbra epilogue
+
+retfloat:
+ btst #2,%d2
+ jbeq retdouble
+ fmove.s %fp0,(%a1)
+ jbra epilogue
+
+retdouble:
+ btst #3,%d2
+ jbeq retlongdouble
+ fmove.d %fp0,(%a1)
+ jbra epilogue
+
+retlongdouble:
+ btst #4,%d2
+ jbeq retpointer
+ fmove.x %fp0,(%a1)
+ jbra epilogue
+
+retpointer:
+ btst #5,%d2
+ jbeq retstruct
+ move.l %a0,(%a1)
+ jbra epilogue
+
+retstruct:
+ btst #6,%d2
+ jbeq noretval
+ move.l 24(%fp),%d2
+ bfins %d0,(%a1){#0,%d2}
+
+noretval:
+epilogue:
+ move.l (%sp)+,%d2
+ unlk %a6
+ rts
+ .size ffi_call_SYSV,.-ffi_call_SYSV
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffi.c
new file mode 100644
index 000000000..73bc95218
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffi.c
@@ -0,0 +1,648 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996 Red Hat, Inc.
+
+ MIPS Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <sys/cachectl.h>
+
+#if _MIPS_SIM == _ABIN32
+#define FIX_ARGP \
+FFI_ASSERT(argp <= &stack[bytes]); \
+if (argp == &stack[bytes]) \
+{ \
+ argp = stack; \
+ ffi_stop_here(); \
+}
+#else
+#define FIX_ARGP
+#endif
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+static void ffi_prep_args(char *stack,
+ extended_cif *ecif,
+ int bytes,
+ int flags)
+{
+ int i;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+#if _MIPS_SIM == _ABIN32
+ /* If more than 8 double words are used, the remainder go
+ on the stack. We reorder stuff on the stack here to
+ support this easily. */
+ if (bytes > 8 * sizeof(ffi_arg))
+ argp = &stack[bytes - (8 * sizeof(ffi_arg))];
+ else
+ argp = stack;
+#else
+ argp = stack;
+#endif
+
+ memset(stack, 0, bytes);
+
+#if _MIPS_SIM == _ABIN32
+ if ( ecif->cif->rstruct_flag != 0 )
+#else
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
+#endif
+ {
+ *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
+ argp += sizeof(ffi_arg);
+ FIX_ARGP;
+ }
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+ {
+ size_t z;
+ unsigned int a;
+
+ /* Align if necessary. */
+ a = (*p_arg)->alignment;
+ if (a < sizeof(ffi_arg))
+ a = sizeof(ffi_arg);
+
+ if ((a - 1) & (unsigned int) argp)
+ {
+ argp = (char *) ALIGN(argp, a);
+ FIX_ARGP;
+ }
+
+ z = (*p_arg)->size;
+ if (z <= sizeof(ffi_arg))
+ {
+ z = sizeof(ffi_arg);
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
+ break;
+
+ /* This can only happen with 64bit slots. */
+ case FFI_TYPE_FLOAT:
+ *(float *) argp = *(float *)(* p_argv);
+ break;
+
+ /* Handle small structures. */
+ case FFI_TYPE_STRUCT:
+ default:
+ memcpy(argp, *p_argv, (*p_arg)->size);
+ break;
+ }
+ }
+ else
+ {
+#if _MIPS_SIM == _ABIO32
+ memcpy(argp, *p_argv, z);
+#else
+ {
+ unsigned end = (unsigned) argp+z;
+ unsigned cap = (unsigned) stack+bytes;
+
+ /* Check if the data will fit within the register space.
+ Handle it if it doesn't. */
+
+ if (end <= cap)
+ memcpy(argp, *p_argv, z);
+ else
+ {
+ unsigned portion = end - cap;
+
+ memcpy(argp, *p_argv, portion);
+ argp = stack;
+ memcpy(argp,
+ (void*)((unsigned)(*p_argv)+portion), z - portion);
+ }
+ }
+#endif
+ }
+ p_argv++;
+ argp += z;
+ FIX_ARGP;
+ }
+}
+
+#if _MIPS_SIM == _ABIN32
+
+/* The n32 spec says that if "a chunk consists solely of a double
+ float field (but not a double, which is part of a union), it
+ is passed in a floating point register. Any other chunk is
+ passed in an integer register". This code traverses structure
+ definitions and generates the appropriate flags. */
+
+unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
+{
+ unsigned flags = 0;
+ unsigned index = 0;
+
+ ffi_type *e;
+
+ while (e = arg->elements[index])
+ {
+ if (e->type == FFI_TYPE_DOUBLE)
+ {
+ flags += (FFI_TYPE_DOUBLE << *shift);
+ *shift += FFI_FLAG_BITS;
+ }
+ else if (e->type == FFI_TYPE_STRUCT)
+ flags += calc_n32_struct_flags(e, shift);
+ else
+ *shift += FFI_FLAG_BITS;
+
+ index++;
+ }
+
+ return flags;
+}
+
+unsigned calc_n32_return_struct_flags(ffi_type *arg)
+{
+ unsigned flags = 0;
+ unsigned index = 0;
+ unsigned small = FFI_TYPE_SMALLSTRUCT;
+ ffi_type *e;
+
+ /* Returning structures under n32 is a tricky thing.
+ A struct with only one or two floating point fields
+ is returned in $f0 (and $f2 if necessary). Any other
+ struct results at most 128 bits are returned in $2
+ (the first 64 bits) and $3 (remainder, if necessary).
+ Larger structs are handled normally. */
+
+ if (arg->size > 16)
+ return 0;
+
+ if (arg->size > 8)
+ small = FFI_TYPE_SMALLSTRUCT2;
+
+ e = arg->elements[0];
+ if (e->type == FFI_TYPE_DOUBLE)
+ flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
+ else if (e->type == FFI_TYPE_FLOAT)
+ flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
+
+ if (flags && (e = arg->elements[1]))
+ {
+ if (e->type == FFI_TYPE_DOUBLE)
+ flags += FFI_TYPE_DOUBLE;
+ else if (e->type == FFI_TYPE_FLOAT)
+ flags += FFI_TYPE_FLOAT;
+ else
+ return small;
+
+ if (flags && (arg->elements[2]))
+ {
+ /* There are three arguments and the first two are
+ floats! This must be passed the old way. */
+ return small;
+ }
+ }
+ else
+ if (!flags)
+ return small;
+
+ return flags;
+}
+
+#endif
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ cif->flags = 0;
+
+#if _MIPS_SIM == _ABIO32
+ /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
+ * does not have special handling for floating point args.
+ */
+
+ if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
+ {
+ if (cif->nargs > 0)
+ {
+ switch ((cif->arg_types)[0]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += (cif->arg_types)[0]->type;
+ break;
+
+ default:
+ break;
+ }
+
+ if (cif->nargs > 1)
+ {
+ /* Only handle the second argument if the first
+ is a float or double. */
+ if (cif->flags)
+ {
+ switch ((cif->arg_types)[1]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Set the return type flag */
+
+ if (cif->abi == FFI_O32_SOFT_FLOAT)
+ {
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ default:
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+ break;
+ }
+ }
+ else
+ {
+ /* FFI_O32 */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
+ break;
+
+ default:
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+ break;
+ }
+ }
+#endif
+
+#if _MIPS_SIM == _ABIN32
+ /* Set the flags necessary for N32 processing */
+ {
+ unsigned shift = 0;
+ unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
+ unsigned index = 0;
+
+ unsigned struct_flags = 0;
+
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ struct_flags = calc_n32_return_struct_flags(cif->rtype);
+
+ if (struct_flags == 0)
+ {
+ /* This means that the structure is being passed as
+ a hidden argument */
+
+ shift = FFI_FLAG_BITS;
+ count = (cif->nargs < 7) ? cif->nargs : 7;
+
+ cif->rstruct_flag = !0;
+ }
+ else
+ cif->rstruct_flag = 0;
+ }
+ else
+ cif->rstruct_flag = 0;
+
+ while (count-- > 0)
+ {
+ switch ((cif->arg_types)[index]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += ((cif->arg_types)[index]->type << shift);
+ shift += FFI_FLAG_BITS;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
+ &shift);
+ break;
+
+ default:
+ shift += FFI_FLAG_BITS;
+ }
+
+ index++;
+ }
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_STRUCT:
+ {
+ if (struct_flags == 0)
+ {
+ /* The structure is returned through a hidden
+ first argument. Do nothing, 'cause FFI_TYPE_VOID
+ is 0 */
+ }
+ else
+ {
+ /* The structure is returned via some tricky
+ mechanism */
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+ cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
+ }
+ break;
+ }
+
+ case FFI_TYPE_VOID:
+ /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
+ break;
+
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
+ break;
+
+ default:
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+ break;
+ }
+ }
+#endif
+
+ return FFI_OK;
+}
+
+/* Low level routine for calling O32 functions */
+extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
+ extended_cif *, unsigned,
+ unsigned, unsigned *, void (*)());
+
+/* Low level routine for calling N32 functions */
+extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
+ extended_cif *, unsigned,
+ unsigned, unsigned *, void (*)());
+
+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ ecif.rvalue = alloca(cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+#if _MIPS_SIM == _ABIO32
+ case FFI_O32:
+ case FFI_O32_SOFT_FLOAT:
+ ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+#endif
+
+#if _MIPS_SIM == _ABIN32
+ case FFI_N32:
+ ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+#endif
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+#if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */
+#if defined(FFI_MIPS_O32)
+extern void ffi_closure_O32(void);
+#endif /* FFI_MIPS_O32 */
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+ unsigned int fn;
+ unsigned int ctx = (unsigned int) closure;
+
+#if defined(FFI_MIPS_O32)
+ FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
+ fn = (unsigned int) ffi_closure_O32;
+#else /* FFI_MIPS_N32 */
+ FFI_ASSERT(cif->abi == FFI_N32);
+ FFI_ASSERT(!"not implemented");
+#endif /* FFI_MIPS_O32 */
+
+ tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */
+ tramp[1] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */
+ tramp[2] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */
+ tramp[3] = 0x03200008; /* jr $25 */
+ tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* XXX this is available on Linux, but anything else? */
+ cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
+
+ return FFI_OK;
+}
+
+/*
+ * Decodes the arguments to a function, which will be stored on the
+ * stack. AR is the pointer to the beginning of the integer arguments
+ * (and, depending upon the arguments, some floating-point arguments
+ * as well). FPR is a pointer to the area where floating point
+ * registers have been saved, if any.
+ *
+ * RVALUE is the location where the function return value will be
+ * stored. CLOSURE is the prepared closure to invoke.
+ *
+ * This function should only be called from assembly, which is in
+ * turn called from a trampoline.
+ *
+ * Returns the function return type.
+ *
+ * Based on the similar routine for sparc.
+ */
+int
+ffi_closure_mips_inner_O32 (ffi_closure *closure,
+ void *rvalue, ffi_arg *ar,
+ double *fpr)
+{
+ ffi_cif *cif;
+ void **avaluep;
+ ffi_arg *avalue;
+ ffi_type **arg_types;
+ int i, avn, argn, seen_int;
+
+ cif = closure->cif;
+ avalue = alloca (cif->nargs * sizeof (ffi_arg));
+ avaluep = alloca (cif->nargs * sizeof (ffi_arg));
+
+ seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
+ argn = 0;
+
+ if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
+ {
+ rvalue = (void *) ar[0];
+ argn = 1;
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ while (i < avn)
+ {
+ if (i < 2 && !seen_int &&
+ (arg_types[i]->type == FFI_TYPE_FLOAT ||
+ arg_types[i]->type == FFI_TYPE_DOUBLE))
+ {
+#ifdef __MIPSEB__
+ if (arg_types[i]->type == FFI_TYPE_FLOAT)
+ avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
+ else
+#endif
+ avaluep[i] = (char *) &fpr[i];
+ }
+ else
+ {
+ if (arg_types[i]->alignment == 8 && (argn & 0x1))
+ argn++;
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ avaluep[i] = &avalue[i];
+ *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
+ break;
+
+ case FFI_TYPE_UINT8:
+ avaluep[i] = &avalue[i];
+ *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
+ break;
+
+ case FFI_TYPE_SINT16:
+ avaluep[i] = &avalue[i];
+ *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
+ break;
+
+ case FFI_TYPE_UINT16:
+ avaluep[i] = &avalue[i];
+ *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
+ break;
+
+ default:
+ avaluep[i] = (char *) &ar[argn];
+ break;
+ }
+ seen_int = 1;
+ }
+ argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ i++;
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rvalue, avaluep, closure->user_data);
+
+ if (cif->abi == FFI_O32_SOFT_FLOAT)
+ {
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_FLOAT:
+ return FFI_TYPE_INT;
+ case FFI_TYPE_DOUBLE:
+ return FFI_TYPE_UINT64;
+ default:
+ return cif->rtype->type;
+ }
+ }
+ else
+ {
+ return cif->rtype->type;
+ }
+}
+
+#endif /* FFI_CLOSURES */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffitarget.h
new file mode 100644
index 000000000..e61074569
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffitarget.h
@@ -0,0 +1,167 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for MIPS.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#if !defined(_MIPS_SIM)
+-- something is very wrong --
+#else
+# if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))
+# define FFI_MIPS_N32
+# else
+# if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))
+# define FFI_MIPS_O32
+# else
+-- this is an unsupported platform --
+# endif
+# endif
+#endif
+
+#ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+#define FFI_SIZEOF_ARG 4
+#else
+/* N32 and N64 frames have 64bit integer args */
+#define FFI_SIZEOF_ARG 8
+#endif
+
+#define FFI_FLAG_BITS 2
+
+/* SGI's strange assembler requires that we multiply by 4 rather
+ than shift left by FFI_FLAG_BITS */
+
+#define FFI_ARGS_D FFI_TYPE_DOUBLE
+#define FFI_ARGS_F FFI_TYPE_FLOAT
+#define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE
+#define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT
+#define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT
+#define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE
+
+/* Needed for N32 structure returns */
+#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8
+#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8
+
+#if 0
+/* The SGI assembler can't handle this.. */
+#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT
+/* (and so on) */
+#else
+/* ...so we calculate these by hand! */
+#define FFI_TYPE_STRUCT_D 61
+#define FFI_TYPE_STRUCT_F 45
+#define FFI_TYPE_STRUCT_DD 253
+#define FFI_TYPE_STRUCT_FF 173
+#define FFI_TYPE_STRUCT_FD 237
+#define FFI_TYPE_STRUCT_DF 189
+#define FFI_TYPE_STRUCT_SMALL 93
+#define FFI_TYPE_STRUCT_SMALL2 109
+#endif
+
+#ifdef LIBFFI_ASM
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define a4 $8
+#define a5 $9
+#define a6 $10
+#define a7 $11
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define t8 $24
+#define t9 $25
+#define ra $31
+
+#ifdef FFI_MIPS_O32
+#define REG_L lw
+#define REG_S sw
+#define SUBU subu
+#define ADDU addu
+#define SRL srl
+#define LI li
+#else /* !FFI_MIPS_O32 */
+#define REG_L ld
+#define REG_S sd
+#define SUBU dsubu
+#define ADDU daddu
+#define SRL dsrl
+#define LI dli
+#endif /* !FFI_MIPS_O32 */
+#else /* !LIBFFI_ASM */
+#ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+typedef unsigned int ffi_arg __attribute__((__mode__(__SI__)));
+typedef signed int ffi_sarg __attribute__((__mode__(__SI__)));
+#else
+/* N32 and N64 frames have 64bit integer args */
+typedef unsigned int ffi_arg __attribute__((__mode__(__DI__)));
+typedef signed int ffi_sarg __attribute__((__mode__(__DI__)));
+#endif
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_O32,
+ FFI_N32,
+ FFI_N64,
+ FFI_O32_SOFT_FLOAT,
+
+#ifdef FFI_MIPS_O32
+#ifdef __mips_soft_float
+ FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT,
+#else
+ FFI_DEFAULT_ABI = FFI_O32,
+#endif
+#else
+ FFI_DEFAULT_ABI = FFI_N32,
+#endif
+
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+
+#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
+#endif /* !LIBFFI_ASM */
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if defined(FFI_MIPS_O32)
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 20
+#else
+/* N32/N64 not implemented yet. */
+#define FFI_CLOSURES 0
+#endif /* FFI_MIPS_O32 */
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/n32.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/n32.S
new file mode 100644
index 000000000..358cfd7e4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/n32.S
@@ -0,0 +1,320 @@
+/* -----------------------------------------------------------------------
+ n32.S - Copyright (c) 1996, 1998, 2005 Red Hat, Inc.
+
+ MIPS Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Only build this code if we are compiling for n32 */
+
+#if defined(FFI_MIPS_N32)
+
+#define callback a0
+#define bytes a2
+#define flags a3
+#define raddr a4
+#define fn a5
+
+#define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG )
+
+ .abicalls
+ .text
+ .align 2
+ .globl ffi_call_N32
+ .ent ffi_call_N32
+ffi_call_N32:
+
+ # Prologue
+ SUBU $sp, SIZEOF_FRAME # Frame size
+ REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer
+ REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address
+ move $fp, $sp
+
+ move t9, callback # callback function pointer
+ REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
+ REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags
+ REG_S raddr, 4*FFI_SIZEOF_ARG($fp) # raddr
+ REG_S fn, 5*FFI_SIZEOF_ARG($fp) # fn
+
+ # Allocate at least 4 words in the argstack
+ move v0, bytes
+ bge bytes, 4 * FFI_SIZEOF_ARG, bigger
+ LI v0, 4 * FFI_SIZEOF_ARG
+ b sixteen
+
+ bigger:
+ ADDU t4, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned
+ and v0, t4, -2 * FFI_SIZEOF_ARG # to a proper boundry.
+
+sixteen:
+ SUBU $sp, $sp, v0 # move the stack pointer to reflect the
+ # arg space
+
+ ADDU a0, $sp, 0 # 4 * FFI_SIZEOF_ARG
+ ADDU a3, $fp, 3 * FFI_SIZEOF_ARG
+
+ # Call ffi_prep_args
+ jal t9
+
+ # ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args
+
+ # Copy the stack pointer to t9
+ move t9, $sp
+
+ # Fix the stack if there are more than 8 64bit slots worth
+ # of arguments.
+
+ # Load the number of bytes
+ REG_L t6, 2*FFI_SIZEOF_ARG($fp)
+
+ # Is it bigger than 8 * FFI_SIZEOF_ARG?
+ dadd t7, $0, 8 * FFI_SIZEOF_ARG
+ dsub t8, t6, t7
+ bltz t8, loadregs
+
+ add t9, t9, t8
+
+loadregs:
+
+ REG_L t4, 3*FFI_SIZEOF_ARG($fp) # load the flags word
+ add t6, t4, 0 # and copy it into t6
+
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg1_floatp
+ REG_L a0, 0*FFI_SIZEOF_ARG(t9)
+ b arg1_next
+arg1_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg1_doublep
+ l.s $f12, 0*FFI_SIZEOF_ARG(t9)
+ b arg1_next
+arg1_doublep:
+ l.d $f12, 0*FFI_SIZEOF_ARG(t9)
+arg1_next:
+
+ add t4, t6, 0
+ SRL t4, 1*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg2_floatp
+ REG_L a1, 1*FFI_SIZEOF_ARG(t9)
+ b arg2_next
+arg2_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg2_doublep
+ l.s $f13, 1*FFI_SIZEOF_ARG(t9)
+ b arg2_next
+arg2_doublep:
+ l.d $f13, 1*FFI_SIZEOF_ARG(t9)
+arg2_next:
+
+ add t4, t6, 0
+ SRL t4, 2*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg3_floatp
+ REG_L a2, 2*FFI_SIZEOF_ARG(t9)
+ b arg3_next
+arg3_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg3_doublep
+ l.s $f14, 2*FFI_SIZEOF_ARG(t9)
+ b arg3_next
+arg3_doublep:
+ l.d $f14, 2*FFI_SIZEOF_ARG(t9)
+arg3_next:
+
+ add t4, t6, 0
+ SRL t4, 3*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg4_floatp
+ REG_L a3, 3*FFI_SIZEOF_ARG(t9)
+ b arg4_next
+arg4_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg4_doublep
+ l.s $f15, 3*FFI_SIZEOF_ARG(t9)
+ b arg4_next
+arg4_doublep:
+ l.d $f15, 3*FFI_SIZEOF_ARG(t9)
+arg4_next:
+
+ add t4, t6, 0
+ SRL t4, 4*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg5_floatp
+ REG_L a4, 4*FFI_SIZEOF_ARG(t9)
+ b arg5_next
+arg5_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg5_doublep
+ l.s $f16, 4*FFI_SIZEOF_ARG(t9)
+ b arg5_next
+arg5_doublep:
+ l.d $f16, 4*FFI_SIZEOF_ARG(t9)
+arg5_next:
+
+ add t4, t6, 0
+ SRL t4, 5*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg6_floatp
+ REG_L a5, 5*FFI_SIZEOF_ARG(t9)
+ b arg6_next
+arg6_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg6_doublep
+ l.s $f17, 5*FFI_SIZEOF_ARG(t9)
+ b arg6_next
+arg6_doublep:
+ l.d $f17, 5*FFI_SIZEOF_ARG(t9)
+arg6_next:
+
+ add t4, t6, 0
+ SRL t4, 6*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg7_floatp
+ REG_L a6, 6*FFI_SIZEOF_ARG(t9)
+ b arg7_next
+arg7_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg7_doublep
+ l.s $f18, 6*FFI_SIZEOF_ARG(t9)
+ b arg7_next
+arg7_doublep:
+ l.d $f18, 6*FFI_SIZEOF_ARG(t9)
+arg7_next:
+
+ add t4, t6, 0
+ SRL t4, 7*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg8_floatp
+ REG_L a7, 7*FFI_SIZEOF_ARG(t9)
+ b arg8_next
+arg8_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg8_doublep
+ l.s $f19, 7*FFI_SIZEOF_ARG(t9)
+ b arg8_next
+arg8_doublep:
+ l.d $f19, 7*FFI_SIZEOF_ARG(t9)
+arg8_next:
+
+callit:
+ # Load the function pointer
+ REG_L t9, 5*FFI_SIZEOF_ARG($fp)
+
+ # If the return value pointer is NULL, assume no return value.
+ REG_L t5, 4*FFI_SIZEOF_ARG($fp)
+ beqz t5, noretval
+
+ # Shift the return type flag over
+ SRL t6, 8*FFI_FLAG_BITS
+
+ bne t6, FFI_TYPE_INT, retfloat
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ REG_S v0, 0(t4)
+ b epilogue
+
+retfloat:
+ bne t6, FFI_TYPE_FLOAT, retdouble
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ b epilogue
+
+retdouble:
+ bne t6, FFI_TYPE_DOUBLE, retstruct_d
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ b epilogue
+
+retstruct_d:
+ bne t6, FFI_TYPE_STRUCT_D, retstruct_f
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ b epilogue
+
+retstruct_f:
+ bne t6, FFI_TYPE_STRUCT_F, retstruct_d_d
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ b epilogue
+
+retstruct_d_d:
+ bne t6, FFI_TYPE_STRUCT_DD, retstruct_f_f
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ s.d $f2, 8(t4)
+ b epilogue
+
+retstruct_f_f:
+ bne t6, FFI_TYPE_STRUCT_FF, retstruct_d_f
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ s.s $f2, 4(t4)
+ b epilogue
+
+retstruct_d_f:
+ bne t6, FFI_TYPE_STRUCT_DF, retstruct_f_d
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ s.s $f2, 8(t4)
+ b epilogue
+
+retstruct_f_d:
+ bne t6, FFI_TYPE_STRUCT_FD, retstruct_small
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ s.d $f2, 8(t4)
+ b epilogue
+
+retstruct_small:
+ bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ REG_S v0, 0(t4)
+ b epilogue
+
+retstruct_small2:
+ bne t6, FFI_TYPE_STRUCT_SMALL2, retstruct
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ REG_S v0, 0(t4)
+ REG_S v1, 8(t4)
+ b epilogue
+
+retstruct:
+noretval:
+ jal t9
+
+ # Epilogue
+epilogue:
+ move $sp, $fp
+ REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer
+ REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address
+ ADDU $sp, SIZEOF_FRAME # Fix stack pointer
+ j ra
+
+ .end ffi_call_N32
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/o32.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/o32.S
new file mode 100644
index 000000000..63f3d1463
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/o32.S
@@ -0,0 +1,377 @@
+/* -----------------------------------------------------------------------
+ o32.S - Copyright (c) 1996, 1998, 2005 Red Hat, Inc.
+
+ MIPS Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Only build this code if we are compiling for o32 */
+
+#if defined(FFI_MIPS_O32)
+
+#define callback a0
+#define bytes a2
+#define flags a3
+
+#define SIZEOF_FRAME (4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG)
+#define A3_OFF (SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG)
+#define FP_OFF (SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG)
+#define RA_OFF (SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG)
+
+ .abicalls
+ .text
+ .align 2
+ .globl ffi_call_O32
+ .ent ffi_call_O32
+ffi_call_O32:
+$LFB0:
+ # Prologue
+ SUBU $sp, SIZEOF_FRAME # Frame size
+$LCFI0:
+ REG_S $fp, FP_OFF($sp) # Save frame pointer
+$LCFI1:
+ REG_S ra, RA_OFF($sp) # Save return address
+$LCFI2:
+ move $fp, $sp
+
+$LCFI3:
+ move t9, callback # callback function pointer
+ REG_S flags, A3_OFF($fp) # flags
+
+ # Allocate at least 4 words in the argstack
+ LI v0, 4 * FFI_SIZEOF_ARG
+ blt bytes, v0, sixteen
+
+ ADDU v0, bytes, 7 # make sure it is aligned
+ and v0, -8 # to an 8 byte boundry
+
+sixteen:
+ SUBU $sp, v0 # move the stack pointer to reflect the
+ # arg space
+
+ ADDU a0, $sp, 4 * FFI_SIZEOF_ARG
+
+ jalr t9
+
+ REG_L t0, A3_OFF($fp) # load the flags word
+ SRL t2, t0, 4 # shift our arg info
+ and t0, ((1<<4)-1) # mask out the return type
+
+ ADDU $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args
+
+ bnez t0, pass_d # make it quick for int
+ REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the
+ REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs.
+ REG_L a2, 2*FFI_SIZEOF_ARG($sp)
+ REG_L a3, 3*FFI_SIZEOF_ARG($sp)
+ b call_it
+
+pass_d:
+ bne t0, FFI_ARGS_D, pass_f
+ l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args
+ REG_L a2, 2*FFI_SIZEOF_ARG($sp) # passing a double
+ REG_L a3, 3*FFI_SIZEOF_ARG($sp)
+ b call_it
+
+pass_f:
+ bne t0, FFI_ARGS_F, pass_d_d
+ l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args
+ REG_L a1, 1*FFI_SIZEOF_ARG($sp) # passing a float
+ REG_L a2, 2*FFI_SIZEOF_ARG($sp)
+ REG_L a3, 3*FFI_SIZEOF_ARG($sp)
+ b call_it
+
+pass_d_d:
+ bne t0, FFI_ARGS_DD, pass_f_f
+ l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args
+ l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing two doubles
+ b call_it
+
+pass_f_f:
+ bne t0, FFI_ARGS_FF, pass_d_f
+ l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args
+ l.s $f14, 1*FFI_SIZEOF_ARG($sp) # passing two floats
+ REG_L a2, 2*FFI_SIZEOF_ARG($sp)
+ REG_L a3, 3*FFI_SIZEOF_ARG($sp)
+ b call_it
+
+pass_d_f:
+ bne t0, FFI_ARGS_DF, pass_f_d
+ l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args
+ l.s $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float
+ REG_L a3, 3*FFI_SIZEOF_ARG($sp)
+ b call_it
+
+pass_f_d:
+ # assume that the only other combination must be float then double
+ # bne t0, FFI_ARGS_F_D, call_it
+ l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args
+ l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float
+
+call_it:
+ # Load the function pointer
+ REG_L t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp)
+
+ # If the return value pointer is NULL, assume no return value.
+ REG_L t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+ beqz t1, noretval
+
+ bne t2, FFI_TYPE_INT, retlonglong
+ jalr t9
+ REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+ REG_S v0, 0(t0)
+ b epilogue
+
+retlonglong:
+ # Really any 64-bit int, signed or not.
+ bne t2, FFI_TYPE_UINT64, retfloat
+ jalr t9
+ REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+ REG_S v1, 4(t0)
+ REG_S v0, 0(t0)
+ b epilogue
+
+retfloat:
+ bne t2, FFI_TYPE_FLOAT, retdouble
+ jalr t9
+ REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+ s.s $f0, 0(t0)
+ b epilogue
+
+retdouble:
+ bne t2, FFI_TYPE_DOUBLE, noretval
+ jalr t9
+ REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+ s.d $f0, 0(t0)
+ b epilogue
+
+noretval:
+ jalr t9
+
+ # Epilogue
+epilogue:
+ move $sp, $fp
+ REG_L $fp, FP_OFF($sp) # Restore frame pointer
+ REG_L ra, RA_OFF($sp) # Restore return address
+ ADDU $sp, SIZEOF_FRAME # Fix stack pointer
+ j ra
+
+$LFE0:
+ .end ffi_call_O32
+
+
+/* ffi_closure_O32. Expects address of the passed-in ffi_closure
+ in t0. Stores any arguments passed in registers onto the
+ stack, then calls ffi_closure_mips_inner_O32, which
+ then decodes them.
+
+ Stack layout:
+
+ 14 - Start of parameters, original sp
+ 13 - ra save
+ 12 - fp save
+ 11 - $16 (s0) save
+ 10 - cprestore
+ 9 - return value high (v1)
+ 8 - return value low (v0)
+ 7 - f14 (le high, be low)
+ 6 - f14 (le low, be high)
+ 5 - f12 (le high, be low)
+ 4 - f12 (le low, be high)
+ 3 - Called function a3 save
+ 2 - Called function a2 save
+ 1 - Called function a1 save
+ 0 - Called function a0 save our sp, fp point here
+ */
+
+#define SIZEOF_FRAME2 (14 * FFI_SIZEOF_ARG)
+#define A3_OFF2 (SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)
+#define A2_OFF2 (SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)
+#define A1_OFF2 (SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)
+#define A0_OFF2 (SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG)
+#define RA_OFF2 (SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG)
+#define FP_OFF2 (SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG)
+#define S0_OFF2 (SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG)
+#define GP_OFF2 (SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG)
+#define V1_OFF2 (SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG)
+#define V0_OFF2 (SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG)
+#define FA_1_1_OFF2 (SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG)
+#define FA_1_0_OFF2 (SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)
+#define FA_0_1_OFF2 (SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)
+#define FA_0_0_OFF2 (SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)
+
+ .text
+ .align 2
+ .globl ffi_closure_O32
+ .ent ffi_closure_O32
+ffi_closure_O32:
+$LFB1:
+ # Prologue
+ .frame $fp, SIZEOF_FRAME2, ra
+ .set noreorder
+ .cpload t9
+ .set reorder
+ SUBU $sp, SIZEOF_FRAME2
+ .cprestore GP_OFF2
+$LCFI4:
+ REG_S $16, S0_OFF2($sp) # Save s0
+ REG_S $fp, FP_OFF2($sp) # Save frame pointer
+ REG_S ra, RA_OFF2($sp) # Save return address
+$LCFI6:
+ move $fp, $sp
+
+$LCFI7:
+ # Store all possible argument registers. If there are more than
+ # four arguments, then they are stored above where we put a3.
+ REG_S a0, A0_OFF2($fp)
+ REG_S a1, A1_OFF2($fp)
+ REG_S a2, A2_OFF2($fp)
+ REG_S a3, A3_OFF2($fp)
+
+ # Load ABI enum to s0
+ REG_L $16, 20($8) # cif pointer follows tramp.
+ REG_L $16, 0($16) # abi is first member.
+
+ li $13, 1 # FFI_O32
+ bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT
+
+ # Store all possible float/double registers.
+ s.d $f12, FA_0_0_OFF2($fp)
+ s.d $f14, FA_1_0_OFF2($fp)
+1:
+ # Call ffi_closure_mips_inner_O32 to do the work.
+ la t9, ffi_closure_mips_inner_O32
+ move a0, $8 # Pointer to the ffi_closure
+ addu a1, $fp, V0_OFF2
+ addu a2, $fp, A0_OFF2
+ addu a3, $fp, FA_0_0_OFF2
+ jalr t9
+
+ # Load the return value into the appropriate register.
+ move $8, $2
+ li $9, FFI_TYPE_VOID
+ beq $8, $9, closure_done
+
+ li $13, 1 # FFI_O32
+ bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT
+
+ li $9, FFI_TYPE_FLOAT
+ l.s $f0, V0_OFF2($fp)
+ beq $8, $9, closure_done
+
+ li $9, FFI_TYPE_DOUBLE
+ l.d $f0, V0_OFF2($fp)
+ beq $8, $9, closure_done
+1:
+ REG_L $3, V1_OFF2($fp)
+ REG_L $2, V0_OFF2($fp)
+
+closure_done:
+ # Epilogue
+ move $sp, $fp
+ REG_L $16, S0_OFF2($sp) # Restore s0
+ REG_L $fp, FP_OFF2($sp) # Restore frame pointer
+ REG_L ra, RA_OFF2($sp) # Restore return address
+ ADDU $sp, SIZEOF_FRAME2
+ j ra
+$LFE1:
+ .end ffi_closure_O32
+
+/* DWARF-2 unwind info. */
+
+ .section .eh_frame,"a",@progbits
+$Lframe0:
+ .4byte $LECIE0-$LSCIE0 # Length of Common Information Entry
+$LSCIE0:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 4 # CIE Data Alignment Factor
+ .byte 0x1f # CIE RA Column
+ .uleb128 0x1 # Augmentation size
+ .byte 0x00 # FDE Encoding (absptr)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x1d
+ .uleb128 0x0
+ .align 2
+$LECIE0:
+$LSFDE0:
+ .4byte $LEFDE0-$LASFDE0 # FDE Length
+$LASFDE0:
+ .4byte $LASFDE0-$Lframe0 # FDE CIE offset
+ .4byte $LFB0 # FDE initial location
+ .4byte $LFE0-$LFB0 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI0-$LFB0
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 0x18
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI2-$LCFI0
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x1e # $fp
+ .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x1f # $ra
+ .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI3-$LCFI2
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x1e
+ .uleb128 0x18
+ .align 2
+$LEFDE0:
+$LSFDE1:
+ .4byte $LEFDE1-$LASFDE1 # FDE Length
+$LASFDE1:
+ .4byte $LASFDE1-$Lframe0 # FDE CIE offset
+ .4byte $LFB1 # FDE initial location
+ .4byte $LFE1-$LFB1 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI4-$LFB1
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 0x38
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI6-$LCFI4
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x10 # $16
+ .sleb128 -3 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x1e # $fp
+ .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x1f # $ra
+ .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte $LCFI7-$LCFI6
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x1e
+ .uleb128 0x38
+ .align 2
+$LEFDE1:
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffi.c
new file mode 100644
index 000000000..f6264dbc5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffi.c
@@ -0,0 +1,625 @@
+/* -----------------------------------------------------------------------
+ ffi.c - (c) 2003-2004 Randolph Chung <tausq@debian.org>
+
+ HPPA Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1))
+#define ROUND_DOWN(v, a) (((size_t)(v) - (a) + 1) & ~((a) - 1))
+#define MIN_STACK_SIZE 64
+#define FIRST_ARG_SLOT 9
+#define DEBUG_LEVEL 0
+
+#define fldw(addr, fpreg) asm volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)
+#define fstw(fpreg, addr) asm volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))
+#define fldd(addr, fpreg) asm volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)
+#define fstd(fpreg, addr) asm volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))
+
+#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
+
+static inline int ffi_struct_type(ffi_type *t)
+{
+ size_t sz = t->size;
+
+ /* Small structure results are passed in registers,
+ larger ones are passed by pointer. */
+
+ if (sz <= 1)
+ return FFI_TYPE_UINT8;
+ else if (sz == 2)
+ return FFI_TYPE_UINT16;
+ else if (sz == 3)
+ return FFI_TYPE_SMALL_STRUCT3;
+ else if (sz == 4)
+ return FFI_TYPE_UINT32;
+ else if (sz == 5)
+ return FFI_TYPE_SMALL_STRUCT5;
+ else if (sz == 6)
+ return FFI_TYPE_SMALL_STRUCT6;
+ else if (sz == 7)
+ return FFI_TYPE_SMALL_STRUCT7;
+ else if (sz <= 8)
+ return FFI_TYPE_UINT64;
+ else
+ return FFI_TYPE_STRUCT; /* else, we pass it by pointer. */
+}
+
+/* PA has a downward growing stack, which looks like this:
+
+ Offset
+ [ Variable args ]
+ SP = (4*(n+9)) arg word N
+ ...
+ SP-52 arg word 4
+ [ Fixed args ]
+ SP-48 arg word 3
+ SP-44 arg word 2
+ SP-40 arg word 1
+ SP-36 arg word 0
+ [ Frame marker ]
+ ...
+ SP-20 RP
+ SP-4 previous SP
+
+ First 4 non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23
+ First 2 non-FP 64-bit args are passed in register pairs, starting
+ on an even numbered register (i.e. r26/r25 and r24+r23)
+ First 4 FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L
+ First 2 FP 64-bit arguments are passed in fr5 and fr7
+ The rest are passed on the stack starting at SP-52, but 64-bit
+ arguments need to be aligned to an 8-byte boundary
+
+ This means we can have holes either in the register allocation,
+ or in the stack. */
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments
+
+ The following code will put everything into the stack frame
+ (which was allocated by the asm routine), and on return
+ the asm routine will load the arguments that should be
+ passed by register into the appropriate registers
+
+ NOTE: We load floating point args in this function... that means we
+ assume gcc will not mess with fp regs in here. */
+
+/*@-exportheader@*/
+void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register ffi_type **p_arg;
+ register void **p_argv;
+ unsigned int slot = FIRST_ARG_SLOT - 1;
+ char *dest_cpy;
+
+ debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack, ecif, bytes);
+
+ p_arg = ecif->cif->arg_types;
+ p_argv = ecif->avalue;
+
+ for (i = 0; i < ecif->cif->nargs; i++)
+ {
+ int type = (*p_arg)->type;
+
+ switch (type)
+ {
+ case FFI_TYPE_SINT8:
+ slot++;
+ *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ slot++;
+ *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ slot++;
+ *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ slot++;
+ *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_POINTER:
+ slot++;
+ debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv), slot);
+ *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ slot += 2;
+ if (slot & 1)
+ slot++;
+
+ *(UINT32 *)(stack - slot) = (*(UINT64 *)(*p_argv)) >> 32;
+ *(UINT32 *)(stack - slot + 1) = (*(UINT64 *)(*p_argv)) & 0xffffffffUL;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ /* First 4 args go in fr4L - fr7L */
+ slot++;
+ switch (slot - FIRST_ARG_SLOT)
+ {
+ case 0: fldw(*p_argv, fr4); break;
+ case 1: fldw(*p_argv, fr5); break;
+ case 2: fldw(*p_argv, fr6); break;
+ case 3: fldw(*p_argv, fr7); break;
+ default:
+ /* Other ones are just passed on the stack. */
+ debug(3, "Storing UINT32(float) in slot %u\n", slot);
+ *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
+ break;
+ }
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ slot += 2;
+ if (slot & 1)
+ slot++;
+ switch (slot - FIRST_ARG_SLOT + 1)
+ {
+ /* First 2 args go in fr5, fr7 */
+ case 2: fldd(*p_argv, fr5); break;
+ case 4: fldd(*p_argv, fr7); break;
+ default:
+ debug(3, "Storing UINT64(double) at slot %u\n", slot);
+ *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
+ break;
+ }
+ break;
+
+ case FFI_TYPE_STRUCT:
+
+ /* Structs smaller or equal than 4 bytes are passed in one
+ register. Structs smaller or equal 8 bytes are passed in two
+ registers. Larger structures are passed by pointer. */
+
+ if((*p_arg)->size <= 4)
+ {
+ slot++;
+ dest_cpy = (char *)(stack - slot);
+ dest_cpy += 4 - (*p_arg)->size;
+ memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size);
+ }
+ else if ((*p_arg)->size <= 8)
+ {
+ slot += 2;
+ if (slot & 1)
+ slot++;
+ dest_cpy = (char *)(stack - slot);
+ dest_cpy += 8 - (*p_arg)->size;
+ memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size);
+ }
+ else
+ {
+ slot++;
+ *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
+ }
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ p_arg++;
+ p_argv++;
+ }
+
+ /* Make sure we didn't mess up and scribble on the stack. */
+ {
+ int n;
+
+ debug(5, "Stack setup:\n");
+ for (n = 0; n < (bytes + 3) / 4; n++)
+ {
+ if ((n%4) == 0) { debug(5, "\n%08x: ", (unsigned int)(stack - n)); }
+ debug(5, "%08x ", *(stack - n));
+ }
+ debug(5, "\n");
+ }
+
+ FFI_ASSERT(slot * 4 <= bytes);
+
+ return;
+}
+
+static void ffi_size_stack_LINUX(ffi_cif *cif)
+{
+ ffi_type **ptr;
+ int i;
+ int z = 0; /* # stack slots */
+
+ for (ptr = cif->arg_types, i = 0; i < cif->nargs; ptr++, i++)
+ {
+ int type = (*ptr)->type;
+
+ switch (type)
+ {
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ z += 2 + (z & 1); /* must start on even regs, so we may waste one */
+ break;
+
+ case FFI_TYPE_STRUCT:
+ z += 1; /* pass by ptr, callee will copy */
+ break;
+
+ default: /* <= 32-bit values */
+ z++;
+ }
+ }
+
+ /* We can fit up to 6 args in the default 64-byte stack frame,
+ if we need more, we need more stack. */
+ if (z <= 6)
+ cif->bytes = MIN_STACK_SIZE; /* min stack size */
+ else
+ cif->bytes = 64 + ROUND_UP((z - 6) * sizeof(UINT32), MIN_STACK_SIZE);
+
+ debug(3, "Calculated stack size is %u bytes\n", cif->bytes);
+}
+
+/* Perform machine dependent cif processing. */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* For the return type we have to check the size of the structures.
+ If the size is smaller or equal 4 bytes, the result is given back
+ in one register. If the size is smaller or equal 8 bytes than we
+ return the result in two registers. But if the size is bigger than
+ 8 bytes, we work with pointers. */
+ cif->flags = ffi_struct_type(cif->rtype);
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ cif->flags = FFI_TYPE_UINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ /* Lucky us, because of the unique PA ABI we get to do our
+ own stack sizing. */
+ switch (cif->abi)
+ {
+ case FFI_LINUX:
+ ffi_size_stack_LINUX(cif);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_LINUX(void (*)(UINT32 *, extended_cif *, unsigned),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return
+ value address then we need to make one. */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_LINUX:
+ /*@-usedef@*/
+ debug(2, "Calling ffi_call_LINUX: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
+ ffi_call_LINUX(ffi_prep_args_LINUX, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+#if FFI_CLOSURES
+/* This is more-or-less an inverse of ffi_call -- we have arguments on
+ the stack, and we need to fill them into a cif structure and invoke
+ the user function. This really ought to be in asm to make sure
+ the compiler doesn't do things we don't expect. */
+UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
+{
+ ffi_cif *cif;
+ void **avalue;
+ void *rvalue;
+ UINT32 ret[2]; /* function can return up to 64-bits in registers */
+ ffi_type **p_arg;
+ char *tmp;
+ int i, avn, slot = FIRST_ARG_SLOT - 1;
+ register UINT32 r28 asm("r28");
+
+ cif = closure->cif;
+
+ /* If returning via structure, callee will write to our pointer. */
+ if (cif->flags == FFI_TYPE_STRUCT)
+ rvalue = (void *)r28;
+ else
+ rvalue = &ret[0];
+
+ avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG);
+ avn = cif->nargs;
+ p_arg = cif->arg_types;
+
+ for (i = 0; i < avn; i++)
+ {
+ int type = (*p_arg)->type;
+
+ switch (type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ slot++;
+ avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ slot += 2;
+ if (slot & 1)
+ slot++;
+ avalue[i] = (void *)(stack - slot);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ slot++;
+ switch (slot - FIRST_ARG_SLOT)
+ {
+ case 0: fstw(fr4, (void *)(stack - slot)); break;
+ case 1: fstw(fr5, (void *)(stack - slot)); break;
+ case 2: fstw(fr6, (void *)(stack - slot)); break;
+ case 3: fstw(fr7, (void *)(stack - slot)); break;
+ }
+ avalue[i] = (void *)(stack - slot);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ slot += 2;
+ if (slot & 1)
+ slot++;
+ switch (slot - FIRST_ARG_SLOT + 1)
+ {
+ case 2: fstd(fr5, (void *)(stack - slot)); break;
+ case 4: fstd(fr7, (void *)(stack - slot)); break;
+ }
+ avalue[i] = (void *)(stack - slot);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* Structs smaller or equal than 4 bytes are passed in one
+ register. Structs smaller or equal 8 bytes are passed in two
+ registers. Larger structures are passed by pointer. */
+ if((*p_arg)->size <= 4) {
+ slot++;
+ avalue[i] = (void *)(stack - slot) + sizeof(UINT32) -
+ (*p_arg)->size;
+ } else if ((*p_arg)->size <= 8) {
+ slot += 2;
+ if (slot & 1)
+ slot++;
+ avalue[i] = (void *)(stack - slot) + sizeof(UINT64) -
+ (*p_arg)->size;
+ } else {
+ slot++;
+ avalue[i] = (void *) *(stack - slot);
+ }
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ p_arg++;
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], ret[1]);
+
+ /* Store the result */
+ switch (cif->flags)
+ {
+ case FFI_TYPE_UINT8:
+ *(stack - FIRST_ARG_SLOT) = (UINT8)(ret[0] >> 24);
+ break;
+ case FFI_TYPE_SINT8:
+ *(stack - FIRST_ARG_SLOT) = (SINT8)(ret[0] >> 24);
+ break;
+ case FFI_TYPE_UINT16:
+ *(stack - FIRST_ARG_SLOT) = (UINT16)(ret[0] >> 16);
+ break;
+ case FFI_TYPE_SINT16:
+ *(stack - FIRST_ARG_SLOT) = (SINT16)(ret[0] >> 16);
+ break;
+ case FFI_TYPE_INT:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ *(stack - FIRST_ARG_SLOT) = ret[0];
+ break;
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ *(stack - FIRST_ARG_SLOT) = ret[0];
+ *(stack - FIRST_ARG_SLOT - 1) = ret[1];
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ fldd(rvalue, fr4);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ fldw(rvalue, fr4);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* Don't need a return value, done by caller. */
+ break;
+
+ case FFI_TYPE_SMALL_STRUCT3:
+ tmp = (void*)(stack - FIRST_ARG_SLOT);
+ tmp += 4 - cif->rtype->size;
+ memcpy((void*)tmp, &ret[0], cif->rtype->size);
+ break;
+
+ case FFI_TYPE_SMALL_STRUCT5:
+ case FFI_TYPE_SMALL_STRUCT6:
+ case FFI_TYPE_SMALL_STRUCT7:
+ {
+ unsigned int ret2[2];
+ int off;
+
+ /* Right justify ret[0] and ret[1] */
+ switch (cif->flags)
+ {
+ case FFI_TYPE_SMALL_STRUCT5: off = 3; break;
+ case FFI_TYPE_SMALL_STRUCT6: off = 2; break;
+ case FFI_TYPE_SMALL_STRUCT7: off = 1; break;
+ default: off = 0; break;
+ }
+
+ memset (ret2, 0, sizeof (ret2));
+ memcpy ((char *)ret2 + off, ret, 8 - off);
+
+ *(stack - FIRST_ARG_SLOT) = ret2[0];
+ *(stack - FIRST_ARG_SLOT - 1) = ret2[1];
+ }
+ break;
+
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_VOID:
+ break;
+
+ default:
+ debug(0, "assert with cif->flags: %d\n",cif->flags);
+ FFI_ASSERT(0);
+ break;
+ }
+ return FFI_OK;
+}
+
+/* Fill in a closure to refer to the specified fun and user_data.
+ cif specifies the argument and result types for fun.
+ The cif must already be prep'ed. */
+
+void ffi_closure_LINUX(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ UINT32 *tramp = (UINT32 *)(closure->tramp);
+
+ FFI_ASSERT (cif->abi == FFI_LINUX);
+
+ /* Make a small trampoline that will branch to our
+ handler function. Use PC-relative addressing. */
+
+ tramp[0] = 0xeaa00000; /* b,l .+8, %r21 ; %r21 <- pc+8 */
+ tramp[1] = 0xd6a01c1e; /* depi 0,31,2, %r21 ; mask priv bits */
+ tramp[2] = 0x4aa10028; /* ldw 20(%r21), %r1 ; load plabel */
+ tramp[3] = 0x36b53ff1; /* ldo -8(%r21), %r21 ; get closure addr */
+ tramp[4] = 0x0c201096; /* ldw 0(%r1), %r22 ; address of handler */
+ tramp[5] = 0xeac0c000; /* bv %r0(%r22) ; branch to handler */
+ tramp[6] = 0x0c281093; /* ldw 4(%r1), %r19 ; GP of handler */
+ tramp[7] = ((UINT32)(ffi_closure_LINUX) & ~2);
+
+ /* Flush d/icache -- have to flush up 2 two lines because of
+ alignment. */
+ asm volatile (
+ "fdc 0(%0)\n"
+ "fdc %1(%0)\n"
+ "fic 0(%%sr4, %0)\n"
+ "fic %1(%%sr4, %0)\n"
+ "sync\n"
+ : : "r"((unsigned long)tramp & ~31), "r"(32 /* stride */));
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffitarget.h
new file mode 100644
index 000000000..562069623
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffitarget.h
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for hppa.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+
+#ifdef PA
+ FFI_LINUX,
+ FFI_DEFAULT_ABI = FFI_LINUX,
+#endif
+
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#define FFI_TRAMPOLINE_SIZE 32
+
+#define FFI_TYPE_SMALL_STRUCT3 -1
+#define FFI_TYPE_SMALL_STRUCT5 -2
+#define FFI_TYPE_SMALL_STRUCT6 -3
+#define FFI_TYPE_SMALL_STRUCT7 -4
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/linux.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/linux.S
new file mode 100644
index 000000000..267cff7b8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/linux.S
@@ -0,0 +1,307 @@
+/* -----------------------------------------------------------------------
+ linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
+
+ HPPA Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .text
+ .level 1.1
+ .align 4
+
+ /* void ffi_call_LINUX(void (*)(char *, extended_cif *),
+ extended_cif *ecif,
+ unsigned bytes,
+ unsigned flags,
+ unsigned *rvalue,
+ void (*fn)());
+ */
+
+ .export ffi_call_LINUX,code
+ .import ffi_prep_args_LINUX,code
+
+ .type ffi_call_LINUX, @function
+.LFB1:
+ffi_call_LINUX:
+ .proc
+ .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
+ .entry
+ stw %rp, -20(%sp)
+ copy %r3, %r1
+.LCFI11:
+
+ copy %sp, %r3
+.LCFI12:
+
+ /* Setup the stack for calling prep_args...
+ We want the stack to look like this:
+
+ [ Previous stack ] <- %r3
+
+ [ 64-bytes register save area ] <- %r4
+
+ [ Stack space for actual call, passed as ] <- %arg0
+ [ arg0 to ffi_prep_args_LINUX ]
+
+ [ Stack for calling prep_args ] <- %sp
+ */
+
+ stwm %r1, 64(%sp)
+ stw %r4, 12(%r3)
+.LCFI13:
+ copy %sp, %r4
+
+ addl %arg2, %r4, %arg0 /* arg stack */
+ stw %arg3, -48(%r3) /* save flags; we need it later */
+
+ /* Call prep_args:
+ %arg0(stack) -- set up above
+ %arg1(ecif) -- same as incoming param
+ %arg2(bytes) -- same as incoming param */
+ bl ffi_prep_args_LINUX,%r2
+ ldo 64(%arg0), %sp
+ ldo -64(%sp), %sp
+
+ /* now %sp should point where %arg0 was pointing. */
+
+ /* Load the arguments that should be passed in registers
+ The fp args were loaded by the prep_args function. */
+ ldw -36(%sp), %arg0
+ ldw -40(%sp), %arg1
+ ldw -44(%sp), %arg2
+ ldw -48(%sp), %arg3
+
+ /* in case the function is going to return a structure
+ we need to give it a place to put the result. */
+ ldw -52(%r3), %ret0 /* %ret0 <- rvalue */
+ ldw -56(%r3), %r22 /* %r22 <- function to call */
+ bl $$dyncall, %r31 /* Call the user function */
+ copy %r31, %rp
+
+ /* Prepare to store the result; we need to recover flags and rvalue. */
+ ldw -48(%r3), %r21 /* r21 <- flags */
+ ldw -52(%r3), %r20 /* r20 <- rvalue */
+
+ /* Store the result according to the return type. */
+
+checksmst3:
+ comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, checksmst567
+ /* 3-byte structs are returned in ret0 as ??xxyyzz. Shift
+ left 8 bits to write to the result structure. */
+ zdep %ret0, 23, 24, %r22
+ b done
+ stw %r22, 0(%r20)
+
+checksmst567:
+ /* 5-7 byte values are returned right justified:
+ ret0 ret1
+ 5: ??????aa bbccddee
+ 6: ????aabb ccddeeff
+ 7: ??aabbcc ddeeffgg
+
+ To store this in the result, write the first 4 bytes into a temp
+ register using shrpw (t1 = aabbccdd), followed by a rotation of
+ ret1:
+
+ ret0 ret1 ret1
+ 5: ??????aa bbccddee -> eebbccdd (rotate 8)
+ 6: ????aabb ccddeeff -> eeffccdd (rotate 16)
+ 7: ??aabbcc ddeeffgg -> eeffggdd (rotate 24)
+
+ then we write (t1, ret1) into the result. */
+
+ addi,<> -FFI_TYPE_SMALL_STRUCT5,%r21,%r0
+ ldi 8, %r22
+ addi,<> -FFI_TYPE_SMALL_STRUCT6,%r21,%r0
+ ldi 16, %r22
+ addi,<> -FFI_TYPE_SMALL_STRUCT7,%r21,%r0
+ ldi 24, %r22
+
+ /* This relies on all the FFI_TYPE_*_STRUCT* defines being <0 */
+ cmpib,<=,n 0, %r21, checkint8
+ mtsar %r22
+
+ shrpw %ret0, %ret1, %sar, %ret0 /* ret0 = aabbccdd */
+ shrpw %ret1, %ret1, %sar, %ret1 /* rotate ret1 */
+
+ stw %ret0, 0(%r20)
+ b done
+ stw %ret1, 4(%r20)
+
+checkint8:
+ comib,<>,n FFI_TYPE_UINT8, %r21, checkint16
+ b done
+ stb %ret0, 0(%r20)
+
+checkint16:
+ comib,<>,n FFI_TYPE_UINT16, %r21, checkint32
+ b done
+ sth %ret0, 0(%r20)
+
+checkint32:
+ comib,<>,n FFI_TYPE_UINT32, %r21, checkint
+ b done
+ stw %ret0, 0(%r20)
+
+checkint:
+ comib,<>,n FFI_TYPE_INT, %r21, checkll
+ b done
+ stw %ret0, 0(%r20)
+
+checkll:
+ comib,<>,n FFI_TYPE_UINT64, %r21, checkdbl
+ stw %ret0, 0(%r20)
+ b done
+ stw %ret1, 4(%r20)
+
+checkdbl:
+ comib,<>,n FFI_TYPE_DOUBLE, %r21, checkfloat
+ b done
+ fstd %fr4,0(%r20)
+
+checkfloat:
+ comib,<>,n FFI_TYPE_FLOAT, %r21, done
+ fstw %fr4L,0(%r20)
+
+ /* structure returns are either handled by one of the
+ INT/UINT64 cases above, or, if passed by pointer,
+ is handled by the callee. */
+
+done:
+ /* all done, return */
+ copy %r4, %sp /* pop arg stack */
+ ldw 12(%r3), %r4
+ ldwm -64(%sp), %r3 /* .. and pop stack */
+ ldw -20(%sp), %rp
+ bv %r0(%rp)
+ nop
+ .exit
+ .procend
+.LFE1:
+
+ /* void ffi_closure_LINUX(void);
+ Called with closure argument in %r21 */
+ .export ffi_closure_LINUX,code
+ .import ffi_closure_inner_LINUX,code
+
+ .type ffi_closure_LINUX, @function
+.LFB2:
+ffi_closure_LINUX:
+ .proc
+ .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+ .entry
+
+ stw %rp, -20(%sp)
+.LCFI20:
+ copy %r3, %r1
+.LCFI21:
+ copy %sp, %r3
+.LCFI22:
+ stwm %r1, 64(%sp)
+
+ /* Put arguments onto the stack and call ffi_closure_inner. */
+ stw %arg0, -36(%r3)
+ stw %arg1, -40(%r3)
+ stw %arg2, -44(%r3)
+ stw %arg3, -48(%r3)
+
+ copy %r21, %arg0
+ bl ffi_closure_inner_LINUX, %r2
+ copy %r3, %arg1
+
+ ldwm -64(%sp), %r3
+ ldw -20(%sp), %rp
+ ldw -36(%sp), %ret0
+ bv %r0(%r2)
+ ldw -40(%sp), %ret1
+
+ .exit
+ .procend
+.LFE2:
+
+ .section ".eh_frame",EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .word .LECIE1-.LSCIE1 ;# Length of Common Information Entry
+.LSCIE1:
+ .word 0x0 ;# CIE Identifier Tag
+ .byte 0x1 ;# CIE Version
+ .ascii "\0" ;# CIE Augmentation
+ .uleb128 0x1 ;# CIE Code Alignment Factor
+ .sleb128 4 ;# CIE Data Alignment Factor
+ .byte 0x2 ;# CIE RA Column
+ .byte 0xc ;# DW_CFA_def_cfa
+ .uleb128 0x1e
+ .uleb128 0x0
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .word .LEFDE1-.LASFDE1 ;# FDE Length
+.LASFDE1:
+ .word .LASFDE1-.Lframe1 ;# FDE CIE offset
+ .word .LFB1 ;# FDE initial location
+ .word .LFE1-.LFB1 ;# FDE address range
+
+ .byte 0x4 ;# DW_CFA_advance_loc4
+ .word .LCFI11-.LFB1
+ .byte 0x83 ;# DW_CFA_offset, column 0x3
+ .uleb128 0x0
+ .byte 0x11 ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
+ .uleb128 0x2
+ .sleb128 -5
+
+ .byte 0x4 ;# DW_CFA_advance_loc4
+ .word .LCFI12-.LCFI11
+ .byte 0xd ;# DW_CFA_def_cfa_register = r3
+ .uleb128 0x3
+
+ .byte 0x4 ;# DW_CFA_advance_loc4
+ .word .LCFI13-.LCFI12
+ .byte 0x84 ;# DW_CFA_offset, column 0x4
+ .uleb128 0x3
+
+ .align 4
+.LEFDE1:
+
+.LSFDE2:
+ .word .LEFDE2-.LASFDE2 ;# FDE Length
+.LASFDE2:
+ .word .LASFDE2-.Lframe1 ;# FDE CIE offset
+ .word .LFB2 ;# FDE initial location
+ .word .LFE2-.LFB2 ;# FDE address range
+ .byte 0x4 ;# DW_CFA_advance_loc4
+ .word .LCFI21-.LFB2
+ .byte 0x83 ;# DW_CFA_offset, column 0x3
+ .uleb128 0x0
+ .byte 0x11 ;# DW_CFA_offset_extended_sf
+ .uleb128 0x2
+ .sleb128 -5
+
+ .byte 0x4 ;# DW_CFA_advance_loc4
+ .word .LCFI12-.LCFI11
+ .byte 0xd ;# DW_CFA_def_cfa_register = r3
+ .uleb128 0x3
+
+ .align 4
+.LEFDE2:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix.S
new file mode 100644
index 000000000..45502f796
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix.S
@@ -0,0 +1,225 @@
+/* -----------------------------------------------------------------------
+ aix.S - Copyright (c) 2002 Free Software Foundation, Inc.
+ based on darwin.S by John Hornkvist
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+ .set r0,0
+ .set r1,1
+ .set r2,2
+ .set r3,3
+ .set r4,4
+ .set r5,5
+ .set r6,6
+ .set r7,7
+ .set r8,8
+ .set r9,9
+ .set r10,10
+ .set r11,11
+ .set r12,12
+ .set r13,13
+ .set r14,14
+ .set r15,15
+ .set r16,16
+ .set r17,17
+ .set r18,18
+ .set r19,19
+ .set r20,20
+ .set r21,21
+ .set r22,22
+ .set r23,23
+ .set r24,24
+ .set r25,25
+ .set r26,26
+ .set r27,27
+ .set r28,28
+ .set r29,29
+ .set r30,30
+ .set r31,31
+ .set f0,0
+ .set f1,1
+ .set f2,2
+ .set f3,3
+ .set f4,4
+ .set f5,5
+ .set f6,6
+ .set f7,7
+ .set f8,8
+ .set f9,9
+ .set f10,10
+ .set f11,11
+ .set f12,12
+ .set f13,13
+ .set f14,14
+ .set f15,15
+ .set f16,16
+ .set f17,17
+ .set f18,18
+ .set f19,19
+ .set f20,20
+ .set f21,21
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#define JUMPTARGET(name) name
+#define L(x) x
+ .file "aix.S"
+ .toc
+ .csect .text[PR]
+ .align 2
+.globl ffi_prep_args
+
+.csect .text[PR]
+ .align 2
+ .globl ffi_call_AIX
+ .globl .ffi_call_AIX
+.csect ffi_call_AIX[DS]
+ffi_call_AIX:
+ .long .ffi_call_AIX, TOC[tc0], 0
+ .csect .text[PR]
+.ffi_call_AIX:
+ mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
+ /* Save the old stack pointer as AP. */
+ mr r8,r1
+
+ /* Allocate the stack space we need. */
+ stwux r1,r1,r4
+
+ /* Save registers we use. */
+ mflr r9
+
+ stw r28,-16(r8)
+ stw r29,-12(r8)
+ stw r30, -8(r8)
+ stw r31, -4(r8)
+
+ stw r9, 8(r8)
+ stw r2, 20(r1)
+
+ /* Save arguments over call... */
+ mr r31,r5 /* flags, */
+ mr r30,r6 /* rvalue, */
+ mr r29,r7 /* function address, */
+ mr r28,r8 /* our AP. */
+
+ /* Call ffi_prep_args. */
+ mr r4,r1
+ li r9,0
+
+ lwz r2,4(r12)
+ lwz r12,0(r12)
+ mtctr r12 // r12 holds address of _ffi_prep_args
+ bctrl
+ lwz r2,20(r1)
+
+ /* Now do the call. */
+ lwz r12,0(r29)
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40,r31
+ stw r2,20(r1)
+ mtctr r12
+ lwz r2,4(r29)
+ /* Load all those argument registers. */
+ // We have set up a nice stack frame, just load it into registers.
+ lwz r3, 20+(1*4)(r1)
+ lwz r4, 20+(2*4)(r1)
+ lwz r5, 20+(3*4)(r1)
+ lwz r6, 20+(4*4)(r1)
+ nop
+ lwz r7, 20+(5*4)(r1)
+ lwz r8, 20+(6*4)(r1)
+ lwz r9, 20+(7*4)(r1)
+ lwz r10,20+(8*4)(r1)
+
+L1:
+ /* Load all the FP registers. */
+ bf 6,L2 // 2f + 0x18
+ lfd f1,-16-(13*8)(r28)
+ lfd f2,-16-(12*8)(r28)
+ lfd f3,-16-(11*8)(r28)
+ lfd f4,-16-(10*8)(r28)
+ nop
+ lfd f5,-16-(9*8)(r28)
+ lfd f6,-16-(8*8)(r28)
+ lfd f7,-16-(7*8)(r28)
+ lfd f8,-16-(6*8)(r28)
+ nop
+ lfd f9,-16-(5*8)(r28)
+ lfd f10,-16-(4*8)(r28)
+ lfd f11,-16-(3*8)(r28)
+ lfd f12,-16-(2*8)(r28)
+ nop
+ lfd f13,-16-(1*8)(r28)
+
+L2:
+ /* Make the call. */
+ bctrl
+ lwz r2,20(r1)
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01,r31
+
+ bt 30,L(done_return_value)
+ bt 29,L(fp_return_value)
+ stw r3,0(r30)
+ bf 28,L(done_return_value)
+ stw r4,4(r30)
+
+ /* Fall through... */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ lwz r9, 8(r28)
+ lwz r31, -4(r28)
+ mtlr r9
+ lwz r30, -8(r28)
+ lwz r29,-12(r28)
+ lwz r28,-16(r28)
+ lwz r1,0(r1)
+ blr
+
+L(fp_return_value):
+ bf 28,L(float_return_value)
+ stfd f1,0(r30)
+ b L(done_return_value)
+L(float_return_value):
+ stfs f1,0(r30)
+ b L(done_return_value)
+ .long 0
+ .byte 0,0,0,1,128,4,0,0
+//END(ffi_call_AIX)
+
+.csect .text[PR]
+ .align 2
+ .globl ffi_call_DARWIN
+ .globl .ffi_call_DARWIN
+.csect ffi_call_DARWIN[DS]
+ffi_call_DARWIN:
+ .long .ffi_call_DARWIN, TOC[tc0], 0
+ .csect .text[PR]
+.ffi_call_DARWIN:
+ blr
+ .long 0
+ .byte 0,0,0,0,0,0,0,0
+//END(ffi_call_DARWIN)
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix_closure.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix_closure.S
new file mode 100644
index 000000000..7bf5c6560
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix_closure.S
@@ -0,0 +1,247 @@
+/* -----------------------------------------------------------------------
+ aix_closure.S - Copyright (c) 2002 2003 Free Software Foundation, Inc.
+ based on darwin_closure.S
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+ .set r0,0
+ .set r1,1
+ .set r2,2
+ .set r3,3
+ .set r4,4
+ .set r5,5
+ .set r6,6
+ .set r7,7
+ .set r8,8
+ .set r9,9
+ .set r10,10
+ .set r11,11
+ .set r12,12
+ .set r13,13
+ .set r14,14
+ .set r15,15
+ .set r16,16
+ .set r17,17
+ .set r18,18
+ .set r19,19
+ .set r20,20
+ .set r21,21
+ .set r22,22
+ .set r23,23
+ .set r24,24
+ .set r25,25
+ .set r26,26
+ .set r27,27
+ .set r28,28
+ .set r29,29
+ .set r30,30
+ .set r31,31
+ .set f0,0
+ .set f1,1
+ .set f2,2
+ .set f3,3
+ .set f4,4
+ .set f5,5
+ .set f6,6
+ .set f7,7
+ .set f8,8
+ .set f9,9
+ .set f10,10
+ .set f11,11
+ .set f12,12
+ .set f13,13
+ .set f14,14
+ .set f15,15
+ .set f16,16
+ .set f17,17
+ .set f18,18
+ .set f19,19
+ .set f20,20
+ .set f21,21
+
+#define LIBFFI_ASM
+#define JUMPTARGET(name) name
+#define L(x) x
+ .file "aix_closure.S"
+ .toc
+LC..60:
+ .tc L..60[TC],L..60
+ .csect .text[PR]
+ .align 2
+
+.csect .text[PR]
+ .align 2
+ .globl ffi_closure_ASM
+ .globl .ffi_closure_ASM
+.csect ffi_closure_ASM[DS]
+
+ffi_closure_ASM:
+ .long .ffi_closure_ASM, TOC[tc0], 0
+ .csect .text[PR]
+.ffi_closure_ASM:
+
+ mflr r0 /* extract return address */
+ stw r0, 8(r1) /* save the return address */
+
+ /* 24 Bytes (Linkage Area) */
+ /* 32 Bytes (params) */
+ /* 104 Bytes (13*8 from FPR) */
+ /* 8 Bytes (result) */
+ /* 168 Bytes */
+
+ stwu r1,-176(r1) /* skip over caller save area
+ keep stack aligned to 16 */
+
+/* we want to build up an area for the parameters passed */
+/* in registers (both floating point and integer) */
+
+ /* we store gpr 3 to gpr 10 (aligned to 4)
+ in the parents outgoing area */
+ stw r3, 200(r1)
+ stw r4, 204(r1)
+ stw r5, 208(r1)
+ stw r6, 212(r1)
+ stw r7, 216(r1)
+ stw r8, 220(r1)
+ stw r9, 224(r1)
+ stw r10, 228(r1)
+
+ /* next save fpr 1 to fpr 13 (aligned to 8) */
+ stfd f1, 56(r1)
+ stfd f2, 64(r1)
+ stfd f3, 72(r1)
+ stfd f4, 80(r1)
+ stfd f5, 88(r1)
+ stfd f6, 96(r1)
+ stfd f7, 104(r1)
+ stfd f8, 112(r1)
+ stfd f9, 120(r1)
+ stfd f10, 128(r1)
+ stfd f11, 136(r1)
+ stfd f12, 144(r1)
+ stfd f13, 152(r1)
+
+ /* set up registers for the routine that actually does the work */
+ /* get the context pointer from the trampoline */
+ mr r3,r11
+
+ /* now load up the pointer to the result storage */
+ addi r4,r1,160
+
+ /* now load up the pointer to the saved gpr registers */
+ addi r5,r1,200
+
+ /* now load up the pointer to the saved fpr registers */
+ addi r6,r1,56
+
+ /* make the call */
+ bl .ffi_closure_helper_DARWIN
+ nop
+
+ /* now r3 contains the return type */
+ /* so use it to look up in a table */
+ /* so we know how to deal with each type */
+
+ /* look up the proper starting point in table */
+ /* by using return type as offset */
+ addi r5,r1,160 /* get pointer to results area */
+ lwz r4,LC..60(2) /* get address of jump table */
+ slwi r3,r3,2 /* now multiply return type by 4 */
+ lwzx r3,r4,r3 /* get the contents of that table value */
+ add r3,r3,r4 /* add contents of table to table address */
+ mtctr r3
+ bctr /* jump to it */
+
+L..60:
+ .long L..44-L..60 /* FFI_TYPE_VOID */
+ .long L..50-L..60 /* FFI_TYPE_INT */
+ .long L..47-L..60 /* FFI_TYPE_FLOAT */
+ .long L..46-L..60 /* FFI_TYPE_DOUBLE */
+ .long L..46-L..60 /* FFI_TYPE_LONGDOUBLE */
+ .long L..56-L..60 /* FFI_TYPE_UINT8 */
+ .long L..55-L..60 /* FFI_TYPE_SINT8 */
+ .long L..58-L..60 /* FFI_TYPE_UINT16 */
+ .long L..57-L..60 /* FFI_TYPE_SINT16 */
+ .long L..50-L..60 /* FFI_TYPE_UINT32 */
+ .long L..50-L..60 /* FFI_TYPE_SINT32 */
+ .long L..48-L..60 /* FFI_TYPE_UINT64 */
+ .long L..48-L..60 /* FFI_TYPE_SINT64 */
+ .long L..44-L..60 /* FFI_TYPE_STRUCT */
+ .long L..50-L..60 /* FFI_TYPE_POINTER */
+
+
+/* case double */
+L..46:
+ lfd f1,0(r5)
+ b L..44
+
+/* case float */
+L..47:
+ lfs f1,0(r5)
+ b L..44
+
+/* case long long */
+L..48:
+ lwz r3,0(r5)
+ lwz r4,4(r5)
+ b L..44
+
+/* case default / int32 / pointer */
+L..50:
+ lwz r3,0(r5)
+ b L..44
+
+/* case signed int8 */
+L..55:
+ addi r5,r5,3
+ lbz r3,0(r5)
+ slwi r3,r3,24
+ srawi r3,r3,24
+ b L..44
+
+/* case unsigned int8 */
+L..56:
+ addi r5,r5,3
+ lbz r3,0(r5)
+ b L..44
+
+/* case signed int16 */
+L..57:
+ addi r5,r5,2
+ lhz r3,0(r5)
+ extsh r3,r3
+ b L..44
+
+/* case unsigned int16 */
+L..58:
+ addi r5,r5,2
+ lhz r3,0(r5)
+
+/* case void / done */
+L..44:
+ addi r1,r1,176 /* restore stack pointer */
+ lwz r0,8(r1) /* get return address */
+ mtlr r0 /* reset link register */
+ blr
+
+/* END(ffi_closure_ASM) */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/asm.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/asm.h
new file mode 100644
index 000000000..e86e6b091
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/asm.h
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------
+ asm.h - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+
+#define C_SYMBOL_NAME(name) name
+/* Macro for a label. */
+#ifdef __STDC__
+#define C_LABEL(name) name##:
+#else
+#define C_LABEL(name) name/**/:
+#endif
+
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a the return address being on the stack
+ to locate our caller and so it can restore it; so store one just
+ for its benefit. */
+#ifdef PIC
+#define CALL_MCOUNT \
+ .pushsection; \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+0:.long 0; \
+ .previous; \
+ mflr %r0; \
+ stw %r0,4(%r1); \
+ bl _GLOBAL_OFFSET_TABLE_@local-4; \
+ mflr %r11; \
+ lwz %r0,0b@got(%r11); \
+ bl JUMPTARGET(_mcount);
+#else /* PIC */
+#define CALL_MCOUNT \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+0:.long 0; \
+ .previous; \
+ mflr %r0; \
+ lis %r11,0b@ha; \
+ stw %r0,4(%r1); \
+ addi %r0,%r11,0b@l; \
+ bl JUMPTARGET(_mcount);
+#endif /* PIC */
+#else /* PROF */
+#define CALL_MCOUNT /* Do nothing. */
+#endif /* PROF */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#ifdef PROF
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT \
+ b 0f; \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ 0:
+#else /* PROF */
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ C_LABEL(name)
+#endif
+
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
+#ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
+/* Local labels stripped out by the linker. */
+#define L(x) .L##x
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin.S
new file mode 100644
index 000000000..917dc9328
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin.S
@@ -0,0 +1,247 @@
+#ifdef __ppc__
+/* -----------------------------------------------------------------------
+ darwin.S - Copyright (c) 2000 John Hornkvist
+ Copyright (c) 2004 Free Software Foundation, Inc.
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */
+
+#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#define JUMPTARGET(name) name
+#define L(x) x
+.text
+ .align 2
+.globl _ffi_prep_args
+
+.text
+ .align 2
+.globl _ffi_call_DARWIN
+.text
+ .align 2
+_ffi_call_DARWIN:
+LFB0:
+ mr r12,r8 /* We only need r12 until the call,
+ so it doesn't have to be saved. */
+LFB1:
+ /* Save the old stack pointer as AP. */
+ mr r8,r1
+LCFI0:
+ /* Allocate the stack space we need. */
+ stwux r1,r1,r4
+
+ /* Save registers we use. */
+ mflr r9
+
+ stw r28,-16(r8)
+ stw r29,-12(r8)
+ stw r30,-8(r8)
+ stw r31,-4(r8)
+
+ stw r9,8(r8)
+ stw r2,20(r1)
+LCFI1:
+
+ /* Save arguments over call. */
+ mr r31,r5 /* flags, */
+ mr r30,r6 /* rvalue, */
+ mr r29,r7 /* function address, */
+ mr r28,r8 /* our AP. */
+LCFI2:
+ /* Call ffi_prep_args. */
+ mr r4,r1
+ li r9,0
+
+ mtctr r12 /* r12 holds address of _ffi_prep_args. */
+ bctrl
+ lwz r2,20(r1)
+
+ /* Now do the call.
+ Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40,r31
+ /* Get the address to call into CTR. */
+ mtctr r29
+ /* Load all those argument registers.
+ We have set up a nice stack frame, just load it into registers. */
+ lwz r3,20+(1*4)(r1)
+ lwz r4,20+(2*4)(r1)
+ lwz r5,20+(3*4)(r1)
+ lwz r6,20+(4*4)(r1)
+ nop
+ lwz r7,20+(5*4)(r1)
+ lwz r8,20+(6*4)(r1)
+ lwz r9,20+(7*4)(r1)
+ lwz r10,20+(8*4)(r1)
+
+L1:
+ /* Load all the FP registers. */
+ bf 6,L2 /* No floats to load. */
+ lfd f1,-16-(13*8)(r28)
+ lfd f2,-16-(12*8)(r28)
+ lfd f3,-16-(11*8)(r28)
+ lfd f4,-16-(10*8)(r28)
+ nop
+ lfd f5,-16-(9*8)(r28)
+ lfd f6,-16-(8*8)(r28)
+ lfd f7,-16-(7*8)(r28)
+ lfd f8,-16-(6*8)(r28)
+ nop
+ lfd f9,-16-(5*8)(r28)
+ lfd f10,-16-(4*8)(r28)
+ lfd f11,-16-(3*8)(r28)
+ lfd f12,-16-(2*8)(r28)
+ nop
+ lfd f13,-16-(1*8)(r28)
+
+L2:
+ mr r12,r29 /* Put the target address in r12 as specified. */
+ mtctr r12
+ nop
+ nop
+ /* Make the call. */
+ bctrl
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01,r31
+
+ bt 30,L(done_return_value)
+ bt 29,L(fp_return_value)
+ stw r3,0(r30)
+ bf 28,L(done_return_value)
+ stw r4,4(r30)
+
+ /* Fall through. */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ lwz r9,8(r28)
+ lwz r31,-4(r28)
+ mtlr r9
+ lwz r30,-8(r28)
+ lwz r29,-12(r28)
+ lwz r28,-16(r28)
+ lwz r1,0(r1)
+ blr
+
+L(fp_return_value):
+ /* Do we have long double to store? */
+ bf 31,L(fd_return_value)
+ stfd f1,0(r30)
+ stfd f2,8(r30)
+ b L(done_return_value)
+
+L(fd_return_value):
+ /* Do we have double to store? */
+ bf 28,L(float_return_value)
+ stfd f1,0(r30)
+ b L(done_return_value)
+
+L(float_return_value):
+ /* We only have a float to store. */
+ stfs f1,0(r30)
+ b L(done_return_value)
+
+LFE1:
+/* END(_ffi_call_DARWIN) */
+
+/* Provide a null definition of _ffi_call_AIX. */
+.text
+ .align 2
+.globl _ffi_call_AIX
+.text
+ .align 2
+_ffi_call_AIX:
+ blr
+/* END(_ffi_call_AIX) */
+
+.data
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
+EH_frame1:
+ .set L$set$0,LECIE1-LSCIE1
+ .long L$set$0 ; Length of Common Information Entry
+LSCIE1:
+ .long 0x0 ; CIE Identifier Tag
+ .byte 0x1 ; CIE Version
+ .ascii "zR\0" ; CIE Augmentation
+ .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
+ .byte 0x41 ; CIE RA Column
+ .byte 0x1 ; uleb128 0x1; Augmentation size
+ .byte 0x90 ; FDE Encoding (indirect pcrel)
+ .byte 0xc ; DW_CFA_def_cfa
+ .byte 0x1 ; uleb128 0x1
+ .byte 0x0 ; uleb128 0x0
+ .align LOG2_GPR_BYTES
+LECIE1:
+.globl _ffi_call_DARWIN.eh
+_ffi_call_DARWIN.eh:
+LSFDE1:
+ .set L$set$1,LEFDE1-LASFDE1
+ .long L$set$1 ; FDE Length
+LASFDE1:
+ .long LASFDE1-EH_frame1 ; FDE CIE offset
+ .g_long LLFB0$non_lazy_ptr-. ; FDE initial location
+ .set L$set$3,LFE1-LFB0
+ .g_long L$set$3 ; FDE address range
+ .byte 0x0 ; uleb128 0x0; Augmentation size
+ .byte 0x4 ; DW_CFA_advance_loc4
+ .set L$set$4,LCFI0-LFB1
+ .long L$set$4
+ .byte 0xd ; DW_CFA_def_cfa_register
+ .byte 0x08 ; uleb128 0x08
+ .byte 0x4 ; DW_CFA_advance_loc4
+ .set L$set$5,LCFI1-LCFI0
+ .long L$set$5
+ .byte 0x11 ; DW_CFA_offset_extended_sf
+ .byte 0x41 ; uleb128 0x41
+ .byte 0x7e ; sleb128 -2
+ .byte 0x9f ; DW_CFA_offset, column 0x1f
+ .byte 0x1 ; uleb128 0x1
+ .byte 0x9e ; DW_CFA_offset, column 0x1e
+ .byte 0x2 ; uleb128 0x2
+ .byte 0x9d ; DW_CFA_offset, column 0x1d
+ .byte 0x3 ; uleb128 0x3
+ .byte 0x9c ; DW_CFA_offset, column 0x1c
+ .byte 0x4 ; uleb128 0x4
+ .byte 0x4 ; DW_CFA_advance_loc4
+ .set L$set$6,LCFI2-LCFI1
+ .long L$set$6
+ .byte 0xd ; DW_CFA_def_cfa_register
+ .byte 0x1c ; uleb128 0x1c
+ .align LOG2_GPR_BYTES
+LEFDE1:
+.data
+ .align LOG2_GPR_BYTES
+LLFB0$non_lazy_ptr:
+ .g_long LFB0
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
new file mode 100644
index 000000000..71054f5f0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
@@ -0,0 +1,319 @@
+#ifdef __ppc__
+/* -----------------------------------------------------------------------
+ darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
+ Inc. based on ppc_closure.S
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#define L(x) x
+
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define lgu MODE_CHOICE(lwzu, ldu)
+
+#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */
+
+#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */
+
+ .file "darwin_closure.S"
+.text
+ .align LOG2_GPR_BYTES
+.globl _ffi_closure_ASM
+
+.text
+ .align LOG2_GPR_BYTES
+_ffi_closure_ASM:
+LFB1:
+ mflr r0 /* extract return address */
+ stw r0,8(r1) /* save the return address */
+LCFI0:
+ /* 24 Bytes (Linkage Area)
+ 32 Bytes (outgoing parameter area, always reserved)
+ 104 Bytes (13*8 from FPR)
+ 16 Bytes (result)
+ 176 Bytes */
+
+ stwu r1,-176(r1) /* skip over caller save area
+ keep stack aligned to 16. */
+LCFI1:
+ /* We want to build up an area for the parameters passed
+ in registers. (both floating point and integer) */
+
+ /* We store gpr 3 to gpr 10 (aligned to 4)
+ in the parents outgoing area. */
+ stw r3,200(r1)
+ stw r4,204(r1)
+ stw r5,208(r1)
+ stw r6,212(r1)
+ stw r7,216(r1)
+ stw r8,220(r1)
+ stw r9,224(r1)
+ stw r10,228(r1)
+
+ /* We save fpr 1 to fpr 13. (aligned to 8) */
+ stfd f1,56(r1)
+ stfd f2,64(r1)
+ stfd f3,72(r1)
+ stfd f4,80(r1)
+ stfd f5,88(r1)
+ stfd f6,96(r1)
+ stfd f7,104(r1)
+ stfd f8,112(r1)
+ stfd f9,120(r1)
+ stfd f10,128(r1)
+ stfd f11,136(r1)
+ stfd f12,144(r1)
+ stfd f13,152(r1)
+
+ /* Set up registers for the routine that actually does the work
+ get the context pointer from the trampoline. */
+ mr r3,r11
+
+ /* Now load up the pointer to the result storage. */
+ addi r4,r1,160
+
+ /* Now load up the pointer to the saved gpr registers. */
+ addi r5,r1,200
+
+ /* Now load up the pointer to the saved fpr registers. */
+ addi r6,r1,56
+
+ /* Make the call. */
+ bl Lffi_closure_helper_DARWIN$stub
+
+ /* Now r3 contains the return type
+ so use it to look up in a table
+ so we know how to deal with each type. */
+
+ /* Look up the proper starting point in table
+ by using return type as offset. */
+ addi r5,r1,160 /* Get pointer to results area. */
+ bl Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR. */
+ mflr r4 /* Move to r4. */
+ slwi r3,r3,4 /* Now multiply return type by 16. */
+ add r3,r3,r4 /* Add contents of table to table address. */
+ mtctr r3
+ bctr /* Jump to it. */
+LFE1:
+/* Each of the ret_typeX code fragments has to be exactly 16 bytes long
+ (4 instructions). For cache effectiveness we align to a 16 byte boundary
+ first. */
+
+ .align 4
+
+ nop
+ nop
+ nop
+Lget_ret_type0_addr:
+ blrl
+
+/* case FFI_TYPE_VOID */
+Lret_type0:
+ b Lfinish
+ nop
+ nop
+ nop
+
+/* case FFI_TYPE_INT */
+Lret_type1:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_FLOAT */
+Lret_type2:
+ lfs f1,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_DOUBLE */
+Lret_type3:
+ lfd f1,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_LONGDOUBLE */
+Lret_type4:
+ lfd f1,0(r5)
+ lfd f2,8(r5)
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_UINT8 */
+Lret_type5:
+ lbz r3,3(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_SINT8 */
+Lret_type6:
+ lbz r3,3(r5)
+ extsb r3,r3
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_UINT16 */
+Lret_type7:
+ lhz r3,2(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_SINT16 */
+Lret_type8:
+ lha r3,2(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_UINT32 */
+Lret_type9:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_SINT32 */
+Lret_type10:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_UINT64 */
+Lret_type11:
+ lwz r3,0(r5)
+ lwz r4,4(r5)
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_SINT64 */
+Lret_type12:
+ lwz r3,0(r5)
+ lwz r4,4(r5)
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_STRUCT */
+Lret_type13:
+ b Lfinish
+ nop
+ nop
+ nop
+
+/* case FFI_TYPE_POINTER */
+Lret_type14:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case done */
+Lfinish:
+ addi r1,r1,176 /* Restore stack pointer. */
+ lwz r0,8(r1) /* Get return address. */
+ mtlr r0 /* Reset link register. */
+ blr
+
+/* END(ffi_closure_ASM) */
+
+.data
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
+EH_frame1:
+ .set L$set$0,LECIE1-LSCIE1
+ .long L$set$0 ; Length of Common Information Entry
+LSCIE1:
+ .long 0x0 ; CIE Identifier Tag
+ .byte 0x1 ; CIE Version
+ .ascii "zR\0" ; CIE Augmentation
+ .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
+ .byte 0x41 ; CIE RA Column
+ .byte 0x1 ; uleb128 0x1; Augmentation size
+ .byte 0x90 ; FDE Encoding (indirect pcrel)
+ .byte 0xc ; DW_CFA_def_cfa
+ .byte 0x1 ; uleb128 0x1
+ .byte 0x0 ; uleb128 0x0
+ .align LOG2_GPR_BYTES
+LECIE1:
+.globl _ffi_closure_ASM.eh
+_ffi_closure_ASM.eh:
+LSFDE1:
+ .set L$set$1,LEFDE1-LASFDE1
+ .long L$set$1 ; FDE Length
+
+LASFDE1:
+ .long LASFDE1-EH_frame1 ; FDE CIE offset
+ .g_long LLFB1$non_lazy_ptr-. ; FDE initial location
+ .set L$set$3,LFE1-LFB1
+ .g_long L$set$3 ; FDE address range
+ .byte 0x0 ; uleb128 0x0; Augmentation size
+ .byte 0x4 ; DW_CFA_advance_loc4
+ .set L$set$3,LCFI1-LCFI0
+ .long L$set$3
+ .byte 0xe ; DW_CFA_def_cfa_offset
+ .byte 176,1 ; uleb128 176
+ .byte 0x4 ; DW_CFA_advance_loc4
+ .set L$set$4,LCFI0-LFB1
+ .long L$set$4
+ .byte 0x11 ; DW_CFA_offset_extended_sf
+ .byte 0x41 ; uleb128 0x41
+ .byte 0x7e ; sleb128 -2
+ .align LOG2_GPR_BYTES
+LEFDE1:
+.data
+ .align LOG2_GPR_BYTES
+LDFCM0:
+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+ .align LOG2_GPR_BYTES
+Lffi_closure_helper_DARWIN$stub:
+#if 1
+ .indirect_symbol _ffi_closure_helper_DARWIN
+ mflr r0
+ bcl 20,31,LO$ffi_closure_helper_DARWIN
+LO$ffi_closure_helper_DARWIN:
+ mflr r11
+ addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)
+ mtlr r0
+ lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11)
+ mtctr r12
+ bctr
+.lazy_symbol_pointer
+L_ffi_closure_helper_DARWIN$lazy_ptr:
+ .indirect_symbol _ffi_closure_helper_DARWIN
+ .g_long dyld_stub_binding_helper
+#endif
+.data
+ .align LOG2_GPR_BYTES
+LLFB1$non_lazy_ptr:
+ .g_long LFB1
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi.c
new file mode 100644
index 000000000..bfd7ab676
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi.c
@@ -0,0 +1,1249 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+extern void ffi_closure_SYSV (void);
+extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
+
+enum {
+ /* The assembly depends on these exact flags. */
+ FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */
+ FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
+ FLAG_RETURNS_FP = 1 << (31-29),
+ FLAG_RETURNS_64BITS = 1 << (31-28),
+ FLAG_RETURNS_128BITS = 1 << (31-27),
+
+ FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
+ FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
+ FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
+ FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the SYSV ABI. */
+enum {
+ NUM_GPR_ARG_REGISTERS = 8,
+ NUM_FPR_ARG_REGISTERS = 8
+};
+enum { ASM_NEEDS_REGISTERS = 4 };
+
+/* ffi_prep_args_SYSV is called by the assembly routine once stack space
+ has been allocated for the function's arguments.
+
+ The stack layout we want looks like this:
+
+ | Return address from ffi_call_SYSV 4bytes | higher addresses
+ |--------------------------------------------|
+ | Previous backchain pointer 4 | stack pointer here
+ |--------------------------------------------|<+ <<< on entry to
+ | Saved r28-r31 4*4 | | ffi_call_SYSV
+ |--------------------------------------------| |
+ | GPR registers r3-r10 8*4 | | ffi_call_SYSV
+ |--------------------------------------------| |
+ | FPR registers f1-f8 (optional) 8*8 | |
+ |--------------------------------------------| | stack |
+ | Space for copied structures | | grows |
+ |--------------------------------------------| | down V
+ | Parameters that didn't fit in registers | |
+ |--------------------------------------------| | lower addresses
+ | Space for callee's LR 4 | |
+ |--------------------------------------------| | stack pointer here
+ | Current backchain pointer 4 |-/ during
+ |--------------------------------------------| <<< ffi_call_SYSV
+
+*/
+
+/*@-exportheader@*/
+void
+ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
+/*@=exportheader@*/
+{
+ const unsigned bytes = ecif->cif->bytes;
+ const unsigned flags = ecif->cif->flags;
+
+ typedef union {
+ char *c;
+ unsigned *u;
+ long long *ll;
+ float *f;
+ double *d;
+ } valp;
+
+ /* 'stacktop' points at the previous backchain pointer. */
+ valp stacktop;
+
+ /* 'gpr_base' points at the space for gpr3, and grows upwards as
+ we use GPR registers. */
+ valp gpr_base;
+ int intarg_count;
+
+ /* 'fpr_base' points at the space for fpr1, and grows upwards as
+ we use FPR registers. */
+ valp fpr_base;
+ int fparg_count;
+
+ /* 'copy_space' grows down as we put structures in it. It should
+ stay 16-byte aligned. */
+ valp copy_space;
+
+ /* 'next_arg' grows up as we put parameters in it. */
+ valp next_arg;
+
+ int i;
+ ffi_type **ptr;
+ double double_tmp;
+ union {
+ void **v;
+ char **c;
+ signed char **sc;
+ unsigned char **uc;
+ signed short **ss;
+ unsigned short **us;
+ unsigned int **ui;
+ long long **ll;
+ float **f;
+ double **d;
+ } p_argv;
+ size_t struct_copy_size;
+ unsigned gprvalue;
+
+ stacktop.c = (char *) stack + bytes;
+ gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+ intarg_count = 0;
+ fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
+ fparg_count = 0;
+ copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
+ next_arg.u = stack + 2;
+
+ /* Check that everything starts aligned properly. */
+ FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
+ FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
+ FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
+ FFI_ASSERT ((bytes & 0xF) == 0);
+ FFI_ASSERT (copy_space.c >= next_arg.c);
+
+ /* Deal with return values that are actually pass-by-reference. */
+ if (flags & FLAG_RETVAL_REFERENCE)
+ {
+ *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
+ intarg_count++;
+ }
+
+ /* Now for the arguments. */
+ p_argv.v = ecif->avalue;
+ for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+ i > 0;
+ i--, ptr++, p_argv.v++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ double_tmp = **p_argv.f;
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ {
+ *next_arg.f = (float) double_tmp;
+ next_arg.u += 1;
+ }
+ else
+ *fpr_base.d++ = double_tmp;
+ fparg_count++;
+ FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ double_tmp = **p_argv.d;
+
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ {
+ if (intarg_count >= NUM_GPR_ARG_REGISTERS
+ && intarg_count % 2 != 0)
+ {
+ intarg_count++;
+ next_arg.u++;
+ }
+ *next_arg.d = double_tmp;
+ next_arg.u += 2;
+ }
+ else
+ *fpr_base.d++ = double_tmp;
+ fparg_count++;
+ FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
+ intarg_count++;
+ if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+ {
+ if (intarg_count % 2 != 0)
+ {
+ intarg_count++;
+ next_arg.u++;
+ }
+ *next_arg.ll = **p_argv.ll;
+ next_arg.u += 2;
+ }
+ else
+ {
+ /* whoops: abi states only certain register pairs
+ * can be used for passing long long int
+ * specifically (r3,r4), (r5,r6), (r7,r8),
+ * (r9,r10) and if next arg is long long but
+ * not correct starting register of pair then skip
+ * until the proper starting register
+ */
+ if (intarg_count % 2 != 0)
+ {
+ intarg_count ++;
+ gpr_base.u++;
+ }
+ *gpr_base.ll++ = **p_argv.ll;
+ }
+ intarg_count += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ struct_copy_size = ((*ptr)->size + 15) & ~0xF;
+ copy_space.c -= struct_copy_size;
+ memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
+
+ gprvalue = (unsigned long) copy_space.c;
+
+ FFI_ASSERT (copy_space.c > next_arg.c);
+ FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
+ goto putgpr;
+
+ case FFI_TYPE_UINT8:
+ gprvalue = **p_argv.uc;
+ goto putgpr;
+ case FFI_TYPE_SINT8:
+ gprvalue = **p_argv.sc;
+ goto putgpr;
+ case FFI_TYPE_UINT16:
+ gprvalue = **p_argv.us;
+ goto putgpr;
+ case FFI_TYPE_SINT16:
+ gprvalue = **p_argv.ss;
+ goto putgpr;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_POINTER:
+ gprvalue = **p_argv.ui;
+
+ putgpr:
+ if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+ *next_arg.u++ = gprvalue;
+ else
+ *gpr_base.u++ = gprvalue;
+ intarg_count++;
+ break;
+ }
+ }
+
+ /* Check that we didn't overrun the stack... */
+ FFI_ASSERT (copy_space.c >= next_arg.c);
+ FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
+ FFI_ASSERT (fpr_base.u
+ <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+ FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+/* About the LINUX64 ABI. */
+enum {
+ NUM_GPR_ARG_REGISTERS64 = 8,
+ NUM_FPR_ARG_REGISTERS64 = 13
+};
+enum { ASM_NEEDS_REGISTERS64 = 4 };
+
+/* ffi_prep_args64 is called by the assembly routine once stack space
+ has been allocated for the function's arguments.
+
+ The stack layout we want looks like this:
+
+ | Ret addr from ffi_call_LINUX64 8bytes | higher addresses
+ |--------------------------------------------|
+ | CR save area 8bytes |
+ |--------------------------------------------|
+ | Previous backchain pointer 8 | stack pointer here
+ |--------------------------------------------|<+ <<< on entry to
+ | Saved r28-r31 4*8 | | ffi_call_LINUX64
+ |--------------------------------------------| |
+ | GPR registers r3-r10 8*8 | |
+ |--------------------------------------------| |
+ | FPR registers f1-f13 (optional) 13*8 | |
+ |--------------------------------------------| |
+ | Parameter save area | |
+ |--------------------------------------------| |
+ | TOC save area 8 | |
+ |--------------------------------------------| | stack |
+ | Linker doubleword 8 | | grows |
+ |--------------------------------------------| | down V
+ | Compiler doubleword 8 | |
+ |--------------------------------------------| | lower addresses
+ | Space for callee's LR 8 | |
+ |--------------------------------------------| |
+ | CR save area 8 | |
+ |--------------------------------------------| | stack pointer here
+ | Current backchain pointer 8 |-/ during
+ |--------------------------------------------| <<< ffi_call_LINUX64
+
+*/
+
+/*@-exportheader@*/
+void FFI_HIDDEN
+ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
+/*@=exportheader@*/
+{
+ const unsigned long bytes = ecif->cif->bytes;
+ const unsigned long flags = ecif->cif->flags;
+
+ typedef union {
+ char *c;
+ unsigned long *ul;
+ float *f;
+ double *d;
+ } valp;
+
+ /* 'stacktop' points at the previous backchain pointer. */
+ valp stacktop;
+
+ /* 'next_arg' points at the space for gpr3, and grows upwards as
+ we use GPR registers, then continues at rest. */
+ valp gpr_base;
+ valp gpr_end;
+ valp rest;
+ valp next_arg;
+
+ /* 'fpr_base' points at the space for fpr3, and grows upwards as
+ we use FPR registers. */
+ valp fpr_base;
+ int fparg_count;
+
+ int i, words;
+ ffi_type **ptr;
+ double double_tmp;
+ union {
+ void **v;
+ char **c;
+ signed char **sc;
+ unsigned char **uc;
+ signed short **ss;
+ unsigned short **us;
+ signed int **si;
+ unsigned int **ui;
+ unsigned long **ul;
+ float **f;
+ double **d;
+ } p_argv;
+ unsigned long gprvalue;
+
+ stacktop.c = (char *) stack + bytes;
+ gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
+ gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
+ rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
+ fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
+ fparg_count = 0;
+ next_arg.ul = gpr_base.ul;
+
+ /* Check that everything starts aligned properly. */
+ FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
+ FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
+ FFI_ASSERT ((bytes & 0xF) == 0);
+
+ /* Deal with return values that are actually pass-by-reference. */
+ if (flags & FLAG_RETVAL_REFERENCE)
+ *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
+
+ /* Now for the arguments. */
+ p_argv.v = ecif->avalue;
+ for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+ i > 0;
+ i--, ptr++, p_argv.v++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ double_tmp = **p_argv.f;
+ *next_arg.f = (float) double_tmp;
+ if (++next_arg.ul == gpr_end.ul)
+ next_arg.ul = rest.ul;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+ *fpr_base.d++ = double_tmp;
+ fparg_count++;
+ FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ double_tmp = **p_argv.d;
+ *next_arg.d = double_tmp;
+ if (++next_arg.ul == gpr_end.ul)
+ next_arg.ul = rest.ul;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+ *fpr_base.d++ = double_tmp;
+ fparg_count++;
+ FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ double_tmp = (*p_argv.d)[0];
+ *next_arg.d = double_tmp;
+ if (++next_arg.ul == gpr_end.ul)
+ next_arg.ul = rest.ul;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+ *fpr_base.d++ = double_tmp;
+ fparg_count++;
+ double_tmp = (*p_argv.d)[1];
+ *next_arg.d = double_tmp;
+ if (++next_arg.ul == gpr_end.ul)
+ next_arg.ul = rest.ul;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+ *fpr_base.d++ = double_tmp;
+ fparg_count++;
+ FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ break;
+#endif
+
+ case FFI_TYPE_STRUCT:
+ words = ((*ptr)->size + 7) / 8;
+ if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
+ {
+ size_t first = gpr_end.c - next_arg.c;
+ memcpy (next_arg.c, *p_argv.c, first);
+ memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
+ next_arg.c = rest.c + words * 8 - first;
+ }
+ else
+ {
+ char *where = next_arg.c;
+
+ /* Structures with size less than eight bytes are passed
+ left-padded. */
+ if ((*ptr)->size < 8)
+ where += 8 - (*ptr)->size;
+
+ memcpy (where, *p_argv.c, (*ptr)->size);
+ next_arg.ul += words;
+ if (next_arg.ul == gpr_end.ul)
+ next_arg.ul = rest.ul;
+ }
+ break;
+
+ case FFI_TYPE_UINT8:
+ gprvalue = **p_argv.uc;
+ goto putgpr;
+ case FFI_TYPE_SINT8:
+ gprvalue = **p_argv.sc;
+ goto putgpr;
+ case FFI_TYPE_UINT16:
+ gprvalue = **p_argv.us;
+ goto putgpr;
+ case FFI_TYPE_SINT16:
+ gprvalue = **p_argv.ss;
+ goto putgpr;
+ case FFI_TYPE_UINT32:
+ gprvalue = **p_argv.ui;
+ goto putgpr;
+ case FFI_TYPE_INT:
+ case FFI_TYPE_SINT32:
+ gprvalue = **p_argv.si;
+ goto putgpr;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_POINTER:
+ gprvalue = **p_argv.ul;
+ putgpr:
+ *next_arg.ul++ = gprvalue;
+ if (next_arg.ul == gpr_end.ul)
+ next_arg.ul = rest.ul;
+ break;
+ }
+ }
+
+ FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
+ || (next_arg.ul >= gpr_base.ul
+ && next_arg.ul <= gpr_base.ul + 4));
+}
+
+
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+ /* All this is for the SYSV and LINUX64 ABI. */
+ int i;
+ ffi_type **ptr;
+ unsigned bytes;
+ int fparg_count = 0, intarg_count = 0;
+ unsigned flags = 0;
+ unsigned struct_copy_size = 0;
+ unsigned type = cif->rtype->type;
+ unsigned size = cif->rtype->size;
+
+ if (cif->abi != FFI_LINUX64)
+ {
+ /* All the machine-independent calculation of cif->bytes will be wrong.
+ Redo the calculation for SYSV. */
+
+ /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
+ bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
+
+ /* Space for the GPR registers. */
+ bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
+ }
+ else
+ {
+ /* 64-bit ABI. */
+
+ /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
+ regs. */
+ bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
+
+ /* Space for the mandatory parm save area and general registers. */
+ bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ if (type == FFI_TYPE_LONGDOUBLE)
+ type = FFI_TYPE_DOUBLE;
+#endif
+ }
+
+ /* Return value handling. The rules for SYSV are as follows:
+ - 32-bit (or less) integer values are returned in gpr3;
+ - Structures of size <= 4 bytes also returned in gpr3;
+ - 64-bit integer values and structures between 5 and 8 bytes are returned
+ in gpr3 and gpr4;
+ - Single/double FP values are returned in fpr1;
+ - Larger structures and long double (if not equivalent to double) values
+ are allocated space and a pointer is passed as the first argument.
+ For LINUX64:
+ - integer values in gpr3;
+ - Structures/Unions by reference;
+ - Single/double FP values in fpr1, long double in fpr1,fpr2. */
+ switch (type)
+ {
+ case FFI_TYPE_DOUBLE:
+ flags |= FLAG_RETURNS_64BITS;
+ /* Fall through. */
+ case FFI_TYPE_FLOAT:
+ flags |= FLAG_RETURNS_FP;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ flags |= FLAG_RETURNS_64BITS;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->abi == FFI_SYSV)
+ {
+ /* The final SYSV ABI says that structures smaller or equal 8 bytes
+ are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
+ in memory. */
+
+ /* Treat structs with size <= 8 bytes. */
+ if (size <= 8)
+ {
+ flags |= FLAG_RETURNS_SMST;
+ /* These structs are returned in r3. We pack the type and the
+ precalculated shift value (needed in the sysv.S) into flags.
+ The same applies for the structs returned in r3/r4. */
+ if (size <= 4)
+ {
+ flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
+ flags |= 8 * (4 - size) << 4;
+ break;
+ }
+ /* These structs are returned in r3 and r4. See above. */
+ if (size <= 8)
+ {
+ flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
+ flags |= 8 * (8 - size) << 4;
+ break;
+ }
+ }
+ }
+ /* else fall through. */
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
+ {
+ flags |= FLAG_RETURNS_128BITS;
+ flags |= FLAG_RETURNS_FP;
+ break;
+ }
+#endif
+ intarg_count++;
+ flags |= FLAG_RETVAL_REFERENCE;
+ /* Fall through. */
+ case FFI_TYPE_VOID:
+ flags |= FLAG_RETURNS_NOTHING;
+ break;
+
+ default:
+ /* Returns 32-bit integer, or similar. Nothing to do here. */
+ break;
+ }
+
+ if (cif->abi != FFI_LINUX64)
+ /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+ first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+ goes on the stack. Structures and long doubles (if not equivalent
+ to double) are passed as a pointer to a copy of the structure.
+ Stuff on the stack needs to keep proper alignment. */
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ fparg_count++;
+ /* floating singles are not 8-aligned on stack */
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ fparg_count++;
+ /* If this FP arg is going on the stack, it must be
+ 8-byte-aligned. */
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
+ && intarg_count >= NUM_GPR_ARG_REGISTERS
+ && intarg_count % 2 != 0)
+ intarg_count++;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ /* 'long long' arguments are passed as two words, but
+ either both words must fit in registers or both go
+ on the stack. If they go on the stack, they must
+ be 8-byte-aligned.
+
+ Also, only certain register pairs can be used for
+ passing long long int -- specifically (r3,r4), (r5,r6),
+ (r7,r8), (r9,r10).
+ */
+ if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+ || intarg_count % 2 != 0)
+ intarg_count++;
+ intarg_count += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ /* We must allocate space for a copy of these to enforce
+ pass-by-value. Pad the space up to a multiple of 16
+ bytes (the maximum alignment required for anything under
+ the SYSV ABI). */
+ struct_copy_size += ((*ptr)->size + 15) & ~0xF;
+ /* Fall through (allocate space for the pointer). */
+
+ default:
+ /* Everything else is passed as a 4-byte word in a GPR, either
+ the object itself or a pointer to it. */
+ intarg_count++;
+ break;
+ }
+ }
+ else
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ switch ((*ptr)->type)
+ {
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ fparg_count += 2;
+ intarg_count += 2;
+ break;
+#endif
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ fparg_count++;
+ intarg_count++;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ intarg_count += ((*ptr)->size + 7) / 8;
+ break;
+
+ default:
+ /* Everything else is passed as a 8-byte word in a GPR, either
+ the object itself or a pointer to it. */
+ intarg_count++;
+ break;
+ }
+ }
+
+ if (fparg_count != 0)
+ flags |= FLAG_FP_ARGUMENTS;
+ if (intarg_count > 4)
+ flags |= FLAG_4_GPR_ARGUMENTS;
+ if (struct_copy_size != 0)
+ flags |= FLAG_ARG_NEEDS_COPY;
+
+ if (cif->abi != FFI_LINUX64)
+ {
+ /* Space for the FPR registers, if needed. */
+ if (fparg_count != 0)
+ bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
+
+ /* Stack space. */
+ if (intarg_count > NUM_GPR_ARG_REGISTERS)
+ bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
+ if (fparg_count > NUM_FPR_ARG_REGISTERS)
+ bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
+ }
+ else
+ {
+ /* Space for the FPR registers, if needed. */
+ if (fparg_count != 0)
+ bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
+
+ /* Stack space. */
+ if (intarg_count > NUM_GPR_ARG_REGISTERS64)
+ bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
+ }
+
+ /* The stack space allocated needs to be a multiple of 16 bytes. */
+ bytes = (bytes + 15) & ~0xF;
+
+ /* Add in the space for the copied structures. */
+ bytes += struct_copy_size;
+
+ cif->flags = flags;
+ cif->bytes = bytes;
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *,
+ unsigned long, unsigned long,
+ /*@out@*/ unsigned long *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void
+ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+#ifndef POWERPC64
+ case FFI_SYSV:
+ case FFI_GCC_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#else
+ case FFI_LINUX64:
+ /*@-usedef@*/
+ ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+}
+
+
+#ifndef POWERPC64
+#define MIN_CACHE_LINE_SIZE 8
+
+static void
+flush_icache (char *addr1, int size)
+{
+ int i;
+ char * addr;
+ for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
+ {
+ addr = addr1 + i;
+ __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;"
+ : : "r" (addr) : "memory");
+ }
+ addr = addr1 + size - 1;
+ __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;"
+ : : "r"(addr) : "memory");
+}
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+ ffi_cif *cif,
+ void (*fun) (ffi_cif *, void *, void **, void *),
+ void *user_data)
+{
+#ifdef POWERPC64
+ void **tramp = (void **) &closure->tramp[0];
+
+ FFI_ASSERT (cif->abi == FFI_LINUX64);
+ /* Copy function address and TOC from ffi_closure_LINUX64. */
+ memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
+ tramp[2] = (void *) closure;
+#else
+ unsigned int *tramp;
+
+ FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ tramp[0] = 0x7c0802a6; /* mflr r0 */
+ tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
+ tramp[4] = 0x7d6802a6; /* mflr r11 */
+ tramp[5] = 0x7c0803a6; /* mtlr r0 */
+ tramp[6] = 0x800b0000; /* lwz r0,0(r11) */
+ tramp[7] = 0x816b0004; /* lwz r11,4(r11) */
+ tramp[8] = 0x7c0903a6; /* mtctr r0 */
+ tramp[9] = 0x4e800420; /* bctr */
+ *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
+ *(void **) &tramp[3] = (void *) closure; /* context */
+
+ /* Flush the icache. */
+ flush_icache (&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+#endif
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ return FFI_OK;
+}
+
+typedef union
+{
+ float f;
+ double d;
+} ffi_dblfl;
+
+int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
+ ffi_dblfl *, unsigned long *);
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on
+ * entry, r11 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the
+ * following helper function to do most of the work
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
+ unsigned long *pgr, ffi_dblfl *pfr,
+ unsigned long *pst)
+{
+ /* rvalue is the pointer to space for return value in closure assembly */
+ /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
+ /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
+ /* pst is the pointer to outgoing parameter stack in original caller */
+
+ void ** avalue;
+ ffi_type ** arg_types;
+ long i, avn;
+ long nf; /* number of floating registers already used */
+ long ng; /* number of general registers already used */
+ ffi_cif * cif;
+ double temp;
+ unsigned size;
+
+ cif = closure->cif;
+ avalue = alloca (cif->nargs * sizeof (void *));
+ size = cif->rtype->size;
+
+ nf = 0;
+ ng = 0;
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller.
+ For FFI_SYSV the result is passed in r3/r4 if the struct size is less
+ or equal 8 bytes. */
+
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ if (!((cif->abi == FFI_SYSV) && (size <= 8)))
+ {
+ rvalue = (void *) *pgr;
+ ng++;
+ pgr++;
+ }
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ /* there are 8 gpr registers used to pass values */
+ if (ng < 8)
+ {
+ avalue[i] = (char *) pgr + 3;
+ ng++;
+ pgr++;
+ }
+ else
+ {
+ avalue[i] = (char *) pst + 3;
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ /* there are 8 gpr registers used to pass values */
+ if (ng < 8)
+ {
+ avalue[i] = (char *) pgr + 2;
+ ng++;
+ pgr++;
+ }
+ else
+ {
+ avalue[i] = (char *) pst + 2;
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ /* there are 8 gpr registers used to pass values */
+ if (ng < 8)
+ {
+ avalue[i] = pgr;
+ ng++;
+ pgr++;
+ }
+ else
+ {
+ avalue[i] = pst;
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* Structs are passed by reference. The address will appear in a
+ gpr if it is one of the first 8 arguments. */
+ if (ng < 8)
+ {
+ avalue[i] = (void *) *pgr;
+ ng++;
+ pgr++;
+ }
+ else
+ {
+ avalue[i] = (void *) *pst;
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ /* passing long long ints are complex, they must
+ * be passed in suitable register pairs such as
+ * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
+ * and if the entire pair aren't available then the outgoing
+ * parameter stack is used for both but an alignment of 8
+ * must will be kept. So we must either look in pgr
+ * or pst to find the correct address for this type
+ * of parameter.
+ */
+ if (ng < 7)
+ {
+ if (ng & 0x01)
+ {
+ /* skip r4, r6, r8 as starting points */
+ ng++;
+ pgr++;
+ }
+ avalue[i] = pgr;
+ ng += 2;
+ pgr += 2;
+ }
+ else
+ {
+ if (((long) pst) & 4)
+ pst++;
+ avalue[i] = pst;
+ pst += 2;
+ }
+ break;
+
+ case FFI_TYPE_FLOAT:
+ /* unfortunately float values are stored as doubles
+ * in the ffi_closure_SYSV code (since we don't check
+ * the type in that routine).
+ */
+
+ /* there are 8 64bit floating point registers */
+
+ if (nf < 8)
+ {
+ temp = pfr->d;
+ pfr->f = (float) temp;
+ avalue[i] = pfr;
+ nf++;
+ pfr++;
+ }
+ else
+ {
+ /* FIXME? here we are really changing the values
+ * stored in the original calling routines outgoing
+ * parameter stack. This is probably a really
+ * naughty thing to do but...
+ */
+ avalue[i] = pst;
+ nf++;
+ pst += 1;
+ }
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ /* On the outgoing stack all values are aligned to 8 */
+ /* there are 8 64bit floating point registers */
+
+ if (nf < 8)
+ {
+ avalue[i] = pfr;
+ nf++;
+ pfr++;
+ }
+ else
+ {
+ if (((long) pst) & 4)
+ pst++;
+ avalue[i] = pst;
+ nf++;
+ pst += 2;
+ }
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ }
+
+ i++;
+ }
+
+
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_SYSV how to perform return type promotions.
+ Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
+ we have to tell ffi_closure_SYSV how to treat them. */
+ if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
+ && size <= 8)
+ return FFI_SYSV_TYPE_SMALL_STRUCT + size;
+ return cif->rtype->type;
+
+}
+
+int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
+ unsigned long *, ffi_dblfl *);
+
+int FFI_HIDDEN
+ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
+ unsigned long *pst, ffi_dblfl *pfr)
+{
+ /* rvalue is the pointer to space for return value in closure assembly */
+ /* pst is the pointer to parameter save area
+ (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
+ /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
+
+ void **avalue;
+ ffi_type **arg_types;
+ long i, avn;
+ ffi_cif *cif;
+ ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
+
+ cif = closure->cif;
+ avalue = alloca (cif->nargs * sizeof (void *));
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller. */
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ rvalue = (void *) *pst;
+ pst++;
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = (char *) pst + 7;
+ pst++;
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = (char *) pst + 6;
+ pst++;
+ break;
+
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ avalue[i] = (char *) pst + 4;
+ pst++;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ avalue[i] = pst;
+ pst++;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* Structures with size less than eight bytes are passed
+ left-padded. */
+ if (arg_types[i]->size < 8)
+ avalue[i] = (char *) pst + 8 - arg_types[i]->size;
+ else
+ avalue[i] = pst;
+ pst += (arg_types[i]->size + 7) / 8;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ /* unfortunately float values are stored as doubles
+ * in the ffi_closure_LINUX64 code (since we don't check
+ * the type in that routine).
+ */
+
+ /* there are 13 64bit floating point registers */
+
+ if (pfr < end_pfr)
+ {
+ double temp = pfr->d;
+ pfr->f = (float) temp;
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+ avalue[i] = pst;
+ pst++;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ /* On the outgoing stack all values are aligned to 8 */
+ /* there are 13 64bit floating point registers */
+
+ if (pfr < end_pfr)
+ {
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+ avalue[i] = pst;
+ pst++;
+ break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ if (pfr + 1 < end_pfr)
+ {
+ avalue[i] = pfr;
+ pfr += 2;
+ }
+ else
+ {
+ if (pfr < end_pfr)
+ {
+ /* Passed partly in f13 and partly on the stack.
+ Move it all to the stack. */
+ *pst = *(unsigned long *) pfr;
+ pfr++;
+ }
+ avalue[i] = pst;
+ }
+ pst += 2;
+ break;
+#endif
+
+ default:
+ FFI_ASSERT (0);
+ }
+
+ i++;
+ }
+
+
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_LINUX64 how to perform return type promotions. */
+ return cif->rtype->type;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
new file mode 100644
index 000000000..55af70cd8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
@@ -0,0 +1,771 @@
+#if !(defined(__APPLE__) && !defined(__ppc__))
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Foreign Function Interface
+
+ Darwin ABI support (c) 2001 John Hornkvist
+ AIX ABI support (c) 2002 Free Software Foundation, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+extern void ffi_closure_ASM(void);
+
+enum {
+ /* The assembly depends on these exact flags. */
+ FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
+ FLAG_RETURNS_FP = 1 << (31-29),
+ FLAG_RETURNS_64BITS = 1 << (31-28),
+ FLAG_RETURNS_128BITS = 1 << (31-31),
+
+ FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
+ FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
+ FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
+ FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the DARWIN ABI. */
+enum {
+ NUM_GPR_ARG_REGISTERS = 8,
+ NUM_FPR_ARG_REGISTERS = 13
+};
+enum { ASM_NEEDS_REGISTERS = 4 };
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments.
+
+ The stack layout we want looks like this:
+
+ | Return address from ffi_call_DARWIN | higher addresses
+ |--------------------------------------------|
+ | Previous backchain pointer 4 | stack pointer here
+ |--------------------------------------------|<+ <<< on entry to
+ | Saved r28-r31 4*4 | | ffi_call_DARWIN
+ |--------------------------------------------| |
+ | Parameters (at least 8*4=32) | |
+ |--------------------------------------------| |
+ | Space for GPR2 4 | |
+ |--------------------------------------------| | stack |
+ | Reserved 2*4 | | grows |
+ |--------------------------------------------| | down V
+ | Space for callee's LR 4 | |
+ |--------------------------------------------| | lower addresses
+ | Saved CR 4 | |
+ |--------------------------------------------| | stack pointer here
+ | Current backchain pointer 4 |-/ during
+ |--------------------------------------------| <<< ffi_call_DARWIN
+
+ */
+
+/*@-exportheader@*/
+void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
+/*@=exportheader@*/
+{
+ const unsigned bytes = ecif->cif->bytes;
+ const unsigned flags = ecif->cif->flags;
+
+ /* 'stacktop' points at the previous backchain pointer. */
+ unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
+
+ /* 'fpr_base' points at the space for fpr1, and grows upwards as
+ we use FPR registers. */
+ double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
+ int fparg_count = 0;
+
+
+ /* 'next_arg' grows up as we put parameters in it. */
+ unsigned *next_arg = stack + 6; /* 6 reserved positions. */
+
+ int i = ecif->cif->nargs;
+ double double_tmp;
+ void **p_argv = ecif->avalue;
+ unsigned gprvalue;
+ ffi_type** ptr = ecif->cif->arg_types;
+ char *dest_cpy;
+ unsigned size_al = 0;
+
+ /* Check that everything starts aligned properly. */
+ FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
+ FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
+ FFI_ASSERT((bytes & 0xF) == 0);
+
+ /* Deal with return values that are actually pass-by-reference.
+ Rule:
+ Return values are referenced by r3, so r4 is the first parameter. */
+
+ if (flags & FLAG_RETVAL_REFERENCE)
+ *next_arg++ = (unsigned)(char *)ecif->rvalue;
+
+ /* Now for the arguments. */
+ for (;
+ i > 0;
+ i--, ptr++, p_argv++)
+ {
+ switch ((*ptr)->type)
+ {
+ /* If a floating-point parameter appears before all of the general-
+ purpose registers are filled, the corresponding GPRs that match
+ the size of the floating-point parameter are skipped. */
+ case FFI_TYPE_FLOAT:
+ double_tmp = *(float *)*p_argv;
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ *(double *)next_arg = double_tmp;
+ else
+ *fpr_base++ = double_tmp;
+ next_arg++;
+ fparg_count++;
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ double_tmp = *(double *)*p_argv;
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ *(double *)next_arg = double_tmp;
+ else
+ *fpr_base++ = double_tmp;
+ next_arg += 2;
+ fparg_count++;
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+ case FFI_TYPE_LONGDOUBLE:
+ double_tmp = ((double *)*p_argv)[0];
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ *(double *)next_arg = double_tmp;
+ else
+ *fpr_base++ = double_tmp;
+ next_arg += 2;
+ fparg_count++;
+ double_tmp = ((double *)*p_argv)[1];
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ *(double *)next_arg = double_tmp;
+ else
+ *fpr_base++ = double_tmp;
+ next_arg += 2;
+ fparg_count++;
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ break;
+#endif
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ *(long long *)next_arg = *(long long *)*p_argv;
+ next_arg+=2;
+ break;
+ case FFI_TYPE_UINT8:
+ gprvalue = *(unsigned char *)*p_argv;
+ goto putgpr;
+ case FFI_TYPE_SINT8:
+ gprvalue = *(signed char *)*p_argv;
+ goto putgpr;
+ case FFI_TYPE_UINT16:
+ gprvalue = *(unsigned short *)*p_argv;
+ goto putgpr;
+ case FFI_TYPE_SINT16:
+ gprvalue = *(signed short *)*p_argv;
+ goto putgpr;
+
+ case FFI_TYPE_STRUCT:
+ dest_cpy = (char *) next_arg;
+
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+ SI 4 bytes) are aligned as if they were those modes.
+ Structures with 3 byte in size are padded upwards. */
+ size_al = (*ptr)->size;
+ /* If the first member of the struct is a double, then align
+ the struct to double-word.
+ Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
+ if ((*ptr)->elements[0]->type == 3)
+ size_al = ALIGN((*ptr)->size, 8);
+ if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
+ dest_cpy += 4 - size_al;
+
+ memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
+ next_arg += (size_al + 3) / 4;
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_POINTER:
+ gprvalue = *(unsigned *)*p_argv;
+ putgpr:
+ *next_arg++ = gprvalue;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Check that we didn't overrun the stack... */
+ //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
+ //FFI_ASSERT((unsigned *)fpr_base
+ // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+ //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+/* Perform machine dependent cif processing. */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* All this is for the DARWIN ABI. */
+ int i;
+ ffi_type **ptr;
+ unsigned bytes;
+ int fparg_count = 0, intarg_count = 0;
+ unsigned flags = 0;
+ unsigned size_al = 0;
+
+ /* All the machine-independent calculation of cif->bytes will be wrong.
+ Redo the calculation for DARWIN. */
+
+ /* Space for the frame pointer, callee's LR, CR, etc, and for
+ the asm's temp regs. */
+
+ bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
+
+ /* Return value handling. The rules are as follows:
+ - 32-bit (or less) integer values are returned in gpr3;
+ - Structures of size <= 4 bytes also returned in gpr3;
+ - 64-bit integer values and structures between 5 and 8 bytes are returned
+ in gpr3 and gpr4;
+ - Single/double FP values are returned in fpr1;
+ - Long double FP (if not equivalent to double) values are returned in
+ fpr1 and fpr2;
+ - Larger structures values are allocated space and a pointer is passed
+ as the first argument. */
+ switch (cif->rtype->type)
+ {
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ flags |= FLAG_RETURNS_128BITS;
+ flags |= FLAG_RETURNS_FP;
+ break;
+#endif
+
+ case FFI_TYPE_DOUBLE:
+ flags |= FLAG_RETURNS_64BITS;
+ /* Fall through. */
+ case FFI_TYPE_FLOAT:
+ flags |= FLAG_RETURNS_FP;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ flags |= FLAG_RETURNS_64BITS;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ flags |= FLAG_RETVAL_REFERENCE;
+ flags |= FLAG_RETURNS_NOTHING;
+ intarg_count++;
+ break;
+ case FFI_TYPE_VOID:
+ flags |= FLAG_RETURNS_NOTHING;
+ break;
+
+ default:
+ /* Returns 32-bit integer, or similar. Nothing to do here. */
+ break;
+ }
+
+ /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+ first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+ goes on the stack. Structures are passed as a pointer to a copy of
+ the structure. Stuff on the stack needs to keep proper alignment. */
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ fparg_count++;
+ /* If this FP arg is going on the stack, it must be
+ 8-byte-aligned. */
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
+ && intarg_count%2 != 0)
+ intarg_count++;
+ break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+ case FFI_TYPE_LONGDOUBLE:
+ fparg_count += 2;
+ /* If this FP arg is going on the stack, it must be
+ 8-byte-aligned. */
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
+ && intarg_count%2 != 0)
+ intarg_count++;
+ intarg_count +=2;
+ break;
+#endif
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ /* 'long long' arguments are passed as two words, but
+ either both words must fit in registers or both go
+ on the stack. If they go on the stack, they must
+ be 8-byte-aligned. */
+ if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+ || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
+ intarg_count++;
+ intarg_count += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ size_al = (*ptr)->size;
+ /* If the first member of the struct is a double, then align
+ the struct to double-word.
+ Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
+ if ((*ptr)->elements[0]->type == 3)
+ size_al = ALIGN((*ptr)->size, 8);
+ intarg_count += (size_al + 3) / 4;
+ break;
+
+ default:
+ /* Everything else is passed as a 4-byte word in a GPR, either
+ the object itself or a pointer to it. */
+ intarg_count++;
+ break;
+ }
+ }
+
+ if (fparg_count != 0)
+ flags |= FLAG_FP_ARGUMENTS;
+
+ /* Space for the FPR registers, if needed. */
+ if (fparg_count != 0)
+ bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+
+ /* Stack space. */
+ if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
+ bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
+ else
+ bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
+
+ /* The stack space allocated needs to be a multiple of 16 bytes. */
+ bytes = (bytes + 15) & ~0xF;
+
+ cif->flags = flags;
+ cif->bytes = bytes;
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_AIX(/*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(void),
+ void (*fn2)(extended_cif *, unsigned *const));
+extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(void),
+ void (*fn2)(extended_cif *, unsigned *const));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(void),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return
+ value address then we need to make one. */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_AIX:
+ /*@-usedef@*/
+ ffi_call_AIX(&ecif, -cif->bytes,
+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
+ /*@=usedef@*/
+ break;
+ case FFI_DARWIN:
+ /*@-usedef@*/
+ ffi_call_DARWIN(&ecif, -cif->bytes,
+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+static void flush_icache(char *);
+static void flush_range(char *, int);
+
+/* The layout of a function descriptor. A C function pointer really
+ points to one of these. */
+
+typedef struct aix_fd_struct {
+ void *code_pointer;
+ void *toc;
+} aix_fd;
+
+/* here I'd like to add the stack frame layout we use in darwin_closure.S
+ and aix_clsoure.S
+
+ SP previous -> +---------------------------------------+ <--- child frame
+ | back chain to caller 4 |
+ +---------------------------------------+ 4
+ | saved CR 4 |
+ +---------------------------------------+ 8
+ | saved LR 4 |
+ +---------------------------------------+ 12
+ | reserved for compilers 4 |
+ +---------------------------------------+ 16
+ | reserved for binders 4 |
+ +---------------------------------------+ 20
+ | saved TOC pointer 4 |
+ +---------------------------------------+ 24
+ | always reserved 8*4=32 (previous GPRs)|
+ | according to the linkage convention |
+ | from AIX |
+ +---------------------------------------+ 56
+ | our FPR area 13*8=104 |
+ | f1 |
+ | . |
+ | f13 |
+ +---------------------------------------+ 160
+ | result area 8 |
+ +---------------------------------------+ 168
+ | alignement to the next multiple of 16 |
+SP current --> +---------------------------------------+ 176 <- parent frame
+ | back chain to caller 4 |
+ +---------------------------------------+ 180
+ | saved CR 4 |
+ +---------------------------------------+ 184
+ | saved LR 4 |
+ +---------------------------------------+ 188
+ | reserved for compilers 4 |
+ +---------------------------------------+ 192
+ | reserved for binders 4 |
+ +---------------------------------------+ 196
+ | saved TOC pointer 4 |
+ +---------------------------------------+ 200
+ | always reserved 8*4=32 we store our |
+ | GPRs here |
+ | r3 |
+ | . |
+ | r10 |
+ +---------------------------------------+ 232
+ | overflow part |
+ +---------------------------------------+ xxx
+ | ???? |
+ +---------------------------------------+ xxx
+
+*/
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp;
+ struct ffi_aix_trampoline_struct *tramp_aix;
+ aix_fd *fd;
+
+ switch (cif->abi)
+ {
+ case FFI_DARWIN:
+
+ FFI_ASSERT (cif->abi == FFI_DARWIN);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ tramp[0] = 0x7c0802a6; /* mflr r0 */
+ tramp[1] = 0x429f000d; /* bcl- 20,4*cr7+so,0x10 */
+ tramp[4] = 0x7d6802a6; /* mflr r11 */
+ tramp[5] = 0x818b0000; /* lwz r12,0(r11) function address */
+ tramp[6] = 0x7c0803a6; /* mtlr r0 */
+ tramp[7] = 0x7d8903a6; /* mtctr r12 */
+ tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */
+ tramp[9] = 0x4e800420; /* bctr */
+ tramp[2] = (unsigned long) ffi_closure_ASM; /* function */
+ tramp[3] = (unsigned long) closure; /* context */
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Flush the icache. Only necessary on Darwin. */
+ flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+
+ break;
+
+ case FFI_AIX:
+
+ tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
+ fd = (aix_fd *)(void *)ffi_closure_ASM;
+
+ FFI_ASSERT (cif->abi == FFI_AIX);
+
+ tramp_aix->code_pointer = fd->code_pointer;
+ tramp_aix->toc = fd->toc;
+ tramp_aix->static_chain = closure;
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ default:
+
+ FFI_ASSERT(0);
+ break;
+ }
+ return FFI_OK;
+}
+
+static void
+flush_icache(char *addr)
+{
+#ifndef _AIX
+ __asm__ volatile (
+ "dcbf 0,%0\n"
+ "\tsync\n"
+ "\ticbi 0,%0\n"
+ "\tsync\n"
+ "\tisync"
+ : : "r"(addr) : "memory");
+#endif
+}
+
+static void
+flush_range(char * addr1, int size)
+{
+#define MIN_LINE_SIZE 32
+ int i;
+ for (i = 0; i < size; i += MIN_LINE_SIZE)
+ flush_icache(addr1+i);
+ flush_icache(addr1+size-1);
+}
+
+typedef union
+{
+ float f;
+ double d;
+} ffi_dblfl;
+
+int ffi_closure_helper_DARWIN (ffi_closure*, void*,
+ unsigned long*, ffi_dblfl*);
+
+/* Basically the trampoline invokes ffi_closure_ASM, and on
+ entry, r11 holds the address of the closure.
+ After storing the registers that could possibly contain
+ parameters to be passed into the stack frame and setting
+ up space for a return value, ffi_closure_ASM invokes the
+ following helper function to do most of the work. */
+
+int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
+ unsigned long * pgr, ffi_dblfl * pfr)
+{
+ /* rvalue is the pointer to space for return value in closure assembly
+ pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
+ pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */
+
+ typedef double ldbits[2];
+
+ union ldu
+ {
+ ldbits lb;
+ long double ld;
+ };
+
+ void ** avalue;
+ ffi_type ** arg_types;
+ long i, avn;
+ long nf; /* number of floating registers already used. */
+ long ng; /* number of general registers already used. */
+ ffi_cif * cif;
+ double temp;
+ unsigned size_al;
+ union ldu temp_ld;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ nf = 0;
+ ng = 0;
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller. */
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ rvalue = (void *) *pgr;
+ pgr++;
+ ng++;
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = (char *) pgr + 3;
+ ng++;
+ pgr++;
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = (char *) pgr + 2;
+ ng++;
+ pgr++;
+ break;
+
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ avalue[i] = pgr;
+ ng++;
+ pgr++;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+ SI 4 bytes) are aligned as if they were those modes. */
+ size_al = arg_types[i]->size;
+ /* If the first member of the struct is a double, then align
+ the struct to double-word.
+ Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
+ if (arg_types[i]->elements[0]->type == 3)
+ size_al = ALIGN(arg_types[i]->size, 8);
+ if (size_al < 3 && cif->abi == FFI_DARWIN)
+ avalue[i] = (void*) pgr + 4 - size_al;
+ else
+ avalue[i] = (void*) pgr;
+ ng += (size_al + 3) / 4;
+ pgr += (size_al + 3) / 4;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ /* Long long ints are passed in two gpr's. */
+ avalue[i] = pgr;
+ ng += 2;
+ pgr += 2;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ /* A float value consumes a GPR.
+ There are 13 64bit floating point registers. */
+ if (nf < NUM_FPR_ARG_REGISTERS)
+ {
+ temp = pfr->d;
+ pfr->f = (float)temp;
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+ {
+ avalue[i] = pgr;
+ }
+ nf++;
+ ng++;
+ pgr++;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ /* A double value consumes two GPRs.
+ There are 13 64bit floating point registers. */
+ if (nf < NUM_FPR_ARG_REGISTERS)
+ {
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+ {
+ avalue[i] = pgr;
+ }
+ nf++;
+ ng += 2;
+ pgr += 2;
+ break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+ case FFI_TYPE_LONGDOUBLE:
+ /* A long double value consumes four GPRs and two FPRs.
+ There are 13 64bit floating point registers. */
+ if (nf < NUM_FPR_ARG_REGISTERS - 1)
+ {
+ avalue[i] = pfr;
+ pfr += 2;
+ }
+ /* Here we have the situation where one part of the long double
+ is stored in fpr13 and the other part is already on the stack.
+ We use a union to pass the long double to avalue[i]. */
+ else if (nf == NUM_FPR_ARG_REGISTERS - 1)
+ {
+ memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
+ memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
+ avalue[i] = &temp_ld.ld;
+ }
+ else
+ {
+ avalue[i] = pgr;
+ }
+ nf += 2;
+ ng += 4;
+ pgr += 4;
+ break;
+#endif
+ default:
+ FFI_ASSERT(0);
+ }
+ i++;
+ }
+
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_ASM to perform return type promotions. */
+ return cif->rtype->type;
+}
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffitarget.h
new file mode 100644
index 000000000..af63796c7
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffitarget.h
@@ -0,0 +1,100 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for PowerPC.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (POWERPC) && defined (__powerpc64__)
+#define POWERPC64
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+
+#ifdef POWERPC
+ FFI_SYSV,
+ FFI_GCC_SYSV,
+ FFI_LINUX64,
+# ifdef POWERPC64
+ FFI_DEFAULT_ABI = FFI_LINUX64,
+# else
+ FFI_DEFAULT_ABI = FFI_GCC_SYSV,
+# endif
+#endif
+
+#ifdef POWERPC_AIX
+ FFI_AIX,
+ FFI_DARWIN,
+ FFI_DEFAULT_ABI = FFI_AIX,
+#endif
+
+#ifdef POWERPC_DARWIN
+ FFI_AIX,
+ FFI_DARWIN,
+ FFI_DEFAULT_ABI = FFI_DARWIN,
+#endif
+
+#ifdef POWERPC_FREEBSD
+ FFI_SYSV,
+ FFI_GCC_SYSV,
+ FFI_LINUX64,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+/* Needed for FFI_SYSV small structure returns. */
+#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST)
+
+#if defined(POWERPC64) || defined(POWERPC_AIX)
+#define FFI_TRAMPOLINE_SIZE 24
+#else /* POWERPC || POWERPC_AIX */
+#define FFI_TRAMPOLINE_SIZE 40
+#endif
+
+#ifndef LIBFFI_ASM
+#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
+struct ffi_aix_trampoline_struct {
+ void * code_pointer; /* Pointer to ffi_closure_ASM */
+ void * toc; /* TOC */
+ void * static_chain; /* Pointer to closure */
+};
+#endif
+#endif
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64.S
new file mode 100644
index 000000000..25b2c4f45
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64.S
@@ -0,0 +1,180 @@
+/* -----------------------------------------------------------------------
+ sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
+
+ PowerPC64 Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef __powerpc64__
+ .hidden ffi_call_LINUX64, .ffi_call_LINUX64
+ .globl ffi_call_LINUX64, .ffi_call_LINUX64
+ .section ".opd","aw"
+ .align 3
+ffi_call_LINUX64:
+ .quad .ffi_call_LINUX64,.TOC.@tocbase,0
+ .size ffi_call_LINUX64,24
+ .type .ffi_call_LINUX64,@function
+ .text
+.ffi_call_LINUX64:
+.LFB1:
+ mflr %r0
+ std %r28, -32(%r1)
+ std %r29, -24(%r1)
+ std %r30, -16(%r1)
+ std %r31, -8(%r1)
+ std %r0, 16(%r1)
+
+ mr %r28, %r1 /* our AP. */
+ stdux %r1, %r1, %r4
+.LCFI0:
+ mr %r31, %r5 /* flags, */
+ mr %r30, %r6 /* rvalue, */
+ mr %r29, %r7 /* function address. */
+ std %r2, 40(%r1)
+
+ /* Call ffi_prep_args64. */
+ mr %r4, %r1
+ bl .ffi_prep_args64
+
+ ld %r0, 0(%r29)
+ ld %r2, 8(%r29)
+ ld %r11, 16(%r29)
+
+ /* Now do the call. */
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40, %r31
+
+ /* Get the address to call into CTR. */
+ mtctr %r0
+ /* Load all those argument registers. */
+ ld %r3, -32-(8*8)(%r28)
+ ld %r4, -32-(7*8)(%r28)
+ ld %r5, -32-(6*8)(%r28)
+ ld %r6, -32-(5*8)(%r28)
+ bf- 5, 1f
+ ld %r7, -32-(4*8)(%r28)
+ ld %r8, -32-(3*8)(%r28)
+ ld %r9, -32-(2*8)(%r28)
+ ld %r10, -32-(1*8)(%r28)
+1:
+
+ /* Load all the FP registers. */
+ bf- 6, 2f
+ lfd %f1, -32-(21*8)(%r28)
+ lfd %f2, -32-(20*8)(%r28)
+ lfd %f3, -32-(19*8)(%r28)
+ lfd %f4, -32-(18*8)(%r28)
+ lfd %f5, -32-(17*8)(%r28)
+ lfd %f6, -32-(16*8)(%r28)
+ lfd %f7, -32-(15*8)(%r28)
+ lfd %f8, -32-(14*8)(%r28)
+ lfd %f9, -32-(13*8)(%r28)
+ lfd %f10, -32-(12*8)(%r28)
+ lfd %f11, -32-(11*8)(%r28)
+ lfd %f12, -32-(10*8)(%r28)
+ lfd %f13, -32-(9*8)(%r28)
+2:
+
+ /* Make the call. */
+ bctrl
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01, %r31
+ bt- 30, .Ldone_return_value
+ bt- 29, .Lfp_return_value
+ std %r3, 0(%r30)
+ /* Fall through... */
+
+.Ldone_return_value:
+ /* Restore the registers we used and return. */
+ ld %r2, 40(%r1)
+ mr %r1, %r28
+ ld %r0, 16(%r28)
+ ld %r28, -32(%r1)
+ mtlr %r0
+ ld %r29, -24(%r1)
+ ld %r30, -16(%r1)
+ ld %r31, -8(%r1)
+ blr
+
+.Lfp_return_value:
+ bt 27, .Lfd_return_value
+ bf 28, .Lfloat_return_value
+ stfd %f1, 0(%r30)
+ b .Ldone_return_value
+.Lfd_return_value:
+ stfd %f1, 0(%r30)
+ stfd %f2, 8(%r30)
+ b .Ldone_return_value
+.Lfloat_return_value:
+ stfs %f1, 0(%r30)
+ b .Ldone_return_value
+.LFE1:
+ .long 0
+ .byte 0,12,0,1,128,4,0,0
+ .size .ffi_call_LINUX64,.-.ffi_call_LINUX64
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 -8 # CIE Data Alignment Factor
+ .byte 0x41 # CIE RA Column
+ .uleb128 0x1 # Augmentation size
+ .byte 0x14 # FDE Encoding (pcrel udata8)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x1
+ .uleb128 0x0
+ .align 3
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 # FDE Length
+.LASFDE1:
+ .4byte .LASFDE1-.Lframe1 # FDE CIE offset
+ .8byte .LFB1-. # FDE initial location
+ .8byte .LFE1-.LFB1 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x2 # DW_CFA_advance_loc1
+ .byte .LCFI0-.LFB1
+ .byte 0xd # DW_CFA_def_cfa_register
+ .uleb128 0x1c
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x41
+ .sleb128 -2
+ .byte 0x9f # DW_CFA_offset, column 0x1f
+ .uleb128 0x1
+ .byte 0x9e # DW_CFA_offset, column 0x1e
+ .uleb128 0x2
+ .byte 0x9d # DW_CFA_offset, column 0x1d
+ .uleb128 0x3
+ .byte 0x9c # DW_CFA_offset, column 0x1c
+ .uleb128 0x4
+ .align 3
+.LEFDE1:
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S
new file mode 100644
index 000000000..b19bc718b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S
@@ -0,0 +1,206 @@
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .file "linux64_closure.S"
+
+#ifdef __powerpc64__
+ FFI_HIDDEN (ffi_closure_LINUX64)
+ FFI_HIDDEN (.ffi_closure_LINUX64)
+ .globl ffi_closure_LINUX64, .ffi_closure_LINUX64
+ .section ".opd","aw"
+ .align 3
+ffi_closure_LINUX64:
+ .quad .ffi_closure_LINUX64,.TOC.@tocbase,0
+ .size ffi_closure_LINUX64,24
+ .type .ffi_closure_LINUX64,@function
+ .text
+.ffi_closure_LINUX64:
+.LFB1:
+ # save general regs into parm save area
+ std %r3, 48(%r1)
+ std %r4, 56(%r1)
+ std %r5, 64(%r1)
+ std %r6, 72(%r1)
+ mflr %r0
+
+ std %r7, 80(%r1)
+ std %r8, 88(%r1)
+ std %r9, 96(%r1)
+ std %r10, 104(%r1)
+ std %r0, 16(%r1)
+
+ # mandatory 48 bytes special reg save area + 64 bytes parm save area
+ # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
+ stdu %r1, -240(%r1)
+.LCFI0:
+
+ # next save fpr 1 to fpr 13
+ stfd %f1, 128+(0*8)(%r1)
+ stfd %f2, 128+(1*8)(%r1)
+ stfd %f3, 128+(2*8)(%r1)
+ stfd %f4, 128+(3*8)(%r1)
+ stfd %f5, 128+(4*8)(%r1)
+ stfd %f6, 128+(5*8)(%r1)
+ stfd %f7, 128+(6*8)(%r1)
+ stfd %f8, 128+(7*8)(%r1)
+ stfd %f9, 128+(8*8)(%r1)
+ stfd %f10, 128+(9*8)(%r1)
+ stfd %f11, 128+(10*8)(%r1)
+ stfd %f12, 128+(11*8)(%r1)
+ stfd %f13, 128+(12*8)(%r1)
+
+ # set up registers for the routine that actually does the work
+ # get the context pointer from the trampoline
+ mr %r3, %r11
+
+ # now load up the pointer to the result storage
+ addi %r4, %r1, 112
+
+ # now load up the pointer to the parameter save area
+ # in the previous frame
+ addi %r5, %r1, 240 + 48
+
+ # now load up the pointer to the saved fpr registers */
+ addi %r6, %r1, 128
+
+ # make the call
+ bl .ffi_closure_helper_LINUX64
+.Lret:
+
+ # now r3 contains the return type
+ # so use it to look up in a table
+ # so we know how to deal with each type
+
+ # look up the proper starting point in table
+ # by using return type as offset
+ mflr %r4 # move address of .Lret to r4
+ sldi %r3, %r3, 4 # now multiply return type by 16
+ addi %r4, %r4, .Lret_type0 - .Lret
+ ld %r0, 240+16(%r1)
+ add %r3, %r3, %r4 # add contents of table to table address
+ mtctr %r3
+ bctr # jump to it
+
+# Each of the ret_typeX code fragments has to be exactly 16 bytes long
+# (4 instructions). For cache effectiveness we align to a 16 byte boundary
+# first.
+ .align 4
+
+.Lret_type0:
+# case FFI_TYPE_VOID
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+ nop
+# case FFI_TYPE_INT
+ lwa %r3, 112+4(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_FLOAT
+ lfs %f1, 112+0(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_DOUBLE
+ lfd %f1, 112+0(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_LONGDOUBLE
+ lfd %f1, 112+0(%r1)
+ mtlr %r0
+ lfd %f2, 112+8(%r1)
+ b .Lfinish
+# case FFI_TYPE_UINT8
+ lbz %r3, 112+7(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_SINT8
+ lbz %r3, 112+7(%r1)
+ extsb %r3,%r3
+ mtlr %r0
+ b .Lfinish
+# case FFI_TYPE_UINT16
+ lhz %r3, 112+6(%r1)
+ mtlr %r0
+.Lfinish:
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_SINT16
+ lha %r3, 112+6(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_UINT32
+ lwz %r3, 112+4(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_SINT32
+ lwa %r3, 112+4(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_UINT64
+ ld %r3, 112+0(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_SINT64
+ ld %r3, 112+0(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# case FFI_TYPE_STRUCT
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+ nop
+# case FFI_TYPE_POINTER
+ ld %r3, 112+0(%r1)
+ mtlr %r0
+ addi %r1, %r1, 240
+ blr
+# esac
+.LFE1:
+ .long 0
+ .byte 0,12,0,1,128,0,0,0
+ .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 -8 # CIE Data Alignment Factor
+ .byte 0x41 # CIE RA Column
+ .uleb128 0x1 # Augmentation size
+ .byte 0x14 # FDE Encoding (pcrel udata8)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x1
+ .uleb128 0x0
+ .align 3
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 # FDE Length
+.LASFDE1:
+ .4byte .LASFDE1-.Lframe1 # FDE CIE offset
+ .8byte .LFB1-. # FDE initial location
+ .8byte .LFE1-.LFB1 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x2 # DW_CFA_advance_loc1
+ .byte .LCFI0-.LFB1
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 240
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x41
+ .sleb128 -2
+ .align 3
+.LEFDE1:
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S
new file mode 100644
index 000000000..370381378
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S
@@ -0,0 +1,323 @@
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+ .file "ppc_closure.S"
+
+#ifndef __powerpc64__
+
+ENTRY(ffi_closure_SYSV)
+.LFB1:
+ stwu %r1,-144(%r1)
+.LCFI0:
+ mflr %r0
+.LCFI1:
+ stw %r0,148(%r1)
+
+# we want to build up an areas for the parameters passed
+# in registers (both floating point and integer)
+
+ # so first save gpr 3 to gpr 10 (aligned to 4)
+ stw %r3, 16(%r1)
+ stw %r4, 20(%r1)
+ stw %r5, 24(%r1)
+ stw %r6, 28(%r1)
+ stw %r7, 32(%r1)
+ stw %r8, 36(%r1)
+ stw %r9, 40(%r1)
+ stw %r10,44(%r1)
+
+ # next save fpr 1 to fpr 8 (aligned to 8)
+ stfd %f1, 48(%r1)
+ stfd %f2, 56(%r1)
+ stfd %f3, 64(%r1)
+ stfd %f4, 72(%r1)
+ stfd %f5, 80(%r1)
+ stfd %f6, 88(%r1)
+ stfd %f7, 96(%r1)
+ stfd %f8, 104(%r1)
+
+ # set up registers for the routine that actually does the work
+ # get the context pointer from the trampoline
+ mr %r3,%r11
+
+ # now load up the pointer to the result storage
+ addi %r4,%r1,112
+
+ # now load up the pointer to the saved gpr registers
+ addi %r5,%r1,16
+
+ # now load up the pointer to the saved fpr registers */
+ addi %r6,%r1,48
+
+ # now load up the pointer to the outgoing parameter
+ # stack in the previous frame
+ # i.e. the previous frame pointer + 8
+ addi %r7,%r1,152
+
+ # make the call
+ bl ffi_closure_helper_SYSV@local
+
+ # now r3 contains the return type
+ # so use it to look up in a table
+ # so we know how to deal with each type
+
+ # look up the proper starting point in table
+ # by using return type as offset
+ addi %r6,%r1,112 # get pointer to results area
+ bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
+ mflr %r4 # move to r4
+ slwi %r3,%r3,4 # now multiply return type by 16
+ add %r3,%r3,%r4 # add contents of table to table address
+ mtctr %r3
+ bctr # jump to it
+.LFE1:
+
+# Each of the ret_typeX code fragments has to be exactly 16 bytes long
+# (4 instructions). For cache effectiveness we align to a 16 byte boundary
+# first.
+ .align 4
+
+ nop
+ nop
+ nop
+.Lget_ret_type0_addr:
+ blrl
+
+# case FFI_TYPE_VOID
+.Lret_type0:
+ b .Lfinish
+ nop
+ nop
+ nop
+
+# case FFI_TYPE_INT
+.Lret_type1:
+ lwz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_FLOAT
+.Lret_type2:
+ lfs %f1,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_DOUBLE
+.Lret_type3:
+ lfd %f1,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_LONGDOUBLE
+.Lret_type4:
+ lfd %f1,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_UINT8
+.Lret_type5:
+ lbz %r3,3(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_SINT8
+.Lret_type6:
+ lbz %r3,3(%r6)
+ extsb %r3,%r3
+ b .Lfinish
+ nop
+
+# case FFI_TYPE_UINT16
+.Lret_type7:
+ lhz %r3,2(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_SINT16
+.Lret_type8:
+ lha %r3,2(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_UINT32
+.Lret_type9:
+ lwz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_SINT32
+.Lret_type10:
+ lwz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_TYPE_UINT64
+.Lret_type11:
+ lwz %r3,0(%r6)
+ lwz %r4,4(%r6)
+ b .Lfinish
+ nop
+
+# case FFI_TYPE_SINT64
+.Lret_type12:
+ lwz %r3,0(%r6)
+ lwz %r4,4(%r6)
+ b .Lfinish
+ nop
+
+# case FFI_TYPE_STRUCT
+.Lret_type13:
+ b .Lfinish
+ nop
+ nop
+ nop
+
+# case FFI_TYPE_POINTER
+.Lret_type14:
+ lwz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# The return types below are only used when the ABI type is FFI_SYSV.
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
+.Lret_type15:
+# fall through.
+ lbz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
+.Lret_type16:
+# fall through.
+ lhz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
+.Lret_type17:
+# fall through.
+ lwz %r3,0(%r6)
+ srwi %r3,%r3,8
+ b .Lfinish
+ nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
+.Lret_type18:
+# this one handles the structs from above too.
+ lwz %r3,0(%r6)
+ b .Lfinish
+ nop
+ nop
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
+.Lret_type19:
+# fall through.
+ lwz %r3,0(%r6)
+ lwz %r4,4(%r6)
+ li %r5,24
+ b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
+.Lret_type20:
+# fall through.
+ lwz %r3,0(%r6)
+ lwz %r4,4(%r6)
+ li %r5,16
+ b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
+.Lret_type21:
+# fall through.
+ lwz %r3,0(%r6)
+ lwz %r4,4(%r6)
+ li %r5,8
+ b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
+.Lret_type22:
+# this one handles the above unhandled structs.
+ lwz %r3,0(%r6)
+ lwz %r4,4(%r6)
+ b .Lfinish
+ nop
+
+# case done
+.Lfinish:
+
+ lwz %r0,148(%r1)
+ mtlr %r0
+ addi %r1,%r1,144
+ blr
+
+.Lstruct567:
+ subfic %r0,%r5,32
+ srw %r4,%r4,%r5
+ slw %r0,%r3,%r0
+ srw %r3,%r3,%r5
+ or %r4,%r0,%r4
+ b .Lfinish
+END(ffi_closure_SYSV)
+
+ .section ".eh_frame",EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+#if defined _RELOCATABLE || defined __PIC__
+ .ascii "zR\0" # CIE Augmentation
+#else
+ .ascii "\0" # CIE Augmentation
+#endif
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 -4 # CIE Data Alignment Factor
+ .byte 0x41 # CIE RA Column
+#if defined _RELOCATABLE || defined __PIC__
+ .uleb128 0x1 # Augmentation size
+ .byte 0x1b # FDE Encoding (pcrel sdata4)
+#endif
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x1
+ .uleb128 0x0
+ .align 2
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 # FDE Length
+.LASFDE1:
+ .4byte .LASFDE1-.Lframe1 # FDE CIE offset
+#if defined _RELOCATABLE || defined __PIC__
+ .4byte .LFB1-. # FDE initial location
+#else
+ .4byte .LFB1 # FDE initial location
+#endif
+ .4byte .LFE1-.LFB1 # FDE address range
+#if defined _RELOCATABLE || defined __PIC__
+ .uleb128 0x0 # Augmentation size
+#endif
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI0-.LFB1
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 144
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI1-.LCFI0
+ .byte 0x11 # DW_CFA_offset_extended_sf
+ .uleb128 0x41
+ .sleb128 -1
+ .align 2
+.LEFDE1:
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/sysv.S
new file mode 100644
index 000000000..6d5a707ec
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/sysv.S
@@ -0,0 +1,217 @@
+/* -----------------------------------------------------------------------
+ sysv.h - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+#ifndef __powerpc64__
+ .globl ffi_prep_args_SYSV
+ENTRY(ffi_call_SYSV)
+.LFB1:
+ /* Save the old stack pointer as AP. */
+ mr %r8,%r1
+
+.LCFI0:
+ /* Allocate the stack space we need. */
+ stwux %r1,%r1,%r4
+ /* Save registers we use. */
+ mflr %r9
+ stw %r28,-16(%r8)
+.LCFI1:
+ stw %r29,-12(%r8)
+.LCFI2:
+ stw %r30, -8(%r8)
+.LCFI3:
+ stw %r31, -4(%r8)
+.LCFI4:
+ stw %r9, 4(%r8)
+.LCFI5:
+
+ /* Save arguments over call... */
+ mr %r31,%r5 /* flags, */
+ mr %r30,%r6 /* rvalue, */
+ mr %r29,%r7 /* function address, */
+ mr %r28,%r8 /* our AP. */
+.LCFI6:
+
+ /* Call ffi_prep_args_SYSV. */
+ mr %r4,%r1
+ bl ffi_prep_args_SYSV@local
+
+ /* Now do the call. */
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40,%r31
+ /* Get the address to call into CTR. */
+ mtctr %r29
+ /* Load all those argument registers. */
+ lwz %r3,-16-(8*4)(%r28)
+ lwz %r4,-16-(7*4)(%r28)
+ lwz %r5,-16-(6*4)(%r28)
+ lwz %r6,-16-(5*4)(%r28)
+ bf- 5,1f
+ nop
+ lwz %r7,-16-(4*4)(%r28)
+ lwz %r8,-16-(3*4)(%r28)
+ lwz %r9,-16-(2*4)(%r28)
+ lwz %r10,-16-(1*4)(%r28)
+ nop
+1:
+
+ /* Load all the FP registers. */
+ bf- 6,2f
+ lfd %f1,-16-(8*4)-(8*8)(%r28)
+ lfd %f2,-16-(8*4)-(7*8)(%r28)
+ lfd %f3,-16-(8*4)-(6*8)(%r28)
+ lfd %f4,-16-(8*4)-(5*8)(%r28)
+ nop
+ lfd %f5,-16-(8*4)-(4*8)(%r28)
+ lfd %f6,-16-(8*4)-(3*8)(%r28)
+ lfd %f7,-16-(8*4)-(2*8)(%r28)
+ lfd %f8,-16-(8*4)-(1*8)(%r28)
+2:
+
+ /* Make the call. */
+ bctrl
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01,%r31
+ bt- 31,L(small_struct_return_value)
+ bt- 30,L(done_return_value)
+ bt- 29,L(fp_return_value)
+ stw %r3,0(%r30)
+ bf+ 28,L(done_return_value)
+ stw %r4,4(%r30)
+ /* Fall through... */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ lwz %r9, 4(%r28)
+ lwz %r31, -4(%r28)
+ mtlr %r9
+ lwz %r30, -8(%r28)
+ lwz %r29,-12(%r28)
+ lwz %r28,-16(%r28)
+ lwz %r1,0(%r1)
+ blr
+
+L(fp_return_value):
+ bf 28,L(float_return_value)
+ stfd %f1,0(%r30)
+ b L(done_return_value)
+L(float_return_value):
+ stfs %f1,0(%r30)
+ b L(done_return_value)
+
+L(small_struct_return_value):
+ mtcrf 0x10,%r31 /* cr3 */
+ bt- 15,L(smst_one_register)
+ mtcrf 0x08,%r31 /* cr4 */
+ bt- 16,L(smst_two_register)
+ b L(done_return_value)
+
+L(smst_one_register):
+ rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
+ slw %r3,%r3,%r5
+ stw %r3,0(%r30)
+ b L(done_return_value)
+L(smst_two_register):
+ rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
+ cmpwi %r5,0
+ subfic %r9,%r5,32
+ slw %r29,%r3,%r5
+ srw %r9,%r4,%r9
+ beq- L(smst_8byte)
+ or %r3,%r9,%r29
+ slw %r4,%r4,%r5
+L(smst_8byte):
+ stw %r3,0(%r30)
+ stw %r4,4(%r30)
+ b L(done_return_value)
+
+.LFE1:
+END(ffi_call_SYSV)
+
+ .section ".eh_frame",EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .4byte 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#if defined _RELOCATABLE || defined __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .uleb128 0x1 /* CIE Code Alignment Factor */
+ .sleb128 -4 /* CIE Data Alignment Factor */
+ .byte 0x41 /* CIE RA Column */
+#if defined _RELOCATABLE || defined __PIC__
+ .uleb128 0x1 /* Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .uleb128 0x1
+ .uleb128 0x0
+ .align 2
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .4byte .LASFDE1-.Lframe1 /* FDE CIE offset */
+#if defined _RELOCATABLE || defined __PIC__
+ .4byte .LFB1-. /* FDE initial location */
+#else
+ .4byte .LFB1 /* FDE initial location */
+#endif
+ .4byte .LFE1-.LFB1 /* FDE address range */
+#if defined _RELOCATABLE || defined __PIC__
+ .uleb128 0x0 /* Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI0-.LFB1
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .uleb128 0x08
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI5-.LCFI0
+ .byte 0x11 /* DW_CFA_offset_extended_sf */
+ .uleb128 0x41
+ .sleb128 -1
+ .byte 0x9f /* DW_CFA_offset, column 0x1f */
+ .uleb128 0x1
+ .byte 0x9e /* DW_CFA_offset, column 0x1e */
+ .uleb128 0x2
+ .byte 0x9d /* DW_CFA_offset, column 0x1d */
+ .uleb128 0x3
+ .byte 0x9c /* DW_CFA_offset, column 0x1c */
+ .uleb128 0x4
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI6-.LCFI5
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .uleb128 0x1c
+ .align 2
+.LEFDE1:
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/prep_cif.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/prep_cif.c
new file mode 100644
index 000000000..2db65ce4d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/prep_cif.c
@@ -0,0 +1,210 @@
+/* -----------------------------------------------------------------------
+ prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+ specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+ ffi_type **ptr;
+
+ FFI_ASSERT(arg != NULL);
+
+ /*@-usedef@*/
+
+ FFI_ASSERT(arg->elements != NULL);
+ FFI_ASSERT(arg->size == 0);
+ FFI_ASSERT(arg->alignment == 0);
+
+ ptr = &(arg->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+#ifdef POWERPC_DARWIN
+ {
+ int curalign;
+
+ curalign = (*ptr)->alignment;
+ if (ptr != &(arg->elements[0])) {
+ if (curalign > 4 && curalign != 16) {
+ curalign = 4;
+ }
+ }
+ arg->size = ALIGN(arg->size, curalign);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > curalign) ?
+ arg->alignment : curalign;
+ }
+#else
+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment : (*ptr)->alignment;
+#endif
+
+ ptr++;
+ }
+
+ /* Structure size includes tail padding. This is important for
+ structures that fit in one register on ABIs like the PowerPC64
+ Linux ABI that right justify small structs in a register.
+ It's also needed for nested structure layout, for example
+ struct A { long a; char b; }; struct B { struct A x; char y; };
+ should find y at an offset of 2*sizeof(long) and result in a
+ total size of 3*sizeof(long). */
+ arg->size = ALIGN (arg->size, arg->alignment);
+
+ if (arg->size == 0)
+ return FFI_BAD_TYPEDEF;
+ else
+ return FFI_OK;
+
+ /*@=usedef@*/
+}
+
+#ifndef __CRIS__
+/* The CRIS ABI specifies structure elements to have byte
+ alignment only, so it completely overrides this functions,
+ which assumes "natural" alignment and padding. */
+
+/* Perform machine independent ffi_cif preparation, then call
+ machine dependent routine. */
+
+#ifdef X86_DARWIN
+static inline int struct_on_stack(int size)
+{
+ if (size > 8) return 1;
+ /* This is not what the ABI says, but is what is really implemented */
+ switch (size) {
+ case 1: case 2: case 4: case 8: return 0;
+ }
+ return 1;
+}
+#endif
+
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi, unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes)
+{
+ unsigned bytes = 0;
+ unsigned int i;
+ ffi_type **ptr;
+
+ FFI_ASSERT(cif != NULL);
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+ cif->abi = abi;
+ cif->arg_types = atypes;
+ cif->nargs = nargs;
+ cif->rtype = rtype;
+
+ cif->flags = 0;
+
+ /* Initialize the return type if necessary */
+ /*@-usedef@*/
+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+ /*@=usedef@*/
+
+ /* Perform a sanity check on the return type */
+ FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+ /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
+#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
+ /* Make space for the return structure pointer */
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef SPARC
+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+#ifdef X86_DARWIN
+
+ && (struct_on_stack(cif->rtype->size))
+#endif
+ )
+ bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+
+ /* Initialize any uninitialized aggregate type definitions */
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type, do this
+ check after the initialization. */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if defined(X86_DARWIN)
+ {
+ int align = (*ptr)->alignment;
+ if (align > 4) align = 4;
+ if ((align - 1) & bytes)
+ bytes = ALIGN(bytes, align);
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+
+#elif !defined __x86_64__ && !defined S390 && !defined PA
+#ifdef SPARC
+ if (((*ptr)->type == FFI_TYPE_STRUCT
+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+ && cif->abi != FFI_V9))
+ bytes += sizeof(void*);
+ else
+#endif
+ {
+ /* Add any padding if necessary */
+ if (((*ptr)->alignment - 1) & bytes)
+ bytes = ALIGN(bytes, (*ptr)->alignment);
+
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+#endif
+ }
+
+ cif->bytes = bytes;
+
+ /* Perform machine dependent cif processing */
+ return ffi_prep_cif_machdep(cif);
+}
+#endif /* not __CRIS__ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffi.c
new file mode 100644
index 000000000..399fa2a91
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffi.c
@@ -0,0 +1,751 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2000 Software AG
+
+ S390 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+/*====================================================================*/
+/* Includes */
+/* -------- */
+/*====================================================================*/
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*====================== End of Includes =============================*/
+
+/*====================================================================*/
+/* Defines */
+/* ------- */
+/*====================================================================*/
+
+/* Maximum number of GPRs available for argument passing. */
+#define MAX_GPRARGS 5
+
+/* Maximum number of FPRs available for argument passing. */
+#ifdef __s390x__
+#define MAX_FPRARGS 4
+#else
+#define MAX_FPRARGS 2
+#endif
+
+/* Round to multiple of 16. */
+#define ROUND_SIZE(size) (((size) + 15) & ~15)
+
+/* If these values change, sysv.S must be adapted! */
+#define FFI390_RET_VOID 0
+#define FFI390_RET_STRUCT 1
+#define FFI390_RET_FLOAT 2
+#define FFI390_RET_DOUBLE 3
+#define FFI390_RET_INT32 4
+#define FFI390_RET_INT64 5
+
+/*===================== End of Defines ===============================*/
+
+/*====================================================================*/
+/* Prototypes */
+/* ---------- */
+/*====================================================================*/
+
+static void ffi_prep_args (unsigned char *, extended_cif *);
+void
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+__attribute__ ((visibility ("hidden")))
+#endif
+ffi_closure_helper_SYSV (ffi_closure *, unsigned long *,
+ unsigned long long *, unsigned long *);
+
+/*====================== End of Prototypes ===========================*/
+
+/*====================================================================*/
+/* Externals */
+/* --------- */
+/*====================================================================*/
+
+extern void ffi_call_SYSV(unsigned,
+ extended_cif *,
+ void (*)(unsigned char *, extended_cif *),
+ unsigned,
+ void *,
+ void (*fn)());
+
+extern void ffi_closure_SYSV(void);
+
+/*====================== End of Externals ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_check_struct_type. */
+/* */
+/* Function - Determine if a structure can be passed within a */
+/* general purpose or floating point register. */
+/* */
+/*====================================================================*/
+
+static int
+ffi_check_struct_type (ffi_type *arg)
+{
+ size_t size = arg->size;
+
+ /* If the struct has just one element, look at that element
+ to find out whether to consider the struct as floating point. */
+ while (arg->type == FFI_TYPE_STRUCT
+ && arg->elements[0] && !arg->elements[1])
+ arg = arg->elements[0];
+
+ /* Structs of size 1, 2, 4, and 8 are passed in registers,
+ just like the corresponding int/float types. */
+ switch (size)
+ {
+ case 1:
+ return FFI_TYPE_UINT8;
+
+ case 2:
+ return FFI_TYPE_UINT16;
+
+ case 4:
+ if (arg->type == FFI_TYPE_FLOAT)
+ return FFI_TYPE_FLOAT;
+ else
+ return FFI_TYPE_UINT32;
+
+ case 8:
+ if (arg->type == FFI_TYPE_DOUBLE)
+ return FFI_TYPE_DOUBLE;
+ else
+ return FFI_TYPE_UINT64;
+
+ default:
+ break;
+ }
+
+ /* Other structs are passed via a pointer to the data. */
+ return FFI_TYPE_POINTER;
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_prep_args. */
+/* */
+/* Function - Prepare parameters for call to function. */
+/* */
+/* ffi_prep_args is called by the assembly routine once stack space */
+/* has been allocated for the function's arguments. */
+/* */
+/*====================================================================*/
+
+static void
+ffi_prep_args (unsigned char *stack, extended_cif *ecif)
+{
+ /* The stack space will be filled with those areas:
+
+ FPR argument register save area (highest addresses)
+ GPR argument register save area
+ temporary struct copies
+ overflow argument area (lowest addresses)
+
+ We set up the following pointers:
+
+ p_fpr: bottom of the FPR area (growing upwards)
+ p_gpr: bottom of the GPR area (growing upwards)
+ p_ov: bottom of the overflow area (growing upwards)
+ p_struct: top of the struct copy area (growing downwards)
+
+ All areas are kept aligned to twice the word size. */
+
+ int gpr_off = ecif->cif->bytes;
+ int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
+
+ unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
+ unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
+ unsigned char *p_struct = (unsigned char *)p_gpr;
+ unsigned long *p_ov = (unsigned long *)stack;
+
+ int n_fpr = 0;
+ int n_gpr = 0;
+ int n_ov = 0;
+
+ ffi_type **ptr;
+ void **p_argv = ecif->avalue;
+ int i;
+
+ /* If we returning a structure then we set the first parameter register
+ to the address of where we are returning this structure. */
+
+ if (ecif->cif->flags == FFI390_RET_STRUCT)
+ p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
+
+ /* Now for the arguments. */
+
+ for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+ i > 0;
+ i--, ptr++, p_argv++)
+ {
+ void *arg = *p_argv;
+ int type = (*ptr)->type;
+
+ /* Check how a structure type is passed. */
+ if (type == FFI_TYPE_STRUCT)
+ {
+ type = ffi_check_struct_type (*ptr);
+
+ /* If we pass the struct via pointer, copy the data. */
+ if (type == FFI_TYPE_POINTER)
+ {
+ p_struct -= ROUND_SIZE ((*ptr)->size);
+ memcpy (p_struct, (char *)arg, (*ptr)->size);
+ arg = &p_struct;
+ }
+ }
+
+ /* Now handle all primitive int/pointer/float data types. */
+ switch (type)
+ {
+ case FFI_TYPE_DOUBLE:
+ if (n_fpr < MAX_FPRARGS)
+ p_fpr[n_fpr++] = *(unsigned long long *) arg;
+ else
+#ifdef __s390x__
+ p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+ p_ov[n_ov++] = ((unsigned long *) arg)[0],
+ p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (n_fpr < MAX_FPRARGS)
+ p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
+ else
+ p_ov[n_ov++] = *(unsigned int *) arg;
+ break;
+
+ case FFI_TYPE_POINTER:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
+ else
+ p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+#ifdef __s390x__
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(unsigned long *) arg;
+ else
+ p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+ if (n_gpr == MAX_GPRARGS-1)
+ n_gpr = MAX_GPRARGS;
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
+ p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
+ else
+ p_ov[n_ov++] = ((unsigned long *) arg)[0],
+ p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+ break;
+
+ case FFI_TYPE_UINT32:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(unsigned int *) arg;
+ else
+ p_ov[n_ov++] = *(unsigned int *) arg;
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_SINT32:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(signed int *) arg;
+ else
+ p_ov[n_ov++] = *(signed int *) arg;
+ break;
+
+ case FFI_TYPE_UINT16:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(unsigned short *) arg;
+ else
+ p_ov[n_ov++] = *(unsigned short *) arg;
+ break;
+
+ case FFI_TYPE_SINT16:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(signed short *) arg;
+ else
+ p_ov[n_ov++] = *(signed short *) arg;
+ break;
+
+ case FFI_TYPE_UINT8:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(unsigned char *) arg;
+ else
+ p_ov[n_ov++] = *(unsigned char *) arg;
+ break;
+
+ case FFI_TYPE_SINT8:
+ if (n_gpr < MAX_GPRARGS)
+ p_gpr[n_gpr++] = *(signed char *) arg;
+ else
+ p_ov[n_ov++] = *(signed char *) arg;
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+ }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_prep_cif_machdep. */
+/* */
+/* Function - Perform machine dependent CIF processing. */
+/* */
+/*====================================================================*/
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ size_t struct_size = 0;
+ int n_gpr = 0;
+ int n_fpr = 0;
+ int n_ov = 0;
+
+ ffi_type **ptr;
+ int i;
+
+ /* Determine return value handling. */
+
+ switch (cif->rtype->type)
+ {
+ /* Void is easy. */
+ case FFI_TYPE_VOID:
+ cif->flags = FFI390_RET_VOID;
+ break;
+
+ /* Structures are returned via a hidden pointer. */
+ case FFI_TYPE_STRUCT:
+ cif->flags = FFI390_RET_STRUCT;
+ n_gpr++; /* We need one GPR to pass the pointer. */
+ break;
+
+ /* Floating point values are returned in fpr 0. */
+ case FFI_TYPE_FLOAT:
+ cif->flags = FFI390_RET_FLOAT;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ cif->flags = FFI390_RET_DOUBLE;
+ break;
+
+ /* Integer values are returned in gpr 2 (and gpr 3
+ for 64-bit values on 31-bit machines). */
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ cif->flags = FFI390_RET_INT64;
+ break;
+
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ /* These are to be extended to word size. */
+#ifdef __s390x__
+ cif->flags = FFI390_RET_INT64;
+#else
+ cif->flags = FFI390_RET_INT32;
+#endif
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+
+ /* Now for the arguments. */
+
+ for (ptr = cif->arg_types, i = cif->nargs;
+ i > 0;
+ i--, ptr++)
+ {
+ int type = (*ptr)->type;
+
+ /* Check how a structure type is passed. */
+ if (type == FFI_TYPE_STRUCT)
+ {
+ type = ffi_check_struct_type (*ptr);
+
+ /* If we pass the struct via pointer, we must reserve space
+ to copy its data for proper call-by-value semantics. */
+ if (type == FFI_TYPE_POINTER)
+ struct_size += ROUND_SIZE ((*ptr)->size);
+ }
+
+ /* Now handle all primitive int/float data types. */
+ switch (type)
+ {
+ /* The first MAX_FPRARGS floating point arguments
+ go in FPRs, the rest overflow to the stack. */
+
+ case FFI_TYPE_DOUBLE:
+ if (n_fpr < MAX_FPRARGS)
+ n_fpr++;
+ else
+ n_ov += sizeof (double) / sizeof (long);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (n_fpr < MAX_FPRARGS)
+ n_fpr++;
+ else
+ n_ov++;
+ break;
+
+ /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
+ if one is still available, or else on the stack. If only one
+ register is free, skip the register (it won't be used for any
+ subsequent argument either). */
+
+#ifndef __s390x__
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ if (n_gpr == MAX_GPRARGS-1)
+ n_gpr = MAX_GPRARGS;
+ if (n_gpr < MAX_GPRARGS)
+ n_gpr += 2;
+ else
+ n_ov += 2;
+ break;
+#endif
+
+ /* Everything else is passed in GPRs (until MAX_GPRARGS
+ have been used) or overflows to the stack. */
+
+ default:
+ if (n_gpr < MAX_GPRARGS)
+ n_gpr++;
+ else
+ n_ov++;
+ break;
+ }
+ }
+
+ /* Total stack space as required for overflow arguments
+ and temporary structure copies. */
+
+ cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
+
+ return FFI_OK;
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_call. */
+/* */
+/* Function - Call the FFI routine. */
+/* */
+/*====================================================================*/
+
+void
+ffi_call(ffi_cif *cif,
+ void (*fn)(),
+ void *rvalue,
+ void **avalue)
+{
+ int ret_type = cif->flags;
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+ ecif.rvalue = rvalue;
+
+ /* If we don't have a return value, we need to fake one. */
+ if (rvalue == NULL)
+ {
+ if (ret_type == FFI390_RET_STRUCT)
+ ecif.rvalue = alloca (cif->rtype->size);
+ else
+ ret_type = FFI390_RET_VOID;
+ }
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
+ ret_type, ecif.rvalue, fn);
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_closure_helper_SYSV. */
+/* */
+/* Function - Call a FFI closure target function. */
+/* */
+/*====================================================================*/
+
+void
+ffi_closure_helper_SYSV (ffi_closure *closure,
+ unsigned long *p_gpr,
+ unsigned long long *p_fpr,
+ unsigned long *p_ov)
+{
+ unsigned long long ret_buffer;
+
+ void *rvalue = &ret_buffer;
+ void **avalue;
+ void **p_arg;
+
+ int n_gpr = 0;
+ int n_fpr = 0;
+ int n_ov = 0;
+
+ ffi_type **ptr;
+ int i;
+
+ /* Allocate buffer for argument list pointers. */
+
+ p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
+
+ /* If we returning a structure, pass the structure address
+ directly to the target function. Otherwise, have the target
+ function store the return value to the GPR save area. */
+
+ if (closure->cif->flags == FFI390_RET_STRUCT)
+ rvalue = (void *) p_gpr[n_gpr++];
+
+ /* Now for the arguments. */
+
+ for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
+ i > 0;
+ i--, p_arg++, ptr++)
+ {
+ int deref_struct_pointer = 0;
+ int type = (*ptr)->type;
+
+ /* Check how a structure type is passed. */
+ if (type == FFI_TYPE_STRUCT)
+ {
+ type = ffi_check_struct_type (*ptr);
+
+ /* If we pass the struct via pointer, remember to
+ retrieve the pointer later. */
+ if (type == FFI_TYPE_POINTER)
+ deref_struct_pointer = 1;
+ }
+
+ /* Pointers are passed like UINTs of the same size. */
+ if (type == FFI_TYPE_POINTER)
+#ifdef __s390x__
+ type = FFI_TYPE_UINT64;
+#else
+ type = FFI_TYPE_UINT32;
+#endif
+
+ /* Now handle all primitive int/float data types. */
+ switch (type)
+ {
+ case FFI_TYPE_DOUBLE:
+ if (n_fpr < MAX_FPRARGS)
+ *p_arg = &p_fpr[n_fpr++];
+ else
+ *p_arg = &p_ov[n_ov],
+ n_ov += sizeof (double) / sizeof (long);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (n_fpr < MAX_FPRARGS)
+ *p_arg = &p_fpr[n_fpr++];
+ else
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+#ifdef __s390x__
+ if (n_gpr < MAX_GPRARGS)
+ *p_arg = &p_gpr[n_gpr++];
+ else
+ *p_arg = &p_ov[n_ov++];
+#else
+ if (n_gpr == MAX_GPRARGS-1)
+ n_gpr = MAX_GPRARGS;
+ if (n_gpr < MAX_GPRARGS)
+ *p_arg = &p_gpr[n_gpr], n_gpr += 2;
+ else
+ *p_arg = &p_ov[n_ov], n_ov += 2;
+#endif
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ if (n_gpr < MAX_GPRARGS)
+ *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
+ else
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+ break;
+
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ if (n_gpr < MAX_GPRARGS)
+ *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
+ else
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
+ break;
+
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ if (n_gpr < MAX_GPRARGS)
+ *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
+ else
+ *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+
+ /* If this is a struct passed via pointer, we need to
+ actually retrieve that pointer. */
+ if (deref_struct_pointer)
+ *p_arg = *(void **)*p_arg;
+ }
+
+
+ /* Call the target function. */
+ (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
+
+ /* Convert the return value. */
+ switch (closure->cif->rtype->type)
+ {
+ /* Void is easy, and so is struct. */
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ break;
+
+ /* Floating point values are returned in fpr 0. */
+ case FFI_TYPE_FLOAT:
+ p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ p_fpr[0] = *(unsigned long long *) rvalue;
+ break;
+
+ /* Integer values are returned in gpr 2 (and gpr 3
+ for 64-bit values on 31-bit machines). */
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+#ifdef __s390x__
+ p_gpr[0] = *(unsigned long *) rvalue;
+#else
+ p_gpr[0] = ((unsigned long *) rvalue)[0],
+ p_gpr[1] = ((unsigned long *) rvalue)[1];
+#endif
+ break;
+
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_UINT8:
+ p_gpr[0] = *(unsigned long *) rvalue;
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_SINT8:
+ p_gpr[0] = *(signed long *) rvalue;
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_prep_closure. */
+/* */
+/* Function - Prepare a FFI closure. */
+/* */
+/*====================================================================*/
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+ ffi_cif *cif,
+ void (*fun) (ffi_cif *, void *, void **, void *),
+ void *user_data)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+#ifndef __s390x__
+ *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
+ *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
+ *(short *)&closure->tramp [4] = 0x1006;
+ *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
+ *(long *)&closure->tramp [8] = (long)closure;
+ *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
+#else
+ *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
+ *(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
+ *(short *)&closure->tramp [4] = 0x100e;
+ *(short *)&closure->tramp [6] = 0x0004;
+ *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
+ *(long *)&closure->tramp[16] = (long)closure;
+ *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
+#endif
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+/*======================== End of Routine ============================*/
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffitarget.h
new file mode 100644
index 000000000..5ec8ade02
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffitarget.h
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for S390.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#if defined (__s390x__)
+#define S390X
+#endif
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#ifdef S390X
+#define FFI_TRAMPOLINE_SIZE 32
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/sysv.S
new file mode 100644
index 000000000..e9cbed977
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/sysv.S
@@ -0,0 +1,429 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2000 Software AG
+
+ S390 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifndef __s390x__
+
+.text
+
+ # r2: cif->bytes
+ # r3: &ecif
+ # r4: ffi_prep_args
+ # r5: ret_type
+ # r6: ecif.rvalue
+ # ov: fn
+
+ # This assumes we are using gas.
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+ stm %r6,%r15,24(%r15) # Save registers
+.LCFI0:
+ basr %r13,0 # Set up base register
+.Lbase:
+ lr %r11,%r15 # Set up frame pointer
+.LCFI1:
+ sr %r15,%r2
+ ahi %r15,-96-48 # Allocate stack
+ lr %r8,%r6 # Save ecif.rvalue
+ sr %r9,%r9
+ ic %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
+ l %r7,96(%r11) # Load function address
+ st %r11,0(%r15) # Set up back chain
+ ahi %r11,-48 # Register save area
+.LCFI2:
+
+ la %r2,96(%r15) # Save area
+ # r3 already holds &ecif
+ basr %r14,%r4 # Call ffi_prep_args
+
+ lm %r2,%r6,0(%r11) # Load arguments
+ ld %f0,32(%r11)
+ ld %f2,40(%r11)
+ la %r14,0(%r13,%r9) # Set return address
+ br %r7 # ... and call function
+
+.LretNone: # Return void
+ l %r4,48+56(%r11)
+ lm %r6,%r15,48+24(%r11)
+ br %r4
+
+.LretFloat:
+ l %r4,48+56(%r11)
+ ste %f0,0(%r8) # Return float
+ lm %r6,%r15,48+24(%r11)
+ br %r4
+
+.LretDouble:
+ l %r4,48+56(%r11)
+ std %f0,0(%r8) # Return double
+ lm %r6,%r15,48+24(%r11)
+ br %r4
+
+.LretInt32:
+ l %r4,48+56(%r11)
+ st %r2,0(%r8) # Return int
+ lm %r6,%r15,48+24(%r11)
+ br %r4
+
+.LretInt64:
+ l %r4,48+56(%r11)
+ stm %r2,%r3,0(%r8) # Return long long
+ lm %r6,%r15,48+24(%r11)
+ br %r4
+
+.Ltable:
+ .byte .LretNone-.Lbase # FFI390_RET_VOID
+ .byte .LretNone-.Lbase # FFI390_RET_STRUCT
+ .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
+ .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
+ .byte .LretInt32-.Lbase # FFI390_RET_INT32
+ .byte .LretInt64-.Lbase # FFI390_RET_INT64
+
+.LFE1:
+.ffi_call_SYSV_end:
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+ .globl ffi_closure_SYSV
+ .type ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+ stm %r12,%r15,48(%r15) # Save registers
+.LCFI10:
+ basr %r13,0 # Set up base register
+.Lcbase:
+ stm %r2,%r6,8(%r15) # Save arguments
+ std %f0,64(%r15)
+ std %f2,72(%r15)
+ lr %r1,%r15 # Set up stack frame
+ ahi %r15,-96
+.LCFI11:
+ l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
+ lr %r2,%r0 # Closure
+ la %r3,8(%r1) # GPRs
+ la %r4,64(%r1) # FPRs
+ la %r5,96(%r1) # Overflow
+ st %r1,0(%r15) # Set up back chain
+
+ bas %r14,0(%r12,%r13) # Call helper
+
+ l %r4,96+56(%r15)
+ ld %f0,96+64(%r15) # Load return registers
+ lm %r2,%r3,96+8(%r15)
+ lm %r12,%r15,96+48(%r15)
+ br %r4
+
+ .align 4
+.Lchelper:
+ .long ffi_closure_helper_SYSV-.Lcbase
+
+.LFE2:
+
+.ffi_closure_SYSV_end:
+ .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 -4 # CIE Data Alignment Factor
+ .byte 0xe # CIE RA Column
+ .uleb128 0x1 # Augmentation size
+ .byte 0x1b # FDE Encoding (pcrel sdata4)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0x60
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 # FDE Length
+.LASFDE1:
+ .4byte .LASFDE1-.Lframe1 # FDE CIE offset
+ .4byte .LFB1-. # FDE initial location
+ .4byte .LFE1-.LFB1 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI0-.LFB1
+ .byte 0x8f # DW_CFA_offset, column 0xf
+ .uleb128 0x9
+ .byte 0x8e # DW_CFA_offset, column 0xe
+ .uleb128 0xa
+ .byte 0x8d # DW_CFA_offset, column 0xd
+ .uleb128 0xb
+ .byte 0x8c # DW_CFA_offset, column 0xc
+ .uleb128 0xc
+ .byte 0x8b # DW_CFA_offset, column 0xb
+ .uleb128 0xd
+ .byte 0x8a # DW_CFA_offset, column 0xa
+ .uleb128 0xe
+ .byte 0x89 # DW_CFA_offset, column 0x9
+ .uleb128 0xf
+ .byte 0x88 # DW_CFA_offset, column 0x8
+ .uleb128 0x10
+ .byte 0x87 # DW_CFA_offset, column 0x7
+ .uleb128 0x11
+ .byte 0x86 # DW_CFA_offset, column 0x6
+ .uleb128 0x12
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI1-.LCFI0
+ .byte 0xd # DW_CFA_def_cfa_register
+ .uleb128 0xb
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI2-.LCFI1
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 0x90
+ .align 4
+.LEFDE1:
+.LSFDE2:
+ .4byte .LEFDE2-.LASFDE2 # FDE Length
+.LASFDE2:
+ .4byte .LASFDE2-.Lframe1 # FDE CIE offset
+ .4byte .LFB2-. # FDE initial location
+ .4byte .LFE2-.LFB2 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI10-.LFB2
+ .byte 0x8f # DW_CFA_offset, column 0xf
+ .uleb128 0x9
+ .byte 0x8e # DW_CFA_offset, column 0xe
+ .uleb128 0xa
+ .byte 0x8d # DW_CFA_offset, column 0xd
+ .uleb128 0xb
+ .byte 0x8c # DW_CFA_offset, column 0xc
+ .uleb128 0xc
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI11-.LCFI10
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 0xc0
+ .align 4
+.LEFDE2:
+
+#else
+
+.text
+
+ # r2: cif->bytes
+ # r3: &ecif
+ # r4: ffi_prep_args
+ # r5: ret_type
+ # r6: ecif.rvalue
+ # ov: fn
+
+ # This assumes we are using gas.
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+ stmg %r6,%r15,48(%r15) # Save registers
+.LCFI0:
+ larl %r13,.Lbase # Set up base register
+ lgr %r11,%r15 # Set up frame pointer
+.LCFI1:
+ sgr %r15,%r2
+ aghi %r15,-160-80 # Allocate stack
+ lgr %r8,%r6 # Save ecif.rvalue
+ llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
+ lg %r7,160(%r11) # Load function address
+ stg %r11,0(%r15) # Set up back chain
+ aghi %r11,-80 # Register save area
+.LCFI2:
+
+ la %r2,160(%r15) # Save area
+ # r3 already holds &ecif
+ basr %r14,%r4 # Call ffi_prep_args
+
+ lmg %r2,%r6,0(%r11) # Load arguments
+ ld %f0,48(%r11)
+ ld %f2,56(%r11)
+ ld %f4,64(%r11)
+ ld %f6,72(%r11)
+ la %r14,0(%r13,%r9) # Set return address
+ br %r7 # ... and call function
+
+.Lbase:
+.LretNone: # Return void
+ lg %r4,80+112(%r11)
+ lmg %r6,%r15,80+48(%r11)
+ br %r4
+
+.LretFloat:
+ lg %r4,80+112(%r11)
+ ste %f0,0(%r8) # Return float
+ lmg %r6,%r15,80+48(%r11)
+ br %r4
+
+.LretDouble:
+ lg %r4,80+112(%r11)
+ std %f0,0(%r8) # Return double
+ lmg %r6,%r15,80+48(%r11)
+ br %r4
+
+.LretInt32:
+ lg %r4,80+112(%r11)
+ st %r2,0(%r8) # Return int
+ lmg %r6,%r15,80+48(%r11)
+ br %r4
+
+.LretInt64:
+ lg %r4,80+112(%r11)
+ stg %r2,0(%r8) # Return long
+ lmg %r6,%r15,80+48(%r11)
+ br %r4
+
+.Ltable:
+ .byte .LretNone-.Lbase # FFI390_RET_VOID
+ .byte .LretNone-.Lbase # FFI390_RET_STRUCT
+ .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
+ .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
+ .byte .LretInt32-.Lbase # FFI390_RET_INT32
+ .byte .LretInt64-.Lbase # FFI390_RET_INT64
+
+.LFE1:
+.ffi_call_SYSV_end:
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+ .globl ffi_closure_SYSV
+ .type ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+ stmg %r14,%r15,112(%r15) # Save registers
+.LCFI10:
+ stmg %r2,%r6,16(%r15) # Save arguments
+ std %f0,128(%r15)
+ std %f2,136(%r15)
+ std %f4,144(%r15)
+ std %f6,152(%r15)
+ lgr %r1,%r15 # Set up stack frame
+ aghi %r15,-160
+.LCFI11:
+ lgr %r2,%r0 # Closure
+ la %r3,16(%r1) # GPRs
+ la %r4,128(%r1) # FPRs
+ la %r5,160(%r1) # Overflow
+ stg %r1,0(%r15) # Set up back chain
+
+ brasl %r14,ffi_closure_helper_SYSV # Call helper
+
+ lg %r14,160+112(%r15)
+ ld %f0,160+128(%r15) # Load return registers
+ lg %r2,160+16(%r15)
+ la %r15,160(%r15)
+ br %r14
+.LFE2:
+
+.ffi_closure_SYSV_end:
+ .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+ .4byte 0x0 # CIE Identifier Tag
+ .byte 0x1 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 -8 # CIE Data Alignment Factor
+ .byte 0xe # CIE RA Column
+ .uleb128 0x1 # Augmentation size
+ .byte 0x1b # FDE Encoding (pcrel sdata4)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0xa0
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 # FDE Length
+.LASFDE1:
+ .4byte .LASFDE1-.Lframe1 # FDE CIE offset
+ .4byte .LFB1-. # FDE initial location
+ .4byte .LFE1-.LFB1 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI0-.LFB1
+ .byte 0x8f # DW_CFA_offset, column 0xf
+ .uleb128 0x5
+ .byte 0x8e # DW_CFA_offset, column 0xe
+ .uleb128 0x6
+ .byte 0x8d # DW_CFA_offset, column 0xd
+ .uleb128 0x7
+ .byte 0x8c # DW_CFA_offset, column 0xc
+ .uleb128 0x8
+ .byte 0x8b # DW_CFA_offset, column 0xb
+ .uleb128 0x9
+ .byte 0x8a # DW_CFA_offset, column 0xa
+ .uleb128 0xa
+ .byte 0x89 # DW_CFA_offset, column 0x9
+ .uleb128 0xb
+ .byte 0x88 # DW_CFA_offset, column 0x8
+ .uleb128 0xc
+ .byte 0x87 # DW_CFA_offset, column 0x7
+ .uleb128 0xd
+ .byte 0x86 # DW_CFA_offset, column 0x6
+ .uleb128 0xe
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI1-.LCFI0
+ .byte 0xd # DW_CFA_def_cfa_register
+ .uleb128 0xb
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI2-.LCFI1
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 0xf0
+ .align 8
+.LEFDE1:
+.LSFDE2:
+ .4byte .LEFDE2-.LASFDE2 # FDE Length
+.LASFDE2:
+ .4byte .LASFDE2-.Lframe1 # FDE CIE offset
+ .4byte .LFB2-. # FDE initial location
+ .4byte .LFE2-.LFB2 # FDE address range
+ .uleb128 0x0 # Augmentation size
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI10-.LFB2
+ .byte 0x8f # DW_CFA_offset, column 0xf
+ .uleb128 0x5
+ .byte 0x8e # DW_CFA_offset, column 0xe
+ .uleb128 0x6
+ .byte 0x4 # DW_CFA_advance_loc4
+ .4byte .LCFI11-.LCFI10
+ .byte 0xe # DW_CFA_def_cfa_offset
+ .uleb128 0x140
+ .align 8
+.LEFDE2:
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffi.c
new file mode 100644
index 000000000..38449e9e6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffi.c
@@ -0,0 +1,728 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima
+
+ SuperH Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 4
+#if defined(__SH4__)
+#define NFREGARG 8
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+/* If the structure has essentialy an unique element, return its type. */
+static int
+simple_type (ffi_type *arg)
+{
+ if (arg->type != FFI_TYPE_STRUCT)
+ return arg->type;
+ else if (arg->elements[1])
+ return FFI_TYPE_STRUCT;
+
+ return simple_type (arg->elements[0]);
+}
+
+static int
+return_type (ffi_type *arg)
+{
+ unsigned short type;
+
+ if (arg->type != FFI_TYPE_STRUCT)
+ return arg->type;
+
+ type = simple_type (arg->elements[0]);
+ if (! arg->elements[1])
+ {
+ switch (type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ return FFI_TYPE_INT;
+
+ default:
+ return type;
+ }
+ }
+
+ /* gcc uses r0/r1 pair for some kind of structures. */
+ if (arg->size <= 2 * sizeof (int))
+ {
+ int i = 0;
+ ffi_type *e;
+
+ while ((e = arg->elements[i++]))
+ {
+ type = simple_type (e);
+ switch (type)
+ {
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_INT:
+ case FFI_TYPE_FLOAT:
+ return FFI_TYPE_UINT64;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register int tmp;
+ register unsigned int avn;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+ int greg, ireg;
+#if defined(__SH4__)
+ int freg = 0;
+#endif
+
+ tmp = 0;
+ argp = stack;
+
+ if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+ {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
+ }
+ else
+ ireg = 0;
+
+ /* Set arguments for registers. */
+ greg = ireg;
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ if (greg++ >= NGREGARG)
+ continue;
+
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ argp += z;
+ }
+ else if (z == sizeof(int))
+ {
+#if defined(__SH4__)
+ if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ if (freg++ >= NFREGARG)
+ continue;
+ }
+ else
+#endif
+ {
+ if (greg++ >= NGREGARG)
+ continue;
+ }
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ argp += z;
+ }
+#if defined(__SH4__)
+ else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+ {
+ if (freg + 1 >= NFREGARG)
+ continue;
+ freg = (freg + 1) & ~1;
+ freg += 2;
+ memcpy (argp, *p_argv, z);
+ argp += z;
+ }
+#endif
+ else
+ {
+ int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+ if (greg + n - 1 >= NGREGARG)
+ continue;
+#else
+ if (greg >= NGREGARG)
+ continue;
+#endif
+ greg += n;
+ memcpy (argp, *p_argv, z);
+ argp += n * sizeof (int);
+ }
+ }
+
+ /* Set arguments on stack. */
+ greg = ireg;
+#if defined(__SH4__)
+ freg = 0;
+#endif
+ p_argv = ecif->avalue;
+
+ for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ if (greg++ < NGREGARG)
+ continue;
+
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ argp += z;
+ }
+ else if (z == sizeof(int))
+ {
+#if defined(__SH4__)
+ if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ if (freg++ < NFREGARG)
+ continue;
+ }
+ else
+#endif
+ {
+ if (greg++ < NGREGARG)
+ continue;
+ }
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ argp += z;
+ }
+#if defined(__SH4__)
+ else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+ {
+ if (freg + 1 < NFREGARG)
+ {
+ freg = (freg + 1) & ~1;
+ freg += 2;
+ continue;
+ }
+ memcpy (argp, *p_argv, z);
+ argp += z;
+ }
+#endif
+ else
+ {
+ int n = (z + sizeof (int) - 1) / sizeof (int);
+ if (greg + n - 1 < NGREGARG)
+ {
+ greg += n;
+ continue;
+ }
+#if (! defined(__SH4__))
+ else if (greg < NGREGARG)
+ {
+ greg = NGREGARG;
+ continue;
+ }
+#endif
+ memcpy (argp, *p_argv, z);
+ argp += n * sizeof (int);
+ }
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ int i, j;
+ int size, type;
+ int n, m;
+ int greg;
+#if defined(__SH4__)
+ int freg = 0;
+#endif
+
+ cif->flags = 0;
+
+ greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
+ STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
+
+#if defined(__SH4__)
+ for (i = j = 0; i < cif->nargs && j < 12; i++)
+ {
+ type = (cif->arg_types)[i]->type;
+ switch (type)
+ {
+ case FFI_TYPE_FLOAT:
+ if (freg >= NFREGARG)
+ continue;
+ freg++;
+ cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+ j++;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ if ((freg + 1) >= NFREGARG)
+ continue;
+ freg = (freg + 1) & ~1;
+ freg += 2;
+ cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+ j++;
+ break;
+
+ default:
+ size = (cif->arg_types)[i]->size;
+ n = (size + sizeof (int) - 1) / sizeof (int);
+ if (greg + n - 1 >= NGREGARG)
+ continue;
+ greg += n;
+ for (m = 0; m < n; m++)
+ cif->flags += FFI_TYPE_INT << (2 * j++);
+ break;
+ }
+ }
+#else
+ for (i = j = 0; i < cif->nargs && j < 4; i++)
+ {
+ size = (cif->arg_types)[i]->size;
+ n = (size + sizeof (int) - 1) / sizeof (int);
+ if (greg >= NGREGARG)
+ continue;
+ else if (greg + n - 1 >= NGREGARG)
+ n = NGREGARG - greg;
+ greg += n;
+ for (m = 0; m < n; m++)
+ cif->flags += FFI_TYPE_INT << (2 * j++);
+ }
+#endif
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_STRUCT:
+ cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
+ break;
+
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags += (unsigned) cif->rtype->type << 24;
+ break;
+
+ default:
+ cif->flags += FFI_TYPE_INT << 24;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+ UINT64 trvalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+ && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+ ecif.rvalue = &trvalue;
+ else if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+
+ if (rvalue
+ && cif->rtype->type == FFI_TYPE_STRUCT
+ && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+ memcpy (rvalue, &trvalue, cif->rtype->size);
+}
+
+extern void ffi_closure_SYSV (void);
+#if defined(__SH4__)
+extern void __ic_invalidate (void *line);
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp;
+ unsigned short insn;
+
+ FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ /* Set T bit if the function returns a struct pointed with R2. */
+ insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
+ ? 0x0018 /* sett */
+ : 0x0008 /* clrt */);
+
+#ifdef __LITTLE_ENDIAN__
+ tramp[0] = 0xd301d102;
+ tramp[1] = 0x0000412b | (insn << 16);
+#else
+ tramp[0] = 0xd102d301;
+ tramp[1] = 0x412b0000 | insn;
+#endif
+ *(void **) &tramp[2] = (void *)closure; /* ctx */
+ *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+#if defined(__SH4__)
+ /* Flush the icache. */
+ __ic_invalidate(&closure->tramp[0]);
+#endif
+
+ return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the
+ * following helper function to do most of the work.
+ */
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_INT8 0
+#define OFS_INT16 0
+#else
+#define OFS_INT8 3
+#define OFS_INT16 2
+#endif
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
+ unsigned long *pgr, unsigned long *pfr,
+ unsigned long *pst)
+{
+ void **avalue;
+ ffi_type **p_arg;
+ int i, avn;
+ int ireg, greg = 0;
+#if defined(__SH4__)
+ int freg = 0;
+#endif
+ ffi_cif *cif;
+ double temp;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller. */
+ if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
+ {
+ rvalue = *pgr++;
+ ireg = 1;
+ }
+ else
+ ireg = 0;
+
+ cif = closure->cif;
+ greg = ireg;
+ avn = cif->nargs;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ if (greg++ >= NGREGARG)
+ continue;
+
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = (((char *)pgr) + OFS_INT8);
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = (((char *)pgr) + OFS_INT16);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ avalue[i] = pgr;
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ pgr++;
+ }
+ else if (z == sizeof(int))
+ {
+#if defined(__SH4__)
+ if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ if (freg++ >= NFREGARG)
+ continue;
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+#endif
+ {
+ if (greg++ >= NGREGARG)
+ continue;
+ avalue[i] = pgr;
+ pgr++;
+ }
+ }
+#if defined(__SH4__)
+ else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+ {
+ if (freg + 1 >= NFREGARG)
+ continue;
+ freg = (freg + 1) & ~1;
+ freg += 2;
+ avalue[i] = pfr;
+ pfr += 2;
+ }
+#endif
+ else
+ {
+ int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+ if (greg + n - 1 >= NGREGARG)
+ continue;
+#else
+ if (greg >= NGREGARG)
+ continue;
+#endif
+ greg += n;
+ avalue[i] = pgr;
+ pgr += n;
+ }
+ }
+
+ greg = ireg;
+#if defined(__SH4__)
+ freg = 0;
+#endif
+
+ for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ if (greg++ < NGREGARG)
+ continue;
+
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = (((char *)pst) + OFS_INT8);
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = (((char *)pst) + OFS_INT16);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ avalue[i] = pst;
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ pst++;
+ }
+ else if (z == sizeof(int))
+ {
+#if defined(__SH4__)
+ if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ if (freg++ < NFREGARG)
+ continue;
+ }
+ else
+#endif
+ {
+ if (greg++ < NGREGARG)
+ continue;
+ }
+ avalue[i] = pst;
+ pst++;
+ }
+#if defined(__SH4__)
+ else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+ {
+ if (freg + 1 < NFREGARG)
+ {
+ freg = (freg + 1) & ~1;
+ freg += 2;
+ continue;
+ }
+ avalue[i] = pst;
+ pst += 2;
+ }
+#endif
+ else
+ {
+ int n = (z + sizeof (int) - 1) / sizeof (int);
+ if (greg + n - 1 < NGREGARG)
+ {
+ greg += n;
+ continue;
+ }
+#if (! defined(__SH4__))
+ else if (greg < NGREGARG)
+ {
+ greg += n;
+ pst += greg - NGREGARG;
+ continue;
+ }
+#endif
+ avalue[i] = pst;
+ pst += n;
+ }
+ }
+
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_SYSV how to perform return type promotions. */
+ return return_type (cif->rtype);
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffitarget.h
new file mode 100644
index 000000000..f8492a1c0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffitarget.h
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for SuperH.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/sysv.S
new file mode 100644
index 000000000..c9002a750
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/sysv.S
@@ -0,0 +1,845 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2002, 2003, 2004 Kaz Kojima
+
+ SuperH Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+.text
+
+ # r4: ffi_prep_args
+ # r5: &ecif
+ # r6: bytes
+ # r7: flags
+ # sp+0: rvalue
+ # sp+4: fn
+
+ # This assumes we are using gas.
+ENTRY(ffi_call_SYSV)
+ # Save registers
+.LFB1:
+ mov.l r8,@-r15
+.LCFI0:
+ mov.l r9,@-r15
+.LCFI1:
+ mov.l r10,@-r15
+.LCFI2:
+ mov.l r12,@-r15
+.LCFI3:
+ mov.l r14,@-r15
+.LCFI4:
+ sts.l pr,@-r15
+.LCFI5:
+ mov r15,r14
+.LCFI6:
+#if defined(__SH4__)
+ mov r6,r8
+ mov r7,r9
+
+ sub r6,r15
+ add #-16,r15
+ mov #~7,r0
+ and r0,r15
+
+ mov r4,r0
+ jsr @r0
+ mov r15,r4
+
+ mov r9,r1
+ shlr8 r9
+ shlr8 r9
+ shlr8 r9
+
+ mov #FFI_TYPE_STRUCT,r2
+ cmp/eq r2,r9
+ bf 1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+ mov.l @r15+,r4
+ bra 2f
+ mov #5,r2
+#else
+ mov.l @r15+,r10
+#endif
+1:
+ mov #4,r2
+2:
+ mov #4,r3
+
+L_pass:
+ cmp/pl r8
+ bf L_call_it
+
+ mov r1,r0
+ and #3,r0
+
+L_pass_d:
+ cmp/eq #FFI_TYPE_DOUBLE,r0
+ bf L_pass_f
+
+ mov r3,r0
+ and #1,r0
+ tst r0,r0
+ bt 1f
+ add #1,r3
+1:
+ mov #12,r0
+ cmp/hs r0,r3
+ bt/s 3f
+ shlr2 r1
+ bsr L_pop_d
+ nop
+3:
+ add #2,r3
+ bra L_pass
+ add #-8,r8
+
+L_pop_d:
+ mov r3,r0
+ add r0,r0
+ add r3,r0
+ add #-12,r0
+ braf r0
+ nop
+#ifdef __LITTLE_ENDIAN__
+ fmov.s @r15+,fr5
+ rts
+ fmov.s @r15+,fr4
+ fmov.s @r15+,fr7
+ rts
+ fmov.s @r15+,fr6
+ fmov.s @r15+,fr9
+ rts
+ fmov.s @r15+,fr8
+ fmov.s @r15+,fr11
+ rts
+ fmov.s @r15+,fr10
+#else
+ fmov.s @r15+,fr4
+ rts
+ fmov.s @r15+,fr5
+ fmov.s @r15+,fr6
+ rts
+ fmov.s @r15+,fr7
+ fmov.s @r15+,fr8
+ rts
+ fmov.s @r15+,fr9
+ fmov.s @r15+,fr10
+ rts
+ fmov.s @r15+,fr11
+#endif
+
+L_pass_f:
+ cmp/eq #FFI_TYPE_FLOAT,r0
+ bf L_pass_i
+
+ mov #12,r0
+ cmp/hs r0,r3
+ bt/s 2f
+ shlr2 r1
+ bsr L_pop_f
+ nop
+2:
+ add #1,r3
+ bra L_pass
+ add #-4,r8
+
+L_pop_f:
+ mov r3,r0
+ shll2 r0
+ add #-16,r0
+ braf r0
+ nop
+#ifdef __LITTLE_ENDIAN__
+ rts
+ fmov.s @r15+,fr5
+ rts
+ fmov.s @r15+,fr4
+ rts
+ fmov.s @r15+,fr7
+ rts
+ fmov.s @r15+,fr6
+ rts
+ fmov.s @r15+,fr9
+ rts
+ fmov.s @r15+,fr8
+ rts
+ fmov.s @r15+,fr11
+ rts
+ fmov.s @r15+,fr10
+#else
+ rts
+ fmov.s @r15+,fr4
+ rts
+ fmov.s @r15+,fr5
+ rts
+ fmov.s @r15+,fr6
+ rts
+ fmov.s @r15+,fr7
+ rts
+ fmov.s @r15+,fr8
+ rts
+ fmov.s @r15+,fr9
+ rts
+ fmov.s @r15+,fr10
+ rts
+ fmov.s @r15+,fr11
+#endif
+
+L_pass_i:
+ cmp/eq #FFI_TYPE_INT,r0
+ bf L_call_it
+
+ mov #8,r0
+ cmp/hs r0,r2
+ bt/s 2f
+ shlr2 r1
+ bsr L_pop_i
+ nop
+2:
+ add #1,r2
+ bra L_pass
+ add #-4,r8
+
+L_pop_i:
+ mov r2,r0
+ shll2 r0
+ add #-16,r0
+ braf r0
+ nop
+ rts
+ mov.l @r15+,r4
+ rts
+ mov.l @r15+,r5
+ rts
+ mov.l @r15+,r6
+ rts
+ mov.l @r15+,r7
+
+L_call_it:
+ # call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+ mov r10, r2
+#endif
+ mov.l @(28,r14),r1
+ jsr @r1
+ nop
+
+L_ret_d:
+ mov #FFI_TYPE_DOUBLE,r2
+ cmp/eq r2,r9
+ bf L_ret_ll
+
+ mov.l @(24,r14),r1
+#ifdef __LITTLE_ENDIAN__
+ fmov.s fr1,@r1
+ add #4,r1
+ bra L_epilogue
+ fmov.s fr0,@r1
+#else
+ fmov.s fr0,@r1
+ add #4,r1
+ bra L_epilogue
+ fmov.s fr1,@r1
+#endif
+
+L_ret_ll:
+ mov #FFI_TYPE_SINT64,r2
+ cmp/eq r2,r9
+ bt/s 1f
+ mov #FFI_TYPE_UINT64,r2
+ cmp/eq r2,r9
+ bf L_ret_f
+
+1:
+ mov.l @(24,r14),r2
+ mov.l r0,@r2
+ bra L_epilogue
+ mov.l r1,@(4,r2)
+
+L_ret_f:
+ mov #FFI_TYPE_FLOAT,r2
+ cmp/eq r2,r9
+ bf L_ret_i
+
+ mov.l @(24,r14),r1
+ bra L_epilogue
+ fmov.s fr0,@r1
+
+L_ret_i:
+ mov #FFI_TYPE_INT,r2
+ cmp/eq r2,r9
+ bf L_epilogue
+
+ mov.l @(24,r14),r1
+ bra L_epilogue
+ mov.l r0,@r1
+
+L_epilogue:
+ # Remove the space we pushed for the args
+ mov r14,r15
+
+ lds.l @r15+,pr
+ mov.l @r15+,r14
+ mov.l @r15+,r12
+ mov.l @r15+,r10
+ mov.l @r15+,r9
+ rts
+ mov.l @r15+,r8
+#else
+ mov r6,r8
+ mov r7,r9
+
+ sub r6,r15
+ add #-16,r15
+ mov #~7,r0
+ and r0,r15
+
+ mov r4,r0
+ jsr @r0
+ mov r15,r4
+
+ mov r9,r3
+ shlr8 r9
+ shlr8 r9
+ shlr8 r9
+
+ mov #FFI_TYPE_STRUCT,r2
+ cmp/eq r2,r9
+ bf 1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+ mov.l @r15+,r4
+ bra 2f
+ mov #5,r2
+#else
+ mov.l @r15+,r10
+#endif
+1:
+ mov #4,r2
+2:
+
+L_pass:
+ cmp/pl r8
+ bf L_call_it
+
+ mov r3,r0
+ and #3,r0
+
+L_pass_d:
+ cmp/eq #FFI_TYPE_DOUBLE,r0
+ bf L_pass_i
+
+ mov r15,r0
+ and #7,r0
+ tst r0,r0
+ bt 1f
+ add #4,r15
+1:
+ mov #8,r0
+ cmp/hs r0,r2
+ bt/s 2f
+ shlr2 r3
+ bsr L_pop_d
+ nop
+2:
+ add #2,r2
+ bra L_pass
+ add #-8,r8
+
+L_pop_d:
+ mov r2,r0
+ add r0,r0
+ add r2,r0
+ add #-12,r0
+ add r0,r0
+ braf r0
+ nop
+ mov.l @r15+,r4
+ rts
+ mov.l @r15+,r5
+ mov.l @r15+,r5
+ rts
+ mov.l @r15+,r6
+ mov.l @r15+,r6
+ rts
+ mov.l @r15+,r7
+ rts
+ mov.l @r15+,r7
+
+L_pass_i:
+ cmp/eq #FFI_TYPE_INT,r0
+ bf L_call_it
+
+ mov #8,r0
+ cmp/hs r0,r2
+ bt/s 2f
+ shlr2 r3
+ bsr L_pop_i
+ nop
+2:
+ add #1,r2
+ bra L_pass
+ add #-4,r8
+
+L_pop_i:
+ mov r2,r0
+ shll2 r0
+ add #-16,r0
+ braf r0
+ nop
+ rts
+ mov.l @r15+,r4
+ rts
+ mov.l @r15+,r5
+ rts
+ mov.l @r15+,r6
+ rts
+ mov.l @r15+,r7
+
+L_call_it:
+ # call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+ mov r10, r2
+#endif
+ mov.l @(28,r14),r1
+ jsr @r1
+ nop
+
+L_ret_d:
+ mov #FFI_TYPE_DOUBLE,r2
+ cmp/eq r2,r9
+ bf L_ret_ll
+
+ mov.l @(24,r14),r2
+ mov.l r0,@r2
+ bra L_epilogue
+ mov.l r1,@(4,r2)
+
+L_ret_ll:
+ mov #FFI_TYPE_SINT64,r2
+ cmp/eq r2,r9
+ bt/s 1f
+ mov #FFI_TYPE_UINT64,r2
+ cmp/eq r2,r9
+ bf L_ret_i
+
+1:
+ mov.l @(24,r14),r2
+ mov.l r0,@r2
+ bra L_epilogue
+ mov.l r1,@(4,r2)
+
+L_ret_i:
+ mov #FFI_TYPE_FLOAT,r2
+ cmp/eq r2,r9
+ bt 1f
+ mov #FFI_TYPE_INT,r2
+ cmp/eq r2,r9
+ bf L_epilogue
+1:
+ mov.l @(24,r14),r1
+ bra L_epilogue
+ mov.l r0,@r1
+
+L_epilogue:
+ # Remove the space we pushed for the args
+ mov r14,r15
+
+ lds.l @r15+,pr
+ mov.l @r15+,r14
+ mov.l @r15+,r12
+ mov.l @r15+,r10
+ mov.l @r15+,r9
+ rts
+ mov.l @r15+,r8
+#endif
+.LFE1:
+.ffi_call_SYSV_end:
+ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+.globl ffi_closure_helper_SYSV
+
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+ mov.l r7,@-r15
+.LCFI7:
+ mov.l r6,@-r15
+.LCFI8:
+ mov.l r5,@-r15
+.LCFI9:
+ mov.l r4,@-r15
+.LCFIA:
+ mov.l r14,@-r15
+.LCFIB:
+ sts.l pr,@-r15
+
+ /* Stack layout:
+ xx bytes (on stack parameters)
+ 16 bytes (register parameters)
+ 4 bytes (saved frame pointer)
+ 4 bytes (saved return address)
+ 32 bytes (floating register parameters, SH-4 only)
+ 8 bytes (result)
+ 4 bytes (pad)
+ 4 bytes (5th arg)
+ <- new stack pointer
+ */
+.LCFIC:
+#if defined(__SH4__)
+ add #-48,r15
+#else
+ add #-16,r15
+#endif
+.LCFID:
+ mov r15,r14
+.LCFIE:
+
+#if defined(__SH4__)
+ mov r14,r1
+ add #48,r1
+#ifdef __LITTLE_ENDIAN__
+ fmov.s fr10,@-r1
+ fmov.s fr11,@-r1
+ fmov.s fr8,@-r1
+ fmov.s fr9,@-r1
+ fmov.s fr6,@-r1
+ fmov.s fr7,@-r1
+ fmov.s fr4,@-r1
+ fmov.s fr5,@-r1
+#else
+ fmov.s fr11,@-r1
+ fmov.s fr10,@-r1
+ fmov.s fr9,@-r1
+ fmov.s fr8,@-r1
+ fmov.s fr7,@-r1
+ fmov.s fr6,@-r1
+ fmov.s fr5,@-r1
+ fmov.s fr4,@-r1
+#endif
+ mov r1,r7
+ mov r14,r6
+ add #56,r6
+#else
+ mov r14,r6
+ add #24,r6
+#endif
+
+ bt/s 10f
+ mov r2, r5
+ mov r14,r1
+ add #8,r1
+ mov r1,r5
+10:
+
+ mov r14,r1
+#if defined(__SH4__)
+ add #72,r1
+#else
+ add #40,r1
+#endif
+ mov.l r1,@r14
+
+#ifdef PIC
+ mov.l L_got,r1
+ mova L_got,r0
+ add r0,r1
+ mov.l L_helper,r0
+ add r1,r0
+#else
+ mov.l L_helper,r0
+#endif
+ jsr @r0
+ mov r3,r4
+
+ shll r0
+ mov r0,r1
+ mova L_table,r0
+ add r1,r0
+ mov.w @r0,r0
+ mov r14,r2
+ braf r0
+ add #8,r2
+0:
+ .align 2
+#ifdef PIC
+L_got:
+ .long _GLOBAL_OFFSET_TABLE_
+L_helper:
+ .long ffi_closure_helper_SYSV@GOTOFF
+#else
+L_helper:
+ .long ffi_closure_helper_SYSV
+#endif
+L_table:
+ .short L_case_v - 0b /* FFI_TYPE_VOID */
+ .short L_case_i - 0b /* FFI_TYPE_INT */
+#if defined(__SH4__)
+ .short L_case_f - 0b /* FFI_TYPE_FLOAT */
+ .short L_case_d - 0b /* FFI_TYPE_DOUBLE */
+ .short L_case_d - 0b /* FFI_TYPE_LONGDOUBLE */
+#else
+ .short L_case_i - 0b /* FFI_TYPE_FLOAT */
+ .short L_case_ll - 0b /* FFI_TYPE_DOUBLE */
+ .short L_case_ll - 0b /* FFI_TYPE_LONGDOUBLE */
+#endif
+ .short L_case_uq - 0b /* FFI_TYPE_UINT8 */
+ .short L_case_q - 0b /* FFI_TYPE_SINT8 */
+ .short L_case_uh - 0b /* FFI_TYPE_UINT16 */
+ .short L_case_h - 0b /* FFI_TYPE_SINT16 */
+ .short L_case_i - 0b /* FFI_TYPE_UINT32 */
+ .short L_case_i - 0b /* FFI_TYPE_SINT32 */
+ .short L_case_ll - 0b /* FFI_TYPE_UINT64 */
+ .short L_case_ll - 0b /* FFI_TYPE_SINT64 */
+ .short L_case_v - 0b /* FFI_TYPE_STRUCT */
+ .short L_case_i - 0b /* FFI_TYPE_POINTER */
+
+#if defined(__SH4__)
+L_case_d:
+#ifdef __LITTLE_ENDIAN__
+ fmov.s @r2+,fr1
+ bra L_case_v
+ fmov.s @r2,fr0
+#else
+ fmov.s @r2+,fr0
+ bra L_case_v
+ fmov.s @r2,fr1
+#endif
+
+L_case_f:
+ bra L_case_v
+ fmov.s @r2,fr0
+#endif
+
+L_case_ll:
+ mov.l @r2+,r0
+ bra L_case_v
+ mov.l @r2,r1
+
+L_case_i:
+ bra L_case_v
+ mov.l @r2,r0
+
+L_case_q:
+#ifdef __LITTLE_ENDIAN__
+#else
+ add #3,r2
+#endif
+ bra L_case_v
+ mov.b @r2,r0
+
+L_case_uq:
+#ifdef __LITTLE_ENDIAN__
+#else
+ add #3,r2
+#endif
+ mov.b @r2,r0
+ bra L_case_v
+ extu.b r0,r0
+
+L_case_h:
+#ifdef __LITTLE_ENDIAN__
+#else
+ add #2,r2
+#endif
+ bra L_case_v
+ mov.w @r2,r0
+
+L_case_uh:
+#ifdef __LITTLE_ENDIAN__
+#else
+ add #2,r2
+#endif
+ mov.w @r2,r0
+ extu.w r0,r0
+ /* fall through */
+
+L_case_v:
+#if defined(__SH4__)
+ add #48,r15
+#else
+ add #16,r15
+#endif
+ lds.l @r15+,pr
+ mov.l @r15+,r14
+ rts
+ add #16,r15
+.LFE2:
+.ffi_closure_SYSV_end:
+ .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+ .section ".eh_frame","aw",@progbits
+__FRAME_BEGIN__:
+ .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .4byte 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef PIC
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .byte 0x0 /* CIE Augmentation */
+#endif
+ .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x11 /* CIE RA Column */
+#ifdef PIC
+ .uleb128 0x1 /* Augmentation size */
+ .byte 0x10 /* FDE Encoding (pcrel) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0xf /* uleb128 0xf */
+ .byte 0x0 /* uleb128 0x0 */
+ .align 2
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .4byte .LASFDE1-__FRAME_BEGIN__ /* FDE CIE offset */
+#ifdef PIC
+ .4byte .LFB1-. /* FDE initial location */
+#else
+ .4byte .LFB1 /* FDE initial location */
+#endif
+ .4byte .LFE1-.LFB1 /* FDE address range */
+#ifdef PIC
+ .uleb128 0x0 /* Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x4 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI1-.LCFI0
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI2-.LCFI1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0xc /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI3-.LCFI2
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x10 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI4-.LCFI3
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x14 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI5-.LCFI4
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x18 /* uleb128 0x4 */
+ .byte 0x91 /* DW_CFA_offset, column 0x11 */
+ .byte 0x6 /* uleb128 0x6 */
+ .byte 0x8e /* DW_CFA_offset, column 0xe */
+ .byte 0x5 /* uleb128 0x5 */
+ .byte 0x8c /* DW_CFA_offset, column 0xc */
+ .byte 0x4 /* uleb128 0x4 */
+ .byte 0x8a /* DW_CFA_offset, column 0xa */
+ .byte 0x3 /* uleb128 0x3 */
+ .byte 0x89 /* DW_CFA_offset, column 0x9 */
+ .byte 0x2 /* uleb128 0x2 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* uleb128 0x1 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI6-.LCFI5
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0xe /* uleb128 0xe */
+ .align 2
+.LEFDE1:
+
+.LSFDE3:
+ .4byte .LEFDE3-.LASFDE3 /* FDE Length */
+.LASFDE3:
+ .4byte .LASFDE3-__FRAME_BEGIN__ /* FDE CIE offset */
+#ifdef PIC
+ .4byte .LFB2-. /* FDE initial location */
+#else
+ .4byte .LFB2 /* FDE initial location */
+#endif
+ .4byte .LFE2-.LFB2 /* FDE address range */
+#ifdef PIC
+ .uleb128 0x0 /* Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI7-.LFB2
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x4 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI8-.LCFI7
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFI9-.LCFI8
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0xc /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFIA-.LCFI9
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x10 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFIB-.LCFIA
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x14 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFIC-.LCFIB
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x18 /* uleb128 0x4 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFID-.LCFIC
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+#if defined(__SH4__)
+ .byte 24+48 /* uleb128 24+48 */
+#else
+ .byte 24+16 /* uleb128 24+16 */
+#endif
+ .byte 0x91 /* DW_CFA_offset, column 0x11 */
+ .byte 0x6 /* uleb128 0x6 */
+ .byte 0x8e /* DW_CFA_offset, column 0xe */
+ .byte 0x5 /* uleb128 0x5 */
+ .byte 0x8b /* DW_CFA_offset, column 0xb */
+ .byte 0x4 /* uleb128 0x4 */
+ .byte 0x8a /* DW_CFA_offset, column 0xa */
+ .byte 0x3 /* uleb128 0x3 */
+ .byte 0x89 /* DW_CFA_offset, column 0x9 */
+ .byte 0x2 /* uleb128 0x2 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* uleb128 0x1 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte .LCFIE-.LCFID
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0xe /* uleb128 0xe */
+ .align 2
+.LEFDE3:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffi.c
new file mode 100644
index 000000000..abf3f0d71
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffi.c
@@ -0,0 +1,451 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
+
+ SuperH SHmedia Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 8
+#define NFREGARG 12
+
+static int
+return_type (ffi_type *arg)
+{
+
+ if (arg->type != FFI_TYPE_STRUCT)
+ return arg->type;
+
+ /* gcc uses r2 if the result can be packed in on register. */
+ if (arg->size <= sizeof (UINT8))
+ return FFI_TYPE_UINT8;
+ else if (arg->size <= sizeof (UINT16))
+ return FFI_TYPE_UINT16;
+ else if (arg->size <= sizeof (UINT32))
+ return FFI_TYPE_UINT32;
+ else if (arg->size <= sizeof (UINT64))
+ return FFI_TYPE_UINT64;
+
+ return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register unsigned int avn;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+ {
+ *(void **) argp = ecif->rvalue;
+ argp += sizeof (UINT64);
+ }
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+ {
+ size_t z;
+ int align;
+
+ z = (*p_arg)->size;
+ align = (*p_arg)->alignment;
+ if (z < sizeof (UINT32))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy (argp, *p_argv, z);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ argp += sizeof (UINT64);
+ }
+ else if (z == sizeof (UINT32) && align == sizeof (UINT32))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_INT:
+ case FFI_TYPE_SINT32:
+ *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_STRUCT:
+ *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ argp += sizeof (UINT64);
+ }
+ else if (z == sizeof (UINT64)
+ && align == sizeof (UINT64)
+ && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0)
+ {
+ *(UINT64 *) argp = *(UINT64 *) (*p_argv);
+ argp += sizeof (UINT64);
+ }
+ else
+ {
+ int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);
+
+ memcpy (argp, *p_argv, z);
+ argp += n * sizeof (UINT64);
+ }
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ int i, j;
+ int size, type;
+ int n, m;
+ int greg;
+ int freg;
+
+ greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0);
+ freg = 0;
+ cif->flags2 = 0;
+
+ for (i = j = 0; i < cif->nargs; i++)
+ {
+ type = (cif->arg_types)[i]->type;
+ switch (type)
+ {
+ case FFI_TYPE_FLOAT:
+ greg++;
+ cif->bytes += sizeof (UINT64) - sizeof (float);
+ if (freg >= NFREGARG - 1)
+ continue;
+ freg++;
+ cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ if (greg++ >= NGREGARG && (freg + 1) >= NFREGARG)
+ continue;
+ if ((freg + 1) < NFREGARG)
+ {
+ freg = (freg + 1) & ~1;
+ freg += 2;
+ cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
+ }
+ else
+ cif->flags2 += FFI_TYPE_INT << (2 * j++);
+ break;
+
+ default:
+ size = (cif->arg_types)[i]->size;
+ if (size < sizeof (UINT64))
+ cif->bytes += sizeof (UINT64) - size;
+ n = (size + sizeof (UINT64) - 1) / sizeof (UINT64);
+ if (greg >= NGREGARG)
+ continue;
+ else if (greg + n - 1 >= NGREGARG)
+ greg = NGREGARG;
+ else
+ greg += n;
+ for (m = 0; m < n; m++)
+ cif->flags2 += FFI_TYPE_INT << (2 * j++);
+ break;
+ }
+ }
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_STRUCT:
+ cif->flags = return_type (cif->rtype);
+ break;
+
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = cif->rtype->type;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned, long long,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+ UINT64 trvalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+ && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+ ecif.rvalue = &trvalue;
+ else if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, cif->flags2, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+
+ if (rvalue
+ && cif->rtype->type == FFI_TYPE_STRUCT
+ && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+ memcpy (rvalue, &trvalue, cif->rtype->size);
+}
+
+extern void ffi_closure_SYSV (void);
+extern void __ic_invalidate (void *line);
+
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp;
+
+ FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ /* Since ffi_closure is an aligned object, the ffi trampoline is
+ called as an SHcompact code. Sigh.
+ SHcompact part:
+ mova @(1,pc),r0; add #1,r0; jmp @r0; nop;
+ SHmedia part:
+ movi fnaddr >> 16,r1; shori fnaddr,r1; ptabs/l r1,tr0
+ movi cxt >> 16,r1; shori cxt,r1; blink tr0,r63 */
+#ifdef __LITTLE_ENDIAN__
+ tramp[0] = 0x7001c701;
+ tramp[1] = 0x0009402b;
+#else
+ tramp[0] = 0xc7017001;
+ tramp[1] = 0x402b0009;
+#endif
+ tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10;
+ tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10;
+ tramp[4] = 0x6bf10600;
+ tramp[5] = 0xcc000010 | (((UINT32) closure) >> 16) << 10;
+ tramp[6] = 0xc8000010 | (((UINT32) closure) & 0xffff) << 10;
+ tramp[7] = 0x4401fff0;
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Flush the icache. */
+ asm volatile ("ocbwb %0,0; synco; icbi %0,0; synci" : : "r" (tramp));
+
+ return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the
+ * following helper function to do most of the work.
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue,
+ UINT64 *pgr, UINT64 *pfr, UINT64 *pst)
+{
+ void **avalue;
+ ffi_type **p_arg;
+ int i, avn;
+ int greg, freg;
+ ffi_cif *cif;
+
+ cif = closure->cif;
+ avalue = alloca (cif->nargs * sizeof (void *));
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller. */
+ if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
+ {
+ rvalue = *pgr;
+ greg = 1;
+ }
+ else
+ greg = 0;
+
+ freg = 0;
+ cif = closure->cif;
+ avn = cif->nargs;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+ {
+ size_t z;
+ void *p;
+
+ z = (*p_arg)->size;
+ if (z < sizeof (UINT32))
+ {
+ p = pgr + greg++;
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_STRUCT:
+#ifdef __LITTLE_ENDIAN__
+ avalue[i] = p;
+#else
+ avalue[i] = ((char *) p) + sizeof (UINT32) - z;
+#endif
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof (UINT32))
+ {
+ if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ if (freg < NFREGARG - 1)
+#ifdef __LITTLE_ENDIAN__
+ avalue[i] = (UINT32 *) pfr + (1 ^ freg++);
+#else
+ avalue[i] = (UINT32 *) pfr + freg++;
+#endif
+ else
+#ifdef __LITTLE_ENDIAN__
+ avalue[i] = pgr + greg;
+#else
+ avalue[i] = (UINT32 *) (pgr + greg) + 1;
+#endif
+ }
+ else
+#ifdef __LITTLE_ENDIAN__
+ avalue[i] = pgr + greg;
+#else
+ avalue[i] = (UINT32 *) (pgr + greg) + 1;
+#endif
+ greg++;
+ }
+ else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+ {
+ if (freg + 1 >= NFREGARG)
+ avalue[i] = pgr + greg;
+ else
+ {
+ freg = (freg + 1) & ~1;
+ avalue[i] = pfr + (freg >> 1);
+ freg += 2;
+ }
+ greg++;
+ }
+ else
+ {
+ int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);
+
+ avalue[i] = pgr + greg;
+ greg += n;
+ }
+ }
+
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_SYSV how to perform return type promotions. */
+ return return_type (cif->rtype);
+}
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffitarget.h
new file mode 100644
index 000000000..a174d09b9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffitarget.h
@@ -0,0 +1,52 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for SuperH - SHmedia.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+
+#define FFI_EXTRA_CIF_FIELDS long long flags2
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 32
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/sysv.S
new file mode 100644
index 000000000..19f1b51b9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/sysv.S
@@ -0,0 +1,525 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
+
+ SuperH SHmedia Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_FLT 0
+#else
+#define OFS_FLT 4
+#endif
+
+ .section .text..SHmedia32,"ax"
+
+ # r2: ffi_prep_args
+ # r3: &ecif
+ # r4: bytes
+ # r5: flags
+ # r6: flags2
+ # r7: rvalue
+ # r8: fn
+
+ # This assumes we are using gas.
+ .align 5
+ENTRY(ffi_call_SYSV)
+ # Save registers
+.LFB1:
+ addi.l r15, -48, r15
+.LCFI0:
+ st.q r15, 40, r32
+ st.q r15, 32, r31
+ st.q r15, 24, r30
+ st.q r15, 16, r29
+ st.q r15, 8, r28
+ st.l r15, 4, r18
+ st.l r15, 0, r14
+.LCFI1:
+ add.l r15, r63, r14
+.LCFI2:
+# add r4, r63, r28
+ add r5, r63, r29
+ add r6, r63, r30
+ add r7, r63, r31
+ add r8, r63, r32
+
+ addi r4, (64 + 7), r4
+ andi r4, ~7, r4
+ sub.l r15, r4, r15
+
+ ptabs/l r2, tr0
+ add r15, r63, r2
+ blink tr0, r18
+
+ addi r15, 64, r22
+ movi 0, r0
+ movi 0, r1
+
+ pt/l 1f, tr1
+ bnei/l r29, FFI_TYPE_STRUCT, tr1
+ ld.l r15, 0, r19
+ addi r15, 8, r15
+ addi r0, 1, r0
+1:
+
+.L_pass:
+ andi r30, 3, r20
+ shlri r30, 2, r30
+
+ pt/l .L_call_it, tr0
+ pt/l .L_pass_i, tr1
+ pt/l .L_pass_f, tr2
+
+ beqi/l r20, FFI_TYPE_VOID, tr0
+ beqi/l r20, FFI_TYPE_INT, tr1
+ beqi/l r20, FFI_TYPE_FLOAT, tr2
+
+.L_pass_d:
+ addi r0, 1, r0
+ addi r1, 1, r1
+ andi r1, ~1, r1
+
+ pt/l 3f, tr0
+ movi 12, r20
+ bge/l r1, r20, tr0
+
+ pt/l .L_pop_d, tr1
+ pt/l 2f, tr0
+ blink tr1, r63
+2:
+ addi.l r15, 8, r15
+3:
+ pt/l .L_pass, tr0
+ addi r1, 2, r1
+ blink tr0, r63
+
+.L_pop_d:
+ pt/l .L_pop_d_tbl, tr1
+ gettr tr1, r20
+ shlli r1, 2, r21
+ add r20, r21, r20
+ ptabs/l r20, tr1
+ blink tr1, r63
+
+.L_pop_d_tbl:
+ fld.d r15, 0, dr0
+ blink tr0, r63
+ fld.d r15, 0, dr2
+ blink tr0, r63
+ fld.d r15, 0, dr4
+ blink tr0, r63
+ fld.d r15, 0, dr6
+ blink tr0, r63
+ fld.d r15, 0, dr8
+ blink tr0, r63
+ fld.d r15, 0, dr10
+ blink tr0, r63
+
+.L_pass_f:
+ addi r0, 1, r0
+ pt/l 3f, tr0
+ movi 12, r20
+ bge/l r1, r20, tr0
+
+ pt/l .L_pop_f, tr1
+ pt/l 2f, tr0
+ blink tr1, r63
+2:
+ addi.l r15, 8, r15
+3:
+ pt/l .L_pass, tr0
+ addi r1, 1, r1
+ blink tr0, r63
+
+.L_pop_f:
+ pt/l .L_pop_f_tbl, tr1
+ gettr tr1, r20
+ shlli r1, 3, r21
+ add r20, r21, r20
+ ptabs/l r20, tr1
+ blink tr1, r63
+
+.L_pop_f_tbl:
+ fld.s r15, OFS_FLT, fr0
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr1
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr2
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr3
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr4
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr5
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr6
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr7
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr8
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr9
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr10
+ blink tr0, r63
+ fld.s r15, OFS_FLT, fr11
+ blink tr0, r63
+
+.L_pass_i:
+ pt/l 3f, tr0
+ movi 8, r20
+ bge/l r0, r20, tr0
+
+ pt/l .L_pop_i, tr1
+ pt/l 2f, tr0
+ blink tr1, r63
+2:
+ addi.l r15, 8, r15
+3:
+ pt/l .L_pass, tr0
+ addi r0, 1, r0
+ blink tr0, r63
+
+.L_pop_i:
+ pt/l .L_pop_i_tbl, tr1
+ gettr tr1, r20
+ shlli r0, 3, r21
+ add r20, r21, r20
+ ptabs/l r20, tr1
+ blink tr1, r63
+
+.L_pop_i_tbl:
+ ld.q r15, 0, r2
+ blink tr0, r63
+ ld.q r15, 0, r3
+ blink tr0, r63
+ ld.q r15, 0, r4
+ blink tr0, r63
+ ld.q r15, 0, r5
+ blink tr0, r63
+ ld.q r15, 0, r6
+ blink tr0, r63
+ ld.q r15, 0, r7
+ blink tr0, r63
+ ld.q r15, 0, r8
+ blink tr0, r63
+ ld.q r15, 0, r9
+ blink tr0, r63
+
+.L_call_it:
+ # call function
+ pt/l 1f, tr1
+ bnei/l r29, FFI_TYPE_STRUCT, tr1
+ add r19, r63, r2
+1:
+ add r22, r63, r15
+ ptabs/l r32, tr0
+ blink tr0, r18
+
+ pt/l .L_ret_i, tr0
+ pt/l .L_ret_ll, tr1
+ pt/l .L_ret_d, tr2
+ pt/l .L_ret_f, tr3
+ pt/l .L_epilogue, tr4
+
+ beqi/l r29, FFI_TYPE_INT, tr0
+ beqi/l r29, FFI_TYPE_UINT32, tr0
+ beqi/l r29, FFI_TYPE_SINT64, tr1
+ beqi/l r29, FFI_TYPE_UINT64, tr1
+ beqi/l r29, FFI_TYPE_DOUBLE, tr2
+ beqi/l r29, FFI_TYPE_FLOAT, tr3
+
+ pt/l .L_ret_q, tr0
+ pt/l .L_ret_h, tr1
+
+ beqi/l r29, FFI_TYPE_UINT8, tr0
+ beqi/l r29, FFI_TYPE_UINT16, tr1
+ blink tr4, r63
+
+.L_ret_d:
+ fst.d r31, 0, dr0
+ blink tr4, r63
+
+.L_ret_ll:
+ st.q r31, 0, r2
+ blink tr4, r63
+
+.L_ret_f:
+ fst.s r31, OFS_FLT, fr0
+ blink tr4, r63
+
+.L_ret_q:
+ st.b r31, 0, r2
+ blink tr4, r63
+
+.L_ret_h:
+ st.w r31, 0, r2
+ blink tr4, r63
+
+.L_ret_i:
+ st.l r31, 0, r2
+ # Fall
+
+.L_epilogue:
+ # Remove the space we pushed for the args
+ add r14, r63, r15
+
+ ld.l r15, 0, r14
+ ld.l r15, 4, r18
+ ld.q r15, 8, r28
+ ld.q r15, 16, r29
+ ld.q r15, 24, r30
+ ld.q r15, 32, r31
+ ld.q r15, 40, r32
+ addi.l r15, 48, r15
+ ptabs r18, tr0
+ blink tr0, r63
+
+.LFE1:
+.ffi_call_SYSV_end:
+ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+ .align 5
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+ addi.l r15, -136, r15
+.LCFI3:
+ st.l r15, 12, r18
+ st.l r15, 8, r14
+ st.l r15, 4, r12
+.LCFI4:
+ add r15, r63, r14
+.LCFI5:
+ /* Stack layout:
+ ...
+ 64 bytes (register parameters)
+ 48 bytes (floating register parameters)
+ 8 bytes (result)
+ 4 bytes (r18)
+ 4 bytes (r14)
+ 4 bytes (r12)
+ 4 bytes (for align)
+ <- new stack pointer
+ */
+ fst.d r14, 24, dr0
+ fst.d r14, 32, dr2
+ fst.d r14, 40, dr4
+ fst.d r14, 48, dr6
+ fst.d r14, 56, dr8
+ fst.d r14, 64, dr10
+ st.q r14, 72, r2
+ st.q r14, 80, r3
+ st.q r14, 88, r4
+ st.q r14, 96, r5
+ st.q r14, 104, r6
+ st.q r14, 112, r7
+ st.q r14, 120, r8
+ st.q r14, 128, r9
+
+ add r1, r63, r2
+ addi r14, 16, r3
+ addi r14, 72, r4
+ addi r14, 24, r5
+ addi r14, 136, r6
+#ifdef PIC
+ movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12
+ shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12
+.LPCS0: ptrel/u r12, tr0
+ movi ((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1
+ gettr tr0, r12
+ ldx.l r1, r12, r1
+ ptabs r1, tr0
+#else
+ pt/l ffi_closure_helper_SYSV, tr0
+#endif
+ blink tr0, r18
+
+ shlli r2, 1, r1
+ movi (((datalabel .L_table) >> 16) & 65535), r2
+ shori ((datalabel .L_table) & 65535), r2
+ ldx.w r2, r1, r1
+ add r1, r2, r1
+ pt/l .L_case_v, tr1
+ ptabs r1, tr0
+ blink tr0, r63
+
+ .align 2
+.L_table:
+ .word .L_case_v - datalabel .L_table /* FFI_TYPE_VOID */
+ .word .L_case_i - datalabel .L_table /* FFI_TYPE_INT */
+ .word .L_case_f - datalabel .L_table /* FFI_TYPE_FLOAT */
+ .word .L_case_d - datalabel .L_table /* FFI_TYPE_DOUBLE */
+ .word .L_case_d - datalabel .L_table /* FFI_TYPE_LONGDOUBLE */
+ .word .L_case_uq - datalabel .L_table /* FFI_TYPE_UINT8 */
+ .word .L_case_q - datalabel .L_table /* FFI_TYPE_SINT8 */
+ .word .L_case_uh - datalabel .L_table /* FFI_TYPE_UINT16 */
+ .word .L_case_h - datalabel .L_table /* FFI_TYPE_SINT16 */
+ .word .L_case_i - datalabel .L_table /* FFI_TYPE_UINT32 */
+ .word .L_case_i - datalabel .L_table /* FFI_TYPE_SINT32 */
+ .word .L_case_ll - datalabel .L_table /* FFI_TYPE_UINT64 */
+ .word .L_case_ll - datalabel .L_table /* FFI_TYPE_SINT64 */
+ .word .L_case_v - datalabel .L_table /* FFI_TYPE_STRUCT */
+ .word .L_case_i - datalabel .L_table /* FFI_TYPE_POINTER */
+
+ .align 2
+.L_case_d:
+ fld.d r14, 16, dr0
+ blink tr1, r63
+.L_case_f:
+ fld.s r14, 16, fr0
+ blink tr1, r63
+.L_case_ll:
+ ld.q r14, 16, r2
+ blink tr1, r63
+.L_case_i:
+ ld.l r14, 16, r2
+ blink tr1, r63
+.L_case_q:
+ ld.b r14, 16, r2
+ blink tr1, r63
+.L_case_uq:
+ ld.ub r14, 16, r2
+ blink tr1, r63
+.L_case_h:
+ ld.w r14, 16, r2
+ blink tr1, r63
+.L_case_uh:
+ ld.uw r14, 16, r2
+ blink tr1, r63
+.L_case_v:
+ add.l r14, r63, r15
+ ld.l r15, 4, r12
+ ld.l r15, 8, r14
+ ld.l r15, 12, r18
+ addi.l r15, 136, r15
+ ptabs r18, tr0
+ blink tr0, r63
+
+.LFE2:
+.ffi_closure_SYSV_end:
+ .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+ .section ".eh_frame","aw",@progbits
+__FRAME_BEGIN__:
+ .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .4byte 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef PIC
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .byte 0x0 /* CIE Augmentation */
+#endif
+ .uleb128 0x1 /* CIE Code Alignment Factor */
+ .sleb128 -4 /* CIE Data Alignment Factor */
+ .byte 0x12 /* CIE RA Column */
+#ifdef PIC
+ .uleb128 0x1 /* Augmentation size */
+ .byte 0x10 /* FDE Encoding (pcrel) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .uleb128 0xf
+ .uleb128 0x0
+ .align 2
+.LECIE1:
+.LSFDE1:
+ .4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */
+.LASFDE1:
+ .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__
+#ifdef PIC
+ .4byte .LFB1-. /* FDE initial location */
+#else
+ .4byte .LFB1 /* FDE initial location */
+#endif
+ .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */
+#ifdef PIC
+ .uleb128 0x0 /* Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte datalabel .LCFI0-datalabel .LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .uleb128 0x30
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte datalabel .LCFI1-datalabel .LCFI0
+ .byte 0x8e /* DW_CFA_offset, column 0xe */
+ .uleb128 0xc
+ .byte 0x92 /* DW_CFA_offset, column 0x12 */
+ .uleb128 0xb
+ .byte 0x9c /* DW_CFA_offset, column 0x1c */
+ .uleb128 0xa
+ .byte 0x9d /* DW_CFA_offset, column 0x1d */
+ .uleb128 0x8
+ .byte 0x9e /* DW_CFA_offset, column 0x1e */
+ .uleb128 0x6
+ .byte 0x9f /* DW_CFA_offset, column 0x1f */
+ .uleb128 0x4
+ .byte 0xa0 /* DW_CFA_offset, column 0x20 */
+ .uleb128 0x2
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte datalabel .LCFI2-datalabel .LCFI1
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .uleb128 0xe
+ .align 2
+.LEFDE1:
+
+.LSFDE3:
+ .4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */
+.LASFDE3:
+ .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__
+#ifdef PIC
+ .4byte .LFB2-. /* FDE initial location */
+#else
+ .4byte .LFB2 /* FDE initial location */
+#endif
+ .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */
+#ifdef PIC
+ .uleb128 0x0 /* Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte datalabel .LCFI3-datalabel .LFB2
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .uleb128 0x88
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte datalabel .LCFI4-datalabel .LCFI3
+ .byte 0x8c /* DW_CFA_offset, column 0xc */
+ .uleb128 0x21
+ .byte 0x8e /* DW_CFA_offset, column 0xe */
+ .uleb128 0x20
+ .byte 0x92 /* DW_CFA_offset, column 0x12 */
+ .uleb128 0x1f
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .4byte datalabel .LCFI5-datalabel .LCFI4
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .uleb128 0xe
+ .align 2
+.LEFDE3:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffi.c
new file mode 100644
index 000000000..b83d63ded
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffi.c
@@ -0,0 +1,608 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 2003, 2004 Red Hat, Inc.
+
+ SPARC Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+void ffi_prep_args_v8(char *stack, extended_cif *ecif)
+{
+ int i;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ /* Skip 16 words for the window save area */
+ argp = stack + 16*sizeof(int);
+
+ /* This should only really be done when we are returning a structure,
+ however, it's faster just to do it all the time...
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+ *(int *) argp = (long)ecif->rvalue;
+
+ /* And 1 word for the structure return value. */
+ argp += sizeof(int);
+
+#ifdef USING_PURIFY
+ /* Purify will probably complain in our assembly routine, unless we
+ zero out this memory. */
+
+ ((int*)argp)[0] = 0;
+ ((int*)argp)[1] = 0;
+ ((int*)argp)[2] = 0;
+ ((int*)argp)[3] = 0;
+ ((int*)argp)[4] = 0;
+ ((int*)argp)[5] = 0;
+#endif
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+ {
+ size_t z;
+
+ if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ {
+ *(unsigned int *) argp = (unsigned long)(* p_argv);
+ z = sizeof(int);
+ }
+ else
+ {
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+{
+ int i, ret = 0;
+ int tmp;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ tmp = 0;
+
+ /* Skip 16 words for the window save area */
+ argp = stack + 16*sizeof(long long);
+
+#ifdef USING_PURIFY
+ /* Purify will probably complain in our assembly routine, unless we
+ zero out this memory. */
+
+ ((long long*)argp)[0] = 0;
+ ((long long*)argp)[1] = 0;
+ ((long long*)argp)[2] = 0;
+ ((long long*)argp)[3] = 0;
+ ((long long*)argp)[4] = 0;
+ ((long long*)argp)[5] = 0;
+#endif
+
+ p_argv = ecif->avalue;
+
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
+ ecif->cif->rtype->size > 32)
+ {
+ *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
+ argp += sizeof(long long);
+ tmp = 1;
+ }
+
+ for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+ i++, p_arg++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_STRUCT:
+ if (z > 16)
+ {
+ /* For structures larger than 16 bytes we pass reference. */
+ *(unsigned long long *) argp = (unsigned long)* p_argv;
+ argp += sizeof(long long);
+ tmp++;
+ p_argv++;
+ continue;
+ }
+ /* FALLTHROUGH */
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ ret = 1; /* We should promote into FP regs as well as integer. */
+ break;
+ }
+ if (z < sizeof(long long))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed long long *) argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed long long *) argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed long long *) argp = *(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy(argp, *p_argv, z);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ z = sizeof(long long);
+ tmp++;
+ }
+ else if (z == sizeof(long long))
+ {
+ memcpy(argp, *p_argv, z);
+ z = sizeof(long long);
+ tmp++;
+ }
+ else
+ {
+ if ((tmp & 1) && (*p_arg)->alignment > 8)
+ {
+ tmp++;
+ argp += sizeof(long long);
+ }
+ memcpy(argp, *p_argv, z);
+ z = 2 * sizeof(long long);
+ tmp += 2;
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return ret;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ int wordsize;
+
+ if (cif->abi != FFI_V9)
+ {
+ wordsize = 4;
+
+ /* If we are returning a struct, this will already have been added.
+ Otherwise we need to add it because it's always got to be there! */
+
+ if (cif->rtype->type != FFI_TYPE_STRUCT)
+ cif->bytes += wordsize;
+
+ /* sparc call frames require that space is allocated for 6 args,
+ even if they aren't used. Make that space if necessary. */
+
+ if (cif->bytes < 4*6+4)
+ cif->bytes = 4*6+4;
+ }
+ else
+ {
+ wordsize = 8;
+
+ /* sparc call frames require that space is allocated for 6 args,
+ even if they aren't used. Make that space if necessary. */
+
+ if (cif->bytes < 8*6)
+ cif->bytes = 8*6;
+ }
+
+ /* Adjust cif->bytes. to include 16 words for the window save area,
+ and maybe the struct/union return pointer area, */
+
+ cif->bytes += 16 * wordsize;
+
+ /* The stack must be 2 word aligned, so round bytes up
+ appropriately. */
+
+ cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ cif->flags = cif->rtype->type;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+ cif->flags = FFI_TYPE_VOID;
+ else
+ cif->flags = FFI_TYPE_STRUCT;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ if (cif->abi != FFI_V9)
+ {
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+ return FFI_OK;
+}
+
+int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+{
+ ffi_type **ptr = &arg->elements[0];
+
+ while (*ptr != NULL)
+ {
+ if (off & ((*ptr)->alignment - 1))
+ off = ALIGN(off, (*ptr)->alignment);
+
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_STRUCT:
+ off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
+ off = ALIGN(off, FFI_SIZEOF_ARG);
+ break;
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ memmove(ret + off, flt + off, (*ptr)->size);
+ off += (*ptr)->size;
+ break;
+ default:
+ memmove(ret + off, intg + off, (*ptr)->size);
+ off += (*ptr)->size;
+ break;
+ }
+ ptr++;
+ }
+ return off;
+}
+
+
+#ifdef SPARC64
+extern int ffi_call_v9(void *, extended_cif *, unsigned,
+ unsigned, unsigned *, void (*fn)());
+#else
+extern int ffi_call_v8(void *, extended_cif *, unsigned,
+ unsigned, unsigned *, void (*fn)());
+#endif
+
+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+ void *rval = rvalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ ecif.rvalue = rvalue;
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ if (cif->rtype->size <= 32)
+ rval = alloca(64);
+ else
+ {
+ rval = NULL;
+ if (rvalue == NULL)
+ ecif.rvalue = alloca(cif->rtype->size);
+ }
+ }
+
+ switch (cif->abi)
+ {
+ case FFI_V8:
+#ifdef SPARC64
+ /* We don't yet support calling 32bit code from 64bit */
+ FFI_ASSERT(0);
+#else
+ ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+ cif->flags, rvalue, fn);
+#endif
+ break;
+ case FFI_V9:
+#ifdef SPARC64
+ ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
+ cif->flags, rval, fn);
+ if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
+ ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+#else
+ /* And vice versa */
+ FFI_ASSERT(0);
+#endif
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+
+}
+
+
+#ifdef SPARC64
+extern void ffi_closure_v9(void);
+#else
+extern void ffi_closure_v8(void);
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+ unsigned long fn;
+#ifdef SPARC64
+ /* Trampoline address is equal to the closure address. We take advantage
+ of that to reduce the trampoline size by 8 bytes. */
+ FFI_ASSERT (cif->abi == FFI_V9);
+ fn = (unsigned long) ffi_closure_v9;
+ tramp[0] = 0x83414000; /* rd %pc, %g1 */
+ tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */
+ tramp[2] = 0x81c14000; /* jmp %g5 */
+ tramp[3] = 0x01000000; /* nop */
+ *((unsigned long *) &tramp[4]) = fn;
+#else
+ unsigned long ctx = (unsigned long) closure;
+ FFI_ASSERT (cif->abi == FFI_V8);
+ fn = (unsigned long) ffi_closure_v8;
+ tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */
+ tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */
+ tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp %g1+%lo(fn) */
+ tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or %g2, %lo(ctx) */
+#endif
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Flush the Icache. FIXME: alignment isn't certain, assume 8 bytes */
+#ifdef SPARC64
+ asm volatile ("flush %0" : : "r" (closure) : "memory");
+ asm volatile ("flush %0" : : "r" (((char *) closure) + 8) : "memory");
+#else
+ asm volatile ("iflush %0" : : "r" (closure) : "memory");
+ asm volatile ("iflush %0" : : "r" (((char *) closure) + 8) : "memory");
+#endif
+
+ return FFI_OK;
+}
+
+int
+ffi_closure_sparc_inner_v8(ffi_closure *closure,
+ void *rvalue, unsigned long *gpr, unsigned long *scratch)
+{
+ ffi_cif *cif;
+ ffi_type **arg_types;
+ void **avalue;
+ int i, argn;
+
+ cif = closure->cif;
+ arg_types = cif->arg_types;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ /* Copy the caller's structure return address so that the closure
+ returns the data directly to the caller. */
+ if (cif->flags == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ rvalue = (void *) gpr[0];
+
+ /* Always skip the structure return address. */
+ argn = 1;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ for (i = 0; i < cif->nargs; i++)
+ {
+ if (arg_types[i]->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ {
+ /* Straight copy of invisible reference. */
+ avalue[i] = (void *)gpr[argn++];
+ }
+ else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_SINT64
+ || arg_types[i]->type == FFI_TYPE_UINT64)
+ /* gpr is 8-byte aligned. */
+ && (argn % 2) != 0)
+ {
+ /* Align on a 8-byte boundary. */
+ scratch[0] = gpr[argn];
+ scratch[1] = gpr[argn+1];
+ avalue[i] = scratch;
+ scratch -= 2;
+ argn += 2;
+ }
+ else
+ {
+ /* Always right-justify. */
+ argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+ }
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_sparc how to perform return type promotions. */
+ return cif->rtype->type;
+}
+
+int
+ffi_closure_sparc_inner_v9(ffi_closure *closure,
+ void *rvalue, unsigned long *gpr, double *fpr)
+{
+ ffi_cif *cif;
+ ffi_type **arg_types;
+ void **avalue;
+ int i, argn, fp_slot_max;
+
+ cif = closure->cif;
+ arg_types = cif->arg_types;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ /* Copy the caller's structure return address so that the closure
+ returns the data directly to the caller. */
+ if (cif->flags == FFI_TYPE_VOID
+ && cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ rvalue = (void *) gpr[0];
+ /* Skip the structure return address. */
+ argn = 1;
+ }
+ else
+ argn = 0;
+
+ fp_slot_max = 16 - argn;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ for (i = 0; i < cif->nargs; i++)
+ {
+ if (arg_types[i]->type == FFI_TYPE_STRUCT)
+ {
+ if (arg_types[i]->size > 16)
+ {
+ /* Straight copy of invisible reference. */
+ avalue[i] = (void *)gpr[argn++];
+ }
+ else
+ {
+ /* Left-justify. */
+ ffi_v9_layout_struct(arg_types[i],
+ 0,
+ (char *) &gpr[argn],
+ (char *) &gpr[argn],
+ (char *) &fpr[argn]);
+ avalue[i] = &gpr[argn];
+ argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ }
+ }
+ else
+ {
+ /* Right-justify. */
+ argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+
+ if (i < fp_slot_max
+ && (arg_types[i]->type == FFI_TYPE_FLOAT
+ || arg_types[i]->type == FFI_TYPE_DOUBLE
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+ ))
+ avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
+ else
+ avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+ }
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_sparc how to perform return type promotions. */
+ return cif->rtype->type;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffitarget.h
new file mode 100644
index 000000000..f4514e55d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffitarget.h
@@ -0,0 +1,65 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for SPARC.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined(__arch64__) || defined(__sparcv9)
+#define SPARC64
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_V8,
+ FFI_V8PLUS,
+ FFI_V9,
+#ifdef SPARC64
+ FFI_DEFAULT_ABI = FFI_V9,
+#else
+ FFI_DEFAULT_ABI = FFI_V8,
+#endif
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef SPARC64
+#define FFI_TRAMPOLINE_SIZE 24
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v8.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v8.S
new file mode 100644
index 000000000..709423ce9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v8.S
@@ -0,0 +1,267 @@
+/* -----------------------------------------------------------------------
+ v8.S - Copyright (c) 1996, 1997, 2003, 2004 Red Hat, Inc.
+
+ SPARC Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#define STACKFRAME 96 /* Minimum stack framesize for SPARC */
+#define ARGS (64+4) /* Offset of register area in frame */
+
+.text
+ .align 8
+.globl ffi_call_v8
+.globl _ffi_call_v8
+
+ffi_call_v8:
+_ffi_call_v8:
+.LLFB1:
+ save %sp, -STACKFRAME, %sp
+.LLCFI0:
+
+ sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
+ add %sp, STACKFRAME, %l0 ! %l0 has start of
+ ! frame to set up
+
+ mov %l0, %o0 ! call routine to set up frame
+ call %i0
+ mov %i1, %o1 ! (delay)
+
+ ld [%l0+ARGS], %o0 ! call foreign function
+ ld [%l0+ARGS+4], %o1
+ ld [%l0+ARGS+8], %o2
+ ld [%l0+ARGS+12], %o3
+ ld [%l0+ARGS+16], %o4
+ ld [%l0+ARGS+20], %o5
+ call %i5
+ mov %l0, %sp ! (delay) switch to frame
+ nop ! STRUCT returning functions skip 12 instead of 8 bytes
+
+ ! If the return value pointer is NULL, assume no return value.
+ tst %i4
+ bz done
+ nop
+
+ cmp %i3, FFI_TYPE_INT
+ be,a done
+ st %o0, [%i4] ! (delay)
+
+ cmp %i3, FFI_TYPE_FLOAT
+ be,a done
+ st %f0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_SINT64
+ be longlong
+
+ cmp %i3, FFI_TYPE_DOUBLE
+ bne done
+ nop
+ st %f0, [%i4+0]
+ st %f1, [%i4+4]
+
+done:
+ ret
+ restore
+
+longlong:
+ st %o0, [%i4+0]
+ st %o1, [%i4+4]
+ ret
+ restore
+.LLFE1:
+
+.ffi_call_v8_end:
+ .size ffi_call_v8,.ffi_call_v8_end-ffi_call_v8
+
+
+#undef STACKFRAME
+#define STACKFRAME 104 /* 16*4 register window +
+ 1*4 struct return +
+ 6*4 args backing store +
+ 3*4 locals */
+
+/* ffi_closure_v8(...)
+
+ Receives the closure argument in %g2. */
+
+ .text
+ .align 8
+ .globl ffi_closure_v8
+
+ffi_closure_v8:
+#ifdef HAVE_AS_REGISTER_PSEUDO_OP
+ .register %g2, #scratch
+#endif
+.LLFB2:
+ ! Reserve frame space for all arguments in case
+ ! we need to align them on a 8-byte boundary.
+ ld [%g2+FFI_TRAMPOLINE_SIZE], %g1
+ ld [%g1+4], %g1
+ sll %g1, 3, %g1
+ add %g1, STACKFRAME, %g1
+ ! %g1 == STACKFRAME + 8*nargs
+ neg %g1
+ save %sp, %g1, %sp
+.LLCFI1:
+
+ ! Store all of the potential argument registers in va_list format.
+ st %i0, [%fp+68+0]
+ st %i1, [%fp+68+4]
+ st %i2, [%fp+68+8]
+ st %i3, [%fp+68+12]
+ st %i4, [%fp+68+16]
+ st %i5, [%fp+68+20]
+
+ ! Call ffi_closure_sparc_inner to do the bulk of the work.
+ mov %g2, %o0
+ add %fp, -8, %o1
+ add %fp, 64, %o2
+ call ffi_closure_sparc_inner_v8
+ add %fp, -16, %o3
+
+ ! Load up the return value in the proper type.
+ ! See ffi_prep_cif_machdep for the list of cases.
+ cmp %o0, FFI_TYPE_VOID
+ be done1
+
+ cmp %o0, FFI_TYPE_INT
+ be integer
+
+ cmp %o0, FFI_TYPE_FLOAT
+ be,a done1
+ ld [%fp-8], %f0
+
+ cmp %o0, FFI_TYPE_DOUBLE
+ be,a done1
+ ldd [%fp-8], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ cmp %o0, FFI_TYPE_LONGDOUBLE
+ be done2
+#endif
+
+ cmp %o0, FFI_TYPE_STRUCT
+ be done2
+
+ ! FFI_TYPE_SINT64
+ ! FFI_TYPE_UINT64
+ ld [%fp-4], %i1
+
+integer:
+ ld [%fp-8], %i0
+
+done1:
+ jmp %i7+8
+ restore
+done2:
+ ! Skip 'unimp'.
+ jmp %i7+12
+ restore
+.LLFE2:
+
+.ffi_closure_v8_end:
+ .size ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
+
+#ifdef SPARC64
+#define WS 8
+#define nword xword
+#define uanword uaxword
+#else
+#define WS 4
+#define nword long
+#define uanword uaword
+#endif
+
+#ifdef HAVE_RO_EH_FRAME
+ .section ".eh_frame",#alloc
+#else
+ .section ".eh_frame",#alloc,#write
+#endif
+.LLframe1:
+ .uaword .LLECIE1-.LLSCIE1 ! Length of Common Information Entry
+.LLSCIE1:
+ .uaword 0x0 ! CIE Identifier Tag
+ .byte 0x1 ! CIE Version
+ .ascii "zR\0" ! CIE Augmentation
+ .byte 0x1 ! uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x80-WS ! sleb128 -WS; CIE Data Alignment Factor
+ .byte 0xf ! CIE RA Column
+ .byte 0x1 ! uleb128 0x1; Augmentation size
+#ifdef HAVE_AS_SPARC_UA_PCREL
+ .byte 0x1b ! FDE Encoding (pcrel sdata4)
+#else
+ .byte 0x50 ! FDE Encoding (aligned absolute)
+#endif
+ .byte 0xc ! DW_CFA_def_cfa
+ .byte 0xe ! uleb128 0xe
+ .byte 0x0 ! uleb128 0x0
+ .align WS
+.LLECIE1:
+.LLSFDE1:
+ .uaword .LLEFDE1-.LLASFDE1 ! FDE Length
+.LLASFDE1:
+ .uaword .LLASFDE1-.LLframe1 ! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+ .uaword %r_disp32(.LLFB1)
+ .uaword .LLFE1-.LLFB1 ! FDE address range
+#else
+ .align WS
+ .nword .LLFB1
+ .uanword .LLFE1-.LLFB1 ! FDE address range
+#endif
+ .byte 0x0 ! uleb128 0x0; Augmentation size
+ .byte 0x4 ! DW_CFA_advance_loc4
+ .uaword .LLCFI0-.LLFB1
+ .byte 0xd ! DW_CFA_def_cfa_register
+ .byte 0x1e ! uleb128 0x1e
+ .byte 0x2d ! DW_CFA_GNU_window_save
+ .byte 0x9 ! DW_CFA_register
+ .byte 0xf ! uleb128 0xf
+ .byte 0x1f ! uleb128 0x1f
+ .align WS
+.LLEFDE1:
+.LLSFDE2:
+ .uaword .LLEFDE2-.LLASFDE2 ! FDE Length
+.LLASFDE2:
+ .uaword .LLASFDE2-.LLframe1 ! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+ .uaword %r_disp32(.LLFB2)
+ .uaword .LLFE2-.LLFB2 ! FDE address range
+#else
+ .align WS
+ .nword .LLFB2
+ .uanword .LLFE2-.LLFB2 ! FDE address range
+#endif
+ .byte 0x0 ! uleb128 0x0; Augmentation size
+ .byte 0x4 ! DW_CFA_advance_loc4
+ .uaword .LLCFI1-.LLFB2
+ .byte 0xd ! DW_CFA_def_cfa_register
+ .byte 0x1e ! uleb128 0x1e
+ .byte 0x2d ! DW_CFA_GNU_window_save
+ .byte 0x9 ! DW_CFA_register
+ .byte 0xf ! uleb128 0xf
+ .byte 0x1f ! uleb128 0x1f
+ .align WS
+.LLEFDE2:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v9.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v9.S
new file mode 100644
index 000000000..d640e0232
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v9.S
@@ -0,0 +1,302 @@
+/* -----------------------------------------------------------------------
+ v9.S - Copyright (c) 2000, 2003, 2004 Red Hat, Inc.
+
+ SPARC 64-bit Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef SPARC64
+/* Only compile this in for 64bit builds, because otherwise the object file
+ will have inproper architecture due to used instructions. */
+
+#define STACKFRAME 128 /* Minimum stack framesize for SPARC */
+#define STACK_BIAS 2047
+#define ARGS (128) /* Offset of register area in frame */
+
+.text
+ .align 8
+.globl ffi_call_v9
+.globl _ffi_call_v9
+
+ffi_call_v9:
+_ffi_call_v9:
+.LLFB1:
+ save %sp, -STACKFRAME, %sp
+.LLCFI0:
+
+ sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
+ add %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of
+ ! frame to set up
+
+ mov %l0, %o0 ! call routine to set up frame
+ call %i0
+ mov %i1, %o1 ! (delay)
+ brz,pt %o0, 1f
+ ldx [%l0+ARGS], %o0 ! call foreign function
+
+ ldd [%l0+ARGS], %f0
+ ldd [%l0+ARGS+8], %f2
+ ldd [%l0+ARGS+16], %f4
+ ldd [%l0+ARGS+24], %f6
+ ldd [%l0+ARGS+32], %f8
+ ldd [%l0+ARGS+40], %f10
+ ldd [%l0+ARGS+48], %f12
+ ldd [%l0+ARGS+56], %f14
+ ldd [%l0+ARGS+64], %f16
+ ldd [%l0+ARGS+72], %f18
+ ldd [%l0+ARGS+80], %f20
+ ldd [%l0+ARGS+88], %f22
+ ldd [%l0+ARGS+96], %f24
+ ldd [%l0+ARGS+104], %f26
+ ldd [%l0+ARGS+112], %f28
+ ldd [%l0+ARGS+120], %f30
+
+1: ldx [%l0+ARGS+8], %o1
+ ldx [%l0+ARGS+16], %o2
+ ldx [%l0+ARGS+24], %o3
+ ldx [%l0+ARGS+32], %o4
+ ldx [%l0+ARGS+40], %o5
+ call %i5
+ sub %l0, STACK_BIAS, %sp ! (delay) switch to frame
+
+ ! If the return value pointer is NULL, assume no return value.
+ brz,pn %i4, done
+ nop
+
+ cmp %i3, FFI_TYPE_INT
+ be,a,pt %icc, done
+ stx %o0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_FLOAT
+ be,a,pn %icc, done
+ st %f0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_DOUBLE
+ be,a,pn %icc, done
+ std %f0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_STRUCT
+ be,pn %icc, dostruct
+
+ cmp %i3, FFI_TYPE_LONGDOUBLE
+ bne,pt %icc, done
+ nop
+ std %f0, [%i4+0]
+ std %f2, [%i4+8]
+
+done: ret
+ restore
+
+dostruct:
+ /* This will not work correctly for unions. */
+ stx %o0, [%i4+0]
+ stx %o1, [%i4+8]
+ stx %o2, [%i4+16]
+ stx %o3, [%i4+24]
+ std %f0, [%i4+32]
+ std %f2, [%i4+40]
+ std %f4, [%i4+48]
+ std %f6, [%i4+56]
+ ret
+ restore
+.LLFE1:
+
+.ffi_call_v9_end:
+ .size ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
+
+
+#undef STACKFRAME
+#define STACKFRAME 336 /* 16*8 register window +
+ 6*8 args backing store +
+ 20*8 locals */
+#define FP %fp+STACK_BIAS
+
+/* ffi_closure_v9(...)
+
+ Receives the closure argument in %g1. */
+
+ .text
+ .align 8
+ .globl ffi_closure_v9
+
+ffi_closure_v9:
+.LLFB2:
+ save %sp, -STACKFRAME, %sp
+.LLCFI1:
+
+ ! Store all of the potential argument registers in va_list format.
+ stx %i0, [FP+128+0]
+ stx %i1, [FP+128+8]
+ stx %i2, [FP+128+16]
+ stx %i3, [FP+128+24]
+ stx %i4, [FP+128+32]
+ stx %i5, [FP+128+40]
+
+ ! Store possible floating point argument registers too.
+ std %f0, [FP-128]
+ std %f2, [FP-120]
+ std %f4, [FP-112]
+ std %f6, [FP-104]
+ std %f8, [FP-96]
+ std %f10, [FP-88]
+ std %f12, [FP-80]
+ std %f14, [FP-72]
+ std %f16, [FP-64]
+ std %f18, [FP-56]
+ std %f20, [FP-48]
+ std %f22, [FP-40]
+ std %f24, [FP-32]
+ std %f26, [FP-24]
+ std %f28, [FP-16]
+ std %f30, [FP-8]
+
+ ! Call ffi_closure_sparc_inner to do the bulk of the work.
+ mov %g1, %o0
+ add %fp, STACK_BIAS-160, %o1
+ add %fp, STACK_BIAS+128, %o2
+ call ffi_closure_sparc_inner_v9
+ add %fp, STACK_BIAS-128, %o3
+
+ ! Load up the return value in the proper type.
+ ! See ffi_prep_cif_machdep for the list of cases.
+ cmp %o0, FFI_TYPE_VOID
+ be,pn %icc, done1
+
+ cmp %o0, FFI_TYPE_INT
+ be,pn %icc, integer
+
+ cmp %o0, FFI_TYPE_FLOAT
+ be,a,pn %icc, done1
+ ld [FP-160], %f0
+
+ cmp %o0, FFI_TYPE_DOUBLE
+ be,a,pn %icc, done1
+ ldd [FP-160], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ cmp %o0, FFI_TYPE_LONGDOUBLE
+ be,a,pn %icc, longdouble1
+ ldd [FP-160], %f0
+#endif
+
+ ! FFI_TYPE_STRUCT
+ ldx [FP-152], %i1
+ ldx [FP-144], %i2
+ ldx [FP-136], %i3
+ ldd [FP-160], %f0
+ ldd [FP-152], %f2
+ ldd [FP-144], %f4
+ ldd [FP-136], %f6
+
+integer:
+ ldx [FP-160], %i0
+
+done1:
+ ret
+ restore
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+longdouble1:
+ ldd [FP-152], %f2
+ ret
+ restore
+#endif
+.LLFE2:
+
+.ffi_closure_v9_end:
+ .size ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
+
+#ifdef HAVE_RO_EH_FRAME
+ .section ".eh_frame",#alloc
+#else
+ .section ".eh_frame",#alloc,#write
+#endif
+.LLframe1:
+ .uaword .LLECIE1-.LLSCIE1 ! Length of Common Information Entry
+.LLSCIE1:
+ .uaword 0x0 ! CIE Identifier Tag
+ .byte 0x1 ! CIE Version
+ .ascii "zR\0" ! CIE Augmentation
+ .byte 0x1 ! uleb128 0x1; CIE Code Alignment Factor
+ .byte 0x78 ! sleb128 -8; CIE Data Alignment Factor
+ .byte 0xf ! CIE RA Column
+ .byte 0x1 ! uleb128 0x1; Augmentation size
+#ifdef HAVE_AS_SPARC_UA_PCREL
+ .byte 0x1b ! FDE Encoding (pcrel sdata4)
+#else
+ .byte 0x50 ! FDE Encoding (aligned absolute)
+#endif
+ .byte 0xc ! DW_CFA_def_cfa
+ .byte 0xe ! uleb128 0xe
+ .byte 0xff,0xf ! uleb128 0x7ff
+ .align 8
+.LLECIE1:
+.LLSFDE1:
+ .uaword .LLEFDE1-.LLASFDE1 ! FDE Length
+.LLASFDE1:
+ .uaword .LLASFDE1-.LLframe1 ! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+ .uaword %r_disp32(.LLFB1)
+ .uaword .LLFE1-.LLFB1 ! FDE address range
+#else
+ .align 8
+ .xword .LLFB1
+ .uaxword .LLFE1-.LLFB1 ! FDE address range
+#endif
+ .byte 0x0 ! uleb128 0x0; Augmentation size
+ .byte 0x4 ! DW_CFA_advance_loc4
+ .uaword .LLCFI0-.LLFB1
+ .byte 0xd ! DW_CFA_def_cfa_register
+ .byte 0x1e ! uleb128 0x1e
+ .byte 0x2d ! DW_CFA_GNU_window_save
+ .byte 0x9 ! DW_CFA_register
+ .byte 0xf ! uleb128 0xf
+ .byte 0x1f ! uleb128 0x1f
+ .align 8
+.LLEFDE1:
+.LLSFDE2:
+ .uaword .LLEFDE2-.LLASFDE2 ! FDE Length
+.LLASFDE2:
+ .uaword .LLASFDE2-.LLframe1 ! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+ .uaword %r_disp32(.LLFB2)
+ .uaword .LLFE2-.LLFB2 ! FDE address range
+#else
+ .align 8
+ .xword .LLFB2
+ .uaxword .LLFE2-.LLFB2 ! FDE address range
+#endif
+ .byte 0x0 ! uleb128 0x0; Augmentation size
+ .byte 0x4 ! DW_CFA_advance_loc4
+ .uaword .LLCFI1-.LLFB2
+ .byte 0xd ! DW_CFA_def_cfa_register
+ .byte 0x1e ! uleb128 0x1e
+ .byte 0x2d ! DW_CFA_GNU_window_save
+ .byte 0x9 ! DW_CFA_register
+ .byte 0xf ! uleb128 0xf
+ .byte 0x1f ! uleb128 0x1f
+ .align 8
+.LLEFDE2:
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/darwin.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/darwin.S
new file mode 100644
index 000000000..d91bdc084
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/darwin.S
@@ -0,0 +1,243 @@
+#ifdef __i386__
+/* -----------------------------------------------------------------------
+ darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc.
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+/*
+ * This file is based on sysv.S and then hacked up by Ronald who hasn't done
+ * assembly programming in 8 years.
+ */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef PyObjC_STRICT_DEBUGGING
+ /* XXX: Debugging of stack alignment, to be removed */
+#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0
+#else
+#define ASSERT_STACK_ALIGNED
+#endif
+
+.text
+
+.globl _ffi_prep_args
+
+.align 4
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+.LFB1:
+ pushl %ebp
+.LCFI0:
+ movl %esp,%ebp
+ subl $8,%esp
+ ASSERT_STACK_ALIGNED
+.LCFI1:
+ /* Make room for all of the new args. */
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ ASSERT_STACK_ALIGNED
+
+ movl %esp,%eax
+
+ /* Place all of the ffi_prep_args in position */
+ subl $8,%esp
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ ASSERT_STACK_ALIGNED
+
+ /* Return stack to previous state and call the function */
+ addl $16,%esp
+
+ ASSERT_STACK_ALIGNED
+
+ call *28(%ebp)
+
+ /* XXX: return returns return with 'ret $4', that upsets the stack! */
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+
+ /* Load %ecx with the return type code */
+ movl 20(%ebp),%ecx
+
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cmpl $0,24(%ebp)
+ jne retint
+
+ /* Even if there is no space for the return value, we are
+ obliged to handle floating-point values. */
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct1b
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+ jmp epilogue
+
+retstruct1b:
+ cmpl $FFI_TYPE_SINT8,%ecx
+ jne retstruct2b
+ movl 24(%ebp),%ecx
+ movb %al,0(%ecx)
+ jmp epilogue
+
+retstruct2b:
+ cmpl $FFI_TYPE_SINT16,%ecx
+ jne retstruct
+ movl 24(%ebp),%ecx
+ movw %ax,0(%ecx)
+ jmp epilogue
+
+retstruct:
+ cmpl $FFI_TYPE_STRUCT,%ecx
+ jne noretval
+ /* Nothing to do! */
+
+ subl $4,%esp
+
+ ASSERT_STACK_ALIGNED
+
+ addl $8,%esp
+ movl %ebp, %esp
+ popl %ebp
+ ret
+
+noretval:
+epilogue:
+ ASSERT_STACK_ALIGNED
+ addl $8, %esp
+
+
+ movl %ebp,%esp
+ popl %ebp
+ ret
+.LFE1:
+.ffi_call_SYSV_end:
+#if 0
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif
+
+#if 0
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+#ifdef __PIC__
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1 /* FDE initial location */
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .align 4
+.LEFDE1:
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#endif /* defined __i386__ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi.c
new file mode 100644
index 000000000..7f792b7a9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi.c
@@ -0,0 +1,469 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc.
+ Copyright (c) 2002 Ranjit Mathew
+ Copyright (c) 2002 Bo Thorsen
+ Copyright (c) 2002 Roger Sayle
+
+ x86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (ecif->cif->flags == FFI_TYPE_STRUCT)
+ {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i != 0;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp)
+ argp = (char *) ALIGN(argp, sizeof(int));
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+#if !defined(X86_WIN32) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
+ case FFI_TYPE_STRUCT:
+#endif
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+#if defined(X86_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size == 1)
+ {
+ cif->flags = FFI_TYPE_SINT8; /* same as char size */
+ }
+ else if (cif->rtype->size == 2)
+ {
+ cif->flags = FFI_TYPE_SINT16; /* same as short size */
+ }
+ else if (cif->rtype->size == 4)
+ {
+ cif->flags = FFI_TYPE_INT; /* same as int type */
+ }
+ else if (cif->rtype->size == 8)
+ {
+ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+ }
+ else
+ {
+ cif->flags = FFI_TYPE_STRUCT;
+ }
+ break;
+#endif
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+#ifdef X86_WIN32
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+#endif /* X86_WIN32 */
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->flags == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#ifdef X86_WIN32
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif /* X86_WIN32 */
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+ void** args, ffi_cif* cif);
+void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
+ __attribute__ ((regparm(1)));
+unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
+ __attribute__ ((regparm(1)));
+void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
+ __attribute__ ((regparm(1)));
+
+/* This function is jumped to by the trampoline */
+
+unsigned int FFI_HIDDEN
+ffi_closure_SYSV_inner (closure, respp, args)
+ ffi_closure *closure;
+ void **respp;
+ void *args;
+{
+ // our various things...
+ ffi_cif *cif;
+ void **arg_area;
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
+
+ (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+ return cif->flags;
+}
+
+/*@-exportheader@*/
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( cif->flags == FFI_TYPE_STRUCT ) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, sizeof(int));
+ }
+
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
+ *(unsigned char*) &__tramp[0] = 0xb8; \
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+ *(unsigned char *) &__tramp[5] = 0xe9; \
+ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+ &ffi_closure_SYSV, \
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data)
+{
+ int i;
+
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ // we currently don't support certain kinds of arguments for raw
+ // closures. This should be implemented by a separate assembly language
+ // routine, since it would require argument processing, something we
+ // don't do now for performance.
+
+ for (i = cif->nargs-1; i >= 0; i--)
+ {
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+ }
+
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+static void
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+ memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument. as of
+ * libffi-1.20, this is not the case.)
+ */
+
+extern void
+ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+
+#ifdef X86_WIN32
+extern void
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+#endif /* X86_WIN32 */
+
+void
+ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *fake_avalue)
+{
+ extended_cif ecif;
+ void **avalue = (void **)fake_avalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#ifdef X86_WIN32
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif /* X86_WIN32 */
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+#endif
+
+#endif /* __x86_64__ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi64.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi64.c
new file mode 100644
index 000000000..c6cf330c2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi64.c
@@ -0,0 +1,569 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
+
+ x86-64 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef __x86_64__
+
+#define MAX_GPR_REGS 6
+#define MAX_SSE_REGS 8
+
+struct register_args
+{
+ /* Registers for argument passing. */
+ UINT64 gpr[MAX_GPR_REGS];
+ __int128_t sse[MAX_SSE_REGS];
+};
+
+extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+ void *raddr, void (*fnaddr)(), unsigned ssecount);
+
+/* All reference to register classes here is identical to the code in
+ gcc/config/i386/i386.c. Do *not* change one without the other. */
+
+/* Register class used for passing given 64bit part of the argument.
+ These represent classes as documented by the PS ABI, with the exception
+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+ use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ whenever possible (upper half does contain padding). */
+enum x86_64_reg_class
+ {
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_COMPLEX_X87_CLASS,
+ X86_64_MEMORY_CLASS
+ };
+
+#define MAX_CLASSES 4
+
+#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
+
+/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
+ of this code is to classify each 8bytes of incoming argument by the register
+ class and assign registers accordingly. */
+
+/* Return the union class of CLASS1 and CLASS2.
+ See the x86-64 PS ABI for details. */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+ /* Rule #1: If both classes are equal, this is the resulting class. */
+ if (class1 == class2)
+ return class1;
+
+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+ the other class. */
+ if (class1 == X86_64_NO_CLASS)
+ return class2;
+ if (class2 == X86_64_NO_CLASS)
+ return class1;
+
+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+ return X86_64_INTEGERSI_CLASS;
+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+ return X86_64_INTEGER_CLASS;
+
+ /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
+ MEMORY is used. */
+ if (class1 == X86_64_X87_CLASS
+ || class1 == X86_64_X87UP_CLASS
+ || class1 == X86_64_COMPLEX_X87_CLASS
+ || class2 == X86_64_X87_CLASS
+ || class2 == X86_64_X87UP_CLASS
+ || class2 == X86_64_COMPLEX_X87_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #6: Otherwise class SSE is used. */
+ return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+ CLASSES will be filled by the register class used to pass each word
+ of the operand. The number of words is returned. In case the parameter
+ should be passed in memory, 0 is returned. As a special case for zero
+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+ See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
+ size_t byte_offset)
+{
+ switch (type->type)
+ {
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_POINTER:
+ if (byte_offset + type->size <= 4)
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ else
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ case FFI_TYPE_FLOAT:
+ if (byte_offset == 0)
+ classes[0] = X86_64_SSESF_CLASS;
+ else
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case FFI_TYPE_DOUBLE:
+ classes[0] = X86_64_SSEDF_CLASS;
+ return 1;
+ case FFI_TYPE_LONGDOUBLE:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ return 2;
+ case FFI_TYPE_STRUCT:
+ {
+ const int UNITS_PER_WORD = 8;
+ int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ ffi_type **ptr;
+ int i;
+ enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+ /* If the struct is larger than 16 bytes, pass it on the stack. */
+ if (type->size > 16)
+ return 0;
+
+ for (i = 0; i < words; i++)
+ classes[i] = X86_64_NO_CLASS;
+
+ /* Merge the fields of structure. */
+ for (ptr = type->elements; *ptr != NULL; ptr++)
+ {
+ int num;
+
+ byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
+
+ num = classify_argument (*ptr, subclasses, byte_offset % 8);
+ if (num == 0)
+ return 0;
+ for (i = 0; i < num; i++)
+ {
+ int pos = byte_offset / 8;
+ classes[i + pos] =
+ merge_classes (subclasses[i], classes[i + pos]);
+ }
+
+ byte_offset += (*ptr)->size;
+ }
+
+ /* Final merger cleanup. */
+ for (i = 0; i < words; i++)
+ {
+ /* If one class is MEMORY, everything should be passed in
+ memory. */
+ if (classes[i] == X86_64_MEMORY_CLASS)
+ return 0;
+
+ /* The X86_64_SSEUP_CLASS should be always preceded by
+ X86_64_SSE_CLASS. */
+ if (classes[i] == X86_64_SSEUP_CLASS
+ && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
+ classes[i] = X86_64_SSE_CLASS;
+
+ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
+ if (classes[i] == X86_64_X87UP_CLASS
+ && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
+ classes[i] = X86_64_SSE_CLASS;
+ }
+ return words;
+ }
+
+ default:
+ FFI_ASSERT(0);
+ }
+ return 0; /* Never reached. */
+}
+
+/* Examine the argument and return set number of register required in each
+ class. Return zero iff parameter should be passed in memory, otherwise
+ the number of registers. */
+
+static int
+examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
+ _Bool in_return, int *pngpr, int *pnsse)
+{
+ int i, n, ngpr, nsse;
+
+ n = classify_argument (type, classes, 0);
+ if (n == 0)
+ return 0;
+
+ ngpr = nsse = 0;
+ for (i = 0; i < n; ++i)
+ switch (classes[i])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ ngpr++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ nsse++;
+ break;
+ case X86_64_NO_CLASS:
+ case X86_64_SSEUP_CLASS:
+ break;
+ case X86_64_X87_CLASS:
+ case X86_64_X87UP_CLASS:
+ case X86_64_COMPLEX_X87_CLASS:
+ return in_return != 0;
+ default:
+ abort ();
+ }
+
+ *pngpr = ngpr;
+ *pnsse = nsse;
+
+ return n;
+}
+
+/* Perform machine dependent cif processing. */
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+ int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ size_t bytes;
+
+ gprcount = ssecount = 0;
+
+ flags = cif->rtype->type;
+ if (flags != FFI_TYPE_VOID)
+ {
+ n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+ if (n == 0)
+ {
+ /* The return value is passed in memory. A pointer to that
+ memory is the first argument. Allocate a register for it. */
+ gprcount++;
+ /* We don't have to do anything in asm for the return. */
+ flags = FFI_TYPE_VOID;
+ }
+ else if (flags == FFI_TYPE_STRUCT)
+ {
+ /* Mark which registers the result appears in. */
+ _Bool sse0 = SSE_CLASS_P (classes[0]);
+ _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
+ if (sse0 && !sse1)
+ flags |= 1 << 8;
+ else if (!sse0 && sse1)
+ flags |= 1 << 9;
+ else if (sse0 && sse1)
+ flags |= 1 << 10;
+ /* Mark the true size of the structure. */
+ flags |= cif->rtype->size << 12;
+ }
+ }
+
+ /* Go over all arguments and determine the way they should be passed.
+ If it's in a register and there is space for it, let that be so. If
+ not, add it's size to the stack byte count. */
+ for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
+ {
+ if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
+ || gprcount + ngpr > MAX_GPR_REGS
+ || ssecount + nsse > MAX_SSE_REGS)
+ {
+ long align = cif->arg_types[i]->alignment;
+
+ if (align < 8)
+ align = 8;
+
+ bytes = ALIGN(bytes, align);
+ bytes += cif->arg_types[i]->size;
+ }
+ else
+ {
+ gprcount += ngpr;
+ ssecount += nsse;
+ }
+ }
+ if (ssecount)
+ flags |= 1 << 11;
+ cif->flags = flags;
+ cif->bytes = bytes;
+
+ return FFI_OK;
+}
+
+void
+ffi_call (ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ char *stack, *argp;
+ ffi_type **arg_types;
+ int gprcount, ssecount, ngpr, nsse, i, avn;
+ _Bool ret_in_memory;
+ struct register_args *reg_args;
+
+ /* Can't call 32-bit mode from 64-bit mode. */
+ FFI_ASSERT (cif->abi == FFI_UNIX64);
+
+ /* If the return value is a struct and we don't have a return value
+ address then we need to make one. Note the setting of flags to
+ VOID above in ffi_prep_cif_machdep. */
+ ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
+ && (cif->flags & 0xff) == FFI_TYPE_VOID);
+ if (rvalue == NULL && ret_in_memory)
+ rvalue = alloca (cif->rtype->size);
+
+ /* Allocate the space for the arguments, plus 4 words of temp space. */
+ stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
+ reg_args = (struct register_args *) stack;
+ argp = stack + sizeof (struct register_args);
+
+ gprcount = ssecount = 0;
+
+ /* If the return value is passed in memory, add the pointer as the
+ first integer argument. */
+ if (ret_in_memory)
+ reg_args->gpr[gprcount++] = (long) rvalue;
+
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ for (i = 0; i < avn; ++i)
+ {
+ size_t size = arg_types[i]->size;
+ int n;
+
+ n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
+ if (n == 0
+ || gprcount + ngpr > MAX_GPR_REGS
+ || ssecount + nsse > MAX_SSE_REGS)
+ {
+ long align = arg_types[i]->alignment;
+
+ /* Stack arguments are *always* at least 8 byte aligned. */
+ if (align < 8)
+ align = 8;
+
+ /* Pass this argument in memory. */
+ argp = (void *) ALIGN (argp, align);
+ memcpy (argp, avalue[i], size);
+ argp += size;
+ }
+ else
+ {
+ /* The argument is passed entirely in registers. */
+ char *a = (char *) avalue[i];
+ int j;
+
+ for (j = 0; j < n; j++, a += 8, size -= 8)
+ {
+ switch (classes[j])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ reg_args->gpr[gprcount] = 0;
+ memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
+ gprcount++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSEDF_CLASS:
+ reg_args->sse[ssecount++] = *(UINT64 *) a;
+ break;
+ case X86_64_SSESF_CLASS:
+ reg_args->sse[ssecount++] = *(UINT32 *) a;
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+ }
+
+ ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
+ cif->flags, rvalue, fn, ssecount);
+}
+
+
+extern void ffi_closure_unix64(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ volatile unsigned short *tramp;
+
+ tramp = (volatile unsigned short *) &closure->tramp[0];
+
+ tramp[0] = 0xbb49; /* mov <code>, %r11 */
+ *(void * volatile *) &tramp[1] = ffi_closure_unix64;
+ tramp[5] = 0xba49; /* mov <data>, %r10 */
+ *(void * volatile *) &tramp[6] = closure;
+
+ /* Set the carry bit iff the function uses any sse registers.
+ This is clc or stc, together with the first byte of the jmp. */
+ tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
+
+ tramp[11] = 0xe3ff; /* jmp *%r11 */
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ return FFI_OK;
+}
+
+int
+ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
+ struct register_args *reg_args, char *argp)
+{
+ ffi_cif *cif;
+ void **avalue;
+ ffi_type **arg_types;
+ long i, avn;
+ int gprcount, ssecount, ngpr, nsse;
+ int ret;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+ gprcount = ssecount = 0;
+
+ ret = cif->rtype->type;
+ if (ret != FFI_TYPE_VOID)
+ {
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+ if (n == 0)
+ {
+ /* The return value goes in memory. Arrange for the closure
+ return value to go directly back to the original caller. */
+ rvalue = (void *) reg_args->gpr[gprcount++];
+ /* We don't have to do anything in asm for the return. */
+ ret = FFI_TYPE_VOID;
+ }
+ else if (ret == FFI_TYPE_STRUCT && n == 2)
+ {
+ /* Mark which register the second word of the structure goes in. */
+ _Bool sse0 = SSE_CLASS_P (classes[0]);
+ _Bool sse1 = SSE_CLASS_P (classes[1]);
+ if (!sse0 && sse1)
+ ret |= 1 << 8;
+ else if (sse0 && !sse1)
+ ret |= 1 << 9;
+ }
+ }
+
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ for (i = 0; i < avn; ++i)
+ {
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int n;
+
+ n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
+ if (n == 0
+ || gprcount + ngpr > MAX_GPR_REGS
+ || ssecount + nsse > MAX_SSE_REGS)
+ {
+ long align = arg_types[i]->alignment;
+
+ /* Stack arguments are *always* at least 8 byte aligned. */
+ if (align < 8)
+ align = 8;
+
+ /* Pass this argument in memory. */
+ argp = (void *) ALIGN (argp, align);
+ avalue[i] = argp;
+ argp += arg_types[i]->size;
+ }
+ /* If the argument is in a single register, or two consecutive
+ registers, then we can use that address directly. */
+ else if (n == 1
+ || (n == 2
+ && SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1])))
+ {
+ /* The argument is in a single register. */
+ if (SSE_CLASS_P (classes[0]))
+ {
+ avalue[i] = &reg_args->sse[ssecount];
+ ssecount += n;
+ }
+ else
+ {
+ avalue[i] = &reg_args->gpr[gprcount];
+ gprcount += n;
+ }
+ }
+ /* Otherwise, allocate space to make them consecutive. */
+ else
+ {
+ char *a = alloca (16);
+ int j;
+
+ avalue[i] = a;
+ for (j = 0; j < n; j++, a += 8)
+ {
+ if (SSE_CLASS_P (classes[j]))
+ memcpy (a, &reg_args->sse[ssecount++], 8);
+ else
+ memcpy (a, &reg_args->gpr[gprcount++], 8);
+ }
+ }
+ }
+
+ /* Invoke the closure. */
+ closure->fun (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell assembly how to perform return type promotions. */
+ return ret;
+}
+
+#endif /* __x86_64__ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi_darwin.c b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
new file mode 100644
index 000000000..c9742d876
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
@@ -0,0 +1,594 @@
+# ifdef __i386__
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc.
+ Copyright (c) 2002 Ranjit Mathew
+ Copyright (c) 2002 Bo Thorsen
+ Copyright (c) 2002 Roger Sayle
+
+ x86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif);
+
+static inline int retval_on_stack(ffi_type* tp)
+{
+ if (tp->type == FFI_TYPE_STRUCT) {
+ int sz = tp->size;
+ if (sz > 8) {
+ return 1;
+ }
+ switch (sz) {
+ case 1: case 2: case 4: case 8: return 0;
+ default: return 1;
+ }
+ }
+ return 0;
+}
+
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (retval_on_stack(ecif->cif->rtype)) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i != 0;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp)
+ argp = (char *) ALIGN(argp, sizeof(int));
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+#if !defined(X86_WIN32) && !defined(X86_DARWIN)
+ case FFI_TYPE_STRUCT:
+#endif
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+#if defined(X86_WIN32) || defined(X86_DARWIN)
+
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size == 1)
+ {
+ cif->flags = FFI_TYPE_SINT8; /* same as char size */
+ }
+ else if (cif->rtype->size == 2)
+ {
+ cif->flags = FFI_TYPE_SINT16; /* same as short size */
+ }
+ else if (cif->rtype->size == 4)
+ {
+ cif->flags = FFI_TYPE_INT; /* same as int type */
+ }
+ else if (cif->rtype->size == 8)
+ {
+ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+ }
+ else
+ {
+ cif->flags = FFI_TYPE_STRUCT;
+ }
+ break;
+#endif
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ /* Darwin: The stack needs to be aligned to a multiple of 16 bytes */
+#if 1
+ cif->bytes = (cif->bytes + 15) & ~0xF;
+#endif
+
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+#ifdef X86_WIN32
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+#endif /* X86_WIN32 */
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) && retval_on_stack(cif->rtype))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ /* To avoid changing the assembly code make sure the size of the argument
+ * block is a multiple of 16. Then add 8 to compensate for local variables
+ * in ffi_call_SYSV.
+ */
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#ifdef X86_WIN32
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif /* X86_WIN32 */
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+
+/** private members **/
+
+static void ffi_closure_SYSV (ffi_closure *)
+ __attribute__ ((regparm(1)));
+#if !FFI_NO_RAW_API
+static void ffi_closure_raw_SYSV (ffi_raw_closure *)
+ __attribute__ ((regparm(1)));
+#endif
+
+/*@-exportheader@*/
+static inline void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (retval_on_stack(cif->rtype)) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, sizeof(int));
+ }
+
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* This function is jumped to by the trampoline */
+
+static void
+ffi_closure_SYSV (closure)
+ ffi_closure *closure;
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ ffi_cif *cif;
+ void **arg_area;
+ void *resp = (void*)&res;
+ void *args = __builtin_dwarf_cfa ();
+
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);
+
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+ /* now, do a generic return based on the value of rtype */
+ if (cif->flags == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (cif->flags == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (cif->flags == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (cif->flags == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (cif->flags == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax;"
+ "movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+#if defined(X86_WIN32) || defined(X86_DARWIN)
+ else if (cif->flags == FFI_TYPE_SINT8) /* 1-byte struct */
+ {
+ asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (cif->flags == FFI_TYPE_SINT16) /* 2-bytes struct */
+ {
+ asm ("movswl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+#endif
+
+ else if (cif->flags == FFI_TYPE_STRUCT)
+ {
+ asm ("lea -8(%ebp),%esp;"
+ "pop %esi;"
+ "pop %edi;"
+ "pop %ebp;"
+ "ret $4");
+ }
+}
+
+
+/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
+ *(unsigned char*) &__tramp[0] = 0xb8; \
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+ *(unsigned char *) &__tramp[5] = 0xe9; \
+ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+ &ffi_closure_SYSV, \
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+static void
+ffi_closure_raw_SYSV (closure)
+ ffi_raw_closure *closure;
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ ffi_raw *raw_args;
+ ffi_cif *cif;
+ unsigned short rtype;
+ void *resp = (void*)&res;
+
+ /* get the cif */
+ cif = closure->cif;
+
+ /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */
+ raw_args = (ffi_raw*) __builtin_dwarf_cfa ();
+
+ (closure->fun) (cif, resp, raw_args, closure->user_data);
+
+ rtype = cif->flags;
+
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax; movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+}
+
+
+
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data)
+{
+ int i;
+
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ // we currently don't support certain kinds of arguments for raw
+ // closures. This should be implemented by a separate assembly language
+ // routine, since it would require argument processing, something we
+ // don't do now for performance.
+
+ for (i = cif->nargs-1; i >= 0; i--)
+ {
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+ }
+
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+static void
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+ memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument. as of
+ * libffi-1.20, this is not the case.)
+ */
+
+extern void
+ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+
+#ifdef X86_WIN32
+extern void
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+#endif /* X86_WIN32 */
+
+void
+ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *fake_avalue)
+{
+ extended_cif ecif;
+ void **avalue = (void **)fake_avalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) && retval_on_stack(cif->rtype))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#ifdef X86_WIN32
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif /* X86_WIN32 */
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+#endif
+
+#endif /* __x86_64__ */
+
+#endif /* __i386__ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffitarget.h
new file mode 100644
index 000000000..8b20d3c7a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffitarget.h
@@ -0,0 +1,81 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for x86 and x86-64.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (X86_64) && defined (__i386__)
+#undef X86_64
+#define X86
+#endif
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+
+ /* ---- Intel x86 Win32 ---------- */
+#ifdef X86_WIN32
+ FFI_SYSV,
+ FFI_STDCALL,
+ /* TODO: Add fastcall support for the sake of completeness */
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+ /* ---- Intel x86 and AMD x86-64 - */
+#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
+ FFI_SYSV,
+ FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
+#ifdef __i386__
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#else
+ FFI_DEFAULT_ABI = FFI_UNIX64,
+#endif
+#endif
+
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+
+#ifdef X86_64
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+#else
+#define FFI_TRAMPOLINE_SIZE 10
+#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
+#endif
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/sysv.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/sysv.S
new file mode 100644
index 000000000..9542fba1a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/sysv.S
@@ -0,0 +1,382 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc.
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+ .align 4
+.globl ffi_call_SYSV
+ .type ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+.LFB1:
+ pushl %ebp
+.LCFI0:
+ movl %esp,%ebp
+.LCFI1:
+ /* Make room for all of the new args. */
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ /* Place all of the ffi_prep_args in position */
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ /* Return stack to previous state and call the function */
+ addl $8,%esp
+
+ call *28(%ebp)
+
+ /* Remove the space we pushed for the args */
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ /* Load %ecx with the return type code */
+ movl 20(%ebp),%ecx
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cmpl $0,24(%ebp)
+ jne retint
+
+ /* Even if there is no space for the return value, we are
+ obliged to handle floating-point values. */
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct:
+ /* Nothing to do! */
+
+noretval:
+epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+.LFE1:
+.ffi_call_SYSV_end:
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+ .align 4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl ffi_closure_SYSV
+ .type ffi_closure_SYSV, @function
+
+ffi_closure_SYSV:
+.LFB2:
+ pushl %ebp
+.LCFI2:
+ movl %esp, %ebp
+.LCFI3:
+ subl $40, %esp
+ leal -24(%ebp), %edx
+ movl %edx, -12(%ebp) /* resp */
+ leal 8(%ebp), %edx
+ movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
+ leal -12(%ebp), %edx
+ movl %edx, (%esp) /* &resp */
+#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
+ call ffi_closure_SYSV_inner
+#else
+ movl %ebx, 8(%esp)
+.LCFI7:
+ call 1f
+1: popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+ call ffi_closure_SYSV_inner@PLT
+ movl 8(%esp), %ebx
+#endif
+ movl -12(%ebp), %ecx
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lcls_retint
+ cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lcls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lcls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lcls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lcls_retllong
+.Lcls_epilogue:
+ movl %ebp, %esp
+ popl %ebp
+ ret
+.Lcls_retint:
+ movl (%ecx), %eax
+ jmp .Lcls_epilogue
+.Lcls_retfloat:
+ flds (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retdouble:
+ fldl (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retldouble:
+ fldt (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retllong:
+ movl (%ecx), %eax
+ movl 4(%ecx), %edx
+ jmp .Lcls_epilogue
+.LFE2:
+ .size ffi_closure_SYSV, .-ffi_closure_SYSV
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+ .align 4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl ffi_closure_raw_SYSV
+ .type ffi_closure_raw_SYSV, @function
+
+ffi_closure_raw_SYSV:
+.LFB3:
+ pushl %ebp
+.LCFI4:
+ movl %esp, %ebp
+.LCFI5:
+ pushl %esi
+.LCFI6:
+ subl $36, %esp
+ movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
+ movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+ movl %edx, 12(%esp) /* user_data */
+ leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
+ movl %edx, 8(%esp) /* raw_args */
+ leal -24(%ebp), %edx
+ movl %edx, 4(%esp) /* &res */
+ movl %esi, (%esp) /* cif */
+ call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
+ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lrcls_retint
+ cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lrcls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lrcls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lrcls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lrcls_retllong
+.Lrcls_epilogue:
+ addl $36, %esp
+ popl %esi
+ popl %ebp
+ ret
+.Lrcls_retint:
+ movl -24(%ebp), %eax
+ jmp .Lrcls_epilogue
+.Lrcls_retfloat:
+ flds -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retdouble:
+ fldl -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retldouble:
+ fldt -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retllong:
+ movl -24(%ebp), %eax
+ movl -20(%ebp), %edx
+ jmp .Lrcls_epilogue
+.LFE3:
+ .size ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
+#endif
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+#ifdef __PIC__
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1 /* FDE initial location */
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .align 4
+.LEFDE1:
+.LSFDE2:
+ .long .LEFDE2-.LASFDE2 /* FDE Length */
+.LASFDE2:
+ .long .LASFDE2-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB2-. /* FDE initial location */
+#else
+ .long .LFB2
+#endif
+ .long .LFE2-.LFB2 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI2-.LFB2
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI3-.LCFI2
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI7-.LCFI3
+ .byte 0x83 /* DW_CFA_offset, column 0x3 */
+ .byte 0xa /* .uleb128 0xa */
+#endif
+ .align 4
+.LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE3:
+ .long .LEFDE3-.LASFDE3 /* FDE Length */
+.LASFDE3:
+ .long .LASFDE3-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB3-. /* FDE initial location */
+#else
+ .long .LFB3
+#endif
+ .long .LFE3-.LFB3 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI4-.LFB3
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI5-.LCFI4
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI6-.LCFI5
+ .byte 0x86 /* DW_CFA_offset, column 0x6 */
+ .byte 0x3 /* .uleb128 0x3 */
+ .align 4
+.LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/unix64.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/unix64.S
new file mode 100644
index 000000000..831e1d713
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/unix64.S
@@ -0,0 +1,412 @@
+/* -----------------------------------------------------------------------
+ unix64.S - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
+
+ x86-64 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#ifdef __x86_64__
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+ void *raddr, void (*fnaddr)());
+
+ Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+ for this function. This has been allocated by ffi_call. We also
+ deallocate some of the stack that has been alloca'd. */
+
+ .align 2
+ .globl ffi_call_unix64
+ .type ffi_call_unix64,@function
+
+ffi_call_unix64:
+.LUW0:
+ movq (%rsp), %r10 /* Load return address. */
+ leaq (%rdi, %rsi), %rax /* Find local stack base. */
+ movq %rdx, (%rax) /* Save flags. */
+ movq %rcx, 8(%rax) /* Save raddr. */
+ movq %rbp, 16(%rax) /* Save old frame pointer. */
+ movq %r10, 24(%rax) /* Relocate return address. */
+ movq %rax, %rbp /* Finalize local stack frame. */
+.LUW1:
+ movq %rdi, %r10 /* Save a copy of the register area. */
+ movq %r8, %r11 /* Save a copy of the target fn. */
+ movl %r9d, %eax /* Set number of SSE registers. */
+
+ /* Load up all argument registers. */
+ movq (%r10), %rdi
+ movq 8(%r10), %rsi
+ movq 16(%r10), %rdx
+ movq 24(%r10), %rcx
+ movq 32(%r10), %r8
+ movq 40(%r10), %r9
+ testl %eax, %eax
+ jnz .Lload_sse
+.Lret_from_load_sse:
+
+ /* Deallocate the reg arg area. */
+ leaq 176(%r10), %rsp
+
+ /* Call the user function. */
+ call *%r11
+
+ /* Deallocate stack arg area; local stack frame in redzone. */
+ leaq 24(%rbp), %rsp
+
+ movq 0(%rbp), %rcx /* Reload flags. */
+ movq 8(%rbp), %rdi /* Reload raddr. */
+ movq 16(%rbp), %rbp /* Reload old frame pointer. */
+.LUW2:
+
+ /* The first byte of the flags contains the FFI_TYPE. */
+ movzbl %cl, %r10d
+ leaq .Lstore_table(%rip), %r11
+ movslq (%r11, %r10, 4), %r10
+ addq %r11, %r10
+ jmp *%r10
+
+ .section .rodata
+.Lstore_table:
+ .long .Lst_void-.Lstore_table /* FFI_TYPE_VOID */
+ .long .Lst_sint32-.Lstore_table /* FFI_TYPE_INT */
+ .long .Lst_float-.Lstore_table /* FFI_TYPE_FLOAT */
+ .long .Lst_double-.Lstore_table /* FFI_TYPE_DOUBLE */
+ .long .Lst_ldouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */
+ .long .Lst_uint8-.Lstore_table /* FFI_TYPE_UINT8 */
+ .long .Lst_sint8-.Lstore_table /* FFI_TYPE_SINT8 */
+ .long .Lst_uint16-.Lstore_table /* FFI_TYPE_UINT16 */
+ .long .Lst_sint16-.Lstore_table /* FFI_TYPE_SINT16 */
+ .long .Lst_uint32-.Lstore_table /* FFI_TYPE_UINT32 */
+ .long .Lst_sint32-.Lstore_table /* FFI_TYPE_SINT32 */
+ .long .Lst_int64-.Lstore_table /* FFI_TYPE_UINT64 */
+ .long .Lst_int64-.Lstore_table /* FFI_TYPE_SINT64 */
+ .long .Lst_struct-.Lstore_table /* FFI_TYPE_STRUCT */
+ .long .Lst_int64-.Lstore_table /* FFI_TYPE_POINTER */
+
+ .text
+ .align 2
+.Lst_void:
+ ret
+ .align 2
+
+.Lst_uint8:
+ movzbq %al, %rax
+ movq %rax, (%rdi)
+ ret
+ .align 2
+.Lst_sint8:
+ movsbq %al, %rax
+ movq %rax, (%rdi)
+ ret
+ .align 2
+.Lst_uint16:
+ movzwq %ax, %rax
+ movq %rax, (%rdi)
+ .align 2
+.Lst_sint16:
+ movswq %ax, %rax
+ movq %rax, (%rdi)
+ ret
+ .align 2
+.Lst_uint32:
+ movl %eax, %eax
+ movq %rax, (%rdi)
+ .align 2
+.Lst_sint32:
+ cltq
+ movq %rax, (%rdi)
+ ret
+ .align 2
+.Lst_int64:
+ movq %rax, (%rdi)
+ ret
+
+ .align 2
+.Lst_float:
+ movss %xmm0, (%rdi)
+ ret
+ .align 2
+.Lst_double:
+ movsd %xmm0, (%rdi)
+ ret
+.Lst_ldouble:
+ fstpt (%rdi)
+ ret
+
+ .align 2
+.Lst_struct:
+ leaq -20(%rsp), %rsi /* Scratch area in redzone. */
+
+ /* We have to locate the values now, and since we don't want to
+ write too much data into the user's return value, we spill the
+ value to a 16 byte scratch area first. Bits 8, 9, and 10
+ control where the values are located. Only one of the three
+ bits will be set; see ffi_prep_cif_machdep for the pattern. */
+ movd %xmm0, %r10
+ movd %xmm1, %r11
+ testl $0x100, %ecx
+ cmovnz %rax, %rdx
+ cmovnz %r10, %rax
+ testl $0x200, %ecx
+ cmovnz %r10, %rdx
+ testl $0x400, %ecx
+ cmovnz %r10, %rax
+ cmovnz %r11, %rdx
+ movq %rax, (%rsi)
+ movq %rdx, 8(%rsi)
+
+ /* Bits 12-31 contain the true size of the structure. Copy from
+ the scratch area to the true destination. */
+ shrl $12, %ecx
+ rep movsb
+ ret
+
+ /* Many times we can avoid loading any SSE registers at all.
+ It's not worth an indirect jump to load the exact set of
+ SSE registers needed; zero or all is a good compromise. */
+ .align 2
+.LUW3:
+.Lload_sse:
+ movdqa 48(%r10), %xmm0
+ movdqa 64(%r10), %xmm1
+ movdqa 80(%r10), %xmm2
+ movdqa 96(%r10), %xmm3
+ movdqa 112(%r10), %xmm4
+ movdqa 128(%r10), %xmm5
+ movdqa 144(%r10), %xmm6
+ movdqa 160(%r10), %xmm7
+ jmp .Lret_from_load_sse
+
+.LUW4:
+ .size ffi_call_unix64,.-ffi_call_unix64
+
+ .align 2
+ .globl ffi_closure_unix64
+ .type ffi_closure_unix64,@function
+
+ffi_closure_unix64:
+.LUW5:
+ /* The carry flag is set by the trampoline iff SSE registers
+ are used. Don't clobber it before the branch instruction. */
+ leaq -200(%rsp), %rsp
+.LUW6:
+ movq %rdi, (%rsp)
+ movq %rsi, 8(%rsp)
+ movq %rdx, 16(%rsp)
+ movq %rcx, 24(%rsp)
+ movq %r8, 32(%rsp)
+ movq %r9, 40(%rsp)
+ jc .Lsave_sse
+.Lret_from_save_sse:
+
+ movq %r10, %rdi
+ leaq 176(%rsp), %rsi
+ movq %rsp, %rdx
+ leaq 208(%rsp), %rcx
+ call ffi_closure_unix64_inner@PLT
+
+ /* Deallocate stack frame early; return value is now in redzone. */
+ addq $200, %rsp
+.LUW7:
+
+ /* The first byte of the return value contains the FFI_TYPE. */
+ movzbl %al, %r10d
+ leaq .Lload_table(%rip), %r11
+ movslq (%r11, %r10, 4), %r10
+ addq %r11, %r10
+ jmp *%r10
+
+ .section .rodata
+.Lload_table:
+ .long .Lld_void-.Lload_table /* FFI_TYPE_VOID */
+ .long .Lld_int32-.Lload_table /* FFI_TYPE_INT */
+ .long .Lld_float-.Lload_table /* FFI_TYPE_FLOAT */
+ .long .Lld_double-.Lload_table /* FFI_TYPE_DOUBLE */
+ .long .Lld_ldouble-.Lload_table /* FFI_TYPE_LONGDOUBLE */
+ .long .Lld_int8-.Lload_table /* FFI_TYPE_UINT8 */
+ .long .Lld_int8-.Lload_table /* FFI_TYPE_SINT8 */
+ .long .Lld_int16-.Lload_table /* FFI_TYPE_UINT16 */
+ .long .Lld_int16-.Lload_table /* FFI_TYPE_SINT16 */
+ .long .Lld_int32-.Lload_table /* FFI_TYPE_UINT32 */
+ .long .Lld_int32-.Lload_table /* FFI_TYPE_SINT32 */
+ .long .Lld_int64-.Lload_table /* FFI_TYPE_UINT64 */
+ .long .Lld_int64-.Lload_table /* FFI_TYPE_SINT64 */
+ .long .Lld_struct-.Lload_table /* FFI_TYPE_STRUCT */
+ .long .Lld_int64-.Lload_table /* FFI_TYPE_POINTER */
+
+ .text
+ .align 2
+.Lld_void:
+ ret
+
+ .align 2
+.Lld_int8:
+ movzbl -24(%rsp), %eax
+ ret
+ .align 2
+.Lld_int16:
+ movzwl -24(%rsp), %eax
+ ret
+ .align 2
+.Lld_int32:
+ movl -24(%rsp), %eax
+ ret
+ .align 2
+.Lld_int64:
+ movq -24(%rsp), %rax
+ ret
+
+ .align 2
+.Lld_float:
+ movss -24(%rsp), %xmm0
+ ret
+ .align 2
+.Lld_double:
+ movsd -24(%rsp), %xmm0
+ ret
+ .align 2
+.Lld_ldouble:
+ fldt -24(%rsp)
+ ret
+
+ .align 2
+.Lld_struct:
+ /* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
+ %rax/%xmm0, %xmm0/%xmm1. We collapse two by always loading
+ both rdx and xmm1 with the second word. For the remaining,
+ bit 8 set means xmm0 gets the second word, and bit 9 means
+ that rax gets the second word. */
+ movq -24(%rsp), %rcx
+ movq -16(%rsp), %rdx
+ movq -16(%rsp), %xmm1
+ testl $0x100, %eax
+ cmovnz %rdx, %rcx
+ movd %rcx, %xmm0
+ testl $0x200, %eax
+ movq -24(%rsp), %rax
+ cmovnz %rdx, %rax
+ ret
+
+ /* See the comment above .Lload_sse; the same logic applies here. */
+ .align 2
+.LUW8:
+.Lsave_sse:
+ movdqa %xmm0, 48(%rsp)
+ movdqa %xmm1, 64(%rsp)
+ movdqa %xmm2, 80(%rsp)
+ movdqa %xmm3, 96(%rsp)
+ movdqa %xmm4, 112(%rsp)
+ movdqa %xmm5, 128(%rsp)
+ movdqa %xmm6, 144(%rsp)
+ movdqa %xmm7, 160(%rsp)
+ jmp .Lret_from_save_sse
+
+.LUW9:
+ .size ffi_closure_unix64,.-ffi_closure_unix64
+
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* CIE Length */
+.LSCIE1:
+ .long 0 /* CIE Identifier Tag */
+ .byte 1 /* CIE Version */
+ .ascii "zR\0" /* CIE Augmentation */
+ .uleb128 1 /* CIE Code Alignment Factor */
+ .sleb128 -8 /* CIE Data Alignment Factor */
+ .byte 0x10 /* CIE RA Column */
+ .uleb128 1 /* Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
+ .uleb128 7
+ .uleb128 8
+ .byte 0x80+16 /* DW_CFA_offset, %rip offset 1*-8 */
+ .uleb128 1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+ .long .LUW0-. /* FDE initial location */
+ .long .LUW4-.LUW0 /* FDE address range */
+ .uleb128 0x0 /* Augmentation size */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LUW1-.LUW0
+
+ /* New stack frame based off rbp. This is a itty bit of unwind
+ trickery in that the CFA *has* changed. There is no easy way
+ to describe it correctly on entry to the function. Fortunately,
+ it doesn't matter too much since at all points we can correctly
+ unwind back to ffi_call. Note that the location to which we
+ moved the return address is (the new) CFA-8, so from the
+ perspective of the unwind info, it hasn't moved. */
+ .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */
+ .uleb128 6
+ .uleb128 32
+ .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */
+ .uleb128 2
+ .byte 0xa /* DW_CFA_remember_state */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LUW2-.LUW1
+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
+ .uleb128 7
+ .uleb128 8
+ .byte 0xc0+6 /* DW_CFA_restore, %rbp */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LUW3-.LUW2
+ .byte 0xb /* DW_CFA_restore_state */
+
+ .align 8
+.LEFDE1:
+.LSFDE3:
+ .long .LEFDE3-.LASFDE3 /* FDE Length */
+.LASFDE3:
+ .long .LASFDE3-.Lframe1 /* FDE CIE offset */
+ .long .LUW5-. /* FDE initial location */
+ .long .LUW9-.LUW5 /* FDE address range */
+ .uleb128 0x0 /* Augmentation size */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LUW6-.LUW5
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .uleb128 208
+ .byte 0xa /* DW_CFA_remember_state */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LUW7-.LUW6
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .uleb128 8
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LUW8-.LUW7
+ .byte 0xb /* DW_CFA_restore_state */
+
+ .align 8
+.LEFDE3:
+
+#endif /* __x86_64__ */
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/win32.S b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/win32.S
new file mode 100644
index 000000000..496953e43
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/win32.S
@@ -0,0 +1,373 @@
+/* -----------------------------------------------------------------------
+ win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc.
+ Copyright (c) 2001 John Beniton
+ Copyright (c) 2002 Ranjit Mathew
+
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+ pushl %ebp
+ movl %esp,%ebp
+
+ # Make room for all of the new args.
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ # Place all of the ffi_prep_args in position
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ # Return stack to previous state and call the function
+ addl $8,%esp
+
+ # FIXME: Align the stack to a 128-bit boundary to avoid
+ # potential performance hits.
+
+ call *28(%ebp)
+
+ # Remove the space we pushed for the args
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ # Load %ecx with the return type code
+ movl 20(%ebp),%ecx
+
+ # If the return value pointer is NULL, assume no return value.
+ cmpl $0,24(%ebp)
+ jne retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct1b
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct1b:
+ cmpl $FFI_TYPE_SINT8,%ecx
+ jne retstruct2b
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movb %al,0(%ecx)
+ jmp epilogue
+
+retstruct2b:
+ cmpl $FFI_TYPE_SINT16,%ecx
+ jne retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movw %ax,0(%ecx)
+ jmp epilogue
+
+retstruct:
+ # Nothing to do!
+
+noretval:
+epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+.ffi_call_SYSV_end:
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_STDCALL
+
+_ffi_call_STDCALL:
+ pushl %ebp
+ movl %esp,%ebp
+
+ # Make room for all of the new args.
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ # Place all of the ffi_prep_args in position
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ # Return stack to previous state and call the function
+ addl $8,%esp
+
+ # FIXME: Align the stack to a 128-bit boundary to avoid
+ # potential performance hits.
+
+ call *28(%ebp)
+
+ # stdcall functions pop arguments off the stack themselves
+
+ # Load %ecx with the return type code
+ movl 20(%ebp),%ecx
+
+ # If the return value pointer is NULL, assume no return value.
+ cmpl $0,24(%ebp)
+ jne sc_retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne sc_noretval
+ fstp %st(0)
+
+ jmp sc_epilogue
+
+sc_retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne sc_retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp sc_epilogue
+
+sc_retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne sc_retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp sc_epilogue
+
+sc_retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne sc_retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp sc_epilogue
+
+sc_retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne sc_retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp sc_epilogue
+
+sc_retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne sc_retstruct1b
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+sc_retstruct1b:
+ cmpl $FFI_TYPE_SINT8,%ecx
+ jne sc_retstruct2b
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movb %al,0(%ecx)
+ jmp sc_epilogue
+
+sc_retstruct2b:
+ cmpl $FFI_TYPE_SINT16,%ecx
+ jne sc_retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movw %ax,0(%ecx)
+ jmp sc_epilogue
+
+sc_retstruct:
+ # Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+.ffi_call_STDCALL_end:
+
+ .globl _ffi_closure_SYSV
+_ffi_closure_SYSV:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $40, %esp
+ leal -24(%ebp), %edx
+ movl %edx, -12(%ebp) /* resp */
+ leal 8(%ebp), %edx
+ movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
+ leal -12(%ebp), %edx
+ movl %edx, (%esp) /* &resp */
+ call _ffi_closure_SYSV_inner
+ movl -12(%ebp), %ecx
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lcls_retint
+ cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lcls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lcls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lcls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lcls_retllong
+ cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */
+ je .Lcls_retstruct1
+ cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */
+ je .Lcls_retstruct2
+.Lcls_epilogue:
+ movl %ebp, %esp
+ popl %ebp
+ ret
+.Lcls_retint:
+ movl (%ecx), %eax
+ jmp .Lcls_epilogue
+.Lcls_retfloat:
+ flds (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retdouble:
+ fldl (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retldouble:
+ fldt (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retllong:
+ movl (%ecx), %eax
+ movl 4(%ecx), %edx
+ jmp .Lcls_epilogue
+.Lcls_retstruct1:
+ movsbl (%ecx), %eax
+ jmp .Lcls_epilogue
+.Lcls_retstruct2:
+ movswl (%ecx), %eax
+ jmp .Lcls_epilogue
+.ffi_closure_SYSV_end:
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+ .balign 16
+ .globl _ffi_closure_raw_SYSV
+_ffi_closure_raw_SYSV:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+ subl $36, %esp
+ movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
+ movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+ movl %edx, 12(%esp) /* user_data */
+ leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
+ movl %edx, 8(%esp) /* raw_args */
+ leal -24(%ebp), %edx
+ movl %edx, 4(%esp) /* &res */
+ movl %esi, (%esp) /* cif */
+ call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
+ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lrcls_retint
+ cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lrcls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lrcls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lrcls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lrcls_retllong
+.Lrcls_epilogue:
+ addl $36, %esp
+ popl %esi
+ popl %ebp
+ ret
+.Lrcls_retint:
+ movl -24(%ebp), %eax
+ jmp .Lrcls_epilogue
+.Lrcls_retfloat:
+ flds -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retdouble:
+ fldl -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retldouble:
+ fldt -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retllong:
+ movl -24(%ebp), %eax
+ movl -20(%ebp), %edx
+ jmp .Lrcls_epilogue
+.ffi_closure_raw_SYSV_end:
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/debug.c b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/debug.c
new file mode 100644
index 000000000..98f1f9f0b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/debug.c
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------------
+ debug.c - Copyright (c) 1996 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* General debugging routines */
+
+void ffi_stop_here(void)
+{
+ /* This function is only useful for debugging purposes.
+ Place a breakpoint on ffi_stop_here to be notified of
+ significant events. */
+}
+
+/* This function should only be called via the FFI_ASSERT() macro */
+
+void ffi_assert(char *expr, char *file, int line)
+{
+ fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);
+ ffi_stop_here();
+ abort();
+}
+
+/* Perform a sanity check on an ffi_type structure */
+
+void ffi_type_test(ffi_type *a, char *file, int line)
+{
+ FFI_ASSERT_AT(a != NULL, file, line);
+
+ /*@-usedef@*/
+ FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
+ FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
+ FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
+ FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
+ /*@=usedef@*/
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.c
new file mode 100644
index 000000000..1193aaac6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.c
@@ -0,0 +1,310 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Red Hat, Inc.
+
+ ARM Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#ifdef _WIN32_WCE
+#pragma warning (disable : 4142) /* benign redefinition of type */
+#include <windows.h>
+#endif
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+ size_t argalign = (*p_arg)->alignment;
+
+#ifdef _WIN32_WCE
+ if (argalign > 4)
+ argalign = 4;
+#endif
+ /* Align if necessary */
+ if ((argalign - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, argalign);
+ }
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* *p_argv may not be aligned for a UINT32 */
+ memcpy(argp, *p_argv, z);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof(int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_SINT64:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+/* Return type changed from void for ctypes */
+int ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ /* I think calculating the real stack pointer delta is not useful
+ because stdcall is not supported */
+ return 0;
+}
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+ void** args, ffi_cif* cif);
+
+/* This function is called by ffi_closure_SYSV in sysv.asm */
+
+unsigned int
+ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
+{
+ ffi_cif *cif = closure->cif;
+ void **out_args;
+
+ out_args = (void **) alloca(cif->nargs * sizeof (void *));
+
+ /* this call will initialize out_args, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set rvalue to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(in_args, &rvalue, out_args, cif);
+
+ (closure->fun)(cif, rvalue, out_args, closure->user_data);
+
+ /* Tell ffi_closure_SYSV what the returntype is */
+ return cif->flags;
+}
+
+/*@-exportheader@*/
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ unsigned int i;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+ size_t argalign = (*p_arg)->alignment;
+
+#ifdef _WIN32_WCE
+ if (argalign > 4)
+ argalign = 4;
+#endif
+ /* Align if necessary */
+ if ((argalign - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, argalign);
+ }
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ z = sizeof(int);
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+}
+
+/*
+ add ip, pc, #-8 ; ip = address of this trampoline == address of ffi_closure
+ ldr pc, [pc, #-4] ; jump to __fun
+ DCD __fun
+*/
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN) \
+{ \
+ unsigned int *__tramp = (unsigned int *)(TRAMP); \
+ __tramp[0] = 0xe24fc008; /* add ip, pc, #-8 */ \
+ __tramp[1] = 0xe51ff004; /* ldr pc, [pc, #-4] */ \
+ __tramp[2] = (unsigned int)(FUN); \
+ }
+
+/* the cif must already be prep'ed */
+
+/* defined in sysv.asm */
+void ffi_closure_SYSV(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+#ifdef _WIN32_WCE
+ /* This is important to allow calling the trampoline safely */
+ FlushInstructionCache(GetCurrentProcess(), 0, 0);
+#endif
+
+ return FFI_OK;
+}
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.h b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.h
new file mode 100644
index 000000000..67975b6b4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.h
@@ -0,0 +1,317 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi 2.00-beta-wince - Copyright (c) 1996-2003 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ The basic API is described in the README file.
+
+ The raw API is designed to bypass some of the argument packing
+ and unpacking on architectures for which it can be avoided.
+
+ The closure API allows interpreted functions to be packaged up
+ inside a C function pointer, so that they can be called as C functions,
+ with no understanding on the client side that they are interpreted.
+ It can also be used in other cases in which it is necessary to package
+ up a user specified parameter and a function pointer as a single
+ function pointer.
+
+ The closure API must be implemented in order to get its functionality,
+ e.g. for use by gij. Routines are provided to emulate the raw API
+ if the underlying platform doesn't allow faster implementation.
+
+ More details on the raw and cloure API can be found in:
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+ and
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+ -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+/*#define @TARGET@*/
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+ But we can find it either under the correct ANSI name, or under GNU
+ C's internal name. */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+# define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+# ifdef __GNUC__
+# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+# endif
+# ifdef _MSC_VER
+# define FFI_LONG_LONG_MAX _I64_MAX
+# endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar ffi_type_uint8
+# define ffi_type_schar ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort ffi_type_uint16
+# define ffi_type_sshort ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort ffi_type_uint32
+# define ffi_type_sshort ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint ffi_type_uint16
+# define ffi_type_sint ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint ffi_type_uint32
+# define ffi_type_sint ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint ffi_type_uint64
+# define ffi_type_sint ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong ffi_type_uint64
+#define ffi_type_slong ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t */
+/* can hold a pointer. */
+
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+ FFI_OK = 0,
+ FFI_BAD_TYPEDEF,
+ FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+ ffi_abi abi;
+ unsigned nargs;
+ /*@dependent@*/ ffi_type **arg_types;
+ /*@dependent@*/ ffi_type *rtype;
+ unsigned bytes;
+ unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+ FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+# define FFI_SIZEOF_ARG 4
+# elif LONG_MAX == 9223372036854775807
+# define FFI_SIZEOF_ARG 8
+# endif
+#endif
+
+typedef union {
+ ffi_sarg sint;
+ ffi_arg uint;
+ float flt;
+ char data[FFI_SIZEOF_ARG];
+ void* ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter */
+/* packing, even on 64-bit machines. I.e. on 64-bit machines */
+/* longs and doubles are followed by an empty 64-bit word. */
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+ void *user_data;
+} ffi_closure;
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data);
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* if this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the transaltion, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+ void *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes);
+
+/* Return type changed from void for ctypes */
+int ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID 0
+#define FFI_TYPE_INT 1
+#define FFI_TYPE_FLOAT 2
+#define FFI_TYPE_DOUBLE 3
+#if 0 /*@HAVE_LONG_DOUBLE@*/
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8 5
+#define FFI_TYPE_SINT8 6
+#define FFI_TYPE_UINT16 7
+#define FFI_TYPE_SINT16 8
+#define FFI_TYPE_UINT32 9
+#define FFI_TYPE_SINT32 10
+#define FFI_TYPE_UINT64 11
+#define FFI_TYPE_SINT64 12
+#define FFI_TYPE_STRUCT 13
+#define FFI_TYPE_POINTER 14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi_common.h b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi_common.h
new file mode 100644
index 000000000..bf879d11d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi_common.h
@@ -0,0 +1,111 @@
+/* -----------------------------------------------------------------------
+ ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
+
+ Common internal definitions and macros. Only necessary for building
+ libffi.
+ ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+
+/* Do not move this. Some versions of AIX are very picky about where
+ this is positioned. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG)
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x)
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+ /*@dependent@*/ ffi_cif *cif;
+ /*@dependent@*/ void *rvalue;
+ /*@dependent@*/ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions. */
+#if defined(__GNUC__)
+
+typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
+typedef signed int SINT8 __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int SINT64 __attribute__((__mode__(__DI__)));
+
+#elif defined(_MSC_VER)
+
+typedef unsigned __int8 UINT8;
+typedef signed __int8 SINT8;
+typedef unsigned __int16 UINT16;
+typedef signed __int16 SINT16;
+typedef unsigned __int32 UINT32;
+typedef signed __int32 SINT32;
+typedef unsigned __int64 UINT64;
+typedef signed __int64 SINT64;
+
+#else
+#error "Need typedefs here"
+#endif
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/fficonfig.h b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/fficonfig.h
new file mode 100644
index 000000000..3c7964c93
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/fficonfig.h
@@ -0,0 +1,152 @@
+/* fficonfig.h created manually for Windows CE on ARM */
+/* fficonfig.h.in. Generated from configure.ac by autoheader. */
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 1234
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+/* #undef EH_FRAME_FLAGS */
+
+/* Define this if you want extra debugging. */
+#ifdef DEBUG /* Defined by the project settings for Debug builds */
+#define FFI_DEBUG
+#else
+#undef FFI_DEBUG
+#endif
+
+/* Define this is you do not want support for the raw API. */
+/* #undef FFI_NO_RAW_API */
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if your assembler supports .register. */
+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+ */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define if you have the long double type and it is bigger than a double */
+/* This differs from the MSVC build, but even there it should not be defined */
+/* #undef HAVE_LONG_DOUBLE */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+/* WinCE has this but I don't think we need to use it */
+/* #undef HAVE_MEMORY_H */
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+/* #undef HAVE_MMAP_ANON */
+
+/* Define if mmap of /dev/zero works. */
+/* #undef HAVE_MMAP_DEV_ZERO */
+
+/* Define if read-only mmap of a plain file works. */
+/* #undef HAVE_MMAP_FILE */
+
+/* Define if .eh_frame sections should be read-only. */
+/* #undef HAVE_RO_EH_FRAME */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+/* #undef HAVE_SYS_MMAN_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+/* #undef HAVE_SYS_STAT_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+/* #undef HAVE_SYS_TYPES_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define if the host machine stores words of multi-word integers in
+ big-endian order. */
+/* #undef HOST_WORDS_BIG_ENDIAN */
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+/* #undef PACKAGE */
+
+/* Define to the address where bug reports for this package should be sent. */
+/* #undef PACKAGE_BUGREPORT */
+
+/* Define to the full name of this package. */
+/* #undef PACKAGE_NAME */
+
+/* Define to the full name and version of this package. */
+/* #undef PACKAGE_STRING */
+
+/* Define to the one symbol short name of this package. */
+/* #undef PACKAGE_TARNAME */
+
+/* Define to the version of this package. */
+/* #undef PACKAGE_VERSION */
+
+/* The number of bytes in type double */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in type long double */
+#define SIZEOF_LONG_DOUBLE 8
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define this if you are using Purify and want to suppress spurious messages.
+ */
+/* #undef USING_PURIFY */
+
+/* Version number of package */
+/* #undef VERSION */
+
+/* whether byteorder is bigendian */
+/* #undef WORDS_BIGENDIAN */
+
+#define alloca _alloca
+
+#define abort() exit(999)
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffitarget.h
new file mode 100644
index 000000000..2627b2577
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffitarget.h
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for ARM.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 12
+
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/prep_cif.c b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/prep_cif.c
new file mode 100644
index 000000000..9edce2f65
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/prep_cif.c
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------
+ prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+ specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+ ffi_type **ptr;
+
+ FFI_ASSERT(arg != NULL);
+
+ /*@-usedef@*/
+
+ FFI_ASSERT(arg->elements != NULL);
+ FFI_ASSERT(arg->size == 0);
+ FFI_ASSERT(arg->alignment == 0);
+
+ ptr = &(arg->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment : (*ptr)->alignment;
+
+ ptr++;
+ }
+
+ /* Structure size includes tail padding. This is important for
+ structures that fit in one register on ABIs like the PowerPC64
+ Linux ABI that right justify small structs in a register.
+ It's also needed for nested structure layout, for example
+ struct A { long a; char b; }; struct B { struct A x; char y; };
+ should find y at an offset of 2*sizeof(long) and result in a
+ total size of 3*sizeof(long). */
+ arg->size = ALIGN (arg->size, arg->alignment);
+
+ if (arg->size == 0)
+ return FFI_BAD_TYPEDEF;
+ else
+ return FFI_OK;
+
+ /*@=usedef@*/
+}
+
+/* Perform machine independent ffi_cif preparation, then call
+ machine dependent routine. */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi, unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes)
+{
+ unsigned bytes = 0;
+ unsigned int i;
+ ffi_type **ptr;
+
+ FFI_ASSERT(cif != NULL);
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+ cif->abi = abi;
+ cif->arg_types = atypes;
+ cif->nargs = nargs;
+ cif->rtype = rtype;
+
+ cif->flags = 0;
+
+ /* Initialize the return type if necessary */
+ /*@-usedef@*/
+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+ /*@=usedef@*/
+
+ /* Perform a sanity check on the return type */
+ FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+ /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
+#if !defined M68K && !defined __x86_64__ && !defined S390
+ /* Make space for the return structure pointer */
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+ /* MSVC returns small structures in registers. But we have a different
+ workaround: pretend int32 or int64 return type, and converting to
+ structure afterwards. */
+#ifdef SPARC
+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+ )
+ bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+
+ /* Initialize any uninitialized aggregate type definitions */
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type, do this
+ check after the initialization. */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if !defined __x86_64__ && !defined S390
+#ifdef SPARC
+ if (((*ptr)->type == FFI_TYPE_STRUCT
+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+ && cif->abi != FFI_V9))
+ bytes += sizeof(void*);
+ else
+#endif
+ {
+#ifndef _MSC_VER
+ /* Don't know if this is a libffi bug or not. At least on
+ Windows with MSVC, function call parameters are *not*
+ aligned in the same way as structure fields are, they are
+ only aligned in integer boundaries.
+
+ This doesn't do any harm for cdecl functions and closures,
+ since the caller cleans up the stack, but it is wrong for
+ stdcall functions where the callee cleans.
+ */
+
+ /* Add any padding if necessary */
+ if (((*ptr)->alignment - 1) & bytes)
+ bytes = ALIGN(bytes, (*ptr)->alignment);
+
+#endif
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+#endif
+ }
+
+ cif->bytes = bytes;
+
+ /* Perform machine dependent cif processing */
+ return ffi_prep_cif_machdep(cif);
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/sysv.asm b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/sysv.asm
new file mode 100644
index 000000000..db78b9085
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/sysv.asm
@@ -0,0 +1,228 @@
+; -----------------------------------------------------------------------
+; sysv.S - Copyright (c) 1998 Red Hat, Inc.
+;
+; ARM Foreign Function Interface
+;
+; Permission is hereby granted, free of charge, to any person obtaining
+; a copy of this software and associated documentation files (the
+; ``Software''), to deal in the Software without restriction, including
+; without limitation the rights to use, copy, modify, merge, publish,
+; distribute, sublicense, and/or sell copies of the Software, and to
+; permit persons to whom the Software is furnished to do so, subject to
+; the following conditions:
+;
+; The above copyright notice and this permission notice shall be included
+; in all copies or substantial portions of the Software.
+;
+; THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+; OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+; IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+; OTHER DEALINGS IN THE SOFTWARE.
+; ----------------------------------------------------------------------- */
+
+;#define LIBFFI_ASM
+;#include <fficonfig.h>
+;#include <ffi.h>
+;#ifdef HAVE_MACHINE_ASM_H
+;#include <machine/asm.h>
+;#else
+;#ifdef __USER_LABEL_PREFIX__
+;#define CONCAT1(a, b) CONCAT2(a, b)
+;#define CONCAT2(a, b) a ## b
+
+;/* Use the right prefix for global labels. */
+;#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+;#else
+;#define CNAME(x) x
+;#endif
+;#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+;#endif
+
+
+FFI_TYPE_VOID EQU 0
+FFI_TYPE_INT EQU 1
+FFI_TYPE_FLOAT EQU 2
+FFI_TYPE_DOUBLE EQU 3
+;FFI_TYPE_LONGDOUBLE EQU 4
+FFI_TYPE_UINT8 EQU 5
+FFI_TYPE_SINT8 EQU 6
+FFI_TYPE_UINT16 EQU 7
+FFI_TYPE_SINT16 EQU 8
+FFI_TYPE_UINT32 EQU 9
+FFI_TYPE_SINT32 EQU 10
+FFI_TYPE_UINT64 EQU 11
+FFI_TYPE_SINT64 EQU 12
+FFI_TYPE_STRUCT EQU 13
+FFI_TYPE_POINTER EQU 14
+
+; WinCE always uses software floating point (I think)
+__SOFTFP__ EQU {TRUE}
+
+
+ AREA |.text|, CODE, ARM ; .text
+
+
+ ; a1: ffi_prep_args
+ ; a2: &ecif
+ ; a3: cif->bytes
+ ; a4: fig->flags
+ ; sp+0: ecif.rvalue
+ ; sp+4: fn
+
+ ; This assumes we are using gas.
+;ENTRY(ffi_call_SYSV)
+
+ EXPORT |ffi_call_SYSV|
+
+|ffi_call_SYSV| PROC
+
+ ; Save registers
+ stmfd sp!, {a1-a4, fp, lr}
+ mov fp, sp
+
+ ; Make room for all of the new args.
+ sub sp, fp, a3
+
+ ; Place all of the ffi_prep_args in position
+ mov ip, a1
+ mov a1, sp
+ ; a2 already set
+
+ ; And call
+ mov lr, pc
+ mov pc, ip
+
+ ; move first 4 parameters in registers
+ ldr a1, [sp, #0]
+ ldr a2, [sp, #4]
+ ldr a3, [sp, #8]
+ ldr a4, [sp, #12]
+
+ ; and adjust stack
+ ldr ip, [fp, #8]
+ cmp ip, #16
+ movge ip, #16
+ add sp, sp, ip
+
+ ; call function
+ mov lr, pc
+ ldr pc, [fp, #28]
+
+ ; Remove the space we pushed for the args
+ mov sp, fp
+
+ ; Load a3 with the pointer to storage for the return value
+ ldr a3, [sp, #24]
+
+ ; Load a4 with the return type code
+ ldr a4, [sp, #12]
+
+ ; If the return value pointer is NULL, assume no return value.
+ cmp a3, #0
+ beq call_epilogue
+
+; return INT
+ cmp a4, #FFI_TYPE_INT
+ streq a1, [a3]
+ beq call_epilogue
+
+; return FLOAT
+ cmp a4, #FFI_TYPE_FLOAT
+ [ __SOFTFP__ ;ifdef __SOFTFP__
+ streq a1, [a3]
+ | ;else
+ stfeqs f0, [a3]
+ ] ;endif
+ beq call_epilogue
+
+; return DOUBLE or LONGDOUBLE
+ cmp a4, #FFI_TYPE_DOUBLE
+ [ __SOFTFP__ ;ifdef __SOFTFP__
+ stmeqia a3, {a1, a2}
+ | ;else
+ stfeqd f0, [a3]
+ ] ;endif
+ beq call_epilogue
+
+; return SINT64 or UINT64
+ cmp a4, #FFI_TYPE_SINT64
+ stmeqia a3, {a1, a2}
+
+call_epilogue
+ ldmfd sp!, {a1-a4, fp, pc}
+
+;.ffi_call_SYSV_end:
+ ;.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+ ENDP
+
+
+RESERVE_RETURN EQU 16
+
+ ; This function is called by the trampoline
+ ; It is NOT callable from C
+ ; ip = pointer to struct ffi_closure
+
+ IMPORT |ffi_closure_SYSV_inner|
+
+ EXPORT |ffi_closure_SYSV|
+|ffi_closure_SYSV| PROC
+
+ ; Store the argument registers on the stack
+ stmfd sp!, {a1-a4}
+ ; Push the return address onto the stack
+ stmfd sp!, {lr}
+
+ mov a1, ip ; first arg = address of ffi_closure
+ add a2, sp, #4 ; second arg = sp+4 (points to saved a1)
+
+ ; Allocate space for a non-struct return value
+ sub sp, sp, #RESERVE_RETURN
+ mov a3, sp ; third arg = return value address
+
+ ; static unsigned int
+ ; ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
+ bl ffi_closure_SYSV_inner
+ ; a1 now contains the return type code
+
+ ; At this point the return value is on the stack
+ ; Transfer it to the correct registers if necessary
+
+; return INT
+ cmp a1, #FFI_TYPE_INT
+ ldreq a1, [sp]
+ beq closure_epilogue
+
+; return FLOAT
+ cmp a1, #FFI_TYPE_FLOAT
+ [ __SOFTFP__ ;ifdef __SOFTFP__
+ ldreq a1, [sp]
+ | ;else
+ stfeqs f0, [sp]
+ ] ;endif
+ beq closure_epilogue
+
+; return DOUBLE or LONGDOUBLE
+ cmp a1, #FFI_TYPE_DOUBLE
+ [ __SOFTFP__ ;ifdef __SOFTFP__
+ ldmeqia sp, {a1, a2}
+ | ;else
+ stfeqd f0, [sp]
+ ] ;endif
+ beq closure_epilogue
+
+; return SINT64 or UINT64
+ cmp a1, #FFI_TYPE_SINT64
+ ldmeqia sp, {a1, a2}
+
+closure_epilogue
+ add sp, sp, #RESERVE_RETURN ; remove return value buffer
+ ldmfd sp!, {ip} ; ip = pop return address
+ add sp, sp, #16 ; remove saved argument registers {a1-a4} from the stack
+ mov pc, ip ; return
+
+ ENDP ; ffi_closure_SYSV
+
+ END
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/LICENSE b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/LICENSE
new file mode 100644
index 000000000..f59179515
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/LICENSE
@@ -0,0 +1,20 @@
+libffi - Copyright (c) 1996-2003 Red Hat, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README
new file mode 100644
index 000000000..1fc27470d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README
@@ -0,0 +1,500 @@
+This directory contains the libffi package, which is not part of GCC but
+shipped with GCC as convenience.
+
+Status
+======
+
+libffi-2.00 has not been released yet! This is a development snapshot!
+
+libffi-1.20 was released on October 5, 1998. Check the libffi web
+page for updates: <URL:http://sources.redhat.com/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.
+
+Ffi stands for Foreign Function Interface. A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms and Prerequisites
+=====================================
+
+Libffi has been ported to:
+
+ SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
+
+ Irix 5.3 & 6.2 (System V/o32 & n32)
+
+ Intel x86 - Linux (System V ABI)
+
+ Alpha - Linux and OSF/1
+
+ m68k - Linux (System V ABI)
+
+ PowerPC - Linux (System V ABI, Darwin, AIX)
+
+ ARM - Linux (System V ABI)
+
+Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
+that other versions will work. Libffi has also been built and tested
+with the SGI compiler tools.
+
+On PowerPC, the tests failed (see the note below).
+
+You must use GNU make to build libffi. SGI's make will not work.
+Sun's probably won't either.
+
+If you port libffi to another platform, please let me know! I assume
+that some will be easy (x86 NetBSD), and others will be more difficult
+(HP).
+
+
+Installing libffi
+=================
+
+[Note: before actually performing any of these installation steps,
+ you may wish to read the "Platform Specific Notes" below.]
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the --prefix configure switch. Libffi
+will install under /usr/local by default.
+
+If you want to enable extra run-time debugging checks use the the
+--enable-debug configure switch. This is useful when your program dies
+mysteriously while using libffi.
+
+Another useful configure switch is --enable-purify-safety. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using
+Purify, as it will slow down the library.
+
+Configure has many other options. Use "configure --help" to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make. SGI's make will not work. Sun's probably won't either.
+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+
+To ensure that libffi is working as advertised, type "make test".
+
+To install the library and header files, type "make install".
+
+
+Using libffi
+============
+
+ The Basics
+ ----------
+
+Libffi assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it,
+as well as the return type of the function.
+
+The first thing you must do is create an ffi_cif object that matches
+the signature of the function you wish to call. The cif in ffi_cif
+stands for Call InterFace. To prepare a call interface object, use the
+following function:
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+ unsigned int nargs,
+ ffi_type *rtype, ffi_type **atypes);
+
+ CIF is a pointer to the call interface object you wish
+ to initialize.
+
+ ABI is an enum that specifies the calling convention
+ to use for the call. FFI_DEFAULT_ABI defaults
+ to the system's native calling convention. Other
+ ABI's may be used with care. They are system
+ specific.
+
+ NARGS is the number of arguments this function accepts.
+ libffi does not yet support vararg functions.
+
+ RTYPE is a pointer to an ffi_type structure that represents
+ the return type of the function. Ffi_type objects
+ describe the types of values. libffi provides
+ ffi_type objects for many of the native C types:
+ signed int, unsigned int, signed char, unsigned char,
+ etc. There is also a pointer ffi_type object and
+ a void ffi_type. Use &ffi_type_void for functions that
+ don't return values.
+
+ ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
+ If NARGS is 0, this is ignored.
+
+
+ffi_prep_cif will return a status code that you are responsible
+for checking. It will be one of the following:
+
+ FFI_OK - All is good.
+
+ FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
+ came across is bad.
+
+
+Before making the call, the VALUES vector should be initialized
+with pointers to the appropriate argument values.
+
+To call the the function using the initialized ffi_cif, use the
+ffi_call function:
+
+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+
+ CIF is a pointer to the ffi_cif initialized specifically
+ for this function.
+
+ FN is a pointer to the function you want to call.
+
+ RVALUE is a pointer to a chunk of memory that is to hold the
+ result of the function call. Currently, it must be
+ at least one word in size (except for the n32 version
+ under Irix 6.x, which must be a pointer to an 8 byte
+ aligned value (a long long). It must also be at least
+ word aligned (depending on the return type, and the
+ system's alignment requirements). If RTYPE is
+ &ffi_type_void, this is ignored. If RVALUE is NULL,
+ the return value is discarded.
+
+ AVALUES is a vector of void* that point to the memory locations
+ holding the argument values for a call.
+ If NARGS is 0, this is ignored.
+
+
+If you are expecting a return value from FN it will have been stored
+at RVALUE.
+
+
+
+ An Example
+ ----------
+
+Here is a trivial example that calls puts() a few times.
+
+ #include <stdio.h>
+ #include <ffi.h>
+
+ int main()
+ {
+ ffi_cif cif;
+ ffi_type *args[1];
+ void *values[1];
+ char *s;
+ int rc;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_uint;
+ values[0] = &s;
+
+ /* Initialize the cif */
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, args) == FFI_OK)
+ {
+ s = "Hello World!";
+ ffi_call(&cif, puts, &rc, values);
+ /* rc now holds the result of the call to puts */
+
+ /* values holds a pointer to the function's arg, so to
+ call puts() again all we need to do is change the
+ value of s */
+ s = "This is cool!";
+ ffi_call(&cif, puts, &rc, values);
+ }
+
+ return 0;
+ }
+
+
+
+ Aggregate Types
+ ---------------
+
+Although libffi has no special support for unions or bit-fields, it is
+perfectly happy passing structures back and forth. You must first
+describe the structure to libffi by creating a new ffi_type object
+for it. Here is the definition of ffi_type:
+
+ typedef struct _ffi_type
+ {
+ unsigned size;
+ short alignment;
+ short type;
+ struct _ffi_type **elements;
+ } ffi_type;
+
+All structures must have type set to FFI_TYPE_STRUCT. You may set
+size and alignment to 0. These will be calculated and reset to the
+appropriate values by ffi_prep_cif().
+
+elements is a NULL terminated array of pointers to ffi_type objects
+that describe the type of the structure elements. These may, in turn,
+be structure elements.
+
+The following example initializes a ffi_type object representing the
+tm struct from Linux's time.h:
+
+ struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ /* Those are for future use. */
+ long int __tm_gmtoff__;
+ __const char *__tm_zone__;
+ };
+
+ {
+ ffi_type tm_type;
+ ffi_type *tm_type_elements[12];
+ int i;
+
+ tm_type.size = tm_type.alignment = 0;
+ tm_type.elements = &tm_type_elements;
+
+ for (i = 0; i < 9; i++)
+ tm_type_elements[i] = &ffi_type_sint;
+
+ tm_type_elements[9] = &ffi_type_slong;
+ tm_type_elements[10] = &ffi_type_pointer;
+ tm_type_elements[11] = NULL;
+
+ /* tm_type can now be used to represent tm argument types and
+ return types for ffi_prep_cif() */
+ }
+
+
+
+Platform Specific Notes
+=======================
+
+ Intel x86
+ ---------
+
+There are no known problems with the x86 port.
+
+ Sun SPARC - SunOS 4.1.3 & Solaris 2.x
+ -------------------------------------
+
+You must use GNU Make to build libffi on Sun platforms.
+
+ MIPS - Irix 5.3 & 6.x
+ ---------------------
+
+Irix 6.2 and better supports three different calling conventions: o32,
+n32 and n64. Currently, libffi only supports both o32 and n32 under
+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
+configured for whichever calling convention it was built for.
+
+By default, the configure script will try to build libffi with the GNU
+development tools. To build libffi with the SGI development tools, set
+the environment variable CC to either "cc -32" or "cc -n32" before
+running configure under Irix 6.x (depending on whether you want an o32
+or n32 library), or just "cc" for Irix 5.3.
+
+With the n32 calling convention, when returning structures smaller
+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
+Here's one way of forcing this:
+
+ double struct_storage[2];
+ my_small_struct *s = (my_small_struct *) struct_storage;
+ /* Use s for RVALUE */
+
+If you don't do this you are liable to get spurious bus errors.
+
+"long long" values are not supported yet.
+
+You must use GNU Make to build libffi on SGI platforms.
+
+ ARM - System V ABI
+ ------------------
+
+The ARM port was performed on a NetWinder running ARM Linux ELF
+(2.0.31) and gcc 2.8.1.
+
+
+
+ PowerPC System V ABI
+ --------------------
+
+There are two `System V ABI's which libffi implements for PowerPC.
+They differ only in how small structures are returned from functions.
+
+In the FFI_SYSV version, structures that are 8 bytes or smaller are
+returned in registers. This is what GCC does when it is configured
+for solaris, and is what the System V ABI I have (dated September
+1995) says.
+
+In the FFI_GCC_SYSV version, all structures are returned the same way:
+by passing a pointer as the first argument to the function. This is
+what GCC does when it is configured for linux or a generic sysv
+target.
+
+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
+inconsistency with the SysV ABI: When a procedure is called with many
+floating-point arguments, some of them get put on the stack. They are
+all supposed to be stored in double-precision format, even if they are
+only single-precision, but EGCS stores single-precision arguments as
+single-precision anyway. This causes one test to fail (the `many
+arguments' test).
+
+
+What's With The Crazy Comments?
+===============================
+
+You might notice a number of cryptic comments in the code, delimited
+by /*@ and @*/. These are annotations read by the program LCLint, a
+tool for statically checking C programs. You can read all about it at
+<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
+
+
+History
+=======
+
+1.20 Oct-5-98
+ Raffaele Sena produces ARM port.
+
+1.19 Oct-5-98
+ Fixed x86 long double and long long return support.
+ m68k bug fixes from Andreas Schwab.
+ Patch for DU assembler compatibility for the Alpha from Richard
+ Henderson.
+
+1.18 Apr-17-98
+ Bug fixes and MIPS configuration changes.
+
+1.17 Feb-24-98
+ Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+ Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+
+1.16 Feb-11-98
+ Richard Henderson produces Alpha port.
+
+1.15 Dec-4-97
+ Fixed an n32 ABI bug. New libtool, auto* support.
+
+1.14 May-13-97
+ libtool is now used to generate shared and static libraries.
+ Fixed a minor portability problem reported by Russ McManus
+ <mcmanr@eq.gs.com>.
+
+1.13 Dec-2-96
+ Added --enable-purify-safety to keep Purify from complaining
+ about certain low level code.
+ Sparc fix for calling functions with < 6 args.
+ Linux x86 a.out fix.
+
+1.12 Nov-22-96
+ Added missing ffi_type_void, needed for supporting void return
+ types. Fixed test case for non MIPS machines. Cygnus Support
+ is now Cygnus Solutions.
+
+1.11 Oct-30-96
+ Added notes about GNU make.
+
+1.10 Oct-29-96
+ Added configuration fix for non GNU compilers.
+
+1.09 Oct-29-96
+ Added --enable-debug configure switch. Clean-ups based on LCLint
+ feedback. ffi_mips.h is always installed. Many configuration
+ fixes. Fixed ffitest.c for sparc builds.
+
+1.08 Oct-15-96
+ Fixed n32 problem. Many clean-ups.
+
+1.07 Oct-14-96
+ Gordon Irlam rewrites v8.S again. Bug fixes.
+
+1.06 Oct-14-96
+ Gordon Irlam improved the sparc port.
+
+1.05 Oct-14-96
+ Interface changes based on feedback.
+
+1.04 Oct-11-96
+ Sparc port complete (modulo struct passing bug).
+
+1.03 Oct-10-96
+ Passing struct args, and returning struct values works for
+ all architectures/calling conventions. Expanded tests.
+
+1.02 Oct-9-96
+ Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+ Added "make test".
+
+1.01 Oct-8-96
+ Fixed float passing bug in mips version. Restructured some
+ of the code. Builds cleanly with SGI tools.
+
+1.00 Oct-7-96
+ First release. No public announcement.
+
+
+Authors & Credits
+=================
+
+libffi was written by Anthony Green <green@cygnus.com>.
+
+Portions of libffi were derived from Gianni Mariani's free gencall
+library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented by Kresten Krab
+Thorup.
+
+The Sparc port was derived from code contributed by the fine folks at
+Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
+made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
+
+The Alpha port was written by Richard Henderson at Cygnus Solutions.
+
+Andreas Schwab ported libffi to m68k Linux and provided a number of
+bug fixes.
+
+Geoffrey Keating ported libffi to the PowerPC.
+
+Raffaele Sena ported libffi to the ARM.
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes and configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+If you have a problem, or have found a bug, please send a note to
+green@cygnus.com.
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README.ctypes b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README.ctypes
new file mode 100644
index 000000000..17e8a40b8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README.ctypes
@@ -0,0 +1,7 @@
+The purpose is to hack the libffi sources so that they can be compiled
+with MSVC, and to extend them so that they have the features I need
+for ctypes.
+
+I retrieved the libffi sources from the gcc cvs repository on
+2004-01-27. Then I did 'configure' in a 'build' subdirectory on a x86
+linux system, and copied the files I found useful.
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.c b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.c
new file mode 100644
index 000000000..9af6b716d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.c
@@ -0,0 +1,394 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc.
+ Copyright (c) 2002 Ranjit Mathew
+ Copyright (c) 2002 Bo Thorsen
+ Copyright (c) 2002 Roger Sayle
+
+ x86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i != 0;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp)
+ argp = (char *) ALIGN(argp, sizeof(int));
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern int
+ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern int
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+int
+ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ return -1; /* theller: Hrm. */
+}
+
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+ void** args, ffi_cif* cif);
+/* This function is jumped to by the trampoline */
+
+static void __fastcall
+ffi_closure_SYSV (ffi_closure *closure, int *argp)
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ ffi_cif *cif;
+ void **arg_area;
+ unsigned short rtype;
+ void *resp = (void*)&res;
+ void *args = &argp[1];
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);
+
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+ rtype = cif->flags;
+
+#ifdef _MSC_VER
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ _asm mov eax, resp ;
+ _asm mov eax, [eax] ;
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ _asm mov eax, resp ;
+ _asm fld DWORD PTR [eax] ;
+// asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ _asm mov eax, resp ;
+ _asm fld QWORD PTR [eax] ;
+// asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+// asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ _asm mov edx, resp ;
+ _asm mov eax, [edx] ;
+ _asm mov edx, [edx + 4] ;
+// asm ("movl 0(%0),%%eax;"
+// "movl 4(%0),%%edx"
+// : : "r"(resp)
+// : "eax", "edx");
+ }
+#else
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax;"
+ "movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+#endif
+}
+
+/*@-exportheader@*/
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, sizeof(int));
+ }
+
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - ((unsigned int) __tramp + 8 + 4); \
+ *(unsigned char*) &__tramp[0] = 0xb9; \
+ *(unsigned int*) &__tramp[1] = __ctx; /* mov ecx, __ctx */ \
+ *(unsigned char*) &__tramp[5] = 0x8b; \
+ *(unsigned char*) &__tramp[6] = 0xd4; /* mov edx, esp */ \
+ *(unsigned char*) &__tramp[7] = 0xe8; \
+ *(unsigned int*) &__tramp[8] = __dis; /* call __fun */ \
+ *(unsigned char*) &__tramp[12] = 0xC2; /* ret BYTES */ \
+ *(unsigned short*) &__tramp[13] = BYTES; \
+ }
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ short bytes;
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ if (cif->abi == FFI_SYSV)
+ bytes = 0;
+ else if (cif->abi == FFI_STDCALL)
+ bytes = cif->bytes;
+ else
+ return FFI_BAD_ABI;
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+ &ffi_closure_SYSV,
+ (void*)closure,
+ bytes);
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.h b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.h
new file mode 100644
index 000000000..203142d9c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.h
@@ -0,0 +1,317 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ The basic API is described in the README file.
+
+ The raw API is designed to bypass some of the argument packing
+ and unpacking on architectures for which it can be avoided.
+
+ The closure API allows interpreted functions to be packaged up
+ inside a C function pointer, so that they can be called as C functions,
+ with no understanding on the client side that they are interpreted.
+ It can also be used in other cases in which it is necessary to package
+ up a user specified parameter and a function pointer as a single
+ function pointer.
+
+ The closure API must be implemented in order to get its functionality,
+ e.g. for use by gij. Routines are provided to emulate the raw API
+ if the underlying platform doesn't allow faster implementation.
+
+ More details on the raw and cloure API can be found in:
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+ and
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+ -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+//XXX #define X86
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+ But we can find it either under the correct ANSI name, or under GNU
+ C's internal name. */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+# define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+# ifdef __GNUC__
+# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+# endif
+# ifdef _MSC_VER
+# define FFI_LONG_LONG_MAX _I64_MAX
+# endif
+# endif
+#endif
+
+#if SCHAR_MAX == 127
+# define ffi_type_uchar ffi_type_uint8
+# define ffi_type_schar ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort ffi_type_uint16
+# define ffi_type_sshort ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort ffi_type_uint32
+# define ffi_type_sshort ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint ffi_type_uint16
+# define ffi_type_sint ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint ffi_type_uint32
+# define ffi_type_sint ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint ffi_type_uint64
+# define ffi_type_sint ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#define ffi_type_ulong ffi_type_uint64
+#define ffi_type_slong ffi_type_sint64
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t */
+/* can hold a pointer. */
+
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ /*@null@*/ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+
+typedef enum {
+ FFI_OK = 0,
+ FFI_BAD_TYPEDEF,
+ FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+ ffi_abi abi;
+ unsigned nargs;
+ /*@dependent@*/ ffi_type **arg_types;
+ /*@dependent@*/ ffi_type *rtype;
+ unsigned bytes;
+ unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+ FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+# define FFI_SIZEOF_ARG 4
+# elif LONG_MAX == 9223372036854775807
+# define FFI_SIZEOF_ARG 8
+# endif
+#endif
+
+typedef union {
+ ffi_sarg sint;
+ ffi_arg uint;
+ float flt;
+ char data[FFI_SIZEOF_ARG];
+ void* ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter */
+/* packing, even on 64-bit machines. I.e. on 64-bit machines */
+/* longs and doubles are followed by an empty 64-bit word. */
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+ void *user_data;
+} ffi_closure;
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data);
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* if this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the transaltion, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+ void *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes);
+
+int
+ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID 0
+#define FFI_TYPE_INT 1
+#define FFI_TYPE_FLOAT 2
+#define FFI_TYPE_DOUBLE 3
+#if 1
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8 5
+#define FFI_TYPE_SINT8 6
+#define FFI_TYPE_UINT16 7
+#define FFI_TYPE_SINT16 8
+#define FFI_TYPE_UINT32 9
+#define FFI_TYPE_SINT32 10
+#define FFI_TYPE_UINT64 11
+#define FFI_TYPE_SINT64 12
+#define FFI_TYPE_STRUCT 13
+#define FFI_TYPE_POINTER 14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi_common.h b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi_common.h
new file mode 100644
index 000000000..43fb83b48
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi_common.h
@@ -0,0 +1,77 @@
+/* -----------------------------------------------------------------------
+ ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
+
+ Common internal definitions and macros. Only necessary for building
+ libffi.
+ ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+#include <malloc.h>
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG)
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x)
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+ /*@dependent@*/ ffi_cif *cif;
+ /*@dependent@*/ void *rvalue;
+ /*@dependent@*/ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions. */
+typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
+typedef signed int SINT8 __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int SINT64 __attribute__((__mode__(__DI__)));
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/fficonfig.h b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/fficonfig.h
new file mode 100644
index 000000000..c14f653ec
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/fficonfig.h
@@ -0,0 +1,96 @@
+/* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */
+
+/* fficonfig.h. Generated automatically by configure. */
+/* fficonfig.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define this for MSVC, but not for mingw32! */
+#ifdef _MSC_VER
+#define __attribute__(x) /* */
+#endif
+#define alloca _alloca
+
+/*----------------------------------------------------------------*/
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #define HAVE_ALLOCA_H 1 */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if read-only mmap of a plain file works. */
+//#define HAVE_MMAP_FILE 1
+
+/* Define if mmap of /dev/zero works. */
+//#define HAVE_MMAP_DEV_ZERO 1
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+//#define HAVE_MMAP_ANON 1
+
+/* The number of bytes in type double */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in type long double */
+#define SIZEOF_LONG_DOUBLE 12
+
+/* Define if you have the long double type and it is bigger than a double */
+#define HAVE_LONG_DOUBLE 1
+
+/* whether byteorder is bigendian */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if the host machine stores words of multi-word integers in
+ big-endian order. */
+/* #undef HOST_WORDS_BIG_ENDIAN */
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 1234
+
+/* Define if your assembler and linker support unaligned PC relative relocs. */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+/* Define if your assembler supports .register. */
+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
+
+/* Define if .eh_frame sections should be read-only. */
+/* #undef HAVE_RO_EH_FRAME */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+/* #define EH_FRAME_FLAGS "aw" */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+/* #define EH_FRAME_FLAGS "aw" */
+
+/* Define this if you want extra debugging. */
+/* #undef FFI_DEBUG */
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define this is you do not want support for the raw API. */
+/* #undef FFI_NO_RAW_API */
+
+/* Define this if you are using Purify and want to suppress spurious messages. */
+/* #undef USING_PURIFY */
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffitarget.h b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffitarget.h
new file mode 100644
index 000000000..78c0c37ca
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffitarget.h
@@ -0,0 +1,79 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for x86 and x86-64.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (X86_64) && defined (__i386__)
+#undef X86_64
+#define X86
+#endif
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+
+ /* ---- Intel x86 Win32 ---------- */
+ FFI_SYSV,
+ FFI_STDCALL,
+ /* TODO: Add fastcall support for the sake of completeness */
+ FFI_DEFAULT_ABI = FFI_SYSV,
+
+ /* ---- Intel x86 and AMD x86-64 - */
+/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */
+/* FFI_SYSV, */
+/* FFI_UNIX64,*/ /* Unix variants all use the same ABI for x86-64 */
+/* #ifdef __i386__ */
+/* FFI_DEFAULT_ABI = FFI_SYSV, */
+/* #else */
+/* FFI_DEFAULT_ABI = FFI_UNIX64, */
+/* #endif */
+/* #endif */
+
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+
+#ifdef X86_64
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+#else
+#define FFI_TRAMPOLINE_SIZE 15
+#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
+#endif
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/prep_cif.c b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/prep_cif.c
new file mode 100644
index 000000000..2650fa052
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/prep_cif.c
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------
+ prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+ specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+ ffi_type **ptr;
+
+ FFI_ASSERT(arg != NULL);
+
+ /*@-usedef@*/
+
+ FFI_ASSERT(arg->elements != NULL);
+ FFI_ASSERT(arg->size == 0);
+ FFI_ASSERT(arg->alignment == 0);
+
+ ptr = &(arg->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment : (*ptr)->alignment;
+
+ ptr++;
+ }
+
+ /* Structure size includes tail padding. This is important for
+ structures that fit in one register on ABIs like the PowerPC64
+ Linux ABI that right justify small structs in a register.
+ It's also needed for nested structure layout, for example
+ struct A { long a; char b; }; struct B { struct A x; char y; };
+ should find y at an offset of 2*sizeof(long) and result in a
+ total size of 3*sizeof(long). */
+ arg->size = ALIGN (arg->size, arg->alignment);
+
+ if (arg->size == 0)
+ return FFI_BAD_TYPEDEF;
+ else
+ return FFI_OK;
+
+ /*@=usedef@*/
+}
+
+/* Perform machine independent ffi_cif preparation, then call
+ machine dependent routine. */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi, unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes)
+{
+ unsigned bytes = 0;
+ unsigned int i;
+ ffi_type **ptr;
+
+ FFI_ASSERT(cif != NULL);
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+ cif->abi = abi;
+ cif->arg_types = atypes;
+ cif->nargs = nargs;
+ cif->rtype = rtype;
+
+ cif->flags = 0;
+
+ /* Initialize the return type if necessary */
+ /*@-usedef@*/
+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+ /*@=usedef@*/
+
+ /* Perform a sanity check on the return type */
+ FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+ /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
+#if !defined M68K && !defined __x86_64__ && !defined S390
+ /* Make space for the return structure pointer */
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+ /* MSVC returns small structures in registers. But we have a different
+ workaround: pretend int32 or int64 return type, and converting to
+ structure afterwards. */
+#ifdef SPARC
+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+ )
+ bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+
+ /* Initialize any uninitialized aggregate type definitions */
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type, do this
+ check after the initialization. */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if !defined __x86_64__ && !defined S390
+#ifdef SPARC
+ if (((*ptr)->type == FFI_TYPE_STRUCT
+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+ && cif->abi != FFI_V9))
+ bytes += sizeof(void*);
+ else
+#endif
+ {
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+ /* Don't know if this is a libffi bug or not. At least on
+ Windows with MSVC, function call parameters are *not*
+ aligned in the same way as structure fields are, they are
+ only aligned in integer boundaries.
+
+ This doesn't do any harm for cdecl functions and closures,
+ since the caller cleans up the stack, but it is wrong for
+ stdcall functions where the callee cleans.
+ */
+
+ /* Add any padding if necessary */
+ if (((*ptr)->alignment - 1) & bytes)
+ bytes = ALIGN(bytes, (*ptr)->alignment);
+
+#endif
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+#endif
+ }
+
+ cif->bytes = bytes;
+
+ /* Perform machine dependent cif processing */
+ return ffi_prep_cif_machdep(cif);
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/types.c b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/types.c
new file mode 100644
index 000000000..df32190d1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/types.c
@@ -0,0 +1,104 @@
+/* -----------------------------------------------------------------------
+ types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
+
+ Predefined ffi_types needed by libffi.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+/* Type definitions */
+
+#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL }
+#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e }
+
+/* Size and alignment are fake here. They must not be 0. */
+FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID);
+
+FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8);
+FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8);
+FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16);
+FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16);
+FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
+FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
+FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
+
+#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \
+ || defined IA64
+
+FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
+
+#endif
+
+#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#elif defined SH
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
+
+#endif
+
+
+#if defined X86 || defined X86_WIN32 || defined M68K
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined SPARC
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+#ifdef SPARC64
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+#else
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
+#endif
+
+#elif defined X86_64
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE);
+
+#endif
+
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.S b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.S
new file mode 100644
index 000000000..cc82ab91e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.S
@@ -0,0 +1,243 @@
+/* -----------------------------------------------------------------------
+ win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc.
+ Copyright (c) 2001 John Beniton
+ Copyright (c) 2002 Ranjit Mathew
+
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+ pushl %ebp
+ movl %esp,%ebp
+
+ #THe: save previous %esi, and store the current stack pointer in %esi
+ pushl %esi
+ movl %esp,%esi
+
+ # Make room for all of the new args.
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ # Place all of the ffi_prep_args in position
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ # Return stack to previous state and call the function
+ addl $8,%esp
+
+ # FIXME: Align the stack to a 128-bit boundary to avoid
+ # potential performance hits.
+
+ call *28(%ebp)
+
+ # Remove the space we pushed for the args
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ sub %esp,%esi # calculate stack pointer difference
+
+ # Load %ecx with the return type code
+ movl 20(%ebp),%ecx
+
+ # If the return value pointer is NULL, assume no return value.
+ cmpl $0,24(%ebp)
+ jne retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct:
+ # Nothing to do!
+
+noretval:
+epilogue:
+ movl %esi,%eax # return the stack pointer detlta in %eax
+ popl %esi # restore previous %esi
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+.ffi_call_SYSV_end:
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_STDCALL
+
+_ffi_call_STDCALL:
+ pushl %ebp
+ movl %esp,%ebp
+
+ #THe: save previous %esi, and store the current stack pointer in %esi
+ pushl %esi
+ movl %esp,%esi
+
+ # Make room for all of the new args.
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ # Place all of the ffi_prep_args in position
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ # Return stack to previous state and call the function
+ addl $8,%esp
+
+ # FIXME: Align the stack to a 128-bit boundary to avoid
+ # potential performance hits.
+
+ call *28(%ebp)
+
+ sub %esp,%esi # difference in stack
+
+ # stdcall functions pop arguments off the stack themselves
+
+ # Load %ecx with the return type code
+ movl 20(%ebp),%ecx
+
+ # If the return value pointer is NULL, assume no return value.
+ cmpl $0,24(%ebp)
+ jne sc_retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne sc_noretval
+ fstp %st(0)
+
+ jmp sc_epilogue
+
+sc_retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne sc_retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp sc_epilogue
+
+sc_retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne sc_retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp sc_epilogue
+
+sc_retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne sc_retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp sc_epilogue
+
+sc_retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne sc_retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp sc_epilogue
+
+sc_retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne sc_retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+sc_retstruct:
+ # Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+ movl %esi,%eax # return the stack difference
+ popl %esi # restore previous %esi value
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+.ffi_call_STDCALL_end:
diff --git a/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.c b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.c
new file mode 100644
index 000000000..0670c8ccf
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.c
@@ -0,0 +1,267 @@
+/* -----------------------------------------------------------------------
+ win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc.
+ Copyright (c) 2001 John Beniton
+ Copyright (c) 2002 Ranjit Mathew
+
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+/* theller: almost verbatim translation from gas syntax to MSVC inline
+ assembler code. */
+
+/* theller: ffi_call_SYSV and ffi_call_STDCALL now return an integer - the
+ difference of the stack pointer before and after the function call. If
+ everything is ok, zero is returned. If stdcall functions are passed the
+ wrong number of arguments, the difference will be nonzero. */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+__declspec(naked) int
+ffi_call_SYSV(void (* prepfunc)(char *, extended_cif *), /* 8 */
+ extended_cif *ecif, /* 12 */
+ unsigned bytes, /* 16 */
+ unsigned flags, /* 20 */
+ unsigned *rvalue, /* 24 */
+ void (*fn)()) /* 28 */
+{
+ _asm {
+ push ebp
+ mov ebp, esp
+
+ push esi // NEW: this register must be preserved across function calls
+// XXX SAVE ESP NOW!
+ mov esi, esp // save stack pointer before the call
+
+// Make room for all of the new args.
+ mov ecx, [ebp+16]
+ sub esp, ecx // sub esp, bytes
+
+ mov eax, esp
+
+// Place all of the ffi_prep_args in position
+ push [ebp + 12] // ecif
+ push eax
+ call [ebp + 8] // prepfunc
+
+// Return stack to previous state and call the function
+ add esp, 8
+// FIXME: Align the stack to a 128-bit boundary to avoid
+// potential performance hits.
+ call [ebp + 28]
+// Remove the space we pushed for the args
+ mov ecx, [ebp + 16]
+ add esp, ecx
+
+// XXX ASSERT THAT ESP IS THE SAME NOW THAN BEFORE!
+ sub esi, esp
+
+// Load %ecx with the return type code
+ mov ecx, [ebp + 20]
+
+// If the return value pointer is NULL, assume no return value.
+/*
+ Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
+ otherwise only one BYTE will be compared (instead of a DWORD)!
+ */
+ cmp DWORD PTR [ebp + 24], 0
+ jne sc_retint
+
+// Even if there is no space for the return value, we are
+// obliged to handle floating-point values.
+ cmp ecx, FFI_TYPE_FLOAT
+ jne sc_noretval
+// fstp %st(0)
+ fstp st(0)
+
+ jmp sc_epilogue
+
+sc_retint:
+ cmp ecx, FFI_TYPE_INT
+ jne sc_retfloat
+// # Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp + 24]
+ mov [ecx + 0], eax
+ jmp sc_epilogue
+
+sc_retfloat:
+ cmp ecx, FFI_TYPE_FLOAT
+ jne sc_retdouble
+// Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp+24]
+// fstps (%ecx)
+ fstp DWORD PTR [ecx]
+ jmp sc_epilogue
+
+sc_retdouble:
+ cmp ecx, FFI_TYPE_DOUBLE
+ jne sc_retlongdouble
+// movl 24(%ebp),%ecx
+ mov ecx, [ebp+24]
+ fstp QWORD PTR [ecx]
+ jmp sc_epilogue
+
+ jmp sc_retlongdouble // avoid warning about unused label
+sc_retlongdouble:
+ cmp ecx, FFI_TYPE_LONGDOUBLE
+ jne sc_retint64
+// Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp+24]
+// fstpt (%ecx)
+ fstp QWORD PTR [ecx] /* XXX ??? */
+ jmp sc_epilogue
+
+sc_retint64:
+ cmp ecx, FFI_TYPE_SINT64
+ jne sc_retstruct
+// Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp+24]
+ mov [ecx+0], eax
+ mov [ecx+4], edx
+
+sc_retstruct:
+// Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+ mov eax, esi
+ pop esi // NEW restore: must be preserved across function calls
+ mov esp, ebp
+ pop ebp
+ ret
+ }
+}
+
+__declspec(naked) int
+ffi_call_STDCALL(void (* prepfunc)(char *, extended_cif *), /* 8 */
+ extended_cif *ecif, /* 12 */
+ unsigned bytes, /* 16 */
+ unsigned flags, /* 20 */
+ unsigned *rvalue, /* 24 */
+ void (*fn)()) /* 28 */
+{
+ _asm {
+ push ebp
+ mov ebp, esp
+
+ push esi // NEW: this register must be preserved across function calls
+
+// XXX SAVE ESP NOW!
+ mov esi, esp
+
+// Make room for all of the new args.
+ mov ecx, [ebp+16]
+ sub esp, ecx
+
+ mov eax, esp
+
+// Place all of the ffi_prep_args in position
+ push [ebp + 12] // ecif
+ push eax
+ call [ebp + 8] // prepfunc
+
+// Return stack to previous state and call the function
+ add esp, 8
+// FIXME: Align the stack to a 128-bit boundary to avoid
+// potential performance hits.
+ call [ebp + 28]
+// stdcall functions pop arguments off the stack themselves
+
+// XXX IS ESP NOW THE SAME AS BEFORE?
+ sub esi, esp
+
+// Load %ecx with the return type code
+ mov ecx, [ebp + 20]
+
+// If the return value pointer is NULL, assume no return value.
+/*
+ Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
+ otherwise only one BYTE will be compared (instead of a DWORD)!
+ */
+ cmp DWORD PTR [ebp + 24], 0
+ jne sc_retint
+
+// Even if there is no space for the return value, we are
+// obliged to handle floating-point values.
+ cmp ecx, FFI_TYPE_FLOAT
+ jne sc_noretval
+// fstp %st(0)
+ fstp st(0)
+
+ jmp sc_epilogue
+
+sc_retint:
+ cmp ecx, FFI_TYPE_INT
+ jne sc_retfloat
+// # Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp + 24]
+ mov [ecx + 0], eax
+ jmp sc_epilogue
+
+sc_retfloat:
+ cmp ecx, FFI_TYPE_FLOAT
+ jne sc_retdouble
+// Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp+24]
+// fstps (%ecx)
+ fstp DWORD PTR [ecx]
+ jmp sc_epilogue
+
+sc_retdouble:
+ cmp ecx, FFI_TYPE_DOUBLE
+ jne sc_retlongdouble
+// movl 24(%ebp),%ecx
+ mov ecx, [ebp+24]
+ fstp QWORD PTR [ecx]
+ jmp sc_epilogue
+
+ jmp sc_retlongdouble // avoid warning about unused label
+sc_retlongdouble:
+ cmp ecx, FFI_TYPE_LONGDOUBLE
+ jne sc_retint64
+// Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp+24]
+// fstpt (%ecx)
+ fstp QWORD PTR [ecx] /* XXX ??? */
+ jmp sc_epilogue
+
+sc_retint64:
+ cmp ecx, FFI_TYPE_SINT64
+ jne sc_retstruct
+// Load %ecx with the pointer to storage for the return value
+ mov ecx, [ebp+24]
+ mov [ecx+0], eax
+ mov [ecx+4], edx
+
+sc_retstruct:
+// Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+ mov eax, esi
+ pop esi // NEW restore: must be preserved across function calls
+ mov esp, ebp
+ pop ebp
+ ret
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/malloc_closure.c b/sys/src/cmd/python/Modules/_ctypes/malloc_closure.c
new file mode 100644
index 000000000..4cd5dd6f5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/malloc_closure.c
@@ -0,0 +1,110 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include <Python.h>
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <unistd.h>
+# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+#endif
+#include "ctypes.h"
+
+/* BLOCKSIZE can be adjusted. Larger blocksize will take a larger memory
+ overhead, but allocate less blocks from the system. It may be that some
+ systems have a limit of how many mmap'd blocks can be open.
+*/
+
+#define BLOCKSIZE _pagesize
+
+/* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */
+
+/******************************************************************/
+
+typedef union _tagITEM {
+ ffi_closure closure;
+ union _tagITEM *next;
+} ITEM;
+
+static ITEM *free_list;
+int _pagesize;
+
+static void more_core(void)
+{
+ ITEM *item;
+ int count, i;
+
+/* determine the pagesize */
+#ifdef MS_WIN32
+ if (!_pagesize) {
+ SYSTEM_INFO systeminfo;
+ GetSystemInfo(&systeminfo);
+ _pagesize = systeminfo.dwPageSize;
+ }
+#else
+ if (!_pagesize) {
+ _pagesize = getpagesize();
+ }
+#endif
+
+ /* calculate the number of nodes to allocate */
+ count = BLOCKSIZE / sizeof(ITEM);
+
+ /* allocate a memory block */
+#ifdef MS_WIN32
+ item = (ITEM *)VirtualAlloc(NULL,
+ count * sizeof(ITEM),
+ MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
+ if (item == NULL)
+ return;
+#else
+ item = (ITEM *)mmap(NULL,
+ count * sizeof(ITEM),
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1,
+ 0);
+ if (item == (void *)MAP_FAILED)
+ return;
+#endif
+
+#ifdef MALLOC_CLOSURE_DEBUG
+ printf("block at %p allocated (%d bytes), %d ITEMs\n",
+ item, count * sizeof(ITEM), count);
+#endif
+ /* put them into the free list */
+ for (i = 0; i < count; ++i) {
+ item->next = free_list;
+ free_list = item;
+ ++item;
+ }
+}
+
+/******************************************************************/
+
+/* put the item back into the free list */
+void FreeClosure(void *p)
+{
+ ITEM *item = (ITEM *)p;
+ item->next = free_list;
+ free_list = item;
+}
+
+/* return one item from the free list, allocating more if needed */
+void *MallocClosure(void)
+{
+ ITEM *item;
+ if (!free_list)
+ more_core();
+ if (!free_list)
+ return NULL;
+ item = free_list;
+ free_list = item->next;
+ return item;
+}
diff --git a/sys/src/cmd/python/Modules/_ctypes/stgdict.c b/sys/src/cmd/python/Modules/_ctypes/stgdict.c
new file mode 100644
index 000000000..8fd9a1e57
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ctypes/stgdict.c
@@ -0,0 +1,494 @@
+/*****************************************************************
+ This file should be kept compatible with Python 2.3, see PEP 291.
+ *****************************************************************/
+
+#include "Python.h"
+#include <ffi.h>
+#ifdef MS_WIN32
+#include <windows.h>
+#endif
+#include "ctypes.h"
+
+/******************************************************************/
+/*
+ StdDict - a dictionary subclass, containing additional C accessible fields
+
+ XXX blabla more
+*/
+
+/* Seems we need this, otherwise we get problems when calling
+ * PyDict_SetItem() (ma_lookup is NULL)
+ */
+static int
+StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds)
+{
+ if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
+ return -1;
+ return 0;
+}
+
+static int
+StgDict_clear(StgDictObject *self)
+{
+ Py_CLEAR(self->proto);
+ Py_CLEAR(self->argtypes);
+ Py_CLEAR(self->converters);
+ Py_CLEAR(self->restype);
+ Py_CLEAR(self->checker);
+ return 0;
+}
+
+static void
+StgDict_dealloc(StgDictObject *self)
+{
+ StgDict_clear(self);
+ PyMem_Free(self->ffi_type_pointer.elements);
+ PyDict_Type.tp_dealloc((PyObject *)self);
+}
+
+int
+StgDict_clone(StgDictObject *dst, StgDictObject *src)
+{
+ char *d, *s;
+ int size;
+
+ StgDict_clear(dst);
+ PyMem_Free(dst->ffi_type_pointer.elements);
+ dst->ffi_type_pointer.elements = NULL;
+
+ d = (char *)dst;
+ s = (char *)src;
+ memcpy(d + sizeof(PyDictObject),
+ s + sizeof(PyDictObject),
+ sizeof(StgDictObject) - sizeof(PyDictObject));
+
+ Py_XINCREF(dst->proto);
+ Py_XINCREF(dst->argtypes);
+ Py_XINCREF(dst->converters);
+ Py_XINCREF(dst->restype);
+ Py_XINCREF(dst->checker);
+
+ if (src->ffi_type_pointer.elements == NULL)
+ return 0;
+ size = sizeof(ffi_type *) * (src->length + 1);
+ dst->ffi_type_pointer.elements = PyMem_Malloc(size);
+ if (dst->ffi_type_pointer.elements == NULL)
+ return -1;
+ memcpy(dst->ffi_type_pointer.elements,
+ src->ffi_type_pointer.elements,
+ size);
+ return 0;
+}
+
+PyTypeObject StgDict_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "StgDict",
+ sizeof(StgDictObject),
+ 0,
+ (destructor)StgDict_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)StgDict_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+};
+
+/* May return NULL, but does not set an exception! */
+StgDictObject *
+PyType_stgdict(PyObject *obj)
+{
+ PyTypeObject *type;
+
+ if (!PyType_Check(obj))
+ return NULL;
+ type = (PyTypeObject *)obj;
+ if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
+ return NULL;
+ if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict))
+ return NULL;
+ return (StgDictObject *)type->tp_dict;
+}
+
+/* May return NULL, but does not set an exception! */
+/*
+ This function should be as fast as possible, so we don't call PyType_stgdict
+ above but inline the code, and avoid the PyType_Check().
+*/
+StgDictObject *
+PyObject_stgdict(PyObject *self)
+{
+ PyTypeObject *type = self->ob_type;
+ if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
+ return NULL;
+ if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict))
+ return NULL;
+ return (StgDictObject *)type->tp_dict;
+}
+
+/* descr is the descriptor for a field marked as anonymous. Get all the
+ _fields_ descriptors from descr->proto, create new descriptors with offset
+ and index adjusted, and stuff them into type.
+ */
+static int
+MakeFields(PyObject *type, CFieldObject *descr,
+ Py_ssize_t index, Py_ssize_t offset)
+{
+ Py_ssize_t i;
+ PyObject *fields;
+ PyObject *fieldlist;
+
+ fields = PyObject_GetAttrString(descr->proto, "_fields_");
+ if (fields == NULL)
+ return -1;
+ fieldlist = PySequence_Fast(fields, "_fields_ must be a sequence");
+ Py_DECREF(fields);
+ if (fieldlist == NULL)
+ return -1;
+
+ for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) {
+ PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */
+ PyObject *fname, *ftype, *bits;
+ CFieldObject *fdescr;
+ CFieldObject *new_descr;
+ /* Convert to PyArg_UnpackTuple... */
+ if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) {
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname);
+ if (fdescr == NULL) {
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ if (fdescr->ob_type != &CField_Type) {
+ PyErr_SetString(PyExc_TypeError, "unexpected type");
+ Py_DECREF(fdescr);
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ if (fdescr->anonymous) {
+ int rc = MakeFields(type, fdescr,
+ index + fdescr->index,
+ offset + fdescr->offset);
+ Py_DECREF(fdescr);
+ if (rc == -1) {
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ continue;
+ }
+ new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL);
+ if (new_descr == NULL) {
+ Py_DECREF(fdescr);
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ assert(new_descr->ob_type == &CField_Type);
+ new_descr->size = fdescr->size;
+ new_descr->offset = fdescr->offset + offset;
+ new_descr->index = fdescr->index + index;
+ new_descr->proto = fdescr->proto;
+ Py_XINCREF(new_descr->proto);
+ new_descr->getfunc = fdescr->getfunc;
+ new_descr->setfunc = fdescr->setfunc;
+
+ Py_DECREF(fdescr);
+
+ if (-1 == PyObject_SetAttr(type, fname, (PyObject *)new_descr)) {
+ Py_DECREF(fieldlist);
+ Py_DECREF(new_descr);
+ return -1;
+ }
+ Py_DECREF(new_descr);
+ }
+ Py_DECREF(fieldlist);
+ return 0;
+}
+
+/* Iterate over the names in the type's _anonymous_ attribute, if present,
+ */
+static int
+MakeAnonFields(PyObject *type)
+{
+ PyObject *anon;
+ PyObject *anon_names;
+ Py_ssize_t i;
+
+ anon = PyObject_GetAttrString(type, "_anonymous_");
+ if (anon == NULL) {
+ PyErr_Clear();
+ return 0;
+ }
+ anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence");
+ Py_DECREF(anon);
+ if (anon_names == NULL)
+ return -1;
+
+ for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) {
+ PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */
+ CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname);
+ if (descr == NULL) {
+ Py_DECREF(anon_names);
+ return -1;
+ }
+ assert(descr->ob_type == &CField_Type);
+ descr->anonymous = 1;
+
+ /* descr is in the field descriptor. */
+ if (-1 == MakeFields(type, (CFieldObject *)descr,
+ ((CFieldObject *)descr)->index,
+ ((CFieldObject *)descr)->offset)) {
+ Py_DECREF(descr);
+ Py_DECREF(anon_names);
+ return -1;
+ }
+ Py_DECREF(descr);
+ }
+
+ Py_DECREF(anon_names);
+ return 0;
+}
+
+/*
+ Retrive the (optional) _pack_ attribute from a type, the _fields_ attribute,
+ and create an StgDictObject. Used for Structure and Union subclasses.
+*/
+int
+StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
+{
+ StgDictObject *stgdict, *basedict;
+ int len, offset, size, align, i;
+ int union_size, total_align;
+ int field_size = 0;
+ int bitofs;
+ PyObject *isPacked;
+ int pack = 0;
+ int ffi_ofs;
+ int big_endian;
+
+ /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to
+ be a way to use the old, broken sematics: _fields_ are not extended
+ but replaced in subclasses.
+
+ XXX Remove this in ctypes 1.0!
+ */
+ int use_broken_old_ctypes_semantics;
+
+ if (fields == NULL)
+ return 0;
+
+#ifdef WORDS_BIGENDIAN
+ big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1;
+#else
+ big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0;
+#endif
+
+ use_broken_old_ctypes_semantics = \
+ PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_");
+
+ isPacked = PyObject_GetAttrString(type, "_pack_");
+ if (isPacked) {
+ pack = PyInt_AsLong(isPacked);
+ if (pack < 0 || PyErr_Occurred()) {
+ Py_XDECREF(isPacked);
+ PyErr_SetString(PyExc_ValueError,
+ "_pack_ must be a non-negative integer");
+ return -1;
+ }
+ Py_DECREF(isPacked);
+ } else
+ PyErr_Clear();
+
+ len = PySequence_Length(fields);
+ if (len == -1) {
+ PyErr_SetString(PyExc_TypeError,
+ "'_fields_' must be a sequence of pairs");
+ return -1;
+ }
+
+ stgdict = PyType_stgdict(type);
+ if (!stgdict)
+ return -1;
+ /* If this structure/union is already marked final we cannot assign
+ _fields_ anymore. */
+
+ if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */
+ PyErr_SetString(PyExc_AttributeError,
+ "_fields_ is final");
+ return -1;
+ }
+
+ if (stgdict->ffi_type_pointer.elements)
+ PyMem_Free(stgdict->ffi_type_pointer.elements);
+
+ basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base);
+ if (basedict && !use_broken_old_ctypes_semantics) {
+ size = offset = basedict->size;
+ align = basedict->align;
+ union_size = 0;
+ total_align = align ? align : 1;
+ stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
+ stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1));
+ memset(stgdict->ffi_type_pointer.elements, 0,
+ sizeof(ffi_type *) * (basedict->length + len + 1));
+ memcpy(stgdict->ffi_type_pointer.elements,
+ basedict->ffi_type_pointer.elements,
+ sizeof(ffi_type *) * (basedict->length));
+ ffi_ofs = basedict->length;
+ } else {
+ offset = 0;
+ size = 0;
+ align = 0;
+ union_size = 0;
+ total_align = 1;
+ stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
+ stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1));
+ memset(stgdict->ffi_type_pointer.elements, 0,
+ sizeof(ffi_type *) * (len + 1));
+ ffi_ofs = 0;
+ }
+
+#define realdict ((PyObject *)&stgdict->dict)
+ for (i = 0; i < len; ++i) {
+ PyObject *name = NULL, *desc = NULL;
+ PyObject *pair = PySequence_GetItem(fields, i);
+ PyObject *prop;
+ StgDictObject *dict;
+ int bitsize = 0;
+
+ if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "'_fields_' must be a sequence of pairs");
+ Py_XDECREF(pair);
+ return -1;
+ }
+ dict = PyType_stgdict(desc);
+ if (dict == NULL) {
+ Py_DECREF(pair);
+ PyErr_Format(PyExc_TypeError,
+ "second item in _fields_ tuple (index %d) must be a C type",
+ i);
+ return -1;
+ }
+ stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer;
+ dict->flags |= DICTFLAG_FINAL; /* mark field type final */
+ if (PyTuple_Size(pair) == 3) { /* bits specified */
+ switch(dict->ffi_type_pointer.type) {
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ break;
+
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_SINT32:
+ if (dict->getfunc != getentry("c")->getfunc
+#ifdef CTYPES_UNICODE
+ && dict->getfunc != getentry("u")->getfunc
+#endif
+ )
+ break;
+ /* else fall through */
+ default:
+ PyErr_Format(PyExc_TypeError,
+ "bit fields not allowed for type %s",
+ ((PyTypeObject *)desc)->tp_name);
+ Py_DECREF(pair);
+ return -1;
+ }
+ if (bitsize <= 0 || bitsize > dict->size * 8) {
+ PyErr_SetString(PyExc_ValueError,
+ "number of bits invalid for bit field");
+ Py_DECREF(pair);
+ return -1;
+ }
+ } else
+ bitsize = 0;
+ if (isStruct) {
+ prop = CField_FromDesc(desc, i,
+ &field_size, bitsize, &bitofs,
+ &size, &offset, &align,
+ pack, big_endian);
+ } else /* union */ {
+ size = 0;
+ offset = 0;
+ align = 0;
+ prop = CField_FromDesc(desc, i,
+ &field_size, bitsize, &bitofs,
+ &size, &offset, &align,
+ pack, big_endian);
+ union_size = max(size, union_size);
+ }
+ total_align = max(align, total_align);
+
+ if (!prop) {
+ Py_DECREF(pair);
+ Py_DECREF((PyObject *)stgdict);
+ return -1;
+ }
+ if (-1 == PyDict_SetItem(realdict, name, prop)) {
+ Py_DECREF(prop);
+ Py_DECREF(pair);
+ Py_DECREF((PyObject *)stgdict);
+ return -1;
+ }
+ Py_DECREF(pair);
+ Py_DECREF(prop);
+ }
+#undef realdict
+ if (!isStruct)
+ size = union_size;
+
+ /* Adjust the size according to the alignment requirements */
+ size = ((size + total_align - 1) / total_align) * total_align;
+
+ stgdict->ffi_type_pointer.alignment = total_align;
+ stgdict->ffi_type_pointer.size = size;
+
+ stgdict->size = size;
+ stgdict->align = total_align;
+ stgdict->length = len; /* ADD ffi_ofs? */
+
+ /* We did check that this flag was NOT set above, it must not
+ have been set until now. */
+ if (stgdict->flags & DICTFLAG_FINAL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Structure or union cannot contain itself");
+ return -1;
+ }
+ stgdict->flags |= DICTFLAG_FINAL;
+
+ return MakeAnonFields(type);
+}
diff --git a/sys/src/cmd/python/Modules/_curses_panel.c b/sys/src/cmd/python/Modules/_curses_panel.c
new file mode 100644
index 000000000..0acf3fdee
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_curses_panel.c
@@ -0,0 +1,480 @@
+/*
+ * Interface to the ncurses panel library
+ *
+ * Original version by Thomas Gellekum
+ */
+
+/* Release Number */
+
+static char *PyCursesVersion = "2.1";
+
+/* Includes */
+
+#include "Python.h"
+
+#include "py_curses.h"
+
+#include <panel.h>
+
+static PyObject *PyCursesError;
+
+
+/* Utility Functions */
+
+/*
+ * Check the return code from a curses function and return None
+ * or raise an exception as appropriate.
+ */
+
+static PyObject *
+PyCursesCheckERR(int code, char *fname)
+{
+ if (code != ERR) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ if (fname == NULL) {
+ PyErr_SetString(PyCursesError, catchall_ERR);
+ } else {
+ PyErr_Format(PyCursesError, "%s() returned ERR", fname);
+ }
+ return NULL;
+ }
+}
+
+/*****************************************************************************
+ The Panel Object
+******************************************************************************/
+
+/* Definition of the panel object and panel type */
+
+typedef struct {
+ PyObject_HEAD
+ PANEL *pan;
+ PyCursesWindowObject *wo; /* for reference counts */
+} PyCursesPanelObject;
+
+PyTypeObject PyCursesPanel_Type;
+
+#define PyCursesPanel_Check(v) ((v)->ob_type == &PyCursesPanel_Type)
+
+/* Some helper functions. The problem is that there's always a window
+ associated with a panel. To ensure that Python's GC doesn't pull
+ this window from under our feet we need to keep track of references
+ to the corresponding window object within Python. We can't use
+ dupwin(oldwin) to keep a copy of the curses WINDOW because the
+ contents of oldwin is copied only once; code like
+
+ win = newwin(...)
+ pan = win.panel()
+ win.addstr(some_string)
+ pan.window().addstr(other_string)
+
+ will fail. */
+
+/* We keep a linked list of PyCursesPanelObjects, lop. A list should
+ suffice, I don't expect more than a handful or at most a few
+ dozens of panel objects within a typical program. */
+typedef struct _list_of_panels {
+ PyCursesPanelObject *po;
+ struct _list_of_panels *next;
+} list_of_panels;
+
+/* list anchor */
+static list_of_panels *lop;
+
+/* Insert a new panel object into lop */
+static int
+insert_lop(PyCursesPanelObject *po)
+{
+ list_of_panels *new;
+
+ if ((new = (list_of_panels *)malloc(sizeof(list_of_panels))) == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ new->po = po;
+ new->next = lop;
+ lop = new;
+ return 0;
+}
+
+/* Remove the panel object from lop */
+static void
+remove_lop(PyCursesPanelObject *po)
+{
+ list_of_panels *temp, *n;
+
+ temp = lop;
+ if (temp->po == po) {
+ lop = temp->next;
+ free(temp);
+ return;
+ }
+ while (temp->next == NULL || temp->next->po != po) {
+ if (temp->next == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "remove_lop: can't find Panel Object");
+ return;
+ }
+ temp = temp->next;
+ }
+ n = temp->next->next;
+ free(temp->next);
+ temp->next = n;
+ return;
+}
+
+/* Return the panel object that corresponds to pan */
+static PyCursesPanelObject *
+find_po(PANEL *pan)
+{
+ list_of_panels *temp;
+ for (temp = lop; temp->po->pan != pan; temp = temp->next)
+ if (temp->next == NULL) return NULL; /* not found!? */
+ return temp->po;
+}
+
+/* Function Prototype Macros - They are ugly but very, very useful. ;-)
+
+ X - function name
+ TYPE - parameter Type
+ ERGSTR - format string for construction of the return value
+ PARSESTR - format string for argument parsing */
+
+#define Panel_NoArgNoReturnFunction(X) \
+static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
+{ return PyCursesCheckERR(X(self->pan), # X); }
+
+#define Panel_NoArgTrueFalseFunction(X) \
+static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
+{ \
+ if (X (self->pan) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
+ else { Py_INCREF(Py_True); return Py_True; } }
+
+#define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
+static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \
+{ \
+ TYPE arg1, arg2; \
+ if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \
+ return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); }
+
+/* ------------- PANEL routines --------------- */
+
+Panel_NoArgNoReturnFunction(bottom_panel)
+Panel_NoArgNoReturnFunction(hide_panel)
+Panel_NoArgNoReturnFunction(show_panel)
+Panel_NoArgNoReturnFunction(top_panel)
+Panel_NoArgTrueFalseFunction(panel_hidden)
+Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x")
+
+/* Allocation and deallocation of Panel Objects */
+
+static PyObject *
+PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo)
+{
+ PyCursesPanelObject *po;
+
+ po = PyObject_NEW(PyCursesPanelObject, &PyCursesPanel_Type);
+ if (po == NULL) return NULL;
+ po->pan = pan;
+ po->wo = wo;
+ Py_INCREF(wo);
+ if (insert_lop(po) < 0) {
+ PyObject_DEL(po);
+ return NULL;
+ }
+ return (PyObject *)po;
+}
+
+static void
+PyCursesPanel_Dealloc(PyCursesPanelObject *po)
+{
+ (void)del_panel(po->pan);
+ Py_DECREF(po->wo);
+ remove_lop(po);
+ PyObject_DEL(po);
+}
+
+/* panel_above(NULL) returns the bottom panel in the stack. To get
+ this behaviour we use curses.panel.bottom_panel(). */
+static PyObject *
+PyCursesPanel_above(PyCursesPanelObject *self)
+{
+ PANEL *pan;
+ PyCursesPanelObject *po;
+
+ pan = panel_above(self->pan);
+
+ if (pan == NULL) { /* valid output, it means the calling panel
+ is on top of the stack */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ po = find_po(pan);
+ if (po == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "panel_above: can't find Panel Object");
+ return NULL;
+ }
+ Py_INCREF(po);
+ return (PyObject *)po;
+}
+
+/* panel_below(NULL) returns the top panel in the stack. To get
+ this behaviour we use curses.panel.top_panel(). */
+static PyObject *
+PyCursesPanel_below(PyCursesPanelObject *self)
+{
+ PANEL *pan;
+ PyCursesPanelObject *po;
+
+ pan = panel_below(self->pan);
+
+ if (pan == NULL) { /* valid output, it means the calling panel
+ is on the bottom of the stack */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ po = find_po(pan);
+ if (po == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "panel_below: can't find Panel Object");
+ return NULL;
+ }
+ Py_INCREF(po);
+ return (PyObject *)po;
+}
+
+static PyObject *
+PyCursesPanel_window(PyCursesPanelObject *self)
+{
+ Py_INCREF(self->wo);
+ return (PyObject *)self->wo;
+}
+
+static PyObject *
+PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
+{
+ PyCursesPanelObject *po;
+ PyCursesWindowObject *temp;
+ int rtn;
+
+ if (PyTuple_Size(args) != 1) {
+ PyErr_SetString(PyExc_TypeError, "replace requires one argument");
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(args, "O!;window object",
+ &PyCursesWindow_Type, &temp))
+ return NULL;
+
+ po = find_po(self->pan);
+ if (po == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "replace_panel: can't find Panel Object");
+ return NULL;
+ }
+
+ rtn = replace_panel(self->pan, temp->win);
+ if (rtn == ERR) {
+ PyErr_SetString(PyCursesError, "replace_panel() returned ERR");
+ return NULL;
+ }
+ Py_DECREF(po->wo);
+ po->wo = temp;
+ Py_INCREF(po->wo);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
+{
+ Py_INCREF(obj);
+ return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
+ "set_panel_userptr");
+}
+
+static PyObject *
+PyCursesPanel_userptr(PyCursesPanelObject *self)
+{
+ PyObject *obj;
+ PyCursesInitialised;
+ obj = (PyObject *) panel_userptr(self->pan);
+ if (obj == NULL) {
+ PyErr_SetString(PyCursesError, "no userptr set");
+ return NULL;
+ }
+
+ Py_INCREF(obj);
+ return obj;
+}
+
+
+/* Module interface */
+
+static PyMethodDef PyCursesPanel_Methods[] = {
+ {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS},
+ {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS},
+ {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS},
+ {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS},
+ {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS},
+ {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS},
+ {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS},
+ {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O},
+ {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS},
+ {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS},
+ {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS},
+ {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+PyCursesPanel_GetAttr(PyCursesPanelObject *self, char *name)
+{
+ return Py_FindMethod(PyCursesPanel_Methods, (PyObject *)self, name);
+}
+
+/* -------------------------------------------------------*/
+
+PyTypeObject PyCursesPanel_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_curses_panel.curses panel", /*tp_name*/
+ sizeof(PyCursesPanelObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyCursesPanel_Dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)PyCursesPanel_GetAttr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+/* Wrapper for panel_above(NULL). This function returns the bottom
+ panel of the stack, so it's renamed to bottom_panel().
+ panel.above() *requires* a panel object in the first place which
+ may be undesirable. */
+static PyObject *
+PyCurses_bottom_panel(PyObject *self)
+{
+ PANEL *pan;
+ PyCursesPanelObject *po;
+
+ PyCursesInitialised;
+
+ pan = panel_above(NULL);
+
+ if (pan == NULL) { /* valid output, it means
+ there's no panel at all */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ po = find_po(pan);
+ if (po == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "panel_above: can't find Panel Object");
+ return NULL;
+ }
+ Py_INCREF(po);
+ return (PyObject *)po;
+}
+
+static PyObject *
+PyCurses_new_panel(PyObject *self, PyObject *args)
+{
+ PyCursesWindowObject *win;
+ PANEL *pan;
+
+ if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win))
+ return NULL;
+ pan = new_panel(win->win);
+ if (pan == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+ return (PyObject *)PyCursesPanel_New(pan, win);
+}
+
+
+/* Wrapper for panel_below(NULL). This function returns the top panel
+ of the stack, so it's renamed to top_panel(). panel.below()
+ *requires* a panel object in the first place which may be
+ undesirable. */
+static PyObject *
+PyCurses_top_panel(PyObject *self)
+{
+ PANEL *pan;
+ PyCursesPanelObject *po;
+
+ PyCursesInitialised;
+
+ pan = panel_below(NULL);
+
+ if (pan == NULL) { /* valid output, it means
+ there's no panel at all */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ po = find_po(pan);
+ if (po == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "panel_below: can't find Panel Object");
+ return NULL;
+ }
+ Py_INCREF(po);
+ return (PyObject *)po;
+}
+
+static PyObject *PyCurses_update_panels(PyObject *self)
+{
+ PyCursesInitialised;
+ update_panels();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef PyCurses_methods[] = {
+ {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS},
+ {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS},
+ {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS},
+ {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+init_curses_panel(void)
+{
+ PyObject *m, *d, *v;
+
+ /* Initialize object type */
+ PyCursesPanel_Type.ob_type = &PyType_Type;
+
+ import_curses();
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("_curses_panel", PyCurses_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ /* For exception _curses_panel.error */
+ PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", PyCursesError);
+
+ /* Make the version available */
+ v = PyString_FromString(PyCursesVersion);
+ PyDict_SetItemString(d, "version", v);
+ PyDict_SetItemString(d, "__version__", v);
+ Py_DECREF(v);
+}
diff --git a/sys/src/cmd/python/Modules/_cursesmodule.c b/sys/src/cmd/python/Modules/_cursesmodule.c
new file mode 100644
index 000000000..c331353df
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_cursesmodule.c
@@ -0,0 +1,2760 @@
+/*
+ * This is a curses module for Python.
+ *
+ * Based on prior work by Lance Ellinghaus and Oliver Andrich
+ * Version 1.2 of this module: Copyright 1994 by Lance Ellinghouse,
+ * Cathedral City, California Republic, United States of America.
+ *
+ * Version 1.5b1, heavily extended for ncurses by Oliver Andrich:
+ * Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany.
+ *
+ * Tidied for Python 1.6, and currently maintained by <amk@amk.ca>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this source file to use, copy, modify, merge, or publish it
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or in any new file that contains a substantial portion of
+ * this file.
+ *
+ * THE AUTHOR MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF
+ * THE SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
+ * EXPRESS OR IMPLIED WARRANTY. THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, STRICT LIABILITY OR
+ * ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* CVS: $Id: _cursesmodule.c 54181 2007-03-06 20:46:26Z walter.doerwald $ */
+
+/*
+
+A number of SysV or ncurses functions don't have wrappers yet; if you need
+a given function, add it and send a patch. Here's a list of currently
+unsupported functions:
+
+ addchnstr addchstr chgat color_set define_key
+ del_curterm delscreen dupwin inchnstr inchstr innstr keyok
+ mcprint mvaddchnstr mvaddchstr mvchgat mvcur mvinchnstr
+ mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr mvwchgat
+ mvwinchnstr mvwinchstr mvwinnstr newterm
+ restartterm ripoffline scr_dump
+ scr_init scr_restore scr_set scrl set_curterm set_term setterm
+ tgetent tgetflag tgetnum tgetstr tgoto timeout tputs
+ vidattr vidputs waddchnstr waddchstr wchgat
+ wcolor_set winchnstr winchstr winnstr wmouse_trafo wscrl
+
+Low-priority:
+ slk_attr slk_attr_off slk_attr_on slk_attr_set slk_attroff
+ slk_attron slk_attrset slk_clear slk_color slk_init slk_label
+ slk_noutrefresh slk_refresh slk_restore slk_set slk_touch
+
+Menu extension (ncurses and probably SYSV):
+ current_item free_item free_menu item_count item_description
+ item_index item_init item_name item_opts item_opts_off
+ item_opts_on item_term item_userptr item_value item_visible
+ menu_back menu_driver menu_fore menu_format menu_grey
+ menu_init menu_items menu_mark menu_opts menu_opts_off
+ menu_opts_on menu_pad menu_pattern menu_request_by_name
+ menu_request_name menu_spacing menu_sub menu_term menu_userptr
+ menu_win new_item new_menu pos_menu_cursor post_menu
+ scale_menu set_current_item set_item_init set_item_opts
+ set_item_term set_item_userptr set_item_value set_menu_back
+ set_menu_fore set_menu_format set_menu_grey set_menu_init
+ set_menu_items set_menu_mark set_menu_opts set_menu_pad
+ set_menu_pattern set_menu_spacing set_menu_sub set_menu_term
+ set_menu_userptr set_menu_win set_top_row top_row unpost_menu
+
+Form extension (ncurses and probably SYSV):
+ current_field data_ahead data_behind dup_field
+ dynamic_fieldinfo field_arg field_back field_buffer
+ field_count field_fore field_index field_info field_init
+ field_just field_opts field_opts_off field_opts_on field_pad
+ field_status field_term field_type field_userptr form_driver
+ form_fields form_init form_opts form_opts_off form_opts_on
+ form_page form_request_by_name form_request_name form_sub
+ form_term form_userptr form_win free_field free_form
+ link_field link_fieldtype move_field new_field new_form
+ new_page pos_form_cursor post_form scale_form
+ set_current_field set_field_back set_field_buffer
+ set_field_fore set_field_init set_field_just set_field_opts
+ set_field_pad set_field_status set_field_term set_field_type
+ set_field_userptr set_fieldtype_arg set_fieldtype_choice
+ set_form_fields set_form_init set_form_opts set_form_page
+ set_form_sub set_form_term set_form_userptr set_form_win
+ set_max_field set_new_page unpost_form
+
+
+ */
+
+/* Release Number */
+
+char *PyCursesVersion = "2.2";
+
+/* Includes */
+
+#include "Python.h"
+
+#ifdef __osf__
+#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
+#endif
+
+#ifdef __hpux
+#define STRICT_SYSV_CURSES
+#endif
+
+#define CURSES_MODULE
+#include "py_curses.h"
+
+/* These prototypes are in <term.h>, but including this header
+ #defines many common symbols (such as "lines") which breaks the
+ curses module in other ways. So the code will just specify
+ explicit prototypes here. */
+extern int setupterm(char *,int,int *);
+#ifdef __sgi
+#include <term.h>
+#endif
+
+#if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5))
+#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
+typedef chtype attr_t; /* No attr_t type is available */
+#endif
+
+#if defined(_AIX)
+#define STRICT_SYSV_CURSES
+#endif
+
+/* Definition of exception curses.error */
+
+static PyObject *PyCursesError;
+
+/* Tells whether setupterm() has been called to initialise terminfo. */
+static int initialised_setupterm = FALSE;
+
+/* Tells whether initscr() has been called to initialise curses. */
+static int initialised = FALSE;
+
+/* Tells whether start_color() has been called to initialise color usage. */
+static int initialisedcolors = FALSE;
+
+/* Utility Macros */
+#define PyCursesSetupTermCalled \
+ if (initialised_setupterm != TRUE) { \
+ PyErr_SetString(PyCursesError, \
+ "must call (at least) setupterm() first"); \
+ return 0; }
+
+#define PyCursesInitialised \
+ if (initialised != TRUE) { \
+ PyErr_SetString(PyCursesError, \
+ "must call initscr() first"); \
+ return 0; }
+
+#define PyCursesInitialisedColor \
+ if (initialisedcolors != TRUE) { \
+ PyErr_SetString(PyCursesError, \
+ "must call start_color() first"); \
+ return 0; }
+
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+/* Utility Functions */
+
+/*
+ * Check the return code from a curses function and return None
+ * or raise an exception as appropriate. These are exported using the
+ * CObject API.
+ */
+
+static PyObject *
+PyCursesCheckERR(int code, char *fname)
+{
+ if (code != ERR) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ if (fname == NULL) {
+ PyErr_SetString(PyCursesError, catchall_ERR);
+ } else {
+ PyErr_Format(PyCursesError, "%s() returned ERR", fname);
+ }
+ return NULL;
+ }
+}
+
+static int
+PyCurses_ConvertToChtype(PyObject *obj, chtype *ch)
+{
+ if (PyInt_Check(obj)) {
+ *ch = (chtype) PyInt_AsLong(obj);
+ } else if(PyString_Check(obj)
+ && (PyString_Size(obj) == 1)) {
+ *ch = (chtype) *PyString_AsString(obj);
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
+/* Function versions of the 3 functions for tested whether curses has been
+ initialised or not. */
+
+static int func_PyCursesSetupTermCalled(void)
+{
+ PyCursesSetupTermCalled;
+ return 1;
+}
+
+static int func_PyCursesInitialised(void)
+{
+ PyCursesInitialised;
+ return 1;
+}
+
+static int func_PyCursesInitialisedColor(void)
+{
+ PyCursesInitialisedColor;
+ return 1;
+}
+
+/*****************************************************************************
+ The Window Object
+******************************************************************************/
+
+/* Definition of the window type */
+
+PyTypeObject PyCursesWindow_Type;
+
+/* Function prototype macros for Window object
+
+ X - function name
+ TYPE - parameter Type
+ ERGSTR - format string for construction of the return value
+ PARSESTR - format string for argument parsing
+ */
+
+#define Window_NoArgNoReturnFunction(X) \
+static PyObject *PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ return PyCursesCheckERR(X(self->win), # X); }
+
+#define Window_NoArgTrueFalseFunction(X) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self) \
+{ \
+ if (X (self->win) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
+ else { Py_INCREF(Py_True); return Py_True; } }
+
+#define Window_NoArgNoReturnVoidFunction(X) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self) \
+{ \
+ X(self->win); Py_INCREF(Py_None); return Py_None; }
+
+#define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self) \
+{ \
+ TYPE arg1, arg2; \
+ X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); }
+
+#define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ \
+ TYPE arg1; \
+ if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \
+ X(self->win,arg1); Py_INCREF(Py_None); return Py_None; }
+
+#define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ \
+ TYPE arg1; \
+ if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \
+ return PyCursesCheckERR(X(self->win, arg1), # X); }
+
+#define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
+static PyObject * PyCursesWindow_ ## X (PyCursesWindowObject *self, PyObject *args) \
+{ \
+ TYPE arg1, arg2; \
+ if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \
+ return PyCursesCheckERR(X(self->win, arg1, arg2), # X); }
+
+/* ------------- WINDOW routines --------------- */
+
+Window_NoArgNoReturnFunction(untouchwin)
+Window_NoArgNoReturnFunction(touchwin)
+Window_NoArgNoReturnFunction(redrawwin)
+Window_NoArgNoReturnFunction(winsertln)
+Window_NoArgNoReturnFunction(werase)
+Window_NoArgNoReturnFunction(wdeleteln)
+
+Window_NoArgTrueFalseFunction(is_wintouched)
+
+Window_NoArgNoReturnVoidFunction(wsyncup)
+Window_NoArgNoReturnVoidFunction(wsyncdown)
+Window_NoArgNoReturnVoidFunction(wstandend)
+Window_NoArgNoReturnVoidFunction(wstandout)
+Window_NoArgNoReturnVoidFunction(wcursyncup)
+Window_NoArgNoReturnVoidFunction(wclrtoeol)
+Window_NoArgNoReturnVoidFunction(wclrtobot)
+Window_NoArgNoReturnVoidFunction(wclear)
+
+Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
+
+Window_NoArg2TupleReturnFunction(getyx, int, "ii")
+Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
+Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
+Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
+
+Window_OneArgNoReturnFunction(wattron, attr_t, "l;attr")
+Window_OneArgNoReturnFunction(wattroff, attr_t, "l;attr")
+Window_OneArgNoReturnFunction(wattrset, attr_t, "l;attr")
+Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
+#if defined(__NetBSD__)
+Window_OneArgNoReturnVoidFunction(keypad, int, "i;True(1) or False(0)")
+#else
+Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
+#endif
+Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
+#if defined(__NetBSD__)
+Window_OneArgNoReturnVoidFunction(nodelay, int, "i;True(1) or False(0)")
+#else
+Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
+#endif
+Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
+Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
+Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
+
+Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
+Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
+Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x")
+#ifndef STRICT_SYSV_CURSES
+Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns")
+#endif
+
+/* Allocation and deallocation of Window Objects */
+
+static PyObject *
+PyCursesWindow_New(WINDOW *win)
+{
+ PyCursesWindowObject *wo;
+
+ wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
+ if (wo == NULL) return NULL;
+ wo->win = win;
+ return (PyObject *)wo;
+}
+
+static void
+PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
+{
+ if (wo->win != stdscr) delwin(wo->win);
+ PyObject_DEL(wo);
+}
+
+/* Addch, Addstr, Addnstr */
+
+static PyObject *
+PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn, x, y, use_xy = FALSE;
+ PyObject *temp;
+ chtype ch = 0;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr))
+ return NULL;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr",
+ &y, &x, &temp, &attr))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "addch requires 1 to 4 arguments");
+ return NULL;
+ }
+
+ if (!PyCurses_ConvertToChtype(temp, &ch)) {
+ PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
+ return NULL;
+ }
+
+ if (use_xy == TRUE)
+ rtn = mvwaddch(self->win,y,x, ch | attr);
+ else {
+ rtn = waddch(self->win, ch | attr);
+ }
+ return PyCursesCheckERR(rtn, "addch");
+}
+
+static PyObject *
+PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn;
+ int x, y;
+ char *str;
+ attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+ int use_xy = FALSE, use_attr = FALSE;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args,"s;str", &str))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr))
+ return NULL;
+ use_attr = TRUE;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"iis;int,int,str", &y, &x, &str))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &attr))
+ return NULL;
+ use_xy = use_attr = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments");
+ return NULL;
+ }
+
+ if (use_attr == TRUE) {
+ attr_old = getattrs(self->win);
+ wattrset(self->win,attr);
+ }
+ if (use_xy == TRUE)
+ rtn = mvwaddstr(self->win,y,x,str);
+ else
+ rtn = waddstr(self->win,str);
+ if (use_attr == TRUE)
+ wattrset(self->win,attr_old);
+ return PyCursesCheckERR(rtn, "addstr");
+}
+
+static PyObject *
+PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn, x, y, n;
+ char *str;
+ attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+ int use_xy = FALSE, use_attr = FALSE;
+
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args,"si;str,n", &str, &n))
+ return NULL;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr))
+ return NULL;
+ use_attr = TRUE;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args,"iisi;y,x,str,n", &y, &x, &str, &n))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ case 5:
+ if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr))
+ return NULL;
+ use_xy = use_attr = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments");
+ return NULL;
+ }
+
+ if (use_attr == TRUE) {
+ attr_old = getattrs(self->win);
+ wattrset(self->win,attr);
+ }
+ if (use_xy == TRUE)
+ rtn = mvwaddnstr(self->win,y,x,str,n);
+ else
+ rtn = waddnstr(self->win,str,n);
+ if (use_attr == TRUE)
+ wattrset(self->win,attr_old);
+ return PyCursesCheckERR(rtn, "addnstr");
+}
+
+static PyObject *
+PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp;
+ chtype bkgd;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments");
+ return NULL;
+ }
+
+ if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
+ PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
+ return NULL;
+ }
+
+ return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
+}
+
+static PyObject *
+PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp;
+ chtype bkgd;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments");
+ return NULL;
+ }
+
+ if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
+ PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
+ return NULL;
+ }
+
+ wbkgdset(self->win, bkgd | attr);
+ return PyCursesCheckERR(0, "bkgdset");
+}
+
+static PyObject *
+PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp[8];
+ chtype ch[8];
+ int i;
+
+ /* Clear the array of parameters */
+ for(i=0; i<8; i++) {
+ temp[i] = NULL;
+ ch[i] = 0;
+ }
+
+ if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br",
+ &temp[0], &temp[1], &temp[2], &temp[3],
+ &temp[4], &temp[5], &temp[6], &temp[7]))
+ return NULL;
+
+ for(i=0; i<8; i++) {
+ if (temp[i] != NULL && !PyCurses_ConvertToChtype(temp[i], &ch[i])) {
+ PyErr_Format(PyExc_TypeError,
+ "argument %i must be a ch or an int", i+1);
+ return NULL;
+ }
+ }
+
+ wborder(self->win,
+ ch[0], ch[1], ch[2], ch[3],
+ ch[4], ch[5], ch[6], ch[7]);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
+{
+ chtype ch1=0,ch2=0;
+ switch(PyTuple_Size(args)){
+ case 0: break;
+ default:
+ if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
+ return NULL;
+ }
+ box(self->win,ch1,ch2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION)
+#define py_mvwdelch mvwdelch
+#else
+int py_mvwdelch(WINDOW *w, int y, int x)
+{
+ mvwdelch(w,y,x);
+ /* On HP/UX, mvwdelch already returns. On other systems,
+ we may well run into this return statement. */
+ return 0;
+}
+#endif
+
+
+static PyObject *
+PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn;
+ int x, y;
+
+ switch (PyTuple_Size(args)) {
+ case 0:
+ rtn = wdelch(self->win);
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
+ return NULL;
+ rtn = py_mvwdelch(self->win,y,x);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments");
+ return NULL;
+ }
+ return PyCursesCheckERR(rtn, "[mv]wdelch");
+}
+
+static PyObject *
+PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args)
+{
+ WINDOW *win;
+ int nlines, ncols, begin_y, begin_x;
+
+ nlines = 0;
+ ncols = 0;
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
+ return NULL;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
+ &nlines,&ncols,&begin_y,&begin_x))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments");
+ return NULL;
+ }
+
+ win = derwin(self->win,nlines,ncols,begin_y,begin_x);
+
+ if (win == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+
+ return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp;
+ chtype ch;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args,"O;ch or int", &temp))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments");
+
+
+ return NULL;
+ }
+
+ if (!PyCurses_ConvertToChtype(temp, &ch)) {
+ PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
+ return NULL;
+ }
+
+#ifdef WINDOW_HAS_FLAGS
+ if (self->win->_flags & _ISPAD)
+ return PyCursesCheckERR(pechochar(self->win, ch | attr),
+ "echochar");
+ else
+#endif
+ return PyCursesCheckERR(wechochar(self->win, ch | attr),
+ "echochar");
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static PyObject *
+PyCursesWindow_Enclose(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y;
+ if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
+ return NULL;
+
+ return PyInt_FromLong( wenclose(self->win,y,x) );
+}
+#endif
+
+static PyObject *
+PyCursesWindow_GetBkgd(PyCursesWindowObject *self)
+{
+ return PyInt_FromLong((long) getbkgd(self->win));
+}
+
+static PyObject *
+PyCursesWindow_GetCh(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y;
+ int rtn;
+
+ switch (PyTuple_Size(args)) {
+ case 0:
+ Py_BEGIN_ALLOW_THREADS
+ rtn = wgetch(self->win);
+ Py_END_ALLOW_THREADS
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rtn = mvwgetch(self->win,y,x);
+ Py_END_ALLOW_THREADS
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments");
+ return NULL;
+ }
+ return PyInt_FromLong((long)rtn);
+}
+
+static PyObject *
+PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y;
+ int rtn;
+
+ switch (PyTuple_Size(args)) {
+ case 0:
+ Py_BEGIN_ALLOW_THREADS
+ rtn = wgetch(self->win);
+ Py_END_ALLOW_THREADS
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rtn = mvwgetch(self->win,y,x);
+ Py_END_ALLOW_THREADS
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "getkey requires 0 or 2 arguments");
+ return NULL;
+ }
+ if (rtn == ERR) {
+ /* getch() returns ERR in nodelay mode */
+ PyErr_SetString(PyCursesError, "no input");
+ return NULL;
+ } else if (rtn<=255)
+ return Py_BuildValue("c", rtn);
+ else
+#if defined(__NetBSD__)
+ return PyString_FromString(unctrl(rtn));
+#else
+ return PyString_FromString((char *)keyname(rtn));
+#endif
+}
+
+static PyObject *
+PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y, n;
+ char rtn[1024]; /* This should be big enough.. I hope */
+ int rtn2;
+
+ switch (PyTuple_Size(args)) {
+ case 0:
+ Py_BEGIN_ALLOW_THREADS
+ rtn2 = wgetnstr(self->win,rtn, 1023);
+ Py_END_ALLOW_THREADS
+ break;
+ case 1:
+ if (!PyArg_ParseTuple(args,"i;n", &n))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rtn2 = wgetnstr(self->win,rtn,MIN(n, 1023));
+ Py_END_ALLOW_THREADS
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+#ifdef STRICT_SYSV_CURSES
+ rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023);
+#else
+ rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
+#endif
+ Py_END_ALLOW_THREADS
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n))
+ return NULL;
+#ifdef STRICT_SYSV_CURSES
+ Py_BEGIN_ALLOW_THREADS
+ rtn2 = wmove(self->win,y,x)==ERR ? ERR :
+ wgetnstr(self->win, rtn, MIN(n, 1023));
+ Py_END_ALLOW_THREADS
+#else
+ Py_BEGIN_ALLOW_THREADS
+ rtn2 = mvwgetnstr(self->win, y, x, rtn, MIN(n, 1023));
+ Py_END_ALLOW_THREADS
+#endif
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments");
+ return NULL;
+ }
+ if (rtn2 == ERR)
+ rtn[0] = 0;
+ return PyString_FromString(rtn);
+}
+
+static PyObject *
+PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp;
+ chtype ch;
+ int n, x, y, code = OK;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
+ return NULL;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr))
+ return NULL;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
+ return NULL;
+ code = wmove(self->win, y, x);
+ break;
+ case 5:
+ if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr",
+ &y, &x, &temp, &n, &attr))
+ return NULL;
+ code = wmove(self->win, y, x);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments");
+ return NULL;
+ }
+
+ if (code != ERR) {
+ if (!PyCurses_ConvertToChtype(temp, &ch)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument 1 or 3 must be a ch or an int");
+ return NULL;
+ }
+ return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline");
+ } else
+ return PyCursesCheckERR(code, "wmove");
+}
+
+static PyObject *
+PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn, x, y, use_xy = FALSE;
+ PyObject *temp;
+ chtype ch = 0;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr))
+ return NULL;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &attr))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "insch requires 1 or 4 arguments");
+ return NULL;
+ }
+
+ if (!PyCurses_ConvertToChtype(temp, &ch)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument 1 or 3 must be a ch or an int");
+ return NULL;
+ }
+
+ if (use_xy == TRUE)
+ rtn = mvwinsch(self->win,y,x, ch | attr);
+ else {
+ rtn = winsch(self->win, ch | attr);
+ }
+ return PyCursesCheckERR(rtn, "insch");
+}
+
+static PyObject *
+PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y, rtn;
+
+ switch (PyTuple_Size(args)) {
+ case 0:
+ rtn = winch(self->win);
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+ return NULL;
+ rtn = mvwinch(self->win,y,x);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "inch requires 0 or 2 arguments");
+ return NULL;
+ }
+ return PyInt_FromLong((long) rtn);
+}
+
+static PyObject *
+PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y, n;
+ char rtn[1024]; /* This should be big enough.. I hope */
+ int rtn2;
+
+ switch (PyTuple_Size(args)) {
+ case 0:
+ rtn2 = winnstr(self->win,rtn, 1023);
+ break;
+ case 1:
+ if (!PyArg_ParseTuple(args,"i;n", &n))
+ return NULL;
+ rtn2 = winnstr(self->win,rtn,MIN(n,1023));
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
+ return NULL;
+ rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
+ return NULL;
+ rtn2 = mvwinnstr(self->win, y, x, rtn, MIN(n,1023));
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
+ return NULL;
+ }
+ if (rtn2 == ERR)
+ rtn[0] = 0;
+ return PyString_FromString(rtn);
+}
+
+static PyObject *
+PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn;
+ int x, y;
+ char *str;
+ attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+ int use_xy = FALSE, use_attr = FALSE;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args,"s;str", &str))
+ return NULL;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr))
+ return NULL;
+ use_attr = TRUE;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"iis;y,x,str", &y, &x, &str))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &attr))
+ return NULL;
+ use_xy = use_attr = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments");
+ return NULL;
+ }
+
+ if (use_attr == TRUE) {
+ attr_old = getattrs(self->win);
+ wattrset(self->win,attr);
+ }
+ if (use_xy == TRUE)
+ rtn = mvwinsstr(self->win,y,x,str);
+ else
+ rtn = winsstr(self->win,str);
+ if (use_attr == TRUE)
+ wattrset(self->win,attr_old);
+ return PyCursesCheckERR(rtn, "insstr");
+}
+
+static PyObject *
+PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
+{
+ int rtn, x, y, n;
+ char *str;
+ attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+ int use_xy = FALSE, use_attr = FALSE;
+
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args,"si;str,n", &str, &n))
+ return NULL;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr))
+ return NULL;
+ use_attr = TRUE;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args,"iisi;y,x,str,n", &y, &x, &str, &n))
+ return NULL;
+ use_xy = TRUE;
+ break;
+ case 5:
+ if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr))
+ return NULL;
+ use_xy = use_attr = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments");
+ return NULL;
+ }
+
+ if (use_attr == TRUE) {
+ attr_old = getattrs(self->win);
+ wattrset(self->win,attr);
+ }
+ if (use_xy == TRUE)
+ rtn = mvwinsnstr(self->win,y,x,str,n);
+ else
+ rtn = winsnstr(self->win,str,n);
+ if (use_attr == TRUE)
+ wattrset(self->win,attr_old);
+ return PyCursesCheckERR(rtn, "insnstr");
+}
+
+static PyObject *
+PyCursesWindow_Is_LineTouched(PyCursesWindowObject *self, PyObject *args)
+{
+ int line, erg;
+ if (!PyArg_ParseTuple(args,"i;line", &line))
+ return NULL;
+ erg = is_linetouched(self->win, line);
+ if (erg == ERR) {
+ PyErr_SetString(PyExc_TypeError,
+ "is_linetouched: line number outside of boundaries");
+ return NULL;
+ } else
+ if (erg == FALSE) {
+ Py_INCREF(Py_False);
+ return Py_False;
+ } else {
+ Py_INCREF(Py_True);
+ return Py_True;
+ }
+}
+
+static PyObject *
+PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
+{
+ int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
+ int rtn;
+
+#ifndef WINDOW_HAS_FLAGS
+ if (0) {
+#else
+ if (self->win->_flags & _ISPAD) {
+#endif
+ switch(PyTuple_Size(args)) {
+ case 6:
+ if (!PyArg_ParseTuple(args,
+ "iiiiii;" \
+ "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol",
+ &pminrow, &pmincol, &sminrow,
+ &smincol, &smaxrow, &smaxcol))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rtn = pnoutrefresh(self->win,
+ pminrow, pmincol, sminrow,
+ smincol, smaxrow, smaxcol);
+ Py_END_ALLOW_THREADS
+ return PyCursesCheckERR(rtn, "pnoutrefresh");
+ default:
+ PyErr_SetString(PyCursesError,
+ "noutrefresh() called for a pad "
+ "requires 6 arguments");
+ return NULL;
+ }
+ } else {
+ if (!PyArg_ParseTuple(args, ":noutrefresh"))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ rtn = wnoutrefresh(self->win);
+ Py_END_ALLOW_THREADS
+ return PyCursesCheckERR(rtn, "wnoutrefresh");
+ }
+}
+
+static PyObject *
+PyCursesWindow_Overlay(PyCursesWindowObject *self, PyObject *args)
+{
+ PyCursesWindowObject *temp;
+ int use_copywin = FALSE;
+ int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
+ int rtn;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O!;window object",
+ &PyCursesWindow_Type, &temp))
+ return NULL;
+ break;
+ case 7:
+ if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
+ &PyCursesWindow_Type, &temp, &sminrow, &smincol,
+ &dminrow, &dmincol, &dmaxrow, &dmaxcol))
+ return NULL;
+ use_copywin = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError,
+ "overlay requires one or seven arguments");
+ return NULL;
+ }
+
+ if (use_copywin == TRUE) {
+ rtn = copywin(self->win, temp->win, sminrow, smincol,
+ dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
+ return PyCursesCheckERR(rtn, "copywin");
+ }
+ else {
+ rtn = overlay(self->win, temp->win);
+ return PyCursesCheckERR(rtn, "overlay");
+ }
+}
+
+static PyObject *
+PyCursesWindow_Overwrite(PyCursesWindowObject *self, PyObject *args)
+{
+ PyCursesWindowObject *temp;
+ int use_copywin = FALSE;
+ int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
+ int rtn;
+
+ switch (PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O!;window object",
+ &PyCursesWindow_Type, &temp))
+ return NULL;
+ break;
+ case 7:
+ if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
+ &PyCursesWindow_Type, &temp, &sminrow, &smincol,
+ &dminrow, &dmincol, &dmaxrow, &dmaxcol))
+ return NULL;
+ use_copywin = TRUE;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError,
+ "overwrite requires one or seven arguments");
+ return NULL;
+ }
+
+ if (use_copywin == TRUE) {
+ rtn = copywin(self->win, temp->win, sminrow, smincol,
+ dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
+ return PyCursesCheckERR(rtn, "copywin");
+ }
+ else {
+ rtn = overwrite(self->win, temp->win);
+ return PyCursesCheckERR(rtn, "overwrite");
+ }
+}
+
+static PyObject *
+PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp;
+
+ if (!PyArg_ParseTuple(args, "O;fileobj", &temp))
+ return NULL;
+ if (!PyFile_Check(temp)) {
+ PyErr_SetString(PyExc_TypeError, "argument must be a file object");
+ return NULL;
+ }
+ return PyCursesCheckERR(putwin(self->win, PyFile_AsFile(temp)),
+ "putwin");
+}
+
+static PyObject *
+PyCursesWindow_RedrawLine(PyCursesWindowObject *self, PyObject *args)
+{
+ int beg, num;
+ if (!PyArg_ParseTuple(args,"ii;beg,num", &beg, &num))
+ return NULL;
+ return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
+}
+
+static PyObject *
+PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
+{
+ int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
+ int rtn;
+
+#ifndef WINDOW_HAS_FLAGS
+ if (0) {
+#else
+ if (self->win->_flags & _ISPAD) {
+#endif
+ switch(PyTuple_Size(args)) {
+ case 6:
+ if (!PyArg_ParseTuple(args,
+ "iiiiii;" \
+ "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol",
+ &pminrow, &pmincol, &sminrow,
+ &smincol, &smaxrow, &smaxcol))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ rtn = prefresh(self->win,
+ pminrow, pmincol, sminrow,
+ smincol, smaxrow, smaxcol);
+ Py_END_ALLOW_THREADS
+ return PyCursesCheckERR(rtn, "prefresh");
+ default:
+ PyErr_SetString(PyCursesError,
+ "refresh() for a pad requires 6 arguments");
+ return NULL;
+ }
+ } else {
+ if (!PyArg_ParseTuple(args, ":refresh"))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rtn = wrefresh(self->win);
+ Py_END_ALLOW_THREADS
+ return PyCursesCheckERR(rtn, "prefresh");
+ }
+}
+
+static PyObject *
+PyCursesWindow_SetScrollRegion(PyCursesWindowObject *self, PyObject *args)
+{
+ int x, y;
+ if (!PyArg_ParseTuple(args,"ii;top, bottom",&y,&x))
+ return NULL;
+ return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg");
+}
+
+static PyObject *
+PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
+{
+ WINDOW *win;
+ int nlines, ncols, begin_y, begin_x;
+
+ nlines = 0;
+ ncols = 0;
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
+ return NULL;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
+ &nlines,&ncols,&begin_y,&begin_x))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "subwin requires 2 or 4 arguments");
+ return NULL;
+ }
+
+ /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */
+#ifdef WINDOW_HAS_FLAGS
+ if (self->win->_flags & _ISPAD)
+ win = subpad(self->win, nlines, ncols, begin_y, begin_x);
+ else
+#endif
+ win = subwin(self->win, nlines, ncols, begin_y, begin_x);
+
+ if (win == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+
+ return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCursesWindow_Scroll(PyCursesWindowObject *self, PyObject *args)
+{
+ int nlines;
+ switch(PyTuple_Size(args)) {
+ case 0:
+ return PyCursesCheckERR(scroll(self->win), "scroll");
+ case 1:
+ if (!PyArg_ParseTuple(args, "i;nlines", &nlines))
+ return NULL;
+ return PyCursesCheckERR(wscrl(self->win, nlines), "scroll");
+ default:
+ PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments");
+ return NULL;
+ }
+}
+
+static PyObject *
+PyCursesWindow_TouchLine(PyCursesWindowObject *self, PyObject *args)
+{
+ int st, cnt, val;
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;start,count",&st,&cnt))
+ return NULL;
+ return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline");
+ case 3:
+ if (!PyArg_ParseTuple(args, "iii;start,count,val", &st, &cnt, &val))
+ return NULL;
+ return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline");
+ default:
+ PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments");
+ return NULL;
+ }
+}
+
+static PyObject *
+PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
+{
+ PyObject *temp;
+ chtype ch;
+ int n, x, y, code = OK;
+ attr_t attr = A_NORMAL;
+
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
+ return NULL;
+ break;
+ case 3:
+ if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr))
+ return NULL;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
+ return NULL;
+ code = wmove(self->win, y, x);
+ break;
+ case 5:
+ if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr",
+ &y, &x, &temp, &n, &attr))
+ return NULL;
+ code = wmove(self->win, y, x);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments");
+ return NULL;
+ }
+
+ if (code != ERR) {
+ if (!PyCurses_ConvertToChtype(temp, &ch)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument 1 or 3 must be a ch or an int");
+ return NULL;
+ }
+ return PyCursesCheckERR(wvline(self->win, ch | attr, n), "vline");
+ } else
+ return PyCursesCheckERR(code, "wmove");
+}
+
+static PyMethodDef PyCursesWindow_Methods[] = {
+ {"addch", (PyCFunction)PyCursesWindow_AddCh, METH_VARARGS},
+ {"addnstr", (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS},
+ {"addstr", (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS},
+ {"attroff", (PyCFunction)PyCursesWindow_wattroff, METH_VARARGS},
+ {"attron", (PyCFunction)PyCursesWindow_wattron, METH_VARARGS},
+ {"attrset", (PyCFunction)PyCursesWindow_wattrset, METH_VARARGS},
+ {"bkgd", (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS},
+ {"bkgdset", (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS},
+ {"border", (PyCFunction)PyCursesWindow_Border, METH_VARARGS},
+ {"box", (PyCFunction)PyCursesWindow_Box, METH_VARARGS},
+ {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS},
+ {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS},
+ {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS},
+ {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS},
+ {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS},
+ {"delch", (PyCFunction)PyCursesWindow_DelCh, METH_VARARGS},
+ {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS},
+ {"derwin", (PyCFunction)PyCursesWindow_DerWin, METH_VARARGS},
+ {"echochar", (PyCFunction)PyCursesWindow_EchoChar, METH_VARARGS},
+#ifdef NCURSES_MOUSE_VERSION
+ {"enclose", (PyCFunction)PyCursesWindow_Enclose, METH_VARARGS},
+#endif
+ {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS},
+ {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
+ {"getbkgd", (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS},
+ {"getch", (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS},
+ {"getkey", (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS},
+ {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
+ {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
+ {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
+ {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS},
+ {"hline", (PyCFunction)PyCursesWindow_Hline, METH_VARARGS},
+ {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS},
+ {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS},
+ {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
+ {"inch", (PyCFunction)PyCursesWindow_InCh, METH_VARARGS},
+ {"insch", (PyCFunction)PyCursesWindow_InsCh, METH_VARARGS},
+ {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
+ {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
+ {"insnstr", (PyCFunction)PyCursesWindow_InsNStr, METH_VARARGS},
+ {"insstr", (PyCFunction)PyCursesWindow_InsStr, METH_VARARGS},
+ {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS},
+ {"is_linetouched", (PyCFunction)PyCursesWindow_Is_LineTouched, METH_VARARGS},
+ {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS},
+ {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS},
+ {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS},
+ {"move", (PyCFunction)PyCursesWindow_wmove, METH_VARARGS},
+ {"mvderwin", (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS},
+ {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS},
+ {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS},
+ {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS},
+ {"noutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
+ /* Backward compatibility alias -- remove in Python 2.3 */
+ {"nooutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
+ {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS},
+ {"overwrite", (PyCFunction)PyCursesWindow_Overwrite,
+ METH_VARARGS},
+ {"putwin", (PyCFunction)PyCursesWindow_PutWin, METH_VARARGS},
+ {"redrawln", (PyCFunction)PyCursesWindow_RedrawLine},
+ {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS},
+ {"refresh", (PyCFunction)PyCursesWindow_Refresh, METH_VARARGS},
+#ifndef STRICT_SYSV_CURSES
+ {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS},
+#endif
+ {"scroll", (PyCFunction)PyCursesWindow_Scroll, METH_VARARGS},
+ {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS},
+ {"setscrreg", (PyCFunction)PyCursesWindow_SetScrollRegion, METH_VARARGS},
+ {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS},
+ {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS},
+ {"subpad", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
+ {"subwin", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
+ {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS},
+ {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS},
+ {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS},
+ {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS},
+ {"touchline", (PyCFunction)PyCursesWindow_TouchLine, METH_VARARGS},
+ {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS},
+ {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS},
+ {"vline", (PyCFunction)PyCursesWindow_Vline, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+PyCursesWindow_GetAttr(PyCursesWindowObject *self, char *name)
+{
+ return Py_FindMethod(PyCursesWindow_Methods, (PyObject *)self, name);
+}
+
+/* -------------------------------------------------------*/
+
+PyTypeObject PyCursesWindow_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_curses.curses window", /*tp_name*/
+ sizeof(PyCursesWindowObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)PyCursesWindow_GetAttr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+/*********************************************************************
+ Global Functions
+**********************************************************************/
+
+NoArgNoReturnFunction(beep)
+NoArgNoReturnFunction(def_prog_mode)
+NoArgNoReturnFunction(def_shell_mode)
+NoArgNoReturnFunction(doupdate)
+NoArgNoReturnFunction(endwin)
+NoArgNoReturnFunction(flash)
+NoArgNoReturnFunction(nocbreak)
+NoArgNoReturnFunction(noecho)
+NoArgNoReturnFunction(nonl)
+NoArgNoReturnFunction(noraw)
+NoArgNoReturnFunction(reset_prog_mode)
+NoArgNoReturnFunction(reset_shell_mode)
+NoArgNoReturnFunction(resetty)
+NoArgNoReturnFunction(savetty)
+
+NoArgOrFlagNoReturnFunction(cbreak)
+NoArgOrFlagNoReturnFunction(echo)
+NoArgOrFlagNoReturnFunction(nl)
+NoArgOrFlagNoReturnFunction(raw)
+
+NoArgReturnIntFunction(baudrate)
+NoArgReturnIntFunction(termattrs)
+
+NoArgReturnStringFunction(termname)
+NoArgReturnStringFunction(longname)
+
+NoArgTrueFalseFunction(can_change_color)
+NoArgTrueFalseFunction(has_colors)
+NoArgTrueFalseFunction(has_ic)
+NoArgTrueFalseFunction(has_il)
+NoArgTrueFalseFunction(isendwin)
+NoArgNoReturnVoidFunction(filter)
+NoArgNoReturnVoidFunction(flushinp)
+NoArgNoReturnVoidFunction(noqiflush)
+
+static PyObject *
+PyCurses_Color_Content(PyObject *self, PyObject *args)
+{
+ short color,r,g,b;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ if (!PyArg_ParseTuple(args, "h:color_content", &color)) return NULL;
+
+ if (color_content(color, &r, &g, &b) != ERR)
+ return Py_BuildValue("(iii)", r, g, b);
+ else {
+ PyErr_SetString(PyCursesError,
+ "Argument 1 was out of range. Check value of COLORS.");
+ return NULL;
+ }
+}
+
+static PyObject *
+PyCurses_color_pair(PyObject *self, PyObject *args)
+{
+ int n;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL;
+ return PyInt_FromLong((long) (n << 8));
+}
+
+static PyObject *
+PyCurses_Curs_Set(PyObject *self, PyObject *args)
+{
+ int vis,erg;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args, "i:curs_set", &vis)) return NULL;
+
+ erg = curs_set(vis);
+ if (erg == ERR) return PyCursesCheckERR(erg, "curs_set");
+
+ return PyInt_FromLong((long) erg);
+}
+
+static PyObject *
+PyCurses_Delay_Output(PyObject *self, PyObject *args)
+{
+ int ms;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args, "i:delay_output", &ms)) return NULL;
+
+ return PyCursesCheckERR(delay_output(ms), "delay_output");
+}
+
+static PyObject *
+PyCurses_EraseChar(PyObject *self)
+{
+ char ch;
+
+ PyCursesInitialised
+
+ ch = erasechar();
+
+ return PyString_FromStringAndSize(&ch, 1);
+}
+
+static PyObject *
+PyCurses_getsyx(PyObject *self)
+{
+ int x,y;
+
+ PyCursesInitialised
+
+ getsyx(y, x);
+
+ return Py_BuildValue("(ii)", y, x);
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static PyObject *
+PyCurses_GetMouse(PyObject *self)
+{
+ int rtn;
+ MEVENT event;
+
+ PyCursesInitialised
+
+ rtn = getmouse( &event );
+ if (rtn == ERR) {
+ PyErr_SetString(PyCursesError, "getmouse() returned ERR");
+ return NULL;
+ }
+ return Py_BuildValue("(hiiil)",
+ (short)event.id,
+ event.x, event.y, event.z,
+ (long) event.bstate);
+}
+
+static PyObject *
+PyCurses_UngetMouse(PyObject *self, PyObject *args)
+{
+ MEVENT event;
+
+ PyCursesInitialised
+ if (!PyArg_ParseTuple(args, "hiiil",
+ &event.id,
+ &event.x, &event.y, &event.z,
+ (int *) &event.bstate))
+ return NULL;
+
+ return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
+}
+#endif
+
+static PyObject *
+PyCurses_GetWin(PyCursesWindowObject *self, PyObject *temp)
+{
+ WINDOW *win;
+
+ PyCursesInitialised
+
+ if (!PyFile_Check(temp)) {
+ PyErr_SetString(PyExc_TypeError, "argument must be a file object");
+ return NULL;
+ }
+
+ win = getwin(PyFile_AsFile(temp));
+
+ if (win == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+
+ return PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_HalfDelay(PyObject *self, PyObject *args)
+{
+ unsigned char tenths;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args, "b:halfdelay", &tenths)) return NULL;
+
+ return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
+}
+
+#ifndef STRICT_SYSV_CURSES
+ /* No has_key! */
+static PyObject * PyCurses_has_key(PyObject *self, PyObject *args)
+{
+ int ch;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
+
+ if (has_key(ch) == FALSE) {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ Py_INCREF(Py_True);
+ return Py_True;
+}
+#endif /* STRICT_SYSV_CURSES */
+
+static PyObject *
+PyCurses_Init_Color(PyObject *self, PyObject *args)
+{
+ short color, r, g, b;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ switch(PyTuple_Size(args)) {
+ case 4:
+ if (!PyArg_ParseTuple(args, "hhhh;color,r,g,b", &color, &r, &g, &b)) return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "init_color requires 4 arguments");
+ return NULL;
+ }
+
+ return PyCursesCheckERR(init_color(color, r, g, b), "init_color");
+}
+
+static PyObject *
+PyCurses_Init_Pair(PyObject *self, PyObject *args)
+{
+ short pair, f, b;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ if (PyTuple_Size(args) != 3) {
+ PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "hhh;pair, f, b", &pair, &f, &b)) return NULL;
+
+ return PyCursesCheckERR(init_pair(pair, f, b), "init_pair");
+}
+
+static PyObject *ModDict;
+
+static PyObject *
+PyCurses_InitScr(PyObject *self)
+{
+ WINDOW *win;
+
+ if (initialised == TRUE) {
+ wrefresh(stdscr);
+ return (PyObject *)PyCursesWindow_New(stdscr);
+ }
+
+ win = initscr();
+
+ if (win == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+
+ initialised = initialised_setupterm = TRUE;
+
+/* This was moved from initcurses() because it core dumped on SGI,
+ where they're not defined until you've called initscr() */
+#define SetDictInt(string,ch) \
+ do { \
+ PyObject *o = PyInt_FromLong((long) (ch)); \
+ if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \
+ Py_DECREF(o); \
+ } \
+ } while (0)
+
+ /* Here are some graphic symbols you can use */
+ SetDictInt("ACS_ULCORNER", (ACS_ULCORNER));
+ SetDictInt("ACS_LLCORNER", (ACS_LLCORNER));
+ SetDictInt("ACS_URCORNER", (ACS_URCORNER));
+ SetDictInt("ACS_LRCORNER", (ACS_LRCORNER));
+ SetDictInt("ACS_LTEE", (ACS_LTEE));
+ SetDictInt("ACS_RTEE", (ACS_RTEE));
+ SetDictInt("ACS_BTEE", (ACS_BTEE));
+ SetDictInt("ACS_TTEE", (ACS_TTEE));
+ SetDictInt("ACS_HLINE", (ACS_HLINE));
+ SetDictInt("ACS_VLINE", (ACS_VLINE));
+ SetDictInt("ACS_PLUS", (ACS_PLUS));
+#if !defined(__hpux) || defined(HAVE_NCURSES_H)
+ /* On HP/UX 11, these are of type cchar_t, which is not an
+ integral type. If this is a problem on more platforms, a
+ configure test should be added to determine whether ACS_S1
+ is of integral type. */
+ SetDictInt("ACS_S1", (ACS_S1));
+ SetDictInt("ACS_S9", (ACS_S9));
+ SetDictInt("ACS_DIAMOND", (ACS_DIAMOND));
+ SetDictInt("ACS_CKBOARD", (ACS_CKBOARD));
+ SetDictInt("ACS_DEGREE", (ACS_DEGREE));
+ SetDictInt("ACS_PLMINUS", (ACS_PLMINUS));
+ SetDictInt("ACS_BULLET", (ACS_BULLET));
+ SetDictInt("ACS_LARROW", (ACS_LARROW));
+ SetDictInt("ACS_RARROW", (ACS_RARROW));
+ SetDictInt("ACS_DARROW", (ACS_DARROW));
+ SetDictInt("ACS_UARROW", (ACS_UARROW));
+ SetDictInt("ACS_BOARD", (ACS_BOARD));
+ SetDictInt("ACS_LANTERN", (ACS_LANTERN));
+ SetDictInt("ACS_BLOCK", (ACS_BLOCK));
+#endif
+ SetDictInt("ACS_BSSB", (ACS_ULCORNER));
+ SetDictInt("ACS_SSBB", (ACS_LLCORNER));
+ SetDictInt("ACS_BBSS", (ACS_URCORNER));
+ SetDictInt("ACS_SBBS", (ACS_LRCORNER));
+ SetDictInt("ACS_SBSS", (ACS_RTEE));
+ SetDictInt("ACS_SSSB", (ACS_LTEE));
+ SetDictInt("ACS_SSBS", (ACS_BTEE));
+ SetDictInt("ACS_BSSS", (ACS_TTEE));
+ SetDictInt("ACS_BSBS", (ACS_HLINE));
+ SetDictInt("ACS_SBSB", (ACS_VLINE));
+ SetDictInt("ACS_SSSS", (ACS_PLUS));
+
+ /* The following are never available with strict SYSV curses */
+#ifdef ACS_S3
+ SetDictInt("ACS_S3", (ACS_S3));
+#endif
+#ifdef ACS_S7
+ SetDictInt("ACS_S7", (ACS_S7));
+#endif
+#ifdef ACS_LEQUAL
+ SetDictInt("ACS_LEQUAL", (ACS_LEQUAL));
+#endif
+#ifdef ACS_GEQUAL
+ SetDictInt("ACS_GEQUAL", (ACS_GEQUAL));
+#endif
+#ifdef ACS_PI
+ SetDictInt("ACS_PI", (ACS_PI));
+#endif
+#ifdef ACS_NEQUAL
+ SetDictInt("ACS_NEQUAL", (ACS_NEQUAL));
+#endif
+#ifdef ACS_STERLING
+ SetDictInt("ACS_STERLING", (ACS_STERLING));
+#endif
+
+ SetDictInt("LINES", LINES);
+ SetDictInt("COLS", COLS);
+
+ return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds)
+{
+ int fd = -1;
+ int err;
+ char* termstr = NULL;
+
+ static char *kwlist[] = {"term", "fd", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, keywds, "|zi:setupterm", kwlist, &termstr, &fd)) {
+ return NULL;
+ }
+
+ if (fd == -1) {
+ PyObject* sys_stdout;
+
+ sys_stdout = PySys_GetObject("stdout");
+
+ if (sys_stdout == NULL) {
+ PyErr_SetString(
+ PyCursesError,
+ "lost sys.stdout");
+ return NULL;
+ }
+
+ fd = PyObject_AsFileDescriptor(sys_stdout);
+
+ if (fd == -1) {
+ return NULL;
+ }
+ }
+
+ if (setupterm(termstr,fd,&err) == ERR) {
+ char* s = "setupterm: unknown error";
+
+ if (err == 0) {
+ s = "setupterm: could not find terminal";
+ } else if (err == -1) {
+ s = "setupterm: could not find terminfo database";
+ }
+
+ PyErr_SetString(PyCursesError,s);
+ return NULL;
+ }
+
+ initialised_setupterm = TRUE;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+PyCurses_IntrFlush(PyObject *self, PyObject *args)
+{
+ int ch;
+
+ PyCursesInitialised
+
+ switch(PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "intrflush requires 1 argument");
+ return NULL;
+ }
+
+ return PyCursesCheckERR(intrflush(NULL,ch), "intrflush");
+}
+
+#ifdef HAVE_CURSES_IS_TERM_RESIZED
+static PyObject *
+PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
+{
+ int lines;
+ int columns;
+ int result;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
+ return NULL;
+ result = is_term_resized(lines, columns);
+ if (result == TRUE) {
+ Py_INCREF(Py_True);
+ return Py_True;
+ } else {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+}
+#endif /* HAVE_CURSES_IS_TERM_RESIZED */
+
+#if !defined(__NetBSD__)
+static PyObject *
+PyCurses_KeyName(PyObject *self, PyObject *args)
+{
+ const char *knp;
+ int ch;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
+
+ if (ch < 0) {
+ PyErr_SetString(PyExc_ValueError, "invalid key number");
+ return NULL;
+ }
+ knp = keyname(ch);
+
+ return PyString_FromString((knp == NULL) ? "" : (char *)knp);
+}
+#endif
+
+static PyObject *
+PyCurses_KillChar(PyObject *self)
+{
+ char ch;
+
+ ch = killchar();
+
+ return PyString_FromStringAndSize(&ch, 1);
+}
+
+static PyObject *
+PyCurses_Meta(PyObject *self, PyObject *args)
+{
+ int ch;
+
+ PyCursesInitialised
+
+ switch(PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "meta requires 1 argument");
+ return NULL;
+ }
+
+ return PyCursesCheckERR(meta(stdscr, ch), "meta");
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static PyObject *
+PyCurses_MouseInterval(PyObject *self, PyObject *args)
+{
+ int interval;
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"i;interval",&interval))
+ return NULL;
+ return PyCursesCheckERR(mouseinterval(interval), "mouseinterval");
+}
+
+static PyObject *
+PyCurses_MouseMask(PyObject *self, PyObject *args)
+{
+ int newmask;
+ mmask_t oldmask, availmask;
+
+ PyCursesInitialised
+ if (!PyArg_ParseTuple(args,"i;mousemask",&newmask))
+ return NULL;
+ availmask = mousemask(newmask, &oldmask);
+ return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
+}
+#endif
+
+static PyObject *
+PyCurses_Napms(PyObject *self, PyObject *args)
+{
+ int ms;
+
+ PyCursesInitialised
+ if (!PyArg_ParseTuple(args, "i;ms", &ms)) return NULL;
+
+ return Py_BuildValue("i", napms(ms));
+}
+
+
+static PyObject *
+PyCurses_NewPad(PyObject *self, PyObject *args)
+{
+ WINDOW *win;
+ int nlines, ncols;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) return NULL;
+
+ win = newpad(nlines, ncols);
+
+ if (win == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+
+ return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_NewWindow(PyObject *self, PyObject *args)
+{
+ WINDOW *win;
+ int nlines, ncols, begin_y=0, begin_x=0;
+
+ PyCursesInitialised
+
+ switch (PyTuple_Size(args)) {
+ case 2:
+ if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols))
+ return NULL;
+ break;
+ case 4:
+ if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
+ &nlines,&ncols,&begin_y,&begin_x))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments");
+ return NULL;
+ }
+
+ win = newwin(nlines,ncols,begin_y,begin_x);
+ if (win == NULL) {
+ PyErr_SetString(PyCursesError, catchall_NULL);
+ return NULL;
+ }
+
+ return (PyObject *)PyCursesWindow_New(win);
+}
+
+static PyObject *
+PyCurses_Pair_Content(PyObject *self, PyObject *args)
+{
+ short pair,f,b;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ switch(PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "h;pair", &pair)) return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "pair_content requires 1 argument");
+ return NULL;
+ }
+
+ if (pair_content(pair, &f, &b)==ERR) {
+ PyErr_SetString(PyCursesError,
+ "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
+ return NULL;
+ }
+
+ return Py_BuildValue("(ii)", f, b);
+}
+
+static PyObject *
+PyCurses_pair_number(PyObject *self, PyObject *args)
+{
+ int n;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ switch(PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "i;pairvalue", &n)) return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError,
+ "pair_number requires 1 argument");
+ return NULL;
+ }
+
+ return PyInt_FromLong((long) ((n & A_COLOR) >> 8));
+}
+
+static PyObject *
+PyCurses_Putp(PyObject *self, PyObject *args)
+{
+ char *str;
+
+ if (!PyArg_ParseTuple(args,"s;str", &str)) return NULL;
+ return PyCursesCheckERR(putp(str), "putp");
+}
+
+static PyObject *
+PyCurses_QiFlush(PyObject *self, PyObject *args)
+{
+ int flag = 0;
+
+ PyCursesInitialised
+
+ switch(PyTuple_Size(args)) {
+ case 0:
+ qiflush();
+ Py_INCREF(Py_None);
+ return Py_None;
+ case 1:
+ if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL;
+ if (flag) qiflush();
+ else noqiflush();
+ Py_INCREF(Py_None);
+ return Py_None;
+ default:
+ PyErr_SetString(PyExc_TypeError, "qiflush requires 0 or 1 arguments");
+ return NULL;
+ }
+}
+
+/* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
+ * and _curses.COLS */
+static int
+update_lines_cols(void)
+{
+ PyObject *o;
+ PyObject *m = PyImport_ImportModule("curses");
+
+ if (!m)
+ return 0;
+
+ o = PyInt_FromLong(LINES);
+ if (!o) {
+ Py_DECREF(m);
+ return 0;
+ }
+ if (PyObject_SetAttrString(m, "LINES", o)) {
+ Py_DECREF(m);
+ Py_DECREF(o);
+ return 0;
+ }
+ if (PyDict_SetItemString(ModDict, "LINES", o)) {
+ Py_DECREF(m);
+ Py_DECREF(o);
+ return 0;
+ }
+ Py_DECREF(o);
+ o = PyInt_FromLong(COLS);
+ if (!o) {
+ Py_DECREF(m);
+ return 0;
+ }
+ if (PyObject_SetAttrString(m, "COLS", o)) {
+ Py_DECREF(m);
+ Py_DECREF(o);
+ return 0;
+ }
+ if (PyDict_SetItemString(ModDict, "COLS", o)) {
+ Py_DECREF(m);
+ Py_DECREF(o);
+ return 0;
+ }
+ Py_DECREF(o);
+ Py_DECREF(m);
+ return 1;
+}
+
+#ifdef HAVE_CURSES_RESIZETERM
+static PyObject *
+PyCurses_ResizeTerm(PyObject *self, PyObject *args)
+{
+ int lines;
+ int columns;
+ PyObject *result;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns))
+ return NULL;
+
+ result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm");
+ if (!result)
+ return NULL;
+ if (!update_lines_cols())
+ return NULL;
+ return result;
+}
+
+#endif
+
+#ifdef HAVE_CURSES_RESIZE_TERM
+static PyObject *
+PyCurses_Resize_Term(PyObject *self, PyObject *args)
+{
+ int lines;
+ int columns;
+
+ PyObject *result;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns))
+ return NULL;
+
+ result = PyCursesCheckERR(resize_term(lines, columns), "resize_term");
+ if (!result)
+ return NULL;
+ if (!update_lines_cols())
+ return NULL;
+ return result;
+}
+#endif /* HAVE_CURSES_RESIZE_TERM */
+
+static PyObject *
+PyCurses_setsyx(PyObject *self, PyObject *args)
+{
+ int y,x;
+
+ PyCursesInitialised
+
+ if (PyTuple_Size(args)!=2) {
+ PyErr_SetString(PyExc_TypeError, "setsyx requires 2 arguments");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "ii;y, x", &y, &x)) return NULL;
+
+ setsyx(y,x);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+PyCurses_Start_Color(PyObject *self)
+{
+ int code;
+ PyObject *c, *cp;
+
+ PyCursesInitialised
+
+ code = start_color();
+ if (code != ERR) {
+ initialisedcolors = TRUE;
+ c = PyInt_FromLong((long) COLORS);
+ PyDict_SetItemString(ModDict, "COLORS", c);
+ Py_DECREF(c);
+ cp = PyInt_FromLong((long) COLOR_PAIRS);
+ PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp);
+ Py_DECREF(cp);
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ PyErr_SetString(PyCursesError, "start_color() returned ERR");
+ return NULL;
+ }
+}
+
+static PyObject *
+PyCurses_tigetflag(PyObject *self, PyObject *args)
+{
+ char *capname;
+
+ PyCursesSetupTermCalled;
+
+ if (!PyArg_ParseTuple(args, "z", &capname))
+ return NULL;
+
+ return PyInt_FromLong( (long) tigetflag( capname ) );
+}
+
+static PyObject *
+PyCurses_tigetnum(PyObject *self, PyObject *args)
+{
+ char *capname;
+
+ PyCursesSetupTermCalled;
+
+ if (!PyArg_ParseTuple(args, "z", &capname))
+ return NULL;
+
+ return PyInt_FromLong( (long) tigetnum( capname ) );
+}
+
+static PyObject *
+PyCurses_tigetstr(PyObject *self, PyObject *args)
+{
+ char *capname;
+
+ PyCursesSetupTermCalled;
+
+ if (!PyArg_ParseTuple(args, "z", &capname))
+ return NULL;
+
+ capname = tigetstr( capname );
+ if (capname == 0 || capname == (char*) -1) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString( capname );
+}
+
+static PyObject *
+PyCurses_tparm(PyObject *self, PyObject *args)
+{
+ char* fmt;
+ char* result = NULL;
+ int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0;
+
+ PyCursesSetupTermCalled;
+
+ if (!PyArg_ParseTuple(args, "s|iiiiiiiii:tparm",
+ &fmt, &i1, &i2, &i3, &i4,
+ &i5, &i6, &i7, &i8, &i9)) {
+ return NULL;
+ }
+
+ result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9);
+ if (!result) {
+ PyErr_SetString(PyCursesError, "tparm() returned NULL");
+ return NULL;
+ }
+
+ return PyString_FromString(result);
+}
+
+static PyObject *
+PyCurses_TypeAhead(PyObject *self, PyObject *args)
+{
+ int fd;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"i;fd",&fd)) return NULL;
+
+ return PyCursesCheckERR(typeahead( fd ), "typeahead");
+}
+
+static PyObject *
+PyCurses_UnCtrl(PyObject *self, PyObject *args)
+{
+ PyObject *temp;
+ chtype ch;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
+
+ if (PyInt_Check(temp))
+ ch = (chtype) PyInt_AsLong(temp);
+ else if (PyString_Check(temp))
+ ch = (chtype) *PyString_AsString(temp);
+ else {
+ PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
+ return NULL;
+ }
+
+ return PyString_FromString(unctrl(ch));
+}
+
+static PyObject *
+PyCurses_UngetCh(PyObject *self, PyObject *args)
+{
+ PyObject *temp;
+ int ch;
+
+ PyCursesInitialised
+
+ if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
+
+ if (PyInt_Check(temp))
+ ch = (int) PyInt_AsLong(temp);
+ else if (PyString_Check(temp))
+ ch = (int) *PyString_AsString(temp);
+ else {
+ PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
+ return NULL;
+ }
+
+ return PyCursesCheckERR(ungetch(ch), "ungetch");
+}
+
+static PyObject *
+PyCurses_Use_Env(PyObject *self, PyObject *args)
+{
+ int flag;
+
+ PyCursesInitialised
+
+ switch(PyTuple_Size(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&flag))
+ return NULL;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument");
+ return NULL;
+ }
+ use_env(flag);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifndef STRICT_SYSV_CURSES
+static PyObject *
+PyCurses_Use_Default_Colors(PyObject *self)
+{
+ int code;
+
+ PyCursesInitialised
+ PyCursesInitialisedColor
+
+ code = use_default_colors();
+ if (code != ERR) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ PyErr_SetString(PyCursesError, "use_default_colors() returned ERR");
+ return NULL;
+ }
+}
+#endif /* STRICT_SYSV_CURSES */
+
+/* List of functions defined in the module */
+
+static PyMethodDef PyCurses_methods[] = {
+ {"baudrate", (PyCFunction)PyCurses_baudrate, METH_NOARGS},
+ {"beep", (PyCFunction)PyCurses_beep, METH_NOARGS},
+ {"can_change_color", (PyCFunction)PyCurses_can_change_color, METH_NOARGS},
+ {"cbreak", (PyCFunction)PyCurses_cbreak, METH_VARARGS},
+ {"color_content", (PyCFunction)PyCurses_Color_Content, METH_VARARGS},
+ {"color_pair", (PyCFunction)PyCurses_color_pair, METH_VARARGS},
+ {"curs_set", (PyCFunction)PyCurses_Curs_Set, METH_VARARGS},
+ {"def_prog_mode", (PyCFunction)PyCurses_def_prog_mode, METH_NOARGS},
+ {"def_shell_mode", (PyCFunction)PyCurses_def_shell_mode, METH_NOARGS},
+ {"delay_output", (PyCFunction)PyCurses_Delay_Output, METH_VARARGS},
+ {"doupdate", (PyCFunction)PyCurses_doupdate, METH_NOARGS},
+ {"echo", (PyCFunction)PyCurses_echo, METH_VARARGS},
+ {"endwin", (PyCFunction)PyCurses_endwin, METH_NOARGS},
+ {"erasechar", (PyCFunction)PyCurses_EraseChar, METH_NOARGS},
+ {"filter", (PyCFunction)PyCurses_filter, METH_NOARGS},
+ {"flash", (PyCFunction)PyCurses_flash, METH_NOARGS},
+ {"flushinp", (PyCFunction)PyCurses_flushinp, METH_NOARGS},
+#ifdef NCURSES_MOUSE_VERSION
+ {"getmouse", (PyCFunction)PyCurses_GetMouse, METH_NOARGS},
+ {"ungetmouse", (PyCFunction)PyCurses_UngetMouse, METH_VARARGS},
+#endif
+ {"getsyx", (PyCFunction)PyCurses_getsyx, METH_NOARGS},
+ {"getwin", (PyCFunction)PyCurses_GetWin, METH_O},
+ {"has_colors", (PyCFunction)PyCurses_has_colors, METH_NOARGS},
+ {"has_ic", (PyCFunction)PyCurses_has_ic, METH_NOARGS},
+ {"has_il", (PyCFunction)PyCurses_has_il, METH_NOARGS},
+#ifndef STRICT_SYSV_CURSES
+ {"has_key", (PyCFunction)PyCurses_has_key, METH_VARARGS},
+#endif
+ {"halfdelay", (PyCFunction)PyCurses_HalfDelay, METH_VARARGS},
+ {"init_color", (PyCFunction)PyCurses_Init_Color, METH_VARARGS},
+ {"init_pair", (PyCFunction)PyCurses_Init_Pair, METH_VARARGS},
+ {"initscr", (PyCFunction)PyCurses_InitScr, METH_NOARGS},
+ {"intrflush", (PyCFunction)PyCurses_IntrFlush, METH_VARARGS},
+ {"isendwin", (PyCFunction)PyCurses_isendwin, METH_NOARGS},
+#ifdef HAVE_CURSES_IS_TERM_RESIZED
+ {"is_term_resized", (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS},
+#endif
+#if !defined(__NetBSD__)
+ {"keyname", (PyCFunction)PyCurses_KeyName, METH_VARARGS},
+#endif
+ {"killchar", (PyCFunction)PyCurses_KillChar, METH_NOARGS},
+ {"longname", (PyCFunction)PyCurses_longname, METH_NOARGS},
+ {"meta", (PyCFunction)PyCurses_Meta, METH_VARARGS},
+#ifdef NCURSES_MOUSE_VERSION
+ {"mouseinterval", (PyCFunction)PyCurses_MouseInterval, METH_VARARGS},
+ {"mousemask", (PyCFunction)PyCurses_MouseMask, METH_VARARGS},
+#endif
+ {"napms", (PyCFunction)PyCurses_Napms, METH_VARARGS},
+ {"newpad", (PyCFunction)PyCurses_NewPad, METH_VARARGS},
+ {"newwin", (PyCFunction)PyCurses_NewWindow, METH_VARARGS},
+ {"nl", (PyCFunction)PyCurses_nl, METH_VARARGS},
+ {"nocbreak", (PyCFunction)PyCurses_nocbreak, METH_NOARGS},
+ {"noecho", (PyCFunction)PyCurses_noecho, METH_NOARGS},
+ {"nonl", (PyCFunction)PyCurses_nonl, METH_NOARGS},
+ {"noqiflush", (PyCFunction)PyCurses_noqiflush, METH_NOARGS},
+ {"noraw", (PyCFunction)PyCurses_noraw, METH_NOARGS},
+ {"pair_content", (PyCFunction)PyCurses_Pair_Content, METH_VARARGS},
+ {"pair_number", (PyCFunction)PyCurses_pair_number, METH_VARARGS},
+ {"putp", (PyCFunction)PyCurses_Putp, METH_VARARGS},
+ {"qiflush", (PyCFunction)PyCurses_QiFlush, METH_VARARGS},
+ {"raw", (PyCFunction)PyCurses_raw, METH_VARARGS},
+ {"reset_prog_mode", (PyCFunction)PyCurses_reset_prog_mode, METH_NOARGS},
+ {"reset_shell_mode", (PyCFunction)PyCurses_reset_shell_mode, METH_NOARGS},
+ {"resetty", (PyCFunction)PyCurses_resetty, METH_NOARGS},
+#ifdef HAVE_CURSES_RESIZETERM
+ {"resizeterm", (PyCFunction)PyCurses_ResizeTerm, METH_VARARGS},
+#endif
+#ifdef HAVE_CURSES_RESIZE_TERM
+ {"resize_term", (PyCFunction)PyCurses_Resize_Term, METH_VARARGS},
+#endif
+ {"savetty", (PyCFunction)PyCurses_savetty, METH_NOARGS},
+ {"setsyx", (PyCFunction)PyCurses_setsyx, METH_VARARGS},
+ {"setupterm", (PyCFunction)PyCurses_setupterm,
+ METH_VARARGS|METH_KEYWORDS},
+ {"start_color", (PyCFunction)PyCurses_Start_Color, METH_NOARGS},
+ {"termattrs", (PyCFunction)PyCurses_termattrs, METH_NOARGS},
+ {"termname", (PyCFunction)PyCurses_termname, METH_NOARGS},
+ {"tigetflag", (PyCFunction)PyCurses_tigetflag, METH_VARARGS},
+ {"tigetnum", (PyCFunction)PyCurses_tigetnum, METH_VARARGS},
+ {"tigetstr", (PyCFunction)PyCurses_tigetstr, METH_VARARGS},
+ {"tparm", (PyCFunction)PyCurses_tparm, METH_VARARGS},
+ {"typeahead", (PyCFunction)PyCurses_TypeAhead, METH_VARARGS},
+ {"unctrl", (PyCFunction)PyCurses_UnCtrl, METH_VARARGS},
+ {"ungetch", (PyCFunction)PyCurses_UngetCh, METH_VARARGS},
+ {"use_env", (PyCFunction)PyCurses_Use_Env, METH_VARARGS},
+#ifndef STRICT_SYSV_CURSES
+ {"use_default_colors", (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+init_curses(void)
+{
+ PyObject *m, *d, *v, *c_api_object;
+ static void *PyCurses_API[PyCurses_API_pointers];
+
+ /* Initialize object type */
+ PyCursesWindow_Type.ob_type = &PyType_Type;
+
+ /* Initialize the C API pointer array */
+ PyCurses_API[0] = (void *)&PyCursesWindow_Type;
+ PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
+ PyCurses_API[2] = (void *)func_PyCursesInitialised;
+ PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("_curses", PyCurses_methods);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ if (d == NULL)
+ return;
+ ModDict = d; /* For PyCurses_InitScr to use later */
+
+ /* Add a CObject for the C API */
+ c_api_object = PyCObject_FromVoidPtr((void *)PyCurses_API, NULL);
+ PyDict_SetItemString(d, "_C_API", c_api_object);
+ Py_DECREF(c_api_object);
+
+ /* For exception curses.error */
+ PyCursesError = PyErr_NewException("_curses.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", PyCursesError);
+
+ /* Make the version available */
+ v = PyString_FromString(PyCursesVersion);
+ PyDict_SetItemString(d, "version", v);
+ PyDict_SetItemString(d, "__version__", v);
+ Py_DECREF(v);
+
+ SetDictInt("ERR", ERR);
+ SetDictInt("OK", OK);
+
+ /* Here are some attributes you can add to chars to print */
+
+ SetDictInt("A_ATTRIBUTES", A_ATTRIBUTES);
+ SetDictInt("A_NORMAL", A_NORMAL);
+ SetDictInt("A_STANDOUT", A_STANDOUT);
+ SetDictInt("A_UNDERLINE", A_UNDERLINE);
+ SetDictInt("A_REVERSE", A_REVERSE);
+ SetDictInt("A_BLINK", A_BLINK);
+ SetDictInt("A_DIM", A_DIM);
+ SetDictInt("A_BOLD", A_BOLD);
+ SetDictInt("A_ALTCHARSET", A_ALTCHARSET);
+#if !defined(__NetBSD__)
+ SetDictInt("A_INVIS", A_INVIS);
+#endif
+ SetDictInt("A_PROTECT", A_PROTECT);
+ SetDictInt("A_CHARTEXT", A_CHARTEXT);
+ SetDictInt("A_COLOR", A_COLOR);
+
+ /* The following are never available with strict SYSV curses */
+#ifdef A_HORIZONTAL
+ SetDictInt("A_HORIZONTAL", A_HORIZONTAL);
+#endif
+#ifdef A_LEFT
+ SetDictInt("A_LEFT", A_LEFT);
+#endif
+#ifdef A_LOW
+ SetDictInt("A_LOW", A_LOW);
+#endif
+#ifdef A_RIGHT
+ SetDictInt("A_RIGHT", A_RIGHT);
+#endif
+#ifdef A_TOP
+ SetDictInt("A_TOP", A_TOP);
+#endif
+#ifdef A_VERTICAL
+ SetDictInt("A_VERTICAL", A_VERTICAL);
+#endif
+
+ SetDictInt("COLOR_BLACK", COLOR_BLACK);
+ SetDictInt("COLOR_RED", COLOR_RED);
+ SetDictInt("COLOR_GREEN", COLOR_GREEN);
+ SetDictInt("COLOR_YELLOW", COLOR_YELLOW);
+ SetDictInt("COLOR_BLUE", COLOR_BLUE);
+ SetDictInt("COLOR_MAGENTA", COLOR_MAGENTA);
+ SetDictInt("COLOR_CYAN", COLOR_CYAN);
+ SetDictInt("COLOR_WHITE", COLOR_WHITE);
+
+#ifdef NCURSES_MOUSE_VERSION
+ /* Mouse-related constants */
+ SetDictInt("BUTTON1_PRESSED", BUTTON1_PRESSED);
+ SetDictInt("BUTTON1_RELEASED", BUTTON1_RELEASED);
+ SetDictInt("BUTTON1_CLICKED", BUTTON1_CLICKED);
+ SetDictInt("BUTTON1_DOUBLE_CLICKED", BUTTON1_DOUBLE_CLICKED);
+ SetDictInt("BUTTON1_TRIPLE_CLICKED", BUTTON1_TRIPLE_CLICKED);
+
+ SetDictInt("BUTTON2_PRESSED", BUTTON2_PRESSED);
+ SetDictInt("BUTTON2_RELEASED", BUTTON2_RELEASED);
+ SetDictInt("BUTTON2_CLICKED", BUTTON2_CLICKED);
+ SetDictInt("BUTTON2_DOUBLE_CLICKED", BUTTON2_DOUBLE_CLICKED);
+ SetDictInt("BUTTON2_TRIPLE_CLICKED", BUTTON2_TRIPLE_CLICKED);
+
+ SetDictInt("BUTTON3_PRESSED", BUTTON3_PRESSED);
+ SetDictInt("BUTTON3_RELEASED", BUTTON3_RELEASED);
+ SetDictInt("BUTTON3_CLICKED", BUTTON3_CLICKED);
+ SetDictInt("BUTTON3_DOUBLE_CLICKED", BUTTON3_DOUBLE_CLICKED);
+ SetDictInt("BUTTON3_TRIPLE_CLICKED", BUTTON3_TRIPLE_CLICKED);
+
+ SetDictInt("BUTTON4_PRESSED", BUTTON4_PRESSED);
+ SetDictInt("BUTTON4_RELEASED", BUTTON4_RELEASED);
+ SetDictInt("BUTTON4_CLICKED", BUTTON4_CLICKED);
+ SetDictInt("BUTTON4_DOUBLE_CLICKED", BUTTON4_DOUBLE_CLICKED);
+ SetDictInt("BUTTON4_TRIPLE_CLICKED", BUTTON4_TRIPLE_CLICKED);
+
+ SetDictInt("BUTTON_SHIFT", BUTTON_SHIFT);
+ SetDictInt("BUTTON_CTRL", BUTTON_CTRL);
+ SetDictInt("BUTTON_ALT", BUTTON_ALT);
+
+ SetDictInt("ALL_MOUSE_EVENTS", ALL_MOUSE_EVENTS);
+ SetDictInt("REPORT_MOUSE_POSITION", REPORT_MOUSE_POSITION);
+#endif
+ /* Now set everything up for KEY_ variables */
+ {
+ int key;
+ char *key_n;
+ char *key_n2;
+#if !defined(__NetBSD__)
+ for (key=KEY_MIN;key < KEY_MAX; key++) {
+ key_n = (char *)keyname(key);
+ if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
+ continue;
+ if (strncmp(key_n,"KEY_F(",6)==0) {
+ char *p1, *p2;
+ key_n2 = malloc(strlen(key_n)+1);
+ if (!key_n2) {
+ PyErr_NoMemory();
+ break;
+ }
+ p1 = key_n;
+ p2 = key_n2;
+ while (*p1) {
+ if (*p1 != '(' && *p1 != ')') {
+ *p2 = *p1;
+ p2++;
+ }
+ p1++;
+ }
+ *p2 = (char)0;
+ } else
+ key_n2 = key_n;
+ SetDictInt(key_n2,key);
+ if (key_n2 != key_n)
+ free(key_n2);
+ }
+#endif
+ SetDictInt("KEY_MIN", KEY_MIN);
+ SetDictInt("KEY_MAX", KEY_MAX);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_elementtree.c b/sys/src/cmd/python/Modules/_elementtree.c
new file mode 100644
index 000000000..f21cf5685
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_elementtree.c
@@ -0,0 +1,2815 @@
+/*
+ * ElementTree
+ * $Id: _elementtree.c 2657 2006-03-12 20:50:32Z fredrik $
+ *
+ * elementtree accelerator
+ *
+ * History:
+ * 1999-06-20 fl created (as part of sgmlop)
+ * 2001-05-29 fl effdom edition
+ * 2001-06-05 fl backported to unix; fixed bogus free in clear
+ * 2001-07-10 fl added findall helper
+ * 2003-02-27 fl elementtree edition (alpha)
+ * 2004-06-03 fl updates for elementtree 1.2
+ * 2005-01-05 fl added universal name cache, Element/SubElement factories
+ * 2005-01-06 fl moved python helpers into C module; removed 1.5.2 support
+ * 2005-01-07 fl added 2.1 support; work around broken __copy__ in 2.3
+ * 2005-01-08 fl added makeelement method; fixed path support
+ * 2005-01-10 fl optimized memory usage
+ * 2005-01-11 fl first public release (cElementTree 0.8)
+ * 2005-01-12 fl split element object into base and extras
+ * 2005-01-13 fl use tagged pointers for tail/text (cElementTree 0.9)
+ * 2005-01-17 fl added treebuilder close method
+ * 2005-01-17 fl fixed crash in getchildren
+ * 2005-01-18 fl removed observer api, added iterparse (cElementTree 0.9.3)
+ * 2005-01-23 fl revised iterparse api; added namespace event support (0.9.8)
+ * 2005-01-26 fl added VERSION module property (cElementTree 1.0)
+ * 2005-01-28 fl added remove method (1.0.1)
+ * 2005-03-01 fl added iselement function; fixed makeelement aliasing (1.0.2)
+ * 2005-03-13 fl export Comment and ProcessingInstruction/PI helpers
+ * 2005-03-26 fl added Comment and PI support to XMLParser
+ * 2005-03-27 fl event optimizations; complain about bogus events
+ * 2005-08-08 fl fixed read error handling in parse
+ * 2005-08-11 fl added runtime test for copy workaround (1.0.3)
+ * 2005-12-13 fl added expat_capi support (for xml.etree) (1.0.4)
+ * 2005-12-16 fl added support for non-standard encodings
+ * 2006-03-08 fl fixed a couple of potential null-refs and leaks
+ * 2006-03-12 fl merge in 2.5 ssize_t changes
+ *
+ * Copyright (c) 1999-2006 by Secret Labs AB. All rights reserved.
+ * Copyright (c) 1999-2006 by Fredrik Lundh.
+ *
+ * info@pythonware.com
+ * http://www.pythonware.com
+ */
+
+/* Licensed to PSF under a Contributor Agreement. */
+/* See http://www.python.org/2.4/license for licensing details. */
+
+#include "Python.h"
+
+#define VERSION "1.0.6"
+
+/* -------------------------------------------------------------------- */
+/* configuration */
+
+/* Leave defined to include the expat-based XMLParser type */
+#define USE_EXPAT
+
+/* Define to to all expat calls via pyexpat's embedded expat library */
+/* #define USE_PYEXPAT_CAPI */
+
+/* An element can hold this many children without extra memory
+ allocations. */
+#define STATIC_CHILDREN 4
+
+/* For best performance, chose a value so that 80-90% of all nodes
+ have no more than the given number of children. Set this to zero
+ to minimize the size of the element structure itself (this only
+ helps if you have lots of leaf nodes with attributes). */
+
+/* Also note that pymalloc always allocates blocks in multiples of
+ eight bytes. For the current version of cElementTree, this means
+ that the number of children should be an even number, at least on
+ 32-bit platforms. */
+
+/* -------------------------------------------------------------------- */
+
+#if 0
+static int memory = 0;
+#define ALLOC(size, comment)\
+do { memory += size; printf("%8d - %s\n", memory, comment); } while (0)
+#define RELEASE(size, comment)\
+do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0)
+#else
+#define ALLOC(size, comment)
+#define RELEASE(size, comment)
+#endif
+
+/* compiler tweaks */
+#if defined(_MSC_VER)
+#define LOCAL(type) static __inline type __fastcall
+#else
+#define LOCAL(type) static type
+#endif
+
+/* compatibility macros */
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#define lenfunc inquiry
+#endif
+
+#if (PY_VERSION_HEX < 0x02040000)
+#define PyDict_CheckExact PyDict_Check
+#if (PY_VERSION_HEX < 0x02020000)
+#define PyList_CheckExact PyList_Check
+#define PyString_CheckExact PyString_Check
+#if (PY_VERSION_HEX >= 0x01060000)
+#define Py_USING_UNICODE /* always enabled for 2.0 and 2.1 */
+#endif
+#endif
+#endif
+
+#if !defined(Py_RETURN_NONE)
+#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+#endif
+
+/* macros used to store 'join' flags in string object pointers. note
+ that all use of text and tail as object pointers must be wrapped in
+ JOIN_OBJ. see comments in the ElementObject definition for more
+ info. */
+#define JOIN_GET(p) ((Py_uintptr_t) (p) & 1)
+#define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag)))
+#define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~1))
+
+/* glue functions (see the init function for details) */
+static PyObject* elementtree_copyelement_obj;
+static PyObject* elementtree_deepcopy_obj;
+static PyObject* elementtree_getiterator_obj;
+static PyObject* elementpath_obj;
+
+/* helpers */
+
+LOCAL(PyObject*)
+deepcopy(PyObject* object, PyObject* memo)
+{
+ /* do a deep copy of the given object */
+
+ PyObject* args;
+ PyObject* result;
+
+ if (!elementtree_deepcopy_obj) {
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "deepcopy helper not found"
+ );
+ return NULL;
+ }
+
+ args = PyTuple_New(2);
+ if (!args)
+ return NULL;
+
+ Py_INCREF(object); PyTuple_SET_ITEM(args, 0, (PyObject*) object);
+ Py_INCREF(memo); PyTuple_SET_ITEM(args, 1, (PyObject*) memo);
+
+ result = PyObject_CallObject(elementtree_deepcopy_obj, args);
+
+ Py_DECREF(args);
+
+ return result;
+}
+
+LOCAL(PyObject*)
+list_join(PyObject* list)
+{
+ /* join list elements (destroying the list in the process) */
+
+ PyObject* joiner;
+ PyObject* function;
+ PyObject* args;
+ PyObject* result;
+
+ switch (PyList_GET_SIZE(list)) {
+ case 0:
+ Py_DECREF(list);
+ return PyString_FromString("");
+ case 1:
+ result = PyList_GET_ITEM(list, 0);
+ Py_INCREF(result);
+ Py_DECREF(list);
+ return result;
+ }
+
+ /* two or more elements: slice out a suitable separator from the
+ first member, and use that to join the entire list */
+
+ joiner = PySequence_GetSlice(PyList_GET_ITEM(list, 0), 0, 0);
+ if (!joiner)
+ return NULL;
+
+ function = PyObject_GetAttrString(joiner, "join");
+ if (!function) {
+ Py_DECREF(joiner);
+ return NULL;
+ }
+
+ args = PyTuple_New(1);
+ if (!args)
+ return NULL;
+
+ PyTuple_SET_ITEM(args, 0, list);
+
+ result = PyObject_CallObject(function, args);
+
+ Py_DECREF(args); /* also removes list */
+ Py_DECREF(function);
+ Py_DECREF(joiner);
+
+ return result;
+}
+
+#if (PY_VERSION_HEX < 0x02020000)
+LOCAL(int)
+PyDict_Update(PyObject* dict, PyObject* other)
+{
+ /* PyDict_Update emulation for 2.1 and earlier */
+
+ PyObject* res;
+
+ res = PyObject_CallMethod(dict, "update", "O", other);
+ if (!res)
+ return -1;
+
+ Py_DECREF(res);
+ return 0;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* the element type */
+
+typedef struct {
+
+ /* attributes (a dictionary object), or None if no attributes */
+ PyObject* attrib;
+
+ /* child elements */
+ int length; /* actual number of items */
+ int allocated; /* allocated items */
+
+ /* this either points to _children or to a malloced buffer */
+ PyObject* *children;
+
+ PyObject* _children[STATIC_CHILDREN];
+
+} ElementObjectExtra;
+
+typedef struct {
+ PyObject_HEAD
+
+ /* element tag (a string). */
+ PyObject* tag;
+
+ /* text before first child. note that this is a tagged pointer;
+ use JOIN_OBJ to get the object pointer. the join flag is used
+ to distinguish lists created by the tree builder from lists
+ assigned to the attribute by application code; the former
+ should be joined before being returned to the user, the latter
+ should be left intact. */
+ PyObject* text;
+
+ /* text after this element, in parent. note that this is a tagged
+ pointer; use JOIN_OBJ to get the object pointer. */
+ PyObject* tail;
+
+ ElementObjectExtra* extra;
+
+} ElementObject;
+
+staticforward PyTypeObject Element_Type;
+
+#define Element_CheckExact(op) ((op)->ob_type == &Element_Type)
+
+/* -------------------------------------------------------------------- */
+/* element constructor and destructor */
+
+LOCAL(int)
+element_new_extra(ElementObject* self, PyObject* attrib)
+{
+ self->extra = PyObject_Malloc(sizeof(ElementObjectExtra));
+ if (!self->extra)
+ return -1;
+
+ if (!attrib)
+ attrib = Py_None;
+
+ Py_INCREF(attrib);
+ self->extra->attrib = attrib;
+
+ self->extra->length = 0;
+ self->extra->allocated = STATIC_CHILDREN;
+ self->extra->children = self->extra->_children;
+
+ return 0;
+}
+
+LOCAL(void)
+element_dealloc_extra(ElementObject* self)
+{
+ int i;
+
+ Py_DECREF(self->extra->attrib);
+
+ for (i = 0; i < self->extra->length; i++)
+ Py_DECREF(self->extra->children[i]);
+
+ if (self->extra->children != self->extra->_children)
+ PyObject_Free(self->extra->children);
+
+ PyObject_Free(self->extra);
+}
+
+LOCAL(PyObject*)
+element_new(PyObject* tag, PyObject* attrib)
+{
+ ElementObject* self;
+
+ self = PyObject_New(ElementObject, &Element_Type);
+ if (self == NULL)
+ return NULL;
+
+ /* use None for empty dictionaries */
+ if (PyDict_CheckExact(attrib) && !PyDict_Size(attrib))
+ attrib = Py_None;
+
+ self->extra = NULL;
+
+ if (attrib != Py_None) {
+
+ if (element_new_extra(self, attrib) < 0) {
+ PyObject_Del(self);
+ return NULL;
+ }
+
+ self->extra->length = 0;
+ self->extra->allocated = STATIC_CHILDREN;
+ self->extra->children = self->extra->_children;
+
+ }
+
+ Py_INCREF(tag);
+ self->tag = tag;
+
+ Py_INCREF(Py_None);
+ self->text = Py_None;
+
+ Py_INCREF(Py_None);
+ self->tail = Py_None;
+
+ ALLOC(sizeof(ElementObject), "create element");
+
+ return (PyObject*) self;
+}
+
+LOCAL(int)
+element_resize(ElementObject* self, int extra)
+{
+ int size;
+ PyObject* *children;
+
+ /* make sure self->children can hold the given number of extra
+ elements. set an exception and return -1 if allocation failed */
+
+ if (!self->extra)
+ element_new_extra(self, NULL);
+
+ size = self->extra->length + extra;
+
+ if (size > self->extra->allocated) {
+ /* use Python 2.4's list growth strategy */
+ size = (size >> 3) + (size < 9 ? 3 : 6) + size;
+ if (self->extra->children != self->extra->_children) {
+ children = PyObject_Realloc(self->extra->children,
+ size * sizeof(PyObject*));
+ if (!children)
+ goto nomemory;
+ } else {
+ children = PyObject_Malloc(size * sizeof(PyObject*));
+ if (!children)
+ goto nomemory;
+ /* copy existing children from static area to malloc buffer */
+ memcpy(children, self->extra->children,
+ self->extra->length * sizeof(PyObject*));
+ }
+ self->extra->children = children;
+ self->extra->allocated = size;
+ }
+
+ return 0;
+
+ nomemory:
+ PyErr_NoMemory();
+ return -1;
+}
+
+LOCAL(int)
+element_add_subelement(ElementObject* self, PyObject* element)
+{
+ /* add a child element to a parent */
+
+ if (element_resize(self, 1) < 0)
+ return -1;
+
+ Py_INCREF(element);
+ self->extra->children[self->extra->length] = element;
+
+ self->extra->length++;
+
+ return 0;
+}
+
+LOCAL(PyObject*)
+element_get_attrib(ElementObject* self)
+{
+ /* return borrowed reference to attrib dictionary */
+ /* note: this function assumes that the extra section exists */
+
+ PyObject* res = self->extra->attrib;
+
+ if (res == Py_None) {
+ /* create missing dictionary */
+ res = PyDict_New();
+ if (!res)
+ return NULL;
+ self->extra->attrib = res;
+ }
+
+ return res;
+}
+
+LOCAL(PyObject*)
+element_get_text(ElementObject* self)
+{
+ /* return borrowed reference to text attribute */
+
+ PyObject* res = self->text;
+
+ if (JOIN_GET(res)) {
+ res = JOIN_OBJ(res);
+ if (PyList_CheckExact(res)) {
+ res = list_join(res);
+ if (!res)
+ return NULL;
+ self->text = res;
+ }
+ }
+
+ return res;
+}
+
+LOCAL(PyObject*)
+element_get_tail(ElementObject* self)
+{
+ /* return borrowed reference to text attribute */
+
+ PyObject* res = self->tail;
+
+ if (JOIN_GET(res)) {
+ res = JOIN_OBJ(res);
+ if (PyList_CheckExact(res)) {
+ res = list_join(res);
+ if (!res)
+ return NULL;
+ self->tail = res;
+ }
+ }
+
+ return res;
+}
+
+static PyObject*
+element(PyObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* elem;
+
+ PyObject* tag;
+ PyObject* attrib = NULL;
+ if (!PyArg_ParseTuple(args, "O|O!:Element", &tag,
+ &PyDict_Type, &attrib))
+ return NULL;
+
+ if (attrib || kw) {
+ attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New();
+ if (!attrib)
+ return NULL;
+ if (kw)
+ PyDict_Update(attrib, kw);
+ } else {
+ Py_INCREF(Py_None);
+ attrib = Py_None;
+ }
+
+ elem = element_new(tag, attrib);
+
+ Py_DECREF(attrib);
+
+ return elem;
+}
+
+static PyObject*
+subelement(PyObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* elem;
+
+ ElementObject* parent;
+ PyObject* tag;
+ PyObject* attrib = NULL;
+ if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
+ &Element_Type, &parent, &tag,
+ &PyDict_Type, &attrib))
+ return NULL;
+
+ if (attrib || kw) {
+ attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New();
+ if (!attrib)
+ return NULL;
+ if (kw)
+ PyDict_Update(attrib, kw);
+ } else {
+ Py_INCREF(Py_None);
+ attrib = Py_None;
+ }
+
+ elem = element_new(tag, attrib);
+
+ Py_DECREF(attrib);
+
+ if (element_add_subelement(parent, elem) < 0) {
+ Py_DECREF(elem);
+ return NULL;
+ }
+
+ return elem;
+}
+
+static void
+element_dealloc(ElementObject* self)
+{
+ if (self->extra)
+ element_dealloc_extra(self);
+
+ /* discard attributes */
+ Py_DECREF(self->tag);
+ Py_DECREF(JOIN_OBJ(self->text));
+ Py_DECREF(JOIN_OBJ(self->tail));
+
+ RELEASE(sizeof(ElementObject), "destroy element");
+
+ PyObject_Del(self);
+}
+
+/* -------------------------------------------------------------------- */
+/* methods (in alphabetical order) */
+
+static PyObject*
+element_append(ElementObject* self, PyObject* args)
+{
+ PyObject* element;
+ if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element))
+ return NULL;
+
+ if (element_add_subelement(self, element) < 0)
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+element_clear(ElementObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":clear"))
+ return NULL;
+
+ if (self->extra) {
+ element_dealloc_extra(self);
+ self->extra = NULL;
+ }
+
+ Py_INCREF(Py_None);
+ Py_DECREF(JOIN_OBJ(self->text));
+ self->text = Py_None;
+
+ Py_INCREF(Py_None);
+ Py_DECREF(JOIN_OBJ(self->tail));
+ self->tail = Py_None;
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+element_copy(ElementObject* self, PyObject* args)
+{
+ int i;
+ ElementObject* element;
+
+ if (!PyArg_ParseTuple(args, ":__copy__"))
+ return NULL;
+
+ element = (ElementObject*) element_new(
+ self->tag, (self->extra) ? self->extra->attrib : Py_None
+ );
+ if (!element)
+ return NULL;
+
+ Py_DECREF(JOIN_OBJ(element->text));
+ element->text = self->text;
+ Py_INCREF(JOIN_OBJ(element->text));
+
+ Py_DECREF(JOIN_OBJ(element->tail));
+ element->tail = self->tail;
+ Py_INCREF(JOIN_OBJ(element->tail));
+
+ if (self->extra) {
+
+ if (element_resize(element, self->extra->length) < 0) {
+ Py_DECREF(element);
+ return NULL;
+ }
+
+ for (i = 0; i < self->extra->length; i++) {
+ Py_INCREF(self->extra->children[i]);
+ element->extra->children[i] = self->extra->children[i];
+ }
+
+ element->extra->length = self->extra->length;
+
+ }
+
+ return (PyObject*) element;
+}
+
+static PyObject*
+element_deepcopy(ElementObject* self, PyObject* args)
+{
+ int i;
+ ElementObject* element;
+ PyObject* tag;
+ PyObject* attrib;
+ PyObject* text;
+ PyObject* tail;
+ PyObject* id;
+
+ PyObject* memo;
+ if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo))
+ return NULL;
+
+ tag = deepcopy(self->tag, memo);
+ if (!tag)
+ return NULL;
+
+ if (self->extra) {
+ attrib = deepcopy(self->extra->attrib, memo);
+ if (!attrib) {
+ Py_DECREF(tag);
+ return NULL;
+ }
+ } else {
+ Py_INCREF(Py_None);
+ attrib = Py_None;
+ }
+
+ element = (ElementObject*) element_new(tag, attrib);
+
+ Py_DECREF(tag);
+ Py_DECREF(attrib);
+
+ if (!element)
+ return NULL;
+
+ text = deepcopy(JOIN_OBJ(self->text), memo);
+ if (!text)
+ goto error;
+ Py_DECREF(element->text);
+ element->text = JOIN_SET(text, JOIN_GET(self->text));
+
+ tail = deepcopy(JOIN_OBJ(self->tail), memo);
+ if (!tail)
+ goto error;
+ Py_DECREF(element->tail);
+ element->tail = JOIN_SET(tail, JOIN_GET(self->tail));
+
+ if (self->extra) {
+
+ if (element_resize(element, self->extra->length) < 0)
+ goto error;
+
+ for (i = 0; i < self->extra->length; i++) {
+ PyObject* child = deepcopy(self->extra->children[i], memo);
+ if (!child) {
+ element->extra->length = i;
+ goto error;
+ }
+ element->extra->children[i] = child;
+ }
+
+ element->extra->length = self->extra->length;
+
+ }
+
+ /* add object to memo dictionary (so deepcopy won't visit it again) */
+ id = PyInt_FromLong((Py_uintptr_t) self);
+
+ i = PyDict_SetItem(memo, id, (PyObject*) element);
+
+ Py_DECREF(id);
+
+ if (i < 0)
+ goto error;
+
+ return (PyObject*) element;
+
+ error:
+ Py_DECREF(element);
+ return NULL;
+}
+
+LOCAL(int)
+checkpath(PyObject* tag)
+{
+ Py_ssize_t i;
+ int check = 1;
+
+ /* check if a tag contains an xpath character */
+
+#define PATHCHAR(ch) (ch == '/' || ch == '*' || ch == '[' || ch == '@')
+
+#if defined(Py_USING_UNICODE)
+ if (PyUnicode_Check(tag)) {
+ Py_UNICODE *p = PyUnicode_AS_UNICODE(tag);
+ for (i = 0; i < PyUnicode_GET_SIZE(tag); i++) {
+ if (p[i] == '{')
+ check = 0;
+ else if (p[i] == '}')
+ check = 1;
+ else if (check && PATHCHAR(p[i]))
+ return 1;
+ }
+ return 0;
+ }
+#endif
+ if (PyString_Check(tag)) {
+ char *p = PyString_AS_STRING(tag);
+ for (i = 0; i < PyString_GET_SIZE(tag); i++) {
+ if (p[i] == '{')
+ check = 0;
+ else if (p[i] == '}')
+ check = 1;
+ else if (check && PATHCHAR(p[i]))
+ return 1;
+ }
+ return 0;
+ }
+
+ return 1; /* unknown type; might be path expression */
+}
+
+static PyObject*
+element_find(ElementObject* self, PyObject* args)
+{
+ int i;
+
+ PyObject* tag;
+ if (!PyArg_ParseTuple(args, "O:find", &tag))
+ return NULL;
+
+ if (checkpath(tag))
+ return PyObject_CallMethod(
+ elementpath_obj, "find", "OO", self, tag
+ );
+
+ if (!self->extra)
+ Py_RETURN_NONE;
+
+ for (i = 0; i < self->extra->length; i++) {
+ PyObject* item = self->extra->children[i];
+ if (Element_CheckExact(item) &&
+ PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
+ Py_INCREF(item);
+ return item;
+ }
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+element_findtext(ElementObject* self, PyObject* args)
+{
+ int i;
+
+ PyObject* tag;
+ PyObject* default_value = Py_None;
+ if (!PyArg_ParseTuple(args, "O|O:findtext", &tag, &default_value))
+ return NULL;
+
+ if (checkpath(tag))
+ return PyObject_CallMethod(
+ elementpath_obj, "findtext", "OOO", self, tag, default_value
+ );
+
+ if (!self->extra) {
+ Py_INCREF(default_value);
+ return default_value;
+ }
+
+ for (i = 0; i < self->extra->length; i++) {
+ ElementObject* item = (ElementObject*) self->extra->children[i];
+ if (Element_CheckExact(item) && !PyObject_Compare(item->tag, tag)) {
+ PyObject* text = element_get_text(item);
+ if (text == Py_None)
+ return PyString_FromString("");
+ Py_XINCREF(text);
+ return text;
+ }
+ }
+
+ Py_INCREF(default_value);
+ return default_value;
+}
+
+static PyObject*
+element_findall(ElementObject* self, PyObject* args)
+{
+ int i;
+ PyObject* out;
+
+ PyObject* tag;
+ if (!PyArg_ParseTuple(args, "O:findall", &tag))
+ return NULL;
+
+ if (checkpath(tag))
+ return PyObject_CallMethod(
+ elementpath_obj, "findall", "OO", self, tag
+ );
+
+ out = PyList_New(0);
+ if (!out)
+ return NULL;
+
+ if (!self->extra)
+ return out;
+
+ for (i = 0; i < self->extra->length; i++) {
+ PyObject* item = self->extra->children[i];
+ if (Element_CheckExact(item) &&
+ PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
+ if (PyList_Append(out, item) < 0) {
+ Py_DECREF(out);
+ return NULL;
+ }
+ }
+ }
+
+ return out;
+}
+
+static PyObject*
+element_get(ElementObject* self, PyObject* args)
+{
+ PyObject* value;
+
+ PyObject* key;
+ PyObject* default_value = Py_None;
+ if (!PyArg_ParseTuple(args, "O|O:get", &key, &default_value))
+ return NULL;
+
+ if (!self->extra || self->extra->attrib == Py_None)
+ value = default_value;
+ else {
+ value = PyDict_GetItem(self->extra->attrib, key);
+ if (!value)
+ value = default_value;
+ }
+
+ Py_INCREF(value);
+ return value;
+}
+
+static PyObject*
+element_getchildren(ElementObject* self, PyObject* args)
+{
+ int i;
+ PyObject* list;
+
+ if (!PyArg_ParseTuple(args, ":getchildren"))
+ return NULL;
+
+ if (!self->extra)
+ return PyList_New(0);
+
+ list = PyList_New(self->extra->length);
+ if (!list)
+ return NULL;
+
+ for (i = 0; i < self->extra->length; i++) {
+ PyObject* item = self->extra->children[i];
+ Py_INCREF(item);
+ PyList_SET_ITEM(list, i, item);
+ }
+
+ return list;
+}
+
+static PyObject*
+element_getiterator(ElementObject* self, PyObject* args)
+{
+ PyObject* result;
+
+ PyObject* tag = Py_None;
+ if (!PyArg_ParseTuple(args, "|O:getiterator", &tag))
+ return NULL;
+
+ if (!elementtree_getiterator_obj) {
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "getiterator helper not found"
+ );
+ return NULL;
+ }
+
+ args = PyTuple_New(2);
+ if (!args)
+ return NULL;
+
+ Py_INCREF(self); PyTuple_SET_ITEM(args, 0, (PyObject*) self);
+ Py_INCREF(tag); PyTuple_SET_ITEM(args, 1, (PyObject*) tag);
+
+ result = PyObject_CallObject(elementtree_getiterator_obj, args);
+
+ Py_DECREF(args);
+
+ return result;
+}
+
+static PyObject*
+element_getitem(PyObject* self_, Py_ssize_t index)
+{
+ ElementObject* self = (ElementObject*) self_;
+
+ if (!self->extra || index < 0 || index >= self->extra->length) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "child index out of range"
+ );
+ return NULL;
+ }
+
+ Py_INCREF(self->extra->children[index]);
+ return self->extra->children[index];
+}
+
+static PyObject*
+element_getslice(PyObject* self_, Py_ssize_t start, Py_ssize_t end)
+{
+ ElementObject* self = (ElementObject*) self_;
+ Py_ssize_t i;
+ PyObject* list;
+
+ if (!self->extra)
+ return PyList_New(0);
+
+ /* standard clamping */
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end = 0;
+ if (end > self->extra->length)
+ end = self->extra->length;
+ if (start > end)
+ start = end;
+
+ list = PyList_New(end - start);
+ if (!list)
+ return NULL;
+
+ for (i = start; i < end; i++) {
+ PyObject* item = self->extra->children[i];
+ Py_INCREF(item);
+ PyList_SET_ITEM(list, i - start, item);
+ }
+
+ return list;
+}
+
+static PyObject*
+element_insert(ElementObject* self, PyObject* args)
+{
+ int i;
+
+ int index;
+ PyObject* element;
+ if (!PyArg_ParseTuple(args, "iO!:insert", &index,
+ &Element_Type, &element))
+ return NULL;
+
+ if (!self->extra)
+ element_new_extra(self, NULL);
+
+ if (index < 0)
+ index = 0;
+ if (index > self->extra->length)
+ index = self->extra->length;
+
+ if (element_resize(self, 1) < 0)
+ return NULL;
+
+ for (i = self->extra->length; i > index; i--)
+ self->extra->children[i] = self->extra->children[i-1];
+
+ Py_INCREF(element);
+ self->extra->children[index] = element;
+
+ self->extra->length++;
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+element_items(ElementObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":items"))
+ return NULL;
+
+ if (!self->extra || self->extra->attrib == Py_None)
+ return PyList_New(0);
+
+ return PyDict_Items(self->extra->attrib);
+}
+
+static PyObject*
+element_keys(ElementObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":keys"))
+ return NULL;
+
+ if (!self->extra || self->extra->attrib == Py_None)
+ return PyList_New(0);
+
+ return PyDict_Keys(self->extra->attrib);
+}
+
+static Py_ssize_t
+element_length(ElementObject* self)
+{
+ if (!self->extra)
+ return 0;
+
+ return self->extra->length;
+}
+
+static PyObject*
+element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* elem;
+
+ PyObject* tag;
+ PyObject* attrib;
+ if (!PyArg_ParseTuple(args, "OO:makeelement", &tag, &attrib))
+ return NULL;
+
+ attrib = PyDict_Copy(attrib);
+ if (!attrib)
+ return NULL;
+
+ elem = element_new(tag, attrib);
+
+ Py_DECREF(attrib);
+
+ return elem;
+}
+
+static PyObject*
+element_reduce(ElementObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":__reduce__"))
+ return NULL;
+
+ /* Hack alert: This method is used to work around a __copy__
+ problem on certain 2.3 and 2.4 versions. To save time and
+ simplify the code, we create the copy in here, and use a dummy
+ copyelement helper to trick the copy module into doing the
+ right thing. */
+
+ if (!elementtree_copyelement_obj) {
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "copyelement helper not found"
+ );
+ return NULL;
+ }
+
+ return Py_BuildValue(
+ "O(N)", elementtree_copyelement_obj, element_copy(self, args)
+ );
+}
+
+static PyObject*
+element_remove(ElementObject* self, PyObject* args)
+{
+ int i;
+
+ PyObject* element;
+ if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element))
+ return NULL;
+
+ if (!self->extra) {
+ /* element has no children, so raise exception */
+ PyErr_SetString(
+ PyExc_ValueError,
+ "list.remove(x): x not in list"
+ );
+ return NULL;
+ }
+
+ for (i = 0; i < self->extra->length; i++) {
+ if (self->extra->children[i] == element)
+ break;
+ if (PyObject_Compare(self->extra->children[i], element) == 0)
+ break;
+ }
+
+ if (i == self->extra->length) {
+ /* element is not in children, so raise exception */
+ PyErr_SetString(
+ PyExc_ValueError,
+ "list.remove(x): x not in list"
+ );
+ return NULL;
+ }
+
+ Py_DECREF(self->extra->children[i]);
+
+ self->extra->length--;
+
+ for (; i < self->extra->length; i++)
+ self->extra->children[i] = self->extra->children[i+1];
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+element_repr(ElementObject* self)
+{
+ PyObject* repr;
+ char buffer[100];
+
+ repr = PyString_FromString("<Element ");
+
+ PyString_ConcatAndDel(&repr, PyObject_Repr(self->tag));
+
+ sprintf(buffer, " at %p>", self);
+ PyString_ConcatAndDel(&repr, PyString_FromString(buffer));
+
+ return repr;
+}
+
+static PyObject*
+element_set(ElementObject* self, PyObject* args)
+{
+ PyObject* attrib;
+
+ PyObject* key;
+ PyObject* value;
+ if (!PyArg_ParseTuple(args, "OO:set", &key, &value))
+ return NULL;
+
+ if (!self->extra)
+ element_new_extra(self, NULL);
+
+ attrib = element_get_attrib(self);
+ if (!attrib)
+ return NULL;
+
+ if (PyDict_SetItem(attrib, key, value) < 0)
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+static int
+element_setslice(PyObject* self_, Py_ssize_t start, Py_ssize_t end, PyObject* item)
+{
+ ElementObject* self = (ElementObject*) self_;
+ Py_ssize_t i, new, old;
+ PyObject* recycle = NULL;
+
+ if (!self->extra)
+ element_new_extra(self, NULL);
+
+ /* standard clamping */
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end = 0;
+ if (end > self->extra->length)
+ end = self->extra->length;
+ if (start > end)
+ start = end;
+
+ old = end - start;
+
+ if (item == NULL)
+ new = 0;
+ else if (PyList_CheckExact(item)) {
+ new = PyList_GET_SIZE(item);
+ } else {
+ /* FIXME: support arbitrary sequences? */
+ PyErr_Format(
+ PyExc_TypeError,
+ "expected list, not \"%.200s\"", item->ob_type->tp_name
+ );
+ return -1;
+ }
+
+ if (old > 0) {
+ /* to avoid recursive calls to this method (via decref), move
+ old items to the recycle bin here, and get rid of them when
+ we're done modifying the element */
+ recycle = PyList_New(old);
+ for (i = 0; i < old; i++)
+ PyList_SET_ITEM(recycle, i, self->extra->children[i + start]);
+ }
+
+ if (new < old) {
+ /* delete slice */
+ for (i = end; i < self->extra->length; i++)
+ self->extra->children[i + new - old] = self->extra->children[i];
+ } else if (new > old) {
+ /* insert slice */
+ if (element_resize(self, new - old) < 0)
+ return -1;
+ for (i = self->extra->length-1; i >= end; i--)
+ self->extra->children[i + new - old] = self->extra->children[i];
+ }
+
+ /* replace the slice */
+ for (i = 0; i < new; i++) {
+ PyObject* element = PyList_GET_ITEM(item, i);
+ Py_INCREF(element);
+ self->extra->children[i + start] = element;
+ }
+
+ self->extra->length += new - old;
+
+ /* discard the recycle bin, and everything in it */
+ Py_XDECREF(recycle);
+
+ return 0;
+}
+
+static int
+element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
+{
+ ElementObject* self = (ElementObject*) self_;
+ int i;
+ PyObject* old;
+
+ if (!self->extra || index < 0 || index >= self->extra->length) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "child assignment index out of range");
+ return -1;
+ }
+
+ old = self->extra->children[index];
+
+ if (item) {
+ Py_INCREF(item);
+ self->extra->children[index] = item;
+ } else {
+ self->extra->length--;
+ for (i = index; i < self->extra->length; i++)
+ self->extra->children[i] = self->extra->children[i+1];
+ }
+
+ Py_DECREF(old);
+
+ return 0;
+}
+
+static PyMethodDef element_methods[] = {
+
+ {"clear", (PyCFunction) element_clear, METH_VARARGS},
+
+ {"get", (PyCFunction) element_get, METH_VARARGS},
+ {"set", (PyCFunction) element_set, METH_VARARGS},
+
+ {"find", (PyCFunction) element_find, METH_VARARGS},
+ {"findtext", (PyCFunction) element_findtext, METH_VARARGS},
+ {"findall", (PyCFunction) element_findall, METH_VARARGS},
+
+ {"append", (PyCFunction) element_append, METH_VARARGS},
+ {"insert", (PyCFunction) element_insert, METH_VARARGS},
+ {"remove", (PyCFunction) element_remove, METH_VARARGS},
+
+ {"getiterator", (PyCFunction) element_getiterator, METH_VARARGS},
+ {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS},
+
+ {"items", (PyCFunction) element_items, METH_VARARGS},
+ {"keys", (PyCFunction) element_keys, METH_VARARGS},
+
+ {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS},
+
+ {"__copy__", (PyCFunction) element_copy, METH_VARARGS},
+ {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS},
+
+ /* Some 2.3 and 2.4 versions do not handle the __copy__ method on
+ C objects correctly, so we have to fake it using a __reduce__-
+ based hack (see the element_reduce implementation above for
+ details). */
+
+ /* The behaviour has been changed in 2.3.5 and 2.4.1, so we're
+ using a runtime test to figure out if we need to fake things
+ or now (see the init code below). The following entry is
+ enabled only if the hack is needed. */
+
+ {"!__reduce__", (PyCFunction) element_reduce, METH_VARARGS},
+
+ {NULL, NULL}
+};
+
+static PyObject*
+element_getattr(ElementObject* self, char* name)
+{
+ PyObject* res;
+
+ res = Py_FindMethod(element_methods, (PyObject*) self, name);
+ if (res)
+ return res;
+
+ PyErr_Clear();
+
+ if (strcmp(name, "tag") == 0)
+ res = self->tag;
+ else if (strcmp(name, "text") == 0)
+ res = element_get_text(self);
+ else if (strcmp(name, "tail") == 0) {
+ res = element_get_tail(self);
+ } else if (strcmp(name, "attrib") == 0) {
+ if (!self->extra)
+ element_new_extra(self, NULL);
+ res = element_get_attrib(self);
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+ }
+
+ if (!res)
+ return NULL;
+
+ Py_INCREF(res);
+ return res;
+}
+
+static int
+element_setattr(ElementObject* self, const char* name, PyObject* value)
+{
+ if (value == NULL) {
+ PyErr_SetString(
+ PyExc_AttributeError,
+ "can't delete element attributes"
+ );
+ return -1;
+ }
+
+ if (strcmp(name, "tag") == 0) {
+ Py_DECREF(self->tag);
+ self->tag = value;
+ Py_INCREF(self->tag);
+ } else if (strcmp(name, "text") == 0) {
+ Py_DECREF(JOIN_OBJ(self->text));
+ self->text = value;
+ Py_INCREF(self->text);
+ } else if (strcmp(name, "tail") == 0) {
+ Py_DECREF(JOIN_OBJ(self->tail));
+ self->tail = value;
+ Py_INCREF(self->tail);
+ } else if (strcmp(name, "attrib") == 0) {
+ if (!self->extra)
+ element_new_extra(self, NULL);
+ Py_DECREF(self->extra->attrib);
+ self->extra->attrib = value;
+ Py_INCREF(self->extra->attrib);
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static PySequenceMethods element_as_sequence = {
+ (lenfunc) element_length,
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ element_getitem,
+ element_getslice,
+ element_setitem,
+ element_setslice,
+};
+
+statichere PyTypeObject Element_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "Element", sizeof(ElementObject), 0,
+ /* methods */
+ (destructor)element_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc)element_getattr, /* tp_getattr */
+ (setattrfunc)element_setattr, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)element_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &element_as_sequence, /* tp_as_sequence */
+};
+
+/* ==================================================================== */
+/* the tree builder type */
+
+typedef struct {
+ PyObject_HEAD
+
+ PyObject* root; /* root node (first created node) */
+
+ ElementObject* this; /* current node */
+ ElementObject* last; /* most recently created node */
+
+ PyObject* data; /* data collector (string or list), or NULL */
+
+ PyObject* stack; /* element stack */
+ Py_ssize_t index; /* current stack size (0=empty) */
+
+ /* element tracing */
+ PyObject* events; /* list of events, or NULL if not collecting */
+ PyObject* start_event_obj; /* event objects (NULL to ignore) */
+ PyObject* end_event_obj;
+ PyObject* start_ns_event_obj;
+ PyObject* end_ns_event_obj;
+
+} TreeBuilderObject;
+
+staticforward PyTypeObject TreeBuilder_Type;
+
+#define TreeBuilder_CheckExact(op) ((op)->ob_type == &TreeBuilder_Type)
+
+/* -------------------------------------------------------------------- */
+/* constructor and destructor */
+
+LOCAL(PyObject*)
+treebuilder_new(void)
+{
+ TreeBuilderObject* self;
+
+ self = PyObject_New(TreeBuilderObject, &TreeBuilder_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->root = NULL;
+
+ Py_INCREF(Py_None);
+ self->this = (ElementObject*) Py_None;
+
+ Py_INCREF(Py_None);
+ self->last = (ElementObject*) Py_None;
+
+ self->data = NULL;
+
+ self->stack = PyList_New(20);
+ self->index = 0;
+
+ self->events = NULL;
+ self->start_event_obj = self->end_event_obj = NULL;
+ self->start_ns_event_obj = self->end_ns_event_obj = NULL;
+
+ ALLOC(sizeof(TreeBuilderObject), "create treebuilder");
+
+ return (PyObject*) self;
+}
+
+static PyObject*
+treebuilder(PyObject* self_, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":TreeBuilder"))
+ return NULL;
+
+ return treebuilder_new();
+}
+
+static void
+treebuilder_dealloc(TreeBuilderObject* self)
+{
+ Py_XDECREF(self->end_ns_event_obj);
+ Py_XDECREF(self->start_ns_event_obj);
+ Py_XDECREF(self->end_event_obj);
+ Py_XDECREF(self->start_event_obj);
+ Py_XDECREF(self->events);
+ Py_DECREF(self->stack);
+ Py_XDECREF(self->data);
+ Py_DECREF(self->last);
+ Py_DECREF(self->this);
+ Py_XDECREF(self->root);
+
+ RELEASE(sizeof(TreeBuilderObject), "destroy treebuilder");
+
+ PyObject_Del(self);
+}
+
+/* -------------------------------------------------------------------- */
+/* handlers */
+
+LOCAL(PyObject*)
+treebuilder_handle_xml(TreeBuilderObject* self, PyObject* encoding,
+ PyObject* standalone)
+{
+ Py_RETURN_NONE;
+}
+
+LOCAL(PyObject*)
+treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
+ PyObject* attrib)
+{
+ PyObject* node;
+ PyObject* this;
+
+ if (self->data) {
+ if (self->this == self->last) {
+ Py_DECREF(JOIN_OBJ(self->last->text));
+ self->last->text = JOIN_SET(
+ self->data, PyList_CheckExact(self->data)
+ );
+ } else {
+ Py_DECREF(JOIN_OBJ(self->last->tail));
+ self->last->tail = JOIN_SET(
+ self->data, PyList_CheckExact(self->data)
+ );
+ }
+ self->data = NULL;
+ }
+
+ node = element_new(tag, attrib);
+ if (!node)
+ return NULL;
+
+ this = (PyObject*) self->this;
+
+ if (this != Py_None) {
+ if (element_add_subelement((ElementObject*) this, node) < 0)
+ goto error;
+ } else {
+ if (self->root) {
+ PyErr_SetString(
+ PyExc_SyntaxError,
+ "multiple elements on top level"
+ );
+ goto error;
+ }
+ Py_INCREF(node);
+ self->root = node;
+ }
+
+ if (self->index < PyList_GET_SIZE(self->stack)) {
+ if (PyList_SetItem(self->stack, self->index, this) < 0)
+ goto error;
+ Py_INCREF(this);
+ } else {
+ if (PyList_Append(self->stack, this) < 0)
+ goto error;
+ }
+ self->index++;
+
+ Py_DECREF(this);
+ Py_INCREF(node);
+ self->this = (ElementObject*) node;
+
+ Py_DECREF(self->last);
+ Py_INCREF(node);
+ self->last = (ElementObject*) node;
+
+ if (self->start_event_obj) {
+ PyObject* res;
+ PyObject* action = self->start_event_obj;
+ res = PyTuple_New(2);
+ if (res) {
+ Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
+ Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
+ PyList_Append(self->events, res);
+ Py_DECREF(res);
+ } else
+ PyErr_Clear(); /* FIXME: propagate error */
+ }
+
+ return node;
+
+ error:
+ Py_DECREF(node);
+ return NULL;
+}
+
+LOCAL(PyObject*)
+treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
+{
+ if (!self->data) {
+ if (self->last == (ElementObject*) Py_None) {
+ /* ignore calls to data before the first call to start */
+ Py_RETURN_NONE;
+ }
+ /* store the first item as is */
+ Py_INCREF(data); self->data = data;
+ } else {
+ /* more than one item; use a list to collect items */
+ if (PyString_CheckExact(self->data) && self->data->ob_refcnt == 1 &&
+ PyString_CheckExact(data) && PyString_GET_SIZE(data) == 1) {
+ /* expat often generates single character data sections; handle
+ the most common case by resizing the existing string... */
+ Py_ssize_t size = PyString_GET_SIZE(self->data);
+ if (_PyString_Resize(&self->data, size + 1) < 0)
+ return NULL;
+ PyString_AS_STRING(self->data)[size] = PyString_AS_STRING(data)[0];
+ } else if (PyList_CheckExact(self->data)) {
+ if (PyList_Append(self->data, data) < 0)
+ return NULL;
+ } else {
+ PyObject* list = PyList_New(2);
+ if (!list)
+ return NULL;
+ PyList_SET_ITEM(list, 0, self->data);
+ Py_INCREF(data); PyList_SET_ITEM(list, 1, data);
+ self->data = list;
+ }
+ }
+
+ Py_RETURN_NONE;
+}
+
+LOCAL(PyObject*)
+treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
+{
+ PyObject* item;
+
+ if (self->data) {
+ if (self->this == self->last) {
+ Py_DECREF(JOIN_OBJ(self->last->text));
+ self->last->text = JOIN_SET(
+ self->data, PyList_CheckExact(self->data)
+ );
+ } else {
+ Py_DECREF(JOIN_OBJ(self->last->tail));
+ self->last->tail = JOIN_SET(
+ self->data, PyList_CheckExact(self->data)
+ );
+ }
+ self->data = NULL;
+ }
+
+ if (self->index == 0) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "pop from empty stack"
+ );
+ return NULL;
+ }
+
+ self->index--;
+
+ item = PyList_GET_ITEM(self->stack, self->index);
+ Py_INCREF(item);
+
+ Py_DECREF(self->last);
+
+ self->last = (ElementObject*) self->this;
+ self->this = (ElementObject*) item;
+
+ if (self->end_event_obj) {
+ PyObject* res;
+ PyObject* action = self->end_event_obj;
+ PyObject* node = (PyObject*) self->last;
+ res = PyTuple_New(2);
+ if (res) {
+ Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
+ Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
+ PyList_Append(self->events, res);
+ Py_DECREF(res);
+ } else
+ PyErr_Clear(); /* FIXME: propagate error */
+ }
+
+ Py_INCREF(self->last);
+ return (PyObject*) self->last;
+}
+
+LOCAL(void)
+treebuilder_handle_namespace(TreeBuilderObject* self, int start,
+ const char* prefix, const char *uri)
+{
+ PyObject* res;
+ PyObject* action;
+ PyObject* parcel;
+
+ if (!self->events)
+ return;
+
+ if (start) {
+ if (!self->start_ns_event_obj)
+ return;
+ action = self->start_ns_event_obj;
+ /* FIXME: prefix and uri use utf-8 encoding! */
+ parcel = Py_BuildValue("ss", (prefix) ? prefix : "", uri);
+ if (!parcel)
+ return;
+ Py_INCREF(action);
+ } else {
+ if (!self->end_ns_event_obj)
+ return;
+ action = self->end_ns_event_obj;
+ Py_INCREF(action);
+ parcel = Py_None;
+ Py_INCREF(parcel);
+ }
+
+ res = PyTuple_New(2);
+
+ if (res) {
+ PyTuple_SET_ITEM(res, 0, action);
+ PyTuple_SET_ITEM(res, 1, parcel);
+ PyList_Append(self->events, res);
+ Py_DECREF(res);
+ } else
+ PyErr_Clear(); /* FIXME: propagate error */
+}
+
+/* -------------------------------------------------------------------- */
+/* methods (in alphabetical order) */
+
+static PyObject*
+treebuilder_data(TreeBuilderObject* self, PyObject* args)
+{
+ PyObject* data;
+ if (!PyArg_ParseTuple(args, "O:data", &data))
+ return NULL;
+
+ return treebuilder_handle_data(self, data);
+}
+
+static PyObject*
+treebuilder_end(TreeBuilderObject* self, PyObject* args)
+{
+ PyObject* tag;
+ if (!PyArg_ParseTuple(args, "O:end", &tag))
+ return NULL;
+
+ return treebuilder_handle_end(self, tag);
+}
+
+LOCAL(PyObject*)
+treebuilder_done(TreeBuilderObject* self)
+{
+ PyObject* res;
+
+ /* FIXME: check stack size? */
+
+ if (self->root)
+ res = self->root;
+ else
+ res = Py_None;
+
+ Py_INCREF(res);
+ return res;
+}
+
+static PyObject*
+treebuilder_close(TreeBuilderObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":close"))
+ return NULL;
+
+ return treebuilder_done(self);
+}
+
+static PyObject*
+treebuilder_start(TreeBuilderObject* self, PyObject* args)
+{
+ PyObject* tag;
+ PyObject* attrib = Py_None;
+ if (!PyArg_ParseTuple(args, "O|O:start", &tag, &attrib))
+ return NULL;
+
+ return treebuilder_handle_start(self, tag, attrib);
+}
+
+static PyObject*
+treebuilder_xml(TreeBuilderObject* self, PyObject* args)
+{
+ PyObject* encoding;
+ PyObject* standalone;
+ if (!PyArg_ParseTuple(args, "OO:xml", &encoding, &standalone))
+ return NULL;
+
+ return treebuilder_handle_xml(self, encoding, standalone);
+}
+
+static PyMethodDef treebuilder_methods[] = {
+ {"data", (PyCFunction) treebuilder_data, METH_VARARGS},
+ {"start", (PyCFunction) treebuilder_start, METH_VARARGS},
+ {"end", (PyCFunction) treebuilder_end, METH_VARARGS},
+ {"xml", (PyCFunction) treebuilder_xml, METH_VARARGS},
+ {"close", (PyCFunction) treebuilder_close, METH_VARARGS},
+ {NULL, NULL}
+};
+
+static PyObject*
+treebuilder_getattr(TreeBuilderObject* self, char* name)
+{
+ return Py_FindMethod(treebuilder_methods, (PyObject*) self, name);
+}
+
+statichere PyTypeObject TreeBuilder_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "TreeBuilder", sizeof(TreeBuilderObject), 0,
+ /* methods */
+ (destructor)treebuilder_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc)treebuilder_getattr, /* tp_getattr */
+};
+
+/* ==================================================================== */
+/* the expat interface */
+
+#if defined(USE_EXPAT)
+
+#include "expat.h"
+
+#if defined(USE_PYEXPAT_CAPI)
+#include "pyexpat.h"
+static struct PyExpat_CAPI* expat_capi;
+#define EXPAT(func) (expat_capi->func)
+#else
+#define EXPAT(func) (XML_##func)
+#endif
+
+typedef struct {
+ PyObject_HEAD
+
+ XML_Parser parser;
+
+ PyObject* target;
+ PyObject* entity;
+
+ PyObject* names;
+
+ PyObject* handle_xml;
+ PyObject* handle_start;
+ PyObject* handle_data;
+ PyObject* handle_end;
+
+ PyObject* handle_comment;
+ PyObject* handle_pi;
+
+} XMLParserObject;
+
+staticforward PyTypeObject XMLParser_Type;
+
+/* helpers */
+
+#if defined(Py_USING_UNICODE)
+LOCAL(int)
+checkstring(const char* string, int size)
+{
+ int i;
+
+ /* check if an 8-bit string contains UTF-8 characters */
+ for (i = 0; i < size; i++)
+ if (string[i] & 0x80)
+ return 1;
+
+ return 0;
+}
+#endif
+
+LOCAL(PyObject*)
+makestring(const char* string, int size)
+{
+ /* convert a UTF-8 string to either a 7-bit ascii string or a
+ Unicode string */
+
+#if defined(Py_USING_UNICODE)
+ if (checkstring(string, size))
+ return PyUnicode_DecodeUTF8(string, size, "strict");
+#endif
+
+ return PyString_FromStringAndSize(string, size);
+}
+
+LOCAL(PyObject*)
+makeuniversal(XMLParserObject* self, const char* string)
+{
+ /* convert a UTF-8 tag/attribute name from the expat parser
+ to a universal name string */
+
+ int size = strlen(string);
+ PyObject* key;
+ PyObject* value;
+
+ /* look the 'raw' name up in the names dictionary */
+ key = PyString_FromStringAndSize(string, size);
+ if (!key)
+ return NULL;
+
+ value = PyDict_GetItem(self->names, key);
+
+ if (value) {
+ Py_INCREF(value);
+ } else {
+ /* new name. convert to universal name, and decode as
+ necessary */
+
+ PyObject* tag;
+ char* p;
+ int i;
+
+ /* look for namespace separator */
+ for (i = 0; i < size; i++)
+ if (string[i] == '}')
+ break;
+ if (i != size) {
+ /* convert to universal name */
+ tag = PyString_FromStringAndSize(NULL, size+1);
+ p = PyString_AS_STRING(tag);
+ p[0] = '{';
+ memcpy(p+1, string, size);
+ size++;
+ } else {
+ /* plain name; use key as tag */
+ Py_INCREF(key);
+ tag = key;
+ }
+
+ /* decode universal name */
+#if defined(Py_USING_UNICODE)
+ /* inline makestring, to avoid duplicating the source string if
+ it's not an utf-8 string */
+ p = PyString_AS_STRING(tag);
+ if (checkstring(p, size)) {
+ value = PyUnicode_DecodeUTF8(p, size, "strict");
+ Py_DECREF(tag);
+ if (!value) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ } else
+#endif
+ value = tag; /* use tag as is */
+
+ /* add to names dictionary */
+ if (PyDict_SetItem(self->names, key, value) < 0) {
+ Py_DECREF(key);
+ Py_DECREF(value);
+ return NULL;
+ }
+ }
+
+ Py_DECREF(key);
+ return value;
+}
+
+/* -------------------------------------------------------------------- */
+/* handlers */
+
+static void
+expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
+ int data_len)
+{
+ PyObject* key;
+ PyObject* value;
+ PyObject* res;
+
+ if (data_len < 2 || data_in[0] != '&')
+ return;
+
+ key = makestring(data_in + 1, data_len - 2);
+ if (!key)
+ return;
+
+ value = PyDict_GetItem(self->entity, key);
+
+ if (value) {
+ if (TreeBuilder_CheckExact(self->target))
+ res = treebuilder_handle_data(
+ (TreeBuilderObject*) self->target, value
+ );
+ else if (self->handle_data)
+ res = PyObject_CallFunction(self->handle_data, "O", value);
+ else
+ res = NULL;
+ Py_XDECREF(res);
+ } else {
+ PyErr_Format(
+ PyExc_SyntaxError, "undefined entity &%s;: line %ld, column %ld",
+ PyString_AS_STRING(key),
+ EXPAT(GetErrorLineNumber)(self->parser),
+ EXPAT(GetErrorColumnNumber)(self->parser)
+ );
+ }
+
+ Py_DECREF(key);
+}
+
+static void
+expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
+ const XML_Char **attrib_in)
+{
+ PyObject* res;
+ PyObject* tag;
+ PyObject* attrib;
+ int ok;
+
+ /* tag name */
+ tag = makeuniversal(self, tag_in);
+ if (!tag)
+ return; /* parser will look for errors */
+
+ /* attributes */
+ if (attrib_in[0]) {
+ attrib = PyDict_New();
+ if (!attrib)
+ return;
+ while (attrib_in[0] && attrib_in[1]) {
+ PyObject* key = makeuniversal(self, attrib_in[0]);
+ PyObject* value = makestring(attrib_in[1], strlen(attrib_in[1]));
+ if (!key || !value) {
+ Py_XDECREF(value);
+ Py_XDECREF(key);
+ Py_DECREF(attrib);
+ return;
+ }
+ ok = PyDict_SetItem(attrib, key, value);
+ Py_DECREF(value);
+ Py_DECREF(key);
+ if (ok < 0) {
+ Py_DECREF(attrib);
+ return;
+ }
+ attrib_in += 2;
+ }
+ } else {
+ Py_INCREF(Py_None);
+ attrib = Py_None;
+ }
+
+ if (TreeBuilder_CheckExact(self->target))
+ /* shortcut */
+ res = treebuilder_handle_start((TreeBuilderObject*) self->target,
+ tag, attrib);
+ else if (self->handle_start)
+ res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib);
+ else
+ res = NULL;
+
+ Py_DECREF(tag);
+ Py_DECREF(attrib);
+
+ Py_XDECREF(res);
+}
+
+static void
+expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
+ int data_len)
+{
+ PyObject* data;
+ PyObject* res;
+
+ data = makestring(data_in, data_len);
+ if (!data)
+ return; /* parser will look for errors */
+
+ if (TreeBuilder_CheckExact(self->target))
+ /* shortcut */
+ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
+ else if (self->handle_data)
+ res = PyObject_CallFunction(self->handle_data, "O", data);
+ else
+ res = NULL;
+
+ Py_DECREF(data);
+
+ Py_XDECREF(res);
+}
+
+static void
+expat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
+{
+ PyObject* tag;
+ PyObject* res = NULL;
+
+ if (TreeBuilder_CheckExact(self->target))
+ /* shortcut */
+ /* the standard tree builder doesn't look at the end tag */
+ res = treebuilder_handle_end(
+ (TreeBuilderObject*) self->target, Py_None
+ );
+ else if (self->handle_end) {
+ tag = makeuniversal(self, tag_in);
+ if (tag) {
+ res = PyObject_CallFunction(self->handle_end, "O", tag);
+ Py_DECREF(tag);
+ }
+ }
+
+ Py_XDECREF(res);
+}
+
+static void
+expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix,
+ const XML_Char *uri)
+{
+ treebuilder_handle_namespace(
+ (TreeBuilderObject*) self->target, 1, prefix, uri
+ );
+}
+
+static void
+expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
+{
+ treebuilder_handle_namespace(
+ (TreeBuilderObject*) self->target, 0, NULL, NULL
+ );
+}
+
+static void
+expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
+{
+ PyObject* comment;
+ PyObject* res;
+
+ if (self->handle_comment) {
+ comment = makestring(comment_in, strlen(comment_in));
+ if (comment) {
+ res = PyObject_CallFunction(self->handle_comment, "O", comment);
+ Py_XDECREF(res);
+ Py_DECREF(comment);
+ }
+ }
+}
+
+static void
+expat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
+ const XML_Char* data_in)
+{
+ PyObject* target;
+ PyObject* data;
+ PyObject* res;
+
+ if (self->handle_pi) {
+ target = makestring(target_in, strlen(target_in));
+ data = makestring(data_in, strlen(data_in));
+ if (target && data) {
+ res = PyObject_CallFunction(self->handle_pi, "OO", target, data);
+ Py_XDECREF(res);
+ Py_DECREF(data);
+ Py_DECREF(target);
+ } else {
+ Py_XDECREF(data);
+ Py_XDECREF(target);
+ }
+ }
+}
+
+#if defined(Py_USING_UNICODE)
+static int
+expat_unknown_encoding_handler(XMLParserObject *self, const XML_Char *name,
+ XML_Encoding *info)
+{
+ PyObject* u;
+ Py_UNICODE* p;
+ unsigned char s[256];
+ int i;
+
+ memset(info, 0, sizeof(XML_Encoding));
+
+ for (i = 0; i < 256; i++)
+ s[i] = i;
+
+ u = PyUnicode_Decode((char*) s, 256, name, "replace");
+ if (!u)
+ return XML_STATUS_ERROR;
+
+ if (PyUnicode_GET_SIZE(u) != 256) {
+ Py_DECREF(u);
+ return XML_STATUS_ERROR;
+ }
+
+ p = PyUnicode_AS_UNICODE(u);
+
+ for (i = 0; i < 256; i++) {
+ if (p[i] != Py_UNICODE_REPLACEMENT_CHARACTER)
+ info->map[i] = p[i];
+ else
+ info->map[i] = -1;
+ }
+
+ Py_DECREF(u);
+
+ return XML_STATUS_OK;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* constructor and destructor */
+
+static PyObject*
+xmlparser(PyObject* self_, PyObject* args, PyObject* kw)
+{
+ XMLParserObject* self;
+ /* FIXME: does this need to be static? */
+ static XML_Memory_Handling_Suite memory_handler;
+
+ PyObject* target = NULL;
+ char* encoding = NULL;
+ static char* kwlist[] = { "target", "encoding", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|Oz:XMLParser", kwlist,
+ &target, &encoding))
+ return NULL;
+
+#if defined(USE_PYEXPAT_CAPI)
+ if (!expat_capi) {
+ PyErr_SetString(
+ PyExc_RuntimeError, "cannot load dispatch table from pyexpat"
+ );
+ return NULL;
+ }
+#endif
+
+ self = PyObject_New(XMLParserObject, &XMLParser_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->entity = PyDict_New();
+ if (!self->entity) {
+ PyObject_Del(self);
+ return NULL;
+ }
+
+ self->names = PyDict_New();
+ if (!self->names) {
+ PyObject_Del(self->entity);
+ PyObject_Del(self);
+ return NULL;
+ }
+
+ memory_handler.malloc_fcn = PyObject_Malloc;
+ memory_handler.realloc_fcn = PyObject_Realloc;
+ memory_handler.free_fcn = PyObject_Free;
+
+ self->parser = EXPAT(ParserCreate_MM)(encoding, &memory_handler, "}");
+ if (!self->parser) {
+ PyObject_Del(self->names);
+ PyObject_Del(self->entity);
+ PyObject_Del(self);
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ /* setup target handlers */
+ if (!target) {
+ target = treebuilder_new();
+ if (!target) {
+ EXPAT(ParserFree)(self->parser);
+ PyObject_Del(self->names);
+ PyObject_Del(self->entity);
+ PyObject_Del(self);
+ return NULL;
+ }
+ } else
+ Py_INCREF(target);
+ self->target = target;
+
+ self->handle_xml = PyObject_GetAttrString(target, "xml");
+ self->handle_start = PyObject_GetAttrString(target, "start");
+ self->handle_data = PyObject_GetAttrString(target, "data");
+ self->handle_end = PyObject_GetAttrString(target, "end");
+ self->handle_comment = PyObject_GetAttrString(target, "comment");
+ self->handle_pi = PyObject_GetAttrString(target, "pi");
+
+ PyErr_Clear();
+
+ /* configure parser */
+ EXPAT(SetUserData)(self->parser, self);
+ EXPAT(SetElementHandler)(
+ self->parser,
+ (XML_StartElementHandler) expat_start_handler,
+ (XML_EndElementHandler) expat_end_handler
+ );
+ EXPAT(SetDefaultHandlerExpand)(
+ self->parser,
+ (XML_DefaultHandler) expat_default_handler
+ );
+ EXPAT(SetCharacterDataHandler)(
+ self->parser,
+ (XML_CharacterDataHandler) expat_data_handler
+ );
+ if (self->handle_comment)
+ EXPAT(SetCommentHandler)(
+ self->parser,
+ (XML_CommentHandler) expat_comment_handler
+ );
+ if (self->handle_pi)
+ EXPAT(SetProcessingInstructionHandler)(
+ self->parser,
+ (XML_ProcessingInstructionHandler) expat_pi_handler
+ );
+#if defined(Py_USING_UNICODE)
+ EXPAT(SetUnknownEncodingHandler)(
+ self->parser,
+ (XML_UnknownEncodingHandler) expat_unknown_encoding_handler, NULL
+ );
+#endif
+
+ ALLOC(sizeof(XMLParserObject), "create expatparser");
+
+ return (PyObject*) self;
+}
+
+static void
+xmlparser_dealloc(XMLParserObject* self)
+{
+ EXPAT(ParserFree)(self->parser);
+
+ Py_XDECREF(self->handle_pi);
+ Py_XDECREF(self->handle_comment);
+ Py_XDECREF(self->handle_end);
+ Py_XDECREF(self->handle_data);
+ Py_XDECREF(self->handle_start);
+ Py_XDECREF(self->handle_xml);
+
+ Py_DECREF(self->target);
+ Py_DECREF(self->entity);
+ Py_DECREF(self->names);
+
+ RELEASE(sizeof(XMLParserObject), "destroy expatparser");
+
+ PyObject_Del(self);
+}
+
+/* -------------------------------------------------------------------- */
+/* methods (in alphabetical order) */
+
+LOCAL(PyObject*)
+expat_parse(XMLParserObject* self, char* data, int data_len, int final)
+{
+ int ok;
+
+ ok = EXPAT(Parse)(self->parser, data, data_len, final);
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ if (!ok) {
+ PyErr_Format(
+ PyExc_SyntaxError, "%s: line %ld, column %ld",
+ EXPAT(ErrorString)(EXPAT(GetErrorCode)(self->parser)),
+ EXPAT(GetErrorLineNumber)(self->parser),
+ EXPAT(GetErrorColumnNumber)(self->parser)
+ );
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+xmlparser_close(XMLParserObject* self, PyObject* args)
+{
+ /* end feeding data to parser */
+
+ PyObject* res;
+ if (!PyArg_ParseTuple(args, ":close"))
+ return NULL;
+
+ res = expat_parse(self, "", 0, 1);
+
+ if (res && TreeBuilder_CheckExact(self->target)) {
+ Py_DECREF(res);
+ return treebuilder_done((TreeBuilderObject*) self->target);
+ }
+
+ return res;
+}
+
+static PyObject*
+xmlparser_feed(XMLParserObject* self, PyObject* args)
+{
+ /* feed data to parser */
+
+ char* data;
+ int data_len;
+ if (!PyArg_ParseTuple(args, "s#:feed", &data, &data_len))
+ return NULL;
+
+ return expat_parse(self, data, data_len, 0);
+}
+
+static PyObject*
+xmlparser_parse(XMLParserObject* self, PyObject* args)
+{
+ /* (internal) parse until end of input stream */
+
+ PyObject* reader;
+ PyObject* buffer;
+ PyObject* res;
+
+ PyObject* fileobj;
+ if (!PyArg_ParseTuple(args, "O:_parse", &fileobj))
+ return NULL;
+
+ reader = PyObject_GetAttrString(fileobj, "read");
+ if (!reader)
+ return NULL;
+
+ /* read from open file object */
+ for (;;) {
+
+ buffer = PyObject_CallFunction(reader, "i", 64*1024);
+
+ if (!buffer) {
+ /* read failed (e.g. due to KeyboardInterrupt) */
+ Py_DECREF(reader);
+ return NULL;
+ }
+
+ if (!PyString_CheckExact(buffer) || PyString_GET_SIZE(buffer) == 0) {
+ Py_DECREF(buffer);
+ break;
+ }
+
+ res = expat_parse(
+ self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0
+ );
+
+ Py_DECREF(buffer);
+
+ if (!res) {
+ Py_DECREF(reader);
+ return NULL;
+ }
+ Py_DECREF(res);
+
+ }
+
+ Py_DECREF(reader);
+
+ res = expat_parse(self, "", 0, 1);
+
+ if (res && TreeBuilder_CheckExact(self->target)) {
+ Py_DECREF(res);
+ return treebuilder_done((TreeBuilderObject*) self->target);
+ }
+
+ return res;
+}
+
+static PyObject*
+xmlparser_setevents(XMLParserObject* self, PyObject* args)
+{
+ /* activate element event reporting */
+
+ Py_ssize_t i;
+ TreeBuilderObject* target;
+
+ PyObject* events; /* event collector */
+ PyObject* event_set = Py_None;
+ if (!PyArg_ParseTuple(args, "O!|O:_setevents", &PyList_Type, &events,
+ &event_set))
+ return NULL;
+
+ if (!TreeBuilder_CheckExact(self->target)) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "event handling only supported for cElementTree.Treebuilder "
+ "targets"
+ );
+ return NULL;
+ }
+
+ target = (TreeBuilderObject*) self->target;
+
+ Py_INCREF(events);
+ Py_XDECREF(target->events);
+ target->events = events;
+
+ /* clear out existing events */
+ Py_XDECREF(target->start_event_obj); target->start_event_obj = NULL;
+ Py_XDECREF(target->end_event_obj); target->end_event_obj = NULL;
+ Py_XDECREF(target->start_ns_event_obj); target->start_ns_event_obj = NULL;
+ Py_XDECREF(target->end_ns_event_obj); target->end_ns_event_obj = NULL;
+
+ if (event_set == Py_None) {
+ /* default is "end" only */
+ target->end_event_obj = PyString_FromString("end");
+ Py_RETURN_NONE;
+ }
+
+ if (!PyTuple_Check(event_set)) /* FIXME: handle arbitrary sequences */
+ goto error;
+
+ for (i = 0; i < PyTuple_GET_SIZE(event_set); i++) {
+ PyObject* item = PyTuple_GET_ITEM(event_set, i);
+ char* event;
+ if (!PyString_Check(item))
+ goto error;
+ event = PyString_AS_STRING(item);
+ if (strcmp(event, "start") == 0) {
+ Py_INCREF(item);
+ target->start_event_obj = item;
+ } else if (strcmp(event, "end") == 0) {
+ Py_INCREF(item);
+ Py_XDECREF(target->end_event_obj);
+ target->end_event_obj = item;
+ } else if (strcmp(event, "start-ns") == 0) {
+ Py_INCREF(item);
+ Py_XDECREF(target->start_ns_event_obj);
+ target->start_ns_event_obj = item;
+ EXPAT(SetNamespaceDeclHandler)(
+ self->parser,
+ (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
+ (XML_EndNamespaceDeclHandler) expat_end_ns_handler
+ );
+ } else if (strcmp(event, "end-ns") == 0) {
+ Py_INCREF(item);
+ Py_XDECREF(target->end_ns_event_obj);
+ target->end_ns_event_obj = item;
+ EXPAT(SetNamespaceDeclHandler)(
+ self->parser,
+ (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
+ (XML_EndNamespaceDeclHandler) expat_end_ns_handler
+ );
+ } else {
+ PyErr_Format(
+ PyExc_ValueError,
+ "unknown event '%s'", event
+ );
+ return NULL;
+ }
+ }
+
+ Py_RETURN_NONE;
+
+ error:
+ PyErr_SetString(
+ PyExc_TypeError,
+ "invalid event tuple"
+ );
+ return NULL;
+}
+
+static PyMethodDef xmlparser_methods[] = {
+ {"feed", (PyCFunction) xmlparser_feed, METH_VARARGS},
+ {"close", (PyCFunction) xmlparser_close, METH_VARARGS},
+ {"_parse", (PyCFunction) xmlparser_parse, METH_VARARGS},
+ {"_setevents", (PyCFunction) xmlparser_setevents, METH_VARARGS},
+ {NULL, NULL}
+};
+
+static PyObject*
+xmlparser_getattr(XMLParserObject* self, char* name)
+{
+ PyObject* res;
+
+ res = Py_FindMethod(xmlparser_methods, (PyObject*) self, name);
+ if (res)
+ return res;
+
+ PyErr_Clear();
+
+ if (strcmp(name, "entity") == 0)
+ res = self->entity;
+ else if (strcmp(name, "target") == 0)
+ res = self->target;
+ else if (strcmp(name, "version") == 0) {
+ char buffer[100];
+ sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION,
+ XML_MINOR_VERSION, XML_MICRO_VERSION);
+ return PyString_FromString(buffer);
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+ }
+
+ Py_INCREF(res);
+ return res;
+}
+
+statichere PyTypeObject XMLParser_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "XMLParser", sizeof(XMLParserObject), 0,
+ /* methods */
+ (destructor)xmlparser_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc)xmlparser_getattr, /* tp_getattr */
+};
+
+#endif
+
+/* ==================================================================== */
+/* python module interface */
+
+static PyMethodDef _functions[] = {
+ {"Element", (PyCFunction) element, METH_VARARGS|METH_KEYWORDS},
+ {"SubElement", (PyCFunction) subelement, METH_VARARGS|METH_KEYWORDS},
+ {"TreeBuilder", (PyCFunction) treebuilder, METH_VARARGS},
+#if defined(USE_EXPAT)
+ {"XMLParser", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
+ {"XMLTreeBuilder", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
+#endif
+ {NULL, NULL}
+};
+
+DL_EXPORT(void)
+init_elementtree(void)
+{
+ PyObject* m;
+ PyObject* g;
+ char* bootstrap;
+#if defined(USE_PYEXPAT_CAPI)
+ struct PyExpat_CAPI* capi;
+#endif
+
+ /* Patch object type */
+ Element_Type.ob_type = TreeBuilder_Type.ob_type = &PyType_Type;
+#if defined(USE_EXPAT)
+ XMLParser_Type.ob_type = &PyType_Type;
+#endif
+
+ m = Py_InitModule("_elementtree", _functions);
+ if (!m)
+ return;
+
+ /* python glue code */
+
+ g = PyDict_New();
+ if (!g)
+ return;
+
+ PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins());
+
+ bootstrap = (
+
+#if (PY_VERSION_HEX >= 0x02020000 && PY_VERSION_HEX < 0x02030000)
+ "from __future__ import generators\n" /* enable yield under 2.2 */
+#endif
+
+ "from copy import copy, deepcopy\n"
+
+ "try:\n"
+ " from xml.etree import ElementTree\n"
+ "except ImportError:\n"
+ " import ElementTree\n"
+ "ET = ElementTree\n"
+ "del ElementTree\n"
+
+ "import _elementtree as cElementTree\n"
+
+ "try:\n" /* check if copy works as is */
+ " copy(cElementTree.Element('x'))\n"
+ "except:\n"
+ " def copyelement(elem):\n"
+ " return elem\n"
+
+ "def Comment(text=None):\n" /* public */
+ " element = cElementTree.Element(ET.Comment)\n"
+ " element.text = text\n"
+ " return element\n"
+ "cElementTree.Comment = Comment\n"
+
+ "class ElementTree(ET.ElementTree):\n" /* public */
+ " def parse(self, source, parser=None):\n"
+ " if not hasattr(source, 'read'):\n"
+ " source = open(source, 'rb')\n"
+ " if parser is not None:\n"
+ " while 1:\n"
+ " data = source.read(65536)\n"
+ " if not data:\n"
+ " break\n"
+ " parser.feed(data)\n"
+ " self._root = parser.close()\n"
+ " else:\n"
+ " parser = cElementTree.XMLParser()\n"
+ " self._root = parser._parse(source)\n"
+ " return self._root\n"
+ "cElementTree.ElementTree = ElementTree\n"
+
+ "def getiterator(node, tag=None):\n" /* helper */
+ " if tag == '*':\n"
+ " tag = None\n"
+#if (PY_VERSION_HEX < 0x02020000)
+ " nodes = []\n" /* 2.1 doesn't have yield */
+ " if tag is None or node.tag == tag:\n"
+ " nodes.append(node)\n"
+ " for node in node:\n"
+ " nodes.extend(getiterator(node, tag))\n"
+ " return nodes\n"
+#else
+ " if tag is None or node.tag == tag:\n"
+ " yield node\n"
+ " for node in node:\n"
+ " for node in getiterator(node, tag):\n"
+ " yield node\n"
+#endif
+
+ "def parse(source, parser=None):\n" /* public */
+ " tree = ElementTree()\n"
+ " tree.parse(source, parser)\n"
+ " return tree\n"
+ "cElementTree.parse = parse\n"
+
+#if (PY_VERSION_HEX < 0x02020000)
+ "if hasattr(ET, 'iterparse'):\n"
+ " cElementTree.iterparse = ET.iterparse\n" /* delegate on 2.1 */
+#else
+ "class iterparse(object):\n"
+ " root = None\n"
+ " def __init__(self, file, events=None):\n"
+ " if not hasattr(file, 'read'):\n"
+ " file = open(file, 'rb')\n"
+ " self._file = file\n"
+ " self._events = events\n"
+ " def __iter__(self):\n"
+ " events = []\n"
+ " b = cElementTree.TreeBuilder()\n"
+ " p = cElementTree.XMLParser(b)\n"
+ " p._setevents(events, self._events)\n"
+ " while 1:\n"
+ " data = self._file.read(16384)\n"
+ " if not data:\n"
+ " break\n"
+ " p.feed(data)\n"
+ " for event in events:\n"
+ " yield event\n"
+ " del events[:]\n"
+ " root = p.close()\n"
+ " for event in events:\n"
+ " yield event\n"
+ " self.root = root\n"
+ "cElementTree.iterparse = iterparse\n"
+#endif
+
+ "def PI(target, text=None):\n" /* public */
+ " element = cElementTree.Element(ET.ProcessingInstruction)\n"
+ " element.text = target\n"
+ " if text:\n"
+ " element.text = element.text + ' ' + text\n"
+ " return element\n"
+
+ " elem = cElementTree.Element(ET.PI)\n"
+ " elem.text = text\n"
+ " return elem\n"
+ "cElementTree.PI = cElementTree.ProcessingInstruction = PI\n"
+
+ "def XML(text):\n" /* public */
+ " parser = cElementTree.XMLParser()\n"
+ " parser.feed(text)\n"
+ " return parser.close()\n"
+ "cElementTree.XML = cElementTree.fromstring = XML\n"
+
+ "def XMLID(text):\n" /* public */
+ " tree = XML(text)\n"
+ " ids = {}\n"
+ " for elem in tree.getiterator():\n"
+ " id = elem.get('id')\n"
+ " if id:\n"
+ " ids[id] = elem\n"
+ " return tree, ids\n"
+ "cElementTree.XMLID = XMLID\n"
+
+ "cElementTree.dump = ET.dump\n"
+ "cElementTree.ElementPath = ElementPath = ET.ElementPath\n"
+ "cElementTree.iselement = ET.iselement\n"
+ "cElementTree.QName = ET.QName\n"
+ "cElementTree.tostring = ET.tostring\n"
+ "cElementTree.VERSION = '" VERSION "'\n"
+ "cElementTree.__version__ = '" VERSION "'\n"
+ "cElementTree.XMLParserError = SyntaxError\n"
+
+ );
+
+ PyRun_String(bootstrap, Py_file_input, g, NULL);
+
+ elementpath_obj = PyDict_GetItemString(g, "ElementPath");
+
+ elementtree_copyelement_obj = PyDict_GetItemString(g, "copyelement");
+ if (elementtree_copyelement_obj) {
+ /* reduce hack needed; enable reduce method */
+ PyMethodDef* mp;
+ for (mp = element_methods; mp->ml_name; mp++)
+ if (mp->ml_meth == (PyCFunction) element_reduce) {
+ mp->ml_name = "__reduce__";
+ break;
+ }
+ } else
+ PyErr_Clear();
+ elementtree_deepcopy_obj = PyDict_GetItemString(g, "deepcopy");
+ elementtree_getiterator_obj = PyDict_GetItemString(g, "getiterator");
+
+#if defined(USE_PYEXPAT_CAPI)
+ /* link against pyexpat, if possible */
+ capi = PyCObject_Import("pyexpat", "expat_CAPI");
+ if (capi &&
+ strcmp(capi->magic, PyExpat_CAPI_MAGIC) == 0 &&
+ capi->size <= sizeof(*expat_capi) &&
+ capi->MAJOR_VERSION == XML_MAJOR_VERSION &&
+ capi->MINOR_VERSION == XML_MINOR_VERSION &&
+ capi->MICRO_VERSION == XML_MICRO_VERSION)
+ expat_capi = capi;
+ else
+ expat_capi = NULL;
+#endif
+
+}
diff --git a/sys/src/cmd/python/Modules/_functoolsmodule.c b/sys/src/cmd/python/Modules/_functoolsmodule.c
new file mode 100644
index 000000000..54abb89d8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_functoolsmodule.c
@@ -0,0 +1,277 @@
+
+#include "Python.h"
+#include "structmember.h"
+
+/* _functools module written and maintained
+ by Hye-Shik Chang <perky@FreeBSD.org>
+ with adaptations by Raymond Hettinger <python@rcn.com>
+ Copyright (c) 2004, 2005, 2006 Python Software Foundation.
+ All rights reserved.
+*/
+
+/* partial object **********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *fn;
+ PyObject *args;
+ PyObject *kw;
+ PyObject *dict;
+ PyObject *weakreflist; /* List of weak references */
+} partialobject;
+
+static PyTypeObject partial_type;
+
+static PyObject *
+partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *func;
+ partialobject *pto;
+
+ if (PyTuple_GET_SIZE(args) < 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "type 'partial' takes at least one argument");
+ return NULL;
+ }
+
+ func = PyTuple_GET_ITEM(args, 0);
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "the first argument must be callable");
+ return NULL;
+ }
+
+ /* create partialobject structure */
+ pto = (partialobject *)type->tp_alloc(type, 0);
+ if (pto == NULL)
+ return NULL;
+
+ pto->fn = func;
+ Py_INCREF(func);
+ pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
+ if (pto->args == NULL) {
+ pto->kw = NULL;
+ Py_DECREF(pto);
+ return NULL;
+ }
+ if (kw != NULL) {
+ pto->kw = PyDict_Copy(kw);
+ if (pto->kw == NULL) {
+ Py_DECREF(pto);
+ return NULL;
+ }
+ } else {
+ pto->kw = Py_None;
+ Py_INCREF(Py_None);
+ }
+
+ pto->weakreflist = NULL;
+ pto->dict = NULL;
+
+ return (PyObject *)pto;
+}
+
+static void
+partial_dealloc(partialobject *pto)
+{
+ PyObject_GC_UnTrack(pto);
+ if (pto->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) pto);
+ Py_XDECREF(pto->fn);
+ Py_XDECREF(pto->args);
+ Py_XDECREF(pto->kw);
+ Py_XDECREF(pto->dict);
+ pto->ob_type->tp_free(pto);
+}
+
+static PyObject *
+partial_call(partialobject *pto, PyObject *args, PyObject *kw)
+{
+ PyObject *ret;
+ PyObject *argappl = NULL, *kwappl = NULL;
+
+ assert (PyCallable_Check(pto->fn));
+ assert (PyTuple_Check(pto->args));
+ assert (pto->kw == Py_None || PyDict_Check(pto->kw));
+
+ if (PyTuple_GET_SIZE(pto->args) == 0) {
+ argappl = args;
+ Py_INCREF(args);
+ } else if (PyTuple_GET_SIZE(args) == 0) {
+ argappl = pto->args;
+ Py_INCREF(pto->args);
+ } else {
+ argappl = PySequence_Concat(pto->args, args);
+ if (argappl == NULL)
+ return NULL;
+ }
+
+ if (pto->kw == Py_None) {
+ kwappl = kw;
+ Py_XINCREF(kw);
+ } else {
+ kwappl = PyDict_Copy(pto->kw);
+ if (kwappl == NULL) {
+ Py_DECREF(argappl);
+ return NULL;
+ }
+ if (kw != NULL) {
+ if (PyDict_Merge(kwappl, kw, 1) != 0) {
+ Py_DECREF(argappl);
+ Py_DECREF(kwappl);
+ return NULL;
+ }
+ }
+ }
+
+ ret = PyObject_Call(pto->fn, argappl, kwappl);
+ Py_DECREF(argappl);
+ Py_XDECREF(kwappl);
+ return ret;
+}
+
+static int
+partial_traverse(partialobject *pto, visitproc visit, void *arg)
+{
+ Py_VISIT(pto->fn);
+ Py_VISIT(pto->args);
+ Py_VISIT(pto->kw);
+ Py_VISIT(pto->dict);
+ return 0;
+}
+
+PyDoc_STRVAR(partial_doc,
+"partial(func, *args, **keywords) - new function with partial application\n\
+ of the given arguments and keywords.\n");
+
+#define OFF(x) offsetof(partialobject, x)
+static PyMemberDef partial_memberlist[] = {
+ {"func", T_OBJECT, OFF(fn), READONLY,
+ "function object to use in future partial calls"},
+ {"args", T_OBJECT, OFF(args), READONLY,
+ "tuple of arguments to future partial calls"},
+ {"keywords", T_OBJECT, OFF(kw), READONLY,
+ "dictionary of keyword arguments to future partial calls"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+partial_get_dict(partialobject *pto)
+{
+ if (pto->dict == NULL) {
+ pto->dict = PyDict_New();
+ if (pto->dict == NULL)
+ return NULL;
+ }
+ Py_INCREF(pto->dict);
+ return pto->dict;
+}
+
+static int
+partial_set_dict(partialobject *pto, PyObject *value)
+{
+ PyObject *tmp;
+
+ /* It is illegal to del p.__dict__ */
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "a partial object's dictionary may not be deleted");
+ return -1;
+ }
+ /* Can only set __dict__ to a dictionary */
+ if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting partial object's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = pto->dict;
+ Py_INCREF(value);
+ pto->dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyGetSetDef partial_getsetlist[] = {
+ {"__dict__", (getter)partial_get_dict, (setter)partial_set_dict},
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject partial_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "functools.partial", /* tp_name */
+ sizeof(partialobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)partial_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)partial_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ partial_doc, /* tp_doc */
+ (traverseproc)partial_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(partialobject, weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ partial_memberlist, /* tp_members */
+ partial_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(partialobject, dict), /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ partial_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* module level code ********************************************************/
+
+PyDoc_STRVAR(module_doc,
+"Tools that operate on functions.");
+
+static PyMethodDef module_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+init_functools(void)
+{
+ int i;
+ PyObject *m;
+ char *name;
+ PyTypeObject *typelist[] = {
+ &partial_type,
+ NULL
+ };
+
+ m = Py_InitModule3("_functools", module_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ for (i=0 ; typelist[i] != NULL ; i++) {
+ if (PyType_Ready(typelist[i]) < 0)
+ return;
+ name = strchr(typelist[i]->tp_name, '.');
+ assert (name != NULL);
+ Py_INCREF(typelist[i]);
+ PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_hashopenssl.c b/sys/src/cmd/python/Modules/_hashopenssl.c
new file mode 100644
index 000000000..859644fc7
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_hashopenssl.c
@@ -0,0 +1,487 @@
+/* Module that wraps all OpenSSL hash algorithms */
+
+/*
+ * Copyright (C) 2005 Gregory P. Smith (greg@electricrain.com)
+ * Licensed to PSF under a Contributor Agreement.
+ *
+ * Derived from a skeleton of shamodule.c containing work performed by:
+ *
+ * Andrew Kuchling (amk@amk.ca)
+ * Greg Stein (gstein@lyra.org)
+ *
+ */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structmember.h"
+
+/* EVP is the preferred interface to hashing in OpenSSL */
+#include <openssl/evp.h>
+
+
+#ifndef HASH_OBJ_CONSTRUCTOR
+#define HASH_OBJ_CONSTRUCTOR 0
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *name; /* name of this hash algorithm */
+ EVP_MD_CTX ctx; /* OpenSSL message digest context */
+} EVPobject;
+
+
+static PyTypeObject EVPtype;
+
+
+#define DEFINE_CONSTS_FOR_NEW(Name) \
+ static PyObject *CONST_ ## Name ## _name_obj; \
+ static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
+ static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
+
+DEFINE_CONSTS_FOR_NEW(md5)
+DEFINE_CONSTS_FOR_NEW(sha1)
+DEFINE_CONSTS_FOR_NEW(sha224)
+DEFINE_CONSTS_FOR_NEW(sha256)
+DEFINE_CONSTS_FOR_NEW(sha384)
+DEFINE_CONSTS_FOR_NEW(sha512)
+
+
+static EVPobject *
+newEVPobject(PyObject *name)
+{
+ EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
+
+ /* save the name for .name to return */
+ if (retval != NULL) {
+ Py_INCREF(name);
+ retval->name = name;
+ }
+
+ return retval;
+}
+
+/* Internal methods for a hash object */
+
+static void
+EVP_dealloc(PyObject *ptr)
+{
+ EVP_MD_CTX_cleanup(&((EVPobject *)ptr)->ctx);
+ Py_XDECREF(((EVPobject *)ptr)->name);
+ PyObject_Del(ptr);
+}
+
+
+/* External methods for a hash object */
+
+PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+EVP_copy(EVPobject *self, PyObject *unused)
+{
+ EVPobject *newobj;
+
+ if ( (newobj = newEVPobject(self->name))==NULL)
+ return NULL;
+
+ EVP_MD_CTX_copy(&newobj->ctx, &self->ctx);
+ return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(EVP_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+EVP_digest(EVPobject *self, PyObject *unused)
+{
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX temp_ctx;
+ PyObject *retval;
+ unsigned int digest_size;
+
+ EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
+ digest_size = EVP_MD_CTX_size(&temp_ctx);
+ EVP_DigestFinal(&temp_ctx, digest, NULL);
+
+ retval = PyString_FromStringAndSize((const char *)digest, digest_size);
+ EVP_MD_CTX_cleanup(&temp_ctx);
+ return retval;
+}
+
+PyDoc_STRVAR(EVP_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+EVP_hexdigest(EVPobject *self, PyObject *unused)
+{
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX temp_ctx;
+ PyObject *retval;
+ char *hex_digest;
+ unsigned int i, j, digest_size;
+
+ /* Get the raw (binary) digest value */
+ EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
+ digest_size = EVP_MD_CTX_size(&temp_ctx);
+ EVP_DigestFinal(&temp_ctx, digest, NULL);
+
+ EVP_MD_CTX_cleanup(&temp_ctx);
+
+ /* Create a new string */
+ /* NOTE: not thread safe! modifying an already created string object */
+ /* (not a problem because we hold the GIL by default) */
+ retval = PyString_FromStringAndSize(NULL, digest_size * 2);
+ if (!retval)
+ return NULL;
+ hex_digest = PyString_AsString(retval);
+ if (!hex_digest) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+
+ /* Make hex version of the digest */
+ for(i=j=0; i<digest_size; i++) {
+ char c;
+ c = (digest[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ c = (digest[i] & 0xf);
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ }
+ return retval;
+}
+
+PyDoc_STRVAR(EVP_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+EVP_update(EVPobject *self, PyObject *args)
+{
+ unsigned char *cp;
+ Py_ssize_t len;
+
+ if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+ return NULL;
+
+ EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
+ unsigned int));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef EVP_methods[] = {
+ {"update", (PyCFunction)EVP_update, METH_VARARGS, EVP_update__doc__},
+ {"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__},
+ {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__},
+ {"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+EVP_get_block_size(EVPobject *self, void *closure)
+{
+ return PyInt_FromLong(EVP_MD_CTX_block_size(&((EVPobject *)self)->ctx));
+}
+
+static PyObject *
+EVP_get_digest_size(EVPobject *self, void *closure)
+{
+ return PyInt_FromLong(EVP_MD_CTX_size(&((EVPobject *)self)->ctx));
+}
+
+static PyMemberDef EVP_members[] = {
+ {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
+ {NULL} /* Sentinel */
+};
+
+static PyGetSetDef EVP_getseters[] = {
+ {"digest_size",
+ (getter)EVP_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {"block_size",
+ (getter)EVP_get_block_size, NULL,
+ NULL,
+ NULL},
+ /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+ * the old sha module also supported 'digestsize'. ugh. */
+ {"digestsize",
+ (getter)EVP_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+
+static PyObject *
+EVP_repr(PyObject *self)
+{
+ char buf[100];
+ PyOS_snprintf(buf, sizeof(buf), "<%s HASH object @ %p>",
+ PyString_AsString(((EVPobject *)self)->name), self);
+ return PyString_FromString(buf);
+}
+
+#if HASH_OBJ_CONSTRUCTOR
+static int
+EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", "string", NULL};
+ PyObject *name_obj = NULL;
+ char *nameStr;
+ unsigned char *cp = NULL;
+ Py_ssize_t len = 0;
+ const EVP_MD *digest;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:HASH", kwlist,
+ &name_obj, &cp, &len)) {
+ return -1;
+ }
+
+ if (!PyArg_Parse(name_obj, "s", &nameStr)) {
+ PyErr_SetString(PyExc_TypeError, "name must be a string");
+ return -1;
+ }
+
+ digest = EVP_get_digestbyname(nameStr);
+ if (!digest) {
+ PyErr_SetString(PyExc_ValueError, "unknown hash function");
+ return -1;
+ }
+ EVP_DigestInit(&self->ctx, digest);
+
+ self->name = name_obj;
+ Py_INCREF(self->name);
+
+ if (cp && len)
+ EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
+ unsigned int));
+
+ return 0;
+}
+#endif
+
+
+PyDoc_STRVAR(hashtype_doc,
+"A hash represents the object used to calculate a checksum of a\n\
+string of information.\n\
+\n\
+Methods:\n\
+\n\
+update() -- updates the current digest with an additional string\n\
+digest() -- return the current digest value\n\
+hexdigest() -- return the current digest as a string of hexadecimal digits\n\
+copy() -- return a copy of the current hash object\n\
+\n\
+Attributes:\n\
+\n\
+name -- the hash algorithm being used by this object\n\
+digest_size -- number of bytes in this hashes output\n");
+
+static PyTypeObject EVPtype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_hashlib.HASH", /*tp_name*/
+ sizeof(EVPobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ EVP_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ EVP_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ hashtype_doc, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ EVP_methods, /* tp_methods */
+ EVP_members, /* tp_members */
+ EVP_getseters, /* tp_getset */
+#if 1
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+#endif
+#if HASH_OBJ_CONSTRUCTOR
+ (initproc)EVP_tp_init, /* tp_init */
+#endif
+};
+
+static PyObject *
+EVPnew(PyObject *name_obj,
+ const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
+ const unsigned char *cp, unsigned int len)
+{
+ EVPobject *self;
+
+ if (!digest && !initial_ctx) {
+ PyErr_SetString(PyExc_ValueError, "unsupported hash type");
+ return NULL;
+ }
+
+ if ((self = newEVPobject(name_obj)) == NULL)
+ return NULL;
+
+ if (initial_ctx) {
+ EVP_MD_CTX_copy(&self->ctx, initial_ctx);
+ } else {
+ EVP_DigestInit(&self->ctx, digest);
+ }
+
+ if (cp && len)
+ EVP_DigestUpdate(&self->ctx, cp, len);
+
+ return (PyObject *)self;
+}
+
+
+/* The module-level function: new() */
+
+PyDoc_STRVAR(EVP_new__doc__,
+"Return a new hash object using the named algorithm.\n\
+An optional string argument may be provided and will be\n\
+automatically hashed.\n\
+\n\
+The MD5 and SHA1 algorithms are always supported.\n");
+
+static PyObject *
+EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"name", "string", NULL};
+ PyObject *name_obj = NULL;
+ char *name;
+ const EVP_MD *digest;
+ unsigned char *cp = NULL;
+ Py_ssize_t len = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s#:new", kwlist,
+ &name_obj, &cp, &len)) {
+ return NULL;
+ }
+
+ if (!PyArg_Parse(name_obj, "s", &name)) {
+ PyErr_SetString(PyExc_TypeError, "name must be a string");
+ return NULL;
+ }
+
+ digest = EVP_get_digestbyname(name);
+
+ return EVPnew(name_obj, digest, NULL, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
+ unsigned int));
+}
+
+/*
+ * This macro generates constructor function definitions for specific
+ * hash algorithms. These constructors are much faster than calling
+ * the generic one passing it a python string and are noticably
+ * faster than calling a python new() wrapper. Thats important for
+ * code that wants to make hashes of a bunch of small strings.
+ */
+#define GEN_CONSTRUCTOR(NAME) \
+ static PyObject * \
+ EVP_new_ ## NAME (PyObject *self, PyObject *args) \
+ { \
+ unsigned char *cp = NULL; \
+ Py_ssize_t len = 0; \
+ \
+ if (!PyArg_ParseTuple(args, "|s#:" #NAME , &cp, &len)) { \
+ return NULL; \
+ } \
+ \
+ return EVPnew( \
+ CONST_ ## NAME ## _name_obj, \
+ NULL, \
+ CONST_new_ ## NAME ## _ctx_p, \
+ cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int)); \
+ }
+
+/* a PyMethodDef structure for the constructor */
+#define CONSTRUCTOR_METH_DEF(NAME) \
+ {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
+ PyDoc_STR("Returns a " #NAME \
+ " hash object; optionally initialized with a string") \
+ }
+
+/* used in the init function to setup a constructor */
+#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
+ CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \
+ if (EVP_get_digestbyname(#NAME)) { \
+ CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
+ EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
+ } \
+} while (0);
+
+GEN_CONSTRUCTOR(md5)
+GEN_CONSTRUCTOR(sha1)
+GEN_CONSTRUCTOR(sha224)
+GEN_CONSTRUCTOR(sha256)
+GEN_CONSTRUCTOR(sha384)
+GEN_CONSTRUCTOR(sha512)
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef EVP_functions[] = {
+ {"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
+ CONSTRUCTOR_METH_DEF(md5),
+ CONSTRUCTOR_METH_DEF(sha1),
+ CONSTRUCTOR_METH_DEF(sha224),
+ CONSTRUCTOR_METH_DEF(sha256),
+ CONSTRUCTOR_METH_DEF(sha384),
+ CONSTRUCTOR_METH_DEF(sha512),
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+PyMODINIT_FUNC
+init_hashlib(void)
+{
+ PyObject *m;
+
+ OpenSSL_add_all_digests();
+
+ /* TODO build EVP_functions openssl_* entries dynamically based
+ * on what hashes are supported rather than listing many
+ * but having some be unsupported. Only init appropriate
+ * constants. */
+
+ EVPtype.ob_type = &PyType_Type;
+ if (PyType_Ready(&EVPtype) < 0)
+ return;
+
+ m = Py_InitModule("_hashlib", EVP_functions);
+ if (m == NULL)
+ return;
+
+#if HASH_OBJ_CONSTRUCTOR
+ Py_INCREF(&EVPtype);
+ PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
+#endif
+
+ /* these constants are used by the convenience constructors */
+ INIT_CONSTRUCTOR_CONSTANTS(md5);
+ INIT_CONSTRUCTOR_CONSTANTS(sha1);
+ INIT_CONSTRUCTOR_CONSTANTS(sha224);
+ INIT_CONSTRUCTOR_CONSTANTS(sha256);
+ INIT_CONSTRUCTOR_CONSTANTS(sha384);
+ INIT_CONSTRUCTOR_CONSTANTS(sha512);
+}
diff --git a/sys/src/cmd/python/Modules/_heapqmodule.c b/sys/src/cmd/python/Modules/_heapqmodule.c
new file mode 100644
index 000000000..3f902cab5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_heapqmodule.c
@@ -0,0 +1,619 @@
+/* Drop in replacement for heapq.py
+
+C implementation derived directly from heapq.py in Py2.3
+which was written by Kevin O'Connor, augmented by Tim Peters,
+annotated by Fran�ois Pinard, and converted to C by Raymond Hettinger.
+
+*/
+
+#include "Python.h"
+
+static int
+_siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
+{
+ PyObject *newitem, *parent;
+ int cmp;
+ Py_ssize_t parentpos;
+
+ assert(PyList_Check(heap));
+ if (pos >= PyList_GET_SIZE(heap)) {
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return -1;
+ }
+
+ newitem = PyList_GET_ITEM(heap, pos);
+ Py_INCREF(newitem);
+ /* Follow the path to the root, moving parents down until finding
+ a place newitem fits. */
+ while (pos > startpos){
+ parentpos = (pos - 1) >> 1;
+ parent = PyList_GET_ITEM(heap, parentpos);
+ cmp = PyObject_RichCompareBool(parent, newitem, Py_LE);
+ if (cmp == -1) {
+ Py_DECREF(newitem);
+ return -1;
+ }
+ if (cmp == 1)
+ break;
+ Py_INCREF(parent);
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, parent);
+ pos = parentpos;
+ }
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, newitem);
+ return 0;
+}
+
+static int
+_siftup(PyListObject *heap, Py_ssize_t pos)
+{
+ Py_ssize_t startpos, endpos, childpos, rightpos;
+ int cmp;
+ PyObject *newitem, *tmp;
+
+ assert(PyList_Check(heap));
+ endpos = PyList_GET_SIZE(heap);
+ startpos = pos;
+ if (pos >= endpos) {
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return -1;
+ }
+ newitem = PyList_GET_ITEM(heap, pos);
+ Py_INCREF(newitem);
+
+ /* Bubble up the smaller child until hitting a leaf. */
+ childpos = 2*pos + 1; /* leftmost child position */
+ while (childpos < endpos) {
+ /* Set childpos to index of smaller child. */
+ rightpos = childpos + 1;
+ if (rightpos < endpos) {
+ cmp = PyObject_RichCompareBool(
+ PyList_GET_ITEM(heap, rightpos),
+ PyList_GET_ITEM(heap, childpos),
+ Py_LE);
+ if (cmp == -1) {
+ Py_DECREF(newitem);
+ return -1;
+ }
+ if (cmp == 1)
+ childpos = rightpos;
+ }
+ /* Move the smaller child up. */
+ tmp = PyList_GET_ITEM(heap, childpos);
+ Py_INCREF(tmp);
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, tmp);
+ pos = childpos;
+ childpos = 2*pos + 1;
+ }
+
+ /* The leaf at pos is empty now. Put newitem there, and and bubble
+ it up to its final resting place (by sifting its parents down). */
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, newitem);
+ return _siftdown(heap, startpos, pos);
+}
+
+static PyObject *
+heappush(PyObject *self, PyObject *args)
+{
+ PyObject *heap, *item;
+
+ if (!PyArg_UnpackTuple(args, "heappush", 2, 2, &heap, &item))
+ return NULL;
+
+ if (!PyList_Check(heap)) {
+ PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+ return NULL;
+ }
+
+ if (PyList_Append(heap, item) == -1)
+ return NULL;
+
+ if (_siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1) == -1)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(heappush_doc,
+"Push item onto heap, maintaining the heap invariant.");
+
+static PyObject *
+heappop(PyObject *self, PyObject *heap)
+{
+ PyObject *lastelt, *returnitem;
+ Py_ssize_t n;
+
+ if (!PyList_Check(heap)) {
+ PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+ return NULL;
+ }
+
+ /* # raises appropriate IndexError if heap is empty */
+ n = PyList_GET_SIZE(heap);
+ if (n == 0) {
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return NULL;
+ }
+
+ lastelt = PyList_GET_ITEM(heap, n-1) ;
+ Py_INCREF(lastelt);
+ PyList_SetSlice(heap, n-1, n, NULL);
+ n--;
+
+ if (!n)
+ return lastelt;
+ returnitem = PyList_GET_ITEM(heap, 0);
+ PyList_SET_ITEM(heap, 0, lastelt);
+ if (_siftup((PyListObject *)heap, 0) == -1) {
+ Py_DECREF(returnitem);
+ return NULL;
+ }
+ return returnitem;
+}
+
+PyDoc_STRVAR(heappop_doc,
+"Pop the smallest item off the heap, maintaining the heap invariant.");
+
+static PyObject *
+heapreplace(PyObject *self, PyObject *args)
+{
+ PyObject *heap, *item, *returnitem;
+
+ if (!PyArg_UnpackTuple(args, "heapreplace", 2, 2, &heap, &item))
+ return NULL;
+
+ if (!PyList_Check(heap)) {
+ PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+ return NULL;
+ }
+
+ if (PyList_GET_SIZE(heap) < 1) {
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return NULL;
+ }
+
+ returnitem = PyList_GET_ITEM(heap, 0);
+ Py_INCREF(item);
+ PyList_SET_ITEM(heap, 0, item);
+ if (_siftup((PyListObject *)heap, 0) == -1) {
+ Py_DECREF(returnitem);
+ return NULL;
+ }
+ return returnitem;
+}
+
+PyDoc_STRVAR(heapreplace_doc,
+"Pop and return the current smallest value, and add the new item.\n\
+\n\
+This is more efficient than heappop() followed by heappush(), and can be\n\
+more appropriate when using a fixed-size heap. Note that the value\n\
+returned may be larger than item! That constrains reasonable uses of\n\
+this routine unless written as part of a conditional replacement:\n\n\
+ if item > heap[0]:\n\
+ item = heapreplace(heap, item)\n");
+
+static PyObject *
+heapify(PyObject *self, PyObject *heap)
+{
+ Py_ssize_t i, n;
+
+ if (!PyList_Check(heap)) {
+ PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
+ return NULL;
+ }
+
+ n = PyList_GET_SIZE(heap);
+ /* Transform bottom-up. The largest index there's any point to
+ looking at is the largest with a child index in-range, so must
+ have 2*i + 1 < n, or i < (n-1)/2. If n is even = 2*j, this is
+ (2*j-1)/2 = j-1/2 so j-1 is the largest, which is n//2 - 1. If
+ n is odd = 2*j+1, this is (2*j+1-1)/2 = j so j-1 is the largest,
+ and that's again n//2-1.
+ */
+ for (i=n/2-1 ; i>=0 ; i--)
+ if(_siftup((PyListObject *)heap, i) == -1)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(heapify_doc,
+"Transform list into a heap, in-place, in O(len(heap)) time.");
+
+static PyObject *
+nlargest(PyObject *self, PyObject *args)
+{
+ PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem;
+ Py_ssize_t i, n;
+
+ if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable))
+ return NULL;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+
+ heap = PyList_New(0);
+ if (heap == NULL)
+ goto fail;
+
+ for (i=0 ; i<n ; i++ ){
+ elem = PyIter_Next(it);
+ if (elem == NULL) {
+ if (PyErr_Occurred())
+ goto fail;
+ else
+ goto sortit;
+ }
+ if (PyList_Append(heap, elem) == -1) {
+ Py_DECREF(elem);
+ goto fail;
+ }
+ Py_DECREF(elem);
+ }
+ if (PyList_GET_SIZE(heap) == 0)
+ goto sortit;
+
+ for (i=n/2-1 ; i>=0 ; i--)
+ if(_siftup((PyListObject *)heap, i) == -1)
+ goto fail;
+
+ sol = PyList_GET_ITEM(heap, 0);
+ while (1) {
+ elem = PyIter_Next(it);
+ if (elem == NULL) {
+ if (PyErr_Occurred())
+ goto fail;
+ else
+ goto sortit;
+ }
+ if (PyObject_RichCompareBool(elem, sol, Py_LE)) {
+ Py_DECREF(elem);
+ continue;
+ }
+ oldelem = PyList_GET_ITEM(heap, 0);
+ PyList_SET_ITEM(heap, 0, elem);
+ Py_DECREF(oldelem);
+ if (_siftup((PyListObject *)heap, 0) == -1)
+ goto fail;
+ sol = PyList_GET_ITEM(heap, 0);
+ }
+sortit:
+ if (PyList_Sort(heap) == -1)
+ goto fail;
+ if (PyList_Reverse(heap) == -1)
+ goto fail;
+ Py_DECREF(it);
+ return heap;
+
+fail:
+ Py_DECREF(it);
+ Py_XDECREF(heap);
+ return NULL;
+}
+
+PyDoc_STRVAR(nlargest_doc,
+"Find the n largest elements in a dataset.\n\
+\n\
+Equivalent to: sorted(iterable, reverse=True)[:n]\n");
+
+static int
+_siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
+{
+ PyObject *newitem, *parent;
+ int cmp;
+ Py_ssize_t parentpos;
+
+ assert(PyList_Check(heap));
+ if (pos >= PyList_GET_SIZE(heap)) {
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return -1;
+ }
+
+ newitem = PyList_GET_ITEM(heap, pos);
+ Py_INCREF(newitem);
+ /* Follow the path to the root, moving parents down until finding
+ a place newitem fits. */
+ while (pos > startpos){
+ parentpos = (pos - 1) >> 1;
+ parent = PyList_GET_ITEM(heap, parentpos);
+ cmp = PyObject_RichCompareBool(newitem, parent, Py_LE);
+ if (cmp == -1) {
+ Py_DECREF(newitem);
+ return -1;
+ }
+ if (cmp == 1)
+ break;
+ Py_INCREF(parent);
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, parent);
+ pos = parentpos;
+ }
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, newitem);
+ return 0;
+}
+
+static int
+_siftupmax(PyListObject *heap, Py_ssize_t pos)
+{
+ Py_ssize_t startpos, endpos, childpos, rightpos;
+ int cmp;
+ PyObject *newitem, *tmp;
+
+ assert(PyList_Check(heap));
+ endpos = PyList_GET_SIZE(heap);
+ startpos = pos;
+ if (pos >= endpos) {
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return -1;
+ }
+ newitem = PyList_GET_ITEM(heap, pos);
+ Py_INCREF(newitem);
+
+ /* Bubble up the smaller child until hitting a leaf. */
+ childpos = 2*pos + 1; /* leftmost child position */
+ while (childpos < endpos) {
+ /* Set childpos to index of smaller child. */
+ rightpos = childpos + 1;
+ if (rightpos < endpos) {
+ cmp = PyObject_RichCompareBool(
+ PyList_GET_ITEM(heap, childpos),
+ PyList_GET_ITEM(heap, rightpos),
+ Py_LE);
+ if (cmp == -1) {
+ Py_DECREF(newitem);
+ return -1;
+ }
+ if (cmp == 1)
+ childpos = rightpos;
+ }
+ /* Move the smaller child up. */
+ tmp = PyList_GET_ITEM(heap, childpos);
+ Py_INCREF(tmp);
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, tmp);
+ pos = childpos;
+ childpos = 2*pos + 1;
+ }
+
+ /* The leaf at pos is empty now. Put newitem there, and and bubble
+ it up to its final resting place (by sifting its parents down). */
+ Py_DECREF(PyList_GET_ITEM(heap, pos));
+ PyList_SET_ITEM(heap, pos, newitem);
+ return _siftdownmax(heap, startpos, pos);
+}
+
+static PyObject *
+nsmallest(PyObject *self, PyObject *args)
+{
+ PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem;
+ Py_ssize_t i, n;
+
+ if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable))
+ return NULL;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+
+ heap = PyList_New(0);
+ if (heap == NULL)
+ goto fail;
+
+ for (i=0 ; i<n ; i++ ){
+ elem = PyIter_Next(it);
+ if (elem == NULL) {
+ if (PyErr_Occurred())
+ goto fail;
+ else
+ goto sortit;
+ }
+ if (PyList_Append(heap, elem) == -1) {
+ Py_DECREF(elem);
+ goto fail;
+ }
+ Py_DECREF(elem);
+ }
+ n = PyList_GET_SIZE(heap);
+ if (n == 0)
+ goto sortit;
+
+ for (i=n/2-1 ; i>=0 ; i--)
+ if(_siftupmax((PyListObject *)heap, i) == -1)
+ goto fail;
+
+ los = PyList_GET_ITEM(heap, 0);
+ while (1) {
+ elem = PyIter_Next(it);
+ if (elem == NULL) {
+ if (PyErr_Occurred())
+ goto fail;
+ else
+ goto sortit;
+ }
+ if (PyObject_RichCompareBool(los, elem, Py_LE)) {
+ Py_DECREF(elem);
+ continue;
+ }
+
+ oldelem = PyList_GET_ITEM(heap, 0);
+ PyList_SET_ITEM(heap, 0, elem);
+ Py_DECREF(oldelem);
+ if (_siftupmax((PyListObject *)heap, 0) == -1)
+ goto fail;
+ los = PyList_GET_ITEM(heap, 0);
+ }
+
+sortit:
+ if (PyList_Sort(heap) == -1)
+ goto fail;
+ Py_DECREF(it);
+ return heap;
+
+fail:
+ Py_DECREF(it);
+ Py_XDECREF(heap);
+ return NULL;
+}
+
+PyDoc_STRVAR(nsmallest_doc,
+"Find the n smallest elements in a dataset.\n\
+\n\
+Equivalent to: sorted(iterable)[:n]\n");
+
+static PyMethodDef heapq_methods[] = {
+ {"heappush", (PyCFunction)heappush,
+ METH_VARARGS, heappush_doc},
+ {"heappop", (PyCFunction)heappop,
+ METH_O, heappop_doc},
+ {"heapreplace", (PyCFunction)heapreplace,
+ METH_VARARGS, heapreplace_doc},
+ {"heapify", (PyCFunction)heapify,
+ METH_O, heapify_doc},
+ {"nlargest", (PyCFunction)nlargest,
+ METH_VARARGS, nlargest_doc},
+ {"nsmallest", (PyCFunction)nsmallest,
+ METH_VARARGS, nsmallest_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"Heap queue algorithm (a.k.a. priority queue).\n\
+\n\
+Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\
+all k, counting elements from 0. For the sake of comparison,\n\
+non-existing elements are considered to be infinite. The interesting\n\
+property of a heap is that a[0] is always its smallest element.\n\
+\n\
+Usage:\n\
+\n\
+heap = [] # creates an empty heap\n\
+heappush(heap, item) # pushes a new item on the heap\n\
+item = heappop(heap) # pops the smallest item from the heap\n\
+item = heap[0] # smallest item on the heap without popping it\n\
+heapify(x) # transforms list into a heap, in-place, in linear time\n\
+item = heapreplace(heap, item) # pops and returns smallest item, and adds\n\
+ # new item; the heap size is unchanged\n\
+\n\
+Our API differs from textbook heap algorithms as follows:\n\
+\n\
+- We use 0-based indexing. This makes the relationship between the\n\
+ index for a node and the indexes for its children slightly less\n\
+ obvious, but is more suitable since Python uses 0-based indexing.\n\
+\n\
+- Our heappop() method returns the smallest item, not the largest.\n\
+\n\
+These two make it possible to view the heap as a regular Python list\n\
+without surprises: heap[0] is the smallest item, and heap.sort()\n\
+maintains the heap invariant!\n");
+
+
+PyDoc_STRVAR(__about__,\
+"Heap queues\n\
+\n\
+[explanation by Fran�ois Pinard]\n\
+\n\
+Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\
+all k, counting elements from 0. For the sake of comparison,\n\
+non-existing elements are considered to be infinite. The interesting\n\
+property of a heap is that a[0] is always its smallest element.\n"
+"\n\
+The strange invariant above is meant to be an efficient memory\n\
+representation for a tournament. The numbers below are `k', not a[k]:\n\
+\n\
+ 0\n\
+\n\
+ 1 2\n\
+\n\
+ 3 4 5 6\n\
+\n\
+ 7 8 9 10 11 12 13 14\n\
+\n\
+ 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30\n\
+\n\
+\n\
+In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'. In\n\
+an usual binary tournament we see in sports, each cell is the winner\n\
+over the two cells it tops, and we can trace the winner down the tree\n\
+to see all opponents s/he had. However, in many computer applications\n\
+of such tournaments, we do not need to trace the history of a winner.\n\
+To be more memory efficient, when a winner is promoted, we try to\n\
+replace it by something else at a lower level, and the rule becomes\n\
+that a cell and the two cells it tops contain three different items,\n\
+but the top cell \"wins\" over the two topped cells.\n"
+"\n\
+If this heap invariant is protected at all time, index 0 is clearly\n\
+the overall winner. The simplest algorithmic way to remove it and\n\
+find the \"next\" winner is to move some loser (let's say cell 30 in the\n\
+diagram above) into the 0 position, and then percolate this new 0 down\n\
+the tree, exchanging values, until the invariant is re-established.\n\
+This is clearly logarithmic on the total number of items in the tree.\n\
+By iterating over all items, you get an O(n ln n) sort.\n"
+"\n\
+A nice feature of this sort is that you can efficiently insert new\n\
+items while the sort is going on, provided that the inserted items are\n\
+not \"better\" than the last 0'th element you extracted. This is\n\
+especially useful in simulation contexts, where the tree holds all\n\
+incoming events, and the \"win\" condition means the smallest scheduled\n\
+time. When an event schedule other events for execution, they are\n\
+scheduled into the future, so they can easily go into the heap. So, a\n\
+heap is a good structure for implementing schedulers (this is what I\n\
+used for my MIDI sequencer :-).\n"
+"\n\
+Various structures for implementing schedulers have been extensively\n\
+studied, and heaps are good for this, as they are reasonably speedy,\n\
+the speed is almost constant, and the worst case is not much different\n\
+than the average case. However, there are other representations which\n\
+are more efficient overall, yet the worst cases might be terrible.\n"
+"\n\
+Heaps are also very useful in big disk sorts. You most probably all\n\
+know that a big sort implies producing \"runs\" (which are pre-sorted\n\
+sequences, which size is usually related to the amount of CPU memory),\n\
+followed by a merging passes for these runs, which merging is often\n\
+very cleverly organised[1]. It is very important that the initial\n\
+sort produces the longest runs possible. Tournaments are a good way\n\
+to that. If, using all the memory available to hold a tournament, you\n\
+replace and percolate items that happen to fit the current run, you'll\n\
+produce runs which are twice the size of the memory for random input,\n\
+and much better for input fuzzily ordered.\n"
+"\n\
+Moreover, if you output the 0'th item on disk and get an input which\n\
+may not fit in the current tournament (because the value \"wins\" over\n\
+the last output value), it cannot fit in the heap, so the size of the\n\
+heap decreases. The freed memory could be cleverly reused immediately\n\
+for progressively building a second heap, which grows at exactly the\n\
+same rate the first heap is melting. When the first heap completely\n\
+vanishes, you switch heaps and start a new run. Clever and quite\n\
+effective!\n\
+\n\
+In a word, heaps are useful memory structures to know. I use them in\n\
+a few applications, and I think it is good to keep a `heap' module\n\
+around. :-)\n"
+"\n\
+--------------------\n\
+[1] The disk balancing algorithms which are current, nowadays, are\n\
+more annoying than clever, and this is a consequence of the seeking\n\
+capabilities of the disks. On devices which cannot seek, like big\n\
+tape drives, the story was quite different, and one had to be very\n\
+clever to ensure (far in advance) that each tape movement will be the\n\
+most effective possible (that is, will best participate at\n\
+\"progressing\" the merge). Some tapes were even able to read\n\
+backwards, and this was also used to avoid the rewinding time.\n\
+Believe me, real good tape sorts were quite spectacular to watch!\n\
+From all times, sorting has always been a Great Art! :-)\n");
+
+PyMODINIT_FUNC
+init_heapq(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("_heapq", heapq_methods, module_doc);
+ if (m == NULL)
+ return;
+ PyModule_AddObject(m, "__about__", PyString_FromString(__about__));
+}
+
diff --git a/sys/src/cmd/python/Modules/_hotshot.c b/sys/src/cmd/python/Modules/_hotshot.c
new file mode 100644
index 000000000..065827f8e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_hotshot.c
@@ -0,0 +1,1647 @@
+/*
+ * This is the High Performance Python Profiler portion of HotShot.
+ */
+
+#include "Python.h"
+#include "code.h"
+#include "eval.h"
+#include "frameobject.h"
+#include "structmember.h"
+
+/*
+ * Which timer to use should be made more configurable, but that should not
+ * be difficult. This will do for now.
+ */
+#ifdef MS_WINDOWS
+#include <windows.h>
+
+#ifdef HAVE_DIRECT_H
+#include <direct.h> /* for getcwd() */
+#endif
+
+typedef __int64 hs_time;
+#define GETTIMEOFDAY(P_HS_TIME) \
+ { LARGE_INTEGER _temp; \
+ QueryPerformanceCounter(&_temp); \
+ *(P_HS_TIME) = _temp.QuadPart; }
+
+
+#else
+#ifndef HAVE_GETTIMEOFDAY
+#error "This module requires gettimeofday() on non-Windows platforms!"
+#endif
+#if (defined(PYOS_OS2) && defined(PYCC_GCC)) || defined(__QNX__)
+#include <sys/time.h>
+#else
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif
+typedef struct timeval hs_time;
+#endif
+
+#if !defined(__cplusplus) && !defined(inline)
+#ifdef __GNUC__
+#define inline __inline
+#endif
+#endif
+
+#ifndef inline
+#define inline
+#endif
+
+#define BUFFERSIZE 10240
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define PATH_MAX 260
+#endif
+
+#if defined(__sgi) && _COMPILER_VERSION>700 && !defined(PATH_MAX)
+/* fix PATH_MAX not being defined with MIPSPro 7.x
+ if mode is ANSI C (default) */
+#define PATH_MAX 1024
+#endif
+
+#ifndef PATH_MAX
+# ifdef MAX_PATH
+# define PATH_MAX MAX_PATH
+# elif defined (_POSIX_PATH_MAX)
+# define PATH_MAX _POSIX_PATH_MAX
+# else
+# error "Need a defn. for PATH_MAX in _hotshot.c"
+# endif
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *filemap;
+ PyObject *logfilename;
+ Py_ssize_t index;
+ unsigned char buffer[BUFFERSIZE];
+ FILE *logfp;
+ int lineevents;
+ int linetimings;
+ int frametimings;
+ /* size_t filled; */
+ int active;
+ int next_fileno;
+ hs_time prev_timeofday;
+} ProfilerObject;
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *info;
+ FILE *logfp;
+ int linetimings;
+ int frametimings;
+} LogReaderObject;
+
+static PyObject * ProfilerError = NULL;
+
+
+#ifndef MS_WINDOWS
+#ifdef GETTIMEOFDAY_NO_TZ
+#define GETTIMEOFDAY(ptv) gettimeofday((ptv))
+#else
+#define GETTIMEOFDAY(ptv) gettimeofday((ptv), (struct timezone *)NULL)
+#endif
+#endif
+
+
+/* The log reader... */
+
+PyDoc_STRVAR(logreader_close__doc__,
+"close()\n"
+"Close the log file, preventing additional records from being read.");
+
+static PyObject *
+logreader_close(LogReaderObject *self, PyObject *args)
+{
+ if (self->logfp != NULL) {
+ fclose(self->logfp);
+ self->logfp = NULL;
+ }
+ Py_INCREF(Py_None);
+
+ return Py_None;
+}
+
+PyDoc_STRVAR(logreader_fileno__doc__,
+"fileno() -> file descriptor\n"
+"Returns the file descriptor for the log file, if open.\n"
+"Raises ValueError if the log file is closed.");
+
+static PyObject *
+logreader_fileno(LogReaderObject *self)
+{
+ if (self->logfp == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "logreader's file object already closed");
+ return NULL;
+ }
+ return PyInt_FromLong(fileno(self->logfp));
+}
+
+
+/* Log File Format
+ * ---------------
+ *
+ * The log file consists of a sequence of variable-length records.
+ * Each record is identified with a record type identifier in two
+ * bits of the first byte. The two bits are the "least significant"
+ * bits of the byte.
+ *
+ * Low bits: Opcode: Meaning:
+ * 0x00 ENTER enter a frame
+ * 0x01 EXIT exit a frame
+ * 0x02 LINENO execution moved onto a different line
+ * 0x03 OTHER more bits are needed to deecode
+ *
+ * If the type is OTHER, the record is not packed so tightly, and the
+ * remaining bits are used to disambiguate the record type. These
+ * records are not used as frequently so compaction is not an issue.
+ * Each of the first three record types has a highly tailored
+ * structure that allows it to be packed tightly.
+ *
+ * The OTHER records have the following identifiers:
+ *
+ * First byte: Opcode: Meaning:
+ * 0x13 ADD_INFO define a key/value pair
+ * 0x23 DEFINE_FILE define an int->filename mapping
+ * 0x33 LINE_TIMES indicates if LINENO events have tdeltas
+ * 0x43 DEFINE_FUNC define a (fileno,lineno)->funcname mapping
+ * 0x53 FRAME_TIMES indicates if ENTER/EXIT events have tdeltas
+ *
+ * Packed Integers
+ *
+ * "Packed integers" are non-negative integer values encoded as a
+ * sequence of bytes. Each byte is encoded such that the most
+ * significant bit is set if the next byte is also part of the
+ * integer. Each byte provides bits to the least-significant end of
+ * the result; the accumulated value must be shifted up to place the
+ * new bits into the result.
+ *
+ * "Modified packed integers" are packed integers where only a portion
+ * of the first byte is used. In the rest of the specification, these
+ * are referred to as "MPI(n,name)", where "n" is the number of bits
+ * discarded from the least-signicant positions of the byte, and
+ * "name" is a name being given to those "discarded" bits, since they
+ * are a field themselves.
+ *
+ * ENTER records:
+ *
+ * MPI(2,type) fileno -- type is 0x00
+ * PI lineno
+ * PI tdelta -- iff frame times are enabled
+ *
+ * EXIT records
+ *
+ * MPI(2,type) tdelta -- type is 0x01; tdelta will be 0
+ * if frame times are disabled
+ *
+ * LINENO records
+ *
+ * MPI(2,type) lineno -- type is 0x02
+ * PI tdelta -- iff LINENO includes it
+ *
+ * ADD_INFO records
+ *
+ * BYTE type -- always 0x13
+ * PI len1 -- length of first string
+ * BYTE string1[len1] -- len1 bytes of string data
+ * PI len2 -- length of second string
+ * BYTE string2[len2] -- len2 bytes of string data
+ *
+ * DEFINE_FILE records
+ *
+ * BYTE type -- always 0x23
+ * PI fileno
+ * PI len -- length of filename
+ * BYTE filename[len] -- len bytes of string data
+ *
+ * DEFINE_FUNC records
+ *
+ * BYTE type -- always 0x43
+ * PI fileno
+ * PI lineno
+ * PI len -- length of funcname
+ * BYTE funcname[len] -- len bytes of string data
+ *
+ * LINE_TIMES records
+ *
+ * This record can be used only before the start of ENTER/EXIT/LINENO
+ * records. If have_tdelta is true, LINENO records will include the
+ * tdelta field, otherwise it will be omitted. If this record is not
+ * given, LINENO records will not contain the tdelta field.
+ *
+ * BYTE type -- always 0x33
+ * BYTE have_tdelta -- 0 if LINENO does *not* have
+ * timing information
+ * FRAME_TIMES records
+ *
+ * This record can be used only before the start of ENTER/EXIT/LINENO
+ * records. If have_tdelta is true, ENTER and EXIT records will
+ * include the tdelta field, otherwise it will be omitted. If this
+ * record is not given, ENTER and EXIT records will contain the tdelta
+ * field.
+ *
+ * BYTE type -- always 0x53
+ * BYTE have_tdelta -- 0 if ENTER/EXIT do *not* have
+ * timing information
+ */
+
+#define WHAT_ENTER 0x00
+#define WHAT_EXIT 0x01
+#define WHAT_LINENO 0x02
+#define WHAT_OTHER 0x03 /* only used in decoding */
+#define WHAT_ADD_INFO 0x13
+#define WHAT_DEFINE_FILE 0x23
+#define WHAT_LINE_TIMES 0x33
+#define WHAT_DEFINE_FUNC 0x43
+#define WHAT_FRAME_TIMES 0x53
+
+#define ERR_NONE 0
+#define ERR_EOF -1
+#define ERR_EXCEPTION -2
+#define ERR_BAD_RECTYPE -3
+
+#define PISIZE (sizeof(int) + 1)
+#define MPISIZE (PISIZE + 1)
+
+/* Maximum size of "normal" events -- nothing that contains string data */
+#define MAXEVENTSIZE (MPISIZE + PISIZE*2)
+
+
+/* Unpack a packed integer; if "discard" is non-zero, unpack a modified
+ * packed integer with "discard" discarded bits.
+ */
+static int
+unpack_packed_int(LogReaderObject *self, int *pvalue, int discard)
+{
+ int c;
+ int accum = 0;
+ int bits = 0;
+ int cont;
+
+ do {
+ /* read byte */
+ if ((c = fgetc(self->logfp)) == EOF)
+ return ERR_EOF;
+ accum |= ((c & 0x7F) >> discard) << bits;
+ bits += (7 - discard);
+ cont = c & 0x80;
+ discard = 0;
+ } while (cont);
+
+ *pvalue = accum;
+
+ return 0;
+}
+
+/* Unpack a string, which is encoded as a packed integer giving the
+ * length of the string, followed by the string data.
+ */
+static int
+unpack_string(LogReaderObject *self, PyObject **pvalue)
+{
+ int i;
+ int len;
+ int err;
+ int ch;
+ char *buf;
+
+ if ((err = unpack_packed_int(self, &len, 0)))
+ return err;
+
+ buf = (char *)malloc(len);
+ if (!buf) {
+ PyErr_NoMemory();
+ return ERR_EXCEPTION;
+ }
+
+ for (i=0; i < len; i++) {
+ ch = fgetc(self->logfp);
+ buf[i] = ch;
+ if (ch == EOF) {
+ free(buf);
+ return ERR_EOF;
+ }
+ }
+ *pvalue = PyString_FromStringAndSize(buf, len);
+ free(buf);
+ if (*pvalue == NULL) {
+ return ERR_EXCEPTION;
+ }
+ return 0;
+}
+
+
+static int
+unpack_add_info(LogReaderObject *self)
+{
+ PyObject *key;
+ PyObject *value = NULL;
+ int err;
+
+ err = unpack_string(self, &key);
+ if (!err) {
+ err = unpack_string(self, &value);
+ if (err)
+ Py_DECREF(key);
+ else {
+ PyObject *list = PyDict_GetItem(self->info, key);
+ if (list == NULL) {
+ list = PyList_New(0);
+ if (list == NULL) {
+ err = ERR_EXCEPTION;
+ goto finally;
+ }
+ if (PyDict_SetItem(self->info, key, list)) {
+ Py_DECREF(list);
+ err = ERR_EXCEPTION;
+ goto finally;
+ }
+ Py_DECREF(list);
+ }
+ if (PyList_Append(list, value))
+ err = ERR_EXCEPTION;
+ }
+ }
+ finally:
+ Py_XDECREF(key);
+ Py_XDECREF(value);
+ return err;
+}
+
+
+static void
+eof_error(LogReaderObject *self)
+{
+ fclose(self->logfp);
+ self->logfp = NULL;
+ PyErr_SetString(PyExc_EOFError,
+ "end of file with incomplete profile record");
+}
+
+static PyObject *
+logreader_tp_iternext(LogReaderObject *self)
+{
+ int c;
+ int what;
+ int err = ERR_NONE;
+ int lineno = -1;
+ int fileno = -1;
+ int tdelta = -1;
+ PyObject *s1 = NULL, *s2 = NULL;
+ PyObject *result = NULL;
+#if 0
+ unsigned char b0, b1;
+#endif
+
+ if (self->logfp == NULL) {
+ PyErr_SetString(ProfilerError,
+ "cannot iterate over closed LogReader object");
+ return NULL;
+ }
+
+restart:
+ /* decode the record type */
+ if ((c = fgetc(self->logfp)) == EOF) {
+ fclose(self->logfp);
+ self->logfp = NULL;
+ return NULL;
+ }
+ what = c & WHAT_OTHER;
+ if (what == WHAT_OTHER)
+ what = c; /* need all the bits for type */
+ else
+ ungetc(c, self->logfp); /* type byte includes packed int */
+
+ switch (what) {
+ case WHAT_ENTER:
+ err = unpack_packed_int(self, &fileno, 2);
+ if (!err) {
+ err = unpack_packed_int(self, &lineno, 0);
+ if (self->frametimings && !err)
+ err = unpack_packed_int(self, &tdelta, 0);
+ }
+ break;
+ case WHAT_EXIT:
+ err = unpack_packed_int(self, &tdelta, 2);
+ break;
+ case WHAT_LINENO:
+ err = unpack_packed_int(self, &lineno, 2);
+ if (self->linetimings && !err)
+ err = unpack_packed_int(self, &tdelta, 0);
+ break;
+ case WHAT_ADD_INFO:
+ err = unpack_add_info(self);
+ break;
+ case WHAT_DEFINE_FILE:
+ err = unpack_packed_int(self, &fileno, 0);
+ if (!err) {
+ err = unpack_string(self, &s1);
+ if (!err) {
+ Py_INCREF(Py_None);
+ s2 = Py_None;
+ }
+ }
+ break;
+ case WHAT_DEFINE_FUNC:
+ err = unpack_packed_int(self, &fileno, 0);
+ if (!err) {
+ err = unpack_packed_int(self, &lineno, 0);
+ if (!err)
+ err = unpack_string(self, &s1);
+ }
+ break;
+ case WHAT_LINE_TIMES:
+ if ((c = fgetc(self->logfp)) == EOF)
+ err = ERR_EOF;
+ else {
+ self->linetimings = c ? 1 : 0;
+ goto restart;
+ }
+ break;
+ case WHAT_FRAME_TIMES:
+ if ((c = fgetc(self->logfp)) == EOF)
+ err = ERR_EOF;
+ else {
+ self->frametimings = c ? 1 : 0;
+ goto restart;
+ }
+ break;
+ default:
+ err = ERR_BAD_RECTYPE;
+ }
+ if (err == ERR_BAD_RECTYPE) {
+ PyErr_SetString(PyExc_ValueError,
+ "unknown record type in log file");
+ }
+ else if (err == ERR_EOF) {
+ eof_error(self);
+ }
+ else if (!err) {
+ result = PyTuple_New(4);
+ if (result == NULL)
+ return NULL;
+ PyTuple_SET_ITEM(result, 0, PyInt_FromLong(what));
+ PyTuple_SET_ITEM(result, 2, PyInt_FromLong(fileno));
+ if (s1 == NULL)
+ PyTuple_SET_ITEM(result, 1, PyInt_FromLong(tdelta));
+ else
+ PyTuple_SET_ITEM(result, 1, s1);
+ if (s2 == NULL)
+ PyTuple_SET_ITEM(result, 3, PyInt_FromLong(lineno));
+ else
+ PyTuple_SET_ITEM(result, 3, s2);
+ }
+ /* The only other case is err == ERR_EXCEPTION, in which case the
+ * exception is already set.
+ */
+#if 0
+ b0 = self->buffer[self->index];
+ b1 = self->buffer[self->index + 1];
+ if (b0 & 1) {
+ /* This is a line-number event. */
+ what = PyTrace_LINE;
+ lineno = ((b0 & ~1) << 7) + b1;
+ self->index += 2;
+ }
+ else {
+ what = (b0 & 0x0E) >> 1;
+ tdelta = ((b0 & 0xF0) << 4) + b1;
+ if (what == PyTrace_CALL) {
+ /* we know there's a 2-byte file ID & 2-byte line number */
+ fileno = ((self->buffer[self->index + 2] << 8)
+ + self->buffer[self->index + 3]);
+ lineno = ((self->buffer[self->index + 4] << 8)
+ + self->buffer[self->index + 5]);
+ self->index += 6;
+ }
+ else
+ self->index += 2;
+ }
+#endif
+ return result;
+}
+
+static void
+logreader_dealloc(LogReaderObject *self)
+{
+ if (self->logfp != NULL) {
+ fclose(self->logfp);
+ self->logfp = NULL;
+ }
+ Py_XDECREF(self->info);
+ PyObject_Del(self);
+}
+
+static PyObject *
+logreader_sq_item(LogReaderObject *self, Py_ssize_t index)
+{
+ PyObject *result = logreader_tp_iternext(self);
+ if (result == NULL && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_IndexError, "no more events in log");
+ return NULL;
+ }
+ return result;
+}
+
+static void
+do_stop(ProfilerObject *self);
+
+static int
+flush_data(ProfilerObject *self)
+{
+ /* Need to dump data to the log file... */
+ size_t written = fwrite(self->buffer, 1, self->index, self->logfp);
+ if (written == (size_t)self->index)
+ self->index = 0;
+ else {
+ memmove(self->buffer, &self->buffer[written],
+ self->index - written);
+ self->index -= written;
+ if (written == 0) {
+ char *s = PyString_AsString(self->logfilename);
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
+ do_stop(self);
+ return -1;
+ }
+ }
+ if (written > 0) {
+ if (fflush(self->logfp)) {
+ char *s = PyString_AsString(self->logfilename);
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
+ do_stop(self);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static inline int
+pack_packed_int(ProfilerObject *self, int value)
+{
+ unsigned char partial;
+
+ do {
+ partial = value & 0x7F;
+ value >>= 7;
+ if (value)
+ partial |= 0x80;
+ self->buffer[self->index] = partial;
+ self->index++;
+ } while (value);
+ return 0;
+}
+
+/* Encode a modified packed integer, with a subfield of modsize bits
+ * containing the value "subfield". The value of subfield is not
+ * checked to ensure it actually fits in modsize bits.
+ */
+static inline int
+pack_modified_packed_int(ProfilerObject *self, int value,
+ int modsize, int subfield)
+{
+ const int maxvalues[] = {-1, 1, 3, 7, 15, 31, 63, 127};
+
+ int bits = 7 - modsize;
+ int partial = value & maxvalues[bits];
+ unsigned char b = subfield | (partial << modsize);
+
+ if (partial != value) {
+ b |= 0x80;
+ self->buffer[self->index] = b;
+ self->index++;
+ return pack_packed_int(self, value >> bits);
+ }
+ self->buffer[self->index] = b;
+ self->index++;
+ return 0;
+}
+
+static int
+pack_string(ProfilerObject *self, const char *s, Py_ssize_t len)
+{
+ if (len + PISIZE + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ assert(len < INT_MAX);
+ if (pack_packed_int(self, (int)len) < 0)
+ return -1;
+ memcpy(self->buffer + self->index, s, len);
+ self->index += len;
+ return 0;
+}
+
+static int
+pack_add_info(ProfilerObject *self, const char *s1, const char *s2)
+{
+ Py_ssize_t len1 = strlen(s1);
+ Py_ssize_t len2 = strlen(s2);
+
+ if (len1 + len2 + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ self->buffer[self->index] = WHAT_ADD_INFO;
+ self->index++;
+ if (pack_string(self, s1, len1) < 0)
+ return -1;
+ return pack_string(self, s2, len2);
+}
+
+static int
+pack_define_file(ProfilerObject *self, int fileno, const char *filename)
+{
+ Py_ssize_t len = strlen(filename);
+
+ if (len + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ self->buffer[self->index] = WHAT_DEFINE_FILE;
+ self->index++;
+ if (pack_packed_int(self, fileno) < 0)
+ return -1;
+ return pack_string(self, filename, len);
+}
+
+static int
+pack_define_func(ProfilerObject *self, int fileno, int lineno,
+ const char *funcname)
+{
+ Py_ssize_t len = strlen(funcname);
+
+ if (len + PISIZE*3 + 1 + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ self->buffer[self->index] = WHAT_DEFINE_FUNC;
+ self->index++;
+ if (pack_packed_int(self, fileno) < 0)
+ return -1;
+ if (pack_packed_int(self, lineno) < 0)
+ return -1;
+ return pack_string(self, funcname, len);
+}
+
+static int
+pack_line_times(ProfilerObject *self)
+{
+ if (2 + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ self->buffer[self->index] = WHAT_LINE_TIMES;
+ self->buffer[self->index + 1] = self->linetimings ? 1 : 0;
+ self->index += 2;
+ return 0;
+}
+
+static int
+pack_frame_times(ProfilerObject *self)
+{
+ if (2 + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ self->buffer[self->index] = WHAT_FRAME_TIMES;
+ self->buffer[self->index + 1] = self->frametimings ? 1 : 0;
+ self->index += 2;
+ return 0;
+}
+
+static inline int
+pack_enter(ProfilerObject *self, int fileno, int tdelta, int lineno)
+{
+ if (MPISIZE + PISIZE*2 + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ pack_modified_packed_int(self, fileno, 2, WHAT_ENTER);
+ pack_packed_int(self, lineno);
+ if (self->frametimings)
+ return pack_packed_int(self, tdelta);
+ else
+ return 0;
+}
+
+static inline int
+pack_exit(ProfilerObject *self, int tdelta)
+{
+ if (MPISIZE + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ if (self->frametimings)
+ return pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT);
+ self->buffer[self->index] = WHAT_EXIT;
+ self->index++;
+ return 0;
+}
+
+static inline int
+pack_lineno(ProfilerObject *self, int lineno)
+{
+ if (MPISIZE + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return -1;
+ }
+ return pack_modified_packed_int(self, lineno, 2, WHAT_LINENO);
+}
+
+static inline int
+pack_lineno_tdelta(ProfilerObject *self, int lineno, int tdelta)
+{
+ if (MPISIZE + PISIZE + self->index >= BUFFERSIZE) {
+ if (flush_data(self) < 0)
+ return 0;
+ }
+ if (pack_modified_packed_int(self, lineno, 2, WHAT_LINENO) < 0)
+ return -1;
+ return pack_packed_int(self, tdelta);
+}
+
+static inline int
+get_fileno(ProfilerObject *self, PyCodeObject *fcode)
+{
+ /* This is only used for ENTER events. */
+
+ PyObject *obj;
+ PyObject *dict;
+ int fileno;
+
+ obj = PyDict_GetItem(self->filemap, fcode->co_filename);
+ if (obj == NULL) {
+ /* first sighting of this file */
+ dict = PyDict_New();
+ if (dict == NULL) {
+ return -1;
+ }
+ fileno = self->next_fileno;
+ obj = Py_BuildValue("iN", fileno, dict);
+ if (obj == NULL) {
+ return -1;
+ }
+ if (PyDict_SetItem(self->filemap, fcode->co_filename, obj)) {
+ Py_DECREF(obj);
+ return -1;
+ }
+ self->next_fileno++;
+ Py_DECREF(obj);
+ if (pack_define_file(self, fileno,
+ PyString_AS_STRING(fcode->co_filename)) < 0)
+ return -1;
+ }
+ else {
+ /* already know this ID */
+ fileno = PyInt_AS_LONG(PyTuple_GET_ITEM(obj, 0));
+ dict = PyTuple_GET_ITEM(obj, 1);
+ }
+ /* make sure we save a function name for this (fileno, lineno) */
+ obj = PyInt_FromLong(fcode->co_firstlineno);
+ if (obj == NULL) {
+ /* We just won't have it saved; too bad. */
+ PyErr_Clear();
+ }
+ else {
+ PyObject *name = PyDict_GetItem(dict, obj);
+ if (name == NULL) {
+ if (pack_define_func(self, fileno, fcode->co_firstlineno,
+ PyString_AS_STRING(fcode->co_name)) < 0) {
+ Py_DECREF(obj);
+ return -1;
+ }
+ if (PyDict_SetItem(dict, obj, fcode->co_name)) {
+ Py_DECREF(obj);
+ return -1;
+ }
+ }
+ Py_DECREF(obj);
+ }
+ return fileno;
+}
+
+static inline int
+get_tdelta(ProfilerObject *self)
+{
+ int tdelta;
+#ifdef MS_WINDOWS
+ hs_time tv;
+ hs_time diff;
+
+ GETTIMEOFDAY(&tv);
+ diff = tv - self->prev_timeofday;
+ tdelta = (int)diff;
+#else
+ struct timeval tv;
+
+ GETTIMEOFDAY(&tv);
+
+ tdelta = tv.tv_usec - self->prev_timeofday.tv_usec;
+ if (tv.tv_sec != self->prev_timeofday.tv_sec)
+ tdelta += (tv.tv_sec - self->prev_timeofday.tv_sec) * 1000000;
+#endif
+ /* time can go backwards on some multiprocessor systems or by NTP */
+ if (tdelta < 0)
+ return 0;
+
+ self->prev_timeofday = tv;
+ return tdelta;
+}
+
+
+/* The workhorse: the profiler callback function. */
+
+static int
+tracer_callback(ProfilerObject *self, PyFrameObject *frame, int what,
+ PyObject *arg)
+{
+ int fileno;
+
+ switch (what) {
+ case PyTrace_CALL:
+ fileno = get_fileno(self, frame->f_code);
+ if (fileno < 0)
+ return -1;
+ return pack_enter(self, fileno,
+ self->frametimings ? get_tdelta(self) : -1,
+ frame->f_code->co_firstlineno);
+
+ case PyTrace_RETURN:
+ return pack_exit(self, get_tdelta(self));
+
+ case PyTrace_LINE: /* we only get these events if we asked for them */
+ if (self->linetimings)
+ return pack_lineno_tdelta(self, frame->f_lineno,
+ get_tdelta(self));
+ else
+ return pack_lineno(self, frame->f_lineno);
+
+ default:
+ /* ignore PyTrace_EXCEPTION */
+ break;
+ }
+ return 0;
+}
+
+
+/* A couple of useful helper functions. */
+
+#ifdef MS_WINDOWS
+static LARGE_INTEGER frequency = {0, 0};
+#endif
+
+static unsigned long timeofday_diff = 0;
+static unsigned long rusage_diff = 0;
+
+static void
+calibrate(void)
+{
+ hs_time tv1, tv2;
+
+#ifdef MS_WINDOWS
+ hs_time diff;
+ QueryPerformanceFrequency(&frequency);
+#endif
+
+ GETTIMEOFDAY(&tv1);
+ while (1) {
+ GETTIMEOFDAY(&tv2);
+#ifdef MS_WINDOWS
+ diff = tv2 - tv1;
+ if (diff != 0) {
+ timeofday_diff = (unsigned long)diff;
+ break;
+ }
+#else
+ if (tv1.tv_sec != tv2.tv_sec || tv1.tv_usec != tv2.tv_usec) {
+ if (tv1.tv_sec == tv2.tv_sec)
+ timeofday_diff = tv2.tv_usec - tv1.tv_usec;
+ else
+ timeofday_diff = (1000000 - tv1.tv_usec) + tv2.tv_usec;
+ break;
+ }
+#endif
+ }
+#if defined(MS_WINDOWS) || defined(PYOS_OS2) || \
+ defined(__VMS) || defined (__QNX__)
+ rusage_diff = -1;
+#else
+ {
+ struct rusage ru1, ru2;
+
+ getrusage(RUSAGE_SELF, &ru1);
+ while (1) {
+ getrusage(RUSAGE_SELF, &ru2);
+ if (ru1.ru_utime.tv_sec != ru2.ru_utime.tv_sec) {
+ rusage_diff = ((1000000 - ru1.ru_utime.tv_usec)
+ + ru2.ru_utime.tv_usec);
+ break;
+ }
+ else if (ru1.ru_utime.tv_usec != ru2.ru_utime.tv_usec) {
+ rusage_diff = ru2.ru_utime.tv_usec - ru1.ru_utime.tv_usec;
+ break;
+ }
+ else if (ru1.ru_stime.tv_sec != ru2.ru_stime.tv_sec) {
+ rusage_diff = ((1000000 - ru1.ru_stime.tv_usec)
+ + ru2.ru_stime.tv_usec);
+ break;
+ }
+ else if (ru1.ru_stime.tv_usec != ru2.ru_stime.tv_usec) {
+ rusage_diff = ru2.ru_stime.tv_usec - ru1.ru_stime.tv_usec;
+ break;
+ }
+ }
+ }
+#endif
+}
+
+static void
+do_start(ProfilerObject *self)
+{
+ self->active = 1;
+ GETTIMEOFDAY(&self->prev_timeofday);
+ if (self->lineevents)
+ PyEval_SetTrace((Py_tracefunc) tracer_callback, (PyObject *)self);
+ else
+ PyEval_SetProfile((Py_tracefunc) tracer_callback, (PyObject *)self);
+}
+
+static void
+do_stop(ProfilerObject *self)
+{
+ if (self->active) {
+ self->active = 0;
+ if (self->lineevents)
+ PyEval_SetTrace(NULL, NULL);
+ else
+ PyEval_SetProfile(NULL, NULL);
+ }
+ if (self->index > 0) {
+ /* Best effort to dump out any remaining data. */
+ flush_data(self);
+ }
+}
+
+static int
+is_available(ProfilerObject *self)
+{
+ if (self->active) {
+ PyErr_SetString(ProfilerError, "profiler already active");
+ return 0;
+ }
+ if (self->logfp == NULL) {
+ PyErr_SetString(ProfilerError, "profiler already closed");
+ return 0;
+ }
+ return 1;
+}
+
+
+/* Profiler object interface methods. */
+
+PyDoc_STRVAR(addinfo__doc__,
+"addinfo(key, value)\n"
+"Insert an ADD_INFO record into the log.");
+
+static PyObject *
+profiler_addinfo(ProfilerObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ char *key, *value;
+
+ if (PyArg_ParseTuple(args, "ss:addinfo", &key, &value)) {
+ if (self->logfp == NULL)
+ PyErr_SetString(ProfilerError, "profiler already closed");
+ else {
+ if (pack_add_info(self, key, value) == 0) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ }
+ }
+ return result;
+}
+
+PyDoc_STRVAR(close__doc__,
+"close()\n"
+"Shut down this profiler and close the log files, even if its active.");
+
+static PyObject *
+profiler_close(ProfilerObject *self)
+{
+ do_stop(self);
+ if (self->logfp != NULL) {
+ fclose(self->logfp);
+ self->logfp = NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#define fileno__doc__ logreader_fileno__doc__
+
+static PyObject *
+profiler_fileno(ProfilerObject *self)
+{
+ if (self->logfp == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "profiler's file object already closed");
+ return NULL;
+ }
+ return PyInt_FromLong(fileno(self->logfp));
+}
+
+PyDoc_STRVAR(runcall__doc__,
+"runcall(callable[, args[, kw]]) -> callable()\n"
+"Profile a specific function call, returning the result of that call.");
+
+static PyObject *
+profiler_runcall(ProfilerObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ PyObject *callargs = NULL;
+ PyObject *callkw = NULL;
+ PyObject *callable;
+
+ if (PyArg_UnpackTuple(args, "runcall", 1, 3,
+ &callable, &callargs, &callkw)) {
+ if (is_available(self)) {
+ do_start(self);
+ result = PyEval_CallObjectWithKeywords(callable, callargs, callkw);
+ do_stop(self);
+ }
+ }
+ return result;
+}
+
+PyDoc_STRVAR(runcode__doc__,
+"runcode(code, globals[, locals])\n"
+"Execute a code object while collecting profile data. If locals is\n"
+"omitted, globals is used for the locals as well.");
+
+static PyObject *
+profiler_runcode(ProfilerObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ PyCodeObject *code;
+ PyObject *globals;
+ PyObject *locals = NULL;
+
+ if (PyArg_ParseTuple(args, "O!O!|O:runcode",
+ &PyCode_Type, &code,
+ &PyDict_Type, &globals,
+ &locals)) {
+ if (is_available(self)) {
+ if (locals == NULL || locals == Py_None)
+ locals = globals;
+ else if (!PyDict_Check(locals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "locals must be a dictionary or None");
+ return NULL;
+ }
+ do_start(self);
+ result = PyEval_EvalCode(code, globals, locals);
+ do_stop(self);
+#if 0
+ if (!PyErr_Occurred()) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+#endif
+ }
+ }
+ return result;
+}
+
+PyDoc_STRVAR(start__doc__,
+"start()\n"
+"Install this profiler for the current thread.");
+
+static PyObject *
+profiler_start(ProfilerObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+
+ if (is_available(self)) {
+ do_start(self);
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ return result;
+}
+
+PyDoc_STRVAR(stop__doc__,
+"stop()\n"
+"Remove this profiler from the current thread.");
+
+static PyObject *
+profiler_stop(ProfilerObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+
+ if (!self->active)
+ PyErr_SetString(ProfilerError, "profiler not active");
+ else {
+ do_stop(self);
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ return result;
+}
+
+
+/* Python API support. */
+
+static void
+profiler_dealloc(ProfilerObject *self)
+{
+ do_stop(self);
+ if (self->logfp != NULL)
+ fclose(self->logfp);
+ Py_XDECREF(self->filemap);
+ Py_XDECREF(self->logfilename);
+ PyObject_Del((PyObject *)self);
+}
+
+static PyMethodDef profiler_methods[] = {
+ {"addinfo", (PyCFunction)profiler_addinfo, METH_VARARGS, addinfo__doc__},
+ {"close", (PyCFunction)profiler_close, METH_NOARGS, close__doc__},
+ {"fileno", (PyCFunction)profiler_fileno, METH_NOARGS, fileno__doc__},
+ {"runcall", (PyCFunction)profiler_runcall, METH_VARARGS, runcall__doc__},
+ {"runcode", (PyCFunction)profiler_runcode, METH_VARARGS, runcode__doc__},
+ {"start", (PyCFunction)profiler_start, METH_NOARGS, start__doc__},
+ {"stop", (PyCFunction)profiler_stop, METH_NOARGS, stop__doc__},
+ {NULL, NULL}
+};
+
+static PyMemberDef profiler_members[] = {
+ {"frametimings", T_LONG, offsetof(ProfilerObject, linetimings), READONLY},
+ {"lineevents", T_LONG, offsetof(ProfilerObject, lineevents), READONLY},
+ {"linetimings", T_LONG, offsetof(ProfilerObject, linetimings), READONLY},
+ {NULL}
+};
+
+static PyObject *
+profiler_get_closed(ProfilerObject *self, void *closure)
+{
+ PyObject *result = (self->logfp == NULL) ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyGetSetDef profiler_getsets[] = {
+ {"closed", (getter)profiler_get_closed, NULL,
+ PyDoc_STR("True if the profiler's output file has already been closed.")},
+ {NULL}
+};
+
+
+PyDoc_STRVAR(profiler_object__doc__,
+"High-performance profiler object.\n"
+"\n"
+"Methods:\n"
+"\n"
+"close(): Stop the profiler and close the log files.\n"
+"fileno(): Returns the file descriptor of the log file.\n"
+"runcall(): Run a single function call with profiling enabled.\n"
+"runcode(): Execute a code object with profiling enabled.\n"
+"start(): Install the profiler and return.\n"
+"stop(): Remove the profiler.\n"
+"\n"
+"Attributes (read-only):\n"
+"\n"
+"closed: True if the profiler has already been closed.\n"
+"frametimings: True if ENTER/EXIT events collect timing information.\n"
+"lineevents: True if line events are reported to the profiler.\n"
+"linetimings: True if line events collect timing information.");
+
+static PyTypeObject ProfilerType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_hotshot.ProfilerType", /* tp_name */
+ (int) sizeof(ProfilerObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)profiler_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ profiler_object__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ profiler_methods, /* tp_methods */
+ profiler_members, /* tp_members */
+ profiler_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+
+static PyMethodDef logreader_methods[] = {
+ {"close", (PyCFunction)logreader_close, METH_NOARGS,
+ logreader_close__doc__},
+ {"fileno", (PyCFunction)logreader_fileno, METH_NOARGS,
+ logreader_fileno__doc__},
+ {NULL, NULL}
+};
+
+static PyMemberDef logreader_members[] = {
+ {"info", T_OBJECT, offsetof(LogReaderObject, info), RO,
+ PyDoc_STR("Dictionary mapping informational keys to lists of values.")},
+ {NULL}
+};
+
+
+PyDoc_STRVAR(logreader__doc__,
+"logreader(filename) --> log-iterator\n\
+Create a log-reader for the timing information file.");
+
+static PySequenceMethods logreader_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)logreader_sq_item, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ 0, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+};
+
+static PyObject *
+logreader_get_closed(LogReaderObject *self, void *closure)
+{
+ PyObject *result = (self->logfp == NULL) ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyGetSetDef logreader_getsets[] = {
+ {"closed", (getter)logreader_get_closed, NULL,
+ PyDoc_STR("True if the logreader's input file has already been closed.")},
+ {NULL}
+};
+
+static PyTypeObject LogReaderType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_hotshot.LogReaderType", /* tp_name */
+ (int) sizeof(LogReaderObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)logreader_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &logreader_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ logreader__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)logreader_tp_iternext,/* tp_iternext */
+ logreader_methods, /* tp_methods */
+ logreader_members, /* tp_members */
+ logreader_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+static PyObject *
+hotshot_logreader(PyObject *unused, PyObject *args)
+{
+ LogReaderObject *self = NULL;
+ char *filename;
+ int c;
+ int err = 0;
+
+ if (PyArg_ParseTuple(args, "s:logreader", &filename)) {
+ self = PyObject_New(LogReaderObject, &LogReaderType);
+ if (self != NULL) {
+ self->frametimings = 1;
+ self->linetimings = 0;
+ self->info = NULL;
+ self->logfp = fopen(filename, "rb");
+ if (self->logfp == NULL) {
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
+ Py_DECREF(self);
+ self = NULL;
+ goto finally;
+ }
+ self->info = PyDict_New();
+ if (self->info == NULL) {
+ Py_DECREF(self);
+ goto finally;
+ }
+ /* read initial info */
+ for (;;) {
+ if ((c = fgetc(self->logfp)) == EOF) {
+ eof_error(self);
+ break;
+ }
+ if (c != WHAT_ADD_INFO) {
+ ungetc(c, self->logfp);
+ break;
+ }
+ err = unpack_add_info(self);
+ if (err) {
+ if (err == ERR_EOF)
+ eof_error(self);
+ else
+ PyErr_SetString(PyExc_RuntimeError,
+ "unexpected error");
+ break;
+ }
+ }
+ }
+ }
+ finally:
+ return (PyObject *) self;
+}
+
+
+/* Return a Python string that represents the version number without the
+ * extra cruft added by revision control, even if the right options were
+ * given to the "cvs export" command to make it not include the extra
+ * cruft.
+ */
+static char *
+get_version_string(void)
+{
+ static char *rcsid = "$Revision: 51218 $";
+ char *rev = rcsid;
+ char *buffer;
+ int i = 0;
+
+ while (*rev && !isdigit(Py_CHARMASK(*rev)))
+ ++rev;
+ while (rev[i] != ' ' && rev[i] != '\0')
+ ++i;
+ buffer = (char *)malloc(i + 1);
+ if (buffer != NULL) {
+ memmove(buffer, rev, i);
+ buffer[i] = '\0';
+ }
+ return buffer;
+}
+
+/* Write out a RFC 822-style header with various useful bits of
+ * information to make the output easier to manage.
+ */
+static int
+write_header(ProfilerObject *self)
+{
+ char *buffer;
+ char cwdbuffer[PATH_MAX];
+ PyObject *temp;
+ Py_ssize_t i, len;
+
+ buffer = get_version_string();
+ if (buffer == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ pack_add_info(self, "hotshot-version", buffer);
+ pack_add_info(self, "requested-frame-timings",
+ (self->frametimings ? "yes" : "no"));
+ pack_add_info(self, "requested-line-events",
+ (self->lineevents ? "yes" : "no"));
+ pack_add_info(self, "requested-line-timings",
+ (self->linetimings ? "yes" : "no"));
+ pack_add_info(self, "platform", Py_GetPlatform());
+ pack_add_info(self, "executable", Py_GetProgramFullPath());
+ free(buffer);
+ buffer = (char *) Py_GetVersion();
+ if (buffer == NULL)
+ PyErr_Clear();
+ else
+ pack_add_info(self, "executable-version", buffer);
+
+#ifdef MS_WINDOWS
+ PyOS_snprintf(cwdbuffer, sizeof(cwdbuffer), "%I64d", frequency.QuadPart);
+ pack_add_info(self, "reported-performance-frequency", cwdbuffer);
+#else
+ PyOS_snprintf(cwdbuffer, sizeof(cwdbuffer), "%lu", rusage_diff);
+ pack_add_info(self, "observed-interval-getrusage", cwdbuffer);
+ PyOS_snprintf(cwdbuffer, sizeof(cwdbuffer), "%lu", timeofday_diff);
+ pack_add_info(self, "observed-interval-gettimeofday", cwdbuffer);
+#endif
+
+ pack_add_info(self, "current-directory",
+ getcwd(cwdbuffer, sizeof cwdbuffer));
+
+ temp = PySys_GetObject("path");
+ if (temp == NULL || !PyList_Check(temp)) {
+ PyErr_SetString(PyExc_RuntimeError, "sys.path must be a list");
+ return -1;
+ }
+ len = PyList_GET_SIZE(temp);
+ for (i = 0; i < len; ++i) {
+ PyObject *item = PyList_GET_ITEM(temp, i);
+ buffer = PyString_AsString(item);
+ if (buffer == NULL) {
+ pack_add_info(self, "sys-path-entry", "<non-string-path-entry>");
+ PyErr_Clear();
+ }
+ else {
+ pack_add_info(self, "sys-path-entry", buffer);
+ }
+ }
+ pack_frame_times(self);
+ pack_line_times(self);
+
+ return 0;
+}
+
+PyDoc_STRVAR(profiler__doc__,
+"profiler(logfilename[, lineevents[, linetimes]]) -> profiler\n\
+Create a new profiler object.");
+
+static PyObject *
+hotshot_profiler(PyObject *unused, PyObject *args)
+{
+ char *logfilename;
+ ProfilerObject *self = NULL;
+ int lineevents = 0;
+ int linetimings = 1;
+
+ if (PyArg_ParseTuple(args, "s|ii:profiler", &logfilename,
+ &lineevents, &linetimings)) {
+ self = PyObject_New(ProfilerObject, &ProfilerType);
+ if (self == NULL)
+ return NULL;
+ self->frametimings = 1;
+ self->lineevents = lineevents ? 1 : 0;
+ self->linetimings = (lineevents && linetimings) ? 1 : 0;
+ self->index = 0;
+ self->active = 0;
+ self->next_fileno = 0;
+ self->logfp = NULL;
+ self->logfilename = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(self->logfilename);
+ self->filemap = PyDict_New();
+ if (self->filemap == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->logfp = fopen(logfilename, "wb");
+ if (self->logfp == NULL) {
+ Py_DECREF(self);
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, logfilename);
+ return NULL;
+ }
+ if (timeofday_diff == 0) {
+ /* Run this several times since sometimes the first
+ * doesn't give the lowest values, and we're really trying
+ * to determine the lowest.
+ */
+ calibrate();
+ calibrate();
+ calibrate();
+ }
+ if (write_header(self)) {
+ /* some error occurred, exception has been set */
+ Py_DECREF(self);
+ self = NULL;
+ }
+ }
+ return (PyObject *) self;
+}
+
+PyDoc_STRVAR(coverage__doc__,
+"coverage(logfilename) -> profiler\n\
+Returns a profiler that doesn't collect any timing information, which is\n\
+useful in building a coverage analysis tool.");
+
+static PyObject *
+hotshot_coverage(PyObject *unused, PyObject *args)
+{
+ char *logfilename;
+ PyObject *result = NULL;
+
+ if (PyArg_ParseTuple(args, "s:coverage", &logfilename)) {
+ result = hotshot_profiler(unused, args);
+ if (result != NULL) {
+ ProfilerObject *self = (ProfilerObject *) result;
+ self->frametimings = 0;
+ self->linetimings = 0;
+ self->lineevents = 1;
+ }
+ }
+ return result;
+}
+
+PyDoc_VAR(resolution__doc__) =
+#ifdef MS_WINDOWS
+PyDoc_STR(
+"resolution() -> (performance-counter-ticks, update-frequency)\n"
+"Return the resolution of the timer provided by the QueryPerformanceCounter()\n"
+"function. The first value is the smallest observed change, and the second\n"
+"is the result of QueryPerformanceFrequency()."
+)
+#else
+PyDoc_STR(
+"resolution() -> (gettimeofday-usecs, getrusage-usecs)\n"
+"Return the resolution of the timers provided by the gettimeofday() and\n"
+"getrusage() system calls, or -1 if the call is not supported."
+)
+#endif
+;
+
+static PyObject *
+hotshot_resolution(PyObject *self, PyObject *unused)
+{
+ if (timeofday_diff == 0) {
+ calibrate();
+ calibrate();
+ calibrate();
+ }
+#ifdef MS_WINDOWS
+ return Py_BuildValue("ii", timeofday_diff, frequency.LowPart);
+#else
+ return Py_BuildValue("ii", timeofday_diff, rusage_diff);
+#endif
+}
+
+
+static PyMethodDef functions[] = {
+ {"coverage", hotshot_coverage, METH_VARARGS, coverage__doc__},
+ {"profiler", hotshot_profiler, METH_VARARGS, profiler__doc__},
+ {"logreader", hotshot_logreader, METH_VARARGS, logreader__doc__},
+ {"resolution", hotshot_resolution, METH_NOARGS, resolution__doc__},
+ {NULL, NULL}
+};
+
+
+void
+init_hotshot(void)
+{
+ PyObject *module;
+
+ LogReaderType.ob_type = &PyType_Type;
+ ProfilerType.ob_type = &PyType_Type;
+ module = Py_InitModule("_hotshot", functions);
+ if (module != NULL) {
+ char *s = get_version_string();
+
+ PyModule_AddStringConstant(module, "__version__", s);
+ free(s);
+ Py_INCREF(&LogReaderType);
+ PyModule_AddObject(module, "LogReaderType",
+ (PyObject *)&LogReaderType);
+ Py_INCREF(&ProfilerType);
+ PyModule_AddObject(module, "ProfilerType",
+ (PyObject *)&ProfilerType);
+
+ if (ProfilerError == NULL)
+ ProfilerError = PyErr_NewException("hotshot.ProfilerError",
+ NULL, NULL);
+ if (ProfilerError != NULL) {
+ Py_INCREF(ProfilerError);
+ PyModule_AddObject(module, "ProfilerError", ProfilerError);
+ }
+ PyModule_AddIntConstant(module, "WHAT_ENTER", WHAT_ENTER);
+ PyModule_AddIntConstant(module, "WHAT_EXIT", WHAT_EXIT);
+ PyModule_AddIntConstant(module, "WHAT_LINENO", WHAT_LINENO);
+ PyModule_AddIntConstant(module, "WHAT_OTHER", WHAT_OTHER);
+ PyModule_AddIntConstant(module, "WHAT_ADD_INFO", WHAT_ADD_INFO);
+ PyModule_AddIntConstant(module, "WHAT_DEFINE_FILE", WHAT_DEFINE_FILE);
+ PyModule_AddIntConstant(module, "WHAT_DEFINE_FUNC", WHAT_DEFINE_FUNC);
+ PyModule_AddIntConstant(module, "WHAT_LINE_TIMES", WHAT_LINE_TIMES);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_localemodule.c b/sys/src/cmd/python/Modules/_localemodule.c
new file mode 100644
index 000000000..7023bcf85
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_localemodule.c
@@ -0,0 +1,788 @@
+/***********************************************************
+Copyright (C) 1997, 2002, 2003 Martin von Loewis
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies.
+
+This software comes with no warranty. Use at your own risk.
+
+******************************************************************/
+
+#include "Python.h"
+
+#include <stdio.h>
+#include <locale.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+#ifdef HAVE_LIBINTL_H
+#include <libintl.h>
+#endif
+
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#if defined(MS_WINDOWS)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#ifdef RISCOS
+char *strdup(const char *);
+#endif
+
+PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
+
+static PyObject *Error;
+
+/* support functions for formatting floating point numbers */
+
+PyDoc_STRVAR(setlocale__doc__,
+"(integer,string=None) -> string. Activates/queries locale processing.");
+
+/* the grouping is terminated by either 0 or CHAR_MAX */
+static PyObject*
+copy_grouping(char* s)
+{
+ int i;
+ PyObject *result, *val = NULL;
+
+ if (s[0] == '\0')
+ /* empty string: no grouping at all */
+ return PyList_New(0);
+
+ for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
+ ; /* nothing */
+
+ result = PyList_New(i+1);
+ if (!result)
+ return NULL;
+
+ i = -1;
+ do {
+ i++;
+ val = PyInt_FromLong(s[i]);
+ if (!val)
+ break;
+ if (PyList_SetItem(result, i, val)) {
+ Py_DECREF(val);
+ val = NULL;
+ break;
+ }
+ } while (s[i] != '\0' && s[i] != CHAR_MAX);
+
+ if (!val) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
+}
+
+static void
+fixup_ulcase(void)
+{
+ PyObject *mods, *strop, *string, *ulo;
+ unsigned char ul[256];
+ int n, c;
+
+ /* find the string and strop modules */
+ mods = PyImport_GetModuleDict();
+ if (!mods)
+ return;
+ string = PyDict_GetItemString(mods, "string");
+ if (string)
+ string = PyModule_GetDict(string);
+ strop=PyDict_GetItemString(mods, "strop");
+ if (strop)
+ strop = PyModule_GetDict(strop);
+ if (!string && !strop)
+ return;
+
+ /* create uppercase map string */
+ n = 0;
+ for (c = 0; c < 256; c++) {
+ if (isupper(c))
+ ul[n++] = c;
+ }
+ ulo = PyString_FromStringAndSize((const char *)ul, n);
+ if (!ulo)
+ return;
+ if (string)
+ PyDict_SetItemString(string, "uppercase", ulo);
+ if (strop)
+ PyDict_SetItemString(strop, "uppercase", ulo);
+ Py_DECREF(ulo);
+
+ /* create lowercase string */
+ n = 0;
+ for (c = 0; c < 256; c++) {
+ if (islower(c))
+ ul[n++] = c;
+ }
+ ulo = PyString_FromStringAndSize((const char *)ul, n);
+ if (!ulo)
+ return;
+ if (string)
+ PyDict_SetItemString(string, "lowercase", ulo);
+ if (strop)
+ PyDict_SetItemString(strop, "lowercase", ulo);
+ Py_DECREF(ulo);
+
+ /* create letters string */
+ n = 0;
+ for (c = 0; c < 256; c++) {
+ if (isalpha(c))
+ ul[n++] = c;
+ }
+ ulo = PyString_FromStringAndSize((const char *)ul, n);
+ if (!ulo)
+ return;
+ if (string)
+ PyDict_SetItemString(string, "letters", ulo);
+ Py_DECREF(ulo);
+}
+
+static PyObject*
+PyLocale_setlocale(PyObject* self, PyObject* args)
+{
+ int category;
+ char *locale = NULL, *result;
+ PyObject *result_object;
+
+ if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
+ return NULL;
+
+ if (locale) {
+ /* set locale */
+ result = setlocale(category, locale);
+ if (!result) {
+ /* operation failed, no setting was changed */
+ PyErr_SetString(Error, "unsupported locale setting");
+ return NULL;
+ }
+ result_object = PyString_FromString(result);
+ if (!result_object)
+ return NULL;
+ /* record changes to LC_CTYPE */
+ if (category == LC_CTYPE || category == LC_ALL)
+ fixup_ulcase();
+ /* things that got wrong up to here are ignored */
+ PyErr_Clear();
+ } else {
+ /* get locale */
+ result = setlocale(category, NULL);
+ if (!result) {
+ PyErr_SetString(Error, "locale query failed");
+ return NULL;
+ }
+ result_object = PyString_FromString(result);
+ }
+ return result_object;
+}
+
+PyDoc_STRVAR(localeconv__doc__,
+"() -> dict. Returns numeric and monetary locale-specific parameters.");
+
+static PyObject*
+PyLocale_localeconv(PyObject* self)
+{
+ PyObject* result;
+ struct lconv *l;
+ PyObject *x;
+
+ result = PyDict_New();
+ if (!result)
+ return NULL;
+
+ /* if LC_NUMERIC is different in the C library, use saved value */
+ l = localeconv();
+
+ /* hopefully, the localeconv result survives the C library calls
+ involved herein */
+
+#define RESULT_STRING(s)\
+ x = PyString_FromString(l->s);\
+ if (!x) goto failed;\
+ PyDict_SetItemString(result, #s, x);\
+ Py_XDECREF(x)
+
+#define RESULT_INT(i)\
+ x = PyInt_FromLong(l->i);\
+ if (!x) goto failed;\
+ PyDict_SetItemString(result, #i, x);\
+ Py_XDECREF(x)
+
+ /* Numeric information */
+ RESULT_STRING(decimal_point);
+ RESULT_STRING(thousands_sep);
+ x = copy_grouping(l->grouping);
+ if (!x)
+ goto failed;
+ PyDict_SetItemString(result, "grouping", x);
+ Py_XDECREF(x);
+
+ /* Monetary information */
+ RESULT_STRING(int_curr_symbol);
+ RESULT_STRING(currency_symbol);
+ RESULT_STRING(mon_decimal_point);
+ RESULT_STRING(mon_thousands_sep);
+ x = copy_grouping(l->mon_grouping);
+ if (!x)
+ goto failed;
+ PyDict_SetItemString(result, "mon_grouping", x);
+ Py_XDECREF(x);
+ RESULT_STRING(positive_sign);
+ RESULT_STRING(negative_sign);
+ RESULT_INT(int_frac_digits);
+ RESULT_INT(frac_digits);
+ RESULT_INT(p_cs_precedes);
+ RESULT_INT(p_sep_by_space);
+ RESULT_INT(n_cs_precedes);
+ RESULT_INT(n_sep_by_space);
+ RESULT_INT(p_sign_posn);
+ RESULT_INT(n_sign_posn);
+ return result;
+
+ failed:
+ Py_XDECREF(result);
+ Py_XDECREF(x);
+ return NULL;
+}
+
+PyDoc_STRVAR(strcoll__doc__,
+"string,string -> int. Compares two strings according to the locale.");
+
+static PyObject*
+PyLocale_strcoll(PyObject* self, PyObject* args)
+{
+#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
+ char *s1,*s2;
+
+ if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
+ return NULL;
+ return PyInt_FromLong(strcoll(s1, s2));
+#else
+ PyObject *os1, *os2, *result = NULL;
+ wchar_t *ws1 = NULL, *ws2 = NULL;
+ int rel1 = 0, rel2 = 0, len1, len2;
+
+ if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
+ return NULL;
+ /* If both arguments are byte strings, use strcoll. */
+ if (PyString_Check(os1) && PyString_Check(os2))
+ return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
+ PyString_AS_STRING(os2)));
+ /* If neither argument is unicode, it's an error. */
+ if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
+ PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
+ }
+ /* Convert the non-unicode argument to unicode. */
+ if (!PyUnicode_Check(os1)) {
+ os1 = PyUnicode_FromObject(os1);
+ if (!os1)
+ return NULL;
+ rel1 = 1;
+ }
+ if (!PyUnicode_Check(os2)) {
+ os2 = PyUnicode_FromObject(os2);
+ if (!os2) {
+ Py_DECREF(os1);
+ return NULL;
+ }
+ rel2 = 1;
+ }
+ /* Convert the unicode strings to wchar[]. */
+ len1 = PyUnicode_GET_SIZE(os1) + 1;
+ ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
+ if (!ws1) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
+ goto done;
+ ws1[len1 - 1] = 0;
+ len2 = PyUnicode_GET_SIZE(os2) + 1;
+ ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
+ if (!ws2) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
+ goto done;
+ ws2[len2 - 1] = 0;
+ /* Collate the strings. */
+ result = PyInt_FromLong(wcscoll(ws1, ws2));
+ done:
+ /* Deallocate everything. */
+ if (ws1) PyMem_FREE(ws1);
+ if (ws2) PyMem_FREE(ws2);
+ if (rel1) {
+ Py_DECREF(os1);
+ }
+ if (rel2) {
+ Py_DECREF(os2);
+ }
+ return result;
+#endif
+}
+
+
+PyDoc_STRVAR(strxfrm__doc__,
+"string -> string. Returns a string that behaves for cmp locale-aware.");
+
+static PyObject*
+PyLocale_strxfrm(PyObject* self, PyObject* args)
+{
+ char *s, *buf;
+ size_t n1, n2;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
+ return NULL;
+
+ /* assume no change in size, first */
+ n1 = strlen(s) + 1;
+ buf = PyMem_Malloc(n1);
+ if (!buf)
+ return PyErr_NoMemory();
+ n2 = strxfrm(buf, s, n1) + 1;
+ if (n2 > n1) {
+ /* more space needed */
+ buf = PyMem_Realloc(buf, n2);
+ if (!buf)
+ return PyErr_NoMemory();
+ strxfrm(buf, s, n2);
+ }
+ result = PyString_FromString(buf);
+ PyMem_Free(buf);
+ return result;
+}
+
+#if defined(PLAN9APE)
+static PyObject*
+PyLocale_getdefaultlocale(PyObject *self)
+{
+ return Py_BuildValue("ss", Py_None, "UTF-8");
+}
+#endif
+
+#if defined(MS_WINDOWS)
+static PyObject*
+PyLocale_getdefaultlocale(PyObject* self)
+{
+ char encoding[100];
+ char locale[100];
+
+ PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
+
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+ LOCALE_SISO639LANGNAME,
+ locale, sizeof(locale))) {
+ Py_ssize_t i = strlen(locale);
+ locale[i++] = '_';
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+ LOCALE_SISO3166CTRYNAME,
+ locale+i, (int)(sizeof(locale)-i)))
+ return Py_BuildValue("ss", locale, encoding);
+ }
+
+ /* If we end up here, this windows version didn't know about
+ ISO639/ISO3166 names (it's probably Windows 95). Return the
+ Windows language identifier instead (a hexadecimal number) */
+
+ locale[0] = '0';
+ locale[1] = 'x';
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
+ locale+2, sizeof(locale)-2)) {
+ return Py_BuildValue("ss", locale, encoding);
+ }
+
+ /* cannot determine the language code (very unlikely) */
+ Py_INCREF(Py_None);
+ return Py_BuildValue("Os", Py_None, encoding);
+}
+#endif
+
+#if defined(__APPLE__)
+/*
+** Find out what the current script is.
+** Donated by Fredrik Lundh.
+*/
+static char *mac_getscript(void)
+{
+ CFStringEncoding enc = CFStringGetSystemEncoding();
+ static CFStringRef name = NULL;
+ /* Return the code name for the encodings for which we have codecs. */
+ switch(enc) {
+ case kCFStringEncodingMacRoman: return "mac-roman";
+ case kCFStringEncodingMacGreek: return "mac-greek";
+ case kCFStringEncodingMacCyrillic: return "mac-cyrillic";
+ case kCFStringEncodingMacTurkish: return "mac-turkish";
+ case kCFStringEncodingMacIcelandic: return "mac-icelandic";
+ /* XXX which one is mac-latin2? */
+ }
+ if (!name) {
+ /* This leaks an object. */
+ name = CFStringConvertEncodingToIANACharSetName(enc);
+ }
+ return (char *)CFStringGetCStringPtr(name, 0);
+}
+
+static PyObject*
+PyLocale_getdefaultlocale(PyObject* self)
+{
+ return Py_BuildValue("Os", Py_None, mac_getscript());
+}
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#define LANGINFO(X) {#X, X}
+struct langinfo_constant{
+ char* name;
+ int value;
+} langinfo_constants[] =
+{
+ /* These constants should exist on any langinfo implementation */
+ LANGINFO(DAY_1),
+ LANGINFO(DAY_2),
+ LANGINFO(DAY_3),
+ LANGINFO(DAY_4),
+ LANGINFO(DAY_5),
+ LANGINFO(DAY_6),
+ LANGINFO(DAY_7),
+
+ LANGINFO(ABDAY_1),
+ LANGINFO(ABDAY_2),
+ LANGINFO(ABDAY_3),
+ LANGINFO(ABDAY_4),
+ LANGINFO(ABDAY_5),
+ LANGINFO(ABDAY_6),
+ LANGINFO(ABDAY_7),
+
+ LANGINFO(MON_1),
+ LANGINFO(MON_2),
+ LANGINFO(MON_3),
+ LANGINFO(MON_4),
+ LANGINFO(MON_5),
+ LANGINFO(MON_6),
+ LANGINFO(MON_7),
+ LANGINFO(MON_8),
+ LANGINFO(MON_9),
+ LANGINFO(MON_10),
+ LANGINFO(MON_11),
+ LANGINFO(MON_12),
+
+ LANGINFO(ABMON_1),
+ LANGINFO(ABMON_2),
+ LANGINFO(ABMON_3),
+ LANGINFO(ABMON_4),
+ LANGINFO(ABMON_5),
+ LANGINFO(ABMON_6),
+ LANGINFO(ABMON_7),
+ LANGINFO(ABMON_8),
+ LANGINFO(ABMON_9),
+ LANGINFO(ABMON_10),
+ LANGINFO(ABMON_11),
+ LANGINFO(ABMON_12),
+
+#ifdef RADIXCHAR
+ /* The following are not available with glibc 2.0 */
+ LANGINFO(RADIXCHAR),
+ LANGINFO(THOUSEP),
+ /* YESSTR and NOSTR are deprecated in glibc, since they are
+ a special case of message translation, which should be rather
+ done using gettext. So we don't expose it to Python in the
+ first place.
+ LANGINFO(YESSTR),
+ LANGINFO(NOSTR),
+ */
+ LANGINFO(CRNCYSTR),
+#endif
+
+ LANGINFO(D_T_FMT),
+ LANGINFO(D_FMT),
+ LANGINFO(T_FMT),
+ LANGINFO(AM_STR),
+ LANGINFO(PM_STR),
+
+ /* The following constants are available only with XPG4, but...
+ AIX 3.2. only has CODESET.
+ OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
+ a few of the others.
+ Solution: ifdef-test them all. */
+#ifdef CODESET
+ LANGINFO(CODESET),
+#endif
+#ifdef T_FMT_AMPM
+ LANGINFO(T_FMT_AMPM),
+#endif
+#ifdef ERA
+ LANGINFO(ERA),
+#endif
+#ifdef ERA_D_FMT
+ LANGINFO(ERA_D_FMT),
+#endif
+#ifdef ERA_D_T_FMT
+ LANGINFO(ERA_D_T_FMT),
+#endif
+#ifdef ERA_T_FMT
+ LANGINFO(ERA_T_FMT),
+#endif
+#ifdef ALT_DIGITS
+ LANGINFO(ALT_DIGITS),
+#endif
+#ifdef YESEXPR
+ LANGINFO(YESEXPR),
+#endif
+#ifdef NOEXPR
+ LANGINFO(NOEXPR),
+#endif
+#ifdef _DATE_FMT
+ /* This is not available in all glibc versions that have CODESET. */
+ LANGINFO(_DATE_FMT),
+#endif
+ {0, 0}
+};
+
+PyDoc_STRVAR(nl_langinfo__doc__,
+"nl_langinfo(key) -> string\n"
+"Return the value for the locale information associated with key.");
+
+static PyObject*
+PyLocale_nl_langinfo(PyObject* self, PyObject* args)
+{
+ int item, i;
+ if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
+ return NULL;
+ /* Check whether this is a supported constant. GNU libc sometimes
+ returns numeric values in the char* return value, which would
+ crash PyString_FromString. */
+ for (i = 0; langinfo_constants[i].name; i++)
+ if (langinfo_constants[i].value == item) {
+ /* Check NULL as a workaround for GNU libc's returning NULL
+ instead of an empty string for nl_langinfo(ERA). */
+ const char *result = nl_langinfo(item);
+ return PyString_FromString(result != NULL ? result : "");
+ }
+ PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
+ return NULL;
+}
+#endif /* HAVE_LANGINFO_H */
+
+#ifdef HAVE_LIBINTL_H
+
+PyDoc_STRVAR(gettext__doc__,
+"gettext(msg) -> string\n"
+"Return translation of msg.");
+
+static PyObject*
+PyIntl_gettext(PyObject* self, PyObject *args)
+{
+ char *in;
+ if (!PyArg_ParseTuple(args, "z", &in))
+ return 0;
+ return PyString_FromString(gettext(in));
+}
+
+PyDoc_STRVAR(dgettext__doc__,
+"dgettext(domain, msg) -> string\n"
+"Return translation of msg in domain.");
+
+static PyObject*
+PyIntl_dgettext(PyObject* self, PyObject *args)
+{
+ char *domain, *in;
+ if (!PyArg_ParseTuple(args, "zz", &domain, &in))
+ return 0;
+ return PyString_FromString(dgettext(domain, in));
+}
+
+PyDoc_STRVAR(dcgettext__doc__,
+"dcgettext(domain, msg, category) -> string\n"
+"Return translation of msg in domain and category.");
+
+static PyObject*
+PyIntl_dcgettext(PyObject *self, PyObject *args)
+{
+ char *domain, *msgid;
+ int category;
+ if (!PyArg_ParseTuple(args, "zzi", &domain, &msgid, &category))
+ return 0;
+ return PyString_FromString(dcgettext(domain,msgid,category));
+}
+
+PyDoc_STRVAR(textdomain__doc__,
+"textdomain(domain) -> string\n"
+"Set the C library's textdmain to domain, returning the new domain.");
+
+static PyObject*
+PyIntl_textdomain(PyObject* self, PyObject* args)
+{
+ char *domain;
+ if (!PyArg_ParseTuple(args, "z", &domain))
+ return 0;
+ domain = textdomain(domain);
+ if (!domain) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+ return PyString_FromString(domain);
+}
+
+PyDoc_STRVAR(bindtextdomain__doc__,
+"bindtextdomain(domain, dir) -> string\n"
+"Bind the C library's domain to dir.");
+
+static PyObject*
+PyIntl_bindtextdomain(PyObject* self,PyObject*args)
+{
+ char *domain,*dirname;
+ if (!PyArg_ParseTuple(args, "zz", &domain, &dirname))
+ return 0;
+ dirname = bindtextdomain(domain, dirname);
+ if (!dirname) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+ return PyString_FromString(dirname);
+}
+
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+PyDoc_STRVAR(bind_textdomain_codeset__doc__,
+"bind_textdomain_codeset(domain, codeset) -> string\n"
+"Bind the C library's domain to codeset.");
+
+static PyObject*
+PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
+{
+ char *domain,*codeset;
+ if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
+ return NULL;
+ codeset = bind_textdomain_codeset(domain, codeset);
+ if (codeset)
+ return PyString_FromString(codeset);
+ Py_RETURN_NONE;
+}
+#endif
+
+#endif
+
+static struct PyMethodDef PyLocale_Methods[] = {
+ {"setlocale", (PyCFunction) PyLocale_setlocale,
+ METH_VARARGS, setlocale__doc__},
+ {"localeconv", (PyCFunction) PyLocale_localeconv,
+ METH_NOARGS, localeconv__doc__},
+ {"strcoll", (PyCFunction) PyLocale_strcoll,
+ METH_VARARGS, strcoll__doc__},
+ {"strxfrm", (PyCFunction) PyLocale_strxfrm,
+ METH_VARARGS, strxfrm__doc__},
+#if defined(MS_WINDOWS) || defined(__APPLE__) || defined(PLAN9APE)
+ {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
+#endif
+#ifdef HAVE_LANGINFO_H
+ {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
+ METH_VARARGS, nl_langinfo__doc__},
+#endif
+#ifdef HAVE_LIBINTL_H
+ {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
+ gettext__doc__},
+ {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
+ dgettext__doc__},
+ {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
+ dcgettext__doc__},
+ {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
+ textdomain__doc__},
+ {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
+ bindtextdomain__doc__},
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
+ METH_VARARGS, bind_textdomain_codeset__doc__},
+#endif
+#endif
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC
+init_locale(void)
+{
+ PyObject *m, *d, *x;
+#ifdef HAVE_LANGINFO_H
+ int i;
+#endif
+
+ m = Py_InitModule("_locale", PyLocale_Methods);
+ if (m == NULL)
+ return;
+
+ d = PyModule_GetDict(m);
+
+ x = PyInt_FromLong(LC_CTYPE);
+ PyDict_SetItemString(d, "LC_CTYPE", x);
+ Py_XDECREF(x);
+
+ x = PyInt_FromLong(LC_TIME);
+ PyDict_SetItemString(d, "LC_TIME", x);
+ Py_XDECREF(x);
+
+ x = PyInt_FromLong(LC_COLLATE);
+ PyDict_SetItemString(d, "LC_COLLATE", x);
+ Py_XDECREF(x);
+
+ x = PyInt_FromLong(LC_MONETARY);
+ PyDict_SetItemString(d, "LC_MONETARY", x);
+ Py_XDECREF(x);
+
+#ifdef LC_MESSAGES
+ x = PyInt_FromLong(LC_MESSAGES);
+ PyDict_SetItemString(d, "LC_MESSAGES", x);
+ Py_XDECREF(x);
+#endif /* LC_MESSAGES */
+
+ x = PyInt_FromLong(LC_NUMERIC);
+ PyDict_SetItemString(d, "LC_NUMERIC", x);
+ Py_XDECREF(x);
+
+ x = PyInt_FromLong(LC_ALL);
+ PyDict_SetItemString(d, "LC_ALL", x);
+ Py_XDECREF(x);
+
+ x = PyInt_FromLong(CHAR_MAX);
+ PyDict_SetItemString(d, "CHAR_MAX", x);
+ Py_XDECREF(x);
+
+ Error = PyErr_NewException("locale.Error", NULL, NULL);
+ PyDict_SetItemString(d, "Error", Error);
+
+ x = PyString_FromString(locale__doc__);
+ PyDict_SetItemString(d, "__doc__", x);
+ Py_XDECREF(x);
+
+#ifdef HAVE_LANGINFO_H
+ for (i = 0; langinfo_constants[i].name; i++) {
+ PyModule_AddIntConstant(m, langinfo_constants[i].name,
+ langinfo_constants[i].value);
+ }
+#endif
+}
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
diff --git a/sys/src/cmd/python/Modules/_lsprof.c b/sys/src/cmd/python/Modules/_lsprof.c
new file mode 100644
index 000000000..d35c894c5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_lsprof.c
@@ -0,0 +1,875 @@
+#include "Python.h"
+#include "compile.h"
+#include "frameobject.h"
+#include "structseq.h"
+#include "rotatingtree.h"
+
+#if !defined(HAVE_LONG_LONG)
+#error "This module requires long longs!"
+#endif
+
+/*** Selection of a high-precision timer ***/
+
+#ifdef MS_WINDOWS
+
+#include <windows.h>
+
+static PY_LONG_LONG
+hpTimer(void)
+{
+ LARGE_INTEGER li;
+ QueryPerformanceCounter(&li);
+ return li.QuadPart;
+}
+
+static double
+hpTimerUnit(void)
+{
+ LARGE_INTEGER li;
+ if (QueryPerformanceFrequency(&li))
+ return 1.0 / li.QuadPart;
+ else
+ return 0.000001; /* unlikely */
+}
+
+#else /* !MS_WINDOWS */
+
+#ifndef HAVE_GETTIMEOFDAY
+#error "This module requires gettimeofday() on non-Windows platforms!"
+#endif
+
+#if (defined(PYOS_OS2) && defined(PYCC_GCC))
+#include <sys/time.h>
+#else
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif
+
+static PY_LONG_LONG
+hpTimer(void)
+{
+ struct timeval tv;
+ PY_LONG_LONG ret;
+#ifdef GETTIMEOFDAY_NO_TZ
+ gettimeofday(&tv);
+#else
+ gettimeofday(&tv, (struct timezone *)NULL);
+#endif
+ ret = tv.tv_sec;
+ ret = ret * 1000000 + tv.tv_usec;
+ return ret;
+}
+
+static double
+hpTimerUnit(void)
+{
+ return 0.000001;
+}
+
+#endif /* MS_WINDOWS */
+
+/************************************************************/
+/* Written by Brett Rosen and Ted Czotter */
+
+struct _ProfilerEntry;
+
+/* represents a function called from another function */
+typedef struct _ProfilerSubEntry {
+ rotating_node_t header;
+ PY_LONG_LONG tt;
+ PY_LONG_LONG it;
+ long callcount;
+ long recursivecallcount;
+ long recursionLevel;
+} ProfilerSubEntry;
+
+/* represents a function or user defined block */
+typedef struct _ProfilerEntry {
+ rotating_node_t header;
+ PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */
+ PY_LONG_LONG tt; /* total time in this entry */
+ PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */
+ long callcount; /* how many times this was called */
+ long recursivecallcount; /* how many times called recursively */
+ long recursionLevel;
+ rotating_node_t *calls;
+} ProfilerEntry;
+
+typedef struct _ProfilerContext {
+ PY_LONG_LONG t0;
+ PY_LONG_LONG subt;
+ struct _ProfilerContext *previous;
+ ProfilerEntry *ctxEntry;
+} ProfilerContext;
+
+typedef struct {
+ PyObject_HEAD
+ rotating_node_t *profilerEntries;
+ ProfilerContext *currentProfilerContext;
+ ProfilerContext *freelistProfilerContext;
+ int flags;
+ PyObject *externalTimer;
+ double externalTimerUnit;
+} ProfilerObject;
+
+#define POF_ENABLED 0x001
+#define POF_SUBCALLS 0x002
+#define POF_BUILTINS 0x004
+#define POF_NOMEMORY 0x100
+
+staticforward PyTypeObject PyProfiler_Type;
+
+#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type)
+#define PyProfiler_CheckExact(op) ((op)->ob_type == &PyProfiler_Type)
+
+/*** External Timers ***/
+
+#define DOUBLE_TIMER_PRECISION 4294967296.0
+static PyObject *empty_tuple;
+
+static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj)
+{
+ PY_LONG_LONG result;
+ PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL);
+ if (o == NULL) {
+ PyErr_WriteUnraisable(pObj->externalTimer);
+ return 0;
+ }
+ if (pObj->externalTimerUnit > 0.0) {
+ /* interpret the result as an integer that will be scaled
+ in profiler_getstats() */
+ result = PyLong_AsLongLong(o);
+ }
+ else {
+ /* interpret the result as a double measured in seconds.
+ As the profiler works with PY_LONG_LONG internally
+ we convert it to a large integer */
+ double val = PyFloat_AsDouble(o);
+ /* error handling delayed to the code below */
+ result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION);
+ }
+ Py_DECREF(o);
+ if (PyErr_Occurred()) {
+ PyErr_WriteUnraisable((PyObject *) pObj);
+ return 0;
+ }
+ return result;
+}
+
+#define CALL_TIMER(pObj) ((pObj)->externalTimer ? \
+ CallExternalTimer(pObj) : \
+ hpTimer())
+
+/*** ProfilerObject ***/
+
+static PyObject *
+normalizeUserObj(PyObject *obj)
+{
+ PyCFunctionObject *fn;
+ if (!PyCFunction_Check(obj)) {
+ Py_INCREF(obj);
+ return obj;
+ }
+ /* Replace built-in function objects with a descriptive string
+ because of built-in methods -- keeping a reference to
+ __self__ is probably not a good idea. */
+ fn = (PyCFunctionObject *)obj;
+
+ if (fn->m_self == NULL) {
+ /* built-in function: look up the module name */
+ PyObject *mod = fn->m_module;
+ char *modname;
+ if (mod && PyString_Check(mod)) {
+ modname = PyString_AS_STRING(mod);
+ }
+ else if (mod && PyModule_Check(mod)) {
+ modname = PyModule_GetName(mod);
+ if (modname == NULL) {
+ PyErr_Clear();
+ modname = "__builtin__";
+ }
+ }
+ else {
+ modname = "__builtin__";
+ }
+ if (strcmp(modname, "__builtin__") != 0)
+ return PyString_FromFormat("<%s.%s>",
+ modname,
+ fn->m_ml->ml_name);
+ else
+ return PyString_FromFormat("<%s>",
+ fn->m_ml->ml_name);
+ }
+ else {
+ /* built-in method: try to return
+ repr(getattr(type(__self__), __name__))
+ */
+ PyObject *self = fn->m_self;
+ PyObject *name = PyString_FromString(fn->m_ml->ml_name);
+ if (name != NULL) {
+ PyObject *mo = _PyType_Lookup(self->ob_type, name);
+ Py_XINCREF(mo);
+ Py_DECREF(name);
+ if (mo != NULL) {
+ PyObject *res = PyObject_Repr(mo);
+ Py_DECREF(mo);
+ if (res != NULL)
+ return res;
+ }
+ }
+ PyErr_Clear();
+ return PyString_FromFormat("<built-in method %s>",
+ fn->m_ml->ml_name);
+ }
+}
+
+static ProfilerEntry*
+newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj)
+{
+ ProfilerEntry *self;
+ self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry));
+ if (self == NULL) {
+ pObj->flags |= POF_NOMEMORY;
+ return NULL;
+ }
+ userObj = normalizeUserObj(userObj);
+ if (userObj == NULL) {
+ PyErr_Clear();
+ free(self);
+ pObj->flags |= POF_NOMEMORY;
+ return NULL;
+ }
+ self->header.key = key;
+ self->userObj = userObj;
+ self->tt = 0;
+ self->it = 0;
+ self->callcount = 0;
+ self->recursivecallcount = 0;
+ self->recursionLevel = 0;
+ self->calls = EMPTY_ROTATING_TREE;
+ RotatingTree_Add(&pObj->profilerEntries, &self->header);
+ return self;
+}
+
+static ProfilerEntry*
+getEntry(ProfilerObject *pObj, void *key)
+{
+ return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key);
+}
+
+static ProfilerSubEntry *
+getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry)
+{
+ return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls,
+ (void *)entry);
+}
+
+static ProfilerSubEntry *
+newSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry)
+{
+ ProfilerSubEntry *self;
+ self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry));
+ if (self == NULL) {
+ pObj->flags |= POF_NOMEMORY;
+ return NULL;
+ }
+ self->header.key = (void *)entry;
+ self->tt = 0;
+ self->it = 0;
+ self->callcount = 0;
+ self->recursivecallcount = 0;
+ self->recursionLevel = 0;
+ RotatingTree_Add(&caller->calls, &self->header);
+ return self;
+}
+
+static int freeSubEntry(rotating_node_t *header, void *arg)
+{
+ ProfilerSubEntry *subentry = (ProfilerSubEntry*) header;
+ free(subentry);
+ return 0;
+}
+
+static int freeEntry(rotating_node_t *header, void *arg)
+{
+ ProfilerEntry *entry = (ProfilerEntry*) header;
+ RotatingTree_Enum(entry->calls, freeSubEntry, NULL);
+ Py_DECREF(entry->userObj);
+ free(entry);
+ return 0;
+}
+
+static void clearEntries(ProfilerObject *pObj)
+{
+ RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL);
+ pObj->profilerEntries = EMPTY_ROTATING_TREE;
+ /* release the memory hold by the free list of ProfilerContexts */
+ while (pObj->freelistProfilerContext) {
+ ProfilerContext *c = pObj->freelistProfilerContext;
+ pObj->freelistProfilerContext = c->previous;
+ free(c);
+ }
+}
+
+static void
+initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
+{
+ self->ctxEntry = entry;
+ self->subt = 0;
+ self->previous = pObj->currentProfilerContext;
+ pObj->currentProfilerContext = self;
+ ++entry->recursionLevel;
+ if ((pObj->flags & POF_SUBCALLS) && self->previous) {
+ /* find or create an entry for me in my caller's entry */
+ ProfilerEntry *caller = self->previous->ctxEntry;
+ ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
+ if (subentry == NULL)
+ subentry = newSubEntry(pObj, caller, entry);
+ if (subentry)
+ ++subentry->recursionLevel;
+ }
+ self->t0 = CALL_TIMER(pObj);
+}
+
+static void
+Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
+{
+ PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0;
+ PY_LONG_LONG it = tt - self->subt;
+ if (self->previous)
+ self->previous->subt += tt;
+ pObj->currentProfilerContext = self->previous;
+ if (--entry->recursionLevel == 0)
+ entry->tt += tt;
+ else
+ ++entry->recursivecallcount;
+ entry->it += it;
+ entry->callcount++;
+ if ((pObj->flags & POF_SUBCALLS) && self->previous) {
+ /* find or create an entry for me in my caller's entry */
+ ProfilerEntry *caller = self->previous->ctxEntry;
+ ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
+ if (subentry) {
+ if (--subentry->recursionLevel == 0)
+ subentry->tt += tt;
+ else
+ ++subentry->recursivecallcount;
+ subentry->it += it;
+ ++subentry->callcount;
+ }
+ }
+}
+
+static void
+ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
+{
+ /* entering a call to the function identified by 'key'
+ (which can be a PyCodeObject or a PyMethodDef pointer) */
+ ProfilerObject *pObj = (ProfilerObject*)self;
+ ProfilerEntry *profEntry;
+ ProfilerContext *pContext;
+
+ profEntry = getEntry(pObj, key);
+ if (profEntry == NULL) {
+ profEntry = newProfilerEntry(pObj, key, userObj);
+ if (profEntry == NULL)
+ return;
+ }
+ /* grab a ProfilerContext out of the free list */
+ pContext = pObj->freelistProfilerContext;
+ if (pContext) {
+ pObj->freelistProfilerContext = pContext->previous;
+ }
+ else {
+ /* free list exhausted, allocate a new one */
+ pContext = (ProfilerContext*)
+ malloc(sizeof(ProfilerContext));
+ if (pContext == NULL) {
+ pObj->flags |= POF_NOMEMORY;
+ return;
+ }
+ }
+ initContext(pObj, pContext, profEntry);
+}
+
+static void
+ptrace_leave_call(PyObject *self, void *key)
+{
+ /* leaving a call to the function identified by 'key' */
+ ProfilerObject *pObj = (ProfilerObject*)self;
+ ProfilerEntry *profEntry;
+ ProfilerContext *pContext;
+
+ pContext = pObj->currentProfilerContext;
+ if (pContext == NULL)
+ return;
+ profEntry = getEntry(pObj, key);
+ if (profEntry) {
+ Stop(pObj, pContext, profEntry);
+ }
+ else {
+ pObj->currentProfilerContext = pContext->previous;
+ }
+ /* put pContext into the free list */
+ pContext->previous = pObj->freelistProfilerContext;
+ pObj->freelistProfilerContext = pContext;
+}
+
+static int
+profiler_callback(PyObject *self, PyFrameObject *frame, int what,
+ PyObject *arg)
+{
+ switch (what) {
+
+ /* the 'frame' of a called function is about to start its execution */
+ case PyTrace_CALL:
+ ptrace_enter_call(self, (void *)frame->f_code,
+ (PyObject *)frame->f_code);
+ break;
+
+ /* the 'frame' of a called function is about to finish
+ (either normally or with an exception) */
+ case PyTrace_RETURN:
+ ptrace_leave_call(self, (void *)frame->f_code);
+ break;
+
+ /* case PyTrace_EXCEPTION:
+ If the exception results in the function exiting, a
+ PyTrace_RETURN event will be generated, so we don't need to
+ handle it. */
+
+#ifdef PyTrace_C_CALL /* not defined in Python <= 2.3 */
+ /* the Python function 'frame' is issuing a call to the built-in
+ function 'arg' */
+ case PyTrace_C_CALL:
+ if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
+ && PyCFunction_Check(arg)) {
+ ptrace_enter_call(self,
+ ((PyCFunctionObject *)arg)->m_ml,
+ arg);
+ }
+ break;
+
+ /* the call to the built-in function 'arg' is returning into its
+ caller 'frame' */
+ case PyTrace_C_RETURN: /* ...normally */
+ case PyTrace_C_EXCEPTION: /* ...with an exception set */
+ if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
+ && PyCFunction_Check(arg)) {
+ ptrace_leave_call(self,
+ ((PyCFunctionObject *)arg)->m_ml);
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int
+pending_exception(ProfilerObject *pObj)
+{
+ if (pObj->flags & POF_NOMEMORY) {
+ pObj->flags -= POF_NOMEMORY;
+ PyErr_SetString(PyExc_MemoryError,
+ "memory was exhausted while profiling");
+ return -1;
+ }
+ return 0;
+}
+
+/************************************************************/
+
+static PyStructSequence_Field profiler_entry_fields[] = {
+ {"code", "code object or built-in function name"},
+ {"callcount", "how many times this was called"},
+ {"reccallcount", "how many times called recursively"},
+ {"totaltime", "total time in this entry"},
+ {"inlinetime", "inline time in this entry (not in subcalls)"},
+ {"calls", "details of the calls"},
+ {0}
+};
+
+static PyStructSequence_Field profiler_subentry_fields[] = {
+ {"code", "called code object or built-in function name"},
+ {"callcount", "how many times this is called"},
+ {"reccallcount", "how many times this is called recursively"},
+ {"totaltime", "total time spent in this call"},
+ {"inlinetime", "inline time (not in further subcalls)"},
+ {0}
+};
+
+static PyStructSequence_Desc profiler_entry_desc = {
+ "_lsprof.profiler_entry", /* name */
+ NULL, /* doc */
+ profiler_entry_fields,
+ 6
+};
+
+static PyStructSequence_Desc profiler_subentry_desc = {
+ "_lsprof.profiler_subentry", /* name */
+ NULL, /* doc */
+ profiler_subentry_fields,
+ 5
+};
+
+static int initialized;
+static PyTypeObject StatsEntryType;
+static PyTypeObject StatsSubEntryType;
+
+
+typedef struct {
+ PyObject *list;
+ PyObject *sublist;
+ double factor;
+} statscollector_t;
+
+static int statsForSubEntry(rotating_node_t *node, void *arg)
+{
+ ProfilerSubEntry *sentry = (ProfilerSubEntry*) node;
+ statscollector_t *collect = (statscollector_t*) arg;
+ ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key;
+ int err;
+ PyObject *sinfo;
+ sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType,
+ "((Olldd))",
+ entry->userObj,
+ sentry->callcount,
+ sentry->recursivecallcount,
+ collect->factor * sentry->tt,
+ collect->factor * sentry->it);
+ if (sinfo == NULL)
+ return -1;
+ err = PyList_Append(collect->sublist, sinfo);
+ Py_DECREF(sinfo);
+ return err;
+}
+
+static int statsForEntry(rotating_node_t *node, void *arg)
+{
+ ProfilerEntry *entry = (ProfilerEntry*) node;
+ statscollector_t *collect = (statscollector_t*) arg;
+ PyObject *info;
+ int err;
+ if (entry->callcount == 0)
+ return 0; /* skip */
+
+ if (entry->calls != EMPTY_ROTATING_TREE) {
+ collect->sublist = PyList_New(0);
+ if (collect->sublist == NULL)
+ return -1;
+ if (RotatingTree_Enum(entry->calls,
+ statsForSubEntry, collect) != 0) {
+ Py_DECREF(collect->sublist);
+ return -1;
+ }
+ }
+ else {
+ Py_INCREF(Py_None);
+ collect->sublist = Py_None;
+ }
+
+ info = PyObject_CallFunction((PyObject*) &StatsEntryType,
+ "((OllddO))",
+ entry->userObj,
+ entry->callcount,
+ entry->recursivecallcount,
+ collect->factor * entry->tt,
+ collect->factor * entry->it,
+ collect->sublist);
+ Py_DECREF(collect->sublist);
+ if (info == NULL)
+ return -1;
+ err = PyList_Append(collect->list, info);
+ Py_DECREF(info);
+ return err;
+}
+
+PyDoc_STRVAR(getstats_doc, "\
+getstats() -> list of profiler_entry objects\n\
+\n\
+Return all information collected by the profiler.\n\
+Each profiler_entry is a tuple-like object with the\n\
+following attributes:\n\
+\n\
+ code code object\n\
+ callcount how many times this was called\n\
+ reccallcount how many times called recursively\n\
+ totaltime total time in this entry\n\
+ inlinetime inline time in this entry (not in subcalls)\n\
+ calls details of the calls\n\
+\n\
+The calls attribute is either None or a list of\n\
+profiler_subentry objects:\n\
+\n\
+ code called code object\n\
+ callcount how many times this is called\n\
+ reccallcount how many times this is called recursively\n\
+ totaltime total time spent in this call\n\
+ inlinetime inline time (not in further subcalls)\n\
+");
+
+static PyObject*
+profiler_getstats(ProfilerObject *pObj, PyObject* noarg)
+{
+ statscollector_t collect;
+ if (pending_exception(pObj))
+ return NULL;
+ if (!pObj->externalTimer)
+ collect.factor = hpTimerUnit();
+ else if (pObj->externalTimerUnit > 0.0)
+ collect.factor = pObj->externalTimerUnit;
+ else
+ collect.factor = 1.0 / DOUBLE_TIMER_PRECISION;
+ collect.list = PyList_New(0);
+ if (collect.list == NULL)
+ return NULL;
+ if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect)
+ != 0) {
+ Py_DECREF(collect.list);
+ return NULL;
+ }
+ return collect.list;
+}
+
+static int
+setSubcalls(ProfilerObject *pObj, int nvalue)
+{
+ if (nvalue == 0)
+ pObj->flags &= ~POF_SUBCALLS;
+ else if (nvalue > 0)
+ pObj->flags |= POF_SUBCALLS;
+ return 0;
+}
+
+static int
+setBuiltins(ProfilerObject *pObj, int nvalue)
+{
+ if (nvalue == 0)
+ pObj->flags &= ~POF_BUILTINS;
+ else if (nvalue > 0) {
+#ifndef PyTrace_C_CALL
+ PyErr_SetString(PyExc_ValueError,
+ "builtins=True requires Python >= 2.4");
+ return -1;
+#else
+ pObj->flags |= POF_BUILTINS;
+#endif
+ }
+ return 0;
+}
+
+PyDoc_STRVAR(enable_doc, "\
+enable(subcalls=True, builtins=True)\n\
+\n\
+Start collecting profiling information.\n\
+If 'subcalls' is True, also records for each function\n\
+statistics separated according to its current caller.\n\
+If 'builtins' is True, records the time spent in\n\
+built-in functions separately from their caller.\n\
+");
+
+static PyObject*
+profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds)
+{
+ int subcalls = -1;
+ int builtins = -1;
+ static char *kwlist[] = {"subcalls", "builtins", 0};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable",
+ kwlist, &subcalls, &builtins))
+ return NULL;
+ if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0)
+ return NULL;
+ PyEval_SetProfile(profiler_callback, (PyObject*)self);
+ self->flags |= POF_ENABLED;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static void
+flush_unmatched(ProfilerObject *pObj)
+{
+ while (pObj->currentProfilerContext) {
+ ProfilerContext *pContext = pObj->currentProfilerContext;
+ ProfilerEntry *profEntry= pContext->ctxEntry;
+ if (profEntry)
+ Stop(pObj, pContext, profEntry);
+ else
+ pObj->currentProfilerContext = pContext->previous;
+ if (pContext)
+ free(pContext);
+ }
+
+}
+
+PyDoc_STRVAR(disable_doc, "\
+disable()\n\
+\n\
+Stop collecting profiling information.\n\
+");
+
+static PyObject*
+profiler_disable(ProfilerObject *self, PyObject* noarg)
+{
+ self->flags &= ~POF_ENABLED;
+ PyEval_SetProfile(NULL, NULL);
+ flush_unmatched(self);
+ if (pending_exception(self))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(clear_doc, "\
+clear()\n\
+\n\
+Clear all profiling information collected so far.\n\
+");
+
+static PyObject*
+profiler_clear(ProfilerObject *pObj, PyObject* noarg)
+{
+ clearEntries(pObj);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static void
+profiler_dealloc(ProfilerObject *op)
+{
+ if (op->flags & POF_ENABLED)
+ PyEval_SetProfile(NULL, NULL);
+ flush_unmatched(op);
+ clearEntries(op);
+ Py_XDECREF(op->externalTimer);
+ op->ob_type->tp_free(op);
+}
+
+static int
+profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw)
+{
+ PyObject *o;
+ PyObject *timer = NULL;
+ double timeunit = 0.0;
+ int subcalls = 1;
+#ifdef PyTrace_C_CALL
+ int builtins = 1;
+#else
+ int builtins = 0;
+#endif
+ static char *kwlist[] = {"timer", "timeunit",
+ "subcalls", "builtins", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist,
+ &timer, &timeunit,
+ &subcalls, &builtins))
+ return -1;
+
+ if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0)
+ return -1;
+ o = pObj->externalTimer;
+ pObj->externalTimer = timer;
+ Py_XINCREF(timer);
+ Py_XDECREF(o);
+ pObj->externalTimerUnit = timeunit;
+ return 0;
+}
+
+static PyMethodDef profiler_methods[] = {
+ {"getstats", (PyCFunction)profiler_getstats,
+ METH_NOARGS, getstats_doc},
+ {"enable", (PyCFunction)profiler_enable,
+ METH_VARARGS | METH_KEYWORDS, enable_doc},
+ {"disable", (PyCFunction)profiler_disable,
+ METH_NOARGS, disable_doc},
+ {"clear", (PyCFunction)profiler_clear,
+ METH_NOARGS, clear_doc},
+ {NULL, NULL}
+};
+
+PyDoc_STRVAR(profiler_doc, "\
+Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\
+\n\
+ Builds a profiler object using the specified timer function.\n\
+ The default timer is a fast built-in one based on real time.\n\
+ For custom timer functions returning integers, time_unit can\n\
+ be a float specifying a scale (i.e. how long each integer unit\n\
+ is, in seconds).\n\
+");
+
+statichere PyTypeObject PyProfiler_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_lsprof.Profiler", /* tp_name */
+ sizeof(ProfilerObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)profiler_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ profiler_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ profiler_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)profiler_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+static PyMethodDef moduleMethods[] = {
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC
+init_lsprof(void)
+{
+ PyObject *module, *d;
+ module = Py_InitModule3("_lsprof", moduleMethods, "Fast profiler");
+ if (module == NULL)
+ return;
+ d = PyModule_GetDict(module);
+ if (PyType_Ready(&PyProfiler_Type) < 0)
+ return;
+ PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
+
+ if (!initialized) {
+ PyStructSequence_InitType(&StatsEntryType,
+ &profiler_entry_desc);
+ PyStructSequence_InitType(&StatsSubEntryType,
+ &profiler_subentry_desc);
+ }
+ Py_INCREF((PyObject*) &StatsEntryType);
+ Py_INCREF((PyObject*) &StatsSubEntryType);
+ PyModule_AddObject(module, "profiler_entry",
+ (PyObject*) &StatsEntryType);
+ PyModule_AddObject(module, "profiler_subentry",
+ (PyObject*) &StatsSubEntryType);
+ empty_tuple = PyTuple_New(0);
+ initialized = 1;
+}
diff --git a/sys/src/cmd/python/Modules/_randommodule.c b/sys/src/cmd/python/Modules/_randommodule.c
new file mode 100644
index 000000000..591947e47
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_randommodule.c
@@ -0,0 +1,580 @@
+/* Random objects */
+
+/* ------------------------------------------------------------------
+ The code in this module was based on a download from:
+ http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html
+
+ It was modified in 2002 by Raymond Hettinger as follows:
+
+ * the principal computational lines untouched except for tabbing.
+
+ * renamed genrand_res53() to random_random() and wrapped
+ in python calling/return code.
+
+ * genrand_int32() and the helper functions, init_genrand()
+ and init_by_array(), were declared static, wrapped in
+ Python calling/return code. also, their global data
+ references were replaced with structure references.
+
+ * unused functions from the original were deleted.
+ new, original C python code was added to implement the
+ Random() interface.
+
+ The following are the verbatim comments from the original code:
+
+ A C-program for MT19937, with initialization improved 2002/1/26.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+
+ Before using, initialize the state by using init_genrand(seed)
+ or init_by_array(init_key, key_length).
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Any feedback is very welcome.
+ http://www.math.keio.ac.jp/matumoto/emt.html
+ email: matumoto@math.keio.ac.jp
+*/
+
+/* ---------------------------------------------------------------*/
+
+#include "Python.h"
+#include <time.h> /* for seeding to current time */
+
+/* Period parameters -- These are all magic. Don't change. */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+typedef struct {
+ PyObject_HEAD
+ unsigned long state[N];
+ int index;
+} RandomObject;
+
+static PyTypeObject Random_Type;
+
+#define RandomObject_Check(v) ((v)->ob_type == &Random_Type)
+
+
+/* Random methods */
+
+
+/* generates a random number on [0,0xffffffff]-interval */
+static unsigned long
+genrand_int32(RandomObject *self)
+{
+ unsigned long y;
+ static unsigned long mag01[2]={0x0UL, MATRIX_A};
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+ unsigned long *mt;
+
+ mt = self->state;
+ if (self->index >= N) { /* generate N words at one time */
+ int kk;
+
+ for (kk=0;kk<N-M;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ for (;kk<N-1;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+ mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+ self->index = 0;
+ }
+
+ y = mt[self->index++];
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680UL;
+ y ^= (y << 15) & 0xefc60000UL;
+ y ^= (y >> 18);
+ return y;
+}
+
+/* random_random is the function named genrand_res53 in the original code;
+ * generates a random number on [0,1) with 53-bit resolution; note that
+ * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
+ * multiply-by-reciprocal in the (likely vain) hope that the compiler will
+ * optimize the division away at compile-time. 67108864 is 2**26. In
+ * effect, a contains 27 random bits shifted left 26, and b fills in the
+ * lower 26 bits of the 53-bit numerator.
+ * The orginal code credited Isaku Wada for this algorithm, 2002/01/09.
+ */
+static PyObject *
+random_random(RandomObject *self)
+{
+ unsigned long a=genrand_int32(self)>>5, b=genrand_int32(self)>>6;
+ return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
+}
+
+/* initializes mt[N] with a seed */
+static void
+init_genrand(RandomObject *self, unsigned long s)
+{
+ int mti;
+ unsigned long *mt;
+
+ mt = self->state;
+ mt[0]= s & 0xffffffffUL;
+ for (mti=1; mti<N; mti++) {
+ mt[mti] =
+ (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array mt[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ mt[mti] &= 0xffffffffUL;
+ /* for >32 bit machines */
+ }
+ self->index = mti;
+ return;
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+static PyObject *
+init_by_array(RandomObject *self, unsigned long init_key[], unsigned long key_length)
+{
+ unsigned int i, j, k; /* was signed in the original code. RDH 12/16/2002 */
+ unsigned long *mt;
+
+ mt = self->state;
+ init_genrand(self, 19650218UL);
+ i=1; j=0;
+ k = (N>key_length ? N : key_length);
+ for (; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
+ + init_key[j] + j; /* non linear */
+ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+ i++; j++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ if (j>=key_length) j=0;
+ }
+ for (k=N-1; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
+ - i; /* non linear */
+ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+ i++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ }
+
+ mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+ * The rest is Python-specific code, neither part of, nor derived from, the
+ * Twister download.
+ */
+
+static PyObject *
+random_seed(RandomObject *self, PyObject *args)
+{
+ PyObject *result = NULL; /* guilty until proved innocent */
+ PyObject *masklower = NULL;
+ PyObject *thirtytwo = NULL;
+ PyObject *n = NULL;
+ unsigned long *key = NULL;
+ unsigned long keymax; /* # of allocated slots in key */
+ unsigned long keyused; /* # of used slots in key */
+ int err;
+
+ PyObject *arg = NULL;
+
+ if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg))
+ return NULL;
+
+ if (arg == NULL || arg == Py_None) {
+ time_t now;
+
+ time(&now);
+ init_genrand(self, (unsigned long)now);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ /* If the arg is an int or long, use its absolute value; else use
+ * the absolute value of its hash code.
+ */
+ if (PyInt_Check(arg) || PyLong_Check(arg))
+ n = PyNumber_Absolute(arg);
+ else {
+ long hash = PyObject_Hash(arg);
+ if (hash == -1)
+ goto Done;
+ n = PyLong_FromUnsignedLong((unsigned long)hash);
+ }
+ if (n == NULL)
+ goto Done;
+
+ /* Now split n into 32-bit chunks, from the right. Each piece is
+ * stored into key, which has a capacity of keymax chunks, of which
+ * keyused are filled. Alas, the repeated shifting makes this a
+ * quadratic-time algorithm; we'd really like to use
+ * _PyLong_AsByteArray here, but then we'd have to break into the
+ * long representation to figure out how big an array was needed
+ * in advance.
+ */
+ keymax = 8; /* arbitrary; grows later if needed */
+ keyused = 0;
+ key = (unsigned long *)PyMem_Malloc(keymax * sizeof(*key));
+ if (key == NULL)
+ goto Done;
+
+ masklower = PyLong_FromUnsignedLong(0xffffffffU);
+ if (masklower == NULL)
+ goto Done;
+ thirtytwo = PyInt_FromLong(32L);
+ if (thirtytwo == NULL)
+ goto Done;
+ while ((err=PyObject_IsTrue(n))) {
+ PyObject *newn;
+ PyObject *pychunk;
+ unsigned long chunk;
+
+ if (err == -1)
+ goto Done;
+ pychunk = PyNumber_And(n, masklower);
+ if (pychunk == NULL)
+ goto Done;
+ chunk = PyLong_AsUnsignedLong(pychunk);
+ Py_DECREF(pychunk);
+ if (chunk == (unsigned long)-1 && PyErr_Occurred())
+ goto Done;
+ newn = PyNumber_Rshift(n, thirtytwo);
+ if (newn == NULL)
+ goto Done;
+ Py_DECREF(n);
+ n = newn;
+ if (keyused >= keymax) {
+ unsigned long bigger = keymax << 1;
+ if ((bigger >> 1) != keymax) {
+ PyErr_NoMemory();
+ goto Done;
+ }
+ key = (unsigned long *)PyMem_Realloc(key,
+ bigger * sizeof(*key));
+ if (key == NULL)
+ goto Done;
+ keymax = bigger;
+ }
+ assert(keyused < keymax);
+ key[keyused++] = chunk;
+ }
+
+ if (keyused == 0)
+ key[keyused++] = 0UL;
+ result = init_by_array(self, key, keyused);
+Done:
+ Py_XDECREF(masklower);
+ Py_XDECREF(thirtytwo);
+ Py_XDECREF(n);
+ PyMem_Free(key);
+ return result;
+}
+
+static PyObject *
+random_getstate(RandomObject *self)
+{
+ PyObject *state;
+ PyObject *element;
+ int i;
+
+ state = PyTuple_New(N+1);
+ if (state == NULL)
+ return NULL;
+ for (i=0; i<N ; i++) {
+ element = PyInt_FromLong((long)(self->state[i]));
+ if (element == NULL)
+ goto Fail;
+ PyTuple_SET_ITEM(state, i, element);
+ }
+ element = PyInt_FromLong((long)(self->index));
+ if (element == NULL)
+ goto Fail;
+ PyTuple_SET_ITEM(state, i, element);
+ return state;
+
+Fail:
+ Py_DECREF(state);
+ return NULL;
+}
+
+static PyObject *
+random_setstate(RandomObject *self, PyObject *state)
+{
+ int i;
+ long element;
+
+ if (!PyTuple_Check(state)) {
+ PyErr_SetString(PyExc_TypeError,
+ "state vector must be a tuple");
+ return NULL;
+ }
+ if (PyTuple_Size(state) != N+1) {
+ PyErr_SetString(PyExc_ValueError,
+ "state vector is the wrong size");
+ return NULL;
+ }
+
+ for (i=0; i<N ; i++) {
+ element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
+ if (element == -1 && PyErr_Occurred())
+ return NULL;
+ self->state[i] = (unsigned long)element;
+ }
+
+ element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
+ if (element == -1 && PyErr_Occurred())
+ return NULL;
+ self->index = (int)element;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+Jumpahead should be a fast way advance the generator n-steps ahead, but
+lacking a formula for that, the next best is to use n and the existing
+state to create a new state far away from the original.
+
+The generator uses constant spaced additive feedback, so shuffling the
+state elements ought to produce a state which would not be encountered
+(in the near term) by calls to random(). Shuffling is normally
+implemented by swapping the ith element with another element ranging
+from 0 to i inclusive. That allows the element to have the possibility
+of not being moved. Since the goal is to produce a new, different
+state, the swap element is ranged from 0 to i-1 inclusive. This assures
+that each element gets moved at least once.
+
+To make sure that consecutive calls to jumpahead(n) produce different
+states (even in the rare case of involutory shuffles), i+1 is added to
+each element at position i. Successive calls are then guaranteed to
+have changing (growing) values as well as shuffled positions.
+
+Finally, the self->index value is set to N so that the generator itself
+kicks in on the next call to random(). This assures that all results
+have been through the generator and do not just reflect alterations to
+the underlying state.
+*/
+
+static PyObject *
+random_jumpahead(RandomObject *self, PyObject *n)
+{
+ long i, j;
+ PyObject *iobj;
+ PyObject *remobj;
+ unsigned long *mt, tmp;
+
+ if (!PyInt_Check(n) && !PyLong_Check(n)) {
+ PyErr_Format(PyExc_TypeError, "jumpahead requires an "
+ "integer, not '%s'",
+ n->ob_type->tp_name);
+ return NULL;
+ }
+
+ mt = self->state;
+ for (i = N-1; i > 1; i--) {
+ iobj = PyInt_FromLong(i);
+ if (iobj == NULL)
+ return NULL;
+ remobj = PyNumber_Remainder(n, iobj);
+ Py_DECREF(iobj);
+ if (remobj == NULL)
+ return NULL;
+ j = PyInt_AsLong(remobj);
+ Py_DECREF(remobj);
+ if (j == -1L && PyErr_Occurred())
+ return NULL;
+ tmp = mt[i];
+ mt[i] = mt[j];
+ mt[j] = tmp;
+ }
+
+ for (i = 0; i < N; i++)
+ mt[i] += i+1;
+
+ self->index = N;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+random_getrandbits(RandomObject *self, PyObject *args)
+{
+ int k, i, bytes;
+ unsigned long r;
+ unsigned char *bytearray;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "i:getrandbits", &k))
+ return NULL;
+
+ if (k <= 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "number of bits must be greater than zero");
+ return NULL;
+ }
+
+ bytes = ((k - 1) / 32 + 1) * 4;
+ bytearray = (unsigned char *)PyMem_Malloc(bytes);
+ if (bytearray == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ /* Fill-out whole words, byte-by-byte to avoid endianness issues */
+ for (i=0 ; i<bytes ; i+=4, k-=32) {
+ r = genrand_int32(self);
+ if (k < 32)
+ r >>= (32 - k);
+ bytearray[i+0] = (unsigned char)r;
+ bytearray[i+1] = (unsigned char)(r >> 8);
+ bytearray[i+2] = (unsigned char)(r >> 16);
+ bytearray[i+3] = (unsigned char)(r >> 24);
+ }
+
+ /* little endian order to match bytearray assignment order */
+ result = _PyLong_FromByteArray(bytearray, bytes, 1, 0);
+ PyMem_Free(bytearray);
+ return result;
+}
+
+static PyObject *
+random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ RandomObject *self;
+ PyObject *tmp;
+
+ if (type == &Random_Type && !_PyArg_NoKeywords("Random()", kwds))
+ return NULL;
+
+ self = (RandomObject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+ tmp = random_seed(self, args);
+ if (tmp == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ Py_DECREF(tmp);
+ return (PyObject *)self;
+}
+
+static PyMethodDef random_methods[] = {
+ {"random", (PyCFunction)random_random, METH_NOARGS,
+ PyDoc_STR("random() -> x in the interval [0, 1).")},
+ {"seed", (PyCFunction)random_seed, METH_VARARGS,
+ PyDoc_STR("seed([n]) -> None. Defaults to current time.")},
+ {"getstate", (PyCFunction)random_getstate, METH_NOARGS,
+ PyDoc_STR("getstate() -> tuple containing the current state.")},
+ {"setstate", (PyCFunction)random_setstate, METH_O,
+ PyDoc_STR("setstate(state) -> None. Restores generator state.")},
+ {"jumpahead", (PyCFunction)random_jumpahead, METH_O,
+ PyDoc_STR("jumpahead(int) -> None. Create new state from "
+ "existing state and integer.")},
+ {"getrandbits", (PyCFunction)random_getrandbits, METH_VARARGS,
+ PyDoc_STR("getrandbits(k) -> x. Generates a long int with "
+ "k random bits.")},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(random_doc,
+"Random() -> create a random number generator with its own internal state.");
+
+static PyTypeObject Random_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_random.Random", /*tp_name*/
+ sizeof(RandomObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ random_doc, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ random_methods, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ random_new, /*tp_new*/
+ _PyObject_Del, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+PyDoc_STRVAR(module_doc,
+"Module implements the Mersenne Twister random number generator.");
+
+PyMODINIT_FUNC
+init_random(void)
+{
+ PyObject *m;
+
+ if (PyType_Ready(&Random_Type) < 0)
+ return;
+ m = Py_InitModule3("_random", NULL, module_doc);
+ if (m == NULL)
+ return;
+ Py_INCREF(&Random_Type);
+ PyModule_AddObject(m, "Random", (PyObject *)&Random_Type);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/cache.c b/sys/src/cmd/python/Modules/_sqlite/cache.c
new file mode 100644
index 000000000..6962695c8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/cache.c
@@ -0,0 +1,375 @@
+/* cache .c - a LRU cache
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "cache.h"
+#include <limits.h>
+
+/* only used internally */
+Node* new_node(PyObject* key, PyObject* data)
+{
+ Node* node;
+
+ node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
+ if (!node) {
+ return NULL;
+ }
+
+ Py_INCREF(key);
+ node->key = key;
+
+ Py_INCREF(data);
+ node->data = data;
+
+ node->prev = NULL;
+ node->next = NULL;
+
+ return node;
+}
+
+void node_dealloc(Node* self)
+{
+ Py_DECREF(self->key);
+ Py_DECREF(self->data);
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* factory;
+ int size = 10;
+
+ self->factory = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) {
+ return -1;
+ }
+
+ /* minimum cache size is 5 entries */
+ if (size < 5) {
+ size = 5;
+ }
+ self->size = size;
+ self->first = NULL;
+ self->last = NULL;
+
+ self->mapping = PyDict_New();
+ if (!self->mapping) {
+ return -1;
+ }
+
+ Py_INCREF(factory);
+ self->factory = factory;
+
+ self->decref_factory = 1;
+
+ return 0;
+}
+
+void cache_dealloc(Cache* self)
+{
+ Node* node;
+ Node* delete_node;
+
+ if (!self->factory) {
+ /* constructor failed, just get out of here */
+ return;
+ }
+
+ /* iterate over all nodes and deallocate them */
+ node = self->first;
+ while (node) {
+ delete_node = node;
+ node = node->next;
+ Py_DECREF(delete_node);
+ }
+
+ if (self->decref_factory) {
+ Py_DECREF(self->factory);
+ }
+ Py_DECREF(self->mapping);
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+PyObject* cache_get(Cache* self, PyObject* args)
+{
+ PyObject* key = args;
+ Node* node;
+ Node* ptr;
+ PyObject* data;
+
+ node = (Node*)PyDict_GetItem(self->mapping, key);
+ if (node) {
+ /* an entry for this key already exists in the cache */
+
+ /* increase usage counter of the node found */
+ if (node->count < LONG_MAX) {
+ node->count++;
+ }
+
+ /* if necessary, reorder entries in the cache by swapping positions */
+ if (node->prev && node->count > node->prev->count) {
+ ptr = node->prev;
+
+ while (ptr->prev && node->count > ptr->prev->count) {
+ ptr = ptr->prev;
+ }
+
+ if (node->next) {
+ node->next->prev = node->prev;
+ } else {
+ self->last = node->prev;
+ }
+ if (node->prev) {
+ node->prev->next = node->next;
+ }
+ if (ptr->prev) {
+ ptr->prev->next = node;
+ } else {
+ self->first = node;
+ }
+
+ node->next = ptr;
+ node->prev = ptr->prev;
+ if (!node->prev) {
+ self->first = node;
+ }
+ ptr->prev = node;
+ }
+ } else {
+ /* There is no entry for this key in the cache, yet. We'll insert a new
+ * entry in the cache, and make space if necessary by throwing the
+ * least used item out of the cache. */
+
+ if (PyDict_Size(self->mapping) == self->size) {
+ if (self->last) {
+ node = self->last;
+
+ if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
+ return NULL;
+ }
+
+ if (node->prev) {
+ node->prev->next = NULL;
+ }
+ self->last = node->prev;
+ node->prev = NULL;
+
+ Py_DECREF(node);
+ }
+ }
+
+ data = PyObject_CallFunction(self->factory, "O", key);
+
+ if (!data) {
+ return NULL;
+ }
+
+ node = new_node(key, data);
+ if (!node) {
+ return NULL;
+ }
+ node->prev = self->last;
+
+ Py_DECREF(data);
+
+ if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
+ Py_DECREF(node);
+ return NULL;
+ }
+
+ if (self->last) {
+ self->last->next = node;
+ } else {
+ self->first = node;
+ }
+ self->last = node;
+ }
+
+ Py_INCREF(node->data);
+ return node->data;
+}
+
+PyObject* cache_display(Cache* self, PyObject* args)
+{
+ Node* ptr;
+ PyObject* prevkey;
+ PyObject* nextkey;
+ PyObject* fmt_args;
+ PyObject* template;
+ PyObject* display_str;
+
+ ptr = self->first;
+
+ while (ptr) {
+ if (ptr->prev) {
+ prevkey = ptr->prev->key;
+ } else {
+ prevkey = Py_None;
+ }
+ Py_INCREF(prevkey);
+
+ if (ptr->next) {
+ nextkey = ptr->next->key;
+ } else {
+ nextkey = Py_None;
+ }
+ Py_INCREF(nextkey);
+
+ fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
+ if (!fmt_args) {
+ return NULL;
+ }
+ template = PyString_FromString("%s <- %s ->%s\n");
+ if (!template) {
+ return NULL;
+ }
+ display_str = PyString_Format(template, fmt_args);
+ Py_DECREF(template);
+ Py_DECREF(fmt_args);
+ if (!display_str) {
+ return NULL;
+ }
+ PyObject_Print(display_str, stdout, Py_PRINT_RAW);
+ Py_DECREF(display_str);
+
+ Py_DECREF(prevkey);
+ Py_DECREF(nextkey);
+
+ ptr = ptr->next;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef cache_methods[] = {
+ {"get", (PyCFunction)cache_get, METH_O,
+ PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
+ {"display", (PyCFunction)cache_display, METH_NOARGS,
+ PyDoc_STR("For debugging only.")},
+ {NULL, NULL}
+};
+
+PyTypeObject NodeType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME "Node", /* tp_name */
+ sizeof(Node), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)node_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+PyTypeObject CacheType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME ".Cache", /* tp_name */
+ sizeof(Cache), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)cache_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ cache_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)cache_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+extern int cache_setup_types(void)
+{
+ int rc;
+
+ NodeType.tp_new = PyType_GenericNew;
+ CacheType.tp_new = PyType_GenericNew;
+
+ rc = PyType_Ready(&NodeType);
+ if (rc < 0) {
+ return rc;
+ }
+
+ rc = PyType_Ready(&CacheType);
+ return rc;
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/cache.h b/sys/src/cmd/python/Modules/_sqlite/cache.h
new file mode 100644
index 000000000..1f13907b7
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/cache.h
@@ -0,0 +1,73 @@
+/* cache.h - definitions for the LRU cache
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_CACHE_H
+#define PYSQLITE_CACHE_H
+#include "Python.h"
+
+/* The LRU cache is implemented as a combination of a doubly-linked with a
+ * dictionary. The list items are of type 'Node' and the dictionary has the
+ * nodes as values. */
+
+typedef struct _Node
+{
+ PyObject_HEAD
+ PyObject* key;
+ PyObject* data;
+ long count;
+ struct _Node* prev;
+ struct _Node* next;
+} Node;
+
+typedef struct
+{
+ PyObject_HEAD
+ int size;
+
+ /* a dictionary mapping keys to Node entries */
+ PyObject* mapping;
+
+ /* the factory callable */
+ PyObject* factory;
+
+ Node* first;
+ Node* last;
+
+ /* if set, decrement the factory function when the Cache is deallocated.
+ * this is almost always desirable, but not in the pysqlite context */
+ int decref_factory;
+} Cache;
+
+extern PyTypeObject NodeType;
+extern PyTypeObject CacheType;
+
+int node_init(Node* self, PyObject* args, PyObject* kwargs);
+void node_dealloc(Node* self);
+
+int cache_init(Cache* self, PyObject* args, PyObject* kwargs);
+void cache_dealloc(Cache* self);
+PyObject* cache_get(Cache* self, PyObject* args);
+
+int cache_setup_types(void);
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/connection.c b/sys/src/cmd/python/Modules/_sqlite/connection.c
new file mode 100644
index 000000000..703af15fa
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/connection.c
@@ -0,0 +1,1255 @@
+/* connection.c - the connection type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "cache.h"
+#include "module.h"
+#include "connection.h"
+#include "statement.h"
+#include "cursor.h"
+#include "prepare_protocol.h"
+#include "util.h"
+#include "sqlitecompat.h"
+
+#include "pythread.h"
+
+static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
+
+
+void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
+{
+ /* in older SQLite versions, calling sqlite3_result_error in callbacks
+ * triggers a bug in SQLite that leads either to irritating results or
+ * segfaults, depending on the SQLite version */
+#if SQLITE_VERSION_NUMBER >= 3003003
+ sqlite3_result_error(ctx, errmsg, len);
+#else
+ PyErr_SetString(OperationalError, errmsg);
+#endif
+}
+
+int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
+
+ char* database;
+ int detect_types = 0;
+ PyObject* isolation_level = NULL;
+ PyObject* factory = NULL;
+ int check_same_thread = 1;
+ int cached_statements = 100;
+ double timeout = 5.0;
+ int rc;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
+ &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
+ {
+ return -1;
+ }
+
+ self->begin_statement = NULL;
+
+ self->statement_cache = NULL;
+ self->statements = NULL;
+
+ Py_INCREF(Py_None);
+ self->row_factory = Py_None;
+
+ Py_INCREF(&PyUnicode_Type);
+ self->text_factory = (PyObject*)&PyUnicode_Type;
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_open(database, &self->db);
+ Py_END_ALLOW_THREADS
+
+ if (rc != SQLITE_OK) {
+ _seterror(self->db);
+ return -1;
+ }
+
+ if (!isolation_level) {
+ isolation_level = PyString_FromString("");
+ if (!isolation_level) {
+ return -1;
+ }
+ } else {
+ Py_INCREF(isolation_level);
+ }
+ self->isolation_level = NULL;
+ connection_set_isolation_level(self, isolation_level);
+ Py_DECREF(isolation_level);
+
+ self->statement_cache = (Cache*)PyObject_CallFunction((PyObject*)&CacheType, "Oi", self, cached_statements);
+ if (PyErr_Occurred()) {
+ return -1;
+ }
+
+ self->statements = PyList_New(0);
+ if (!self->statements) {
+ return -1;
+ }
+ self->created_statements = 0;
+
+ /* By default, the Cache class INCREFs the factory in its initializer, and
+ * decrefs it in its deallocator method. Since this would create a circular
+ * reference here, we're breaking it by decrementing self, and telling the
+ * cache class to not decref the factory (self) in its deallocator.
+ */
+ self->statement_cache->decref_factory = 0;
+ Py_DECREF(self);
+
+ self->inTransaction = 0;
+ self->detect_types = detect_types;
+ self->timeout = timeout;
+ (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
+
+ self->thread_ident = PyThread_get_thread_ident();
+ self->check_same_thread = check_same_thread;
+
+ self->function_pinboard = PyDict_New();
+ if (!self->function_pinboard) {
+ return -1;
+ }
+
+ self->collations = PyDict_New();
+ if (!self->collations) {
+ return -1;
+ }
+
+ self->Warning = Warning;
+ self->Error = Error;
+ self->InterfaceError = InterfaceError;
+ self->DatabaseError = DatabaseError;
+ self->DataError = DataError;
+ self->OperationalError = OperationalError;
+ self->IntegrityError = IntegrityError;
+ self->InternalError = InternalError;
+ self->ProgrammingError = ProgrammingError;
+ self->NotSupportedError = NotSupportedError;
+
+ return 0;
+}
+
+/* Empty the entire statement cache of this connection */
+void flush_statement_cache(Connection* self)
+{
+ Node* node;
+ Statement* statement;
+
+ node = self->statement_cache->first;
+
+ while (node) {
+ statement = (Statement*)(node->data);
+ (void)statement_finalize(statement);
+ node = node->next;
+ }
+
+ Py_DECREF(self->statement_cache);
+ self->statement_cache = (Cache*)PyObject_CallFunction((PyObject*)&CacheType, "O", self);
+ Py_DECREF(self);
+ self->statement_cache->decref_factory = 0;
+}
+
+void reset_all_statements(Connection* self)
+{
+ int i;
+ PyObject* weakref;
+ PyObject* statement;
+
+ for (i = 0; i < PyList_Size(self->statements); i++) {
+ weakref = PyList_GetItem(self->statements, i);
+ statement = PyWeakref_GetObject(weakref);
+ if (statement != Py_None) {
+ (void)statement_reset((Statement*)statement);
+ }
+ }
+}
+
+void connection_dealloc(Connection* self)
+{
+ Py_XDECREF(self->statement_cache);
+
+ /* Clean up if user has not called .close() explicitly. */
+ if (self->db) {
+ Py_BEGIN_ALLOW_THREADS
+ sqlite3_close(self->db);
+ Py_END_ALLOW_THREADS
+ }
+
+ if (self->begin_statement) {
+ PyMem_Free(self->begin_statement);
+ }
+ Py_XDECREF(self->isolation_level);
+ Py_XDECREF(self->function_pinboard);
+ Py_XDECREF(self->row_factory);
+ Py_XDECREF(self->text_factory);
+ Py_XDECREF(self->collations);
+ Py_XDECREF(self->statements);
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ static char *kwlist[] = {"factory", NULL, NULL};
+ PyObject* factory = NULL;
+ PyObject* cursor;
+
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
+ &factory)) {
+ return NULL;
+ }
+
+ if (!check_thread(self) || !check_connection(self)) {
+ return NULL;
+ }
+
+ if (factory == NULL) {
+ factory = (PyObject*)&CursorType;
+ }
+
+ cursor = PyObject_CallFunction(factory, "O", self);
+
+ if (cursor && self->row_factory != Py_None) {
+ Py_XDECREF(((Cursor*)cursor)->row_factory);
+ Py_INCREF(self->row_factory);
+ ((Cursor*)cursor)->row_factory = self->row_factory;
+ }
+
+ return cursor;
+}
+
+PyObject* connection_close(Connection* self, PyObject* args)
+{
+ int rc;
+
+ if (!check_thread(self)) {
+ return NULL;
+ }
+
+ flush_statement_cache(self);
+
+ if (self->db) {
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_close(self->db);
+ Py_END_ALLOW_THREADS
+
+ if (rc != SQLITE_OK) {
+ _seterror(self->db);
+ return NULL;
+ } else {
+ self->db = NULL;
+ }
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+ * Checks if a connection object is usable (i. e. not closed).
+ *
+ * 0 => error; 1 => ok
+ */
+int check_connection(Connection* con)
+{
+ if (!con->db) {
+ PyErr_SetString(ProgrammingError, "Cannot operate on a closed database.");
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+PyObject* _connection_begin(Connection* self)
+{
+ int rc;
+ const char* tail;
+ sqlite3_stmt* statement;
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_prepare(self->db, self->begin_statement, -1, &statement, &tail);
+ Py_END_ALLOW_THREADS
+
+ if (rc != SQLITE_OK) {
+ _seterror(self->db);
+ goto error;
+ }
+
+ rc = _sqlite_step_with_busyhandler(statement, self);
+ if (rc == SQLITE_DONE) {
+ self->inTransaction = 1;
+ } else {
+ _seterror(self->db);
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_finalize(statement);
+ Py_END_ALLOW_THREADS
+
+ if (rc != SQLITE_OK && !PyErr_Occurred()) {
+ _seterror(self->db);
+ }
+
+error:
+ if (PyErr_Occurred()) {
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyObject* connection_commit(Connection* self, PyObject* args)
+{
+ int rc;
+ const char* tail;
+ sqlite3_stmt* statement;
+
+ if (!check_thread(self) || !check_connection(self)) {
+ return NULL;
+ }
+
+ if (self->inTransaction) {
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
+ Py_END_ALLOW_THREADS
+ if (rc != SQLITE_OK) {
+ _seterror(self->db);
+ goto error;
+ }
+
+ rc = _sqlite_step_with_busyhandler(statement, self);
+ if (rc == SQLITE_DONE) {
+ self->inTransaction = 0;
+ } else {
+ _seterror(self->db);
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_finalize(statement);
+ Py_END_ALLOW_THREADS
+ if (rc != SQLITE_OK && !PyErr_Occurred()) {
+ _seterror(self->db);
+ }
+
+ }
+
+error:
+ if (PyErr_Occurred()) {
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyObject* connection_rollback(Connection* self, PyObject* args)
+{
+ int rc;
+ const char* tail;
+ sqlite3_stmt* statement;
+
+ if (!check_thread(self) || !check_connection(self)) {
+ return NULL;
+ }
+
+ if (self->inTransaction) {
+ reset_all_statements(self);
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
+ Py_END_ALLOW_THREADS
+ if (rc != SQLITE_OK) {
+ _seterror(self->db);
+ goto error;
+ }
+
+ rc = _sqlite_step_with_busyhandler(statement, self);
+ if (rc == SQLITE_DONE) {
+ self->inTransaction = 0;
+ } else {
+ _seterror(self->db);
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_finalize(statement);
+ Py_END_ALLOW_THREADS
+ if (rc != SQLITE_OK && !PyErr_Occurred()) {
+ _seterror(self->db);
+ }
+
+ }
+
+error:
+ if (PyErr_Occurred()) {
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+void _set_result(sqlite3_context* context, PyObject* py_val)
+{
+ long longval;
+ const char* buffer;
+ Py_ssize_t buflen;
+ PyObject* stringval;
+
+ if ((!py_val) || PyErr_Occurred()) {
+ sqlite3_result_null(context);
+ } else if (py_val == Py_None) {
+ sqlite3_result_null(context);
+ } else if (PyInt_Check(py_val)) {
+ longval = PyInt_AsLong(py_val);
+ sqlite3_result_int64(context, (PY_LONG_LONG)longval);
+ } else if (PyFloat_Check(py_val)) {
+ sqlite3_result_double(context, PyFloat_AsDouble(py_val));
+ } else if (PyBuffer_Check(py_val)) {
+ if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
+ PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
+ } else {
+ sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
+ }
+ } else if (PyString_Check(py_val)) {
+ sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT);
+ } else if (PyUnicode_Check(py_val)) {
+ stringval = PyUnicode_AsUTF8String(py_val);
+ if (stringval) {
+ sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
+ Py_DECREF(stringval);
+ }
+ } else {
+ /* TODO: raise error */
+ }
+}
+
+PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv)
+{
+ PyObject* args;
+ int i;
+ sqlite3_value* cur_value;
+ PyObject* cur_py_value;
+ const char* val_str;
+ PY_LONG_LONG val_int;
+ Py_ssize_t buflen;
+ void* raw_buffer;
+
+ args = PyTuple_New(argc);
+ if (!args) {
+ return NULL;
+ }
+
+ for (i = 0; i < argc; i++) {
+ cur_value = argv[i];
+ switch (sqlite3_value_type(argv[i])) {
+ case SQLITE_INTEGER:
+ val_int = sqlite3_value_int64(cur_value);
+ cur_py_value = PyInt_FromLong((long)val_int);
+ break;
+ case SQLITE_FLOAT:
+ cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
+ break;
+ case SQLITE_TEXT:
+ val_str = (const char*)sqlite3_value_text(cur_value);
+ cur_py_value = PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
+ /* TODO: have a way to show errors here */
+ if (!cur_py_value) {
+ PyErr_Clear();
+ Py_INCREF(Py_None);
+ cur_py_value = Py_None;
+ }
+ break;
+ case SQLITE_BLOB:
+ buflen = sqlite3_value_bytes(cur_value);
+ cur_py_value = PyBuffer_New(buflen);
+ if (!cur_py_value) {
+ break;
+ }
+ if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) {
+ Py_DECREF(cur_py_value);
+ cur_py_value = NULL;
+ break;
+ }
+ memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen);
+ break;
+ case SQLITE_NULL:
+ default:
+ Py_INCREF(Py_None);
+ cur_py_value = Py_None;
+ }
+
+ if (!cur_py_value) {
+ Py_DECREF(args);
+ return NULL;
+ }
+
+ PyTuple_SetItem(args, i, cur_py_value);
+
+ }
+
+ return args;
+}
+
+void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
+{
+ PyObject* args;
+ PyObject* py_func;
+ PyObject* py_retval = NULL;
+
+ PyGILState_STATE threadstate;
+
+ threadstate = PyGILState_Ensure();
+
+ py_func = (PyObject*)sqlite3_user_data(context);
+
+ args = _build_py_params(context, argc, argv);
+ if (args) {
+ py_retval = PyObject_CallObject(py_func, args);
+ Py_DECREF(args);
+ }
+
+ if (py_retval) {
+ _set_result(context, py_retval);
+ Py_DECREF(py_retval);
+ } else {
+ if (_enable_callback_tracebacks) {
+ PyErr_Print();
+ } else {
+ PyErr_Clear();
+ }
+ _sqlite3_result_error(context, "user-defined function raised exception", -1);
+ }
+
+ PyGILState_Release(threadstate);
+}
+
+static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
+{
+ PyObject* args;
+ PyObject* function_result = NULL;
+ PyObject* aggregate_class;
+ PyObject** aggregate_instance;
+ PyObject* stepmethod = NULL;
+
+ PyGILState_STATE threadstate;
+
+ threadstate = PyGILState_Ensure();
+
+ aggregate_class = (PyObject*)sqlite3_user_data(context);
+
+ aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
+
+ if (*aggregate_instance == 0) {
+ *aggregate_instance = PyObject_CallFunction(aggregate_class, "");
+
+ if (PyErr_Occurred()) {
+ *aggregate_instance = 0;
+ if (_enable_callback_tracebacks) {
+ PyErr_Print();
+ } else {
+ PyErr_Clear();
+ }
+ _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
+ goto error;
+ }
+ }
+
+ stepmethod = PyObject_GetAttrString(*aggregate_instance, "step");
+ if (!stepmethod) {
+ goto error;
+ }
+
+ args = _build_py_params(context, argc, params);
+ if (!args) {
+ goto error;
+ }
+
+ function_result = PyObject_CallObject(stepmethod, args);
+ Py_DECREF(args);
+
+ if (!function_result) {
+ if (_enable_callback_tracebacks) {
+ PyErr_Print();
+ } else {
+ PyErr_Clear();
+ }
+ _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
+ }
+
+error:
+ Py_XDECREF(stepmethod);
+ Py_XDECREF(function_result);
+
+ PyGILState_Release(threadstate);
+}
+
+void _final_callback(sqlite3_context* context)
+{
+ PyObject* function_result = NULL;
+ PyObject** aggregate_instance;
+ PyObject* aggregate_class;
+
+ PyGILState_STATE threadstate;
+
+ threadstate = PyGILState_Ensure();
+
+ aggregate_class = (PyObject*)sqlite3_user_data(context);
+
+ aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
+ if (!*aggregate_instance) {
+ /* this branch is executed if there was an exception in the aggregate's
+ * __init__ */
+
+ goto error;
+ }
+
+ function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
+ if (!function_result) {
+ if (_enable_callback_tracebacks) {
+ PyErr_Print();
+ } else {
+ PyErr_Clear();
+ }
+ _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
+ } else {
+ _set_result(context, function_result);
+ }
+
+error:
+ Py_XDECREF(*aggregate_instance);
+ Py_XDECREF(function_result);
+
+ PyGILState_Release(threadstate);
+}
+
+void _drop_unused_statement_references(Connection* self)
+{
+ PyObject* new_list;
+ PyObject* weakref;
+ int i;
+
+ /* we only need to do this once in a while */
+ if (self->created_statements++ < 200) {
+ return;
+ }
+
+ self->created_statements = 0;
+
+ new_list = PyList_New(0);
+ if (!new_list) {
+ return;
+ }
+
+ for (i = 0; i < PyList_Size(self->statements); i++) {
+ weakref = PyList_GetItem(self->statements, i);
+ if (PyWeakref_GetObject(weakref) != Py_None) {
+ if (PyList_Append(new_list, weakref) != 0) {
+ Py_DECREF(new_list);
+ return;
+ }
+ }
+ }
+
+ Py_DECREF(self->statements);
+ self->statements = new_list;
+}
+
+PyObject* connection_create_function(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ static char *kwlist[] = {"name", "narg", "func", NULL, NULL};
+
+ PyObject* func;
+ char* name;
+ int narg;
+ int rc;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist,
+ &name, &narg, &func))
+ {
+ return NULL;
+ }
+
+ rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _func_callback, NULL, NULL);
+
+ if (rc != SQLITE_OK) {
+ /* Workaround for SQLite bug: no error code or string is available here */
+ PyErr_SetString(OperationalError, "Error creating function");
+ return NULL;
+ } else {
+ PyDict_SetItem(self->function_pinboard, func, Py_None);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyObject* connection_create_aggregate(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* aggregate_class;
+
+ int n_arg;
+ char* name;
+ static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL };
+ int rc;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate",
+ kwlist, &name, &n_arg, &aggregate_class)) {
+ return NULL;
+ }
+
+ rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_step_callback, &_final_callback);
+ if (rc != SQLITE_OK) {
+ /* Workaround for SQLite bug: no error code or string is available here */
+ PyErr_SetString(OperationalError, "Error creating aggregate");
+ return NULL;
+ } else {
+ PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source)
+{
+ PyObject *ret;
+ int rc;
+ PyGILState_STATE gilstate;
+
+ gilstate = PyGILState_Ensure();
+ ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
+
+ if (!ret) {
+ if (_enable_callback_tracebacks) {
+ PyErr_Print();
+ } else {
+ PyErr_Clear();
+ }
+
+ rc = SQLITE_DENY;
+ } else {
+ if (PyInt_Check(ret)) {
+ rc = (int)PyInt_AsLong(ret);
+ } else {
+ rc = SQLITE_DENY;
+ }
+ Py_DECREF(ret);
+ }
+
+ PyGILState_Release(gilstate);
+ return rc;
+}
+
+PyObject* connection_set_authorizer(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* authorizer_cb;
+
+ static char *kwlist[] = { "authorizer_callback", NULL };
+ int rc;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer",
+ kwlist, &authorizer_cb)) {
+ return NULL;
+ }
+
+ rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb);
+
+ if (rc != SQLITE_OK) {
+ PyErr_SetString(OperationalError, "Error setting authorizer callback");
+ return NULL;
+ } else {
+ PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+int check_thread(Connection* self)
+{
+ if (self->check_same_thread) {
+ if (PyThread_get_thread_ident() != self->thread_ident) {
+ PyErr_Format(ProgrammingError,
+ "SQLite objects created in a thread can only be used in that same thread."
+ "The object was created in thread id %ld and this is thread id %ld",
+ self->thread_ident, PyThread_get_thread_ident());
+ return 0;
+ }
+
+ }
+
+ return 1;
+}
+
+static PyObject* connection_get_isolation_level(Connection* self, void* unused)
+{
+ Py_INCREF(self->isolation_level);
+ return self->isolation_level;
+}
+
+static PyObject* connection_get_total_changes(Connection* self, void* unused)
+{
+ if (!check_connection(self)) {
+ return NULL;
+ } else {
+ return Py_BuildValue("i", sqlite3_total_changes(self->db));
+ }
+}
+
+static int connection_set_isolation_level(Connection* self, PyObject* isolation_level)
+{
+ PyObject* res;
+ PyObject* begin_statement;
+
+ Py_XDECREF(self->isolation_level);
+
+ if (self->begin_statement) {
+ PyMem_Free(self->begin_statement);
+ self->begin_statement = NULL;
+ }
+
+ if (isolation_level == Py_None) {
+ Py_INCREF(Py_None);
+ self->isolation_level = Py_None;
+
+ res = connection_commit(self, NULL);
+ if (!res) {
+ return -1;
+ }
+ Py_DECREF(res);
+
+ self->inTransaction = 0;
+ } else {
+ Py_INCREF(isolation_level);
+ self->isolation_level = isolation_level;
+
+ begin_statement = PyString_FromString("BEGIN ");
+ if (!begin_statement) {
+ return -1;
+ }
+ PyString_Concat(&begin_statement, isolation_level);
+ if (!begin_statement) {
+ return -1;
+ }
+
+ self->begin_statement = PyMem_Malloc(PyString_Size(begin_statement) + 2);
+ if (!self->begin_statement) {
+ return -1;
+ }
+
+ strcpy(self->begin_statement, PyString_AsString(begin_statement));
+ Py_DECREF(begin_statement);
+ }
+
+ return 0;
+}
+
+PyObject* connection_call(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* sql;
+ Statement* statement;
+ PyObject* weakref;
+ int rc;
+
+ if (!PyArg_ParseTuple(args, "O", &sql)) {
+ return NULL;
+ }
+
+ _drop_unused_statement_references(self);
+
+ statement = PyObject_New(Statement, &StatementType);
+ if (!statement) {
+ return NULL;
+ }
+
+ rc = statement_create(statement, self, sql);
+
+ if (rc != SQLITE_OK) {
+ if (rc == PYSQLITE_TOO_MUCH_SQL) {
+ PyErr_SetString(Warning, "You can only execute one statement at a time.");
+ } else if (rc == PYSQLITE_SQL_WRONG_TYPE) {
+ PyErr_SetString(Warning, "SQL is of wrong type. Must be string or unicode.");
+ } else {
+ _seterror(self->db);
+ }
+
+ Py_DECREF(statement);
+ statement = 0;
+ } else {
+ weakref = PyWeakref_NewRef((PyObject*)statement, NULL);
+ if (!weakref) {
+ Py_DECREF(statement);
+ statement = 0;
+ goto error;
+ }
+
+ if (PyList_Append(self->statements, weakref) != 0) {
+ Py_DECREF(weakref);
+ statement = 0;
+ goto error;
+ }
+
+ Py_DECREF(weakref);
+ }
+
+error:
+ return (PyObject*)statement;
+}
+
+PyObject* connection_execute(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* cursor = 0;
+ PyObject* result = 0;
+ PyObject* method = 0;
+
+ cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+ if (!cursor) {
+ goto error;
+ }
+
+ method = PyObject_GetAttrString(cursor, "execute");
+ if (!method) {
+ Py_DECREF(cursor);
+ cursor = 0;
+ goto error;
+ }
+
+ result = PyObject_CallObject(method, args);
+ if (!result) {
+ Py_DECREF(cursor);
+ cursor = 0;
+ }
+
+error:
+ Py_XDECREF(result);
+ Py_XDECREF(method);
+
+ return cursor;
+}
+
+PyObject* connection_executemany(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* cursor = 0;
+ PyObject* result = 0;
+ PyObject* method = 0;
+
+ cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+ if (!cursor) {
+ goto error;
+ }
+
+ method = PyObject_GetAttrString(cursor, "executemany");
+ if (!method) {
+ Py_DECREF(cursor);
+ cursor = 0;
+ goto error;
+ }
+
+ result = PyObject_CallObject(method, args);
+ if (!result) {
+ Py_DECREF(cursor);
+ cursor = 0;
+ }
+
+error:
+ Py_XDECREF(result);
+ Py_XDECREF(method);
+
+ return cursor;
+}
+
+PyObject* connection_executescript(Connection* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* cursor = 0;
+ PyObject* result = 0;
+ PyObject* method = 0;
+
+ cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+ if (!cursor) {
+ goto error;
+ }
+
+ method = PyObject_GetAttrString(cursor, "executescript");
+ if (!method) {
+ Py_DECREF(cursor);
+ cursor = 0;
+ goto error;
+ }
+
+ result = PyObject_CallObject(method, args);
+ if (!result) {
+ Py_DECREF(cursor);
+ cursor = 0;
+ }
+
+error:
+ Py_XDECREF(result);
+ Py_XDECREF(method);
+
+ return cursor;
+}
+
+/* ------------------------- COLLATION CODE ------------------------ */
+
+static int
+collation_callback(
+ void* context,
+ int text1_length, const void* text1_data,
+ int text2_length, const void* text2_data)
+{
+ PyObject* callback = (PyObject*)context;
+ PyObject* string1 = 0;
+ PyObject* string2 = 0;
+ PyGILState_STATE gilstate;
+
+ PyObject* retval = NULL;
+ int result = 0;
+
+ gilstate = PyGILState_Ensure();
+
+ if (PyErr_Occurred()) {
+ goto finally;
+ }
+
+ string1 = PyString_FromStringAndSize((const char*)text1_data, text1_length);
+ string2 = PyString_FromStringAndSize((const char*)text2_data, text2_length);
+
+ if (!string1 || !string2) {
+ goto finally; /* failed to allocate strings */
+ }
+
+ retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL);
+
+ if (!retval) {
+ /* execution failed */
+ goto finally;
+ }
+
+ result = PyInt_AsLong(retval);
+ if (PyErr_Occurred()) {
+ result = 0;
+ }
+
+finally:
+ Py_XDECREF(string1);
+ Py_XDECREF(string2);
+ Py_XDECREF(retval);
+
+ PyGILState_Release(gilstate);
+
+ return result;
+}
+
+static PyObject *
+connection_interrupt(Connection* self, PyObject* args)
+{
+ PyObject* retval = NULL;
+
+ if (!check_connection(self)) {
+ goto finally;
+ }
+
+ sqlite3_interrupt(self->db);
+
+ Py_INCREF(Py_None);
+ retval = Py_None;
+
+finally:
+ return retval;
+}
+
+static PyObject *
+connection_create_collation(Connection* self, PyObject* args)
+{
+ PyObject* callable;
+ PyObject* uppercase_name = 0;
+ PyObject* name;
+ PyObject* retval;
+ char* chk;
+ int rc;
+
+ if (!check_thread(self) || !check_connection(self)) {
+ goto finally;
+ }
+
+ if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyString_Type, &name, &callable)) {
+ goto finally;
+ }
+
+ uppercase_name = PyObject_CallMethod(name, "upper", "");
+ if (!uppercase_name) {
+ goto finally;
+ }
+
+ chk = PyString_AsString(uppercase_name);
+ while (*chk) {
+ if ((*chk >= '0' && *chk <= '9')
+ || (*chk >= 'A' && *chk <= 'Z')
+ || (*chk == '_'))
+ {
+ chk++;
+ } else {
+ PyErr_SetString(ProgrammingError, "invalid character in collation name");
+ goto finally;
+ }
+ }
+
+ if (callable != Py_None && !PyCallable_Check(callable)) {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+ goto finally;
+ }
+
+ if (callable != Py_None) {
+ PyDict_SetItem(self->collations, uppercase_name, callable);
+ } else {
+ PyDict_DelItem(self->collations, uppercase_name);
+ }
+
+ rc = sqlite3_create_collation(self->db,
+ PyString_AsString(uppercase_name),
+ SQLITE_UTF8,
+ (callable != Py_None) ? callable : NULL,
+ (callable != Py_None) ? collation_callback : NULL);
+ if (rc != SQLITE_OK) {
+ PyDict_DelItem(self->collations, uppercase_name);
+ _seterror(self->db);
+ goto finally;
+ }
+
+finally:
+ Py_XDECREF(uppercase_name);
+
+ if (PyErr_Occurred()) {
+ retval = NULL;
+ } else {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ }
+
+ return retval;
+}
+
+static char connection_doc[] =
+PyDoc_STR("SQLite database connection object.");
+
+static PyGetSetDef connection_getset[] = {
+ {"isolation_level", (getter)connection_get_isolation_level, (setter)connection_set_isolation_level},
+ {"total_changes", (getter)connection_get_total_changes, (setter)0},
+ {NULL}
+};
+
+static PyMethodDef connection_methods[] = {
+ {"cursor", (PyCFunction)connection_cursor, METH_VARARGS|METH_KEYWORDS,
+ PyDoc_STR("Return a cursor for the connection.")},
+ {"close", (PyCFunction)connection_close, METH_NOARGS,
+ PyDoc_STR("Closes the connection.")},
+ {"commit", (PyCFunction)connection_commit, METH_NOARGS,
+ PyDoc_STR("Commit the current transaction.")},
+ {"rollback", (PyCFunction)connection_rollback, METH_NOARGS,
+ PyDoc_STR("Roll back the current transaction.")},
+ {"create_function", (PyCFunction)connection_create_function, METH_VARARGS|METH_KEYWORDS,
+ PyDoc_STR("Creates a new function. Non-standard.")},
+ {"create_aggregate", (PyCFunction)connection_create_aggregate, METH_VARARGS|METH_KEYWORDS,
+ PyDoc_STR("Creates a new aggregate. Non-standard.")},
+ {"set_authorizer", (PyCFunction)connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
+ PyDoc_STR("Sets authorizer callback. Non-standard.")},
+ {"execute", (PyCFunction)connection_execute, METH_VARARGS,
+ PyDoc_STR("Executes a SQL statement. Non-standard.")},
+ {"executemany", (PyCFunction)connection_executemany, METH_VARARGS,
+ PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")},
+ {"executescript", (PyCFunction)connection_executescript, METH_VARARGS,
+ PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
+ {"create_collation", (PyCFunction)connection_create_collation, METH_VARARGS,
+ PyDoc_STR("Creates a collation function. Non-standard.")},
+ {"interrupt", (PyCFunction)connection_interrupt, METH_NOARGS,
+ PyDoc_STR("Abort any pending database operation. Non-standard.")},
+ {NULL, NULL}
+};
+
+static struct PyMemberDef connection_members[] =
+{
+ {"Warning", T_OBJECT, offsetof(Connection, Warning), RO},
+ {"Error", T_OBJECT, offsetof(Connection, Error), RO},
+ {"InterfaceError", T_OBJECT, offsetof(Connection, InterfaceError), RO},
+ {"DatabaseError", T_OBJECT, offsetof(Connection, DatabaseError), RO},
+ {"DataError", T_OBJECT, offsetof(Connection, DataError), RO},
+ {"OperationalError", T_OBJECT, offsetof(Connection, OperationalError), RO},
+ {"IntegrityError", T_OBJECT, offsetof(Connection, IntegrityError), RO},
+ {"InternalError", T_OBJECT, offsetof(Connection, InternalError), RO},
+ {"ProgrammingError", T_OBJECT, offsetof(Connection, ProgrammingError), RO},
+ {"NotSupportedError", T_OBJECT, offsetof(Connection, NotSupportedError), RO},
+ {"row_factory", T_OBJECT, offsetof(Connection, row_factory)},
+ {"text_factory", T_OBJECT, offsetof(Connection, text_factory)},
+ {NULL}
+};
+
+PyTypeObject ConnectionType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME ".Connection", /* tp_name */
+ sizeof(Connection), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)connection_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)connection_call, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+ connection_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ connection_methods, /* tp_methods */
+ connection_members, /* tp_members */
+ connection_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)connection_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+extern int connection_setup_types(void)
+{
+ ConnectionType.tp_new = PyType_GenericNew;
+ return PyType_Ready(&ConnectionType);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/connection.h b/sys/src/cmd/python/Modules/_sqlite/connection.h
new file mode 100644
index 000000000..8f4d36e1a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/connection.h
@@ -0,0 +1,129 @@
+/* connection.h - definitions for the connection type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_CONNECTION_H
+#define PYSQLITE_CONNECTION_H
+#include "Python.h"
+#include "pythread.h"
+#include "structmember.h"
+
+#include "cache.h"
+#include "module.h"
+
+#include "sqlite3.h"
+
+typedef struct
+{
+ PyObject_HEAD
+ sqlite3* db;
+
+ /* 1 if we are currently within a transaction, i. e. if a BEGIN has been
+ * issued */
+ int inTransaction;
+
+ /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
+ * bitwise combination thereof makes sense */
+ int detect_types;
+
+ /* the timeout value in seconds for database locks */
+ double timeout;
+
+ /* for internal use in the timeout handler: when did the timeout handler
+ * first get called with count=0? */
+ double timeout_started;
+
+ /* None for autocommit, otherwise a PyString with the isolation level */
+ PyObject* isolation_level;
+
+ /* NULL for autocommit, otherwise a string with the BEGIN statment; will be
+ * freed in connection destructor */
+ char* begin_statement;
+
+ /* 1 if a check should be performed for each API call if the connection is
+ * used from the same thread it was created in */
+ int check_same_thread;
+
+ /* thread identification of the thread the connection was created in */
+ long thread_ident;
+
+ Cache* statement_cache;
+
+ /* A list of weak references to statements used within this connection */
+ PyObject* statements;
+
+ /* a counter for how many statements were created in the connection. May be
+ * reset to 0 at certain intervals */
+ int created_statements;
+
+ PyObject* row_factory;
+
+ /* Determines how bytestrings from SQLite are converted to Python objects:
+ * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings
+ * - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created.
+ * - PyString_Type: PyStrings are created as-is.
+ * - Any custom callable: Any object returned from the callable called with the bytestring
+ * as single parameter.
+ */
+ PyObject* text_factory;
+
+ /* remember references to functions/classes used in
+ * create_function/create/aggregate, use these as dictionary keys, so we
+ * can keep the total system refcount constant by clearing that dictionary
+ * in connection_dealloc */
+ PyObject* function_pinboard;
+
+ /* a dictionary of registered collation name => collation callable mappings */
+ PyObject* collations;
+
+ /* Exception objects */
+ PyObject* Warning;
+ PyObject* Error;
+ PyObject* InterfaceError;
+ PyObject* DatabaseError;
+ PyObject* DataError;
+ PyObject* OperationalError;
+ PyObject* IntegrityError;
+ PyObject* InternalError;
+ PyObject* ProgrammingError;
+ PyObject* NotSupportedError;
+} Connection;
+
+extern PyTypeObject ConnectionType;
+
+PyObject* connection_alloc(PyTypeObject* type, int aware);
+void connection_dealloc(Connection* self);
+PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs);
+PyObject* connection_close(Connection* self, PyObject* args);
+PyObject* _connection_begin(Connection* self);
+PyObject* connection_begin(Connection* self, PyObject* args);
+PyObject* connection_commit(Connection* self, PyObject* args);
+PyObject* connection_rollback(Connection* self, PyObject* args);
+PyObject* connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
+int connection_init(Connection* self, PyObject* args, PyObject* kwargs);
+
+int check_thread(Connection* self);
+int check_connection(Connection* con);
+
+int connection_setup_types(void);
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/cursor.c b/sys/src/cmd/python/Modules/_sqlite/cursor.c
new file mode 100644
index 000000000..91d8f74ee
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/cursor.c
@@ -0,0 +1,1057 @@
+/* cursor.c - the cursor type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "cursor.h"
+#include "module.h"
+#include "util.h"
+#include "sqlitecompat.h"
+
+/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647 - 1)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX 2147483647
+#endif
+
+PyObject* cursor_iternext(Cursor *self);
+
+static StatementKind detect_statement_type(char* statement)
+{
+ char buf[20];
+ char* src;
+ char* dst;
+
+ src = statement;
+ /* skip over whitepace */
+ while (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') {
+ src++;
+ }
+
+ if (*src == 0)
+ return STATEMENT_INVALID;
+
+ dst = buf;
+ *dst = 0;
+ while (isalpha(*src) && dst - buf < sizeof(buf) - 2) {
+ *dst++ = tolower(*src++);
+ }
+
+ *dst = 0;
+
+ if (!strcmp(buf, "select")) {
+ return STATEMENT_SELECT;
+ } else if (!strcmp(buf, "insert")) {
+ return STATEMENT_INSERT;
+ } else if (!strcmp(buf, "update")) {
+ return STATEMENT_UPDATE;
+ } else if (!strcmp(buf, "delete")) {
+ return STATEMENT_DELETE;
+ } else if (!strcmp(buf, "replace")) {
+ return STATEMENT_REPLACE;
+ } else {
+ return STATEMENT_OTHER;
+ }
+}
+
+int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs)
+{
+ Connection* connection;
+
+ if (!PyArg_ParseTuple(args, "O!", &ConnectionType, &connection))
+ {
+ return -1;
+ }
+
+ Py_INCREF(connection);
+ self->connection = connection;
+ self->statement = NULL;
+ self->next_row = NULL;
+
+ self->row_cast_map = PyList_New(0);
+ if (!self->row_cast_map) {
+ return -1;
+ }
+
+ Py_INCREF(Py_None);
+ self->description = Py_None;
+
+ Py_INCREF(Py_None);
+ self->lastrowid= Py_None;
+
+ self->arraysize = 1;
+
+ self->rowcount = PyInt_FromLong(-1L);
+ if (!self->rowcount) {
+ return -1;
+ }
+
+ Py_INCREF(Py_None);
+ self->row_factory = Py_None;
+
+ if (!check_thread(self->connection)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void cursor_dealloc(Cursor* self)
+{
+ int rc;
+
+ /* Reset the statement if the user has not closed the cursor */
+ if (self->statement) {
+ rc = statement_reset(self->statement);
+ Py_DECREF(self->statement);
+ }
+
+ Py_XDECREF(self->connection);
+ Py_XDECREF(self->row_cast_map);
+ Py_XDECREF(self->description);
+ Py_XDECREF(self->lastrowid);
+ Py_XDECREF(self->rowcount);
+ Py_XDECREF(self->row_factory);
+ Py_XDECREF(self->next_row);
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+PyObject* _get_converter(PyObject* key)
+{
+ PyObject* upcase_key;
+ PyObject* retval;
+
+ upcase_key = PyObject_CallMethod(key, "upper", "");
+ if (!upcase_key) {
+ return NULL;
+ }
+
+ retval = PyDict_GetItem(converters, upcase_key);
+ Py_DECREF(upcase_key);
+
+ return retval;
+}
+
+int build_row_cast_map(Cursor* self)
+{
+ int i;
+ const char* type_start = (const char*)-1;
+ const char* pos;
+
+ const char* colname;
+ const char* decltype;
+ PyObject* py_decltype;
+ PyObject* converter;
+ PyObject* key;
+
+ if (!self->connection->detect_types) {
+ return 0;
+ }
+
+ Py_XDECREF(self->row_cast_map);
+ self->row_cast_map = PyList_New(0);
+
+ for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
+ converter = NULL;
+
+ if (self->connection->detect_types | PARSE_COLNAMES) {
+ colname = sqlite3_column_name(self->statement->st, i);
+ if (colname) {
+ for (pos = colname; *pos != 0; pos++) {
+ if (*pos == '[') {
+ type_start = pos + 1;
+ } else if (*pos == ']' && type_start != (const char*)-1) {
+ key = PyString_FromStringAndSize(type_start, pos - type_start);
+ if (!key) {
+ /* creating a string failed, but it is too complicated
+ * to propagate the error here, we just assume there is
+ * no converter and proceed */
+ break;
+ }
+
+ converter = _get_converter(key);
+ Py_DECREF(key);
+ break;
+ }
+ }
+ }
+ }
+
+ if (!converter && self->connection->detect_types | PARSE_DECLTYPES) {
+ decltype = sqlite3_column_decltype(self->statement->st, i);
+ if (decltype) {
+ for (pos = decltype;;pos++) {
+ if (*pos == ' ' || *pos == 0) {
+ py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
+ if (!py_decltype) {
+ return -1;
+ }
+ break;
+ }
+ }
+
+ converter = _get_converter(py_decltype);
+ Py_DECREF(py_decltype);
+ }
+ }
+
+ if (!converter) {
+ converter = Py_None;
+ }
+
+ if (PyList_Append(self->row_cast_map, converter) != 0) {
+ if (converter != Py_None) {
+ Py_DECREF(converter);
+ }
+ Py_XDECREF(self->row_cast_map);
+ self->row_cast_map = NULL;
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+PyObject* _build_column_name(const char* colname)
+{
+ const char* pos;
+
+ if (!colname) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ for (pos = colname;; pos++) {
+ if (*pos == 0 || *pos == '[') {
+ if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) {
+ pos--;
+ }
+ return PyString_FromStringAndSize(colname, pos - colname);
+ }
+ }
+}
+
+PyObject* unicode_from_string(const char* val_str, int optimize)
+{
+ const char* check;
+ int is_ascii = 0;
+
+ if (optimize) {
+ is_ascii = 1;
+
+ check = val_str;
+ while (*check) {
+ if (*check & 0x80) {
+ is_ascii = 0;
+ break;
+ }
+
+ check++;
+ }
+ }
+
+ if (is_ascii) {
+ return PyString_FromString(val_str);
+ } else {
+ return PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
+ }
+}
+
+/*
+ * Returns a row from the currently active SQLite statement
+ *
+ * Precondidition:
+ * - sqlite3_step() has been called before and it returned SQLITE_ROW.
+ */
+PyObject* _fetch_one_row(Cursor* self)
+{
+ int i, numcols;
+ PyObject* row;
+ PyObject* item = NULL;
+ int coltype;
+ PY_LONG_LONG intval;
+ PyObject* converter;
+ PyObject* converted;
+ Py_ssize_t nbytes;
+ PyObject* buffer;
+ void* raw_buffer;
+ const char* val_str;
+ char buf[200];
+ const char* colname;
+
+ Py_BEGIN_ALLOW_THREADS
+ numcols = sqlite3_data_count(self->statement->st);
+ Py_END_ALLOW_THREADS
+
+ row = PyTuple_New(numcols);
+ if (!row) {
+ return NULL;
+ }
+
+ for (i = 0; i < numcols; i++) {
+ if (self->connection->detect_types) {
+ converter = PyList_GetItem(self->row_cast_map, i);
+ if (!converter) {
+ converter = Py_None;
+ }
+ } else {
+ converter = Py_None;
+ }
+
+ if (converter != Py_None) {
+ nbytes = sqlite3_column_bytes(self->statement->st, i);
+ val_str = (const char*)sqlite3_column_blob(self->statement->st, i);
+ if (!val_str) {
+ Py_INCREF(Py_None);
+ converted = Py_None;
+ } else {
+ item = PyString_FromStringAndSize(val_str, nbytes);
+ if (!item) {
+ return NULL;
+ }
+ converted = PyObject_CallFunction(converter, "O", item);
+ Py_DECREF(item);
+ if (!converted) {
+ break;
+ }
+ }
+ } else {
+ Py_BEGIN_ALLOW_THREADS
+ coltype = sqlite3_column_type(self->statement->st, i);
+ Py_END_ALLOW_THREADS
+ if (coltype == SQLITE_NULL) {
+ Py_INCREF(Py_None);
+ converted = Py_None;
+ } else if (coltype == SQLITE_INTEGER) {
+ intval = sqlite3_column_int64(self->statement->st, i);
+ if (intval < INT32_MIN || intval > INT32_MAX) {
+ converted = PyLong_FromLongLong(intval);
+ } else {
+ converted = PyInt_FromLong((long)intval);
+ }
+ } else if (coltype == SQLITE_FLOAT) {
+ converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
+ } else if (coltype == SQLITE_TEXT) {
+ val_str = (const char*)sqlite3_column_text(self->statement->st, i);
+ if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
+ || (self->connection->text_factory == OptimizedUnicode)) {
+
+ converted = unicode_from_string(val_str,
+ self->connection->text_factory == OptimizedUnicode ? 1 : 0);
+
+ if (!converted) {
+ colname = sqlite3_column_name(self->statement->st, i);
+ if (!colname) {
+ colname = "<unknown column name>";
+ }
+ PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
+ colname , val_str);
+ PyErr_SetString(OperationalError, buf);
+ }
+ } else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
+ converted = PyString_FromString(val_str);
+ } else {
+ converted = PyObject_CallFunction(self->connection->text_factory, "s", val_str);
+ }
+ } else {
+ /* coltype == SQLITE_BLOB */
+ nbytes = sqlite3_column_bytes(self->statement->st, i);
+ buffer = PyBuffer_New(nbytes);
+ if (!buffer) {
+ break;
+ }
+ if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) {
+ break;
+ }
+ memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes);
+ converted = buffer;
+ }
+ }
+
+ if (converted) {
+ PyTuple_SetItem(row, i, converted);
+ } else {
+ Py_INCREF(Py_None);
+ PyTuple_SetItem(row, i, Py_None);
+ }
+ }
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(row);
+ row = NULL;
+ }
+
+ return row;
+}
+
+PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
+{
+ PyObject* operation;
+ PyObject* operation_bytestr = NULL;
+ char* operation_cstr;
+ PyObject* parameters_list = NULL;
+ PyObject* parameters_iter = NULL;
+ PyObject* parameters = NULL;
+ int i;
+ int rc;
+ PyObject* func_args;
+ PyObject* result;
+ int numcols;
+ PY_LONG_LONG lastrowid;
+ int statement_type;
+ PyObject* descriptor;
+ PyObject* second_argument = NULL;
+ long rowcount = 0;
+
+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
+ return NULL;
+ }
+
+ Py_XDECREF(self->next_row);
+ self->next_row = NULL;
+
+ if (multiple) {
+ /* executemany() */
+ if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) {
+ return NULL;
+ }
+
+ if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
+ PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
+ return NULL;
+ }
+
+ if (PyIter_Check(second_argument)) {
+ /* iterator */
+ Py_INCREF(second_argument);
+ parameters_iter = second_argument;
+ } else {
+ /* sequence */
+ parameters_iter = PyObject_GetIter(second_argument);
+ if (!parameters_iter) {
+ return NULL;
+ }
+ }
+ } else {
+ /* execute() */
+ if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) {
+ return NULL;
+ }
+
+ if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
+ PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
+ return NULL;
+ }
+
+ parameters_list = PyList_New(0);
+ if (!parameters_list) {
+ return NULL;
+ }
+
+ if (second_argument == NULL) {
+ second_argument = PyTuple_New(0);
+ if (!second_argument) {
+ goto error;
+ }
+ } else {
+ Py_INCREF(second_argument);
+ }
+ if (PyList_Append(parameters_list, second_argument) != 0) {
+ Py_DECREF(second_argument);
+ goto error;
+ }
+ Py_DECREF(second_argument);
+
+ parameters_iter = PyObject_GetIter(parameters_list);
+ if (!parameters_iter) {
+ goto error;
+ }
+ }
+
+ if (self->statement != NULL) {
+ /* There is an active statement */
+ rc = statement_reset(self->statement);
+ }
+
+ if (PyString_Check(operation)) {
+ operation_cstr = PyString_AsString(operation);
+ } else {
+ operation_bytestr = PyUnicode_AsUTF8String(operation);
+ if (!operation_bytestr) {
+ goto error;
+ }
+
+ operation_cstr = PyString_AsString(operation_bytestr);
+ }
+
+ /* reset description and rowcount */
+ Py_DECREF(self->description);
+ Py_INCREF(Py_None);
+ self->description = Py_None;
+
+ Py_DECREF(self->rowcount);
+ self->rowcount = PyInt_FromLong(-1L);
+ if (!self->rowcount) {
+ goto error;
+ }
+
+ statement_type = detect_statement_type(operation_cstr);
+ if (self->connection->begin_statement) {
+ switch (statement_type) {
+ case STATEMENT_UPDATE:
+ case STATEMENT_DELETE:
+ case STATEMENT_INSERT:
+ case STATEMENT_REPLACE:
+ if (!self->connection->inTransaction) {
+ result = _connection_begin(self->connection);
+ if (!result) {
+ goto error;
+ }
+ Py_DECREF(result);
+ }
+ break;
+ case STATEMENT_OTHER:
+ /* it's a DDL statement or something similar
+ - we better COMMIT first so it works for all cases */
+ if (self->connection->inTransaction) {
+ result = connection_commit(self->connection, NULL);
+ if (!result) {
+ goto error;
+ }
+ Py_DECREF(result);
+ }
+ break;
+ case STATEMENT_SELECT:
+ if (multiple) {
+ PyErr_SetString(ProgrammingError,
+ "You cannot execute SELECT statements in executemany().");
+ goto error;
+ }
+ break;
+ }
+ }
+
+ func_args = PyTuple_New(1);
+ if (!func_args) {
+ goto error;
+ }
+ Py_INCREF(operation);
+ if (PyTuple_SetItem(func_args, 0, operation) != 0) {
+ goto error;
+ }
+
+ if (self->statement) {
+ (void)statement_reset(self->statement);
+ Py_DECREF(self->statement);
+ }
+
+ self->statement = (Statement*)cache_get(self->connection->statement_cache, func_args);
+ Py_DECREF(func_args);
+
+ if (!self->statement) {
+ goto error;
+ }
+
+ if (self->statement->in_use) {
+ Py_DECREF(self->statement);
+ self->statement = PyObject_New(Statement, &StatementType);
+ if (!self->statement) {
+ goto error;
+ }
+ rc = statement_create(self->statement, self->connection, operation);
+ if (rc != SQLITE_OK) {
+ self->statement = 0;
+ goto error;
+ }
+ }
+
+ statement_reset(self->statement);
+ statement_mark_dirty(self->statement);
+
+ while (1) {
+ parameters = PyIter_Next(parameters_iter);
+ if (!parameters) {
+ break;
+ }
+
+ statement_mark_dirty(self->statement);
+
+ statement_bind_parameters(self->statement, parameters);
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+
+ if (build_row_cast_map(self) != 0) {
+ PyErr_SetString(OperationalError, "Error while building row_cast_map");
+ goto error;
+ }
+
+ rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+ if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
+ rc = statement_reset(self->statement);
+ if (rc == SQLITE_SCHEMA) {
+ rc = statement_recompile(self->statement, parameters);
+ if (rc == SQLITE_OK) {
+ rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+ } else {
+ _seterror(self->connection->db);
+ goto error;
+ }
+ } else {
+ if (PyErr_Occurred()) {
+ /* there was an error that occurred in a user-defined callback */
+ if (_enable_callback_tracebacks) {
+ PyErr_Print();
+ } else {
+ PyErr_Clear();
+ }
+ }
+ _seterror(self->connection->db);
+ goto error;
+ }
+ }
+
+ if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
+ Py_BEGIN_ALLOW_THREADS
+ numcols = sqlite3_column_count(self->statement->st);
+ Py_END_ALLOW_THREADS
+
+ if (self->description == Py_None) {
+ Py_DECREF(self->description);
+ self->description = PyTuple_New(numcols);
+ if (!self->description) {
+ goto error;
+ }
+ for (i = 0; i < numcols; i++) {
+ descriptor = PyTuple_New(7);
+ if (!descriptor) {
+ goto error;
+ }
+ PyTuple_SetItem(descriptor, 0, _build_column_name(sqlite3_column_name(self->statement->st, i)));
+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);
+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None);
+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None);
+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None);
+ PyTuple_SetItem(self->description, i, descriptor);
+ }
+ }
+ }
+
+ if (rc == SQLITE_ROW) {
+ if (multiple) {
+ PyErr_SetString(ProgrammingError, "executemany() can only execute DML statements.");
+ goto error;
+ }
+
+ self->next_row = _fetch_one_row(self);
+ } else if (rc == SQLITE_DONE && !multiple) {
+ statement_reset(self->statement);
+ Py_DECREF(self->statement);
+ self->statement = 0;
+ }
+
+ switch (statement_type) {
+ case STATEMENT_UPDATE:
+ case STATEMENT_DELETE:
+ case STATEMENT_INSERT:
+ case STATEMENT_REPLACE:
+ Py_BEGIN_ALLOW_THREADS
+ rowcount += (long)sqlite3_changes(self->connection->db);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(self->rowcount);
+ self->rowcount = PyInt_FromLong(rowcount);
+ }
+
+ Py_DECREF(self->lastrowid);
+ if (statement_type == STATEMENT_INSERT) {
+ Py_BEGIN_ALLOW_THREADS
+ lastrowid = sqlite3_last_insert_rowid(self->connection->db);
+ Py_END_ALLOW_THREADS
+ self->lastrowid = PyInt_FromLong((long)lastrowid);
+ } else {
+ Py_INCREF(Py_None);
+ self->lastrowid = Py_None;
+ }
+
+ if (multiple) {
+ rc = statement_reset(self->statement);
+ }
+ Py_XDECREF(parameters);
+ }
+
+error:
+ Py_XDECREF(operation_bytestr);
+ Py_XDECREF(parameters);
+ Py_XDECREF(parameters_iter);
+ Py_XDECREF(parameters_list);
+
+ if (PyErr_Occurred()) {
+ return NULL;
+ } else {
+ Py_INCREF(self);
+ return (PyObject*)self;
+ }
+}
+
+PyObject* cursor_execute(Cursor* self, PyObject* args)
+{
+ return _query_execute(self, 0, args);
+}
+
+PyObject* cursor_executemany(Cursor* self, PyObject* args)
+{
+ return _query_execute(self, 1, args);
+}
+
+PyObject* cursor_executescript(Cursor* self, PyObject* args)
+{
+ PyObject* script_obj;
+ PyObject* script_str = NULL;
+ const char* script_cstr;
+ sqlite3_stmt* statement;
+ int rc;
+ PyObject* result;
+ int statement_completed = 0;
+
+ if (!PyArg_ParseTuple(args, "O", &script_obj)) {
+ return NULL;
+ }
+
+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
+ return NULL;
+ }
+
+ if (PyString_Check(script_obj)) {
+ script_cstr = PyString_AsString(script_obj);
+ } else if (PyUnicode_Check(script_obj)) {
+ script_str = PyUnicode_AsUTF8String(script_obj);
+ if (!script_str) {
+ return NULL;
+ }
+
+ script_cstr = PyString_AsString(script_str);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "script argument must be unicode or string.");
+ return NULL;
+ }
+
+ /* commit first */
+ result = connection_commit(self->connection, NULL);
+ if (!result) {
+ goto error;
+ }
+ Py_DECREF(result);
+
+ while (1) {
+ if (!sqlite3_complete(script_cstr)) {
+ break;
+ }
+ statement_completed = 1;
+
+ rc = sqlite3_prepare(self->connection->db,
+ script_cstr,
+ -1,
+ &statement,
+ &script_cstr);
+ if (rc != SQLITE_OK) {
+ _seterror(self->connection->db);
+ goto error;
+ }
+
+ /* execute statement, and ignore results of SELECT statements */
+ rc = SQLITE_ROW;
+ while (rc == SQLITE_ROW) {
+ rc = _sqlite_step_with_busyhandler(statement, self->connection);
+ }
+
+ if (rc != SQLITE_DONE) {
+ (void)sqlite3_finalize(statement);
+ _seterror(self->connection->db);
+ goto error;
+ }
+
+ rc = sqlite3_finalize(statement);
+ if (rc != SQLITE_OK) {
+ _seterror(self->connection->db);
+ goto error;
+ }
+ }
+
+error:
+ Py_XDECREF(script_str);
+
+ if (!statement_completed) {
+ PyErr_SetString(ProgrammingError, "you did not provide a complete SQL statement");
+ }
+
+ if (PyErr_Occurred()) {
+ return NULL;
+ } else {
+ Py_INCREF(self);
+ return (PyObject*)self;
+ }
+}
+
+PyObject* cursor_getiter(Cursor *self)
+{
+ Py_INCREF(self);
+ return (PyObject*)self;
+}
+
+PyObject* cursor_iternext(Cursor *self)
+{
+ PyObject* next_row_tuple;
+ PyObject* next_row;
+ int rc;
+
+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
+ return NULL;
+ }
+
+ if (!self->next_row) {
+ if (self->statement) {
+ (void)statement_reset(self->statement);
+ Py_DECREF(self->statement);
+ self->statement = NULL;
+ }
+ return NULL;
+ }
+
+ next_row_tuple = self->next_row;
+ self->next_row = NULL;
+
+ if (self->row_factory != Py_None) {
+ next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple);
+ Py_DECREF(next_row_tuple);
+ } else {
+ next_row = next_row_tuple;
+ }
+
+ rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
+ if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
+ Py_DECREF(next_row);
+ _seterror(self->connection->db);
+ return NULL;
+ }
+
+ if (rc == SQLITE_ROW) {
+ self->next_row = _fetch_one_row(self);
+ }
+
+ return next_row;
+}
+
+PyObject* cursor_fetchone(Cursor* self, PyObject* args)
+{
+ PyObject* row;
+
+ row = cursor_iternext(self);
+ if (!row && !PyErr_Occurred()) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return row;
+}
+
+PyObject* cursor_fetchmany(Cursor* self, PyObject* args)
+{
+ PyObject* row;
+ PyObject* list;
+ int maxrows = self->arraysize;
+ int counter = 0;
+
+ if (!PyArg_ParseTuple(args, "|i", &maxrows)) {
+ return NULL;
+ }
+
+ list = PyList_New(0);
+ if (!list) {
+ return NULL;
+ }
+
+ /* just make sure we enter the loop */
+ row = Py_None;
+
+ while (row) {
+ row = cursor_iternext(self);
+ if (row) {
+ PyList_Append(list, row);
+ Py_DECREF(row);
+ } else {
+ break;
+ }
+
+ if (++counter == maxrows) {
+ break;
+ }
+ }
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(list);
+ return NULL;
+ } else {
+ return list;
+ }
+}
+
+PyObject* cursor_fetchall(Cursor* self, PyObject* args)
+{
+ PyObject* row;
+ PyObject* list;
+
+ list = PyList_New(0);
+ if (!list) {
+ return NULL;
+ }
+
+ /* just make sure we enter the loop */
+ row = (PyObject*)Py_None;
+
+ while (row) {
+ row = cursor_iternext(self);
+ if (row) {
+ PyList_Append(list, row);
+ Py_DECREF(row);
+ }
+ }
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(list);
+ return NULL;
+ } else {
+ return list;
+ }
+}
+
+PyObject* pysqlite_noop(Connection* self, PyObject* args)
+{
+ /* don't care, return None */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* cursor_close(Cursor* self, PyObject* args)
+{
+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
+ return NULL;
+ }
+
+ if (self->statement) {
+ (void)statement_reset(self->statement);
+ Py_DECREF(self->statement);
+ self->statement = 0;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef cursor_methods[] = {
+ {"execute", (PyCFunction)cursor_execute, METH_VARARGS,
+ PyDoc_STR("Executes a SQL statement.")},
+ {"executemany", (PyCFunction)cursor_executemany, METH_VARARGS,
+ PyDoc_STR("Repeatedly executes a SQL statement.")},
+ {"executescript", (PyCFunction)cursor_executescript, METH_VARARGS,
+ PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
+ {"fetchone", (PyCFunction)cursor_fetchone, METH_NOARGS,
+ PyDoc_STR("Fetches several rows from the resultset.")},
+ {"fetchmany", (PyCFunction)cursor_fetchmany, METH_VARARGS,
+ PyDoc_STR("Fetches all rows from the resultset.")},
+ {"fetchall", (PyCFunction)cursor_fetchall, METH_NOARGS,
+ PyDoc_STR("Fetches one row from the resultset.")},
+ {"close", (PyCFunction)cursor_close, METH_NOARGS,
+ PyDoc_STR("Closes the cursor.")},
+ {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS,
+ PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
+ {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS,
+ PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
+ {NULL, NULL}
+};
+
+static struct PyMemberDef cursor_members[] =
+{
+ {"connection", T_OBJECT, offsetof(Cursor, connection), RO},
+ {"description", T_OBJECT, offsetof(Cursor, description), RO},
+ {"arraysize", T_INT, offsetof(Cursor, arraysize), 0},
+ {"lastrowid", T_OBJECT, offsetof(Cursor, lastrowid), RO},
+ {"rowcount", T_OBJECT, offsetof(Cursor, rowcount), RO},
+ {"row_factory", T_OBJECT, offsetof(Cursor, row_factory), 0},
+ {NULL}
+};
+
+static char cursor_doc[] =
+PyDoc_STR("SQLite database cursor class.");
+
+PyTypeObject CursorType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME ".Cursor", /* tp_name */
+ sizeof(Cursor), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)cursor_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE, /* tp_flags */
+ cursor_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)cursor_getiter, /* tp_iter */
+ (iternextfunc)cursor_iternext, /* tp_iternext */
+ cursor_methods, /* tp_methods */
+ cursor_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)cursor_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+extern int cursor_setup_types(void)
+{
+ CursorType.tp_new = PyType_GenericNew;
+ return PyType_Ready(&CursorType);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/cursor.h b/sys/src/cmd/python/Modules/_sqlite/cursor.h
new file mode 100644
index 000000000..831ff812a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/cursor.h
@@ -0,0 +1,71 @@
+/* cursor.h - definitions for the cursor type
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_CURSOR_H
+#define PYSQLITE_CURSOR_H
+#include "Python.h"
+
+#include "statement.h"
+#include "connection.h"
+#include "module.h"
+
+typedef struct
+{
+ PyObject_HEAD
+ Connection* connection;
+ PyObject* description;
+ PyObject* row_cast_map;
+ int arraysize;
+ PyObject* lastrowid;
+ PyObject* rowcount;
+ PyObject* row_factory;
+ Statement* statement;
+
+ /* the next row to be returned, NULL if no next row available */
+ PyObject* next_row;
+} Cursor;
+
+typedef enum {
+ STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
+ STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
+ STATEMENT_OTHER
+} StatementKind;
+
+extern PyTypeObject CursorType;
+
+int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs);
+void cursor_dealloc(Cursor* self);
+PyObject* cursor_execute(Cursor* self, PyObject* args);
+PyObject* cursor_executemany(Cursor* self, PyObject* args);
+PyObject* cursor_getiter(Cursor *self);
+PyObject* cursor_iternext(Cursor *self);
+PyObject* cursor_fetchone(Cursor* self, PyObject* args);
+PyObject* cursor_fetchmany(Cursor* self, PyObject* args);
+PyObject* cursor_fetchall(Cursor* self, PyObject* args);
+PyObject* pysqlite_noop(Connection* self, PyObject* args);
+PyObject* cursor_close(Cursor* self, PyObject* args);
+
+int cursor_setup_types(void);
+
+#define UNKNOWN (-1)
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/microprotocols.c b/sys/src/cmd/python/Modules/_sqlite/microprotocols.c
new file mode 100644
index 000000000..4956ac073
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/microprotocols.c
@@ -0,0 +1,142 @@
+/* microprotocols.c - minimalist and non-validating protocols implementation
+ *
+ * Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
+ *
+ * This file is part of psycopg and was adapted for pysqlite. Federico Di
+ * Gregorio gave the permission to use it within pysqlite under the following
+ * license:
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <Python.h>
+#include <structmember.h>
+
+#include "cursor.h"
+#include "microprotocols.h"
+#include "prepare_protocol.h"
+
+
+/** the adapters registry **/
+
+PyObject *psyco_adapters;
+
+/* microprotocols_init - initialize the adapters dictionary */
+
+int
+microprotocols_init(PyObject *dict)
+{
+ /* create adapters dictionary and put it in module namespace */
+ if ((psyco_adapters = PyDict_New()) == NULL) {
+ return -1;
+ }
+
+ return PyDict_SetItemString(dict, "adapters", psyco_adapters);
+}
+
+
+/* microprotocols_add - add a reverse type-caster to the dictionary */
+
+int
+microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
+{
+ PyObject* key;
+ int rc;
+
+ if (proto == NULL) proto = (PyObject*)&SQLitePrepareProtocolType;
+
+ key = Py_BuildValue("(OO)", (PyObject*)type, proto);
+ if (!key) {
+ return -1;
+ }
+
+ rc = PyDict_SetItem(psyco_adapters, key, cast);
+ Py_DECREF(key);
+
+ return rc;
+}
+
+/* microprotocols_adapt - adapt an object to the built-in protocol */
+
+PyObject *
+microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
+{
+ PyObject *adapter, *key;
+
+ /* we don't check for exact type conformance as specified in PEP 246
+ because the SQLitePrepareProtocolType type is abstract and there is no
+ way to get a quotable object to be its instance */
+
+ /* look for an adapter in the registry */
+ key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
+ if (!key) {
+ return NULL;
+ }
+ adapter = PyDict_GetItem(psyco_adapters, key);
+ Py_DECREF(key);
+ if (adapter) {
+ PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+ return adapted;
+ }
+
+ /* try to have the protocol adapt this object*/
+ if (PyObject_HasAttrString(proto, "__adapt__")) {
+ PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
+ if (adapted) {
+ if (adapted != Py_None) {
+ return adapted;
+ } else {
+ Py_DECREF(adapted);
+ }
+ }
+
+ if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
+ return NULL;
+ }
+
+ /* and finally try to have the object adapt itself */
+ if (PyObject_HasAttrString(obj, "__conform__")) {
+ PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
+ if (adapted) {
+ if (adapted != Py_None) {
+ return adapted;
+ } else {
+ Py_DECREF(adapted);
+ }
+ }
+
+ if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
+ return NULL;
+ }
+ }
+
+ /* else set the right exception and return NULL */
+ PyErr_SetString(ProgrammingError, "can't adapt");
+ return NULL;
+}
+
+/** module-level functions **/
+
+PyObject *
+psyco_microprotocols_adapt(Cursor *self, PyObject *args)
+{
+ PyObject *obj, *alt = NULL;
+ PyObject *proto = (PyObject*)&SQLitePrepareProtocolType;
+
+ if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
+ return microprotocols_adapt(obj, proto, alt);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/microprotocols.h b/sys/src/cmd/python/Modules/_sqlite/microprotocols.h
new file mode 100644
index 000000000..f601bb3d3
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/microprotocols.h
@@ -0,0 +1,59 @@
+/* microprotocols.c - definitions for minimalist and non-validating protocols
+ *
+ * Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
+ *
+ * This file is part of psycopg and was adapted for pysqlite. Federico Di
+ * Gregorio gave the permission to use it within pysqlite under the following
+ * license:
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PSYCOPG_MICROPROTOCOLS_H
+#define PSYCOPG_MICROPROTOCOLS_H 1
+
+#include <Python.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** adapters registry **/
+
+extern PyObject *psyco_adapters;
+
+/** the names of the three mandatory methods **/
+
+#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
+#define MICROPROTOCOLS_GETSTRING_NAME "getstring"
+#define MICROPROTOCOLS_GETBINARY_NAME "getbinary"
+
+/** exported functions **/
+
+/* used by module.c to init the microprotocols system */
+extern int microprotocols_init(PyObject *dict);
+extern int microprotocols_add(
+ PyTypeObject *type, PyObject *proto, PyObject *cast);
+extern PyObject *microprotocols_adapt(
+ PyObject *obj, PyObject *proto, PyObject *alt);
+
+extern PyObject *
+ psyco_microprotocols_adapt(Cursor* self, PyObject *args);
+#define psyco_microprotocols_adapt_doc \
+ "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard."
+
+#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */
diff --git a/sys/src/cmd/python/Modules/_sqlite/module.c b/sys/src/cmd/python/Modules/_sqlite/module.c
new file mode 100644
index 000000000..606454ca1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/module.c
@@ -0,0 +1,409 @@
+ /* module.c - the module itself
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "connection.h"
+#include "statement.h"
+#include "cursor.h"
+#include "cache.h"
+#include "prepare_protocol.h"
+#include "microprotocols.h"
+#include "row.h"
+
+#if SQLITE_VERSION_NUMBER >= 3003003
+#define HAVE_SHARED_CACHE
+#endif
+
+/* static objects at module-level */
+
+PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
+ *OperationalError, *ProgrammingError, *IntegrityError, *DataError,
+ *NotSupportedError, *OptimizedUnicode;
+
+PyObject* converters;
+int _enable_callback_tracebacks;
+
+static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ /* Python seems to have no way of extracting a single keyword-arg at
+ * C-level, so this code is redundant with the one in connection_init in
+ * connection.c and must always be copied from there ... */
+
+ static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
+ char* database;
+ int detect_types = 0;
+ PyObject* isolation_level;
+ PyObject* factory = NULL;
+ int check_same_thread = 1;
+ int cached_statements;
+ double timeout = 5.0;
+
+ PyObject* result;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
+ &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
+ {
+ return NULL;
+ }
+
+ if (factory == NULL) {
+ factory = (PyObject*)&ConnectionType;
+ }
+
+ result = PyObject_Call(factory, args, kwargs);
+
+ return result;
+}
+
+static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ static char *kwlist[] = {"statement", NULL, NULL};
+ char* statement;
+
+ PyObject* result;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement))
+ {
+ return NULL;
+ }
+
+ if (sqlite3_complete(statement)) {
+ result = Py_True;
+ } else {
+ result = Py_False;
+ }
+
+ Py_INCREF(result);
+
+ return result;
+}
+
+#ifdef HAVE_SHARED_CACHE
+static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ static char *kwlist[] = {"do_enable", NULL, NULL};
+ int do_enable;
+ int rc;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
+ {
+ return NULL;
+ }
+
+ rc = sqlite3_enable_shared_cache(do_enable);
+
+ if (rc != SQLITE_OK) {
+ PyErr_SetString(OperationalError, "Changing the shared_cache flag failed");
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SHARED_CACHE */
+
+static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+ PyTypeObject* type;
+ PyObject* caster;
+
+ if (!PyArg_ParseTuple(args, "OO", &type, &caster)) {
+ return NULL;
+ }
+
+ microprotocols_add(type, (PyObject*)&SQLitePrepareProtocolType, caster);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+ char* orig_name;
+ char* name = NULL;
+ char* c;
+ PyObject* callable;
+ PyObject* retval = NULL;
+
+ if (!PyArg_ParseTuple(args, "sO", &orig_name, &callable)) {
+ return NULL;
+ }
+
+ /* convert the name to lowercase */
+ name = PyMem_Malloc(strlen(orig_name) + 2);
+ if (!name) {
+ goto error;
+ }
+ strcpy(name, orig_name);
+ for (c = name; *c != (char)0; c++) {
+ *c = (*c) & 0xDF;
+ }
+
+ if (PyDict_SetItemString(converters, name, callable) != 0) {
+ goto error;
+ }
+
+ Py_INCREF(Py_None);
+ retval = Py_None;
+error:
+ if (name) {
+ PyMem_Free(name);
+ }
+ return retval;
+}
+
+static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args, PyObject* kwargs)
+{
+ if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+void converters_init(PyObject* dict)
+{
+ converters = PyDict_New();
+ if (!converters) {
+ return;
+ }
+
+ PyDict_SetItemString(dict, "converters", converters);
+}
+
+static PyMethodDef module_methods[] = {
+ {"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
+ {"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement. Non-standard.")},
+#ifdef HAVE_SHARED_CACHE
+ {"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread. Experimental/Non-standard.")},
+#endif
+ {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry. Non-standard.")},
+ {"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite. Non-standard.")},
+ {"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
+ {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, METH_VARARGS, PyDoc_STR("Enable or disable callback functions throwing errors to stderr.")},
+ {NULL, NULL}
+};
+
+struct _IntConstantPair {
+ char* constant_name;
+ int constant_value;
+};
+
+typedef struct _IntConstantPair IntConstantPair;
+
+static IntConstantPair _int_constants[] = {
+ {"PARSE_DECLTYPES", PARSE_DECLTYPES},
+ {"PARSE_COLNAMES", PARSE_COLNAMES},
+
+ {"SQLITE_OK", SQLITE_OK},
+ {"SQLITE_DENY", SQLITE_DENY},
+ {"SQLITE_IGNORE", SQLITE_IGNORE},
+ {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX},
+ {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE},
+ {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX},
+ {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE},
+ {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER},
+ {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW},
+ {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER},
+ {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW},
+ {"SQLITE_DELETE", SQLITE_DELETE},
+ {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX},
+ {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE},
+ {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX},
+ {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE},
+ {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER},
+ {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW},
+ {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER},
+ {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW},
+ {"SQLITE_INSERT", SQLITE_INSERT},
+ {"SQLITE_PRAGMA", SQLITE_PRAGMA},
+ {"SQLITE_READ", SQLITE_READ},
+ {"SQLITE_SELECT", SQLITE_SELECT},
+ {"SQLITE_TRANSACTION", SQLITE_TRANSACTION},
+ {"SQLITE_UPDATE", SQLITE_UPDATE},
+ {"SQLITE_ATTACH", SQLITE_ATTACH},
+ {"SQLITE_DETACH", SQLITE_DETACH},
+#if SQLITE_VERSION_NUMBER >= 3002001
+ {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE},
+ {"SQLITE_REINDEX", SQLITE_REINDEX},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3003000
+ {"SQLITE_ANALYZE", SQLITE_ANALYZE},
+#endif
+ {(char*)NULL, 0}
+};
+
+PyMODINIT_FUNC init_sqlite3(void)
+{
+ PyObject *module, *dict;
+ PyObject *tmp_obj;
+ int i;
+
+ module = Py_InitModule("_sqlite3", module_methods);
+
+ if (!module ||
+ (row_setup_types() < 0) ||
+ (cursor_setup_types() < 0) ||
+ (connection_setup_types() < 0) ||
+ (cache_setup_types() < 0) ||
+ (statement_setup_types() < 0) ||
+ (prepare_protocol_setup_types() < 0)
+ ) {
+ return;
+ }
+
+ Py_INCREF(&ConnectionType);
+ PyModule_AddObject(module, "Connection", (PyObject*) &ConnectionType);
+ Py_INCREF(&CursorType);
+ PyModule_AddObject(module, "Cursor", (PyObject*) &CursorType);
+ Py_INCREF(&CacheType);
+ PyModule_AddObject(module, "Statement", (PyObject*)&StatementType);
+ Py_INCREF(&StatementType);
+ PyModule_AddObject(module, "Cache", (PyObject*) &CacheType);
+ Py_INCREF(&SQLitePrepareProtocolType);
+ PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &SQLitePrepareProtocolType);
+ Py_INCREF(&RowType);
+ PyModule_AddObject(module, "Row", (PyObject*) &RowType);
+
+ if (!(dict = PyModule_GetDict(module))) {
+ goto error;
+ }
+
+ /*** Create DB-API Exception hierarchy */
+
+ if (!(Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "Error", Error);
+
+ if (!(Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "Warning", Warning);
+
+ /* Error subclasses */
+
+ if (!(InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", Error, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
+
+ if (!(DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", Error, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
+
+ /* DatabaseError subclasses */
+
+ if (!(InternalError = PyErr_NewException(MODULE_NAME ".InternalError", DatabaseError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "InternalError", InternalError);
+
+ if (!(OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", DatabaseError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "OperationalError", OperationalError);
+
+ if (!(ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", DatabaseError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
+
+ if (!(IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", DatabaseError,NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
+
+ if (!(DataError = PyErr_NewException(MODULE_NAME ".DataError", DatabaseError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "DataError", DataError);
+
+ if (!(NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", DatabaseError, NULL))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
+
+ /* We just need "something" unique for OptimizedUnicode. It does not really
+ * need to be a string subclass. Just anything that can act as a special
+ * marker for us. So I pulled PyCell_Type out of my magic hat.
+ */
+ Py_INCREF((PyObject*)&PyCell_Type);
+ OptimizedUnicode = (PyObject*)&PyCell_Type;
+ PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
+
+ /* Set integer constants */
+ for (i = 0; _int_constants[i].constant_name != 0; i++) {
+ tmp_obj = PyInt_FromLong(_int_constants[i].constant_value);
+ if (!tmp_obj) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj);
+ Py_DECREF(tmp_obj);
+ }
+
+ if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "version", tmp_obj);
+ Py_DECREF(tmp_obj);
+
+ if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
+ goto error;
+ }
+ PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
+ Py_DECREF(tmp_obj);
+
+ /* initialize microprotocols layer */
+ microprotocols_init(dict);
+
+ /* initialize the default converters */
+ converters_init(dict);
+
+ _enable_callback_tracebacks = 0;
+
+ /* Original comment form _bsddb.c in the Python core. This is also still
+ * needed nowadays for Python 2.3/2.4.
+ *
+ * PyEval_InitThreads is called here due to a quirk in python 1.5
+ * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
+ * The global interepreter lock is not initialized until the first
+ * thread is created using thread.start_new_thread() or fork() is
+ * called. that would cause the ALLOW_THREADS here to segfault due
+ * to a null pointer reference if no threads or child processes
+ * have been created. This works around that and is a no-op if
+ * threads have already been initialized.
+ * (see pybsddb-users mailing list post on 2002-08-07)
+ */
+ PyEval_InitThreads();
+
+error:
+ if (PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
+ }
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/module.h b/sys/src/cmd/python/Modules/_sqlite/module.h
new file mode 100644
index 000000000..e514bd151
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/module.h
@@ -0,0 +1,57 @@
+/* module.h - definitions for the module
+ *
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_MODULE_H
+#define PYSQLITE_MODULE_H
+#include "Python.h"
+
+#define PYSQLITE_VERSION "2.3.2"
+
+extern PyObject* Error;
+extern PyObject* Warning;
+extern PyObject* InterfaceError;
+extern PyObject* DatabaseError;
+extern PyObject* InternalError;
+extern PyObject* OperationalError;
+extern PyObject* ProgrammingError;
+extern PyObject* IntegrityError;
+extern PyObject* DataError;
+extern PyObject* NotSupportedError;
+
+extern PyObject* OptimizedUnicode;
+
+/* the functions time.time() and time.sleep() */
+extern PyObject* time_time;
+extern PyObject* time_sleep;
+
+/* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter
+ * functions, that convert the SQL value to the appropriate Python value.
+ * The key is uppercase.
+ */
+extern PyObject* converters;
+
+extern int _enable_callback_tracebacks;
+
+#define PARSE_DECLTYPES 1
+#define PARSE_COLNAMES 2
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c b/sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c
new file mode 100644
index 000000000..26b663be1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c
@@ -0,0 +1,84 @@
+/* prepare_protocol.c - the protocol for preparing values for SQLite
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "prepare_protocol.h"
+
+int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs)
+{
+ return 0;
+}
+
+void prepare_protocol_dealloc(SQLitePrepareProtocol* self)
+{
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+PyTypeObject SQLitePrepareProtocolType= {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME ".PrepareProtocol", /* tp_name */
+ sizeof(SQLitePrepareProtocol), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)prepare_protocol_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)prepare_protocol_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+extern int prepare_protocol_setup_types(void)
+{
+ SQLitePrepareProtocolType.tp_new = PyType_GenericNew;
+ SQLitePrepareProtocolType.ob_type= &PyType_Type;
+ return PyType_Ready(&SQLitePrepareProtocolType);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h b/sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h
new file mode 100644
index 000000000..2fc4f61cd
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h
@@ -0,0 +1,41 @@
+/* prepare_protocol.h - the protocol for preparing values for SQLite
+ *
+ * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_PREPARE_PROTOCOL_H
+#define PYSQLITE_PREPARE_PROTOCOL_H
+#include "Python.h"
+
+typedef struct
+{
+ PyObject_HEAD
+} SQLitePrepareProtocol;
+
+extern PyTypeObject SQLitePrepareProtocolType;
+
+int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs);
+void prepare_protocol_dealloc(SQLitePrepareProtocol* self);
+
+int prepare_protocol_setup_types(void);
+
+#define UNKNOWN (-1)
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/row.c b/sys/src/cmd/python/Modules/_sqlite/row.c
new file mode 100644
index 000000000..80b613554
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/row.c
@@ -0,0 +1,202 @@
+/* row.c - an enhanced tuple for database rows
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "row.h"
+#include "cursor.h"
+#include "sqlitecompat.h"
+
+void row_dealloc(Row* self)
+{
+ Py_XDECREF(self->data);
+ Py_XDECREF(self->description);
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+int row_init(Row* self, PyObject* args, PyObject* kwargs)
+{
+ PyObject* data;
+ Cursor* cursor;
+
+ self->data = 0;
+ self->description = 0;
+
+ if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) {
+ return -1;
+ }
+
+ if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&CursorType)) {
+ PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
+ return -1;
+ }
+
+ if (!PyTuple_Check(data)) {
+ PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
+ return -1;
+ }
+
+ Py_INCREF(data);
+ self->data = data;
+
+ Py_INCREF(cursor->description);
+ self->description = cursor->description;
+
+ return 0;
+}
+
+PyObject* row_subscript(Row* self, PyObject* idx)
+{
+ long _idx;
+ char* key;
+ int nitems, i;
+ char* compare_key;
+
+ char* p1;
+ char* p2;
+
+ PyObject* item;
+
+ if (PyInt_Check(idx)) {
+ _idx = PyInt_AsLong(idx);
+ item = PyTuple_GetItem(self->data, _idx);
+ Py_XINCREF(item);
+ return item;
+ } else if (PyLong_Check(idx)) {
+ _idx = PyLong_AsLong(idx);
+ item = PyTuple_GetItem(self->data, _idx);
+ Py_XINCREF(item);
+ return item;
+ } else if (PyString_Check(idx)) {
+ key = PyString_AsString(idx);
+
+ nitems = PyTuple_Size(self->description);
+
+ for (i = 0; i < nitems; i++) {
+ compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
+ if (!compare_key) {
+ return NULL;
+ }
+
+ p1 = key;
+ p2 = compare_key;
+
+ while (1) {
+ if ((*p1 == (char)0) || (*p2 == (char)0)) {
+ break;
+ }
+
+ if ((*p1 | 0x20) != (*p2 | 0x20)) {
+ break;
+ }
+
+ p1++;
+ p2++;
+ }
+
+ if ((*p1 == (char)0) && (*p2 == (char)0)) {
+ /* found item */
+ item = PyTuple_GetItem(self->data, i);
+ Py_INCREF(item);
+ return item;
+ }
+
+ }
+
+ PyErr_SetString(PyExc_IndexError, "No item with that key");
+ return NULL;
+ } else if (PySlice_Check(idx)) {
+ PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
+ return NULL;
+ } else {
+ PyErr_SetString(PyExc_IndexError, "Index must be int or string");
+ return NULL;
+ }
+}
+
+Py_ssize_t row_length(Row* self, PyObject* args, PyObject* kwargs)
+{
+ return PyTuple_GET_SIZE(self->data);
+}
+
+static int row_print(Row* self, FILE *fp, int flags)
+{
+ return (&PyTuple_Type)->tp_print(self->data, fp, flags);
+}
+
+
+PyMappingMethods row_as_mapping = {
+ /* mp_length */ (lenfunc)row_length,
+ /* mp_subscript */ (binaryfunc)row_subscript,
+ /* mp_ass_subscript */ (objobjargproc)0,
+};
+
+
+PyTypeObject RowType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME ".Row", /* tp_name */
+ sizeof(Row), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)row_dealloc, /* tp_dealloc */
+ (printfunc)row_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)row_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+extern int row_setup_types(void)
+{
+ RowType.tp_new = PyType_GenericNew;
+ RowType.tp_as_mapping = &row_as_mapping;
+ return PyType_Ready(&RowType);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/row.h b/sys/src/cmd/python/Modules/_sqlite/row.h
new file mode 100644
index 000000000..c6e083c9c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/row.h
@@ -0,0 +1,39 @@
+/* row.h - an enhanced tuple for database rows
+ *
+ * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_ROW_H
+#define PYSQLITE_ROW_H
+#include "Python.h"
+
+typedef struct _Row
+{
+ PyObject_HEAD
+ PyObject* data;
+ PyObject* description;
+} Row;
+
+extern PyTypeObject RowType;
+
+int row_setup_types(void);
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h b/sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h
new file mode 100644
index 000000000..c3798257b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h
@@ -0,0 +1,34 @@
+/* sqlitecompat.h - compatibility macros
+ *
+ * Copyright (C) 2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_COMPAT_H
+#define PYSQLITE_COMPAT_H
+
+/* define Py_ssize_t for pre-2.5 versions of Python */
+
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+typedef int (*lenfunc)(PyObject*);
+#endif
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/statement.c b/sys/src/cmd/python/Modules/_sqlite/statement.c
new file mode 100644
index 000000000..55923e785
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/statement.c
@@ -0,0 +1,432 @@
+/* statement.c - the statement type
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "statement.h"
+#include "cursor.h"
+#include "connection.h"
+#include "microprotocols.h"
+#include "prepare_protocol.h"
+#include "sqlitecompat.h"
+
+/* prototypes */
+int check_remaining_sql(const char* tail);
+
+typedef enum {
+ LINECOMMENT_1,
+ IN_LINECOMMENT,
+ COMMENTSTART_1,
+ IN_COMMENT,
+ COMMENTEND_1,
+ NORMAL
+} parse_remaining_sql_state;
+
+int statement_create(Statement* self, Connection* connection, PyObject* sql)
+{
+ const char* tail;
+ int rc;
+ PyObject* sql_str;
+ char* sql_cstr;
+
+ self->st = NULL;
+ self->in_use = 0;
+
+ if (PyString_Check(sql)) {
+ sql_str = sql;
+ Py_INCREF(sql_str);
+ } else if (PyUnicode_Check(sql)) {
+ sql_str = PyUnicode_AsUTF8String(sql);
+ if (!sql_str) {
+ rc = PYSQLITE_SQL_WRONG_TYPE;
+ return rc;
+ }
+ } else {
+ rc = PYSQLITE_SQL_WRONG_TYPE;
+ return rc;
+ }
+
+ self->in_weakreflist = NULL;
+ self->sql = sql_str;
+
+ sql_cstr = PyString_AsString(sql_str);
+
+ rc = sqlite3_prepare(connection->db,
+ sql_cstr,
+ -1,
+ &self->st,
+ &tail);
+
+ self->db = connection->db;
+
+ if (rc == SQLITE_OK && check_remaining_sql(tail)) {
+ (void)sqlite3_finalize(self->st);
+ self->st = NULL;
+ rc = PYSQLITE_TOO_MUCH_SQL;
+ }
+
+ return rc;
+}
+
+int statement_bind_parameter(Statement* self, int pos, PyObject* parameter)
+{
+ int rc = SQLITE_OK;
+ long longval;
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG longlongval;
+#endif
+ const char* buffer;
+ char* string;
+ Py_ssize_t buflen;
+ PyObject* stringval;
+
+ if (parameter == Py_None) {
+ rc = sqlite3_bind_null(self->st, pos);
+ } else if (PyInt_Check(parameter)) {
+ longval = PyInt_AsLong(parameter);
+ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
+#ifdef HAVE_LONG_LONG
+ } else if (PyLong_Check(parameter)) {
+ longlongval = PyLong_AsLongLong(parameter);
+ /* in the overflow error case, longlongval is -1, and an exception is set */
+ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
+#endif
+ } else if (PyFloat_Check(parameter)) {
+ rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
+ } else if (PyBuffer_Check(parameter)) {
+ if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) {
+ rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
+ rc = -1;
+ }
+ } else if PyString_Check(parameter) {
+ string = PyString_AsString(parameter);
+ rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
+ } else if PyUnicode_Check(parameter) {
+ stringval = PyUnicode_AsUTF8String(parameter);
+ string = PyString_AsString(stringval);
+ rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
+ Py_DECREF(stringval);
+ } else {
+ rc = -1;
+ }
+
+ return rc;
+}
+
+void statement_bind_parameters(Statement* self, PyObject* parameters)
+{
+ PyObject* current_param;
+ PyObject* adapted;
+ const char* binding_name;
+ int i;
+ int rc;
+ int num_params_needed;
+ int num_params;
+
+ Py_BEGIN_ALLOW_THREADS
+ num_params_needed = sqlite3_bind_parameter_count(self->st);
+ Py_END_ALLOW_THREADS
+
+ if (PyDict_Check(parameters)) {
+ /* parameters passed as dictionary */
+ for (i = 1; i <= num_params_needed; i++) {
+ Py_BEGIN_ALLOW_THREADS
+ binding_name = sqlite3_bind_parameter_name(self->st, i);
+ Py_END_ALLOW_THREADS
+ if (!binding_name) {
+ PyErr_Format(ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i);
+ return;
+ }
+
+ binding_name++; /* skip first char (the colon) */
+ current_param = PyDict_GetItemString(parameters, binding_name);
+ if (!current_param) {
+ PyErr_Format(ProgrammingError, "You did not supply a value for binding %d.", i);
+ return;
+ }
+
+ Py_INCREF(current_param);
+ adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
+ if (adapted) {
+ Py_DECREF(current_param);
+ } else {
+ PyErr_Clear();
+ adapted = current_param;
+ }
+
+ rc = statement_bind_parameter(self, i, adapted);
+ Py_DECREF(adapted);
+
+ if (rc != SQLITE_OK) {
+ PyErr_Format(InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
+ return;
+ }
+ }
+ } else {
+ /* parameters passed as sequence */
+ num_params = PySequence_Length(parameters);
+ if (num_params != num_params_needed) {
+ PyErr_Format(ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.",
+ num_params_needed, num_params);
+ return;
+ }
+ for (i = 0; i < num_params; i++) {
+ current_param = PySequence_GetItem(parameters, i);
+ if (!current_param) {
+ return;
+ }
+ adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
+
+ if (adapted) {
+ Py_DECREF(current_param);
+ } else {
+ PyErr_Clear();
+ adapted = current_param;
+ }
+
+ rc = statement_bind_parameter(self, i + 1, adapted);
+ Py_DECREF(adapted);
+
+ if (rc != SQLITE_OK) {
+ PyErr_Format(InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
+ return;
+ }
+ }
+ }
+}
+
+int statement_recompile(Statement* self, PyObject* params)
+{
+ const char* tail;
+ int rc;
+ char* sql_cstr;
+ sqlite3_stmt* new_st;
+
+ sql_cstr = PyString_AsString(self->sql);
+
+ rc = sqlite3_prepare(self->db,
+ sql_cstr,
+ -1,
+ &new_st,
+ &tail);
+
+ if (rc == SQLITE_OK) {
+ /* The efficient sqlite3_transfer_bindings is only available in SQLite
+ * version 3.2.2 or later. For older SQLite releases, that might not
+ * even define SQLITE_VERSION_NUMBER, we do it the manual way.
+ */
+ #ifdef SQLITE_VERSION_NUMBER
+ #if SQLITE_VERSION_NUMBER >= 3002002
+ (void)sqlite3_transfer_bindings(self->st, new_st);
+ #endif
+ #else
+ statement_bind_parameters(self, params);
+ #endif
+
+ (void)sqlite3_finalize(self->st);
+ self->st = new_st;
+ }
+
+ return rc;
+}
+
+int statement_finalize(Statement* self)
+{
+ int rc;
+
+ rc = SQLITE_OK;
+ if (self->st) {
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_finalize(self->st);
+ Py_END_ALLOW_THREADS
+ self->st = NULL;
+ }
+
+ self->in_use = 0;
+
+ return rc;
+}
+
+int statement_reset(Statement* self)
+{
+ int rc;
+
+ rc = SQLITE_OK;
+
+ if (self->in_use && self->st) {
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_reset(self->st);
+ Py_END_ALLOW_THREADS
+
+ if (rc == SQLITE_OK) {
+ self->in_use = 0;
+ }
+ }
+
+ return rc;
+}
+
+void statement_mark_dirty(Statement* self)
+{
+ self->in_use = 1;
+}
+
+void statement_dealloc(Statement* self)
+{
+ int rc;
+
+ if (self->st) {
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_finalize(self->st);
+ Py_END_ALLOW_THREADS
+ }
+
+ self->st = NULL;
+
+ Py_XDECREF(self->sql);
+
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject*)self);
+ }
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+/*
+ * Checks if there is anything left in an SQL string after SQLite compiled it.
+ * This is used to check if somebody tried to execute more than one SQL command
+ * with one execute()/executemany() command, which the DB-API and we don't
+ * allow.
+ *
+ * Returns 1 if there is more left than should be. 0 if ok.
+ */
+int check_remaining_sql(const char* tail)
+{
+ const char* pos = tail;
+
+ parse_remaining_sql_state state = NORMAL;
+
+ for (;;) {
+ switch (*pos) {
+ case 0:
+ return 0;
+ case '-':
+ if (state == NORMAL) {
+ state = LINECOMMENT_1;
+ } else if (state == LINECOMMENT_1) {
+ state = IN_LINECOMMENT;
+ }
+ break;
+ case ' ':
+ case '\t':
+ break;
+ case '\n':
+ case 13:
+ if (state == IN_LINECOMMENT) {
+ state = NORMAL;
+ }
+ break;
+ case '/':
+ if (state == NORMAL) {
+ state = COMMENTSTART_1;
+ } else if (state == COMMENTEND_1) {
+ state = NORMAL;
+ } else if (state == COMMENTSTART_1) {
+ return 1;
+ }
+ break;
+ case '*':
+ if (state == NORMAL) {
+ return 1;
+ } else if (state == LINECOMMENT_1) {
+ return 1;
+ } else if (state == COMMENTSTART_1) {
+ state = IN_COMMENT;
+ } else if (state == IN_COMMENT) {
+ state = COMMENTEND_1;
+ }
+ break;
+ default:
+ if (state == COMMENTEND_1) {
+ state = IN_COMMENT;
+ } else if (state == IN_LINECOMMENT) {
+ } else if (state == IN_COMMENT) {
+ } else {
+ return 1;
+ }
+ }
+
+ pos++;
+ }
+
+ return 0;
+}
+
+PyTypeObject StatementType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ MODULE_NAME ".Statement", /* tp_name */
+ sizeof(Statement), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)statement_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(Statement, in_weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0 /* tp_free */
+};
+
+extern int statement_setup_types(void)
+{
+ StatementType.tp_new = PyType_GenericNew;
+ return PyType_Ready(&StatementType);
+}
diff --git a/sys/src/cmd/python/Modules/_sqlite/statement.h b/sys/src/cmd/python/Modules/_sqlite/statement.h
new file mode 100644
index 000000000..57ee36fa6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/statement.h
@@ -0,0 +1,59 @@
+/* statement.h - definitions for the statement type
+ *
+ * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_STATEMENT_H
+#define PYSQLITE_STATEMENT_H
+#include "Python.h"
+
+#include "connection.h"
+#include "sqlite3.h"
+
+#define PYSQLITE_TOO_MUCH_SQL (-100)
+#define PYSQLITE_SQL_WRONG_TYPE (-101)
+
+typedef struct
+{
+ PyObject_HEAD
+ sqlite3* db;
+ sqlite3_stmt* st;
+ PyObject* sql;
+ int in_use;
+ PyObject* in_weakreflist; /* List of weak references */
+} Statement;
+
+extern PyTypeObject StatementType;
+
+int statement_create(Statement* self, Connection* connection, PyObject* sql);
+void statement_dealloc(Statement* self);
+
+int statement_bind_parameter(Statement* self, int pos, PyObject* parameter);
+void statement_bind_parameters(Statement* self, PyObject* parameters);
+
+int statement_recompile(Statement* self, PyObject* parameters);
+int statement_finalize(Statement* self);
+int statement_reset(Statement* self);
+void statement_mark_dirty(Statement* self);
+
+int statement_setup_types(void);
+
+#endif
diff --git a/sys/src/cmd/python/Modules/_sqlite/util.c b/sys/src/cmd/python/Modules/_sqlite/util.c
new file mode 100644
index 000000000..f5a7233a9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/util.c
@@ -0,0 +1,96 @@
+/* util.c - various utility functions
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "module.h"
+#include "connection.h"
+
+int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
+)
+{
+ int rc;
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_step(statement);
+ Py_END_ALLOW_THREADS
+
+ return rc;
+}
+
+/**
+ * Checks the SQLite error code and sets the appropriate DB-API exception.
+ * Returns the error code (0 means no error occurred).
+ */
+int _seterror(sqlite3* db)
+{
+ int errorcode;
+
+ errorcode = sqlite3_errcode(db);
+
+ switch (errorcode)
+ {
+ case SQLITE_OK:
+ PyErr_Clear();
+ break;
+ case SQLITE_INTERNAL:
+ case SQLITE_NOTFOUND:
+ PyErr_SetString(InternalError, sqlite3_errmsg(db));
+ break;
+ case SQLITE_NOMEM:
+ (void)PyErr_NoMemory();
+ break;
+ case SQLITE_ERROR:
+ case SQLITE_PERM:
+ case SQLITE_ABORT:
+ case SQLITE_BUSY:
+ case SQLITE_LOCKED:
+ case SQLITE_READONLY:
+ case SQLITE_INTERRUPT:
+ case SQLITE_IOERR:
+ case SQLITE_FULL:
+ case SQLITE_CANTOPEN:
+ case SQLITE_PROTOCOL:
+ case SQLITE_EMPTY:
+ case SQLITE_SCHEMA:
+ PyErr_SetString(OperationalError, sqlite3_errmsg(db));
+ break;
+ case SQLITE_CORRUPT:
+ PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
+ break;
+ case SQLITE_TOOBIG:
+ PyErr_SetString(DataError, sqlite3_errmsg(db));
+ break;
+ case SQLITE_CONSTRAINT:
+ case SQLITE_MISMATCH:
+ PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
+ break;
+ case SQLITE_MISUSE:
+ PyErr_SetString(ProgrammingError, sqlite3_errmsg(db));
+ break;
+ default:
+ PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
+ break;
+ }
+
+ return errorcode;
+}
+
diff --git a/sys/src/cmd/python/Modules/_sqlite/util.h b/sys/src/cmd/python/Modules/_sqlite/util.h
new file mode 100644
index 000000000..7ce3d403c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sqlite/util.h
@@ -0,0 +1,38 @@
+/* util.h - various utility functions
+ *
+ * Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
+ *
+ * This file is part of pysqlite.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef PYSQLITE_UTIL_H
+#define PYSQLITE_UTIL_H
+#include "Python.h"
+#include "pythread.h"
+#include "sqlite3.h"
+#include "connection.h"
+
+int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection);
+
+/**
+ * Checks the SQLite error code and sets the appropriate DB-API exception.
+ * Returns the error code (0 means no error occurred).
+ */
+int _seterror(sqlite3* db);
+#endif
diff --git a/sys/src/cmd/python/Modules/_sre.c b/sys/src/cmd/python/Modules/_sre.c
new file mode 100644
index 000000000..c1eb71cf2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_sre.c
@@ -0,0 +1,3429 @@
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * partial history:
+ * 1999-10-24 fl created (based on existing template matcher code)
+ * 2000-03-06 fl first alpha, sort of
+ * 2000-08-01 fl fixes for 1.6b1
+ * 2000-08-07 fl use PyOS_CheckStack() if available
+ * 2000-09-20 fl added expand method
+ * 2001-03-20 fl lots of fixes for 2.1b2
+ * 2001-04-15 fl export copyright as Python attribute, not global
+ * 2001-04-28 fl added __copy__ methods (work in progress)
+ * 2001-05-14 fl fixes for 1.5.2 compatibility
+ * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis)
+ * 2001-10-18 fl fixed group reset issue (from Matthew Mueller)
+ * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1
+ * 2001-10-21 fl added sub/subn primitive
+ * 2001-10-24 fl added finditer primitive (for 2.2 only)
+ * 2001-12-07 fl fixed memory leak in sub/subn (Guido van Rossum)
+ * 2002-11-09 fl fixed empty sub/subn return type
+ * 2003-04-18 mvl fully support 4-byte codes
+ * 2003-10-17 gn implemented non recursive scheme
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
+ *
+ * This version of the SRE library can be redistributed under CNRI's
+ * Python 1.6 license. For any other use, please contact Secret Labs
+ * AB (info@pythonware.com).
+ *
+ * Portions of this engine have been developed in cooperation with
+ * CNRI. Hewlett-Packard provided funding for 1.6 integration and
+ * other compatibility work.
+ */
+
+#ifndef SRE_RECURSIVE
+
+static char copyright[] =
+ " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB ";
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structmember.h" /* offsetof */
+
+#include "sre.h"
+
+#include <ctype.h>
+
+/* name of this module, minus the leading underscore */
+#if !defined(SRE_MODULE)
+#define SRE_MODULE "sre"
+#endif
+
+#define SRE_PY_MODULE "re"
+
+/* defining this one enables tracing */
+#undef VERBOSE
+
+#if PY_VERSION_HEX >= 0x01060000
+#if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE)
+/* defining this enables unicode support (default under 1.6a1 and later) */
+#define HAVE_UNICODE
+#endif
+#endif
+
+/* -------------------------------------------------------------------- */
+/* optional features */
+
+/* enables fast searching */
+#define USE_FAST_SEARCH
+
+/* enables aggressive inlining (always on for Visual C) */
+#undef USE_INLINE
+
+/* enables copy/deepcopy handling (work in progress) */
+#undef USE_BUILTIN_COPY
+
+#if PY_VERSION_HEX < 0x01060000
+#define PyObject_DEL(op) PyMem_DEL((op))
+#endif
+
+/* -------------------------------------------------------------------- */
+
+#if defined(_MSC_VER)
+#pragma optimize("agtw", on) /* doesn't seem to make much difference... */
+#pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */
+/* fastest possible local call under MSVC */
+#define LOCAL(type) static __inline type __fastcall
+#elif defined(USE_INLINE)
+#define LOCAL(type) static inline type
+#else
+#define LOCAL(type) static type
+#endif
+
+/* error codes */
+#define SRE_ERROR_ILLEGAL -1 /* illegal opcode */
+#define SRE_ERROR_STATE -2 /* illegal state */
+#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
+#define SRE_ERROR_MEMORY -9 /* out of memory */
+
+#if defined(VERBOSE)
+#define TRACE(v) printf v
+#else
+#define TRACE(v)
+#endif
+
+/* -------------------------------------------------------------------- */
+/* search engine state */
+
+/* default character predicates (run sre_chars.py to regenerate tables) */
+
+#define SRE_DIGIT_MASK 1
+#define SRE_SPACE_MASK 2
+#define SRE_LINEBREAK_MASK 4
+#define SRE_ALNUM_MASK 8
+#define SRE_WORD_MASK 16
+
+/* FIXME: this assumes ASCII. create tables in init_sre() instead */
+
+static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2,
+2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,
+0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 };
+
+static char sre_char_lower[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+120, 121, 122, 123, 124, 125, 126, 127 };
+
+#define SRE_IS_DIGIT(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)
+#define SRE_IS_SPACE(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)
+#define SRE_IS_LINEBREAK(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)
+#define SRE_IS_ALNUM(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)
+#define SRE_IS_WORD(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)
+
+static unsigned int sre_lower(unsigned int ch)
+{
+ return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch);
+}
+
+/* locale-specific character predicates */
+/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
+ * warnings when c's type supports only numbers < N+1 */
+#define SRE_LOC_IS_DIGIT(ch) (!((ch) & ~255) ? isdigit((ch)) : 0)
+#define SRE_LOC_IS_SPACE(ch) (!((ch) & ~255) ? isspace((ch)) : 0)
+#define SRE_LOC_IS_LINEBREAK(ch) ((ch) == '\n')
+#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0)
+#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')
+
+static unsigned int sre_lower_locale(unsigned int ch)
+{
+ return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);
+}
+
+/* unicode-specific character predicates */
+
+#if defined(HAVE_UNICODE)
+
+#define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDIGIT((Py_UNICODE)(ch))
+#define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch))
+#define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK((Py_UNICODE)(ch))
+#define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM((Py_UNICODE)(ch))
+#define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')
+
+static unsigned int sre_lower_unicode(unsigned int ch)
+{
+ return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch));
+}
+
+#endif
+
+LOCAL(int)
+sre_category(SRE_CODE category, unsigned int ch)
+{
+ switch (category) {
+
+ case SRE_CATEGORY_DIGIT:
+ return SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_NOT_DIGIT:
+ return !SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_SPACE:
+ return SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_NOT_SPACE:
+ return !SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_WORD:
+ return SRE_IS_WORD(ch);
+ case SRE_CATEGORY_NOT_WORD:
+ return !SRE_IS_WORD(ch);
+ case SRE_CATEGORY_LINEBREAK:
+ return SRE_IS_LINEBREAK(ch);
+ case SRE_CATEGORY_NOT_LINEBREAK:
+ return !SRE_IS_LINEBREAK(ch);
+
+ case SRE_CATEGORY_LOC_WORD:
+ return SRE_LOC_IS_WORD(ch);
+ case SRE_CATEGORY_LOC_NOT_WORD:
+ return !SRE_LOC_IS_WORD(ch);
+
+#if defined(HAVE_UNICODE)
+ case SRE_CATEGORY_UNI_DIGIT:
+ return SRE_UNI_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_NOT_DIGIT:
+ return !SRE_UNI_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_SPACE:
+ return SRE_UNI_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_NOT_SPACE:
+ return !SRE_UNI_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_WORD:
+ return SRE_UNI_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_NOT_WORD:
+ return !SRE_UNI_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_LINEBREAK:
+ return SRE_UNI_IS_LINEBREAK(ch);
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+ return !SRE_UNI_IS_LINEBREAK(ch);
+#else
+ case SRE_CATEGORY_UNI_DIGIT:
+ return SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_NOT_DIGIT:
+ return !SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_SPACE:
+ return SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_NOT_SPACE:
+ return !SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_WORD:
+ return SRE_LOC_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_NOT_WORD:
+ return !SRE_LOC_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_LINEBREAK:
+ return SRE_IS_LINEBREAK(ch);
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+ return !SRE_IS_LINEBREAK(ch);
+#endif
+ }
+ return 0;
+}
+
+/* helpers */
+
+static void
+data_stack_dealloc(SRE_STATE* state)
+{
+ if (state->data_stack) {
+ PyMem_FREE(state->data_stack);
+ state->data_stack = NULL;
+ }
+ state->data_stack_size = state->data_stack_base = 0;
+}
+
+static int
+data_stack_grow(SRE_STATE* state, Py_ssize_t size)
+{
+ Py_ssize_t minsize, cursize;
+ minsize = state->data_stack_base+size;
+ cursize = state->data_stack_size;
+ if (cursize < minsize) {
+ void* stack;
+ cursize = minsize+minsize/4+1024;
+ TRACE(("allocate/grow stack %d\n", cursize));
+ stack = PyMem_REALLOC(state->data_stack, cursize);
+ if (!stack) {
+ data_stack_dealloc(state);
+ return SRE_ERROR_MEMORY;
+ }
+ state->data_stack = (char *)stack;
+ state->data_stack_size = cursize;
+ }
+ return 0;
+}
+
+/* generate 8-bit version */
+
+#define SRE_CHAR unsigned char
+#define SRE_AT sre_at
+#define SRE_COUNT sre_count
+#define SRE_CHARSET sre_charset
+#define SRE_INFO sre_info
+#define SRE_MATCH sre_match
+#define SRE_MATCH_CONTEXT sre_match_context
+#define SRE_SEARCH sre_search
+#define SRE_LITERAL_TEMPLATE sre_literal_template
+
+#if defined(HAVE_UNICODE)
+
+#define SRE_RECURSIVE
+#include "_sre.c"
+#undef SRE_RECURSIVE
+
+#undef SRE_LITERAL_TEMPLATE
+#undef SRE_SEARCH
+#undef SRE_MATCH
+#undef SRE_MATCH_CONTEXT
+#undef SRE_INFO
+#undef SRE_CHARSET
+#undef SRE_COUNT
+#undef SRE_AT
+#undef SRE_CHAR
+
+/* generate 16-bit unicode version */
+
+#define SRE_CHAR Py_UNICODE
+#define SRE_AT sre_uat
+#define SRE_COUNT sre_ucount
+#define SRE_CHARSET sre_ucharset
+#define SRE_INFO sre_uinfo
+#define SRE_MATCH sre_umatch
+#define SRE_MATCH_CONTEXT sre_umatch_context
+#define SRE_SEARCH sre_usearch
+#define SRE_LITERAL_TEMPLATE sre_uliteral_template
+#endif
+
+#endif /* SRE_RECURSIVE */
+
+/* -------------------------------------------------------------------- */
+/* String matching engine */
+
+/* the following section is compiled twice, with different character
+ settings */
+
+LOCAL(int)
+SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)
+{
+ /* check if pointer is at given position */
+
+ Py_ssize_t thisp, thatp;
+
+ switch (at) {
+
+ case SRE_AT_BEGINNING:
+ case SRE_AT_BEGINNING_STRING:
+ return ((void*) ptr == state->beginning);
+
+ case SRE_AT_BEGINNING_LINE:
+ return ((void*) ptr == state->beginning ||
+ SRE_IS_LINEBREAK((int) ptr[-1]));
+
+ case SRE_AT_END:
+ return (((void*) (ptr+1) == state->end &&
+ SRE_IS_LINEBREAK((int) ptr[0])) ||
+ ((void*) ptr == state->end));
+
+ case SRE_AT_END_LINE:
+ return ((void*) ptr == state->end ||
+ SRE_IS_LINEBREAK((int) ptr[0]));
+
+ case SRE_AT_END_STRING:
+ return ((void*) ptr == state->end);
+
+ case SRE_AT_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_IS_WORD((int) ptr[0]) : 0;
+ return thisp != thatp;
+
+ case SRE_AT_NON_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_IS_WORD((int) ptr[0]) : 0;
+ return thisp == thatp;
+
+ case SRE_AT_LOC_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_LOC_IS_WORD((int) ptr[0]) : 0;
+ return thisp != thatp;
+
+ case SRE_AT_LOC_NON_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_LOC_IS_WORD((int) ptr[0]) : 0;
+ return thisp == thatp;
+
+#if defined(HAVE_UNICODE)
+ case SRE_AT_UNI_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_UNI_IS_WORD((int) ptr[0]) : 0;
+ return thisp != thatp;
+
+ case SRE_AT_UNI_NON_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_UNI_IS_WORD((int) ptr[0]) : 0;
+ return thisp == thatp;
+#endif
+
+ }
+
+ return 0;
+}
+
+LOCAL(int)
+SRE_CHARSET(SRE_CODE* set, SRE_CODE ch)
+{
+ /* check if character is a member of the given set */
+
+ int ok = 1;
+
+ for (;;) {
+ switch (*set++) {
+
+ case SRE_OP_FAILURE:
+ return !ok;
+
+ case SRE_OP_LITERAL:
+ /* <LITERAL> <code> */
+ if (ch == set[0])
+ return ok;
+ set++;
+ break;
+
+ case SRE_OP_CATEGORY:
+ /* <CATEGORY> <code> */
+ if (sre_category(set[0], (int) ch))
+ return ok;
+ set += 1;
+ break;
+
+ case SRE_OP_CHARSET:
+ if (sizeof(SRE_CODE) == 2) {
+ /* <CHARSET> <bitmap> (16 bits per code word) */
+ if (ch < 256 && (set[ch >> 4] & (1 << (ch & 15))))
+ return ok;
+ set += 16;
+ }
+ else {
+ /* <CHARSET> <bitmap> (32 bits per code word) */
+ if (ch < 256 && (set[ch >> 5] & (1 << (ch & 31))))
+ return ok;
+ set += 8;
+ }
+ break;
+
+ case SRE_OP_RANGE:
+ /* <RANGE> <lower> <upper> */
+ if (set[0] <= ch && ch <= set[1])
+ return ok;
+ set += 2;
+ break;
+
+ case SRE_OP_NEGATE:
+ ok = !ok;
+ break;
+
+ case SRE_OP_BIGCHARSET:
+ /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
+ {
+ Py_ssize_t count, block;
+ count = *(set++);
+
+ if (sizeof(SRE_CODE) == 2) {
+ block = ((unsigned char*)set)[ch >> 8];
+ set += 128;
+ if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15)))
+ return ok;
+ set += count*16;
+ }
+ else {
+ /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
+ * warnings when c's type supports only numbers < N+1 */
+ if (!(ch & ~65535))
+ block = ((unsigned char*)set)[ch >> 8];
+ else
+ block = -1;
+ set += 64;
+ if (block >=0 &&
+ (set[block*8 + ((ch & 255)>>5)] & (1 << (ch & 31))))
+ return ok;
+ set += count*8;
+ }
+ break;
+ }
+
+ default:
+ /* internal error -- there's not much we can do about it
+ here, so let's just pretend it didn't match... */
+ return 0;
+ }
+ }
+}
+
+LOCAL(Py_ssize_t) SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern);
+
+LOCAL(Py_ssize_t)
+SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
+{
+ SRE_CODE chr;
+ SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;
+ SRE_CHAR* end = (SRE_CHAR *)state->end;
+ Py_ssize_t i;
+
+ /* adjust end */
+ if (maxcount < end - ptr && maxcount != 65535)
+ end = ptr + maxcount;
+
+ switch (pattern[0]) {
+
+ case SRE_OP_IN:
+ /* repeated set */
+ TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
+ while (ptr < end && SRE_CHARSET(pattern + 2, *ptr))
+ ptr++;
+ break;
+
+ case SRE_OP_ANY:
+ /* repeated dot wildcard. */
+ TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
+ while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
+ ptr++;
+ break;
+
+ case SRE_OP_ANY_ALL:
+ /* repeated dot wildcard. skip to the end of the target
+ string, and backtrack from there */
+ TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
+ ptr = end;
+ break;
+
+ case SRE_OP_LITERAL:
+ /* repeated literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) *ptr == chr)
+ ptr++;
+ break;
+
+ case SRE_OP_LITERAL_IGNORE:
+ /* repeated literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) state->lower(*ptr) == chr)
+ ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL:
+ /* repeated non-literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) *ptr != chr)
+ ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL_IGNORE:
+ /* repeated non-literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) state->lower(*ptr) != chr)
+ ptr++;
+ break;
+
+ default:
+ /* repeated single character pattern */
+ TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
+ while ((SRE_CHAR*) state->ptr < end) {
+ i = SRE_MATCH(state, pattern);
+ if (i < 0)
+ return i;
+ if (!i)
+ break;
+ }
+ TRACE(("|%p|%p|COUNT %d\n", pattern, ptr,
+ (SRE_CHAR*) state->ptr - ptr));
+ return (SRE_CHAR*) state->ptr - ptr;
+ }
+
+ TRACE(("|%p|%p|COUNT %d\n", pattern, ptr, ptr - (SRE_CHAR*) state->ptr));
+ return ptr - (SRE_CHAR*) state->ptr;
+}
+
+#if 0 /* not used in this release */
+LOCAL(int)
+SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)
+{
+ /* check if an SRE_OP_INFO block matches at the current position.
+ returns the number of SRE_CODE objects to skip if successful, 0
+ if no match */
+
+ SRE_CHAR* end = state->end;
+ SRE_CHAR* ptr = state->ptr;
+ Py_ssize_t i;
+
+ /* check minimal length */
+ if (pattern[3] && (end - ptr) < pattern[3])
+ return 0;
+
+ /* check known prefix */
+ if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) {
+ /* <length> <skip> <prefix data> <overlap data> */
+ for (i = 0; i < pattern[5]; i++)
+ if ((SRE_CODE) ptr[i] != pattern[7 + i])
+ return 0;
+ return pattern[0] + 2 * pattern[6];
+ }
+ return pattern[0];
+}
+#endif
+
+/* The macros below should be used to protect recursive SRE_MATCH()
+ * calls that *failed* and do *not* return immediately (IOW, those
+ * that will backtrack). Explaining:
+ *
+ * - Recursive SRE_MATCH() returned true: that's usually a success
+ * (besides atypical cases like ASSERT_NOT), therefore there's no
+ * reason to restore lastmark;
+ *
+ * - Recursive SRE_MATCH() returned false but the current SRE_MATCH()
+ * is returning to the caller: If the current SRE_MATCH() is the
+ * top function of the recursion, returning false will be a matching
+ * failure, and it doesn't matter where lastmark is pointing to.
+ * If it's *not* the top function, it will be a recursive SRE_MATCH()
+ * failure by itself, and the calling SRE_MATCH() will have to deal
+ * with the failure by the same rules explained here (it will restore
+ * lastmark by itself if necessary);
+ *
+ * - Recursive SRE_MATCH() returned false, and will continue the
+ * outside 'for' loop: must be protected when breaking, since the next
+ * OP could potentially depend on lastmark;
+ *
+ * - Recursive SRE_MATCH() returned false, and will be called again
+ * inside a local for/while loop: must be protected between each
+ * loop iteration, since the recursive SRE_MATCH() could do anything,
+ * and could potentially depend on lastmark.
+ *
+ * For more information, check the discussion at SF patch #712900.
+ */
+#define LASTMARK_SAVE() \
+ do { \
+ ctx->lastmark = state->lastmark; \
+ ctx->lastindex = state->lastindex; \
+ } while (0)
+#define LASTMARK_RESTORE() \
+ do { \
+ state->lastmark = ctx->lastmark; \
+ state->lastindex = ctx->lastindex; \
+ } while (0)
+
+#define RETURN_ERROR(i) do { return i; } while(0)
+#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
+#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
+
+#define RETURN_ON_ERROR(i) \
+ do { if (i < 0) RETURN_ERROR(i); } while (0)
+#define RETURN_ON_SUCCESS(i) \
+ do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
+#define RETURN_ON_FAILURE(i) \
+ do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
+
+#define SFY(x) #x
+
+#define DATA_STACK_ALLOC(state, type, ptr) \
+do { \
+ alloc_pos = state->data_stack_base; \
+ TRACE(("allocating %s in %d (%d)\n", \
+ SFY(type), alloc_pos, sizeof(type))); \
+ if (state->data_stack_size < alloc_pos+sizeof(type)) { \
+ int j = data_stack_grow(state, sizeof(type)); \
+ if (j < 0) return j; \
+ if (ctx_pos != -1) \
+ DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
+ } \
+ ptr = (type*)(state->data_stack+alloc_pos); \
+ state->data_stack_base += sizeof(type); \
+} while (0)
+
+#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
+do { \
+ TRACE(("looking up %s at %d\n", SFY(type), pos)); \
+ ptr = (type*)(state->data_stack+pos); \
+} while (0)
+
+#define DATA_STACK_PUSH(state, data, size) \
+do { \
+ TRACE(("copy data in %p to %d (%d)\n", \
+ data, state->data_stack_base, size)); \
+ if (state->data_stack_size < state->data_stack_base+size) { \
+ int j = data_stack_grow(state, size); \
+ if (j < 0) return j; \
+ if (ctx_pos != -1) \
+ DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
+ } \
+ memcpy(state->data_stack+state->data_stack_base, data, size); \
+ state->data_stack_base += size; \
+} while (0)
+
+#define DATA_STACK_POP(state, data, size, discard) \
+do { \
+ TRACE(("copy data to %p from %d (%d)\n", \
+ data, state->data_stack_base-size, size)); \
+ memcpy(data, state->data_stack+state->data_stack_base-size, size); \
+ if (discard) \
+ state->data_stack_base -= size; \
+} while (0)
+
+#define DATA_STACK_POP_DISCARD(state, size) \
+do { \
+ TRACE(("discard data from %d (%d)\n", \
+ state->data_stack_base-size, size)); \
+ state->data_stack_base -= size; \
+} while(0)
+
+#define DATA_PUSH(x) \
+ DATA_STACK_PUSH(state, (x), sizeof(*(x)))
+#define DATA_POP(x) \
+ DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
+#define DATA_POP_DISCARD(x) \
+ DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
+#define DATA_ALLOC(t,p) \
+ DATA_STACK_ALLOC(state, t, p)
+#define DATA_LOOKUP_AT(t,p,pos) \
+ DATA_STACK_LOOKUP_AT(state,t,p,pos)
+
+#define MARK_PUSH(lastmark) \
+ do if (lastmark > 0) { \
+ i = lastmark; /* ctx->lastmark may change if reallocated */ \
+ DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \
+ } while (0)
+#define MARK_POP(lastmark) \
+ do if (lastmark > 0) { \
+ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \
+ } while (0)
+#define MARK_POP_KEEP(lastmark) \
+ do if (lastmark > 0) { \
+ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \
+ } while (0)
+#define MARK_POP_DISCARD(lastmark) \
+ do if (lastmark > 0) { \
+ DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \
+ } while (0)
+
+#define JUMP_NONE 0
+#define JUMP_MAX_UNTIL_1 1
+#define JUMP_MAX_UNTIL_2 2
+#define JUMP_MAX_UNTIL_3 3
+#define JUMP_MIN_UNTIL_1 4
+#define JUMP_MIN_UNTIL_2 5
+#define JUMP_MIN_UNTIL_3 6
+#define JUMP_REPEAT 7
+#define JUMP_REPEAT_ONE_1 8
+#define JUMP_REPEAT_ONE_2 9
+#define JUMP_MIN_REPEAT_ONE 10
+#define JUMP_BRANCH 11
+#define JUMP_ASSERT 12
+#define JUMP_ASSERT_NOT 13
+
+#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
+ DATA_ALLOC(SRE_MATCH_CONTEXT, nextctx); \
+ nextctx->last_ctx_pos = ctx_pos; \
+ nextctx->jump = jumpvalue; \
+ nextctx->pattern = nextpattern; \
+ ctx_pos = alloc_pos; \
+ ctx = nextctx; \
+ goto entrance; \
+ jumplabel: \
+ while (0) /* gcc doesn't like labels at end of scopes */ \
+
+typedef struct {
+ Py_ssize_t last_ctx_pos;
+ Py_ssize_t jump;
+ SRE_CHAR* ptr;
+ SRE_CODE* pattern;
+ Py_ssize_t count;
+ Py_ssize_t lastmark;
+ Py_ssize_t lastindex;
+ union {
+ SRE_CODE chr;
+ SRE_REPEAT* rep;
+ } u;
+} SRE_MATCH_CONTEXT;
+
+/* check if string matches the given pattern. returns <0 for
+ error, 0 for failure, and 1 for success */
+LOCAL(Py_ssize_t)
+SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
+{
+ SRE_CHAR* end = (SRE_CHAR *)state->end;
+ Py_ssize_t alloc_pos, ctx_pos = -1;
+ Py_ssize_t i, ret = 0;
+ Py_ssize_t jump;
+
+ SRE_MATCH_CONTEXT* ctx;
+ SRE_MATCH_CONTEXT* nextctx;
+
+ TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
+
+ DATA_ALLOC(SRE_MATCH_CONTEXT, ctx);
+ ctx->last_ctx_pos = -1;
+ ctx->jump = JUMP_NONE;
+ ctx->pattern = pattern;
+ ctx_pos = alloc_pos;
+
+entrance:
+
+ ctx->ptr = (SRE_CHAR *)state->ptr;
+
+ if (ctx->pattern[0] == SRE_OP_INFO) {
+ /* optimization info block */
+ /* <INFO> <1=skip> <2=flags> <3=min> ... */
+ if (ctx->pattern[3] && (end - ctx->ptr) < ctx->pattern[3]) {
+ TRACE(("reject (got %d chars, need %d)\n",
+ (end - ctx->ptr), ctx->pattern[3]));
+ RETURN_FAILURE;
+ }
+ ctx->pattern += ctx->pattern[1] + 1;
+ }
+
+ for (;;) {
+
+ switch (*ctx->pattern++) {
+
+ case SRE_OP_MARK:
+ /* set mark */
+ /* <MARK> <gid> */
+ TRACE(("|%p|%p|MARK %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ i = ctx->pattern[0];
+ if (i & 1)
+ state->lastindex = i/2 + 1;
+ if (i > state->lastmark) {
+ /* state->lastmark is the highest valid index in the
+ state->mark array. If it is increased by more than 1,
+ the intervening marks must be set to NULL to signal
+ that these marks have not been encountered. */
+ Py_ssize_t j = state->lastmark + 1;
+ while (j < i)
+ state->mark[j++] = NULL;
+ state->lastmark = i;
+ }
+ state->mark[i] = ctx->ptr;
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_LITERAL:
+ /* match literal string */
+ /* <LITERAL> <code> */
+ TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,
+ ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL:
+ /* match anything that is not literal character */
+ /* <NOT_LITERAL> <code> */
+ TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,
+ ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_SUCCESS:
+ /* end of pattern */
+ TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+
+ case SRE_OP_AT:
+ /* match at given position */
+ /* <AT> <code> */
+ TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));
+ if (!SRE_AT(state, ctx->ptr, *ctx->pattern))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_CATEGORY:
+ /* match at given category */
+ /* <CATEGORY> <code> */
+ TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,
+ ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_ANY:
+ /* match anything (except a newline) */
+ /* <ANY> */
+ TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))
+ RETURN_FAILURE;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_ANY_ALL:
+ /* match anything */
+ /* <ANY_ALL> */
+ TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end)
+ RETURN_FAILURE;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_IN:
+ /* match set member (or non_member) */
+ /* <IN> <skip> <set> */
+ TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end || !SRE_CHARSET(ctx->pattern + 1, *ctx->ptr))
+ RETURN_FAILURE;
+ ctx->pattern += ctx->pattern[0];
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_LITERAL_IGNORE:
+ TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
+ ctx->pattern, ctx->ptr, ctx->pattern[0]));
+ if (ctx->ptr >= end ||
+ state->lower(*ctx->ptr) != state->lower(*ctx->pattern))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL_IGNORE:
+ TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
+ ctx->pattern, ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end ||
+ state->lower(*ctx->ptr) == state->lower(*ctx->pattern))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_IN_IGNORE:
+ TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end
+ || !SRE_CHARSET(ctx->pattern+1,
+ (SRE_CODE)state->lower(*ctx->ptr)))
+ RETURN_FAILURE;
+ ctx->pattern += ctx->pattern[0];
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_JUMP:
+ case SRE_OP_INFO:
+ /* jump forward */
+ /* <JUMP> <offset> */
+ TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ ctx->pattern += ctx->pattern[0];
+ break;
+
+ case SRE_OP_BRANCH:
+ /* alternation */
+ /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
+ TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));
+ LASTMARK_SAVE();
+ ctx->u.rep = state->repeat;
+ if (ctx->u.rep)
+ MARK_PUSH(ctx->lastmark);
+ for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {
+ if (ctx->pattern[1] == SRE_OP_LITERAL &&
+ (ctx->ptr >= end ||
+ (SRE_CODE) *ctx->ptr != ctx->pattern[2]))
+ continue;
+ if (ctx->pattern[1] == SRE_OP_IN &&
+ (ctx->ptr >= end ||
+ !SRE_CHARSET(ctx->pattern + 3, (SRE_CODE) *ctx->ptr)))
+ continue;
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);
+ if (ret) {
+ if (ctx->u.rep)
+ MARK_POP_DISCARD(ctx->lastmark);
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ if (ctx->u.rep)
+ MARK_POP_KEEP(ctx->lastmark);
+ LASTMARK_RESTORE();
+ }
+ if (ctx->u.rep)
+ MARK_POP_DISCARD(ctx->lastmark);
+ RETURN_FAILURE;
+
+ case SRE_OP_REPEAT_ONE:
+ /* match repeated sequence (maximizing regexp) */
+
+ /* this operator only works if the repeated item is
+ exactly one character wide, and we're not already
+ collecting backtracking points. for other cases,
+ use the MAX_REPEAT operator */
+
+ /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
+
+ TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[1], ctx->pattern[2]));
+
+ if (ctx->ptr + ctx->pattern[1] > end)
+ RETURN_FAILURE; /* cannot match */
+
+ state->ptr = ctx->ptr;
+
+ ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[2]);
+ RETURN_ON_ERROR(ret);
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+ ctx->count = ret;
+ ctx->ptr += ctx->count;
+
+ /* when we arrive here, count contains the number of
+ matches, and ctx->ptr points to the tail of the target
+ string. check if the rest of the pattern matches,
+ and backtrack if not. */
+
+ if (ctx->count < (Py_ssize_t) ctx->pattern[1])
+ RETURN_FAILURE;
+
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+ /* tail is empty. we're finished */
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+ }
+
+ LASTMARK_SAVE();
+
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {
+ /* tail starts with a literal. skip positions where
+ the rest of the pattern cannot possibly match */
+ ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];
+ for (;;) {
+ while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&
+ (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {
+ ctx->ptr--;
+ ctx->count--;
+ }
+ if (ctx->count < (Py_ssize_t) ctx->pattern[1])
+ break;
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
+ ctx->pattern+ctx->pattern[0]);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+
+ LASTMARK_RESTORE();
+
+ ctx->ptr--;
+ ctx->count--;
+ }
+
+ } else {
+ /* general case */
+ while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
+ ctx->pattern+ctx->pattern[0]);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->ptr--;
+ ctx->count--;
+ LASTMARK_RESTORE();
+ }
+ }
+ RETURN_FAILURE;
+
+ case SRE_OP_MIN_REPEAT_ONE:
+ /* match repeated sequence (minimizing regexp) */
+
+ /* this operator only works if the repeated item is
+ exactly one character wide, and we're not already
+ collecting backtracking points. for other cases,
+ use the MIN_REPEAT operator */
+
+ /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
+
+ TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[1], ctx->pattern[2]));
+
+ if (ctx->ptr + ctx->pattern[1] > end)
+ RETURN_FAILURE; /* cannot match */
+
+ state->ptr = ctx->ptr;
+
+ if (ctx->pattern[1] == 0)
+ ctx->count = 0;
+ else {
+ /* count using pattern min as the maximum */
+ ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[1]);
+ RETURN_ON_ERROR(ret);
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+ if (ret < (Py_ssize_t) ctx->pattern[1])
+ /* didn't match minimum number of times */
+ RETURN_FAILURE;
+ /* advance past minimum matches of repeat */
+ ctx->count = ret;
+ ctx->ptr += ctx->count;
+ }
+
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+ /* tail is empty. we're finished */
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+
+ } else {
+ /* general case */
+ LASTMARK_SAVE();
+ while ((Py_ssize_t)ctx->pattern[2] == 65535
+ || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
+ ctx->pattern+ctx->pattern[0]);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ state->ptr = ctx->ptr;
+ ret = SRE_COUNT(state, ctx->pattern+3, 1);
+ RETURN_ON_ERROR(ret);
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+ if (ret == 0)
+ break;
+ assert(ret == 1);
+ ctx->ptr++;
+ ctx->count++;
+ LASTMARK_RESTORE();
+ }
+ }
+ RETURN_FAILURE;
+
+ case SRE_OP_REPEAT:
+ /* create repeat context. all the hard work is done
+ by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
+ /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */
+ TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[1], ctx->pattern[2]));
+
+ /* install new repeat context */
+ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
+ if (!ctx->u.rep) {
+ PyErr_NoMemory();
+ RETURN_FAILURE;
+ }
+ ctx->u.rep->count = -1;
+ ctx->u.rep->pattern = ctx->pattern;
+ ctx->u.rep->prev = state->repeat;
+ ctx->u.rep->last_ptr = NULL;
+ state->repeat = ctx->u.rep;
+
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
+ state->repeat = ctx->u.rep->prev;
+ PyObject_FREE(ctx->u.rep);
+
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ RETURN_FAILURE;
+
+ case SRE_OP_MAX_UNTIL:
+ /* maximizing repeat */
+ /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
+
+ /* FIXME: we probably need to deal with zero-width
+ matches in here... */
+
+ ctx->u.rep = state->repeat;
+ if (!ctx->u.rep)
+ RETURN_ERROR(SRE_ERROR_STATE);
+
+ state->ptr = ctx->ptr;
+
+ ctx->count = ctx->u.rep->count+1;
+
+ TRACE(("|%p|%p|MAX_UNTIL %d\n", ctx->pattern,
+ ctx->ptr, ctx->count));
+
+ if (ctx->count < ctx->u.rep->pattern[1]) {
+ /* not enough matches */
+ ctx->u.rep->count = ctx->count;
+ DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
+ ctx->u.rep->pattern+3);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+ }
+
+ if ((ctx->count < ctx->u.rep->pattern[2] ||
+ ctx->u.rep->pattern[2] == 65535) &&
+ state->ptr != ctx->u.rep->last_ptr) {
+ /* we may have enough matches, but if we can
+ match another item, do so */
+ ctx->u.rep->count = ctx->count;
+ LASTMARK_SAVE();
+ MARK_PUSH(ctx->lastmark);
+ /* zero-width match protection */
+ DATA_PUSH(&ctx->u.rep->last_ptr);
+ ctx->u.rep->last_ptr = state->ptr;
+ DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
+ ctx->u.rep->pattern+3);
+ DATA_POP(&ctx->u.rep->last_ptr);
+ if (ret) {
+ MARK_POP_DISCARD(ctx->lastmark);
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ MARK_POP(ctx->lastmark);
+ LASTMARK_RESTORE();
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ }
+
+ /* cannot match more repeated items here. make sure the
+ tail matches */
+ state->repeat = ctx->u.rep->prev;
+ DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);
+ RETURN_ON_SUCCESS(ret);
+ state->repeat = ctx->u.rep;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+
+ case SRE_OP_MIN_UNTIL:
+ /* minimizing repeat */
+ /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
+
+ ctx->u.rep = state->repeat;
+ if (!ctx->u.rep)
+ RETURN_ERROR(SRE_ERROR_STATE);
+
+ state->ptr = ctx->ptr;
+
+ ctx->count = ctx->u.rep->count+1;
+
+ TRACE(("|%p|%p|MIN_UNTIL %d %p\n", ctx->pattern,
+ ctx->ptr, ctx->count, ctx->u.rep->pattern));
+
+ if (ctx->count < ctx->u.rep->pattern[1]) {
+ /* not enough matches */
+ ctx->u.rep->count = ctx->count;
+ DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
+ ctx->u.rep->pattern+3);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+ }
+
+ LASTMARK_SAVE();
+
+ /* see if the tail matches */
+ state->repeat = ctx->u.rep->prev;
+ DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+
+ state->repeat = ctx->u.rep;
+ state->ptr = ctx->ptr;
+
+ LASTMARK_RESTORE();
+
+ if (ctx->count >= ctx->u.rep->pattern[2]
+ && ctx->u.rep->pattern[2] != 65535)
+ RETURN_FAILURE;
+
+ ctx->u.rep->count = ctx->count;
+ DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
+ ctx->u.rep->pattern+3);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+
+ case SRE_OP_GROUPREF:
+ /* match backreference */
+ TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ i = ctx->pattern[0];
+ {
+ Py_ssize_t groupref = i+i;
+ if (groupref >= state->lastmark) {
+ RETURN_FAILURE;
+ } else {
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+ if (!p || !e || e < p)
+ RETURN_FAILURE;
+ while (p < e) {
+ if (ctx->ptr >= end || *ctx->ptr != *p)
+ RETURN_FAILURE;
+ p++; ctx->ptr++;
+ }
+ }
+ }
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_GROUPREF_IGNORE:
+ /* match backreference */
+ TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ i = ctx->pattern[0];
+ {
+ Py_ssize_t groupref = i+i;
+ if (groupref >= state->lastmark) {
+ RETURN_FAILURE;
+ } else {
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+ if (!p || !e || e < p)
+ RETURN_FAILURE;
+ while (p < e) {
+ if (ctx->ptr >= end ||
+ state->lower(*ctx->ptr) != state->lower(*p))
+ RETURN_FAILURE;
+ p++; ctx->ptr++;
+ }
+ }
+ }
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_GROUPREF_EXISTS:
+ TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
+ i = ctx->pattern[0];
+ {
+ Py_ssize_t groupref = i+i;
+ if (groupref >= state->lastmark) {
+ ctx->pattern += ctx->pattern[1];
+ break;
+ } else {
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+ if (!p || !e || e < p) {
+ ctx->pattern += ctx->pattern[1];
+ break;
+ }
+ }
+ }
+ ctx->pattern += 2;
+ break;
+
+ case SRE_OP_ASSERT:
+ /* assert subpattern */
+ /* <ASSERT> <skip> <back> <pattern> */
+ TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[1]));
+ state->ptr = ctx->ptr - ctx->pattern[1];
+ if (state->ptr < state->beginning)
+ RETURN_FAILURE;
+ DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);
+ RETURN_ON_FAILURE(ret);
+ ctx->pattern += ctx->pattern[0];
+ break;
+
+ case SRE_OP_ASSERT_NOT:
+ /* assert not subpattern */
+ /* <ASSERT_NOT> <skip> <back> <pattern> */
+ TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[1]));
+ state->ptr = ctx->ptr - ctx->pattern[1];
+ if (state->ptr >= state->beginning) {
+ DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_FAILURE;
+ }
+ }
+ ctx->pattern += ctx->pattern[0];
+ break;
+
+ case SRE_OP_FAILURE:
+ /* immediate failure */
+ TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));
+ RETURN_FAILURE;
+
+ default:
+ TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[-1]));
+ RETURN_ERROR(SRE_ERROR_ILLEGAL);
+ }
+ }
+
+exit:
+ ctx_pos = ctx->last_ctx_pos;
+ jump = ctx->jump;
+ DATA_POP_DISCARD(ctx);
+ if (ctx_pos == -1)
+ return ret;
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+
+ switch (jump) {
+ case JUMP_MAX_UNTIL_2:
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));
+ goto jump_max_until_2;
+ case JUMP_MAX_UNTIL_3:
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));
+ goto jump_max_until_3;
+ case JUMP_MIN_UNTIL_2:
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));
+ goto jump_min_until_2;
+ case JUMP_MIN_UNTIL_3:
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));
+ goto jump_min_until_3;
+ case JUMP_BRANCH:
+ TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));
+ goto jump_branch;
+ case JUMP_MAX_UNTIL_1:
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));
+ goto jump_max_until_1;
+ case JUMP_MIN_UNTIL_1:
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));
+ goto jump_min_until_1;
+ case JUMP_REPEAT:
+ TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));
+ goto jump_repeat;
+ case JUMP_REPEAT_ONE_1:
+ TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));
+ goto jump_repeat_one_1;
+ case JUMP_REPEAT_ONE_2:
+ TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));
+ goto jump_repeat_one_2;
+ case JUMP_MIN_REPEAT_ONE:
+ TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));
+ goto jump_min_repeat_one;
+ case JUMP_ASSERT:
+ TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));
+ goto jump_assert;
+ case JUMP_ASSERT_NOT:
+ TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));
+ goto jump_assert_not;
+ case JUMP_NONE:
+ TRACE(("|%p|%p|RETURN %d\n", ctx->pattern, ctx->ptr, ret));
+ break;
+ }
+
+ return ret; /* should never get here */
+}
+
+LOCAL(Py_ssize_t)
+SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
+{
+ SRE_CHAR* ptr = (SRE_CHAR *)state->start;
+ SRE_CHAR* end = (SRE_CHAR *)state->end;
+ Py_ssize_t status = 0;
+ Py_ssize_t prefix_len = 0;
+ Py_ssize_t prefix_skip = 0;
+ SRE_CODE* prefix = NULL;
+ SRE_CODE* charset = NULL;
+ SRE_CODE* overlap = NULL;
+ int flags = 0;
+
+ if (pattern[0] == SRE_OP_INFO) {
+ /* optimization info block */
+ /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */
+
+ flags = pattern[2];
+
+ if (pattern[3] > 1) {
+ /* adjust end point (but make sure we leave at least one
+ character in there, so literal search will work) */
+ end -= pattern[3]-1;
+ if (end <= ptr)
+ end = ptr+1;
+ }
+
+ if (flags & SRE_INFO_PREFIX) {
+ /* pattern starts with a known prefix */
+ /* <length> <skip> <prefix data> <overlap data> */
+ prefix_len = pattern[5];
+ prefix_skip = pattern[6];
+ prefix = pattern + 7;
+ overlap = prefix + prefix_len - 1;
+ } else if (flags & SRE_INFO_CHARSET)
+ /* pattern starts with a character from a known set */
+ /* <charset> */
+ charset = pattern + 5;
+
+ pattern += 1 + pattern[1];
+ }
+
+ TRACE(("prefix = %p %d %d\n", prefix, prefix_len, prefix_skip));
+ TRACE(("charset = %p\n", charset));
+
+#if defined(USE_FAST_SEARCH)
+ if (prefix_len > 1) {
+ /* pattern starts with a known prefix. use the overlap
+ table to skip forward as fast as we possibly can */
+ Py_ssize_t i = 0;
+ end = (SRE_CHAR *)state->end;
+ while (ptr < end) {
+ for (;;) {
+ if ((SRE_CODE) ptr[0] != prefix[i]) {
+ if (!i)
+ break;
+ else
+ i = overlap[i];
+ } else {
+ if (++i == prefix_len) {
+ /* found a potential match */
+ TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
+ state->start = ptr + 1 - prefix_len;
+ state->ptr = ptr + 1 - prefix_len + prefix_skip;
+ if (flags & SRE_INFO_LITERAL)
+ return 1; /* we got all of it */
+ status = SRE_MATCH(state, pattern + 2*prefix_skip);
+ if (status != 0)
+ return status;
+ /* close but no cigar -- try again */
+ i = overlap[i];
+ }
+ break;
+ }
+ }
+ ptr++;
+ }
+ return 0;
+ }
+#endif
+
+ if (pattern[0] == SRE_OP_LITERAL) {
+ /* pattern starts with a literal character. this is used
+ for short prefixes, and if fast search is disabled */
+ SRE_CODE chr = pattern[1];
+ end = (SRE_CHAR *)state->end;
+ for (;;) {
+ while (ptr < end && (SRE_CODE) ptr[0] != chr)
+ ptr++;
+ if (ptr >= end)
+ return 0;
+ TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
+ state->start = ptr;
+ state->ptr = ++ptr;
+ if (flags & SRE_INFO_LITERAL)
+ return 1; /* we got all of it */
+ status = SRE_MATCH(state, pattern + 2);
+ if (status != 0)
+ break;
+ }
+ } else if (charset) {
+ /* pattern starts with a character from a known set */
+ end = (SRE_CHAR *)state->end;
+ for (;;) {
+ while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
+ ptr++;
+ if (ptr >= end)
+ return 0;
+ TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
+ state->start = ptr;
+ state->ptr = ptr;
+ status = SRE_MATCH(state, pattern);
+ if (status != 0)
+ break;
+ ptr++;
+ }
+ } else
+ /* general case */
+ while (ptr <= end) {
+ TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
+ state->start = state->ptr = ptr++;
+ status = SRE_MATCH(state, pattern);
+ if (status != 0)
+ break;
+ }
+
+ return status;
+}
+
+LOCAL(int)
+SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, Py_ssize_t len)
+{
+ /* check if given string is a literal template (i.e. no escapes) */
+ while (len-- > 0)
+ if (*ptr++ == '\\')
+ return 0;
+ return 1;
+}
+
+#if !defined(SRE_RECURSIVE)
+
+/* -------------------------------------------------------------------- */
+/* factories and destructors */
+
+/* see sre.h for object declarations */
+static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int);
+static PyObject*pattern_scanner(PatternObject*, PyObject*);
+
+static PyObject *
+sre_codesize(PyObject* self, PyObject *unused)
+{
+ return Py_BuildValue("l", sizeof(SRE_CODE));
+}
+
+static PyObject *
+sre_getlower(PyObject* self, PyObject* args)
+{
+ int character, flags;
+ if (!PyArg_ParseTuple(args, "ii", &character, &flags))
+ return NULL;
+ if (flags & SRE_FLAG_LOCALE)
+ return Py_BuildValue("i", sre_lower_locale(character));
+ if (flags & SRE_FLAG_UNICODE)
+#if defined(HAVE_UNICODE)
+ return Py_BuildValue("i", sre_lower_unicode(character));
+#else
+ return Py_BuildValue("i", sre_lower_locale(character));
+#endif
+ return Py_BuildValue("i", sre_lower(character));
+}
+
+LOCAL(void)
+state_reset(SRE_STATE* state)
+{
+ /* FIXME: dynamic! */
+ /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/
+
+ state->lastmark = -1;
+ state->lastindex = -1;
+
+ state->repeat = NULL;
+
+ data_stack_dealloc(state);
+}
+
+static void*
+getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
+{
+ /* given a python object, return a data pointer, a length (in
+ characters), and a character size. return NULL if the object
+ is not a string (or not compatible) */
+
+ PyBufferProcs *buffer;
+ Py_ssize_t size, bytes;
+ int charsize;
+ void* ptr;
+
+#if defined(HAVE_UNICODE)
+ if (PyUnicode_Check(string)) {
+ /* unicode strings doesn't always support the buffer interface */
+ ptr = (void*) PyUnicode_AS_DATA(string);
+ bytes = PyUnicode_GET_DATA_SIZE(string);
+ size = PyUnicode_GET_SIZE(string);
+ charsize = sizeof(Py_UNICODE);
+
+ } else {
+#endif
+
+ /* get pointer to string buffer */
+ buffer = string->ob_type->tp_as_buffer;
+ if (!buffer || !buffer->bf_getreadbuffer || !buffer->bf_getsegcount ||
+ buffer->bf_getsegcount(string, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError, "expected string or buffer");
+ return NULL;
+ }
+
+ /* determine buffer size */
+ bytes = buffer->bf_getreadbuffer(string, 0, &ptr);
+ if (bytes < 0) {
+ PyErr_SetString(PyExc_TypeError, "buffer has negative size");
+ return NULL;
+ }
+
+ /* determine character size */
+#if PY_VERSION_HEX >= 0x01060000
+ size = PyObject_Size(string);
+#else
+ size = PyObject_Length(string);
+#endif
+
+ if (PyString_Check(string) || bytes == size)
+ charsize = 1;
+#if defined(HAVE_UNICODE)
+ else if (bytes == (Py_ssize_t) (size * sizeof(Py_UNICODE)))
+ charsize = sizeof(Py_UNICODE);
+#endif
+ else {
+ PyErr_SetString(PyExc_TypeError, "buffer size mismatch");
+ return NULL;
+ }
+
+#if defined(HAVE_UNICODE)
+ }
+#endif
+
+ *p_length = size;
+ *p_charsize = charsize;
+
+ return ptr;
+}
+
+LOCAL(PyObject*)
+state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ /* prepare state object */
+
+ Py_ssize_t length;
+ int charsize;
+ void* ptr;
+
+ memset(state, 0, sizeof(SRE_STATE));
+
+ state->lastmark = -1;
+ state->lastindex = -1;
+
+ ptr = getstring(string, &length, &charsize);
+ if (!ptr)
+ return NULL;
+
+ /* adjust boundaries */
+ if (start < 0)
+ start = 0;
+ else if (start > length)
+ start = length;
+
+ if (end < 0)
+ end = 0;
+ else if (end > length)
+ end = length;
+
+ state->charsize = charsize;
+
+ state->beginning = ptr;
+
+ state->start = (void*) ((char*) ptr + start * state->charsize);
+ state->end = (void*) ((char*) ptr + end * state->charsize);
+
+ Py_INCREF(string);
+ state->string = string;
+ state->pos = start;
+ state->endpos = end;
+
+ if (pattern->flags & SRE_FLAG_LOCALE)
+ state->lower = sre_lower_locale;
+ else if (pattern->flags & SRE_FLAG_UNICODE)
+#if defined(HAVE_UNICODE)
+ state->lower = sre_lower_unicode;
+#else
+ state->lower = sre_lower_locale;
+#endif
+ else
+ state->lower = sre_lower;
+
+ return string;
+}
+
+LOCAL(void)
+state_fini(SRE_STATE* state)
+{
+ Py_XDECREF(state->string);
+ data_stack_dealloc(state);
+}
+
+/* calculate offset from start of string */
+#define STATE_OFFSET(state, member)\
+ (((char*)(member) - (char*)(state)->beginning) / (state)->charsize)
+
+LOCAL(PyObject*)
+state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty)
+{
+ Py_ssize_t i, j;
+
+ index = (index - 1) * 2;
+
+ if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) {
+ if (empty)
+ /* want empty string */
+ i = j = 0;
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ } else {
+ i = STATE_OFFSET(state, state->mark[index]);
+ j = STATE_OFFSET(state, state->mark[index+1]);
+ }
+
+ return PySequence_GetSlice(string, i, j);
+}
+
+static void
+pattern_error(int status)
+{
+ switch (status) {
+ case SRE_ERROR_RECURSION_LIMIT:
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "maximum recursion limit exceeded"
+ );
+ break;
+ case SRE_ERROR_MEMORY:
+ PyErr_NoMemory();
+ break;
+ default:
+ /* other error codes indicate compiler/engine bugs */
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "internal error in regular expression engine"
+ );
+ }
+}
+
+static void
+pattern_dealloc(PatternObject* self)
+{
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
+ Py_XDECREF(self->pattern);
+ Py_XDECREF(self->groupindex);
+ Py_XDECREF(self->indexgroup);
+ PyObject_DEL(self);
+}
+
+static PyObject*
+pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ int status;
+
+ PyObject* string;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist,
+ &string, &start, &end))
+ return NULL;
+
+ string = state_init(&state, self, string, start, end);
+ if (!string)
+ return NULL;
+
+ state.ptr = state.start;
+
+ TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
+
+ if (state.charsize == 1) {
+ status = sre_match(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_umatch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
+ if (PyErr_Occurred())
+ return NULL;
+
+ state_fini(&state);
+
+ return pattern_new_match(self, &state, status);
+}
+
+static PyObject*
+pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ int status;
+
+ PyObject* string;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
+ &string, &start, &end))
+ return NULL;
+
+ string = state_init(&state, self, string, start, end);
+ if (!string)
+ return NULL;
+
+ TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr));
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
+
+ state_fini(&state);
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ return pattern_new_match(self, &state, status);
+}
+
+static PyObject*
+call(char* module, char* function, PyObject* args)
+{
+ PyObject* name;
+ PyObject* mod;
+ PyObject* func;
+ PyObject* result;
+
+ if (!args)
+ return NULL;
+ name = PyString_FromString(module);
+ if (!name)
+ return NULL;
+ mod = PyImport_Import(name);
+ Py_DECREF(name);
+ if (!mod)
+ return NULL;
+ func = PyObject_GetAttrString(mod, function);
+ Py_DECREF(mod);
+ if (!func)
+ return NULL;
+ result = PyObject_CallObject(func, args);
+ Py_DECREF(func);
+ Py_DECREF(args);
+ return result;
+}
+
+#ifdef USE_BUILTIN_COPY
+static int
+deepcopy(PyObject** object, PyObject* memo)
+{
+ PyObject* copy;
+
+ copy = call(
+ "copy", "deepcopy",
+ PyTuple_Pack(2, *object, memo)
+ );
+ if (!copy)
+ return 0;
+
+ Py_DECREF(*object);
+ *object = copy;
+
+ return 1; /* success */
+}
+#endif
+
+static PyObject*
+join_list(PyObject* list, PyObject* pattern)
+{
+ /* join list elements */
+
+ PyObject* joiner;
+#if PY_VERSION_HEX >= 0x01060000
+ PyObject* function;
+ PyObject* args;
+#endif
+ PyObject* result;
+
+ switch (PyList_GET_SIZE(list)) {
+ case 0:
+ Py_DECREF(list);
+ return PySequence_GetSlice(pattern, 0, 0);
+ case 1:
+ result = PyList_GET_ITEM(list, 0);
+ Py_INCREF(result);
+ Py_DECREF(list);
+ return result;
+ }
+
+ /* two or more elements: slice out a suitable separator from the
+ first member, and use that to join the entire list */
+
+ joiner = PySequence_GetSlice(pattern, 0, 0);
+ if (!joiner)
+ return NULL;
+
+#if PY_VERSION_HEX >= 0x01060000
+ function = PyObject_GetAttrString(joiner, "join");
+ if (!function) {
+ Py_DECREF(joiner);
+ return NULL;
+ }
+ args = PyTuple_New(1);
+ if (!args) {
+ Py_DECREF(function);
+ Py_DECREF(joiner);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(args, 0, list);
+ result = PyObject_CallObject(function, args);
+ Py_DECREF(args); /* also removes list */
+ Py_DECREF(function);
+#else
+ result = call(
+ "string", "join",
+ PyTuple_Pack(2, list, joiner)
+ );
+#endif
+ Py_DECREF(joiner);
+
+ return result;
+}
+
+static PyObject*
+pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ PyObject* list;
+ int status;
+ Py_ssize_t i, b, e;
+
+ PyObject* string;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ static char* kwlist[] = { "source", "pos", "endpos", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
+ &string, &start, &end))
+ return NULL;
+
+ string = state_init(&state, self, string, start, end);
+ if (!string)
+ return NULL;
+
+ list = PyList_New(0);
+ if (!list) {
+ state_fini(&state);
+ return NULL;
+ }
+
+ while (state.start <= state.end) {
+
+ PyObject* item;
+
+ state_reset(&state);
+
+ state.ptr = state.start;
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ if (PyErr_Occurred())
+ goto error;
+
+ if (status <= 0) {
+ if (status == 0)
+ break;
+ pattern_error(status);
+ goto error;
+ }
+
+ /* don't bother to build a match object */
+ switch (self->groups) {
+ case 0:
+ b = STATE_OFFSET(&state, state.start);
+ e = STATE_OFFSET(&state, state.ptr);
+ item = PySequence_GetSlice(string, b, e);
+ if (!item)
+ goto error;
+ break;
+ case 1:
+ item = state_getslice(&state, 1, string, 1);
+ if (!item)
+ goto error;
+ break;
+ default:
+ item = PyTuple_New(self->groups);
+ if (!item)
+ goto error;
+ for (i = 0; i < self->groups; i++) {
+ PyObject* o = state_getslice(&state, i+1, string, 1);
+ if (!o) {
+ Py_DECREF(item);
+ goto error;
+ }
+ PyTuple_SET_ITEM(item, i, o);
+ }
+ break;
+ }
+
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ if (state.ptr == state.start)
+ state.start = (void*) ((char*) state.ptr + state.charsize);
+ else
+ state.start = state.ptr;
+
+ }
+
+ state_fini(&state);
+ return list;
+
+error:
+ Py_DECREF(list);
+ state_fini(&state);
+ return NULL;
+
+}
+
+#if PY_VERSION_HEX >= 0x02020000
+static PyObject*
+pattern_finditer(PatternObject* pattern, PyObject* args)
+{
+ PyObject* scanner;
+ PyObject* search;
+ PyObject* iterator;
+
+ scanner = pattern_scanner(pattern, args);
+ if (!scanner)
+ return NULL;
+
+ search = PyObject_GetAttrString(scanner, "search");
+ Py_DECREF(scanner);
+ if (!search)
+ return NULL;
+
+ iterator = PyCallIter_New(search, Py_None);
+ Py_DECREF(search);
+
+ return iterator;
+}
+#endif
+
+static PyObject*
+pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ PyObject* list;
+ PyObject* item;
+ int status;
+ Py_ssize_t n;
+ Py_ssize_t i;
+ void* last;
+
+ PyObject* string;
+ Py_ssize_t maxsplit = 0;
+ static char* kwlist[] = { "source", "maxsplit", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
+ &string, &maxsplit))
+ return NULL;
+
+ string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
+ if (!string)
+ return NULL;
+
+ list = PyList_New(0);
+ if (!list) {
+ state_fini(&state);
+ return NULL;
+ }
+
+ n = 0;
+ last = state.start;
+
+ while (!maxsplit || n < maxsplit) {
+
+ state_reset(&state);
+
+ state.ptr = state.start;
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ if (PyErr_Occurred())
+ goto error;
+
+ if (status <= 0) {
+ if (status == 0)
+ break;
+ pattern_error(status);
+ goto error;
+ }
+
+ if (state.start == state.ptr) {
+ if (last == state.end)
+ break;
+ /* skip one character */
+ state.start = (void*) ((char*) state.ptr + state.charsize);
+ continue;
+ }
+
+ /* get segment before this match */
+ item = PySequence_GetSlice(
+ string, STATE_OFFSET(&state, last),
+ STATE_OFFSET(&state, state.start)
+ );
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ /* add groups (if any) */
+ for (i = 0; i < self->groups; i++) {
+ item = state_getslice(&state, i+1, string, 0);
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+ }
+
+ n = n + 1;
+
+ last = state.start = state.ptr;
+
+ }
+
+ /* get segment following last match (even if empty) */
+ item = PySequence_GetSlice(
+ string, STATE_OFFSET(&state, last), state.endpos
+ );
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ state_fini(&state);
+ return list;
+
+error:
+ Py_DECREF(list);
+ state_fini(&state);
+ return NULL;
+
+}
+
+static PyObject*
+pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
+ Py_ssize_t count, Py_ssize_t subn)
+{
+ SRE_STATE state;
+ PyObject* list;
+ PyObject* item;
+ PyObject* filter;
+ PyObject* args;
+ PyObject* match;
+ void* ptr;
+ int status;
+ Py_ssize_t n;
+ Py_ssize_t i, b, e;
+ int bint;
+ int filter_is_callable;
+
+ if (PyCallable_Check(ptemplate)) {
+ /* sub/subn takes either a function or a template */
+ filter = ptemplate;
+ Py_INCREF(filter);
+ filter_is_callable = 1;
+ } else {
+ /* if not callable, check if it's a literal string */
+ int literal;
+ ptr = getstring(ptemplate, &n, &bint);
+ b = bint;
+ if (ptr) {
+ if (b == 1) {
+ literal = sre_literal_template((unsigned char *)ptr, n);
+ } else {
+#if defined(HAVE_UNICODE)
+ literal = sre_uliteral_template((Py_UNICODE *)ptr, n);
+#endif
+ }
+ } else {
+ PyErr_Clear();
+ literal = 0;
+ }
+ if (literal) {
+ filter = ptemplate;
+ Py_INCREF(filter);
+ filter_is_callable = 0;
+ } else {
+ /* not a literal; hand it over to the template compiler */
+ filter = call(
+ SRE_PY_MODULE, "_subx",
+ PyTuple_Pack(2, self, ptemplate)
+ );
+ if (!filter)
+ return NULL;
+ filter_is_callable = PyCallable_Check(filter);
+ }
+ }
+
+ string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
+ if (!string) {
+ Py_DECREF(filter);
+ return NULL;
+ }
+
+ list = PyList_New(0);
+ if (!list) {
+ Py_DECREF(filter);
+ state_fini(&state);
+ return NULL;
+ }
+
+ n = i = 0;
+
+ while (!count || n < count) {
+
+ state_reset(&state);
+
+ state.ptr = state.start;
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ if (PyErr_Occurred())
+ goto error;
+
+ if (status <= 0) {
+ if (status == 0)
+ break;
+ pattern_error(status);
+ goto error;
+ }
+
+ b = STATE_OFFSET(&state, state.start);
+ e = STATE_OFFSET(&state, state.ptr);
+
+ if (i < b) {
+ /* get segment before this match */
+ item = PySequence_GetSlice(string, i, b);
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ } else if (i == b && i == e && n > 0)
+ /* ignore empty match on latest position */
+ goto next;
+
+ if (filter_is_callable) {
+ /* pass match object through filter */
+ match = pattern_new_match(self, &state, 1);
+ if (!match)
+ goto error;
+ args = PyTuple_Pack(1, match);
+ if (!args) {
+ Py_DECREF(match);
+ goto error;
+ }
+ item = PyObject_CallObject(filter, args);
+ Py_DECREF(args);
+ Py_DECREF(match);
+ if (!item)
+ goto error;
+ } else {
+ /* filter is literal string */
+ item = filter;
+ Py_INCREF(item);
+ }
+
+ /* add to list */
+ if (item != Py_None) {
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+ }
+
+ i = e;
+ n = n + 1;
+
+next:
+ /* move on */
+ if (state.ptr == state.start)
+ state.start = (void*) ((char*) state.ptr + state.charsize);
+ else
+ state.start = state.ptr;
+
+ }
+
+ /* get segment following last match */
+ if (i < state.endpos) {
+ item = PySequence_GetSlice(string, i, state.endpos);
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+ }
+
+ state_fini(&state);
+
+ Py_DECREF(filter);
+
+ /* convert list to single string (also removes list) */
+ item = join_list(list, self->pattern);
+
+ if (!item)
+ return NULL;
+
+ if (subn)
+ return Py_BuildValue("Ni", item, n);
+
+ return item;
+
+error:
+ Py_DECREF(list);
+ state_fini(&state);
+ Py_DECREF(filter);
+ return NULL;
+
+}
+
+static PyObject*
+pattern_sub(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* ptemplate;
+ PyObject* string;
+ Py_ssize_t count = 0;
+ static char* kwlist[] = { "repl", "string", "count", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:sub", kwlist,
+ &ptemplate, &string, &count))
+ return NULL;
+
+ return pattern_subx(self, ptemplate, string, count, 0);
+}
+
+static PyObject*
+pattern_subn(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* ptemplate;
+ PyObject* string;
+ Py_ssize_t count = 0;
+ static char* kwlist[] = { "repl", "string", "count", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:subn", kwlist,
+ &ptemplate, &string, &count))
+ return NULL;
+
+ return pattern_subx(self, ptemplate, string, count, 1);
+}
+
+static PyObject*
+pattern_copy(PatternObject* self, PyObject *unused)
+{
+#ifdef USE_BUILTIN_COPY
+ PatternObject* copy;
+ int offset;
+
+ copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize);
+ if (!copy)
+ return NULL;
+
+ offset = offsetof(PatternObject, groups);
+
+ Py_XINCREF(self->groupindex);
+ Py_XINCREF(self->indexgroup);
+ Py_XINCREF(self->pattern);
+
+ memcpy((char*) copy + offset, (char*) self + offset,
+ sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
+ copy->weakreflist = NULL;
+
+ return (PyObject*) copy;
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object");
+ return NULL;
+#endif
+}
+
+static PyObject*
+pattern_deepcopy(PatternObject* self, PyObject* memo)
+{
+#ifdef USE_BUILTIN_COPY
+ PatternObject* copy;
+
+ copy = (PatternObject*) pattern_copy(self);
+ if (!copy)
+ return NULL;
+
+ if (!deepcopy(&copy->groupindex, memo) ||
+ !deepcopy(&copy->indexgroup, memo) ||
+ !deepcopy(&copy->pattern, memo)) {
+ Py_DECREF(copy);
+ return NULL;
+ }
+
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object");
+ return NULL;
+#endif
+}
+
+PyDoc_STRVAR(pattern_match_doc,
+"match(string[, pos[, endpos]]) --> match object or None.\n\
+ Matches zero or more characters at the beginning of the string");
+
+PyDoc_STRVAR(pattern_search_doc,
+"search(string[, pos[, endpos]]) --> match object or None.\n\
+ Scan through string looking for a match, and return a corresponding\n\
+ MatchObject instance. Return None if no position in the string matches.");
+
+PyDoc_STRVAR(pattern_split_doc,
+"split(string[, maxsplit = 0]) --> list.\n\
+ Split string by the occurrences of pattern.");
+
+PyDoc_STRVAR(pattern_findall_doc,
+"findall(string[, pos[, endpos]]) --> list.\n\
+ Return a list of all non-overlapping matches of pattern in string.");
+
+PyDoc_STRVAR(pattern_finditer_doc,
+"finditer(string[, pos[, endpos]]) --> iterator.\n\
+ Return an iterator over all non-overlapping matches for the \n\
+ RE pattern in string. For each match, the iterator returns a\n\
+ match object.");
+
+PyDoc_STRVAR(pattern_sub_doc,
+"sub(repl, string[, count = 0]) --> newstring\n\
+ Return the string obtained by replacing the leftmost non-overlapping\n\
+ occurrences of pattern in string by the replacement repl.");
+
+PyDoc_STRVAR(pattern_subn_doc,
+"subn(repl, string[, count = 0]) --> (newstring, number of subs)\n\
+ Return the tuple (new_string, number_of_subs_made) found by replacing\n\
+ the leftmost non-overlapping occurrences of pattern with the\n\
+ replacement repl.");
+
+PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");
+
+static PyMethodDef pattern_methods[] = {
+ {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS,
+ pattern_match_doc},
+ {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,
+ pattern_search_doc},
+ {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS,
+ pattern_sub_doc},
+ {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS,
+ pattern_subn_doc},
+ {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS,
+ pattern_split_doc},
+ {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS,
+ pattern_findall_doc},
+#if PY_VERSION_HEX >= 0x02020000
+ {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS,
+ pattern_finditer_doc},
+#endif
+ {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS},
+ {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS},
+ {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O},
+ {NULL, NULL}
+};
+
+static PyObject*
+pattern_getattr(PatternObject* self, char* name)
+{
+ PyObject* res;
+
+ res = Py_FindMethod(pattern_methods, (PyObject*) self, name);
+
+ if (res)
+ return res;
+
+ PyErr_Clear();
+
+ /* attributes */
+ if (!strcmp(name, "pattern")) {
+ Py_INCREF(self->pattern);
+ return self->pattern;
+ }
+
+ if (!strcmp(name, "flags"))
+ return Py_BuildValue("i", self->flags);
+
+ if (!strcmp(name, "groups"))
+ return Py_BuildValue("i", self->groups);
+
+ if (!strcmp(name, "groupindex") && self->groupindex) {
+ Py_INCREF(self->groupindex);
+ return self->groupindex;
+ }
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+statichere PyTypeObject Pattern_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "_" SRE_MODULE ".SRE_Pattern",
+ sizeof(PatternObject), sizeof(SRE_CODE),
+ (destructor)pattern_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)pattern_getattr, /*tp_getattr*/
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ pattern_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
+};
+
+static PyObject *
+_compile(PyObject* self_, PyObject* args)
+{
+ /* "compile" pattern descriptor to pattern object */
+
+ PatternObject* self;
+ Py_ssize_t i, n;
+
+ PyObject* pattern;
+ int flags = 0;
+ PyObject* code;
+ Py_ssize_t groups = 0;
+ PyObject* groupindex = NULL;
+ PyObject* indexgroup = NULL;
+ if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags,
+ &PyList_Type, &code, &groups,
+ &groupindex, &indexgroup))
+ return NULL;
+
+ n = PyList_GET_SIZE(code);
+
+ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
+ if (!self)
+ return NULL;
+
+ self->codesize = n;
+
+ for (i = 0; i < n; i++) {
+ PyObject *o = PyList_GET_ITEM(code, i);
+ unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
+ : PyLong_AsUnsignedLong(o);
+ self->code[i] = (SRE_CODE) value;
+ if ((unsigned long) self->code[i] != value) {
+ PyErr_SetString(PyExc_OverflowError,
+ "regular expression code size limit exceeded");
+ break;
+ }
+ }
+
+ if (PyErr_Occurred()) {
+ PyObject_DEL(self);
+ return NULL;
+ }
+
+ Py_INCREF(pattern);
+ self->pattern = pattern;
+
+ self->flags = flags;
+
+ self->groups = groups;
+
+ Py_XINCREF(groupindex);
+ self->groupindex = groupindex;
+
+ Py_XINCREF(indexgroup);
+ self->indexgroup = indexgroup;
+
+ self->weakreflist = NULL;
+
+ return (PyObject*) self;
+}
+
+/* -------------------------------------------------------------------- */
+/* match methods */
+
+static void
+match_dealloc(MatchObject* self)
+{
+ Py_XDECREF(self->regs);
+ Py_XDECREF(self->string);
+ Py_DECREF(self->pattern);
+ PyObject_DEL(self);
+}
+
+static PyObject*
+match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def)
+{
+ if (index < 0 || index >= self->groups) {
+ /* raise IndexError if we were given a bad group number */
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ index *= 2;
+
+ if (self->string == Py_None || self->mark[index] < 0) {
+ /* return default value if the string or group is undefined */
+ Py_INCREF(def);
+ return def;
+ }
+
+ return PySequence_GetSlice(
+ self->string, self->mark[index], self->mark[index+1]
+ );
+}
+
+static Py_ssize_t
+match_getindex(MatchObject* self, PyObject* index)
+{
+ Py_ssize_t i;
+
+ if (PyInt_Check(index))
+ return PyInt_AsSsize_t(index);
+
+ i = -1;
+
+ if (self->pattern->groupindex) {
+ index = PyObject_GetItem(self->pattern->groupindex, index);
+ if (index) {
+ if (PyInt_Check(index) || PyLong_Check(index))
+ i = PyInt_AsSsize_t(index);
+ Py_DECREF(index);
+ } else
+ PyErr_Clear();
+ }
+
+ return i;
+}
+
+static PyObject*
+match_getslice(MatchObject* self, PyObject* index, PyObject* def)
+{
+ return match_getslice_by_index(self, match_getindex(self, index), def);
+}
+
+static PyObject*
+match_expand(MatchObject* self, PyObject* ptemplate)
+{
+ /* delegate to Python code */
+ return call(
+ SRE_PY_MODULE, "_expand",
+ PyTuple_Pack(3, self->pattern, self, ptemplate)
+ );
+}
+
+static PyObject*
+match_group(MatchObject* self, PyObject* args)
+{
+ PyObject* result;
+ Py_ssize_t i, size;
+
+ size = PyTuple_GET_SIZE(args);
+
+ switch (size) {
+ case 0:
+ result = match_getslice(self, Py_False, Py_None);
+ break;
+ case 1:
+ result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None);
+ break;
+ default:
+ /* fetch multiple items */
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ for (i = 0; i < size; i++) {
+ PyObject* item = match_getslice(
+ self, PyTuple_GET_ITEM(args, i), Py_None
+ );
+ if (!item) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, item);
+ }
+ break;
+ }
+ return result;
+}
+
+static PyObject*
+match_groups(MatchObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* result;
+ Py_ssize_t index;
+
+ PyObject* def = Py_None;
+ static char* kwlist[] = { "default", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def))
+ return NULL;
+
+ result = PyTuple_New(self->groups-1);
+ if (!result)
+ return NULL;
+
+ for (index = 1; index < self->groups; index++) {
+ PyObject* item;
+ item = match_getslice_by_index(self, index, def);
+ if (!item) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, index-1, item);
+ }
+
+ return result;
+}
+
+static PyObject*
+match_groupdict(MatchObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* result;
+ PyObject* keys;
+ Py_ssize_t index;
+
+ PyObject* def = Py_None;
+ static char* kwlist[] = { "default", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def))
+ return NULL;
+
+ result = PyDict_New();
+ if (!result || !self->pattern->groupindex)
+ return result;
+
+ keys = PyMapping_Keys(self->pattern->groupindex);
+ if (!keys)
+ goto failed;
+
+ for (index = 0; index < PyList_GET_SIZE(keys); index++) {
+ int status;
+ PyObject* key;
+ PyObject* value;
+ key = PyList_GET_ITEM(keys, index);
+ if (!key)
+ goto failed;
+ value = match_getslice(self, key, def);
+ if (!value) {
+ Py_DECREF(key);
+ goto failed;
+ }
+ status = PyDict_SetItem(result, key, value);
+ Py_DECREF(value);
+ if (status < 0)
+ goto failed;
+ }
+
+ Py_DECREF(keys);
+
+ return result;
+
+failed:
+ Py_XDECREF(keys);
+ Py_DECREF(result);
+ return NULL;
+}
+
+static PyObject*
+match_start(MatchObject* self, PyObject* args)
+{
+ Py_ssize_t index;
+
+ PyObject* index_ = Py_False; /* zero */
+ if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_))
+ return NULL;
+
+ index = match_getindex(self, index_);
+
+ if (index < 0 || index >= self->groups) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ /* mark is -1 if group is undefined */
+ return Py_BuildValue("i", self->mark[index*2]);
+}
+
+static PyObject*
+match_end(MatchObject* self, PyObject* args)
+{
+ Py_ssize_t index;
+
+ PyObject* index_ = Py_False; /* zero */
+ if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_))
+ return NULL;
+
+ index = match_getindex(self, index_);
+
+ if (index < 0 || index >= self->groups) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ /* mark is -1 if group is undefined */
+ return Py_BuildValue("i", self->mark[index*2+1]);
+}
+
+LOCAL(PyObject*)
+_pair(Py_ssize_t i1, Py_ssize_t i2)
+{
+ PyObject* pair;
+ PyObject* item;
+
+ pair = PyTuple_New(2);
+ if (!pair)
+ return NULL;
+
+ item = PyInt_FromSsize_t(i1);
+ if (!item)
+ goto error;
+ PyTuple_SET_ITEM(pair, 0, item);
+
+ item = PyInt_FromSsize_t(i2);
+ if (!item)
+ goto error;
+ PyTuple_SET_ITEM(pair, 1, item);
+
+ return pair;
+
+ error:
+ Py_DECREF(pair);
+ return NULL;
+}
+
+static PyObject*
+match_span(MatchObject* self, PyObject* args)
+{
+ Py_ssize_t index;
+
+ PyObject* index_ = Py_False; /* zero */
+ if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))
+ return NULL;
+
+ index = match_getindex(self, index_);
+
+ if (index < 0 || index >= self->groups) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ /* marks are -1 if group is undefined */
+ return _pair(self->mark[index*2], self->mark[index*2+1]);
+}
+
+static PyObject*
+match_regs(MatchObject* self)
+{
+ PyObject* regs;
+ PyObject* item;
+ Py_ssize_t index;
+
+ regs = PyTuple_New(self->groups);
+ if (!regs)
+ return NULL;
+
+ for (index = 0; index < self->groups; index++) {
+ item = _pair(self->mark[index*2], self->mark[index*2+1]);
+ if (!item) {
+ Py_DECREF(regs);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(regs, index, item);
+ }
+
+ Py_INCREF(regs);
+ self->regs = regs;
+
+ return regs;
+}
+
+static PyObject*
+match_copy(MatchObject* self, PyObject *unused)
+{
+#ifdef USE_BUILTIN_COPY
+ MatchObject* copy;
+ Py_ssize_t slots, offset;
+
+ slots = 2 * (self->pattern->groups+1);
+
+ copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots);
+ if (!copy)
+ return NULL;
+
+ /* this value a constant, but any compiler should be able to
+ figure that out all by itself */
+ offset = offsetof(MatchObject, string);
+
+ Py_XINCREF(self->pattern);
+ Py_XINCREF(self->string);
+ Py_XINCREF(self->regs);
+
+ memcpy((char*) copy + offset, (char*) self + offset,
+ sizeof(MatchObject) + slots * sizeof(Py_ssize_t) - offset);
+
+ return (PyObject*) copy;
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot copy this match object");
+ return NULL;
+#endif
+}
+
+static PyObject*
+match_deepcopy(MatchObject* self, PyObject* memo)
+{
+#ifdef USE_BUILTIN_COPY
+ MatchObject* copy;
+
+ copy = (MatchObject*) match_copy(self);
+ if (!copy)
+ return NULL;
+
+ if (!deepcopy((PyObject**) &copy->pattern, memo) ||
+ !deepcopy(&copy->string, memo) ||
+ !deepcopy(&copy->regs, memo)) {
+ Py_DECREF(copy);
+ return NULL;
+ }
+
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object");
+ return NULL;
+#endif
+}
+
+static PyMethodDef match_methods[] = {
+ {"group", (PyCFunction) match_group, METH_VARARGS},
+ {"start", (PyCFunction) match_start, METH_VARARGS},
+ {"end", (PyCFunction) match_end, METH_VARARGS},
+ {"span", (PyCFunction) match_span, METH_VARARGS},
+ {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS},
+ {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS},
+ {"expand", (PyCFunction) match_expand, METH_O},
+ {"__copy__", (PyCFunction) match_copy, METH_NOARGS},
+ {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
+ {NULL, NULL}
+};
+
+static PyObject*
+match_getattr(MatchObject* self, char* name)
+{
+ PyObject* res;
+
+ res = Py_FindMethod(match_methods, (PyObject*) self, name);
+ if (res)
+ return res;
+
+ PyErr_Clear();
+
+ if (!strcmp(name, "lastindex")) {
+ if (self->lastindex >= 0)
+ return Py_BuildValue("i", self->lastindex);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (!strcmp(name, "lastgroup")) {
+ if (self->pattern->indexgroup && self->lastindex >= 0) {
+ PyObject* result = PySequence_GetItem(
+ self->pattern->indexgroup, self->lastindex
+ );
+ if (result)
+ return result;
+ PyErr_Clear();
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (!strcmp(name, "string")) {
+ if (self->string) {
+ Py_INCREF(self->string);
+ return self->string;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+
+ if (!strcmp(name, "regs")) {
+ if (self->regs) {
+ Py_INCREF(self->regs);
+ return self->regs;
+ } else
+ return match_regs(self);
+ }
+
+ if (!strcmp(name, "re")) {
+ Py_INCREF(self->pattern);
+ return (PyObject*) self->pattern;
+ }
+
+ if (!strcmp(name, "pos"))
+ return Py_BuildValue("i", self->pos);
+
+ if (!strcmp(name, "endpos"))
+ return Py_BuildValue("i", self->endpos);
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+/* FIXME: implement setattr("string", None) as a special case (to
+ detach the associated string, if any */
+
+statichere PyTypeObject Match_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "_" SRE_MODULE ".SRE_Match",
+ sizeof(MatchObject), sizeof(Py_ssize_t),
+ (destructor)match_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)match_getattr /*tp_getattr*/
+};
+
+static PyObject*
+pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)
+{
+ /* create match object (from state object) */
+
+ MatchObject* match;
+ Py_ssize_t i, j;
+ char* base;
+ int n;
+
+ if (status > 0) {
+
+ /* create match object (with room for extra group marks) */
+ match = PyObject_NEW_VAR(MatchObject, &Match_Type,
+ 2*(pattern->groups+1));
+ if (!match)
+ return NULL;
+
+ Py_INCREF(pattern);
+ match->pattern = pattern;
+
+ Py_INCREF(state->string);
+ match->string = state->string;
+
+ match->regs = NULL;
+ match->groups = pattern->groups+1;
+
+ /* fill in group slices */
+
+ base = (char*) state->beginning;
+ n = state->charsize;
+
+ match->mark[0] = ((char*) state->start - base) / n;
+ match->mark[1] = ((char*) state->ptr - base) / n;
+
+ for (i = j = 0; i < pattern->groups; i++, j+=2)
+ if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {
+ match->mark[j+2] = ((char*) state->mark[j] - base) / n;
+ match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;
+ } else
+ match->mark[j+2] = match->mark[j+3] = -1; /* undefined */
+
+ match->pos = state->pos;
+ match->endpos = state->endpos;
+
+ match->lastindex = state->lastindex;
+
+ return (PyObject*) match;
+
+ } else if (status == 0) {
+
+ /* no match */
+ Py_INCREF(Py_None);
+ return Py_None;
+
+ }
+
+ /* internal error */
+ pattern_error(status);
+ return NULL;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* scanner methods (experimental) */
+
+static void
+scanner_dealloc(ScannerObject* self)
+{
+ state_fini(&self->state);
+ Py_DECREF(self->pattern);
+ PyObject_DEL(self);
+}
+
+static PyObject*
+scanner_match(ScannerObject* self, PyObject *unused)
+{
+ SRE_STATE* state = &self->state;
+ PyObject* match;
+ int status;
+
+ state_reset(state);
+
+ state->ptr = state->start;
+
+ if (state->charsize == 1) {
+ status = sre_match(state, PatternObject_GetCode(self->pattern));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_umatch(state, PatternObject_GetCode(self->pattern));
+#endif
+ }
+ if (PyErr_Occurred())
+ return NULL;
+
+ match = pattern_new_match((PatternObject*) self->pattern,
+ state, status);
+
+ if (status == 0 || state->ptr == state->start)
+ state->start = (void*) ((char*) state->ptr + state->charsize);
+ else
+ state->start = state->ptr;
+
+ return match;
+}
+
+
+static PyObject*
+scanner_search(ScannerObject* self, PyObject *unused)
+{
+ SRE_STATE* state = &self->state;
+ PyObject* match;
+ int status;
+
+ state_reset(state);
+
+ state->ptr = state->start;
+
+ if (state->charsize == 1) {
+ status = sre_search(state, PatternObject_GetCode(self->pattern));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(state, PatternObject_GetCode(self->pattern));
+#endif
+ }
+ if (PyErr_Occurred())
+ return NULL;
+
+ match = pattern_new_match((PatternObject*) self->pattern,
+ state, status);
+
+ if (status == 0 || state->ptr == state->start)
+ state->start = (void*) ((char*) state->ptr + state->charsize);
+ else
+ state->start = state->ptr;
+
+ return match;
+}
+
+static PyMethodDef scanner_methods[] = {
+ {"match", (PyCFunction) scanner_match, METH_NOARGS},
+ {"search", (PyCFunction) scanner_search, METH_NOARGS},
+ {NULL, NULL}
+};
+
+static PyObject*
+scanner_getattr(ScannerObject* self, char* name)
+{
+ PyObject* res;
+
+ res = Py_FindMethod(scanner_methods, (PyObject*) self, name);
+ if (res)
+ return res;
+
+ PyErr_Clear();
+
+ /* attributes */
+ if (!strcmp(name, "pattern")) {
+ Py_INCREF(self->pattern);
+ return self->pattern;
+ }
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+statichere PyTypeObject Scanner_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "_" SRE_MODULE ".SRE_Scanner",
+ sizeof(ScannerObject), 0,
+ (destructor)scanner_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)scanner_getattr, /*tp_getattr*/
+};
+
+static PyObject*
+pattern_scanner(PatternObject* pattern, PyObject* args)
+{
+ /* create search state object */
+
+ ScannerObject* self;
+
+ PyObject* string;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ if (!PyArg_ParseTuple(args, "O|nn:scanner", &string, &start, &end))
+ return NULL;
+
+ /* create scanner object */
+ self = PyObject_NEW(ScannerObject, &Scanner_Type);
+ if (!self)
+ return NULL;
+
+ string = state_init(&self->state, pattern, string, start, end);
+ if (!string) {
+ PyObject_DEL(self);
+ return NULL;
+ }
+
+ Py_INCREF(pattern);
+ self->pattern = (PyObject*) pattern;
+
+ return (PyObject*) self;
+}
+
+static PyMethodDef _functions[] = {
+ {"compile", _compile, METH_VARARGS},
+ {"getcodesize", sre_codesize, METH_NOARGS},
+ {"getlower", sre_getlower, METH_VARARGS},
+ {NULL, NULL}
+};
+
+#if PY_VERSION_HEX < 0x02030000
+DL_EXPORT(void) init_sre(void)
+#else
+PyMODINIT_FUNC init_sre(void)
+#endif
+{
+ PyObject* m;
+ PyObject* d;
+ PyObject* x;
+
+ /* Patch object types */
+ Pattern_Type.ob_type = Match_Type.ob_type =
+ Scanner_Type.ob_type = &PyType_Type;
+
+ m = Py_InitModule("_" SRE_MODULE, _functions);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ x = PyInt_FromLong(SRE_MAGIC);
+ if (x) {
+ PyDict_SetItemString(d, "MAGIC", x);
+ Py_DECREF(x);
+ }
+
+ x = PyInt_FromLong(sizeof(SRE_CODE));
+ if (x) {
+ PyDict_SetItemString(d, "CODESIZE", x);
+ Py_DECREF(x);
+ }
+
+ x = PyString_FromString(copyright);
+ if (x) {
+ PyDict_SetItemString(d, "copyright", x);
+ Py_DECREF(x);
+ }
+}
+
+#endif /* !defined(SRE_RECURSIVE) */
+
+/* vim:ts=4:sw=4:et
+*/
diff --git a/sys/src/cmd/python/Modules/_ssl.c b/sys/src/cmd/python/Modules/_ssl.c
new file mode 100644
index 000000000..3b91b2451
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_ssl.c
@@ -0,0 +1,726 @@
+/* SSL socket module
+
+ SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
+
+ This module is imported by socket.py. It should *not* be used
+ directly.
+
+*/
+
+#include "Python.h"
+enum py_ssl_error {
+ /* these mirror ssl.h */
+ PY_SSL_ERROR_NONE,
+ PY_SSL_ERROR_SSL,
+ PY_SSL_ERROR_WANT_READ,
+ PY_SSL_ERROR_WANT_WRITE,
+ PY_SSL_ERROR_WANT_X509_LOOKUP,
+ PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */
+ PY_SSL_ERROR_ZERO_RETURN,
+ PY_SSL_ERROR_WANT_CONNECT,
+ /* start of non ssl.h errorcodes */
+ PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */
+ PY_SSL_ERROR_INVALID_ERROR_CODE
+};
+
+/* Include symbols from _socket module */
+#include "socketmodule.h"
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+/* Include OpenSSL header files */
+#include "openssl/rsa.h"
+#include "openssl/crypto.h"
+#include "openssl/x509.h"
+#include "openssl/pem.h"
+#include "openssl/ssl.h"
+#include "openssl/err.h"
+#include "openssl/rand.h"
+
+/* SSL error object */
+static PyObject *PySSLErrorObject;
+
+/* SSL socket object */
+
+#define X509_NAME_MAXLEN 256
+
+/* RAND_* APIs got added to OpenSSL in 0.9.5 */
+#if OPENSSL_VERSION_NUMBER >= 0x0090500fL
+# define HAVE_OPENSSL_RAND 1
+#else
+# undef HAVE_OPENSSL_RAND
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ PySocketSockObject *Socket; /* Socket on which we're layered */
+ SSL_CTX* ctx;
+ SSL* ssl;
+ X509* server_cert;
+ char server[X509_NAME_MAXLEN];
+ char issuer[X509_NAME_MAXLEN];
+
+} PySSLObject;
+
+static PyTypeObject PySSL_Type;
+static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
+static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
+static int check_socket_and_wait_for_timeout(PySocketSockObject *s,
+ int writing);
+
+#define PySSLObject_Check(v) ((v)->ob_type == &PySSL_Type)
+
+typedef enum {
+ SOCKET_IS_NONBLOCKING,
+ SOCKET_IS_BLOCKING,
+ SOCKET_HAS_TIMED_OUT,
+ SOCKET_HAS_BEEN_CLOSED,
+ SOCKET_TOO_LARGE_FOR_SELECT,
+ SOCKET_OPERATION_OK
+} timeout_state;
+
+/* XXX It might be helpful to augment the error message generated
+ below with the name of the SSL function that generated the error.
+ I expect it's obvious most of the time.
+*/
+
+static PyObject *
+PySSL_SetError(PySSLObject *obj, int ret)
+{
+ PyObject *v, *n, *s;
+ char *errstr;
+ int err;
+ enum py_ssl_error p;
+
+ assert(ret <= 0);
+
+ err = SSL_get_error(obj->ssl, ret);
+
+ switch (err) {
+ case SSL_ERROR_ZERO_RETURN:
+ errstr = "TLS/SSL connection has been closed";
+ p = PY_SSL_ERROR_ZERO_RETURN;
+ break;
+ case SSL_ERROR_WANT_READ:
+ errstr = "The operation did not complete (read)";
+ p = PY_SSL_ERROR_WANT_READ;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ p = PY_SSL_ERROR_WANT_WRITE;
+ errstr = "The operation did not complete (write)";
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ p = PY_SSL_ERROR_WANT_X509_LOOKUP;
+ errstr = "The operation did not complete (X509 lookup)";
+ break;
+ case SSL_ERROR_WANT_CONNECT:
+ p = PY_SSL_ERROR_WANT_CONNECT;
+ errstr = "The operation did not complete (connect)";
+ break;
+ case SSL_ERROR_SYSCALL:
+ {
+ unsigned long e = ERR_get_error();
+ if (e == 0) {
+ if (ret == 0 || !obj->Socket) {
+ p = PY_SSL_ERROR_EOF;
+ errstr = "EOF occurred in violation of protocol";
+ } else if (ret == -1) {
+ /* the underlying BIO reported an I/O error */
+ return obj->Socket->errorhandler();
+ } else { /* possible? */
+ p = PY_SSL_ERROR_SYSCALL;
+ errstr = "Some I/O error occurred";
+ }
+ } else {
+ p = PY_SSL_ERROR_SYSCALL;
+ /* XXX Protected by global interpreter lock */
+ errstr = ERR_error_string(e, NULL);
+ }
+ break;
+ }
+ case SSL_ERROR_SSL:
+ {
+ unsigned long e = ERR_get_error();
+ p = PY_SSL_ERROR_SSL;
+ if (e != 0)
+ /* XXX Protected by global interpreter lock */
+ errstr = ERR_error_string(e, NULL);
+ else { /* possible? */
+ errstr = "A failure in the SSL library occurred";
+ }
+ break;
+ }
+ default:
+ p = PY_SSL_ERROR_INVALID_ERROR_CODE;
+ errstr = "Invalid error code";
+ }
+ n = PyInt_FromLong((long) p);
+ if (n == NULL)
+ return NULL;
+ v = PyTuple_New(2);
+ if (v == NULL) {
+ Py_DECREF(n);
+ return NULL;
+ }
+
+ s = PyString_FromString(errstr);
+ if (s == NULL) {
+ Py_DECREF(v);
+ Py_DECREF(n);
+ }
+ PyTuple_SET_ITEM(v, 0, n);
+ PyTuple_SET_ITEM(v, 1, s);
+ PyErr_SetObject(PySSLErrorObject, v);
+ Py_DECREF(v);
+ return NULL;
+}
+
+static PySSLObject *
+newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
+{
+ PySSLObject *self;
+ char *errstr = NULL;
+ int ret;
+ int err;
+ int sockstate;
+
+ self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
+ if (self == NULL)
+ return NULL;
+ memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
+ memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
+ self->server_cert = NULL;
+ self->ssl = NULL;
+ self->ctx = NULL;
+ self->Socket = NULL;
+
+ if ((key_file && !cert_file) || (!key_file && cert_file)) {
+ errstr = "Both the key & certificate files must be specified";
+ goto fail;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
+ Py_END_ALLOW_THREADS
+ if (self->ctx == NULL) {
+ errstr = "SSL_CTX_new error";
+ goto fail;
+ }
+
+ if (key_file) {
+ Py_BEGIN_ALLOW_THREADS
+ ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
+ SSL_FILETYPE_PEM);
+ Py_END_ALLOW_THREADS
+ if (ret < 1) {
+ errstr = "SSL_CTX_use_PrivateKey_file error";
+ goto fail;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = SSL_CTX_use_certificate_chain_file(self->ctx,
+ cert_file);
+ Py_END_ALLOW_THREADS
+ SSL_CTX_set_options(self->ctx, SSL_OP_ALL); /* ssl compatibility */
+ if (ret < 1) {
+ errstr = "SSL_CTX_use_certificate_chain_file error";
+ goto fail;
+ }
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ SSL_CTX_set_verify(self->ctx,
+ SSL_VERIFY_NONE, NULL); /* set verify lvl */
+ self->ssl = SSL_new(self->ctx); /* New ssl struct */
+ Py_END_ALLOW_THREADS
+ SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */
+
+ /* If the socket is in non-blocking mode or timeout mode, set the BIO
+ * to non-blocking mode (blocking is the default)
+ */
+ if (Sock->sock_timeout >= 0.0) {
+ /* Set both the read and write BIO's to non-blocking mode */
+ BIO_set_nbio(SSL_get_rbio(self->ssl), 1);
+ BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ SSL_set_connect_state(self->ssl);
+ Py_END_ALLOW_THREADS
+
+ /* Actually negotiate SSL connection */
+ /* XXX If SSL_connect() returns 0, it's also a failure. */
+ sockstate = 0;
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ ret = SSL_connect(self->ssl);
+ err = SSL_get_error(self->ssl, ret);
+ Py_END_ALLOW_THREADS
+ if(PyErr_CheckSignals()) {
+ goto fail;
+ }
+ if (err == SSL_ERROR_WANT_READ) {
+ sockstate = check_socket_and_wait_for_timeout(Sock, 0);
+ } else if (err == SSL_ERROR_WANT_WRITE) {
+ sockstate = check_socket_and_wait_for_timeout(Sock, 1);
+ } else {
+ sockstate = SOCKET_OPERATION_OK;
+ }
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The connect operation timed out");
+ goto fail;
+ } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+ PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+ goto fail;
+ } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+ PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+ goto fail;
+ } else if (sockstate == SOCKET_IS_NONBLOCKING) {
+ break;
+ }
+ } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+ if (ret <= 0) {
+ PySSL_SetError(self, ret);
+ goto fail;
+ }
+ self->ssl->debug = 1;
+
+ Py_BEGIN_ALLOW_THREADS
+ if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
+ X509_NAME_oneline(X509_get_subject_name(self->server_cert),
+ self->server, X509_NAME_MAXLEN);
+ X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
+ self->issuer, X509_NAME_MAXLEN);
+ }
+ Py_END_ALLOW_THREADS
+ self->Socket = Sock;
+ Py_INCREF(self->Socket);
+ return self;
+ fail:
+ if (errstr)
+ PyErr_SetString(PySSLErrorObject, errstr);
+ Py_DECREF(self);
+ return NULL;
+}
+
+static PyObject *
+PySocket_ssl(PyObject *self, PyObject *args)
+{
+ PySSLObject *rv;
+ PySocketSockObject *Sock;
+ char *key_file = NULL;
+ char *cert_file = NULL;
+
+ if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+ PySocketModule.Sock_Type,
+ (PyObject*)&Sock,
+ &key_file, &cert_file))
+ return NULL;
+
+ rv = newPySSLObject(Sock, key_file, cert_file);
+ if (rv == NULL)
+ return NULL;
+ return (PyObject *)rv;
+}
+
+PyDoc_STRVAR(ssl_doc,
+"ssl(socket, [keyfile, certfile]) -> sslobject");
+
+/* SSL object methods */
+
+static PyObject *
+PySSL_server(PySSLObject *self)
+{
+ return PyString_FromString(self->server);
+}
+
+static PyObject *
+PySSL_issuer(PySSLObject *self)
+{
+ return PyString_FromString(self->issuer);
+}
+
+
+static void PySSL_dealloc(PySSLObject *self)
+{
+ if (self->server_cert) /* Possible not to have one? */
+ X509_free (self->server_cert);
+ if (self->ssl)
+ SSL_free(self->ssl);
+ if (self->ctx)
+ SSL_CTX_free(self->ctx);
+ Py_XDECREF(self->Socket);
+ PyObject_Del(self);
+}
+
+/* If the socket has a timeout, do a select()/poll() on the socket.
+ The argument writing indicates the direction.
+ Returns one of the possibilities in the timeout_state enum (above).
+ */
+
+static int
+check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
+{
+ fd_set fds;
+ struct timeval tv;
+ int rc;
+
+ /* Nothing to do unless we're in timeout mode (not non-blocking) */
+ if (s->sock_timeout < 0.0)
+ return SOCKET_IS_BLOCKING;
+ else if (s->sock_timeout == 0.0)
+ return SOCKET_IS_NONBLOCKING;
+
+ /* Guard against closed socket */
+ if (s->sock_fd < 0)
+ return SOCKET_HAS_BEEN_CLOSED;
+
+ /* Prefer poll, if available, since you can poll() any fd
+ * which can't be done with select(). */
+#ifdef HAVE_POLL
+ {
+ struct pollfd pollfd;
+ int timeout;
+
+ pollfd.fd = s->sock_fd;
+ pollfd.events = writing ? POLLOUT : POLLIN;
+
+ /* s->sock_timeout is in seconds, timeout in ms */
+ timeout = (int)(s->sock_timeout * 1000 + 0.5);
+ Py_BEGIN_ALLOW_THREADS
+ rc = poll(&pollfd, 1, timeout);
+ Py_END_ALLOW_THREADS
+
+ goto normal_return;
+ }
+#endif
+
+ /* Guard against socket too large for select*/
+#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+ if (s->sock_fd >= FD_SETSIZE)
+ return SOCKET_TOO_LARGE_FOR_SELECT;
+#endif
+
+ /* Construct the arguments to select */
+ tv.tv_sec = (int)s->sock_timeout;
+ tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+ FD_ZERO(&fds);
+ FD_SET(s->sock_fd, &fds);
+
+ /* See if the socket is ready */
+ Py_BEGIN_ALLOW_THREADS
+ if (writing)
+ rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
+ else
+ rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+ Py_END_ALLOW_THREADS
+
+normal_return:
+ /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
+ (when we are able to write or when there's something to read) */
+ return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK;
+}
+
+static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
+{
+ char *data;
+ int len;
+ int count;
+ int sockstate;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "s#:write", &data, &count))
+ return NULL;
+
+ sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+ return NULL;
+ } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+ PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+ return NULL;
+ } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+ PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+ return NULL;
+ }
+ do {
+ err = 0;
+ Py_BEGIN_ALLOW_THREADS
+ len = SSL_write(self->ssl, data, count);
+ err = SSL_get_error(self->ssl, len);
+ Py_END_ALLOW_THREADS
+ if(PyErr_CheckSignals()) {
+ return NULL;
+ }
+ if (err == SSL_ERROR_WANT_READ) {
+ sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+ } else if (err == SSL_ERROR_WANT_WRITE) {
+ sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+ } else {
+ sockstate = SOCKET_OPERATION_OK;
+ }
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+ return NULL;
+ } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+ PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+ return NULL;
+ } else if (sockstate == SOCKET_IS_NONBLOCKING) {
+ break;
+ }
+ } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+ if (len > 0)
+ return PyInt_FromLong(len);
+ else
+ return PySSL_SetError(self, len);
+}
+
+PyDoc_STRVAR(PySSL_SSLwrite_doc,
+"write(s) -> len\n\
+\n\
+Writes the string s into the SSL object. Returns the number\n\
+of bytes written.");
+
+static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
+{
+ PyObject *buf;
+ int count = 0;
+ int len = 1024;
+ int sockstate;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "|i:read", &len))
+ return NULL;
+
+ if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
+ return NULL;
+
+ /* first check if there are bytes ready to be read */
+ Py_BEGIN_ALLOW_THREADS
+ count = SSL_pending(self->ssl);
+ Py_END_ALLOW_THREADS
+
+ if (!count) {
+ sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+ Py_DECREF(buf);
+ return NULL;
+ } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
+ PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+ return NULL;
+ }
+ }
+ do {
+ err = 0;
+ Py_BEGIN_ALLOW_THREADS
+ count = SSL_read(self->ssl, PyString_AsString(buf), len);
+ err = SSL_get_error(self->ssl, count);
+ Py_END_ALLOW_THREADS
+ if(PyErr_CheckSignals()) {
+ Py_DECREF(buf);
+ return NULL;
+ }
+ if (err == SSL_ERROR_WANT_READ) {
+ sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+ } else if (err == SSL_ERROR_WANT_WRITE) {
+ sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+ } else {
+ sockstate = SOCKET_OPERATION_OK;
+ }
+ if (sockstate == SOCKET_HAS_TIMED_OUT) {
+ PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+ Py_DECREF(buf);
+ return NULL;
+ } else if (sockstate == SOCKET_IS_NONBLOCKING) {
+ break;
+ }
+ } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+ if (count <= 0) {
+ Py_DECREF(buf);
+ return PySSL_SetError(self, count);
+ }
+ if (count != len)
+ _PyString_Resize(&buf, count);
+ return buf;
+}
+
+PyDoc_STRVAR(PySSL_SSLread_doc,
+"read([len]) -> string\n\
+\n\
+Read up to len bytes from the SSL socket.");
+
+static PyMethodDef PySSLMethods[] = {
+ {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
+ PySSL_SSLwrite_doc},
+ {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
+ PySSL_SSLread_doc},
+ {"server", (PyCFunction)PySSL_server, METH_NOARGS},
+ {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
+ {NULL, NULL}
+};
+
+static PyObject *PySSL_getattr(PySSLObject *self, char *name)
+{
+ return Py_FindMethod(PySSLMethods, (PyObject *)self, name);
+}
+
+static PyTypeObject PySSL_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "socket.SSL", /*tp_name*/
+ sizeof(PySSLObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PySSL_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)PySSL_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+#ifdef HAVE_OPENSSL_RAND
+
+/* helper routines for seeding the SSL PRNG */
+static PyObject *
+PySSL_RAND_add(PyObject *self, PyObject *args)
+{
+ char *buf;
+ int len;
+ double entropy;
+
+ if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))
+ return NULL;
+ RAND_add(buf, len, entropy);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(PySSL_RAND_add_doc,
+"RAND_add(string, entropy)\n\
+\n\
+Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\
+bound on the entropy contained in string.");
+
+static PyObject *
+PySSL_RAND_status(PyObject *self)
+{
+ return PyInt_FromLong(RAND_status());
+}
+
+PyDoc_STRVAR(PySSL_RAND_status_doc,
+"RAND_status() -> 0 or 1\n\
+\n\
+Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\
+It is necessary to seed the PRNG with RAND_add() on some platforms before\n\
+using the ssl() function.");
+
+static PyObject *
+PySSL_RAND_egd(PyObject *self, PyObject *arg)
+{
+ int bytes;
+
+ if (!PyString_Check(arg))
+ return PyErr_Format(PyExc_TypeError,
+ "RAND_egd() expected string, found %s",
+ arg->ob_type->tp_name);
+ bytes = RAND_egd(PyString_AS_STRING(arg));
+ if (bytes == -1) {
+ PyErr_SetString(PySSLErrorObject,
+ "EGD connection failed or EGD did not return "
+ "enough data to seed the PRNG");
+ return NULL;
+ }
+ return PyInt_FromLong(bytes);
+}
+
+PyDoc_STRVAR(PySSL_RAND_egd_doc,
+"RAND_egd(path) -> bytes\n\
+\n\
+Queries the entropy gather daemon (EGD) on socket path. Returns number\n\
+of bytes read. Raises socket.sslerror if connection to EGD fails or\n\
+if it does provide enough data to seed PRNG.");
+
+#endif
+
+/* List of functions exported by this module. */
+
+static PyMethodDef PySSL_methods[] = {
+ {"ssl", PySocket_ssl,
+ METH_VARARGS, ssl_doc},
+#ifdef HAVE_OPENSSL_RAND
+ {"RAND_add", PySSL_RAND_add, METH_VARARGS,
+ PySSL_RAND_add_doc},
+ {"RAND_egd", PySSL_RAND_egd, METH_O,
+ PySSL_RAND_egd_doc},
+ {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS,
+ PySSL_RAND_status_doc},
+#endif
+ {NULL, NULL} /* Sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"Implementation module for SSL socket operations. See the socket module\n\
+for documentation.");
+
+PyMODINIT_FUNC
+init_ssl(void)
+{
+ PyObject *m, *d;
+
+ PySSL_Type.ob_type = &PyType_Type;
+
+ m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ /* Load _socket module and its C API */
+ if (PySocketModule_ImportModuleAndAPI())
+ return;
+
+ /* Init OpenSSL */
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+
+ /* Add symbols to module dict */
+ PySSLErrorObject = PyErr_NewException("socket.sslerror",
+ PySocketModule.error,
+ NULL);
+ if (PySSLErrorObject == NULL)
+ return;
+ PyDict_SetItemString(d, "sslerror", PySSLErrorObject);
+ if (PyDict_SetItemString(d, "SSLType",
+ (PyObject *)&PySSL_Type) != 0)
+ return;
+ PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
+ PY_SSL_ERROR_ZERO_RETURN);
+ PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
+ PY_SSL_ERROR_WANT_READ);
+ PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
+ PY_SSL_ERROR_WANT_WRITE);
+ PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
+ PY_SSL_ERROR_WANT_X509_LOOKUP);
+ PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
+ PY_SSL_ERROR_SYSCALL);
+ PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
+ PY_SSL_ERROR_SSL);
+ PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
+ PY_SSL_ERROR_WANT_CONNECT);
+ /* non ssl.h errorcodes */
+ PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
+ PY_SSL_ERROR_EOF);
+ PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
+ PY_SSL_ERROR_INVALID_ERROR_CODE);
+
+}
diff --git a/sys/src/cmd/python/Modules/_struct.c b/sys/src/cmd/python/Modules/_struct.c
new file mode 100644
index 000000000..53c64848b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_struct.c
@@ -0,0 +1,1896 @@
+/* struct module -- pack values into and (out of) strings */
+
+/* New version supporting byte order, alignment and size options,
+ character strings, and unsigned numbers */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structseq.h"
+#include "structmember.h"
+#include <ctype.h>
+
+static PyTypeObject PyStructType;
+
+/* compatibility macros */
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
+ numbers for explicit endians such that they fit in the given type, much
+ like explicit casting in C. A warning will be raised if the number did
+ not originally fit within the range of the requested type. If it is
+ not defined, then all range errors and overflow will be struct.error
+ exceptions. */
+
+#define PY_STRUCT_OVERFLOW_MASKING 1
+
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+static PyObject *pylong_ulong_mask = NULL;
+static PyObject *pyint_zero = NULL;
+#endif
+
+/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
+ arguments for integer formats with a warning for backwards
+ compatibility. */
+
+#define PY_STRUCT_FLOAT_COERCE 1
+
+#ifdef PY_STRUCT_FLOAT_COERCE
+#define FLOAT_COERCE "integer argument expected, got float"
+#endif
+
+
+/* The translation function for each format character is table driven */
+typedef struct _formatdef {
+ char format;
+ Py_ssize_t size;
+ Py_ssize_t alignment;
+ PyObject* (*unpack)(const char *,
+ const struct _formatdef *);
+ int (*pack)(char *, PyObject *,
+ const struct _formatdef *);
+} formatdef;
+
+typedef struct _formatcode {
+ const struct _formatdef *fmtdef;
+ Py_ssize_t offset;
+ Py_ssize_t size;
+} formatcode;
+
+/* Struct object interface */
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t s_size;
+ Py_ssize_t s_len;
+ formatcode *s_codes;
+ PyObject *s_format;
+ PyObject *weakreflist; /* List of weak references */
+} PyStructObject;
+
+
+#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
+#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
+
+
+/* Exception */
+
+static PyObject *StructError;
+
+
+/* Define various structs to figure out the alignments of types */
+
+
+typedef struct { char c; short x; } st_short;
+typedef struct { char c; int x; } st_int;
+typedef struct { char c; long x; } st_long;
+typedef struct { char c; float x; } st_float;
+typedef struct { char c; double x; } st_double;
+typedef struct { char c; void *x; } st_void_p;
+
+#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
+#define INT_ALIGN (sizeof(st_int) - sizeof(int))
+#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
+#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
+#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
+#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
+
+/* We can't support q and Q in native mode unless the compiler does;
+ in std mode, they're 8 bytes on all platforms. */
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } s_long_long;
+#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
+#endif
+
+#define STRINGIFY(x) #x
+
+#ifdef __powerc
+#pragma options align=reset
+#endif
+
+/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
+
+static PyObject *
+get_pylong(PyObject *v)
+{
+ PyNumberMethods *m;
+
+ assert(v != NULL);
+ if (PyInt_Check(v))
+ return PyLong_FromLong(PyInt_AS_LONG(v));
+ if (PyLong_Check(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+ m = v->ob_type->tp_as_number;
+ if (m != NULL && m->nb_long != NULL) {
+ v = m->nb_long(v);
+ if (v == NULL)
+ return NULL;
+ if (PyLong_Check(v))
+ return v;
+ Py_DECREF(v);
+ }
+ PyErr_SetString(StructError,
+ "cannot convert argument to long");
+ return NULL;
+}
+
+/* Helper routine to get a Python integer and raise the appropriate error
+ if it isn't one */
+
+static int
+get_long(PyObject *v, long *p)
+{
+ long x = PyInt_AsLong(v);
+ if (x == -1 && PyErr_Occurred()) {
+#ifdef PY_STRUCT_FLOAT_COERCE
+ if (PyFloat_Check(v)) {
+ PyObject *o;
+ int res;
+ PyErr_Clear();
+ if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
+ return -1;
+ o = PyNumber_Int(v);
+ if (o == NULL)
+ return -1;
+ res = get_long(o, p);
+ Py_DECREF(o);
+ return res;
+ }
+#endif
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_SetString(StructError,
+ "required argument is not an integer");
+ return -1;
+ }
+ *p = x;
+ return 0;
+}
+
+
+/* Same, but handling unsigned long */
+
+static int
+get_ulong(PyObject *v, unsigned long *p)
+{
+ if (PyLong_Check(v)) {
+ unsigned long x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long)(-1) && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+ }
+ if (get_long(v, (long *)p) < 0)
+ return -1;
+ if (((long)*p) < 0) {
+ PyErr_SetString(StructError,
+ "unsigned argument is < 0");
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Same, but handling native long long. */
+
+static int
+get_longlong(PyObject *v, PY_LONG_LONG *p)
+{
+ PY_LONG_LONG x;
+
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ assert(PyLong_Check(v));
+ x = PyLong_AsLongLong(v);
+ Py_DECREF(v);
+ if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+}
+
+/* Same, but handling native unsigned long long. */
+
+static int
+get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
+{
+ unsigned PY_LONG_LONG x;
+
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ assert(PyLong_Check(v));
+ x = PyLong_AsUnsignedLongLong(v);
+ Py_DECREF(v);
+ if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ return 0;
+}
+
+#endif
+
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+
+/* Helper routine to get a Python integer and raise the appropriate error
+ if it isn't one */
+
+#define INT_OVERFLOW "struct integer overflow masking is deprecated"
+
+static int
+get_wrapped_long(PyObject *v, long *p)
+{
+ if (get_long(v, p) < 0) {
+ if (PyLong_Check(v) &&
+ PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ PyObject *wrapped;
+ long x;
+ PyErr_Clear();
+#ifdef PY_STRUCT_FLOAT_COERCE
+ if (PyFloat_Check(v)) {
+ PyObject *o;
+ int res;
+ PyErr_Clear();
+ if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
+ return -1;
+ o = PyNumber_Int(v);
+ if (o == NULL)
+ return -1;
+ res = get_wrapped_long(o, p);
+ Py_DECREF(o);
+ return res;
+ }
+#endif
+ if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
+ return -1;
+ wrapped = PyNumber_And(v, pylong_ulong_mask);
+ if (wrapped == NULL)
+ return -1;
+ x = (long)PyLong_AsUnsignedLong(wrapped);
+ Py_DECREF(wrapped);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ *p = x;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+get_wrapped_ulong(PyObject *v, unsigned long *p)
+{
+ long x = (long)PyLong_AsUnsignedLong(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyObject *wrapped;
+ PyErr_Clear();
+#ifdef PY_STRUCT_FLOAT_COERCE
+ if (PyFloat_Check(v)) {
+ PyObject *o;
+ int res;
+ PyErr_Clear();
+ if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
+ return -1;
+ o = PyNumber_Int(v);
+ if (o == NULL)
+ return -1;
+ res = get_wrapped_ulong(o, p);
+ Py_DECREF(o);
+ return res;
+ }
+#endif
+ wrapped = PyNumber_And(v, pylong_ulong_mask);
+ if (wrapped == NULL)
+ return -1;
+ if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
+ Py_DECREF(wrapped);
+ return -1;
+ }
+ x = (long)PyLong_AsUnsignedLong(wrapped);
+ Py_DECREF(wrapped);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ }
+ *p = (unsigned long)x;
+ return 0;
+}
+
+#define RANGE_ERROR(x, f, flag, mask) \
+ do { \
+ if (_range_error(f, flag) < 0) \
+ return -1; \
+ else \
+ (x) &= (mask); \
+ } while (0)
+
+#else
+
+#define get_wrapped_long get_long
+#define get_wrapped_ulong get_ulong
+#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
+
+#endif
+
+/* Floating point helpers */
+
+static PyObject *
+unpack_float(const char *p, /* start of 4-byte string */
+ int le) /* true for little-endian, false for big-endian */
+{
+ double x;
+
+ x = _PyFloat_Unpack4((unsigned char *)p, le);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyFloat_FromDouble(x);
+}
+
+static PyObject *
+unpack_double(const char *p, /* start of 8-byte string */
+ int le) /* true for little-endian, false for big-endian */
+{
+ double x;
+
+ x = _PyFloat_Unpack8((unsigned char *)p, le);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyFloat_FromDouble(x);
+}
+
+/* Helper to format the range error exceptions */
+static int
+_range_error(const formatdef *f, int is_unsigned)
+{
+ /* ulargest is the largest unsigned value with f->size bytes.
+ * Note that the simpler:
+ * ((size_t)1 << (f->size * 8)) - 1
+ * doesn't work when f->size == sizeof(size_t) because C doesn't
+ * define what happens when a left shift count is >= the number of
+ * bits in the integer being shifted; e.g., on some boxes it doesn't
+ * shift at all when they're equal.
+ */
+ const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
+ assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
+ if (is_unsigned)
+ PyErr_Format(StructError,
+ "'%c' format requires 0 <= number <= %zu",
+ f->format,
+ ulargest);
+ else {
+ const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
+ PyErr_Format(StructError,
+ "'%c' format requires %zd <= number <= %zd",
+ f->format,
+ ~ largest,
+ largest);
+ }
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ {
+ PyObject *ptype, *pvalue, *ptraceback;
+ PyObject *msg;
+ int rval;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ assert(pvalue != NULL);
+ msg = PyObject_Str(pvalue);
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ if (msg == NULL)
+ return -1;
+ rval = PyErr_WarnEx(PyExc_DeprecationWarning,
+ PyString_AS_STRING(msg), 2);
+ Py_DECREF(msg);
+ if (rval == 0)
+ return 0;
+ }
+#endif
+ return -1;
+}
+
+
+
+/* A large number of small routines follow, with names of the form
+
+ [bln][up]_TYPE
+
+ [bln] distiguishes among big-endian, little-endian and native.
+ [pu] distiguishes between pack (to struct) and unpack (from struct).
+ TYPE is one of char, byte, ubyte, etc.
+*/
+
+/* Native mode routines. ****************************************************/
+/* NOTE:
+ In all n[up]_<type> routines handling types larger than 1 byte, there is
+ *no* guarantee that the p pointer is properly aligned for each type,
+ therefore memcpy is called. An intermediate variable is used to
+ compensate for big-endian architectures.
+ Normally both the intermediate variable and the memcpy call will be
+ skipped by C optimisation in little-endian architectures (gcc >= 2.91
+ does this). */
+
+static PyObject *
+nu_char(const char *p, const formatdef *f)
+{
+ return PyString_FromStringAndSize(p, 1);
+}
+
+static PyObject *
+nu_byte(const char *p, const formatdef *f)
+{
+ return PyInt_FromLong((long) *(signed char *)p);
+}
+
+static PyObject *
+nu_ubyte(const char *p, const formatdef *f)
+{
+ return PyInt_FromLong((long) *(unsigned char *)p);
+}
+
+static PyObject *
+nu_short(const char *p, const formatdef *f)
+{
+ short x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyInt_FromLong((long)x);
+}
+
+static PyObject *
+nu_ushort(const char *p, const formatdef *f)
+{
+ unsigned short x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyInt_FromLong((long)x);
+}
+
+static PyObject *
+nu_int(const char *p, const formatdef *f)
+{
+ int x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyInt_FromLong((long)x);
+}
+
+static PyObject *
+nu_uint(const char *p, const formatdef *f)
+{
+ unsigned int x;
+ memcpy((char *)&x, p, sizeof x);
+#if (SIZEOF_LONG > SIZEOF_INT)
+ return PyInt_FromLong((long)x);
+#else
+ if (x <= ((unsigned int)LONG_MAX))
+ return PyInt_FromLong((long)x);
+ return PyLong_FromUnsignedLong((unsigned long)x);
+#endif
+}
+
+static PyObject *
+nu_long(const char *p, const formatdef *f)
+{
+ long x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyInt_FromLong(x);
+}
+
+static PyObject *
+nu_ulong(const char *p, const formatdef *f)
+{
+ unsigned long x;
+ memcpy((char *)&x, p, sizeof x);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong((long)x);
+ return PyLong_FromUnsignedLong(x);
+}
+
+/* Native mode doesn't support q or Q unless the platform C supports
+ long long (or, on Windows, __int64). */
+
+#ifdef HAVE_LONG_LONG
+
+static PyObject *
+nu_longlong(const char *p, const formatdef *f)
+{
+ PY_LONG_LONG x;
+ memcpy((char *)&x, p, sizeof x);
+ if (x >= LONG_MIN && x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+ return PyLong_FromLongLong(x);
+}
+
+static PyObject *
+nu_ulonglong(const char *p, const formatdef *f)
+{
+ unsigned PY_LONG_LONG x;
+ memcpy((char *)&x, p, sizeof x);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+ return PyLong_FromUnsignedLongLong(x);
+}
+
+#endif
+
+static PyObject *
+nu_float(const char *p, const formatdef *f)
+{
+ float x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyFloat_FromDouble((double)x);
+}
+
+static PyObject *
+nu_double(const char *p, const formatdef *f)
+{
+ double x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyFloat_FromDouble(x);
+}
+
+static PyObject *
+nu_void_p(const char *p, const formatdef *f)
+{
+ void *x;
+ memcpy((char *)&x, p, sizeof x);
+ return PyLong_FromVoidPtr(x);
+}
+
+static int
+np_byte(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ if (get_long(v, &x) < 0)
+ return -1;
+ if (x < -128 || x > 127){
+ PyErr_SetString(StructError,
+ "byte format requires -128 <= number <= 127");
+ return -1;
+ }
+ *p = (char)x;
+ return 0;
+}
+
+static int
+np_ubyte(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ if (get_long(v, &x) < 0)
+ return -1;
+ if (x < 0 || x > 255){
+ PyErr_SetString(StructError,
+ "ubyte format requires 0 <= number <= 255");
+ return -1;
+ }
+ *p = (char)x;
+ return 0;
+}
+
+static int
+np_char(char *p, PyObject *v, const formatdef *f)
+{
+ if (!PyString_Check(v) || PyString_Size(v) != 1) {
+ PyErr_SetString(StructError,
+ "char format require string of length 1");
+ return -1;
+ }
+ *p = *PyString_AsString(v);
+ return 0;
+}
+
+static int
+np_short(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ short y;
+ if (get_long(v, &x) < 0)
+ return -1;
+ if (x < SHRT_MIN || x > SHRT_MAX){
+ PyErr_SetString(StructError,
+ "short format requires " STRINGIFY(SHRT_MIN)
+ " <= number <= " STRINGIFY(SHRT_MAX));
+ return -1;
+ }
+ y = (short)x;
+ memcpy(p, (char *)&y, sizeof y);
+ return 0;
+}
+
+static int
+np_ushort(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ unsigned short y;
+ if (get_long(v, &x) < 0)
+ return -1;
+ if (x < 0 || x > USHRT_MAX){
+ PyErr_SetString(StructError,
+ "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
+ return -1;
+ }
+ y = (unsigned short)x;
+ memcpy(p, (char *)&y, sizeof y);
+ return 0;
+}
+
+static int
+np_int(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ int y;
+ if (get_long(v, &x) < 0)
+ return -1;
+#if (SIZEOF_LONG > SIZEOF_INT)
+ if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
+ return _range_error(f, 0);
+#endif
+ y = (int)x;
+ memcpy(p, (char *)&y, sizeof y);
+ return 0;
+}
+
+static int
+np_uint(char *p, PyObject *v, const formatdef *f)
+{
+ unsigned long x;
+ unsigned int y;
+ if (get_ulong(v, &x) < 0)
+ return _range_error(f, 1);
+ y = (unsigned int)x;
+#if (SIZEOF_LONG > SIZEOF_INT)
+ if (x > ((unsigned long)UINT_MAX))
+ return _range_error(f, 1);
+#endif
+ memcpy(p, (char *)&y, sizeof y);
+ return 0;
+}
+
+static int
+np_long(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ if (get_long(v, &x) < 0)
+ return -1;
+ memcpy(p, (char *)&x, sizeof x);
+ return 0;
+}
+
+static int
+np_ulong(char *p, PyObject *v, const formatdef *f)
+{
+ unsigned long x;
+ if (get_ulong(v, &x) < 0)
+ return _range_error(f, 1);
+ memcpy(p, (char *)&x, sizeof x);
+ return 0;
+}
+
+#ifdef HAVE_LONG_LONG
+
+static int
+np_longlong(char *p, PyObject *v, const formatdef *f)
+{
+ PY_LONG_LONG x;
+ if (get_longlong(v, &x) < 0)
+ return -1;
+ memcpy(p, (char *)&x, sizeof x);
+ return 0;
+}
+
+static int
+np_ulonglong(char *p, PyObject *v, const formatdef *f)
+{
+ unsigned PY_LONG_LONG x;
+ if (get_ulonglong(v, &x) < 0)
+ return -1;
+ memcpy(p, (char *)&x, sizeof x);
+ return 0;
+}
+#endif
+
+static int
+np_float(char *p, PyObject *v, const formatdef *f)
+{
+ float x = (float)PyFloat_AsDouble(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_SetString(StructError,
+ "required argument is not a float");
+ return -1;
+ }
+ memcpy(p, (char *)&x, sizeof x);
+ return 0;
+}
+
+static int
+np_double(char *p, PyObject *v, const formatdef *f)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_SetString(StructError,
+ "required argument is not a float");
+ return -1;
+ }
+ memcpy(p, (char *)&x, sizeof(double));
+ return 0;
+}
+
+static int
+np_void_p(char *p, PyObject *v, const formatdef *f)
+{
+ void *x;
+
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ assert(PyLong_Check(v));
+ x = PyLong_AsVoidPtr(v);
+ Py_DECREF(v);
+ if (x == NULL && PyErr_Occurred())
+ return -1;
+ memcpy(p, (char *)&x, sizeof x);
+ return 0;
+}
+
+static formatdef native_table[] = {
+ {'x', sizeof(char), 0, NULL},
+ {'b', sizeof(char), 0, nu_byte, np_byte},
+ {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
+ {'c', sizeof(char), 0, nu_char, np_char},
+ {'s', sizeof(char), 0, NULL},
+ {'p', sizeof(char), 0, NULL},
+ {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
+ {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
+ {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
+ {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
+ {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
+ {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
+#ifdef HAVE_LONG_LONG
+ {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
+ {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
+#endif
+ {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
+ {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
+ {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
+ {0}
+};
+
+/* Big-endian routines. *****************************************************/
+
+static PyObject *
+bu_int(const char *p, const formatdef *f)
+{
+ long x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | *bytes++;
+ } while (--i > 0);
+ /* Extend the sign bit. */
+ if (SIZEOF_LONG > f->size)
+ x |= -(x & (1L << ((8 * f->size) - 1)));
+ return PyInt_FromLong(x);
+}
+
+static PyObject *
+bu_uint(const char *p, const formatdef *f)
+{
+ unsigned long x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | *bytes++;
+ } while (--i > 0);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong((long)x);
+ return PyLong_FromUnsignedLong(x);
+}
+
+static PyObject *
+bu_longlong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | *bytes++;
+ } while (--i > 0);
+ /* Extend the sign bit. */
+ if (SIZEOF_LONG_LONG > f->size)
+ x |= -(x & ( (PY_LONG_LONG)1 << ((8 * f->size) - 1)));
+ if (x >= LONG_MIN && x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+ return PyLong_FromLongLong(x);
+#else
+ return _PyLong_FromByteArray((const unsigned char *)p,
+ 8,
+ 0, /* little-endian */
+ 1 /* signed */);
+#endif
+}
+
+static PyObject *
+bu_ulonglong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+ unsigned PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | *bytes++;
+ } while (--i > 0);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+ return PyLong_FromUnsignedLongLong(x);
+#else
+ return _PyLong_FromByteArray((const unsigned char *)p,
+ 8,
+ 0, /* little-endian */
+ 0 /* signed */);
+#endif
+}
+
+static PyObject *
+bu_float(const char *p, const formatdef *f)
+{
+ return unpack_float(p, 0);
+}
+
+static PyObject *
+bu_double(const char *p, const formatdef *f)
+{
+ return unpack_double(p, 0);
+}
+
+static int
+bp_int(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ Py_ssize_t i;
+ if (get_wrapped_long(v, &x) < 0)
+ return -1;
+ i = f->size;
+ if (i != SIZEOF_LONG) {
+ if ((i == 2) && (x < -32768 || x > 32767))
+ RANGE_ERROR(x, f, 0, 0xffffL);
+#if (SIZEOF_LONG != 4)
+ else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
+ RANGE_ERROR(x, f, 0, 0xffffffffL);
+#endif
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ else if ((i == 1) && (x < -128 || x > 127))
+ RANGE_ERROR(x, f, 0, 0xffL);
+#endif
+ }
+ do {
+ p[--i] = (char)x;
+ x >>= 8;
+ } while (i > 0);
+ return 0;
+}
+
+static int
+bp_uint(char *p, PyObject *v, const formatdef *f)
+{
+ unsigned long x;
+ Py_ssize_t i;
+ if (get_wrapped_ulong(v, &x) < 0)
+ return -1;
+ i = f->size;
+ if (i != SIZEOF_LONG) {
+ unsigned long maxint = 1;
+ maxint <<= (unsigned long)(i * 8);
+ if (x >= maxint)
+ RANGE_ERROR(x, f, 1, maxint - 1);
+ }
+ do {
+ p[--i] = (char)x;
+ x >>= 8;
+ } while (i > 0);
+ return 0;
+}
+
+static int
+bp_longlong(char *p, PyObject *v, const formatdef *f)
+{
+ int res;
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ res = _PyLong_AsByteArray((PyLongObject *)v,
+ (unsigned char *)p,
+ 8,
+ 0, /* little_endian */
+ 1 /* signed */);
+ Py_DECREF(v);
+ return res;
+}
+
+static int
+bp_ulonglong(char *p, PyObject *v, const formatdef *f)
+{
+ int res;
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ res = _PyLong_AsByteArray((PyLongObject *)v,
+ (unsigned char *)p,
+ 8,
+ 0, /* little_endian */
+ 0 /* signed */);
+ Py_DECREF(v);
+ return res;
+}
+
+static int
+bp_float(char *p, PyObject *v, const formatdef *f)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_SetString(StructError,
+ "required argument is not a float");
+ return -1;
+ }
+ return _PyFloat_Pack4(x, (unsigned char *)p, 0);
+}
+
+static int
+bp_double(char *p, PyObject *v, const formatdef *f)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_SetString(StructError,
+ "required argument is not a float");
+ return -1;
+ }
+ return _PyFloat_Pack8(x, (unsigned char *)p, 0);
+}
+
+static formatdef bigendian_table[] = {
+ {'x', 1, 0, NULL},
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ /* Native packers do range checking without overflow masking. */
+ {'b', 1, 0, nu_byte, bp_int},
+ {'B', 1, 0, nu_ubyte, bp_uint},
+#else
+ {'b', 1, 0, nu_byte, np_byte},
+ {'B', 1, 0, nu_ubyte, np_ubyte},
+#endif
+ {'c', 1, 0, nu_char, np_char},
+ {'s', 1, 0, NULL},
+ {'p', 1, 0, NULL},
+ {'h', 2, 0, bu_int, bp_int},
+ {'H', 2, 0, bu_uint, bp_uint},
+ {'i', 4, 0, bu_int, bp_int},
+ {'I', 4, 0, bu_uint, bp_uint},
+ {'l', 4, 0, bu_int, bp_int},
+ {'L', 4, 0, bu_uint, bp_uint},
+ {'q', 8, 0, bu_longlong, bp_longlong},
+ {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
+ {'f', 4, 0, bu_float, bp_float},
+ {'d', 8, 0, bu_double, bp_double},
+ {0}
+};
+
+/* Little-endian routines. *****************************************************/
+
+static PyObject *
+lu_int(const char *p, const formatdef *f)
+{
+ long x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | bytes[--i];
+ } while (i > 0);
+ /* Extend the sign bit. */
+ if (SIZEOF_LONG > f->size)
+ x |= -(x & (1L << ((8 * f->size) - 1)));
+ return PyInt_FromLong(x);
+}
+
+static PyObject *
+lu_uint(const char *p, const formatdef *f)
+{
+ unsigned long x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | bytes[--i];
+ } while (i > 0);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong((long)x);
+ return PyLong_FromUnsignedLong((long)x);
+}
+
+static PyObject *
+lu_longlong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | bytes[--i];
+ } while (i > 0);
+ /* Extend the sign bit. */
+ if (SIZEOF_LONG_LONG > f->size)
+ x |= -(x & ( (PY_LONG_LONG)1 << ((8 * f->size) - 1)));
+ if (x >= LONG_MIN && x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+ return PyLong_FromLongLong(x);
+#else
+ return _PyLong_FromByteArray((const unsigned char *)p,
+ 8,
+ 1, /* little-endian */
+ 1 /* signed */);
+#endif
+}
+
+static PyObject *
+lu_ulonglong(const char *p, const formatdef *f)
+{
+#ifdef HAVE_LONG_LONG
+ unsigned PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ const unsigned char *bytes = (const unsigned char *)p;
+ do {
+ x = (x<<8) | bytes[--i];
+ } while (i > 0);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+ return PyLong_FromUnsignedLongLong(x);
+#else
+ return _PyLong_FromByteArray((const unsigned char *)p,
+ 8,
+ 1, /* little-endian */
+ 0 /* signed */);
+#endif
+}
+
+static PyObject *
+lu_float(const char *p, const formatdef *f)
+{
+ return unpack_float(p, 1);
+}
+
+static PyObject *
+lu_double(const char *p, const formatdef *f)
+{
+ return unpack_double(p, 1);
+}
+
+static int
+lp_int(char *p, PyObject *v, const formatdef *f)
+{
+ long x;
+ Py_ssize_t i;
+ if (get_wrapped_long(v, &x) < 0)
+ return -1;
+ i = f->size;
+ if (i != SIZEOF_LONG) {
+ if ((i == 2) && (x < -32768 || x > 32767))
+ RANGE_ERROR(x, f, 0, 0xffffL);
+#if (SIZEOF_LONG != 4)
+ else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
+ RANGE_ERROR(x, f, 0, 0xffffffffL);
+#endif
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ else if ((i == 1) && (x < -128 || x > 127))
+ RANGE_ERROR(x, f, 0, 0xffL);
+#endif
+ }
+ do {
+ *p++ = (char)x;
+ x >>= 8;
+ } while (--i > 0);
+ return 0;
+}
+
+static int
+lp_uint(char *p, PyObject *v, const formatdef *f)
+{
+ unsigned long x;
+ Py_ssize_t i;
+ if (get_wrapped_ulong(v, &x) < 0)
+ return -1;
+ i = f->size;
+ if (i != SIZEOF_LONG) {
+ unsigned long maxint = 1;
+ maxint <<= (unsigned long)(i * 8);
+ if (x >= maxint)
+ RANGE_ERROR(x, f, 1, maxint - 1);
+ }
+ do {
+ *p++ = (char)x;
+ x >>= 8;
+ } while (--i > 0);
+ return 0;
+}
+
+static int
+lp_longlong(char *p, PyObject *v, const formatdef *f)
+{
+ int res;
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ res = _PyLong_AsByteArray((PyLongObject*)v,
+ (unsigned char *)p,
+ 8,
+ 1, /* little_endian */
+ 1 /* signed */);
+ Py_DECREF(v);
+ return res;
+}
+
+static int
+lp_ulonglong(char *p, PyObject *v, const formatdef *f)
+{
+ int res;
+ v = get_pylong(v);
+ if (v == NULL)
+ return -1;
+ res = _PyLong_AsByteArray((PyLongObject*)v,
+ (unsigned char *)p,
+ 8,
+ 1, /* little_endian */
+ 0 /* signed */);
+ Py_DECREF(v);
+ return res;
+}
+
+static int
+lp_float(char *p, PyObject *v, const formatdef *f)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_SetString(StructError,
+ "required argument is not a float");
+ return -1;
+ }
+ return _PyFloat_Pack4(x, (unsigned char *)p, 1);
+}
+
+static int
+lp_double(char *p, PyObject *v, const formatdef *f)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_SetString(StructError,
+ "required argument is not a float");
+ return -1;
+ }
+ return _PyFloat_Pack8(x, (unsigned char *)p, 1);
+}
+
+static formatdef lilendian_table[] = {
+ {'x', 1, 0, NULL},
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ /* Native packers do range checking without overflow masking. */
+ {'b', 1, 0, nu_byte, lp_int},
+ {'B', 1, 0, nu_ubyte, lp_uint},
+#else
+ {'b', 1, 0, nu_byte, np_byte},
+ {'B', 1, 0, nu_ubyte, np_ubyte},
+#endif
+ {'c', 1, 0, nu_char, np_char},
+ {'s', 1, 0, NULL},
+ {'p', 1, 0, NULL},
+ {'h', 2, 0, lu_int, lp_int},
+ {'H', 2, 0, lu_uint, lp_uint},
+ {'i', 4, 0, lu_int, lp_int},
+ {'I', 4, 0, lu_uint, lp_uint},
+ {'l', 4, 0, lu_int, lp_int},
+ {'L', 4, 0, lu_uint, lp_uint},
+ {'q', 8, 0, lu_longlong, lp_longlong},
+ {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
+ {'f', 4, 0, lu_float, lp_float},
+ {'d', 8, 0, lu_double, lp_double},
+ {0}
+};
+
+
+static const formatdef *
+whichtable(char **pfmt)
+{
+ const char *fmt = (*pfmt)++; /* May be backed out of later */
+ switch (*fmt) {
+ case '<':
+ return lilendian_table;
+ case '>':
+ case '!': /* Network byte order is big-endian */
+ return bigendian_table;
+ case '=': { /* Host byte order -- different from native in aligment! */
+ int n = 1;
+ char *p = (char *) &n;
+ if (*p == 1)
+ return lilendian_table;
+ else
+ return bigendian_table;
+ }
+ default:
+ --*pfmt; /* Back out of pointer increment */
+ /* Fall through */
+ case '@':
+ return native_table;
+ }
+}
+
+
+/* Get the table entry for a format code */
+
+static const formatdef *
+getentry(int c, const formatdef *f)
+{
+ for (; f->format != '\0'; f++) {
+ if (f->format == c) {
+ return f;
+ }
+ }
+ PyErr_SetString(StructError, "bad char in struct format");
+ return NULL;
+}
+
+
+/* Align a size according to a format code */
+
+static int
+align(Py_ssize_t size, char c, const formatdef *e)
+{
+ if (e->format == c) {
+ if (e->alignment) {
+ size = ((size + e->alignment - 1)
+ / e->alignment)
+ * e->alignment;
+ }
+ }
+ return size;
+}
+
+
+/* calculate the size of a format string */
+
+static int
+prepare_s(PyStructObject *self)
+{
+ const formatdef *f;
+ const formatdef *e;
+ formatcode *codes;
+
+ const char *s;
+ const char *fmt;
+ char c;
+ Py_ssize_t size, len, num, itemsize, x;
+
+ fmt = PyString_AS_STRING(self->s_format);
+
+ f = whichtable((char **)&fmt);
+
+ s = fmt;
+ size = 0;
+ len = 0;
+ while ((c = *s++) != '\0') {
+ if (isspace(Py_CHARMASK(c)))
+ continue;
+ if ('0' <= c && c <= '9') {
+ num = c - '0';
+ while ('0' <= (c = *s++) && c <= '9') {
+ x = num*10 + (c - '0');
+ if (x/10 != num) {
+ PyErr_SetString(
+ StructError,
+ "overflow in item count");
+ return -1;
+ }
+ num = x;
+ }
+ if (c == '\0')
+ break;
+ }
+ else
+ num = 1;
+
+ e = getentry(c, f);
+ if (e == NULL)
+ return -1;
+
+ switch (c) {
+ case 's': /* fall through */
+ case 'p': len++; break;
+ case 'x': break;
+ default: len += num; break;
+ }
+
+ itemsize = e->size;
+ size = align(size, c, e);
+ x = num * itemsize;
+ size += x;
+ if (x/itemsize != num || size < 0) {
+ PyErr_SetString(StructError,
+ "total struct size too long");
+ return -1;
+ }
+ }
+
+ self->s_size = size;
+ self->s_len = len;
+ codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
+ if (codes == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->s_codes = codes;
+
+ s = fmt;
+ size = 0;
+ while ((c = *s++) != '\0') {
+ if (isspace(Py_CHARMASK(c)))
+ continue;
+ if ('0' <= c && c <= '9') {
+ num = c - '0';
+ while ('0' <= (c = *s++) && c <= '9')
+ num = num*10 + (c - '0');
+ if (c == '\0')
+ break;
+ }
+ else
+ num = 1;
+
+ e = getentry(c, f);
+
+ size = align(size, c, e);
+ if (c == 's' || c == 'p') {
+ codes->offset = size;
+ codes->size = num;
+ codes->fmtdef = e;
+ codes++;
+ size += num;
+ } else if (c == 'x') {
+ size += num;
+ } else {
+ while (--num >= 0) {
+ codes->offset = size;
+ codes->size = e->size;
+ codes->fmtdef = e;
+ codes++;
+ size += e->size;
+ }
+ }
+ }
+ codes->fmtdef = NULL;
+ codes->offset = size;
+ codes->size = 0;
+
+ return 0;
+}
+
+static PyObject *
+s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ assert(type != NULL && type->tp_alloc != NULL);
+
+ self = type->tp_alloc(type, 0);
+ if (self != NULL) {
+ PyStructObject *s = (PyStructObject*)self;
+ Py_INCREF(Py_None);
+ s->s_format = Py_None;
+ s->s_codes = NULL;
+ s->s_size = -1;
+ s->s_len = -1;
+ }
+ return self;
+}
+
+static int
+s_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyStructObject *soself = (PyStructObject *)self;
+ PyObject *o_format = NULL;
+ int ret = 0;
+ static char *kwlist[] = {"format", 0};
+
+ assert(PyStruct_Check(self));
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
+ &o_format))
+ return -1;
+
+ Py_INCREF(o_format);
+ Py_XDECREF(soself->s_format);
+ soself->s_format = o_format;
+
+ ret = prepare_s(soself);
+ return ret;
+}
+
+static void
+s_dealloc(PyStructObject *s)
+{
+ if (s->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *)s);
+ if (s->s_codes != NULL) {
+ PyMem_FREE(s->s_codes);
+ }
+ Py_XDECREF(s->s_format);
+ s->ob_type->tp_free((PyObject *)s);
+}
+
+static PyObject *
+s_unpack_internal(PyStructObject *soself, char *startfrom) {
+ formatcode *code;
+ Py_ssize_t i = 0;
+ PyObject *result = PyTuple_New(soself->s_len);
+ if (result == NULL)
+ return NULL;
+
+ for (code = soself->s_codes; code->fmtdef != NULL; code++) {
+ PyObject *v;
+ const formatdef *e = code->fmtdef;
+ const char *res = startfrom + code->offset;
+ if (e->format == 's') {
+ v = PyString_FromStringAndSize(res, code->size);
+ } else if (e->format == 'p') {
+ Py_ssize_t n = *(unsigned char*)res;
+ if (n >= code->size)
+ n = code->size - 1;
+ v = PyString_FromStringAndSize(res + 1, n);
+ } else {
+ v = e->unpack(res, e);
+ }
+ if (v == NULL)
+ goto fail;
+ PyTuple_SET_ITEM(result, i++, v);
+ }
+
+ return result;
+fail:
+ Py_DECREF(result);
+ return NULL;
+}
+
+
+PyDoc_STRVAR(s_unpack__doc__,
+"S.unpack(str) -> (v1, v2, ...)\n\
+\n\
+Return tuple containing values unpacked according to this Struct's format.\n\
+Requires len(str) == self.size. See struct.__doc__ for more on format\n\
+strings.");
+
+static PyObject *
+s_unpack(PyObject *self, PyObject *inputstr)
+{
+ char *start;
+ Py_ssize_t len;
+ PyObject *args=NULL, *result;
+ PyStructObject *soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+ if (inputstr == NULL)
+ goto fail;
+ if (PyString_Check(inputstr) &&
+ PyString_GET_SIZE(inputstr) == soself->s_size) {
+ return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+ }
+ args = PyTuple_Pack(1, inputstr);
+ if (args == NULL)
+ return NULL;
+ if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
+ goto fail;
+ if (soself->s_size != len)
+ goto fail;
+ result = s_unpack_internal(soself, start);
+ Py_DECREF(args);
+ return result;
+
+fail:
+ Py_XDECREF(args);
+ PyErr_Format(StructError,
+ "unpack requires a string argument of length %zd",
+ soself->s_size);
+ return NULL;
+}
+
+PyDoc_STRVAR(s_unpack_from__doc__,
+"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
+\n\
+Return tuple containing values unpacked according to this Struct's format.\n\
+Unlike unpack, unpack_from can unpack values from any object supporting\n\
+the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
+See struct.__doc__ for more on format strings.");
+
+static PyObject *
+s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"buffer", "offset", 0};
+#if (PY_VERSION_HEX < 0x02050000)
+ static char *fmt = "z#|i:unpack_from";
+#else
+ static char *fmt = "z#|n:unpack_from";
+#endif
+ Py_ssize_t buffer_len = 0, offset = 0;
+ char *buffer = NULL;
+ PyStructObject *soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
+ &buffer, &buffer_len, &offset))
+ return NULL;
+
+ if (buffer == NULL) {
+ PyErr_Format(StructError,
+ "unpack_from requires a buffer argument");
+ return NULL;
+ }
+
+ if (offset < 0)
+ offset += buffer_len;
+
+ if (offset < 0 || (buffer_len - offset) < soself->s_size) {
+ PyErr_Format(StructError,
+ "unpack_from requires a buffer of at least %zd bytes",
+ soself->s_size);
+ return NULL;
+ }
+ return s_unpack_internal(soself, buffer + offset);
+}
+
+
+/*
+ * Guts of the pack function.
+ *
+ * Takes a struct object, a tuple of arguments, and offset in that tuple of
+ * argument for where to start processing the arguments for packing, and a
+ * character buffer for writing the packed string. The caller must insure
+ * that the buffer may contain the required length for packing the arguments.
+ * 0 is returned on success, 1 is returned if there is an error.
+ *
+ */
+static int
+s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
+{
+ formatcode *code;
+ /* XXX(nnorwitz): why does i need to be a local? can we use
+ the offset parameter or do we need the wider width? */
+ Py_ssize_t i;
+
+ memset(buf, '\0', soself->s_size);
+ i = offset;
+ for (code = soself->s_codes; code->fmtdef != NULL; code++) {
+ Py_ssize_t n;
+ PyObject *v = PyTuple_GET_ITEM(args, i++);
+ const formatdef *e = code->fmtdef;
+ char *res = buf + code->offset;
+ if (e->format == 's') {
+ if (!PyString_Check(v)) {
+ PyErr_SetString(StructError,
+ "argument for 's' must be a string");
+ return -1;
+ }
+ n = PyString_GET_SIZE(v);
+ if (n > code->size)
+ n = code->size;
+ if (n > 0)
+ memcpy(res, PyString_AS_STRING(v), n);
+ } else if (e->format == 'p') {
+ if (!PyString_Check(v)) {
+ PyErr_SetString(StructError,
+ "argument for 'p' must be a string");
+ return -1;
+ }
+ n = PyString_GET_SIZE(v);
+ if (n > (code->size - 1))
+ n = code->size - 1;
+ if (n > 0)
+ memcpy(res + 1, PyString_AS_STRING(v), n);
+ if (n > 255)
+ n = 255;
+ *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
+ } else {
+ if (e->pack(res, v, e) < 0) {
+ if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_SetString(StructError,
+ "long too large to convert to int");
+ return -1;
+ }
+ }
+ }
+
+ /* Success */
+ return 0;
+}
+
+
+PyDoc_STRVAR(s_pack__doc__,
+"S.pack(v1, v2, ...) -> string\n\
+\n\
+Return a string containing values v1, v2, ... packed according to this\n\
+Struct's format. See struct.__doc__ for more on format strings.");
+
+static PyObject *
+s_pack(PyObject *self, PyObject *args)
+{
+ PyStructObject *soself;
+ PyObject *result;
+
+ /* Validate arguments. */
+ soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+ if (PyTuple_GET_SIZE(args) != soself->s_len)
+ {
+ PyErr_Format(StructError,
+ "pack requires exactly %zd arguments", soself->s_len);
+ return NULL;
+ }
+
+ /* Allocate a new string */
+ result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
+ if (result == NULL)
+ return NULL;
+
+ /* Call the guts */
+ if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
+}
+
+PyDoc_STRVAR(s_pack_into__doc__,
+"S.pack_into(buffer, offset, v1, v2, ...)\n\
+\n\
+Pack the values v1, v2, ... according to this Struct's format, write \n\
+the packed bytes into the writable buffer buf starting at offset. Note\n\
+that the offset is not an optional argument. See struct.__doc__ for \n\
+more on format strings.");
+
+static PyObject *
+s_pack_into(PyObject *self, PyObject *args)
+{
+ PyStructObject *soself;
+ char *buffer;
+ Py_ssize_t buffer_len, offset;
+
+ /* Validate arguments. +1 is for the first arg as buffer. */
+ soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+ if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
+ {
+ PyErr_Format(StructError,
+ "pack_into requires exactly %zd arguments",
+ (soself->s_len + 2));
+ return NULL;
+ }
+
+ /* Extract a writable memory buffer from the first argument */
+ if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
+ (void**)&buffer, &buffer_len) == -1 ) {
+ return NULL;
+ }
+ assert( buffer_len >= 0 );
+
+ /* Extract the offset from the first argument */
+ offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
+
+ /* Support negative offsets. */
+ if (offset < 0)
+ offset += buffer_len;
+
+ /* Check boundaries */
+ if (offset < 0 || (buffer_len - offset) < soself->s_size) {
+ PyErr_Format(StructError,
+ "pack_into requires a buffer of at least %zd bytes",
+ soself->s_size);
+ return NULL;
+ }
+
+ /* Call the guts */
+ if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+s_get_format(PyStructObject *self, void *unused)
+{
+ Py_INCREF(self->s_format);
+ return self->s_format;
+}
+
+static PyObject *
+s_get_size(PyStructObject *self, void *unused)
+{
+ return PyInt_FromSsize_t(self->s_size);
+}
+
+/* List of functions */
+
+static struct PyMethodDef s_methods[] = {
+ {"pack", s_pack, METH_VARARGS, s_pack__doc__},
+ {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
+ {"unpack", s_unpack, METH_O, s_unpack__doc__},
+ {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
+ s_unpack_from__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(s__doc__, "Compiled struct object");
+
+#define OFF(x) offsetof(PyStructObject, x)
+
+static PyGetSetDef s_getsetlist[] = {
+ {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
+ {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
+ {NULL} /* sentinel */
+};
+
+static
+PyTypeObject PyStructType = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "Struct",
+ sizeof(PyStructObject),
+ 0,
+ (destructor)s_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
+ s__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ s_methods, /* tp_methods */
+ NULL, /* tp_members */
+ s_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ s_init, /* tp_init */
+ PyType_GenericAlloc,/* tp_alloc */
+ s_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+/* Module initialization */
+
+PyMODINIT_FUNC
+init_struct(void)
+{
+ PyObject *m = Py_InitModule("_struct", NULL);
+ if (m == NULL)
+ return;
+
+ PyStructType.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyStructType) < 0)
+ return;
+
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ if (pyint_zero == NULL) {
+ pyint_zero = PyInt_FromLong(0);
+ if (pyint_zero == NULL)
+ return;
+ }
+ if (pylong_ulong_mask == NULL) {
+#if (SIZEOF_LONG == 4)
+ pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
+#else
+ pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
+#endif
+ if (pylong_ulong_mask == NULL)
+ return;
+ }
+
+#else
+ /* This speed trick can't be used until overflow masking goes away, because
+ native endian always raises exceptions instead of overflow masking. */
+
+ /* Check endian and swap in faster functions */
+ {
+ int one = 1;
+ formatdef *native = native_table;
+ formatdef *other, *ptr;
+ if ((int)*(unsigned char*)&one)
+ other = lilendian_table;
+ else
+ other = bigendian_table;
+ /* Scan through the native table, find a matching
+ entry in the endian table and swap in the
+ native implementations whenever possible
+ (64-bit platforms may not have "standard" sizes) */
+ while (native->format != '\0' && other->format != '\0') {
+ ptr = other;
+ while (ptr->format != '\0') {
+ if (ptr->format == native->format) {
+ /* Match faster when formats are
+ listed in the same order */
+ if (ptr == other)
+ other++;
+ /* Only use the trick if the
+ size matches */
+ if (ptr->size != native->size)
+ break;
+ /* Skip float and double, could be
+ "unknown" float format */
+ if (ptr->format == 'd' || ptr->format == 'f')
+ break;
+ ptr->pack = native->pack;
+ ptr->unpack = native->unpack;
+ break;
+ }
+ ptr++;
+ }
+ native++;
+ }
+ }
+#endif
+
+ /* Add some symbolic constants to the module */
+ if (StructError == NULL) {
+ StructError = PyErr_NewException("struct.error", NULL, NULL);
+ if (StructError == NULL)
+ return;
+ }
+
+ Py_INCREF(StructError);
+ PyModule_AddObject(m, "error", StructError);
+
+ Py_INCREF((PyObject*)&PyStructType);
+ PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
+
+ PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
+#ifdef PY_STRUCT_OVERFLOW_MASKING
+ PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
+#endif
+#ifdef PY_STRUCT_FLOAT_COERCE
+ PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
+#endif
+
+}
diff --git a/sys/src/cmd/python/Modules/_testcapimodule.c b/sys/src/cmd/python/Modules/_testcapimodule.c
new file mode 100644
index 000000000..b11f0aebf
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_testcapimodule.c
@@ -0,0 +1,898 @@
+/*
+ * C Extension module to test Python interpreter C APIs.
+ *
+ * The 'test_*' functions exported by this module are run as part of the
+ * standard Python regression test, via Lib/test/test_capi.py.
+ */
+
+#include "Python.h"
+#include <float.h>
+#include "structmember.h"
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif /* WITH_THREAD */
+static PyObject *TestError; /* set to exception object in init */
+
+/* Raise TestError with test_name + ": " + msg, and return NULL. */
+
+static PyObject *
+raiseTestError(const char* test_name, const char* msg)
+{
+ char buf[2048];
+
+ if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50)
+ PyErr_SetString(TestError, "internal error msg too large");
+ else {
+ PyOS_snprintf(buf, sizeof(buf), "%s: %s", test_name, msg);
+ PyErr_SetString(TestError, buf);
+ }
+ return NULL;
+}
+
+/* Test #defines from pyconfig.h (particularly the SIZEOF_* defines).
+
+ The ones derived from autoconf on the UNIX-like OSes can be relied
+ upon (in the absence of sloppy cross-compiling), but the Windows
+ platforms have these hardcoded. Better safe than sorry.
+*/
+static PyObject*
+sizeof_error(const char* fatname, const char* typname,
+ int expected, int got)
+{
+ char buf[1024];
+ PyOS_snprintf(buf, sizeof(buf),
+ "%.200s #define == %d but sizeof(%.200s) == %d",
+ fatname, expected, typname, got);
+ PyErr_SetString(TestError, buf);
+ return (PyObject*)NULL;
+}
+
+static PyObject*
+test_config(PyObject *self)
+{
+#define CHECK_SIZEOF(FATNAME, TYPE) \
+ if (FATNAME != sizeof(TYPE)) \
+ return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE))
+
+ CHECK_SIZEOF(SIZEOF_SHORT, short);
+ CHECK_SIZEOF(SIZEOF_INT, int);
+ CHECK_SIZEOF(SIZEOF_LONG, long);
+ CHECK_SIZEOF(SIZEOF_VOID_P, void*);
+ CHECK_SIZEOF(SIZEOF_TIME_T, time_t);
+#ifdef HAVE_LONG_LONG
+ CHECK_SIZEOF(SIZEOF_LONG_LONG, PY_LONG_LONG);
+#endif
+
+#undef CHECK_SIZEOF
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+test_list_api(PyObject *self)
+{
+ PyObject* list;
+ int i;
+
+ /* SF bug 132008: PyList_Reverse segfaults */
+#define NLIST 30
+ list = PyList_New(NLIST);
+ if (list == (PyObject*)NULL)
+ return (PyObject*)NULL;
+ /* list = range(NLIST) */
+ for (i = 0; i < NLIST; ++i) {
+ PyObject* anint = PyInt_FromLong(i);
+ if (anint == (PyObject*)NULL) {
+ Py_DECREF(list);
+ return (PyObject*)NULL;
+ }
+ PyList_SET_ITEM(list, i, anint);
+ }
+ /* list.reverse(), via PyList_Reverse() */
+ i = PyList_Reverse(list); /* should not blow up! */
+ if (i != 0) {
+ Py_DECREF(list);
+ return (PyObject*)NULL;
+ }
+ /* Check that list == range(29, -1, -1) now */
+ for (i = 0; i < NLIST; ++i) {
+ PyObject* anint = PyList_GET_ITEM(list, i);
+ if (PyInt_AS_LONG(anint) != NLIST-1-i) {
+ PyErr_SetString(TestError,
+ "test_list_api: reverse screwed up");
+ Py_DECREF(list);
+ return (PyObject*)NULL;
+ }
+ }
+ Py_DECREF(list);
+#undef NLIST
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int
+test_dict_inner(int count)
+{
+ Py_ssize_t pos = 0, iterations = 0;
+ int i;
+ PyObject *dict = PyDict_New();
+ PyObject *v, *k;
+
+ if (dict == NULL)
+ return -1;
+
+ for (i = 0; i < count; i++) {
+ v = PyInt_FromLong(i);
+ PyDict_SetItem(dict, v, v);
+ Py_DECREF(v);
+ }
+
+ while (PyDict_Next(dict, &pos, &k, &v)) {
+ PyObject *o;
+ iterations++;
+
+ i = PyInt_AS_LONG(v) + 1;
+ o = PyInt_FromLong(i);
+ if (o == NULL)
+ return -1;
+ if (PyDict_SetItem(dict, k, o) < 0) {
+ Py_DECREF(o);
+ return -1;
+ }
+ Py_DECREF(o);
+ }
+
+ Py_DECREF(dict);
+
+ if (iterations != count) {
+ PyErr_SetString(
+ TestError,
+ "test_dict_iteration: dict iteration went wrong ");
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+static PyObject*
+test_dict_iteration(PyObject* self)
+{
+ int i;
+
+ for (i = 0; i < 200; i++) {
+ if (test_dict_inner(i) < 0) {
+ return NULL;
+ }
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
+ PyLong_{As, From}{Unsigned,}LongLong().
+
+ Note that the meat of the test is contained in testcapi_long.h.
+ This is revolting, but delicate code duplication is worse: "almost
+ exactly the same" code is needed to test PY_LONG_LONG, but the ubiquitous
+ dependence on type names makes it impossible to use a parameterized
+ function. A giant macro would be even worse than this. A C++ template
+ would be perfect.
+
+ The "report an error" functions are deliberately not part of the #include
+ file: if the test fails, you can set a breakpoint in the appropriate
+ error function directly, and crawl back from there in the debugger.
+*/
+
+#define UNBIND(X) Py_DECREF(X); (X) = NULL
+
+static PyObject *
+raise_test_long_error(const char* msg)
+{
+ return raiseTestError("test_long_api", msg);
+}
+
+#define TESTNAME test_long_api_inner
+#define TYPENAME long
+#define F_S_TO_PY PyLong_FromLong
+#define F_PY_TO_S PyLong_AsLong
+#define F_U_TO_PY PyLong_FromUnsignedLong
+#define F_PY_TO_U PyLong_AsUnsignedLong
+
+#include "testcapi_long.h"
+
+static PyObject *
+test_long_api(PyObject* self)
+{
+ return TESTNAME(raise_test_long_error);
+}
+
+#undef TESTNAME
+#undef TYPENAME
+#undef F_S_TO_PY
+#undef F_PY_TO_S
+#undef F_U_TO_PY
+#undef F_PY_TO_U
+
+#ifdef HAVE_LONG_LONG
+
+static PyObject *
+raise_test_longlong_error(const char* msg)
+{
+ return raiseTestError("test_longlong_api", msg);
+}
+
+#define TESTNAME test_longlong_api_inner
+#define TYPENAME PY_LONG_LONG
+#define F_S_TO_PY PyLong_FromLongLong
+#define F_PY_TO_S PyLong_AsLongLong
+#define F_U_TO_PY PyLong_FromUnsignedLongLong
+#define F_PY_TO_U PyLong_AsUnsignedLongLong
+
+#include "testcapi_long.h"
+
+static PyObject *
+test_longlong_api(PyObject* self, PyObject *args)
+{
+ return TESTNAME(raise_test_longlong_error);
+}
+
+#undef TESTNAME
+#undef TYPENAME
+#undef F_S_TO_PY
+#undef F_PY_TO_S
+#undef F_U_TO_PY
+#undef F_PY_TO_U
+
+/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG
+ for both long and int arguments. The test may leak a little memory if
+ it fails.
+*/
+static PyObject *
+test_L_code(PyObject *self)
+{
+ PyObject *tuple, *num;
+ PY_LONG_LONG value;
+
+ tuple = PyTuple_New(1);
+ if (tuple == NULL)
+ return NULL;
+
+ num = PyLong_FromLong(42);
+ if (num == NULL)
+ return NULL;
+
+ PyTuple_SET_ITEM(tuple, 0, num);
+
+ value = -1;
+ if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
+ return NULL;
+ if (value != 42)
+ return raiseTestError("test_L_code",
+ "L code returned wrong value for long 42");
+
+ Py_DECREF(num);
+ num = PyInt_FromLong(42);
+ if (num == NULL)
+ return NULL;
+
+ PyTuple_SET_ITEM(tuple, 0, num);
+
+ value = -1;
+ if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
+ return NULL;
+ if (value != 42)
+ return raiseTestError("test_L_code",
+ "L code returned wrong value for int 42");
+
+ Py_DECREF(tuple);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
+
+/* Test tuple argument processing */
+static PyObject *
+getargs_tuple(PyObject *self, PyObject *args)
+{
+ int a, b, c;
+ if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c))
+ return NULL;
+ return Py_BuildValue("iii", a, b, c);
+}
+
+/* Functions to call PyArg_ParseTuple with integer format codes,
+ and return the result.
+*/
+static PyObject *
+getargs_b(PyObject *self, PyObject *args)
+{
+ unsigned char value;
+ if (!PyArg_ParseTuple(args, "b", &value))
+ return NULL;
+ return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_B(PyObject *self, PyObject *args)
+{
+ unsigned char value;
+ if (!PyArg_ParseTuple(args, "B", &value))
+ return NULL;
+ return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_H(PyObject *self, PyObject *args)
+{
+ unsigned short value;
+ if (!PyArg_ParseTuple(args, "H", &value))
+ return NULL;
+ return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_I(PyObject *self, PyObject *args)
+{
+ unsigned int value;
+ if (!PyArg_ParseTuple(args, "I", &value))
+ return NULL;
+ return PyLong_FromUnsignedLong((unsigned long)value);
+}
+
+static PyObject *
+getargs_k(PyObject *self, PyObject *args)
+{
+ unsigned long value;
+ if (!PyArg_ParseTuple(args, "k", &value))
+ return NULL;
+ return PyLong_FromUnsignedLong(value);
+}
+
+static PyObject *
+getargs_i(PyObject *self, PyObject *args)
+{
+ int value;
+ if (!PyArg_ParseTuple(args, "i", &value))
+ return NULL;
+ return PyLong_FromLong((long)value);
+}
+
+static PyObject *
+getargs_l(PyObject *self, PyObject *args)
+{
+ long value;
+ if (!PyArg_ParseTuple(args, "l", &value))
+ return NULL;
+ return PyLong_FromLong(value);
+}
+
+static PyObject *
+getargs_n(PyObject *self, PyObject *args)
+{
+ Py_ssize_t value;
+ if (!PyArg_ParseTuple(args, "n", &value))
+ return NULL;
+ return PyInt_FromSsize_t(value);
+}
+
+#ifdef HAVE_LONG_LONG
+static PyObject *
+getargs_L(PyObject *self, PyObject *args)
+{
+ PY_LONG_LONG value;
+ if (!PyArg_ParseTuple(args, "L", &value))
+ return NULL;
+ return PyLong_FromLongLong(value);
+}
+
+static PyObject *
+getargs_K(PyObject *self, PyObject *args)
+{
+ unsigned PY_LONG_LONG value;
+ if (!PyArg_ParseTuple(args, "K", &value))
+ return NULL;
+ return PyLong_FromUnsignedLongLong(value);
+}
+#endif
+
+/* This function not only tests the 'k' getargs code, but also the
+ PyInt_AsUnsignedLongMask() and PyInt_AsUnsignedLongMask() functions. */
+static PyObject *
+test_k_code(PyObject *self)
+{
+ PyObject *tuple, *num;
+ unsigned long value;
+
+ tuple = PyTuple_New(1);
+ if (tuple == NULL)
+ return NULL;
+
+ /* a number larger than ULONG_MAX even on 64-bit platforms */
+ num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
+ if (num == NULL)
+ return NULL;
+
+ value = PyInt_AsUnsignedLongMask(num);
+ if (value != ULONG_MAX)
+ return raiseTestError("test_k_code",
+ "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
+
+ PyTuple_SET_ITEM(tuple, 0, num);
+
+ value = 0;
+ if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
+ return NULL;
+ if (value != ULONG_MAX)
+ return raiseTestError("test_k_code",
+ "k code returned wrong value for long 0xFFF...FFF");
+
+ Py_DECREF(num);
+ num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16);
+ if (num == NULL)
+ return NULL;
+
+ value = PyInt_AsUnsignedLongMask(num);
+ if (value != (unsigned long)-0x42)
+ return raiseTestError("test_k_code",
+ "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
+
+ PyTuple_SET_ITEM(tuple, 0, num);
+
+ value = 0;
+ if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
+ return NULL;
+ if (value != (unsigned long)-0x42)
+ return raiseTestError("test_k_code",
+ "k code returned wrong value for long -0xFFF..000042");
+
+ Py_DECREF(tuple);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef Py_USING_UNICODE
+
+/* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case
+ of an error.
+*/
+static PyObject *
+test_u_code(PyObject *self)
+{
+ PyObject *tuple, *obj;
+ Py_UNICODE *value;
+ int len;
+
+ tuple = PyTuple_New(1);
+ if (tuple == NULL)
+ return NULL;
+
+ obj = PyUnicode_Decode("test", strlen("test"),
+ "ascii", NULL);
+ if (obj == NULL)
+ return NULL;
+
+ PyTuple_SET_ITEM(tuple, 0, obj);
+
+ value = 0;
+ if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0)
+ return NULL;
+ if (value != PyUnicode_AS_UNICODE(obj))
+ return raiseTestError("test_u_code",
+ "u code returned wrong value for u'test'");
+ value = 0;
+ if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0)
+ return NULL;
+ if (value != PyUnicode_AS_UNICODE(obj) ||
+ len != PyUnicode_GET_SIZE(obj))
+ return raiseTestError("test_u_code",
+ "u# code returned wrong values for u'test'");
+
+ Py_DECREF(tuple);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+codec_incrementalencoder(PyObject *self, PyObject *args)
+{
+ const char *encoding, *errors = NULL;
+ if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder",
+ &encoding, &errors))
+ return NULL;
+ return PyCodec_IncrementalEncoder(encoding, errors);
+}
+
+static PyObject *
+codec_incrementaldecoder(PyObject *self, PyObject *args)
+{
+ const char *encoding, *errors = NULL;
+ if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder",
+ &encoding, &errors))
+ return NULL;
+ return PyCodec_IncrementalDecoder(encoding, errors);
+}
+
+#endif
+
+/* Simple test of _PyLong_NumBits and _PyLong_Sign. */
+static PyObject *
+test_long_numbits(PyObject *self)
+{
+ struct triple {
+ long input;
+ size_t nbits;
+ int sign;
+ } testcases[] = {{0, 0, 0},
+ {1L, 1, 1},
+ {-1L, 1, -1},
+ {2L, 2, 1},
+ {-2L, 2, -1},
+ {3L, 2, 1},
+ {-3L, 2, -1},
+ {4L, 3, 1},
+ {-4L, 3, -1},
+ {0x7fffL, 15, 1}, /* one Python long digit */
+ {-0x7fffL, 15, -1},
+ {0xffffL, 16, 1},
+ {-0xffffL, 16, -1},
+ {0xfffffffL, 28, 1},
+ {-0xfffffffL, 28, -1}};
+ int i;
+
+ for (i = 0; i < sizeof(testcases) / sizeof(struct triple); ++i) {
+ PyObject *plong = PyLong_FromLong(testcases[i].input);
+ size_t nbits = _PyLong_NumBits(plong);
+ int sign = _PyLong_Sign(plong);
+
+ Py_DECREF(plong);
+ if (nbits != testcases[i].nbits)
+ return raiseTestError("test_long_numbits",
+ "wrong result for _PyLong_NumBits");
+ if (sign != testcases[i].sign)
+ return raiseTestError("test_long_numbits",
+ "wrong result for _PyLong_Sign");
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* Example passing NULLs to PyObject_Str(NULL) and PyObject_Unicode(NULL). */
+
+static PyObject *
+test_null_strings(PyObject *self)
+{
+ PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Unicode(NULL);
+ PyObject *tuple = PyTuple_Pack(2, o1, o2);
+ Py_XDECREF(o1);
+ Py_XDECREF(o2);
+ return tuple;
+}
+
+static PyObject *
+raise_exception(PyObject *self, PyObject *args)
+{
+ PyObject *exc;
+ PyObject *exc_args, *v;
+ int num_args, i;
+
+ if (!PyArg_ParseTuple(args, "Oi:raise_exception",
+ &exc, &num_args))
+ return NULL;
+
+ exc_args = PyTuple_New(num_args);
+ if (exc_args == NULL)
+ return NULL;
+ for (i = 0; i < num_args; ++i) {
+ v = PyInt_FromLong(i);
+ if (v == NULL) {
+ Py_DECREF(exc_args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(exc_args, i, v);
+ }
+ PyErr_SetObject(exc, exc_args);
+ Py_DECREF(exc_args);
+ return NULL;
+}
+
+#ifdef WITH_THREAD
+
+/* test_thread_state spawns a thread of its own, and that thread releases
+ * `thread_done` when it's finished. The driver code has to know when the
+ * thread finishes, because the thread uses a PyObject (the callable) that
+ * may go away when the driver finishes. The former lack of this explicit
+ * synchronization caused rare segfaults, so rare that they were seen only
+ * on a Mac buildbot (although they were possible on any box).
+ */
+static PyThread_type_lock thread_done = NULL;
+
+static void
+_make_call(void *callable)
+{
+ PyObject *rc;
+ PyGILState_STATE s = PyGILState_Ensure();
+ rc = PyObject_CallFunction((PyObject *)callable, "");
+ Py_XDECREF(rc);
+ PyGILState_Release(s);
+}
+
+/* Same thing, but releases `thread_done` when it returns. This variant
+ * should be called only from threads spawned by test_thread_state().
+ */
+static void
+_make_call_from_thread(void *callable)
+{
+ _make_call(callable);
+ PyThread_release_lock(thread_done);
+}
+
+static PyObject *
+test_thread_state(PyObject *self, PyObject *args)
+{
+ PyObject *fn;
+
+ if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn))
+ return NULL;
+
+ /* Ensure Python is set up for threading */
+ PyEval_InitThreads();
+ thread_done = PyThread_allocate_lock();
+ if (thread_done == NULL)
+ return PyErr_NoMemory();
+ PyThread_acquire_lock(thread_done, 1);
+
+ /* Start a new thread with our callback. */
+ PyThread_start_new_thread(_make_call_from_thread, fn);
+ /* Make the callback with the thread lock held by this thread */
+ _make_call(fn);
+ /* Do it all again, but this time with the thread-lock released */
+ Py_BEGIN_ALLOW_THREADS
+ _make_call(fn);
+ PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
+ Py_END_ALLOW_THREADS
+
+ /* And once more with and without a thread
+ XXX - should use a lock and work out exactly what we are trying
+ to test <wink>
+ */
+ Py_BEGIN_ALLOW_THREADS
+ PyThread_start_new_thread(_make_call_from_thread, fn);
+ _make_call(fn);
+ PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
+ Py_END_ALLOW_THREADS
+
+ /* Release lock we acquired above. This is required on HP-UX. */
+ PyThread_release_lock(thread_done);
+
+ PyThread_free_lock(thread_done);
+ Py_RETURN_NONE;
+}
+#endif
+
+/* Some tests of PyString_FromFormat(). This needs more tests. */
+static PyObject *
+test_string_from_format(PyObject *self, PyObject *args)
+{
+ PyObject *result;
+ char *msg;
+
+#define CHECK_1_FORMAT(FORMAT, TYPE) \
+ result = PyString_FromFormat(FORMAT, (TYPE)1); \
+ if (result == NULL) \
+ return NULL; \
+ if (strcmp(PyString_AsString(result), "1")) { \
+ msg = FORMAT " failed at 1"; \
+ goto Fail; \
+ } \
+ Py_DECREF(result)
+
+ CHECK_1_FORMAT("%d", int);
+ CHECK_1_FORMAT("%ld", long);
+ /* The z width modifier was added in Python 2.5. */
+ CHECK_1_FORMAT("%zd", Py_ssize_t);
+
+ /* The u type code was added in Python 2.5. */
+ CHECK_1_FORMAT("%u", unsigned int);
+ CHECK_1_FORMAT("%lu", unsigned long);
+ CHECK_1_FORMAT("%zu", size_t);
+
+ Py_RETURN_NONE;
+
+ Fail:
+ Py_XDECREF(result);
+ return raiseTestError("test_string_from_format", msg);
+
+#undef CHECK_1_FORMAT
+}
+
+/* This is here to provide a docstring for test_descr. */
+static PyObject *
+test_with_docstring(PyObject *self)
+{
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef TestMethods[] = {
+ {"raise_exception", raise_exception, METH_VARARGS},
+ {"test_config", (PyCFunction)test_config, METH_NOARGS},
+ {"test_list_api", (PyCFunction)test_list_api, METH_NOARGS},
+ {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS},
+ {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS},
+ {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS},
+ {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS},
+ {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS},
+ {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS},
+ {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS,
+ PyDoc_STR("This is a pretty normal docstring.")},
+
+ {"getargs_tuple", getargs_tuple, METH_VARARGS},
+ {"getargs_b", getargs_b, METH_VARARGS},
+ {"getargs_B", getargs_B, METH_VARARGS},
+ {"getargs_H", getargs_H, METH_VARARGS},
+ {"getargs_I", getargs_I, METH_VARARGS},
+ {"getargs_k", getargs_k, METH_VARARGS},
+ {"getargs_i", getargs_i, METH_VARARGS},
+ {"getargs_l", getargs_l, METH_VARARGS},
+ {"getargs_n", getargs_n, METH_VARARGS},
+#ifdef HAVE_LONG_LONG
+ {"getargs_L", getargs_L, METH_VARARGS},
+ {"getargs_K", getargs_K, METH_VARARGS},
+ {"test_longlong_api", test_longlong_api, METH_NOARGS},
+ {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS},
+ {"codec_incrementalencoder",
+ (PyCFunction)codec_incrementalencoder, METH_VARARGS},
+ {"codec_incrementaldecoder",
+ (PyCFunction)codec_incrementaldecoder, METH_VARARGS},
+#endif
+#ifdef Py_USING_UNICODE
+ {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS},
+#endif
+#ifdef WITH_THREAD
+ {"_test_thread_state", test_thread_state, METH_VARARGS},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);}
+
+typedef struct {
+ char byte_member;
+ unsigned char ubyte_member;
+ short short_member;
+ unsigned short ushort_member;
+ int int_member;
+ unsigned int uint_member;
+ long long_member;
+ unsigned long ulong_member;
+ float float_member;
+ double double_member;
+} all_structmembers;
+
+typedef struct {
+ PyObject_HEAD
+ all_structmembers structmembers;
+} test_structmembers;
+
+static struct PyMemberDef test_members[] = {
+ {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
+ {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
+ {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
+ {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
+ {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
+ {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
+ {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
+ {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
+ {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
+ {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
+ {NULL}
+};
+
+
+static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){
+ static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT",
+ "T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", NULL};
+ test_structmembers *ob=PyObject_New(test_structmembers, type);
+ if (ob==NULL)
+ return NULL;
+ memset(&ob->structmembers, 0, sizeof(all_structmembers));
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|bBhHiIlkfd", keywords,
+ &ob->structmembers.byte_member, &ob->structmembers.ubyte_member,
+ &ob->structmembers.short_member, &ob->structmembers.ushort_member,
+ &ob->structmembers.int_member, &ob->structmembers.uint_member,
+ &ob->structmembers.long_member, &ob->structmembers.ulong_member,
+ &ob->structmembers.float_member, &ob->structmembers.double_member)){
+ Py_DECREF(ob);
+ return NULL;
+ }
+ return (PyObject *)ob;
+}
+
+static void test_structmembers_free(PyObject *ob){
+ PyObject_FREE(ob);
+}
+
+static PyTypeObject test_structmembersType = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "test_structmembersType",
+ sizeof(test_structmembers), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ test_structmembers_free, /* destructor tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr,
+ PyObject_GenericSetAttr,
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ "Type containing all structmember types",
+ 0, /* traverseproc tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ test_members, /* tp_members */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ test_structmembers_new, /* tp_new */
+};
+
+
+PyMODINIT_FUNC
+init_testcapi(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule("_testcapi", TestMethods);
+ if (m == NULL)
+ return;
+
+ test_structmembersType.ob_type=&PyType_Type;
+ Py_INCREF(&test_structmembersType);
+ PyModule_AddObject(m, "test_structmembersType", (PyObject *)&test_structmembersType);
+
+ PyModule_AddObject(m, "CHAR_MAX", PyInt_FromLong(CHAR_MAX));
+ PyModule_AddObject(m, "CHAR_MIN", PyInt_FromLong(CHAR_MIN));
+ PyModule_AddObject(m, "UCHAR_MAX", PyInt_FromLong(UCHAR_MAX));
+ PyModule_AddObject(m, "SHRT_MAX", PyInt_FromLong(SHRT_MAX));
+ PyModule_AddObject(m, "SHRT_MIN", PyInt_FromLong(SHRT_MIN));
+ PyModule_AddObject(m, "USHRT_MAX", PyInt_FromLong(USHRT_MAX));
+ PyModule_AddObject(m, "INT_MAX", PyLong_FromLong(INT_MAX));
+ PyModule_AddObject(m, "INT_MIN", PyLong_FromLong(INT_MIN));
+ PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX));
+ PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX));
+ PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN));
+ PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX));
+ PyModule_AddObject(m, "FLT_MAX", PyFloat_FromDouble(FLT_MAX));
+ PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN));
+ PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX));
+ PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN));
+ PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX));
+ PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
+
+ TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
+ Py_INCREF(TestError);
+ PyModule_AddObject(m, "error", TestError);
+}
diff --git a/sys/src/cmd/python/Modules/_tkinter.c b/sys/src/cmd/python/Modules/_tkinter.c
new file mode 100644
index 000000000..0b853b5b4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_tkinter.c
@@ -0,0 +1,3165 @@
+/***********************************************************
+Copyright (C) 1994 Steen Lumholt.
+
+ All Rights Reserved
+
+******************************************************************/
+
+/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
+
+/* TCL/TK VERSION INFO:
+
+ Only Tcl/Tk 8.2 and later are supported. Older versions are not
+ supported. (Use Python 2.2 if you cannot upgrade your Tcl/Tk
+ libraries.)
+*/
+
+/* XXX Further speed-up ideas, involving Tcl 8.0 features:
+
+ - Register a new Tcl type, "Python callable", which can be called more
+ efficiently and passed to Tcl_EvalObj() directly (if this is possible).
+
+*/
+
+
+#include "Python.h"
+#include <ctype.h>
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+/* Allow using this code in Python 2.[12] */
+#ifndef PyDoc_STRVAR
+#define PyDoc_STRVAR(name,str) static char name[] = str
+#endif
+
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC void
+#endif
+
+#ifndef PyBool_Check
+#define PyBool_Check(o) 0
+#define PyBool_FromLong PyInt_FromLong
+#endif
+
+/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
+ making _tkinter correct for this API means to break earlier
+ versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
+ earlier versions. Once Tcl releases before 8.4 don't need to be supported
+ anymore, this should go. */
+#define USE_COMPAT_CONST
+
+/* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
+ it always; if Tcl is not threaded, the thread functions in
+ Tcl are empty. */
+#define TCL_THREADS
+
+#ifdef TK_FRAMEWORK
+#include <Tcl/tcl.h>
+#include <Tk/tk.h>
+#else
+#include <tcl.h>
+#include <tk.h>
+#endif
+
+/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
+#ifndef CONST84_RETURN
+#define CONST84_RETURN
+#undef CONST
+#define CONST
+#endif
+
+#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
+
+#if TKMAJORMINOR < 8002
+#error "Tk older than 8.2 not supported"
+#endif
+
+/* Unicode conversion assumes that Tcl_UniChar is two bytes.
+ We cannot test this directly, so we test UTF-8 size instead,
+ expecting that TCL_UTF_MAX is changed if Tcl ever supports
+ either UTF-16 or UCS-4.
+ Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
+ Tcl_Unichar. This is also ok as long as Python uses UCS-4,
+ as well.
+*/
+#if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
+#error "unsupported Tcl configuration"
+#endif
+
+#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
+#define HAVE_CREATEFILEHANDLER
+#endif
+
+#ifdef HAVE_CREATEFILEHANDLER
+
+/* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
+ with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
+#ifndef TCL_UNIX_FD
+# ifdef TCL_WIN_SOCKET
+# define TCL_UNIX_FD (! TCL_WIN_SOCKET)
+# else
+# define TCL_UNIX_FD 1
+# endif
+#endif
+
+/* Tcl_CreateFileHandler() changed several times; these macros deal with the
+ messiness. In Tcl 8.0 and later, it is not available on Windows (and on
+ Unix, only because Jack added it back); when available on Windows, it only
+ applies to sockets. */
+
+#ifdef MS_WINDOWS
+#define FHANDLETYPE TCL_WIN_SOCKET
+#else
+#define FHANDLETYPE TCL_UNIX_FD
+#endif
+
+/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
+ which uses this to handle Tcl events while the user is typing commands. */
+
+#if FHANDLETYPE == TCL_UNIX_FD
+#define WAIT_FOR_STDIN
+#endif
+
+#endif /* HAVE_CREATEFILEHANDLER */
+
+#ifdef MS_WINDOWS
+#include <conio.h>
+#define WAIT_FOR_STDIN
+#endif
+
+#ifdef WITH_THREAD
+
+/* The threading situation is complicated. Tcl is not thread-safe, except
+ when configured with --enable-threads.
+ So we need to use a lock around all uses of Tcl. Previously, the Python
+ interpreter lock was used for this. However, this causes problems when
+ other Python threads need to run while Tcl is blocked waiting for events.
+
+ To solve this problem, a separate lock for Tcl is introduced. Holding it
+ is incompatible with holding Python's interpreter lock. The following four
+ macros manipulate both locks together.
+
+ ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
+ Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
+ that could call an event handler, or otherwise affect the state of a Tcl
+ interpreter. These assume that the surrounding code has the Python
+ interpreter lock; inside the brackets, the Python interpreter lock has been
+ released and the lock for Tcl has been acquired.
+
+ Sometimes, it is necessary to have both the Python lock and the Tcl lock.
+ (For example, when transferring data from the Tcl interpreter result to a
+ Python string object.) This can be done by using different macros to close
+ the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
+ the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
+ releases the Tcl lock.
+
+ By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
+ handlers when the handler needs to use Python. Such event handlers are
+ entered while the lock for Tcl is held; the event handler presumably needs
+ to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
+ the Python interpreter lock, restoring the appropriate thread state, and
+ LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
+ for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
+ the code between ENTER_PYTHON and LEAVE_PYTHON.
+
+ These locks expand to several statements and brackets; they should not be
+ used in branches of if statements and the like.
+
+ If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
+ only valid in the thread that created it, and all Tk activity must happen in this
+ thread, also. That means that the mainloop must be invoked in the thread that
+ created the interpreter. Invoking commands from other threads is possible;
+ _tkinter will queue an event for the interpreter thread, which will then
+ execute the command and pass back the result. If the main thread is not in the
+ mainloop, and invoking commands causes an exception; if the main loop is running
+ but not processing events, the command invocation will block.
+
+ In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient
+ anymore, since multiple Tcl interpreters may simultaneously dispatch in different
+ threads. So we use the Tcl TLS API.
+
+*/
+
+static PyThread_type_lock tcl_lock = 0;
+
+#ifdef TCL_THREADS
+static Tcl_ThreadDataKey state_key;
+typedef PyThreadState *ThreadSpecificData;
+#define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
+#else
+static PyThreadState *tcl_tstate = NULL;
+#endif
+
+#define ENTER_TCL \
+ { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
+ if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
+
+#define LEAVE_TCL \
+ tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
+
+#define ENTER_OVERLAP \
+ Py_END_ALLOW_THREADS
+
+#define LEAVE_OVERLAP_TCL \
+ tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
+
+#define ENTER_PYTHON \
+ { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
+ if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
+
+#define LEAVE_PYTHON \
+ { PyThreadState *tstate = PyEval_SaveThread(); \
+ if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
+
+#define CHECK_TCL_APPARTMENT \
+ if (((TkappObject *)self)->threaded && \
+ ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
+ PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartment"); \
+ return 0; \
+ }
+
+#else
+
+#define ENTER_TCL
+#define LEAVE_TCL
+#define ENTER_OVERLAP
+#define LEAVE_OVERLAP_TCL
+#define ENTER_PYTHON
+#define LEAVE_PYTHON
+#define CHECK_TCL_APPARTMENT
+
+#endif
+
+#ifndef FREECAST
+#define FREECAST (char *)
+#endif
+
+/**** Tkapp Object Declaration ****/
+
+static PyTypeObject Tkapp_Type;
+
+typedef struct {
+ PyObject_HEAD
+ Tcl_Interp *interp;
+ int wantobjects;
+ int threaded; /* True if tcl_platform[threaded] */
+ Tcl_ThreadId thread_id;
+ int dispatching;
+ /* We cannot include tclInt.h, as this is internal.
+ So we cache interesting types here. */
+ Tcl_ObjType *BooleanType;
+ Tcl_ObjType *ByteArrayType;
+ Tcl_ObjType *DoubleType;
+ Tcl_ObjType *IntType;
+ Tcl_ObjType *ListType;
+ Tcl_ObjType *ProcBodyType;
+ Tcl_ObjType *StringType;
+} TkappObject;
+
+#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
+#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
+#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
+
+#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
+(void *) v, ((PyObject *) v)->ob_refcnt))
+
+
+
+/**** Error Handling ****/
+
+static PyObject *Tkinter_TclError;
+static int quitMainLoop = 0;
+static int errorInCmd = 0;
+static PyObject *excInCmd;
+static PyObject *valInCmd;
+static PyObject *trbInCmd;
+
+
+
+static PyObject *
+Tkinter_Error(PyObject *v)
+{
+ PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
+ return NULL;
+}
+
+
+
+/**** Utils ****/
+
+static int Tkinter_busywaitinterval = 20;
+
+#ifdef WITH_THREAD
+#ifndef MS_WINDOWS
+
+/* Millisecond sleep() for Unix platforms. */
+
+static void
+Sleep(int milli)
+{
+ /* XXX Too bad if you don't have select(). */
+ struct timeval t;
+ t.tv_sec = milli/1000;
+ t.tv_usec = (milli%1000) * 1000;
+ select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+}
+#endif /* MS_WINDOWS */
+
+/* Wait up to 1s for the mainloop to come up. */
+
+static int
+WaitForMainloop(TkappObject* self)
+{
+ int i;
+ for (i = 0; i < 10; i++) {
+ if (self->dispatching)
+ return 1;
+ Py_BEGIN_ALLOW_THREADS
+ Sleep(100);
+ Py_END_ALLOW_THREADS
+ }
+ if (self->dispatching)
+ return 1;
+ PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
+ return 0;
+}
+#endif /* WITH_THREAD */
+
+
+static char *
+AsString(PyObject *value, PyObject *tmp)
+{
+ if (PyString_Check(value))
+ return PyString_AsString(value);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(value)) {
+ PyObject *v = PyUnicode_AsUTF8String(value);
+ if (v == NULL)
+ return NULL;
+ if (PyList_Append(tmp, v) != 0) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ Py_DECREF(v);
+ return PyString_AsString(v);
+ }
+#endif
+ else {
+ PyObject *v = PyObject_Str(value);
+ if (v == NULL)
+ return NULL;
+ if (PyList_Append(tmp, v) != 0) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ Py_DECREF(v);
+ return PyString_AsString(v);
+ }
+}
+
+
+
+#define ARGSZ 64
+
+static char *
+Merge(PyObject *args)
+{
+ PyObject *tmp = NULL;
+ char *argvStore[ARGSZ];
+ char **argv = NULL;
+ int fvStore[ARGSZ];
+ int *fv = NULL;
+ int argc = 0, fvc = 0, i;
+ char *res = NULL;
+
+ if (!(tmp = PyList_New(0)))
+ return NULL;
+
+ argv = argvStore;
+ fv = fvStore;
+
+ if (args == NULL)
+ argc = 0;
+
+ else if (!PyTuple_Check(args)) {
+ argc = 1;
+ fv[0] = 0;
+ if (!(argv[0] = AsString(args, tmp)))
+ goto finally;
+ }
+ else {
+ argc = PyTuple_Size(args);
+
+ if (argc > ARGSZ) {
+ argv = (char **)ckalloc(argc * sizeof(char *));
+ fv = (int *)ckalloc(argc * sizeof(int));
+ if (argv == NULL || fv == NULL) {
+ PyErr_NoMemory();
+ goto finally;
+ }
+ }
+
+ for (i = 0; i < argc; i++) {
+ PyObject *v = PyTuple_GetItem(args, i);
+ if (PyTuple_Check(v)) {
+ fv[i] = 1;
+ if (!(argv[i] = Merge(v)))
+ goto finally;
+ fvc++;
+ }
+ else if (v == Py_None) {
+ argc = i;
+ break;
+ }
+ else {
+ fv[i] = 0;
+ if (!(argv[i] = AsString(v, tmp)))
+ goto finally;
+ fvc++;
+ }
+ }
+ }
+ res = Tcl_Merge(argc, argv);
+ if (res == NULL)
+ PyErr_SetString(Tkinter_TclError, "merge failed");
+
+ finally:
+ for (i = 0; i < fvc; i++)
+ if (fv[i]) {
+ ckfree(argv[i]);
+ }
+ if (argv != argvStore)
+ ckfree(FREECAST argv);
+ if (fv != fvStore)
+ ckfree(FREECAST fv);
+
+ Py_DECREF(tmp);
+ return res;
+}
+
+
+
+static PyObject *
+Split(char *list)
+{
+ int argc;
+ char **argv;
+ PyObject *v;
+
+ if (list == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
+ /* Not a list.
+ * Could be a quoted string containing funnies, e.g. {"}.
+ * Return the string itself.
+ */
+ return PyString_FromString(list);
+ }
+
+ if (argc == 0)
+ v = PyString_FromString("");
+ else if (argc == 1)
+ v = PyString_FromString(argv[0]);
+ else if ((v = PyTuple_New(argc)) != NULL) {
+ int i;
+ PyObject *w;
+
+ for (i = 0; i < argc; i++) {
+ if ((w = Split(argv[i])) == NULL) {
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ PyTuple_SetItem(v, i, w);
+ }
+ }
+ Tcl_Free(FREECAST argv);
+ return v;
+}
+
+/* In some cases, Tcl will still return strings that are supposed to be
+ lists. SplitObj walks through a nested tuple, finding string objects that
+ need to be split. */
+
+PyObject *
+SplitObj(PyObject *arg)
+{
+ if (PyTuple_Check(arg)) {
+ int i, size;
+ PyObject *elem, *newelem, *result;
+
+ size = PyTuple_Size(arg);
+ result = NULL;
+ /* Recursively invoke SplitObj for all tuple items.
+ If this does not return a new object, no action is
+ needed. */
+ for(i = 0; i < size; i++) {
+ elem = PyTuple_GetItem(arg, i);
+ newelem = SplitObj(elem);
+ if (!newelem) {
+ Py_XDECREF(result);
+ return NULL;
+ }
+ if (!result) {
+ int k;
+ if (newelem == elem) {
+ Py_DECREF(newelem);
+ continue;
+ }
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ for(k = 0; k < i; k++) {
+ elem = PyTuple_GetItem(arg, k);
+ Py_INCREF(elem);
+ PyTuple_SetItem(result, k, elem);
+ }
+ }
+ PyTuple_SetItem(result, i, newelem);
+ }
+ if (result)
+ return result;
+ /* Fall through, returning arg. */
+ }
+ else if (PyString_Check(arg)) {
+ int argc;
+ char **argv;
+ char *list = PyString_AsString(arg);
+
+ if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
+ Py_INCREF(arg);
+ return arg;
+ }
+ Tcl_Free(FREECAST argv);
+ if (argc > 1)
+ return Split(PyString_AsString(arg));
+ /* Fall through, returning arg. */
+ }
+ Py_INCREF(arg);
+ return arg;
+}
+
+
+/**** Tkapp Object ****/
+
+#ifndef WITH_APPINIT
+int
+Tcl_AppInit(Tcl_Interp *interp)
+{
+ Tk_Window main;
+ const char * _tkinter_skip_tk_init;
+
+ if (Tcl_Init(interp) == TCL_ERROR) {
+ PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
+ return TCL_ERROR;
+ }
+ _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
+ if (_tkinter_skip_tk_init == NULL || strcmp(_tkinter_skip_tk_init, "1") != 0) {
+ main = Tk_MainWindow(interp);
+ if (Tk_Init(interp) == TCL_ERROR) {
+ PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+}
+#endif /* !WITH_APPINIT */
+
+
+
+
+/* Initialize the Tk application; see the `main' function in
+ * `tkMain.c'.
+ */
+
+static void EnableEventHook(void); /* Forward */
+static void DisableEventHook(void); /* Forward */
+
+static TkappObject *
+Tkapp_New(char *screenName, char *baseName, char *className,
+ int interactive, int wantobjects, int wantTk, int sync, char *use)
+{
+ TkappObject *v;
+ char *argv0;
+
+ v = PyObject_New(TkappObject, &Tkapp_Type);
+ if (v == NULL)
+ return NULL;
+
+ v->interp = Tcl_CreateInterp();
+ v->wantobjects = wantobjects;
+ v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
+ TCL_GLOBAL_ONLY) != NULL;
+ v->thread_id = Tcl_GetCurrentThread();
+ v->dispatching = 0;
+
+#ifndef TCL_THREADS
+ if (v->threaded) {
+ PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not");
+ Py_DECREF(v);
+ return 0;
+ }
+#endif
+#ifdef WITH_THREAD
+ if (v->threaded && tcl_lock) {
+ /* If Tcl is threaded, we don't need the lock. */
+ PyThread_free_lock(tcl_lock);
+ tcl_lock = NULL;
+ }
+#endif
+
+ v->BooleanType = Tcl_GetObjType("boolean");
+ v->ByteArrayType = Tcl_GetObjType("bytearray");
+ v->DoubleType = Tcl_GetObjType("double");
+ v->IntType = Tcl_GetObjType("int");
+ v->ListType = Tcl_GetObjType("list");
+ v->ProcBodyType = Tcl_GetObjType("procbody");
+ v->StringType = Tcl_GetObjType("string");
+
+ /* Delete the 'exit' command, which can screw things up */
+ Tcl_DeleteCommand(v->interp, "exit");
+
+ if (screenName != NULL)
+ Tcl_SetVar2(v->interp, "env", "DISPLAY",
+ screenName, TCL_GLOBAL_ONLY);
+
+ if (interactive)
+ Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
+ else
+ Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+ /* This is used to get the application class for Tk 4.1 and up */
+ argv0 = (char*)ckalloc(strlen(className) + 1);
+ if (!argv0) {
+ PyErr_NoMemory();
+ Py_DECREF(v);
+ return NULL;
+ }
+
+ strcpy(argv0, className);
+ if (isupper(Py_CHARMASK(argv0[0])))
+ argv0[0] = tolower(Py_CHARMASK(argv0[0]));
+ Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
+ ckfree(argv0);
+
+ if (! wantTk) {
+ Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY);
+ }
+
+ /* some initial arguments need to be in argv */
+ if (sync || use) {
+ char *args;
+ int len = 0;
+
+ if (sync)
+ len += sizeof "-sync";
+ if (use)
+ len += strlen(use) + sizeof "-use ";
+
+ args = (char*)ckalloc(len);
+ if (!args) {
+ PyErr_NoMemory();
+ Py_DECREF(v);
+ return NULL;
+ }
+
+ args[0] = '\0';
+ if (sync)
+ strcat(args, "-sync");
+ if (use) {
+ if (sync)
+ strcat(args, " ");
+ strcat(args, "-use ");
+ strcat(args, use);
+ }
+
+ Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY);
+ ckfree(args);
+ }
+
+ if (Tcl_AppInit(v->interp) != TCL_OK) {
+ PyObject *result = Tkinter_Error((PyObject *)v);
+ Py_DECREF((PyObject *)v);
+ return (TkappObject *)result;
+ }
+
+ EnableEventHook();
+
+ return v;
+}
+
+
+static void
+Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
+ Tcl_Condition *cond, Tcl_Mutex *mutex)
+{
+ Py_BEGIN_ALLOW_THREADS;
+ Tcl_MutexLock(mutex);
+ Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL);
+ Tcl_ThreadAlert(self->thread_id);
+ Tcl_ConditionWait(cond, mutex, NULL);
+ Tcl_MutexUnlock(mutex);
+ Py_END_ALLOW_THREADS
+}
+
+
+/** Tcl Eval **/
+
+typedef struct {
+ PyObject_HEAD
+ Tcl_Obj *value;
+ PyObject *string; /* This cannot cause cycles. */
+} PyTclObject;
+
+staticforward PyTypeObject PyTclObject_Type;
+#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
+
+static PyObject *
+newPyTclObject(Tcl_Obj *arg)
+{
+ PyTclObject *self;
+ self = PyObject_New(PyTclObject, &PyTclObject_Type);
+ if (self == NULL)
+ return NULL;
+ Tcl_IncrRefCount(arg);
+ self->value = arg;
+ self->string = NULL;
+ return (PyObject*)self;
+}
+
+static void
+PyTclObject_dealloc(PyTclObject *self)
+{
+ Tcl_DecrRefCount(self->value);
+ Py_XDECREF(self->string);
+ PyObject_Del(self);
+}
+
+static PyObject *
+PyTclObject_str(PyTclObject *self)
+{
+ if (self->string && PyString_Check(self->string)) {
+ Py_INCREF(self->string);
+ return self->string;
+ }
+ /* XXX Could cache value if it is an ASCII string. */
+ return PyString_FromString(Tcl_GetString(self->value));
+}
+
+static char*
+PyTclObject_TclString(PyObject *self)
+{
+ return Tcl_GetString(((PyTclObject*)self)->value);
+}
+
+/* Like _str, but create Unicode if necessary. */
+PyDoc_STRVAR(PyTclObject_string__doc__,
+"the string representation of this object, either as string or Unicode");
+
+static PyObject *
+PyTclObject_string(PyTclObject *self, void *ignored)
+{
+ char *s;
+ int i, len;
+ if (!self->string) {
+ s = Tcl_GetStringFromObj(self->value, &len);
+ for (i = 0; i < len; i++)
+ if (s[i] & 0x80)
+ break;
+#ifdef Py_USING_UNICODE
+ if (i == len)
+ /* It is an ASCII string. */
+ self->string = PyString_FromStringAndSize(s, len);
+ else {
+ self->string = PyUnicode_DecodeUTF8(s, len, "strict");
+ if (!self->string) {
+ PyErr_Clear();
+ self->string = PyString_FromStringAndSize(s, len);
+ }
+ }
+#else
+ self->string = PyString_FromStringAndSize(s, len);
+#endif
+ if (!self->string)
+ return NULL;
+ }
+ Py_INCREF(self->string);
+ return self->string;
+}
+
+#ifdef Py_USING_UNICODE
+PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
+
+static PyObject *
+PyTclObject_unicode(PyTclObject *self, void *ignored)
+{
+ char *s;
+ int len;
+ if (self->string && PyUnicode_Check(self->string)) {
+ Py_INCREF(self->string);
+ return self->string;
+ }
+ /* XXX Could chache result if it is non-ASCII. */
+ s = Tcl_GetStringFromObj(self->value, &len);
+ return PyUnicode_DecodeUTF8(s, len, "strict");
+}
+#endif
+
+static PyObject *
+PyTclObject_repr(PyTclObject *self)
+{
+ char buf[50];
+ PyOS_snprintf(buf, 50, "<%s object at %p>",
+ self->value->typePtr->name, self->value);
+ return PyString_FromString(buf);
+}
+
+static int
+PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
+{
+ int res;
+ res = strcmp(Tcl_GetString(self->value),
+ Tcl_GetString(other->value));
+ if (res < 0) return -1;
+ if (res > 0) return 1;
+ return 0;
+}
+
+PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
+
+static PyObject*
+get_typename(PyTclObject* obj, void* ignored)
+{
+ return PyString_FromString(obj->value->typePtr->name);
+}
+
+
+static PyGetSetDef PyTclObject_getsetlist[] = {
+ {"typename", (getter)get_typename, NULL, get_typename__doc__},
+ {"string", (getter)PyTclObject_string, NULL,
+ PyTclObject_string__doc__},
+ {0},
+};
+
+static PyMethodDef PyTclObject_methods[] = {
+#ifdef Py_USING_UNICODE
+ {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
+ PyTclObject_unicode__doc__},
+#endif
+ {0}
+};
+
+statichere PyTypeObject PyTclObject_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_tkinter.Tcl_Obj", /*tp_name*/
+ sizeof(PyTclObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyTclObject_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ (cmpfunc)PyTclObject_cmp, /*tp_compare*/
+ (reprfunc)PyTclObject_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ (reprfunc)PyTclObject_str, /*tp_str*/
+ PyObject_GenericGetAttr,/*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ PyTclObject_methods, /*tp_methods*/
+ 0, /*tp_members*/
+ PyTclObject_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+static Tcl_Obj*
+AsObj(PyObject *value)
+{
+ Tcl_Obj *result;
+
+ if (PyString_Check(value))
+ return Tcl_NewStringObj(PyString_AS_STRING(value),
+ PyString_GET_SIZE(value));
+ else if (PyBool_Check(value))
+ return Tcl_NewBooleanObj(PyObject_IsTrue(value));
+ else if (PyInt_Check(value))
+ return Tcl_NewLongObj(PyInt_AS_LONG(value));
+ else if (PyFloat_Check(value))
+ return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
+ else if (PyTuple_Check(value)) {
+ Tcl_Obj **argv = (Tcl_Obj**)
+ ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
+ int i;
+ if(!argv)
+ return 0;
+ for(i=0;i<PyTuple_Size(value);i++)
+ argv[i] = AsObj(PyTuple_GetItem(value,i));
+ result = Tcl_NewListObj(PyTuple_Size(value), argv);
+ ckfree(FREECAST argv);
+ return result;
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(value)) {
+ Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
+ Py_ssize_t size = PyUnicode_GET_SIZE(value);
+ /* This #ifdef assumes that Tcl uses UCS-2.
+ See TCL_UTF_MAX test above. */
+#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
+ Tcl_UniChar *outbuf;
+ Py_ssize_t i;
+ assert(size < size * sizeof(Tcl_UniChar));
+ outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
+ if (!outbuf) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ for (i = 0; i < size; i++) {
+ if (inbuf[i] >= 0x10000) {
+ /* Tcl doesn't do UTF-16, yet. */
+ PyErr_SetString(PyExc_ValueError,
+ "unsupported character");
+ ckfree(FREECAST outbuf);
+ return NULL;
+ }
+ outbuf[i] = inbuf[i];
+ }
+ result = Tcl_NewUnicodeObj(outbuf, size);
+ ckfree(FREECAST outbuf);
+ return result;
+#else
+ return Tcl_NewUnicodeObj(inbuf, size);
+#endif
+
+ }
+#endif
+ else if(PyTclObject_Check(value)) {
+ Tcl_Obj *v = ((PyTclObject*)value)->value;
+ Tcl_IncrRefCount(v);
+ return v;
+ }
+ else {
+ PyObject *v = PyObject_Str(value);
+ if (!v)
+ return 0;
+ result = AsObj(v);
+ Py_DECREF(v);
+ return result;
+ }
+}
+
+static PyObject*
+FromObj(PyObject* tkapp, Tcl_Obj *value)
+{
+ PyObject *result = NULL;
+ TkappObject *app = (TkappObject*)tkapp;
+
+ if (value->typePtr == NULL) {
+ /* If the result contains any bytes with the top bit set,
+ it's UTF-8 and we should decode it to Unicode */
+#ifdef Py_USING_UNICODE
+ int i;
+ char *s = value->bytes;
+ int len = value->length;
+ for (i = 0; i < len; i++) {
+ if (value->bytes[i] & 0x80)
+ break;
+ }
+
+ if (i == value->length)
+ result = PyString_FromStringAndSize(s, len);
+ else {
+ /* Convert UTF-8 to Unicode string */
+ result = PyUnicode_DecodeUTF8(s, len, "strict");
+ if (result == NULL) {
+ PyErr_Clear();
+ result = PyString_FromStringAndSize(s, len);
+ }
+ }
+#else
+ result = PyString_FromStringAndSize(value->bytes, value->length);
+#endif
+ return result;
+ }
+
+ if (value->typePtr == app->BooleanType) {
+ result = value->internalRep.longValue ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+ }
+
+ if (value->typePtr == app->ByteArrayType) {
+ int size;
+ char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
+ return PyString_FromStringAndSize(data, size);
+ }
+
+ if (value->typePtr == app->DoubleType) {
+ return PyFloat_FromDouble(value->internalRep.doubleValue);
+ }
+
+ if (value->typePtr == app->IntType) {
+ return PyInt_FromLong(value->internalRep.longValue);
+ }
+
+ if (value->typePtr == app->ListType) {
+ int size;
+ int i, status;
+ PyObject *elem;
+ Tcl_Obj *tcl_elem;
+
+ status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
+ if (status == TCL_ERROR)
+ return Tkinter_Error(tkapp);
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ for (i = 0; i < size; i++) {
+ status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
+ value, i, &tcl_elem);
+ if (status == TCL_ERROR) {
+ Py_DECREF(result);
+ return Tkinter_Error(tkapp);
+ }
+ elem = FromObj(tkapp, tcl_elem);
+ if (!elem) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SetItem(result, i, elem);
+ }
+ return result;
+ }
+
+ if (value->typePtr == app->ProcBodyType) {
+ /* fall through: return tcl object. */
+ }
+
+ if (value->typePtr == app->StringType) {
+#ifdef Py_USING_UNICODE
+#if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
+ PyObject *result;
+ int size;
+ Tcl_UniChar *input;
+ Py_UNICODE *output;
+
+ size = Tcl_GetCharLength(value);
+ result = PyUnicode_FromUnicode(NULL, size);
+ if (!result)
+ return NULL;
+ input = Tcl_GetUnicode(value);
+ output = PyUnicode_AS_UNICODE(result);
+ while (size--)
+ *output++ = *input++;
+ return result;
+#else
+ return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
+ Tcl_GetCharLength(value));
+#endif
+#else
+ int size;
+ char *c;
+ c = Tcl_GetStringFromObj(value, &size);
+ return PyString_FromStringAndSize(c, size);
+#endif
+ }
+
+ return newPyTclObject(value);
+}
+
+/* This mutex synchronizes inter-thread command calls. */
+
+TCL_DECLARE_MUTEX(call_mutex)
+
+typedef struct Tkapp_CallEvent {
+ Tcl_Event ev; /* Must be first */
+ TkappObject *self;
+ PyObject *args;
+ int flags;
+ PyObject **res;
+ PyObject **exc_type, **exc_value, **exc_tb;
+ Tcl_Condition done;
+} Tkapp_CallEvent;
+
+void
+Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
+{
+ int i;
+ for (i = 0; i < objc; i++)
+ Tcl_DecrRefCount(objv[i]);
+ if (objv != objStore)
+ ckfree(FREECAST objv);
+}
+
+/* Convert Python objects to Tcl objects. This must happen in the
+ interpreter thread, which may or may not be the calling thread. */
+
+static Tcl_Obj**
+Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
+{
+ Tcl_Obj **objv = objStore;
+ int objc = 0, i;
+ if (args == NULL)
+ /* do nothing */;
+
+ else if (!PyTuple_Check(args)) {
+ objv[0] = AsObj(args);
+ if (objv[0] == 0)
+ goto finally;
+ objc = 1;
+ Tcl_IncrRefCount(objv[0]);
+ }
+ else {
+ objc = PyTuple_Size(args);
+
+ if (objc > ARGSZ) {
+ objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
+ if (objv == NULL) {
+ PyErr_NoMemory();
+ objc = 0;
+ goto finally;
+ }
+ }
+
+ for (i = 0; i < objc; i++) {
+ PyObject *v = PyTuple_GetItem(args, i);
+ if (v == Py_None) {
+ objc = i;
+ break;
+ }
+ objv[i] = AsObj(v);
+ if (!objv[i]) {
+ /* Reset objc, so it attempts to clear
+ objects only up to i. */
+ objc = i;
+ goto finally;
+ }
+ Tcl_IncrRefCount(objv[i]);
+ }
+ }
+ *pobjc = objc;
+ return objv;
+finally:
+ Tkapp_CallDeallocArgs(objv, objStore, objc);
+ return NULL;
+}
+
+/* Convert the results of a command call into a Python objects. */
+
+static PyObject*
+Tkapp_CallResult(TkappObject *self)
+{
+ PyObject *res = NULL;
+ if(self->wantobjects) {
+ Tcl_Obj *value = Tcl_GetObjResult(self->interp);
+ /* Not sure whether the IncrRef is necessary, but something
+ may overwrite the interpreter result while we are
+ converting it. */
+ Tcl_IncrRefCount(value);
+ res = FromObj((PyObject*)self, value);
+ Tcl_DecrRefCount(value);
+ } else {
+ const char *s = Tcl_GetStringResult(self->interp);
+ const char *p = s;
+
+ /* If the result contains any bytes with the top bit set,
+ it's UTF-8 and we should decode it to Unicode */
+#ifdef Py_USING_UNICODE
+ while (*p != '\0') {
+ if (*p & 0x80)
+ break;
+ p++;
+ }
+
+ if (*p == '\0')
+ res = PyString_FromStringAndSize(s, (int)(p-s));
+ else {
+ /* Convert UTF-8 to Unicode string */
+ p = strchr(p, '\0');
+ res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
+ if (res == NULL) {
+ PyErr_Clear();
+ res = PyString_FromStringAndSize(s, (int)(p-s));
+ }
+ }
+#else
+ p = strchr(p, '\0');
+ res = PyString_FromStringAndSize(s, (int)(p-s));
+#endif
+ }
+ return res;
+}
+
+/* Tkapp_CallProc is the event procedure that is executed in the context of
+ the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
+ hold the Python lock. */
+
+static int
+Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
+{
+ Tcl_Obj *objStore[ARGSZ];
+ Tcl_Obj **objv;
+ int objc;
+ int i;
+ ENTER_PYTHON
+ objv = Tkapp_CallArgs(e->args, objStore, &objc);
+ if (!objv) {
+ PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb);
+ *(e->res) = NULL;
+ }
+ LEAVE_PYTHON
+ if (!objv)
+ goto done;
+ i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags);
+ ENTER_PYTHON
+ if (i == TCL_ERROR) {
+ *(e->res) = NULL;
+ *(e->exc_type) = NULL;
+ *(e->exc_tb) = NULL;
+ *(e->exc_value) = PyObject_CallFunction(
+ Tkinter_TclError, "s",
+ Tcl_GetStringResult(e->self->interp));
+ }
+ else {
+ *(e->res) = Tkapp_CallResult(e->self);
+ }
+ LEAVE_PYTHON
+ done:
+ /* Wake up calling thread. */
+ Tcl_MutexLock(&call_mutex);
+ Tcl_ConditionNotify(&e->done);
+ Tcl_MutexUnlock(&call_mutex);
+ return 1;
+}
+
+/* This is the main entry point for calling a Tcl command.
+ It supports three cases, with regard to threading:
+ 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
+ the context of the calling thread.
+ 2. Tcl is threaded, caller of the command is in the interpreter thread:
+ Execute the command in the calling thread. Since the Tcl lock will
+ not be used, we can merge that with case 1.
+ 3. Tcl is threaded, caller is in a different thread: Must queue an event to
+ the interpreter thread. Allocation of Tcl objects needs to occur in the
+ interpreter thread, so we ship the PyObject* args to the target thread,
+ and perform processing there. */
+
+static PyObject *
+Tkapp_Call(PyObject *selfptr, PyObject *args)
+{
+ Tcl_Obj *objStore[ARGSZ];
+ Tcl_Obj **objv = NULL;
+ int objc, i;
+ PyObject *res = NULL;
+ TkappObject *self = (TkappObject*)selfptr;
+ /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
+ int flags = TCL_EVAL_DIRECT;
+
+#ifdef WITH_THREAD
+ if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+ /* We cannot call the command directly. Instead, we must
+ marshal the parameters to the interpreter thread. */
+ Tkapp_CallEvent *ev;
+ PyObject *exc_type, *exc_value, *exc_tb;
+ if (!WaitForMainloop(self))
+ return NULL;
+ ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
+ ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
+ ev->self = self;
+ ev->args = args;
+ ev->res = &res;
+ ev->exc_type = &exc_type;
+ ev->exc_value = &exc_value;
+ ev->exc_tb = &exc_tb;
+ ev->done = (Tcl_Condition)0;
+
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
+
+ if (res == NULL) {
+ if (exc_type)
+ PyErr_Restore(exc_type, exc_value, exc_tb);
+ else
+ PyErr_SetObject(Tkinter_TclError, exc_value);
+ }
+ }
+ else
+#endif
+ {
+
+ objv = Tkapp_CallArgs(args, objStore, &objc);
+ if (!objv)
+ return NULL;
+
+ ENTER_TCL
+
+ i = Tcl_EvalObjv(self->interp, objc, objv, flags);
+
+ ENTER_OVERLAP
+
+ if (i == TCL_ERROR)
+ Tkinter_Error(selfptr);
+ else
+ res = Tkapp_CallResult(self);
+
+ LEAVE_OVERLAP_TCL
+
+ Tkapp_CallDeallocArgs(objv, objStore, objc);
+ }
+ return res;
+}
+
+
+static PyObject *
+Tkapp_GlobalCall(PyObject *self, PyObject *args)
+{
+ /* Could do the same here as for Tkapp_Call(), but this is not used
+ much, so I can't be bothered. Unfortunately Tcl doesn't export a
+ way for the user to do what all its Global* variants do (save and
+ reset the scope pointer, call the local version, restore the saved
+ scope pointer). */
+
+ char *cmd;
+ PyObject *res = NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ cmd = Merge(args);
+ if (cmd) {
+ int err;
+ ENTER_TCL
+ err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
+ ENTER_OVERLAP
+ if (err == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = PyString_FromString(Tkapp_Result(self));
+ LEAVE_OVERLAP_TCL
+ ckfree(cmd);
+ }
+
+ return res;
+}
+
+static PyObject *
+Tkapp_Eval(PyObject *self, PyObject *args)
+{
+ char *script;
+ PyObject *res = NULL;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "s:eval", &script))
+ return NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ err = Tcl_Eval(Tkapp_Interp(self), script);
+ ENTER_OVERLAP
+ if (err == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = PyString_FromString(Tkapp_Result(self));
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_GlobalEval(PyObject *self, PyObject *args)
+{
+ char *script;
+ PyObject *res = NULL;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "s:globaleval", &script))
+ return NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ err = Tcl_GlobalEval(Tkapp_Interp(self), script);
+ ENTER_OVERLAP
+ if (err == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = PyString_FromString(Tkapp_Result(self));
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_EvalFile(PyObject *self, PyObject *args)
+{
+ char *fileName;
+ PyObject *res = NULL;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
+ return NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
+ ENTER_OVERLAP
+ if (err == TCL_ERROR)
+ res = Tkinter_Error(self);
+
+ else
+ res = PyString_FromString(Tkapp_Result(self));
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_Record(PyObject *self, PyObject *args)
+{
+ char *script;
+ PyObject *res = NULL;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "s", &script))
+ return NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
+ ENTER_OVERLAP
+ if (err == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = PyString_FromString(Tkapp_Result(self));
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
+{
+ char *msg;
+
+ if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
+ return NULL;
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
+ LEAVE_TCL
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+
+/** Tcl Variable **/
+
+TCL_DECLARE_MUTEX(var_mutex)
+
+typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
+typedef struct VarEvent {
+ Tcl_Event ev; /* must be first */
+ PyObject *self;
+ PyObject *args;
+ int flags;
+ EventFunc func;
+ PyObject **res;
+ PyObject **exc_type;
+ PyObject **exc_val;
+ Tcl_Condition cond;
+} VarEvent;
+
+static int
+varname_converter(PyObject *in, void *_out)
+{
+ char **out = (char**)_out;
+ if (PyString_Check(in)) {
+ *out = PyString_AsString(in);
+ return 1;
+ }
+ if (PyTclObject_Check(in)) {
+ *out = PyTclObject_TclString(in);
+ return 1;
+ }
+ /* XXX: Should give diagnostics. */
+ return 0;
+}
+
+void
+var_perform(VarEvent *ev)
+{
+ *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
+ if (!*(ev->res)) {
+ PyObject *exc, *val, *tb;
+ PyErr_Fetch(&exc, &val, &tb);
+ PyErr_NormalizeException(&exc, &val, &tb);
+ *(ev->exc_type) = exc;
+ *(ev->exc_val) = val;
+ Py_DECREF(tb);
+ }
+
+}
+
+static int
+var_proc(VarEvent* ev, int flags)
+{
+ ENTER_PYTHON
+ var_perform(ev);
+ Tcl_MutexLock(&var_mutex);
+ Tcl_ConditionNotify(&ev->cond);
+ Tcl_MutexUnlock(&var_mutex);
+ LEAVE_PYTHON
+ return 1;
+}
+
+static PyObject*
+var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
+{
+ TkappObject *self = (TkappObject*)selfptr;
+#ifdef WITH_THREAD
+ if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+ TkappObject *self = (TkappObject*)selfptr;
+ VarEvent *ev;
+ PyObject *res, *exc_type, *exc_val;
+
+ /* The current thread is not the interpreter thread. Marshal
+ the call to the interpreter thread, then wait for
+ completion. */
+ if (!WaitForMainloop(self))
+ return NULL;
+
+ ev = (VarEvent*)ckalloc(sizeof(VarEvent));
+
+ ev->self = selfptr;
+ ev->args = args;
+ ev->flags = flags;
+ ev->func = func;
+ ev->res = &res;
+ ev->exc_type = &exc_type;
+ ev->exc_val = &exc_val;
+ ev->cond = NULL;
+ ev->ev.proc = (Tcl_EventProc*)var_proc;
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
+ if (!res) {
+ PyErr_SetObject(exc_type, exc_val);
+ Py_DECREF(exc_type);
+ Py_DECREF(exc_val);
+ return NULL;
+ }
+ return res;
+ }
+#endif
+ /* Tcl is not threaded, or this is the interpreter thread. */
+ return func(selfptr, args, flags);
+}
+
+static PyObject *
+SetVar(PyObject *self, PyObject *args, int flags)
+{
+ char *name1, *name2;
+ PyObject *newValue;
+ PyObject *res = NULL;
+ Tcl_Obj *newval, *ok;
+
+ if (PyArg_ParseTuple(args, "O&O:setvar",
+ varname_converter, &name1, &newValue)) {
+ /* XXX Acquire tcl lock??? */
+ newval = AsObj(newValue);
+ if (newval == NULL)
+ return NULL;
+ ENTER_TCL
+ ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
+ newval, flags);
+ ENTER_OVERLAP
+ if (!ok)
+ Tkinter_Error(self);
+ else {
+ res = Py_None;
+ Py_INCREF(res);
+ }
+ LEAVE_OVERLAP_TCL
+ }
+ else {
+ PyErr_Clear();
+ if (PyArg_ParseTuple(args, "ssO:setvar",
+ &name1, &name2, &newValue)) {
+ /* XXX must hold tcl lock already??? */
+ newval = AsObj(newValue);
+ ENTER_TCL
+ ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
+ ENTER_OVERLAP
+ if (!ok)
+ Tkinter_Error(self);
+ else {
+ res = Py_None;
+ Py_INCREF(res);
+ }
+ LEAVE_OVERLAP_TCL
+ }
+ else {
+ return NULL;
+ }
+ }
+ return res;
+}
+
+static PyObject *
+Tkapp_SetVar(PyObject *self, PyObject *args)
+{
+ return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
+{
+ return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+
+static PyObject *
+GetVar(PyObject *self, PyObject *args, int flags)
+{
+ char *name1, *name2=NULL;
+ PyObject *res = NULL;
+ Tcl_Obj *tres;
+
+ if (!PyArg_ParseTuple(args, "O&|s:getvar",
+ varname_converter, &name1, &name2))
+ return NULL;
+
+ ENTER_TCL
+ tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
+ ENTER_OVERLAP
+ if (tres == NULL) {
+ PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
+ } else {
+ if (((TkappObject*)self)->wantobjects) {
+ res = FromObj(self, tres);
+ }
+ else {
+ res = PyString_FromString(Tcl_GetString(tres));
+ }
+ }
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_GetVar(PyObject *self, PyObject *args)
+{
+ return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
+{
+ return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+
+static PyObject *
+UnsetVar(PyObject *self, PyObject *args, int flags)
+{
+ char *name1, *name2=NULL;
+ int code;
+ PyObject *res = NULL;
+
+ if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
+ return NULL;
+
+ ENTER_TCL
+ code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
+ ENTER_OVERLAP
+ if (code == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else {
+ Py_INCREF(Py_None);
+ res = Py_None;
+ }
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_UnsetVar(PyObject *self, PyObject *args)
+{
+ return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
+{
+ return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+
+
+/** Tcl to Python **/
+
+static PyObject *
+Tkapp_GetInt(PyObject *self, PyObject *args)
+{
+ char *s;
+ int v;
+
+ if (PyTuple_Size(args) == 1) {
+ PyObject* o = PyTuple_GetItem(args, 0);
+ if (PyInt_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "s:getint", &s))
+ return NULL;
+ if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+ return Tkinter_Error(self);
+ return Py_BuildValue("i", v);
+}
+
+static PyObject *
+Tkapp_GetDouble(PyObject *self, PyObject *args)
+{
+ char *s;
+ double v;
+
+ if (PyTuple_Size(args) == 1) {
+ PyObject *o = PyTuple_GetItem(args, 0);
+ if (PyFloat_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "s:getdouble", &s))
+ return NULL;
+ if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+ return Tkinter_Error(self);
+ return Py_BuildValue("d", v);
+}
+
+static PyObject *
+Tkapp_GetBoolean(PyObject *self, PyObject *args)
+{
+ char *s;
+ int v;
+
+ if (PyTuple_Size(args) == 1) {
+ PyObject *o = PyTuple_GetItem(args, 0);
+ if (PyInt_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "s:getboolean", &s))
+ return NULL;
+ if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
+ return Tkinter_Error(self);
+ return PyBool_FromLong(v);
+}
+
+static PyObject *
+Tkapp_ExprString(PyObject *self, PyObject *args)
+{
+ char *s;
+ PyObject *res = NULL;
+ int retval;
+
+ if (!PyArg_ParseTuple(args, "s:exprstring", &s))
+ return NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ retval = Tcl_ExprString(Tkapp_Interp(self), s);
+ ENTER_OVERLAP
+ if (retval == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = Py_BuildValue("s", Tkapp_Result(self));
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_ExprLong(PyObject *self, PyObject *args)
+{
+ char *s;
+ PyObject *res = NULL;
+ int retval;
+ long v;
+
+ if (!PyArg_ParseTuple(args, "s:exprlong", &s))
+ return NULL;
+
+ CHECK_TCL_APPARTMENT;
+
+ ENTER_TCL
+ retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
+ ENTER_OVERLAP
+ if (retval == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = Py_BuildValue("l", v);
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_ExprDouble(PyObject *self, PyObject *args)
+{
+ char *s;
+ PyObject *res = NULL;
+ double v;
+ int retval;
+
+ if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
+ return NULL;
+ CHECK_TCL_APPARTMENT;
+ PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
+ ENTER_TCL
+ retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
+ ENTER_OVERLAP
+ PyFPE_END_PROTECT(retval)
+ if (retval == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = Py_BuildValue("d", v);
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+static PyObject *
+Tkapp_ExprBoolean(PyObject *self, PyObject *args)
+{
+ char *s;
+ PyObject *res = NULL;
+ int retval;
+ int v;
+
+ if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
+ return NULL;
+ CHECK_TCL_APPARTMENT;
+ ENTER_TCL
+ retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
+ ENTER_OVERLAP
+ if (retval == TCL_ERROR)
+ res = Tkinter_Error(self);
+ else
+ res = Py_BuildValue("i", v);
+ LEAVE_OVERLAP_TCL
+ return res;
+}
+
+
+
+static PyObject *
+Tkapp_SplitList(PyObject *self, PyObject *args)
+{
+ char *list;
+ int argc;
+ char **argv;
+ PyObject *v;
+ int i;
+
+ if (PyTuple_Size(args) == 1) {
+ v = PyTuple_GetItem(args, 0);
+ if (PyTuple_Check(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
+ return NULL;
+
+ if (Tcl_SplitList(Tkapp_Interp(self), list,
+ &argc, &argv) == TCL_ERROR) {
+ PyMem_Free(list);
+ return Tkinter_Error(self);
+ }
+
+ if (!(v = PyTuple_New(argc)))
+ goto finally;
+
+ for (i = 0; i < argc; i++) {
+ PyObject *s = PyString_FromString(argv[i]);
+ if (!s || PyTuple_SetItem(v, i, s)) {
+ Py_DECREF(v);
+ v = NULL;
+ goto finally;
+ }
+ }
+
+ finally:
+ ckfree(FREECAST argv);
+ PyMem_Free(list);
+ return v;
+}
+
+static PyObject *
+Tkapp_Split(PyObject *self, PyObject *args)
+{
+ PyObject *v;
+ char *list;
+
+ if (PyTuple_Size(args) == 1) {
+ PyObject* o = PyTuple_GetItem(args, 0);
+ if (PyTuple_Check(o)) {
+ o = SplitObj(o);
+ return o;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
+ return NULL;
+ v = Split(list);
+ PyMem_Free(list);
+ return v;
+}
+
+static PyObject *
+Tkapp_Merge(PyObject *self, PyObject *args)
+{
+ char *s = Merge(args);
+ PyObject *res = NULL;
+
+ if (s) {
+ res = PyString_FromString(s);
+ ckfree(s);
+ }
+
+ return res;
+}
+
+
+
+/** Tcl Command **/
+
+/* Client data struct */
+typedef struct {
+ PyObject *self;
+ PyObject *func;
+} PythonCmd_ClientData;
+
+static int
+PythonCmd_Error(Tcl_Interp *interp)
+{
+ errorInCmd = 1;
+ PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+ LEAVE_PYTHON
+ return TCL_ERROR;
+}
+
+/* This is the Tcl command that acts as a wrapper for Python
+ * function or method.
+ */
+static int
+PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
+{
+ PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
+ PyObject *self, *func, *arg, *res, *tmp;
+ int i, rv;
+ char *s;
+
+ ENTER_PYTHON
+
+ /* TBD: no error checking here since we know, via the
+ * Tkapp_CreateCommand() that the client data is a two-tuple
+ */
+ self = data->self;
+ func = data->func;
+
+ /* Create argument list (argv1, ..., argvN) */
+ if (!(arg = PyTuple_New(argc - 1)))
+ return PythonCmd_Error(interp);
+
+ for (i = 0; i < (argc - 1); i++) {
+ PyObject *s = PyString_FromString(argv[i + 1]);
+ if (!s || PyTuple_SetItem(arg, i, s)) {
+ Py_DECREF(arg);
+ return PythonCmd_Error(interp);
+ }
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(arg);
+
+ if (res == NULL)
+ return PythonCmd_Error(interp);
+
+ if (!(tmp = PyList_New(0))) {
+ Py_DECREF(res);
+ return PythonCmd_Error(interp);
+ }
+
+ s = AsString(res, tmp);
+ if (s == NULL) {
+ rv = PythonCmd_Error(interp);
+ }
+ else {
+ Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
+ rv = TCL_OK;
+ }
+
+ Py_DECREF(res);
+ Py_DECREF(tmp);
+
+ LEAVE_PYTHON
+
+ return rv;
+}
+
+static void
+PythonCmdDelete(ClientData clientData)
+{
+ PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
+
+ ENTER_PYTHON
+ Py_XDECREF(data->self);
+ Py_XDECREF(data->func);
+ PyMem_DEL(data);
+ LEAVE_PYTHON
+}
+
+
+
+
+TCL_DECLARE_MUTEX(command_mutex)
+
+typedef struct CommandEvent{
+ Tcl_Event ev;
+ Tcl_Interp* interp;
+ char *name;
+ int create;
+ int *status;
+ ClientData *data;
+ Tcl_Condition done;
+} CommandEvent;
+
+static int
+Tkapp_CommandProc(CommandEvent *ev, int flags)
+{
+ if (ev->create)
+ *ev->status = Tcl_CreateCommand(
+ ev->interp, ev->name, PythonCmd,
+ ev->data, PythonCmdDelete) == NULL;
+ else
+ *ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
+ Tcl_MutexLock(&command_mutex);
+ Tcl_ConditionNotify(&ev->done);
+ Tcl_MutexUnlock(&command_mutex);
+ return 1;
+}
+
+static PyObject *
+Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
+{
+ TkappObject *self = (TkappObject*)selfptr;
+ PythonCmd_ClientData *data;
+ char *cmdName;
+ PyObject *func;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError, "command not callable");
+ return NULL;
+ }
+
+#ifdef WITH_THREAD
+ if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
+ !WaitForMainloop(self))
+ return NULL;
+#endif
+
+ data = PyMem_NEW(PythonCmd_ClientData, 1);
+ if (!data)
+ return PyErr_NoMemory();
+ Py_INCREF(self);
+ Py_INCREF(func);
+ data->self = selfptr;
+ data->func = func;
+
+ if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+ CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
+ ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
+ ev->interp = self->interp;
+ ev->create = 1;
+ ev->name = cmdName;
+ ev->data = (ClientData)data;
+ ev->status = &err;
+ ev->done = NULL;
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
+ }
+ else {
+ ENTER_TCL
+ err = Tcl_CreateCommand(
+ Tkapp_Interp(self), cmdName, PythonCmd,
+ (ClientData)data, PythonCmdDelete) == NULL;
+ LEAVE_TCL
+ }
+ if (err) {
+ PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
+ PyMem_DEL(data);
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+
+static PyObject *
+Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
+{
+ TkappObject *self = (TkappObject*)selfptr;
+ char *cmdName;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
+ return NULL;
+ if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+ CommandEvent *ev;
+ ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
+ ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
+ ev->interp = self->interp;
+ ev->create = 0;
+ ev->name = cmdName;
+ ev->status = &err;
+ ev->done = NULL;
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
+ &command_mutex);
+ }
+ else {
+ ENTER_TCL
+ err = Tcl_DeleteCommand(self->interp, cmdName);
+ LEAVE_TCL
+ }
+ if (err == -1) {
+ PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+
+#ifdef HAVE_CREATEFILEHANDLER
+/** File Handler **/
+
+typedef struct _fhcdata {
+ PyObject *func;
+ PyObject *file;
+ int id;
+ struct _fhcdata *next;
+} FileHandler_ClientData;
+
+static FileHandler_ClientData *HeadFHCD;
+
+static FileHandler_ClientData *
+NewFHCD(PyObject *func, PyObject *file, int id)
+{
+ FileHandler_ClientData *p;
+ p = PyMem_NEW(FileHandler_ClientData, 1);
+ if (p != NULL) {
+ Py_XINCREF(func);
+ Py_XINCREF(file);
+ p->func = func;
+ p->file = file;
+ p->id = id;
+ p->next = HeadFHCD;
+ HeadFHCD = p;
+ }
+ return p;
+}
+
+static void
+DeleteFHCD(int id)
+{
+ FileHandler_ClientData *p, **pp;
+
+ pp = &HeadFHCD;
+ while ((p = *pp) != NULL) {
+ if (p->id == id) {
+ *pp = p->next;
+ Py_XDECREF(p->func);
+ Py_XDECREF(p->file);
+ PyMem_DEL(p);
+ }
+ else
+ pp = &p->next;
+ }
+}
+
+static void
+FileHandler(ClientData clientData, int mask)
+{
+ FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
+ PyObject *func, *file, *arg, *res;
+
+ ENTER_PYTHON
+ func = data->func;
+ file = data->file;
+
+ arg = Py_BuildValue("(Oi)", file, (long) mask);
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(arg);
+
+ if (res == NULL) {
+ errorInCmd = 1;
+ PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+ }
+ Py_XDECREF(res);
+ LEAVE_PYTHON
+}
+
+static PyObject *
+Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
+ /* args is (file, mask, func) */
+{
+ FileHandler_ClientData *data;
+ PyObject *file, *func;
+ int mask, tfile;
+
+ if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
+ &file, &mask, &func))
+ return NULL;
+
+#ifdef WITH_THREAD
+ if (!self && !tcl_lock) {
+ /* We don't have the Tcl lock since Tcl is threaded. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "_tkinter.createfilehandler not supported "
+ "for threaded Tcl");
+ return NULL;
+ }
+#endif
+
+ if (self) {
+ CHECK_TCL_APPARTMENT;
+ }
+
+ tfile = PyObject_AsFileDescriptor(file);
+ if (tfile < 0)
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError, "bad argument list");
+ return NULL;
+ }
+
+ data = NewFHCD(func, file, tfile);
+ if (data == NULL)
+ return NULL;
+
+ /* Ought to check for null Tcl_File object... */
+ ENTER_TCL
+ Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
+ LEAVE_TCL
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
+{
+ PyObject *file;
+ int tfile;
+
+ if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
+ return NULL;
+
+#ifdef WITH_THREAD
+ if (!self && !tcl_lock) {
+ /* We don't have the Tcl lock since Tcl is threaded. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "_tkinter.deletefilehandler not supported "
+ "for threaded Tcl");
+ return NULL;
+ }
+#endif
+
+ if (self) {
+ CHECK_TCL_APPARTMENT;
+ }
+
+ tfile = PyObject_AsFileDescriptor(file);
+ if (tfile < 0)
+ return NULL;
+
+ DeleteFHCD(tfile);
+
+ /* Ought to check for null Tcl_File object... */
+ ENTER_TCL
+ Tcl_DeleteFileHandler(tfile);
+ LEAVE_TCL
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_CREATEFILEHANDLER */
+
+
+/**** Tktt Object (timer token) ****/
+
+static PyTypeObject Tktt_Type;
+
+typedef struct {
+ PyObject_HEAD
+ Tcl_TimerToken token;
+ PyObject *func;
+} TkttObject;
+
+static PyObject *
+Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
+{
+ TkttObject *v = (TkttObject *)self;
+ PyObject *func = v->func;
+
+ if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
+ return NULL;
+ if (v->token != NULL) {
+ Tcl_DeleteTimerHandler(v->token);
+ v->token = NULL;
+ }
+ if (func != NULL) {
+ v->func = NULL;
+ Py_DECREF(func);
+ Py_DECREF(v); /* See Tktt_New() */
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef Tktt_methods[] =
+{
+ {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
+ {NULL, NULL}
+};
+
+static TkttObject *
+Tktt_New(PyObject *func)
+{
+ TkttObject *v;
+
+ v = PyObject_New(TkttObject, &Tktt_Type);
+ if (v == NULL)
+ return NULL;
+
+ Py_INCREF(func);
+ v->token = NULL;
+ v->func = func;
+
+ /* Extra reference, deleted when called or when handler is deleted */
+ Py_INCREF(v);
+ return v;
+}
+
+static void
+Tktt_Dealloc(PyObject *self)
+{
+ TkttObject *v = (TkttObject *)self;
+ PyObject *func = v->func;
+
+ Py_XDECREF(func);
+
+ PyObject_Del(self);
+}
+
+static PyObject *
+Tktt_Repr(PyObject *self)
+{
+ TkttObject *v = (TkttObject *)self;
+ char buf[100];
+
+ PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
+ v->func == NULL ? ", handler deleted" : "");
+ return PyString_FromString(buf);
+}
+
+static PyObject *
+Tktt_GetAttr(PyObject *self, char *name)
+{
+ return Py_FindMethod(Tktt_methods, self, name);
+}
+
+static PyTypeObject Tktt_Type =
+{
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size */
+ "tktimertoken", /*tp_name */
+ sizeof(TkttObject), /*tp_basicsize */
+ 0, /*tp_itemsize */
+ Tktt_Dealloc, /*tp_dealloc */
+ 0, /*tp_print */
+ Tktt_GetAttr, /*tp_getattr */
+ 0, /*tp_setattr */
+ 0, /*tp_compare */
+ Tktt_Repr, /*tp_repr */
+ 0, /*tp_as_number */
+ 0, /*tp_as_sequence */
+ 0, /*tp_as_mapping */
+ 0, /*tp_hash */
+};
+
+
+
+/** Timer Handler **/
+
+static void
+TimerHandler(ClientData clientData)
+{
+ TkttObject *v = (TkttObject *)clientData;
+ PyObject *func = v->func;
+ PyObject *res;
+
+ if (func == NULL)
+ return;
+
+ v->func = NULL;
+
+ ENTER_PYTHON
+
+ res = PyEval_CallObject(func, NULL);
+ Py_DECREF(func);
+ Py_DECREF(v); /* See Tktt_New() */
+
+ if (res == NULL) {
+ errorInCmd = 1;
+ PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
+ }
+ else
+ Py_DECREF(res);
+
+ LEAVE_PYTHON
+}
+
+static PyObject *
+Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
+{
+ int milliseconds;
+ PyObject *func;
+ TkttObject *v;
+
+ if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
+ &milliseconds, &func))
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError, "bad argument list");
+ return NULL;
+ }
+
+#ifdef WITH_THREAD
+ if (!self && !tcl_lock) {
+ /* We don't have the Tcl lock since Tcl is threaded. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "_tkinter.createtimerhandler not supported "
+ "for threaded Tcl");
+ return NULL;
+ }
+#endif
+
+ if (self) {
+ CHECK_TCL_APPARTMENT;
+ }
+
+ v = Tktt_New(func);
+ if (v) {
+ v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
+ (ClientData)v);
+ }
+
+ return (PyObject *) v;
+}
+
+
+/** Event Loop **/
+
+static PyObject *
+Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
+{
+ int threshold = 0;
+ TkappObject *self = (TkappObject*)selfptr;
+#ifdef WITH_THREAD
+ PyThreadState *tstate = PyThreadState_Get();
+#endif
+
+ if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
+ return NULL;
+
+#ifdef WITH_THREAD
+ if (!self && !tcl_lock) {
+ /* We don't have the Tcl lock since Tcl is threaded. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "_tkinter.mainloop not supported "
+ "for threaded Tcl");
+ return NULL;
+ }
+#endif
+
+ if (self) {
+ CHECK_TCL_APPARTMENT;
+ self->dispatching = 1;
+ }
+
+ quitMainLoop = 0;
+ while (Tk_GetNumMainWindows() > threshold &&
+ !quitMainLoop &&
+ !errorInCmd)
+ {
+ int result;
+
+#ifdef WITH_THREAD
+ if (self && self->threaded) {
+ /* Allow other Python threads to run. */
+ ENTER_TCL
+ result = Tcl_DoOneEvent(0);
+ LEAVE_TCL
+ }
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
+ tcl_tstate = tstate;
+ result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+ tcl_tstate = NULL;
+ if(tcl_lock)PyThread_release_lock(tcl_lock);
+ if (result == 0)
+ Sleep(Tkinter_busywaitinterval);
+ Py_END_ALLOW_THREADS
+ }
+#else
+ result = Tcl_DoOneEvent(0);
+#endif
+
+ if (PyErr_CheckSignals() != 0) {
+ if (self)
+ self->dispatching = 0;
+ return NULL;
+ }
+ if (result < 0)
+ break;
+ }
+ if (self)
+ self->dispatching = 0;
+ quitMainLoop = 0;
+
+ if (errorInCmd) {
+ errorInCmd = 0;
+ PyErr_Restore(excInCmd, valInCmd, trbInCmd);
+ excInCmd = valInCmd = trbInCmd = NULL;
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_DoOneEvent(PyObject *self, PyObject *args)
+{
+ int flags = 0;
+ int rv;
+
+ if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
+ return NULL;
+
+ ENTER_TCL
+ rv = Tcl_DoOneEvent(flags);
+ LEAVE_TCL
+ return Py_BuildValue("i", rv);
+}
+
+static PyObject *
+Tkapp_Quit(PyObject *self, PyObject *args)
+{
+
+ if (!PyArg_ParseTuple(args, ":quit"))
+ return NULL;
+
+ quitMainLoop = 1;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_InterpAddr(PyObject *self, PyObject *args)
+{
+
+ if (!PyArg_ParseTuple(args, ":interpaddr"))
+ return NULL;
+
+ return PyInt_FromLong((long)Tkapp_Interp(self));
+}
+
+static PyObject *
+Tkapp_TkInit(PyObject *self, PyObject *args)
+{
+ static int has_failed;
+ Tcl_Interp *interp = Tkapp_Interp(self);
+ Tk_Window main_window;
+ const char * _tk_exists = NULL;
+ int err;
+ main_window = Tk_MainWindow(interp);
+
+ /* In all current versions of Tk (including 8.4.13), Tk_Init
+ deadlocks on the second call when the first call failed.
+ To avoid the deadlock, we just refuse the second call through
+ a static variable. */
+ if (has_failed) {
+ PyErr_SetString(Tkinter_TclError,
+ "Calling Tk_Init again after a previous call failed might deadlock");
+ return NULL;
+ }
+
+ /* We want to guard against calling Tk_Init() multiple times */
+ CHECK_TCL_APPARTMENT;
+ ENTER_TCL
+ err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
+ ENTER_OVERLAP
+ if (err == TCL_ERROR) {
+ /* This sets an exception, but we cannot return right
+ away because we need to exit the overlap first. */
+ Tkinter_Error(self);
+ } else {
+ _tk_exists = Tkapp_Result(self);
+ }
+ LEAVE_OVERLAP_TCL
+ if (err == TCL_ERROR) {
+ return NULL;
+ }
+ if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
+ if (Tk_Init(interp) == TCL_ERROR) {
+ PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
+ has_failed = 1;
+ return NULL;
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_WantObjects(PyObject *self, PyObject *args)
+{
+
+ int wantobjects = -1;
+ if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
+ return NULL;
+ if (wantobjects == -1)
+ return PyBool_FromLong(((TkappObject*)self)->wantobjects);
+ ((TkappObject*)self)->wantobjects = wantobjects;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_WillDispatch(PyObject *self, PyObject *args)
+{
+
+ ((TkappObject*)self)->dispatching = 1;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/**** Tkapp Method List ****/
+
+static PyMethodDef Tkapp_methods[] =
+{
+ {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
+ {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
+ {"call", Tkapp_Call, METH_OLDARGS},
+ {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
+ {"eval", Tkapp_Eval, METH_VARARGS},
+ {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
+ {"evalfile", Tkapp_EvalFile, METH_VARARGS},
+ {"record", Tkapp_Record, METH_VARARGS},
+ {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
+ {"setvar", Tkapp_SetVar, METH_VARARGS},
+ {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
+ {"getvar", Tkapp_GetVar, METH_VARARGS},
+ {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
+ {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
+ {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
+ {"getint", Tkapp_GetInt, METH_VARARGS},
+ {"getdouble", Tkapp_GetDouble, METH_VARARGS},
+ {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
+ {"exprstring", Tkapp_ExprString, METH_VARARGS},
+ {"exprlong", Tkapp_ExprLong, METH_VARARGS},
+ {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
+ {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
+ {"splitlist", Tkapp_SplitList, METH_VARARGS},
+ {"split", Tkapp_Split, METH_VARARGS},
+ {"merge", Tkapp_Merge, METH_OLDARGS},
+ {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
+ {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
+#ifdef HAVE_CREATEFILEHANDLER
+ {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
+ {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
+#endif
+ {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
+ {"mainloop", Tkapp_MainLoop, METH_VARARGS},
+ {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
+ {"quit", Tkapp_Quit, METH_VARARGS},
+ {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
+ {"loadtk", Tkapp_TkInit, METH_NOARGS},
+ {NULL, NULL}
+};
+
+
+
+/**** Tkapp Type Methods ****/
+
+static void
+Tkapp_Dealloc(PyObject *self)
+{
+ /*CHECK_TCL_APPARTMENT;*/
+ ENTER_TCL
+ Tcl_DeleteInterp(Tkapp_Interp(self));
+ LEAVE_TCL
+ PyObject_Del(self);
+ DisableEventHook();
+}
+
+static PyObject *
+Tkapp_GetAttr(PyObject *self, char *name)
+{
+ return Py_FindMethod(Tkapp_methods, self, name);
+}
+
+static PyTypeObject Tkapp_Type =
+{
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size */
+ "tkapp", /*tp_name */
+ sizeof(TkappObject), /*tp_basicsize */
+ 0, /*tp_itemsize */
+ Tkapp_Dealloc, /*tp_dealloc */
+ 0, /*tp_print */
+ Tkapp_GetAttr, /*tp_getattr */
+ 0, /*tp_setattr */
+ 0, /*tp_compare */
+ 0, /*tp_repr */
+ 0, /*tp_as_number */
+ 0, /*tp_as_sequence */
+ 0, /*tp_as_mapping */
+ 0, /*tp_hash */
+};
+
+
+
+/**** Tkinter Module ****/
+
+typedef struct {
+ PyObject* tuple;
+ int size; /* current size */
+ int maxsize; /* allocated size */
+} FlattenContext;
+
+static int
+_bump(FlattenContext* context, int size)
+{
+ /* expand tuple to hold (at least) size new items.
+ return true if successful, false if an exception was raised */
+
+ int maxsize = context->maxsize * 2;
+
+ if (maxsize < context->size + size)
+ maxsize = context->size + size;
+
+ context->maxsize = maxsize;
+
+ return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
+}
+
+static int
+_flatten1(FlattenContext* context, PyObject* item, int depth)
+{
+ /* add tuple or list to argument tuple (recursively) */
+
+ int i, size;
+
+ if (depth > 1000) {
+ PyErr_SetString(PyExc_ValueError,
+ "nesting too deep in _flatten");
+ return 0;
+ } else if (PyList_Check(item)) {
+ size = PyList_GET_SIZE(item);
+ /* preallocate (assume no nesting) */
+ if (context->size + size > context->maxsize &&
+ !_bump(context, size))
+ return 0;
+ /* copy items to output tuple */
+ for (i = 0; i < size; i++) {
+ PyObject *o = PyList_GET_ITEM(item, i);
+ if (PyList_Check(o) || PyTuple_Check(o)) {
+ if (!_flatten1(context, o, depth + 1))
+ return 0;
+ } else if (o != Py_None) {
+ if (context->size + 1 > context->maxsize &&
+ !_bump(context, 1))
+ return 0;
+ Py_INCREF(o);
+ PyTuple_SET_ITEM(context->tuple,
+ context->size++, o);
+ }
+ }
+ } else if (PyTuple_Check(item)) {
+ /* same, for tuples */
+ size = PyTuple_GET_SIZE(item);
+ if (context->size + size > context->maxsize &&
+ !_bump(context, size))
+ return 0;
+ for (i = 0; i < size; i++) {
+ PyObject *o = PyTuple_GET_ITEM(item, i);
+ if (PyList_Check(o) || PyTuple_Check(o)) {
+ if (!_flatten1(context, o, depth + 1))
+ return 0;
+ } else if (o != Py_None) {
+ if (context->size + 1 > context->maxsize &&
+ !_bump(context, 1))
+ return 0;
+ Py_INCREF(o);
+ PyTuple_SET_ITEM(context->tuple,
+ context->size++, o);
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "argument must be sequence");
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject *
+Tkinter_Flatten(PyObject* self, PyObject* args)
+{
+ FlattenContext context;
+ PyObject* item;
+
+ if (!PyArg_ParseTuple(args, "O:_flatten", &item))
+ return NULL;
+
+ context.maxsize = PySequence_Size(item);
+ if (context.maxsize <= 0)
+ return PyTuple_New(0);
+
+ context.tuple = PyTuple_New(context.maxsize);
+ if (!context.tuple)
+ return NULL;
+
+ context.size = 0;
+
+ if (!_flatten1(&context, item,0))
+ return NULL;
+
+ if (_PyTuple_Resize(&context.tuple, context.size))
+ return NULL;
+
+ return context.tuple;
+}
+
+static PyObject *
+Tkinter_Create(PyObject *self, PyObject *args)
+{
+ char *screenName = NULL;
+ char *baseName = NULL;
+ char *className = NULL;
+ int interactive = 0;
+ int wantobjects = 0;
+ int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
+ int sync = 0; /* pass -sync to wish */
+ char *use = NULL; /* pass -use to wish */
+
+ baseName = strrchr(Py_GetProgramName(), '/');
+ if (baseName != NULL)
+ baseName++;
+ else
+ baseName = Py_GetProgramName();
+ className = "Tk";
+
+ if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
+ &screenName, &baseName, &className,
+ &interactive, &wantobjects, &wantTk,
+ &sync, &use))
+ return NULL;
+
+ return (PyObject *) Tkapp_New(screenName, baseName, className,
+ interactive, wantobjects, wantTk,
+ sync, use);
+}
+
+static PyObject *
+Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
+{
+ int new_val;
+ if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
+ return NULL;
+ if (new_val < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "busywaitinterval must be >= 0");
+ return NULL;
+ }
+ Tkinter_busywaitinterval = new_val;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char setbusywaitinterval_doc[] =
+"setbusywaitinterval(n) -> None\n\
+\n\
+Set the busy-wait interval in milliseconds between successive\n\
+calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
+It should be set to a divisor of the maximum time between\n\
+frames in an animation.";
+
+static PyObject *
+Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
+{
+ return PyInt_FromLong(Tkinter_busywaitinterval);
+}
+
+static char getbusywaitinterval_doc[] =
+"getbusywaitinterval() -> int\n\
+\n\
+Return the current busy-wait interval between successive\n\
+calls to Tcl_DoOneEvent in a threaded Python interpreter.";
+
+static PyMethodDef moduleMethods[] =
+{
+ {"_flatten", Tkinter_Flatten, METH_VARARGS},
+ {"create", Tkinter_Create, METH_VARARGS},
+#ifdef HAVE_CREATEFILEHANDLER
+ {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
+ {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
+#endif
+ {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
+ {"mainloop", Tkapp_MainLoop, METH_VARARGS},
+ {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
+ {"quit", Tkapp_Quit, METH_VARARGS},
+ {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
+ setbusywaitinterval_doc},
+ {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
+ METH_NOARGS, getbusywaitinterval_doc},
+ {NULL, NULL}
+};
+
+#ifdef WAIT_FOR_STDIN
+
+static int stdin_ready = 0;
+
+#ifndef MS_WINDOWS
+static void
+MyFileProc(void *clientData, int mask)
+{
+ stdin_ready = 1;
+}
+#endif
+
+#ifdef WITH_THREAD
+static PyThreadState *event_tstate = NULL;
+#endif
+
+static int
+EventHook(void)
+{
+#ifndef MS_WINDOWS
+ int tfile;
+#endif
+#ifdef WITH_THREAD
+ PyEval_RestoreThread(event_tstate);
+#endif
+ stdin_ready = 0;
+ errorInCmd = 0;
+#ifndef MS_WINDOWS
+ tfile = fileno(stdin);
+ Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
+#endif
+ while (!errorInCmd && !stdin_ready) {
+ int result;
+#ifdef MS_WINDOWS
+ if (_kbhit()) {
+ stdin_ready = 1;
+ break;
+ }
+#endif
+#if defined(WITH_THREAD) || defined(MS_WINDOWS)
+ Py_BEGIN_ALLOW_THREADS
+ if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
+ tcl_tstate = event_tstate;
+
+ result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+
+ tcl_tstate = NULL;
+ if(tcl_lock)PyThread_release_lock(tcl_lock);
+ if (result == 0)
+ Sleep(Tkinter_busywaitinterval);
+ Py_END_ALLOW_THREADS
+#else
+ result = Tcl_DoOneEvent(0);
+#endif
+
+ if (result < 0)
+ break;
+ }
+#ifndef MS_WINDOWS
+ Tcl_DeleteFileHandler(tfile);
+#endif
+ if (errorInCmd) {
+ errorInCmd = 0;
+ PyErr_Restore(excInCmd, valInCmd, trbInCmd);
+ excInCmd = valInCmd = trbInCmd = NULL;
+ PyErr_Print();
+ }
+#ifdef WITH_THREAD
+ PyEval_SaveThread();
+#endif
+ return 0;
+}
+
+#endif
+
+static void
+EnableEventHook(void)
+{
+#ifdef WAIT_FOR_STDIN
+ if (PyOS_InputHook == NULL) {
+#ifdef WITH_THREAD
+ event_tstate = PyThreadState_Get();
+#endif
+ PyOS_InputHook = EventHook;
+ }
+#endif
+}
+
+static void
+DisableEventHook(void)
+{
+#ifdef WAIT_FOR_STDIN
+ if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
+ PyOS_InputHook = NULL;
+ }
+#endif
+}
+
+
+/* all errors will be checked in one fell swoop in init_tkinter() */
+static void
+ins_long(PyObject *d, char *name, long val)
+{
+ PyObject *v = PyInt_FromLong(val);
+ if (v) {
+ PyDict_SetItemString(d, name, v);
+ Py_DECREF(v);
+ }
+}
+static void
+ins_string(PyObject *d, char *name, char *val)
+{
+ PyObject *v = PyString_FromString(val);
+ if (v) {
+ PyDict_SetItemString(d, name, v);
+ Py_DECREF(v);
+ }
+}
+
+
+PyMODINIT_FUNC
+init_tkinter(void)
+{
+ PyObject *m, *d;
+
+ Tkapp_Type.ob_type = &PyType_Type;
+
+#ifdef WITH_THREAD
+ tcl_lock = PyThread_allocate_lock();
+#endif
+
+ m = Py_InitModule("_tkinter", moduleMethods);
+ if (m == NULL)
+ return;
+
+ d = PyModule_GetDict(m);
+ Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
+ PyDict_SetItemString(d, "TclError", Tkinter_TclError);
+
+ ins_long(d, "READABLE", TCL_READABLE);
+ ins_long(d, "WRITABLE", TCL_WRITABLE);
+ ins_long(d, "EXCEPTION", TCL_EXCEPTION);
+ ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
+ ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
+ ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
+ ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
+ ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
+ ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
+ ins_string(d, "TK_VERSION", TK_VERSION);
+ ins_string(d, "TCL_VERSION", TCL_VERSION);
+
+ PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
+
+ Tktt_Type.ob_type = &PyType_Type;
+ PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
+
+ PyTclObject_Type.ob_type = &PyType_Type;
+ PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
+
+#ifdef TK_AQUA
+ /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
+ * start waking up. Note that Tcl_FindExecutable will do this, this
+ * code must be above it! The original warning from
+ * tkMacOSXAppInit.c is copied below.
+ *
+ * NB - You have to swap in the Tk Notifier BEFORE you start up the
+ * Tcl interpreter for now. It probably should work to do this
+ * in the other order, but for now it doesn't seem to.
+ *
+ */
+ Tk_MacOSXSetupTkNotifier();
+#endif
+
+
+ /* This helps the dynamic loader; in Unicode aware Tcl versions
+ it also helps Tcl find its encodings. */
+ Tcl_FindExecutable(Py_GetProgramName());
+
+ if (PyErr_Occurred())
+ return;
+
+#if 0
+ /* This was not a good idea; through <Destroy> bindings,
+ Tcl_Finalize() may invoke Python code but at that point the
+ interpreter and thread state have already been destroyed! */
+ Py_AtExit(Tcl_Finalize);
+#endif
+
+}
diff --git a/sys/src/cmd/python/Modules/_typesmodule.c b/sys/src/cmd/python/Modules/_typesmodule.c
new file mode 100644
index 000000000..5a6f2b980
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_typesmodule.c
@@ -0,0 +1,94 @@
+/* This extension module exposes some types that are only available at the
+ * C level. It should not be used directly, but instead through the Python
+ * level types modules, which imports this.
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+typedef struct
+{
+ PyObject_HEAD
+ int member;
+} Helper;
+
+static PyMemberDef helper_members[] = {
+ { "member", T_INT, offsetof(Helper, member), READONLY,
+ PyDoc_STR("A member descriptor")
+ },
+ { NULL }
+};
+
+static PyObject *
+helper_getter(Helper *self, void *unused)
+{
+ Py_RETURN_NONE;
+}
+
+static PyGetSetDef helper_getset[] = {
+ { "getter", (getter)helper_getter, NULL,
+ PyDoc_STR("A getset descriptor"),
+ },
+ { NULL }
+};
+
+static PyTypeObject HelperType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "_types.Helper", /* tp_name */
+ sizeof(Helper), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ helper_members, /* tp_members */
+ helper_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+};
+
+PyMODINIT_FUNC
+init_types(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("_types", NULL, "A types module helper");
+ if (!m)
+ return;
+
+ if (PyType_Ready(&HelperType) < 0)
+ return;
+
+ Py_INCREF(&HelperType);
+ PyModule_AddObject(m, "Helper", (PyObject *)&HelperType);
+}
+
+
diff --git a/sys/src/cmd/python/Modules/_weakref.c b/sys/src/cmd/python/Modules/_weakref.c
new file mode 100644
index 000000000..1712f12c0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/_weakref.c
@@ -0,0 +1,112 @@
+#include "Python.h"
+
+
+#define GET_WEAKREFS_LISTPTR(o) \
+ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
+
+
+PyDoc_STRVAR(weakref_getweakrefcount__doc__,
+"getweakrefcount(object) -- return the number of weak references\n"
+"to 'object'.");
+
+static PyObject *
+weakref_getweakrefcount(PyObject *self, PyObject *object)
+{
+ PyObject *result = NULL;
+
+ if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) {
+ PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
+
+ result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list));
+ }
+ else
+ result = PyInt_FromLong(0);
+
+ return result;
+}
+
+
+PyDoc_STRVAR(weakref_getweakrefs__doc__,
+"getweakrefs(object) -- return a list of all weak reference objects\n"
+"that point to 'object'.");
+
+static PyObject *
+weakref_getweakrefs(PyObject *self, PyObject *object)
+{
+ PyObject *result = NULL;
+
+ if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) {
+ PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
+ Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
+
+ result = PyList_New(count);
+ if (result != NULL) {
+ PyWeakReference *current = *list;
+ Py_ssize_t i;
+ for (i = 0; i < count; ++i) {
+ PyList_SET_ITEM(result, i, (PyObject *) current);
+ Py_INCREF(current);
+ current = current->wr_next;
+ }
+ }
+ }
+ else {
+ result = PyList_New(0);
+ }
+ return result;
+}
+
+
+PyDoc_STRVAR(weakref_proxy__doc__,
+"proxy(object[, callback]) -- create a proxy object that weakly\n"
+"references 'object'. 'callback', if given, is called with a\n"
+"reference to the proxy when 'object' is about to be finalized.");
+
+static PyObject *
+weakref_proxy(PyObject *self, PyObject *args)
+{
+ PyObject *object;
+ PyObject *callback = NULL;
+ PyObject *result = NULL;
+
+ if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) {
+ result = PyWeakref_NewProxy(object, callback);
+ }
+ return result;
+}
+
+
+static PyMethodDef
+weakref_functions[] = {
+ {"getweakrefcount", weakref_getweakrefcount, METH_O,
+ weakref_getweakrefcount__doc__},
+ {"getweakrefs", weakref_getweakrefs, METH_O,
+ weakref_getweakrefs__doc__},
+ {"proxy", weakref_proxy, METH_VARARGS,
+ weakref_proxy__doc__},
+ {NULL, NULL, 0, NULL}
+};
+
+
+PyMODINIT_FUNC
+init_weakref(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("_weakref", weakref_functions,
+ "Weak-reference support module.");
+ if (m != NULL) {
+ Py_INCREF(&_PyWeakref_RefType);
+ PyModule_AddObject(m, "ref",
+ (PyObject *) &_PyWeakref_RefType);
+ Py_INCREF(&_PyWeakref_RefType);
+ PyModule_AddObject(m, "ReferenceType",
+ (PyObject *) &_PyWeakref_RefType);
+ Py_INCREF(&_PyWeakref_ProxyType);
+ PyModule_AddObject(m, "ProxyType",
+ (PyObject *) &_PyWeakref_ProxyType);
+ Py_INCREF(&_PyWeakref_CallableProxyType);
+ PyModule_AddObject(m, "CallableProxyType",
+ (PyObject *) &_PyWeakref_CallableProxyType);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/addrinfo.h b/sys/src/cmd/python/Modules/addrinfo.h
new file mode 100644
index 000000000..6f67a2e95
--- /dev/null
+++ b/sys/src/cmd/python/Modules/addrinfo.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HAVE_GETADDRINFO
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+#ifdef EAI_ADDRFAMILY
+/* If this is defined, there is a conflicting implementation
+ in the C library, which can't be used for some reason.
+ Make sure it won't interfere with this emulation. */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+#undef getaddrinfo
+#define getaddrinfo fake_getaddrinfo
+#endif /* EAI_ADDRFAMILY */
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#ifdef AI_PASSIVE
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+#undef AI_MASK
+#undef AI_ALL
+#undef AI_V4MAPPED_CFG
+#undef AI_ADDRCONFIG
+#undef AI_V4MAPPED
+#undef AI_DEFAULT
+#endif /* AI_PASSIVE */
+
+#define AI_PASSIVE 0x00000001 /* get address to use bind() */
+#define AI_CANONNAME 0x00000002 /* fill ai_canonname */
+#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
+/* valid flags for addrinfo */
+#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
+
+#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
+#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
+#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */
+#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */
+/* special recommended flags for getipnodebyname */
+#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
+
+#endif /* !HAVE_GETADDRINFO */
+
+#ifndef HAVE_GETNAMEINFO
+
+/*
+ * Constants for getnameinfo()
+ */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+#endif /* !NI_MAXHOST */
+
+/*
+ * Flag values for getnameinfo()
+ */
+#ifndef NI_NOFQDN
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#endif /* !NI_NOFQDN */
+
+#endif /* !HAVE_GETNAMEINFO */
+
+#ifndef HAVE_ADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+#endif /* !HAVE_ADDRINFO */
+
+#ifndef HAVE_SOCKADDR_STORAGE
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define _SS_MAXSIZE 128
+#ifdef HAVE_LONG_LONG
+#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG))
+#else
+#define _SS_ALIGNSIZE (sizeof(double))
+#endif /* HAVE_LONG_LONG */
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2)
+#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+#ifdef HAVE_SOCKADDR_SA_LEN
+ unsigned char ss_len; /* address length */
+ unsigned char ss_family; /* address family */
+#else
+ unsigned short ss_family; /* address family */
+#endif /* HAVE_SOCKADDR_SA_LEN */
+ char __ss_pad1[_SS_PAD1SIZE];
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG __ss_align; /* force desired structure storage alignment */
+#else
+ double __ss_align; /* force desired structure storage alignment */
+#endif /* HAVE_LONG_LONG */
+ char __ss_pad2[_SS_PAD2SIZE];
+};
+#endif /* !HAVE_SOCKADDR_STORAGE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void freehostent Py_PROTO((struct hostent *));
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/src/cmd/python/Modules/almodule.c b/sys/src/cmd/python/Modules/almodule.c
new file mode 100644
index 000000000..0a45d2e0c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/almodule.c
@@ -0,0 +1,3226 @@
+
+#define OLD_INTERFACE /* define for pre-Irix 6 interface */
+
+#include "Python.h"
+#include "stringobject.h"
+#include <audio.h>
+#include <stdarg.h>
+
+#ifndef AL_NO_ELEM
+#ifndef OLD_INTERFACE
+#define OLD_INTERFACE
+#endif /* OLD_INTERFACE */
+#endif /* AL_NO_ELEM */
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type port */
+
+typedef struct {
+ PyObject_HEAD
+ /* XXXX Add your own stuff here */
+ ALport port;
+} alpobject;
+
+static PyTypeObject Alptype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+/* Declarations for objects of type config */
+
+typedef struct {
+ PyObject_HEAD
+ /* XXXX Add your own stuff here */
+ ALconfig config;
+} alcobject;
+
+static PyTypeObject Alctype;
+
+
+static void
+ErrorHandler(long code, const char *fmt, ...)
+{
+ va_list args;
+ char buf[128];
+
+ va_start(args, fmt);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+ PyErr_SetString(ErrorObject, buf);
+}
+
+#ifdef AL_NO_ELEM /* IRIX 6 */
+
+static PyObject *
+param2python(int resource, int param, ALvalue value, ALparamInfo *pinfo)
+{
+ ALparamInfo info;
+
+ if (pinfo == NULL) {
+ pinfo = &info;
+ if (alGetParamInfo(resource, param, &info) < 0)
+ return NULL;
+ }
+ switch (pinfo->elementType) {
+ case AL_PTR_ELEM:
+ /* XXXX don't know how to handle this */
+ case AL_NO_ELEM:
+ Py_INCREF(Py_None);
+ return Py_None;
+ case AL_INT32_ELEM:
+ case AL_RESOURCE_ELEM:
+ case AL_ENUM_ELEM:
+ return PyInt_FromLong((long) value.i);
+ case AL_INT64_ELEM:
+ return PyLong_FromLongLong(value.ll);
+ case AL_FIXED_ELEM:
+ return PyFloat_FromDouble(alFixedToDouble(value.ll));
+ case AL_CHAR_ELEM:
+ if (value.ptr == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString((char *) value.ptr);
+ default:
+ PyErr_SetString(ErrorObject, "unknown element type");
+ return NULL;
+ }
+}
+
+static int
+python2elem(PyObject *item, void *ptr, int elementType)
+{
+ switch (elementType) {
+ case AL_INT32_ELEM:
+ case AL_RESOURCE_ELEM:
+ case AL_ENUM_ELEM:
+ if (!PyInt_Check(item)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ *((int *) ptr) = PyInt_AsLong(item);
+ break;
+ case AL_INT64_ELEM:
+ if (PyInt_Check(item))
+ *((long long *) ptr) = PyInt_AsLong(item);
+ else if (PyLong_Check(item))
+ *((long long *) ptr) = PyLong_AsLongLong(item);
+ else {
+ PyErr_BadArgument();
+ return -1;
+ }
+ break;
+ case AL_FIXED_ELEM:
+ if (PyInt_Check(item))
+ *((long long *) ptr) = alDoubleToFixed((double) PyInt_AsLong(item));
+ else if (PyFloat_Check(item))
+ *((long long *) ptr) = alDoubleToFixed(PyFloat_AsDouble(item));
+ else {
+ PyErr_BadArgument();
+ return -1;
+ }
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "unknown element type");
+ return -1;
+ }
+ return 0;
+}
+
+static int
+python2param(int resource, ALpv *param, PyObject *value, ALparamInfo *pinfo)
+{
+ ALparamInfo info;
+ int i, stepsize;
+ PyObject *item;
+
+ if (pinfo == NULL) {
+ pinfo = &info;
+ if (alGetParamInfo(resource, param->param, &info) < 0)
+ return -1;
+ }
+ switch (pinfo->valueType) {
+ case AL_STRING_VAL:
+ if (pinfo->elementType != AL_CHAR_ELEM) {
+ PyErr_SetString(ErrorObject, "unknown element type");
+ return -1;
+ }
+ if (!PyString_Check(value)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ param->value.ptr = PyString_AS_STRING(value);
+ param->sizeIn = PyString_GET_SIZE(value)+1; /*account for NUL*/
+ break;
+ case AL_SET_VAL:
+ case AL_VECTOR_VAL:
+ if (!PyList_Check(value) && !PyTuple_Check(value)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ switch (pinfo->elementType) {
+ case AL_INT32_ELEM:
+ case AL_RESOURCE_ELEM:
+ case AL_ENUM_ELEM:
+ param->sizeIn = PySequence_Size(value);
+ param->value.ptr = PyMem_NEW(int, param->sizeIn);
+ stepsize = sizeof(int);
+ break;
+ case AL_INT64_ELEM:
+ case AL_FIXED_ELEM:
+ param->sizeIn = PySequence_Size(value);
+ param->value.ptr = PyMem_NEW(long long, param->sizeIn);
+ stepsize = sizeof(long long);
+ break;
+ }
+ for (i = 0; i < param->sizeIn; i++) {
+ item = PySequence_GetItem(value, i);
+ if (python2elem(item, (void *) ((char *) param->value.ptr + i*stepsize), pinfo->elementType) < 0) {
+ PyMem_DEL(param->value.ptr);
+ return -1;
+ }
+ }
+ break;
+ case AL_SCALAR_VAL:
+ switch (pinfo->elementType) {
+ case AL_INT32_ELEM:
+ case AL_RESOURCE_ELEM:
+ case AL_ENUM_ELEM:
+ return python2elem(value, (void *) &param->value.i,
+ pinfo->elementType);
+ case AL_INT64_ELEM:
+ case AL_FIXED_ELEM:
+ return python2elem(value, (void *) &param->value.ll,
+ pinfo->elementType);
+ default:
+ PyErr_SetString(ErrorObject, "unknown element type");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+python2params(int resource1, int resource2, PyObject *list, ALpv **pvsp, ALparamInfo **pinfop)
+{
+ PyObject *item;
+ ALpv *pvs;
+ ALparamInfo *pinfo;
+ int npvs, i;
+
+ npvs = PyList_Size(list);
+ pvs = PyMem_NEW(ALpv, npvs);
+ pinfo = PyMem_NEW(ALparamInfo, npvs);
+ for (i = 0; i < npvs; i++) {
+ item = PyList_GetItem(list, i);
+ if (!PyArg_ParseTuple(item, "iO", &pvs[i].param, &item))
+ goto error;
+ if (alGetParamInfo(resource1, pvs[i].param, &pinfo[i]) < 0 &&
+ alGetParamInfo(resource2, pvs[i].param, &pinfo[i]) < 0)
+ goto error;
+ if (python2param(resource1, &pvs[i], item, &pinfo[i]) < 0)
+ goto error;
+ }
+
+ *pvsp = pvs;
+ *pinfop = pinfo;
+ return npvs;
+
+ error:
+ /* XXXX we should clean up everything */
+ if (pvs)
+ PyMem_DEL(pvs);
+ if (pinfo)
+ PyMem_DEL(pinfo);
+ return -1;
+}
+
+/* -------------------------------------------------------- */
+
+
+static PyObject *
+SetConfig(alcobject *self, PyObject *args, int (*func)(ALconfig, int))
+{
+ int par;
+
+ if (!PyArg_ParseTuple(args, "i:SetConfig", &par))
+ return NULL;
+
+ if ((*func)(self->config, par) == -1)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+GetConfig(alcobject *self, PyObject *args, int (*func)(ALconfig))
+{
+ int par;
+
+ if (!PyArg_ParseTuple(args, ":GetConfig"))
+ return NULL;
+
+ if ((par = (*func)(self->config)) == -1)
+ return NULL;
+
+ return PyInt_FromLong((long) par);
+}
+
+PyDoc_STRVAR(alc_SetWidth__doc__,
+"alSetWidth: set the wordsize for integer audio data.");
+
+static PyObject *
+alc_SetWidth(alcobject *self, PyObject *args)
+{
+ return SetConfig(self, args, alSetWidth);
+}
+
+
+PyDoc_STRVAR(alc_GetWidth__doc__,
+"alGetWidth: get the wordsize for integer audio data.");
+
+static PyObject *
+alc_GetWidth(alcobject *self, PyObject *args)
+{
+ return GetConfig(self, args, alGetWidth);
+}
+
+
+PyDoc_STRVAR(alc_SetSampFmt__doc__,
+"alSetSampFmt: set the sample format setting in an audio ALconfig "
+"structure.");
+
+static PyObject *
+alc_SetSampFmt(alcobject *self, PyObject *args)
+{
+ return SetConfig(self, args, alSetSampFmt);
+}
+
+
+PyDoc_STRVAR(alc_GetSampFmt__doc__,
+"alGetSampFmt: get the sample format setting in an audio ALconfig "
+"structure.");
+
+static PyObject *
+alc_GetSampFmt(alcobject *self, PyObject *args)
+{
+ return GetConfig(self, args, alGetSampFmt);
+}
+
+
+PyDoc_STRVAR(alc_SetChannels__doc__,
+"alSetChannels: set the channel settings in an audio ALconfig.");
+
+static PyObject *
+alc_SetChannels(alcobject *self, PyObject *args)
+{
+ return SetConfig(self, args, alSetChannels);
+}
+
+
+PyDoc_STRVAR(alc_GetChannels__doc__,
+"alGetChannels: get the channel settings in an audio ALconfig.");
+
+static PyObject *
+alc_GetChannels(alcobject *self, PyObject *args)
+{
+ return GetConfig(self, args, alGetChannels);
+}
+
+
+PyDoc_STRVAR(alc_SetFloatMax__doc__,
+"alSetFloatMax: set the maximum value of floating point sample data.");
+
+static PyObject *
+alc_SetFloatMax(alcobject *self, PyObject *args)
+{
+ double maximum_value;
+
+ if (!PyArg_ParseTuple(args, "d:SetFloatMax", &maximum_value))
+ return NULL;
+ if (alSetFloatMax(self->config, maximum_value) < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(alc_GetFloatMax__doc__,
+"alGetFloatMax: get the maximum value of floating point sample data.");
+
+static PyObject *
+alc_GetFloatMax(alcobject *self, PyObject *args)
+{
+ double maximum_value;
+
+ if (!PyArg_ParseTuple(args, ":GetFloatMax"))
+ return NULL;
+ if ((maximum_value = alGetFloatMax(self->config)) == 0)
+ return NULL;
+ return PyFloat_FromDouble(maximum_value);
+}
+
+
+PyDoc_STRVAR(alc_SetDevice__doc__,
+"alSetDevice: set the device setting in an audio ALconfig structure.");
+
+static PyObject *
+alc_SetDevice(alcobject *self, PyObject *args)
+{
+ return SetConfig(self, args, alSetDevice);
+}
+
+
+PyDoc_STRVAR(alc_GetDevice__doc__,
+"alGetDevice: get the device setting in an audio ALconfig structure.");
+
+static PyObject *
+alc_GetDevice(alcobject *self, PyObject *args)
+{
+ return GetConfig(self, args, alGetDevice);
+}
+
+
+PyDoc_STRVAR(alc_SetQueueSize__doc__,
+"alSetQueueSize: set audio port buffer size.");
+
+static PyObject *
+alc_SetQueueSize(alcobject *self, PyObject *args)
+{
+ return SetConfig(self, args, alSetQueueSize);
+}
+
+
+PyDoc_STRVAR(alc_GetQueueSize__doc__,
+"alGetQueueSize: get audio port buffer size.");
+
+static PyObject *
+alc_GetQueueSize(alcobject *self, PyObject *args)
+{
+ return GetConfig(self, args, alGetQueueSize);
+}
+
+#endif /* AL_NO_ELEM */
+
+static PyObject *
+setconfig(alcobject *self, PyObject *args, int (*func)(ALconfig, long))
+{
+ long par;
+
+ if (!PyArg_ParseTuple(args, "l:SetConfig", &par))
+ return NULL;
+
+ if ((*func)(self->config, par) == -1)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+getconfig(alcobject *self, PyObject *args, long (*func)(ALconfig))
+{
+ long par;
+
+ if (!PyArg_ParseTuple(args, ":GetConfig"))
+ return NULL;
+
+ if ((par = (*func)(self->config)) == -1)
+ return NULL;
+
+ return PyInt_FromLong((long) par);
+}
+
+static PyObject *
+alc_setqueuesize (alcobject *self, PyObject *args)
+{
+ return setconfig(self, args, ALsetqueuesize);
+}
+
+static PyObject *
+alc_getqueuesize (alcobject *self, PyObject *args)
+{
+ return getconfig(self, args, ALgetqueuesize);
+}
+
+static PyObject *
+alc_setwidth (alcobject *self, PyObject *args)
+{
+ return setconfig(self, args, ALsetwidth);
+}
+
+static PyObject *
+alc_getwidth (alcobject *self, PyObject *args)
+{
+ return getconfig(self, args, ALgetwidth);
+}
+
+static PyObject *
+alc_getchannels (alcobject *self, PyObject *args)
+{
+ return getconfig(self, args, ALgetchannels);
+}
+
+static PyObject *
+alc_setchannels (alcobject *self, PyObject *args)
+{
+ return setconfig(self, args, ALsetchannels);
+}
+
+#ifdef AL_405
+
+static PyObject *
+alc_getsampfmt (alcobject *self, PyObject *args)
+{
+ return getconfig(self, args, ALgetsampfmt);
+}
+
+static PyObject *
+alc_setsampfmt (alcobject *self, PyObject *args)
+{
+ return setconfig(self, args, ALsetsampfmt);
+}
+
+static PyObject *
+alc_getfloatmax(alcobject *self, PyObject *args)
+{
+ double arg;
+
+ if (!PyArg_ParseTuple(args, ":GetFloatMax"))
+ return 0;
+ if ((arg = ALgetfloatmax(self->config)) == 0)
+ return NULL;
+ return PyFloat_FromDouble(arg);
+}
+
+static PyObject *
+alc_setfloatmax(alcobject *self, PyObject *args)
+{
+ double arg;
+
+ if (!PyArg_ParseTuple(args, "d:SetFloatMax", &arg))
+ return 0;
+ if (ALsetfloatmax(self->config, arg) == -1)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* AL_405 */
+
+static struct PyMethodDef alc_methods[] = {
+#ifdef AL_NO_ELEM /* IRIX 6 */
+ {"SetWidth", (PyCFunction)alc_SetWidth, METH_VARARGS, alc_SetWidth__doc__},
+ {"GetWidth", (PyCFunction)alc_GetWidth, METH_VARARGS, alc_GetWidth__doc__},
+ {"SetSampFmt", (PyCFunction)alc_SetSampFmt, METH_VARARGS, alc_SetSampFmt__doc__},
+ {"GetSampFmt", (PyCFunction)alc_GetSampFmt, METH_VARARGS, alc_GetSampFmt__doc__},
+ {"SetChannels", (PyCFunction)alc_SetChannels, METH_VARARGS, alc_SetChannels__doc__},
+ {"GetChannels", (PyCFunction)alc_GetChannels, METH_VARARGS, alc_GetChannels__doc__},
+ {"SetFloatMax", (PyCFunction)alc_SetFloatMax, METH_VARARGS, alc_SetFloatMax__doc__},
+ {"GetFloatMax", (PyCFunction)alc_GetFloatMax, METH_VARARGS, alc_GetFloatMax__doc__},
+ {"SetDevice", (PyCFunction)alc_SetDevice, METH_VARARGS, alc_SetDevice__doc__},
+ {"GetDevice", (PyCFunction)alc_GetDevice, METH_VARARGS, alc_GetDevice__doc__},
+ {"SetQueueSize", (PyCFunction)alc_SetQueueSize, METH_VARARGS, alc_SetQueueSize__doc__},
+ {"GetQueueSize", (PyCFunction)alc_GetQueueSize, METH_VARARGS, alc_GetQueueSize__doc__},
+#endif /* AL_NO_ELEM */
+ {"getqueuesize", (PyCFunction)alc_getqueuesize, METH_VARARGS},
+ {"setqueuesize", (PyCFunction)alc_setqueuesize, METH_VARARGS},
+ {"getwidth", (PyCFunction)alc_getwidth, METH_VARARGS},
+ {"setwidth", (PyCFunction)alc_setwidth, METH_VARARGS},
+ {"getchannels", (PyCFunction)alc_getchannels, METH_VARARGS},
+ {"setchannels", (PyCFunction)alc_setchannels, METH_VARARGS},
+#ifdef AL_405
+ {"getsampfmt", (PyCFunction)alc_getsampfmt, METH_VARARGS},
+ {"setsampfmt", (PyCFunction)alc_setsampfmt, METH_VARARGS},
+ {"getfloatmax", (PyCFunction)alc_getfloatmax, METH_VARARGS},
+ {"setfloatmax", (PyCFunction)alc_setfloatmax, METH_VARARGS},
+#endif /* AL_405 */
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+
+static PyObject *
+newalcobject(ALconfig config)
+{
+ alcobject *self;
+
+ self = PyObject_New(alcobject, &Alctype);
+ if (self == NULL)
+ return NULL;
+ /* XXXX Add your own initializers here */
+ self->config = config;
+ return (PyObject *) self;
+}
+
+
+static void
+alc_dealloc(alcobject *self)
+{
+ /* XXXX Add your own cleanup code here */
+#ifdef AL_NO_ELEM /* IRIX 6 */
+ (void) alFreeConfig(self->config); /* ignore errors */
+#else
+ (void) ALfreeconfig(self->config); /* ignore errors */
+#endif
+ PyObject_Del(self);
+}
+
+static PyObject *
+alc_getattr(alcobject *self, char *name)
+{
+ /* XXXX Add your own getattr code here */
+ return Py_FindMethod(alc_methods, (PyObject *)self, name);
+}
+
+PyDoc_STRVAR(Alctype__doc__, "");
+
+static PyTypeObject Alctype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "al.config", /*tp_name*/
+ sizeof(alcobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)alc_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)alc_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ Alctype__doc__ /* Documentation string */
+};
+
+/* End of code for config objects */
+/* ---------------------------------------------------------------- */
+
+#ifdef AL_NO_ELEM /* IRIX 6 */
+
+PyDoc_STRVAR(alp_SetConfig__doc__,
+"alSetConfig: set the ALconfig of an audio ALport.");
+
+static PyObject *
+alp_SetConfig(alpobject *self, PyObject *args)
+{
+ alcobject *config;
+ if (!PyArg_ParseTuple(args, "O!:SetConfig", &Alctype, &config))
+ return NULL;
+ if (alSetConfig(self->port, config->config) < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_GetConfig__doc__,
+"alGetConfig: get the ALconfig of an audio ALport.");
+
+static PyObject *
+alp_GetConfig(alpobject *self, PyObject *args)
+{
+ ALconfig config;
+ if (!PyArg_ParseTuple(args, ":GetConfig"))
+ return NULL;
+ if ((config = alGetConfig(self->port)) == NULL)
+ return NULL;
+ return newalcobject(config);
+}
+
+
+PyDoc_STRVAR(alp_GetResource__doc__,
+"alGetResource: get the resource associated with an audio port.");
+
+static PyObject *
+alp_GetResource(alpobject *self, PyObject *args)
+{
+ int resource;
+
+ if (!PyArg_ParseTuple(args, ":GetResource"))
+ return NULL;
+ if ((resource = alGetResource(self->port)) == 0)
+ return NULL;
+ return PyInt_FromLong((long) resource);
+}
+
+
+PyDoc_STRVAR(alp_GetFD__doc__,
+"alGetFD: get the file descriptor for an audio port.");
+
+static PyObject *
+alp_GetFD(alpobject *self, PyObject *args)
+{
+ int fd;
+
+ if (!PyArg_ParseTuple(args, ":GetFD"))
+ return NULL;
+
+ if ((fd = alGetFD(self->port)) < 0)
+ return NULL;
+
+ return PyInt_FromLong((long) fd);
+}
+
+
+PyDoc_STRVAR(alp_GetFilled__doc__,
+"alGetFilled: return the number of filled sample frames in "
+"an audio port.");
+
+static PyObject *
+alp_GetFilled(alpobject *self, PyObject *args)
+{
+ int filled;
+
+ if (!PyArg_ParseTuple(args, ":GetFilled"))
+ return NULL;
+ if ((filled = alGetFilled(self->port)) < 0)
+ return NULL;
+ return PyInt_FromLong((long) filled);
+}
+
+
+PyDoc_STRVAR(alp_GetFillable__doc__,
+"alGetFillable: report the number of unfilled sample frames "
+"in an audio port.");
+
+static PyObject *
+alp_GetFillable(alpobject *self, PyObject *args)
+{
+ int fillable;
+
+ if (!PyArg_ParseTuple(args, ":GetFillable"))
+ return NULL;
+ if ((fillable = alGetFillable(self->port)) < 0)
+ return NULL;
+ return PyInt_FromLong((long) fillable);
+}
+
+
+PyDoc_STRVAR(alp_ReadFrames__doc__,
+"alReadFrames: read sample frames from an audio port.");
+
+static PyObject *
+alp_ReadFrames(alpobject *self, PyObject *args)
+{
+ int framecount;
+ PyObject *v;
+ int size;
+ int ch;
+ ALconfig c;
+
+ if (!PyArg_ParseTuple(args, "i:ReadFrames", &framecount))
+ return NULL;
+ if (framecount < 0) {
+ PyErr_SetString(ErrorObject, "negative framecount");
+ return NULL;
+ }
+ c = alGetConfig(self->port);
+ switch (alGetSampFmt(c)) {
+ case AL_SAMPFMT_TWOSCOMP:
+ switch (alGetWidth(c)) {
+ case AL_SAMPLE_8:
+ size = 1;
+ break;
+ case AL_SAMPLE_16:
+ size = 2;
+ break;
+ case AL_SAMPLE_24:
+ size = 4;
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "can't determine width");
+ alFreeConfig(c);
+ return NULL;
+ }
+ break;
+ case AL_SAMPFMT_FLOAT:
+ size = 4;
+ break;
+ case AL_SAMPFMT_DOUBLE:
+ size = 8;
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "can't determine format");
+ alFreeConfig(c);
+ return NULL;
+ }
+ ch = alGetChannels(c);
+ alFreeConfig(c);
+ if (ch < 0) {
+ PyErr_SetString(ErrorObject, "can't determine # of channels");
+ return NULL;
+ }
+ size *= ch;
+ v = PyString_FromStringAndSize((char *) NULL, size * framecount);
+ if (v == NULL)
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ alReadFrames(self->port, (void *) PyString_AS_STRING(v), framecount);
+ Py_END_ALLOW_THREADS
+
+ return v;
+}
+
+
+PyDoc_STRVAR(alp_DiscardFrames__doc__,
+"alDiscardFrames: discard audio from an audio port.");
+
+static PyObject *
+alp_DiscardFrames(alpobject *self, PyObject *args)
+{
+ int framecount;
+
+ if (!PyArg_ParseTuple(args, "i:DiscardFrames", &framecount))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ framecount = alDiscardFrames(self->port, framecount);
+ Py_END_ALLOW_THREADS
+
+ if (framecount < 0)
+ return NULL;
+
+ return PyInt_FromLong((long) framecount);
+}
+
+
+PyDoc_STRVAR(alp_ZeroFrames__doc__,
+"alZeroFrames: write zero-valued sample frames to an audio port.");
+
+static PyObject *
+alp_ZeroFrames(alpobject *self, PyObject *args)
+{
+ int framecount;
+
+ if (!PyArg_ParseTuple(args, "i:ZeroFrames", &framecount))
+ return NULL;
+
+ if (framecount < 0) {
+ PyErr_SetString(ErrorObject, "negative framecount");
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ alZeroFrames(self->port, framecount);
+ Py_END_ALLOW_THREADS
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_SetFillPoint__doc__,
+"alSetFillPoint: set low- or high-water mark for an audio port.");
+
+static PyObject *
+alp_SetFillPoint(alpobject *self, PyObject *args)
+{
+ int fillpoint;
+
+ if (!PyArg_ParseTuple(args, "i:SetFillPoint", &fillpoint))
+ return NULL;
+
+ if (alSetFillPoint(self->port, fillpoint) < 0)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_GetFillPoint__doc__,
+"alGetFillPoint: get low- or high-water mark for an audio port.");
+
+static PyObject *
+alp_GetFillPoint(alpobject *self, PyObject *args)
+{
+ int fillpoint;
+
+ if (!PyArg_ParseTuple(args, ":GetFillPoint"))
+ return NULL;
+
+ if ((fillpoint = alGetFillPoint(self->port)) < 0)
+ return NULL;
+
+ return PyInt_FromLong((long) fillpoint);
+}
+
+
+PyDoc_STRVAR(alp_GetFrameNumber__doc__,
+"alGetFrameNumber: get the absolute sample frame number "
+"associated with a port.");
+
+static PyObject *
+alp_GetFrameNumber(alpobject *self, PyObject *args)
+{
+ stamp_t fnum;
+
+ if (!PyArg_ParseTuple(args, ":GetFrameNumber"))
+ return NULL;
+
+ if (alGetFrameNumber(self->port, &fnum) < 0)
+ return NULL;
+
+ return PyLong_FromLongLong((long long) fnum);
+}
+
+
+PyDoc_STRVAR(alp_GetFrameTime__doc__,
+"alGetFrameTime: get the time at which a sample frame came "
+"in or will go out.");
+
+static PyObject *
+alp_GetFrameTime(alpobject *self, PyObject *args)
+{
+ stamp_t fnum, time;
+ PyObject *ret, *v0, *v1;
+
+ if (!PyArg_ParseTuple(args, ":GetFrameTime"))
+ return NULL;
+ if (alGetFrameTime(self->port, &fnum, &time) < 0)
+ return NULL;
+ v0 = PyLong_FromLongLong((long long) fnum);
+ v1 = PyLong_FromLongLong((long long) time);
+ if (PyErr_Occurred()) {
+ Py_XDECREF(v0);
+ Py_XDECREF(v1);
+ return NULL;
+ }
+ ret = PyTuple_Pack(2, v0, v1);
+ Py_DECREF(v0);
+ Py_DECREF(v1);
+ return ret;
+}
+
+
+PyDoc_STRVAR(alp_WriteFrames__doc__,
+"alWriteFrames: write sample frames to an audio port.");
+
+static PyObject *
+alp_WriteFrames(alpobject *self, PyObject *args)
+{
+ char *samples;
+ int length;
+ int size, ch;
+ ALconfig c;
+
+ if (!PyArg_ParseTuple(args, "s#:WriteFrames", &samples, &length))
+ return NULL;
+ c = alGetConfig(self->port);
+ switch (alGetSampFmt(c)) {
+ case AL_SAMPFMT_TWOSCOMP:
+ switch (alGetWidth(c)) {
+ case AL_SAMPLE_8:
+ size = 1;
+ break;
+ case AL_SAMPLE_16:
+ size = 2;
+ break;
+ case AL_SAMPLE_24:
+ size = 4;
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "can't determine width");
+ alFreeConfig(c);
+ return NULL;
+ }
+ break;
+ case AL_SAMPFMT_FLOAT:
+ size = 4;
+ break;
+ case AL_SAMPFMT_DOUBLE:
+ size = 8;
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "can't determine format");
+ alFreeConfig(c);
+ return NULL;
+ }
+ ch = alGetChannels(c);
+ alFreeConfig(c);
+ if (ch < 0) {
+ PyErr_SetString(ErrorObject, "can't determine # of channels");
+ return NULL;
+ }
+ size *= ch;
+ if (length % size != 0) {
+ PyErr_SetString(ErrorObject,
+ "buffer length not whole number of frames");
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ alWriteFrames(self->port, (void *) samples, length / size);
+ Py_END_ALLOW_THREADS
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(alp_ClosePort__doc__, "alClosePort: close an audio port.");
+
+static PyObject *
+alp_ClosePort(alpobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":ClosePort"))
+ return NULL;
+ if (alClosePort(self->port) < 0)
+ return NULL;
+ self->port = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#endif /* AL_NO_ELEM */
+
+#ifdef OLD_INTERFACE
+static PyObject *
+alp_closeport(alpobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":ClosePort"))
+ return NULL;
+ if (ALcloseport(self->port) < 0)
+ return NULL;
+ self->port = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+alp_getfd(alpobject *self, PyObject *args)
+{
+ int fd;
+
+ if (!PyArg_ParseTuple(args, ":GetFD"))
+ return NULL;
+ if ((fd = ALgetfd(self-> port)) == -1)
+ return NULL;
+ return PyInt_FromLong(fd);
+}
+
+static PyObject *
+alp_getfilled(alpobject *self, PyObject *args)
+{
+ long count;
+
+ if (!PyArg_ParseTuple(args, ":GetFilled"))
+ return NULL;
+ if ((count = ALgetfilled(self-> port)) == -1)
+ return NULL;
+ return PyInt_FromLong(count);
+}
+
+static PyObject *
+alp_getfillable(alpobject *self, PyObject *args)
+{
+ long count;
+
+ if (!PyArg_ParseTuple(args, ":GetFillable"))
+ return NULL;
+ if ((count = ALgetfillable(self-> port)) == -1)
+ return NULL;
+ return PyInt_FromLong (count);
+}
+
+static PyObject *
+alp_readsamps(alpobject *self, PyObject *args)
+{
+ long count;
+ PyObject *v;
+ ALconfig c;
+ int width;
+ int ret;
+
+ if (!PyArg_ParseTuple(args, "l:readsamps", &count))
+ return NULL;
+
+ if (count <= 0) {
+ PyErr_SetString(ErrorObject, "al.readsamps : arg <= 0");
+ return NULL;
+ }
+
+ c = ALgetconfig(self->port);
+#ifdef AL_405
+ width = ALgetsampfmt(c);
+ if (width == AL_SAMPFMT_FLOAT)
+ width = sizeof(float);
+ else if (width == AL_SAMPFMT_DOUBLE)
+ width = sizeof(double);
+ else
+ width = ALgetwidth(c);
+#else
+ width = ALgetwidth(c);
+#endif /* AL_405 */
+ ALfreeconfig(c);
+ v = PyString_FromStringAndSize((char *)NULL, width * count);
+ if (v == NULL)
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = ALreadsamps(self->port, (void *) PyString_AsString(v), count);
+ Py_END_ALLOW_THREADS
+ if (ret == -1) {
+ Py_DECREF(v);
+ return NULL;
+ }
+
+ return (v);
+}
+
+static PyObject *
+alp_writesamps(alpobject *self, PyObject *args)
+{
+ char *buf;
+ int size, width;
+ ALconfig c;
+ int ret;
+
+ if (!PyArg_ParseTuple(args, "s#:writesamps", &buf, &size))
+ return NULL;
+
+ c = ALgetconfig(self->port);
+#ifdef AL_405
+ width = ALgetsampfmt(c);
+ if (width == AL_SAMPFMT_FLOAT)
+ width = sizeof(float);
+ else if (width == AL_SAMPFMT_DOUBLE)
+ width = sizeof(double);
+ else
+ width = ALgetwidth(c);
+#else
+ width = ALgetwidth(c);
+#endif /* AL_405 */
+ ALfreeconfig(c);
+ Py_BEGIN_ALLOW_THREADS
+ ret = ALwritesamps (self->port, (void *) buf, (long) size / width);
+ Py_END_ALLOW_THREADS
+ if (ret == -1)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+alp_getfillpoint(alpobject *self, PyObject *args)
+{
+ long count;
+
+ if (!PyArg_ParseTuple(args, ":GetFillPoint"))
+ return NULL;
+ if ((count = ALgetfillpoint(self->port)) == -1)
+ return NULL;
+ return PyInt_FromLong(count);
+}
+
+static PyObject *
+alp_setfillpoint(alpobject *self, PyObject *args)
+{
+ long count;
+
+ if (!PyArg_ParseTuple(args, "l:SetFillPoint", &count))
+ return NULL;
+ if (ALsetfillpoint(self->port, count) == -1)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+alp_setconfig(alpobject *self, PyObject *args)
+{
+ alcobject *config;
+
+ if (!PyArg_ParseTuple(args, "O!:SetConfig", &Alctype, &config))
+ return NULL;
+ if (ALsetconfig(self->port, config->config) == -1)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+alp_getconfig(alpobject *self, PyObject *args)
+{
+ ALconfig config;
+
+ if (!PyArg_ParseTuple(args, ":GetConfig"))
+ return NULL;
+ config = ALgetconfig(self->port);
+ if (config == NULL)
+ return NULL;
+ return newalcobject(config);
+}
+
+#ifdef AL_405
+static PyObject *
+alp_getstatus(alpobject *self, PyObject *args)
+{
+ PyObject *list, *v;
+ long *PVbuffer;
+ long length;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &list))
+ return NULL;
+ length = PyList_Size(list);
+ PVbuffer = PyMem_NEW(long, length);
+ if (PVbuffer == NULL)
+ return PyErr_NoMemory();
+ for (i = 0; i < length; i++) {
+ v = PyList_GetItem(list, i);
+ if (!PyInt_Check(v)) {
+ PyMem_DEL(PVbuffer);
+ PyErr_BadArgument();
+ return NULL;
+ }
+ PVbuffer[i] = PyInt_AsLong(v);
+ }
+
+ if (ALgetstatus(self->port, PVbuffer, length) == -1)
+ return NULL;
+
+ for (i = 0; i < length; i++)
+ PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+
+ PyMem_DEL(PVbuffer);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* AL_405 */
+
+#endif /* OLD_INTERFACE */
+
+static struct PyMethodDef alp_methods[] = {
+#ifdef AL_NO_ELEM /* IRIX 6 */
+ {"SetConfig", (PyCFunction)alp_SetConfig, METH_VARARGS, alp_SetConfig__doc__},
+ {"GetConfig", (PyCFunction)alp_GetConfig, METH_VARARGS, alp_GetConfig__doc__},
+ {"GetResource", (PyCFunction)alp_GetResource, METH_VARARGS, alp_GetResource__doc__},
+ {"GetFD", (PyCFunction)alp_GetFD, METH_VARARGS, alp_GetFD__doc__},
+ {"GetFilled", (PyCFunction)alp_GetFilled, METH_VARARGS, alp_GetFilled__doc__},
+ {"GetFillable", (PyCFunction)alp_GetFillable, METH_VARARGS, alp_GetFillable__doc__},
+ {"ReadFrames", (PyCFunction)alp_ReadFrames, METH_VARARGS, alp_ReadFrames__doc__},
+ {"DiscardFrames", (PyCFunction)alp_DiscardFrames, METH_VARARGS, alp_DiscardFrames__doc__},
+ {"ZeroFrames", (PyCFunction)alp_ZeroFrames, METH_VARARGS, alp_ZeroFrames__doc__},
+ {"SetFillPoint", (PyCFunction)alp_SetFillPoint, METH_VARARGS, alp_SetFillPoint__doc__},
+ {"GetFillPoint", (PyCFunction)alp_GetFillPoint, METH_VARARGS, alp_GetFillPoint__doc__},
+ {"GetFrameNumber", (PyCFunction)alp_GetFrameNumber, METH_VARARGS, alp_GetFrameNumber__doc__},
+ {"GetFrameTime", (PyCFunction)alp_GetFrameTime, METH_VARARGS, alp_GetFrameTime__doc__},
+ {"WriteFrames", (PyCFunction)alp_WriteFrames, METH_VARARGS, alp_WriteFrames__doc__},
+ {"ClosePort", (PyCFunction)alp_ClosePort, METH_VARARGS, alp_ClosePort__doc__},
+#endif /* AL_NO_ELEM */
+#ifdef OLD_INTERFACE
+ {"closeport", (PyCFunction)alp_closeport, METH_VARARGS},
+ {"getfd", (PyCFunction)alp_getfd, METH_VARARGS},
+ {"fileno", (PyCFunction)alp_getfd, METH_VARARGS},
+ {"getfilled", (PyCFunction)alp_getfilled, METH_VARARGS},
+ {"getfillable", (PyCFunction)alp_getfillable, METH_VARARGS},
+ {"readsamps", (PyCFunction)alp_readsamps, METH_VARARGS},
+ {"writesamps", (PyCFunction)alp_writesamps, METH_VARARGS},
+ {"setfillpoint", (PyCFunction)alp_setfillpoint, METH_VARARGS},
+ {"getfillpoint", (PyCFunction)alp_getfillpoint, METH_VARARGS},
+ {"setconfig", (PyCFunction)alp_setconfig, METH_VARARGS},
+ {"getconfig", (PyCFunction)alp_getconfig, METH_VARARGS},
+#ifdef AL_405
+ {"getstatus", (PyCFunction)alp_getstatus, METH_VARARGS},
+#endif /* AL_405 */
+#endif /* OLD_INTERFACE */
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+
+static PyObject *
+newalpobject(ALport port)
+{
+ alpobject *self;
+
+ self = PyObject_New(alpobject, &Alptype);
+ if (self == NULL)
+ return NULL;
+ /* XXXX Add your own initializers here */
+ self->port = port;
+ return (PyObject *) self;
+}
+
+
+static void
+alp_dealloc(alpobject *self)
+{
+ /* XXXX Add your own cleanup code here */
+ if (self->port) {
+#ifdef AL_NO_ELEM /* IRIX 6 */
+ alClosePort(self->port);
+#else
+ ALcloseport(self->port);
+#endif
+ }
+ PyObject_Del(self);
+}
+
+static PyObject *
+alp_getattr(alpobject *self, char *name)
+{
+ /* XXXX Add your own getattr code here */
+ if (self->port == NULL) {
+ PyErr_SetString(ErrorObject, "port already closed");
+ return NULL;
+ }
+ return Py_FindMethod(alp_methods, (PyObject *)self, name);
+}
+
+PyDoc_STRVAR(Alptype__doc__, "");
+
+static PyTypeObject Alptype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "al.port", /*tp_name*/
+ sizeof(alpobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)alp_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)alp_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ Alptype__doc__ /* Documentation string */
+};
+
+/* End of code for port objects */
+/* -------------------------------------------------------- */
+
+
+#ifdef AL_NO_ELEM /* IRIX 6 */
+
+PyDoc_STRVAR(al_NewConfig__doc__,
+"alNewConfig: create and initialize an audio ALconfig structure.");
+
+static PyObject *
+al_NewConfig(PyObject *self, PyObject *args)
+{
+ ALconfig config;
+
+ if (!PyArg_ParseTuple(args, ":NewConfig"))
+ return NULL;
+ if ((config = alNewConfig()) == NULL)
+ return NULL;
+ return newalcobject(config);
+}
+
+PyDoc_STRVAR(al_OpenPort__doc__,
+"alOpenPort: open an audio port.");
+
+static PyObject *
+al_OpenPort(PyObject *self, PyObject *args)
+{
+ ALport port;
+ char *name, *dir;
+ alcobject *config = NULL;
+
+ if (!PyArg_ParseTuple(args, "ss|O!:OpenPort", &name, &dir, &Alctype, &config))
+ return NULL;
+ if ((port = alOpenPort(name, dir, config ? config->config : NULL)) == NULL)
+ return NULL;
+ return newalpobject(port);
+}
+
+PyDoc_STRVAR(al_Connect__doc__,
+"alConnect: connect two audio I/O resources.");
+
+static PyObject *
+al_Connect(PyObject *self, PyObject *args)
+{
+ int source, dest, nprops = 0, id, i;
+ ALpv *props = NULL;
+ ALparamInfo *propinfo = NULL;
+ PyObject *propobj = NULL;
+
+ if (!PyArg_ParseTuple(args, "ii|O!:Connect", &source, &dest, &PyList_Type, &propobj))
+ return NULL;
+ if (propobj != NULL) {
+ nprops = python2params(source, dest, propobj, &props, &propinfo);
+ if (nprops < 0)
+ return NULL;
+ }
+
+ id = alConnect(source, dest, props, nprops);
+
+ if (props) {
+ for (i = 0; i < nprops; i++) {
+ switch (propinfo[i].valueType) {
+ case AL_SET_VAL:
+ case AL_VECTOR_VAL:
+ PyMem_DEL(props[i].value.ptr);
+ break;
+ }
+ }
+ PyMem_DEL(props);
+ PyMem_DEL(propinfo);
+ }
+
+ if (id < 0)
+ return NULL;
+ return PyInt_FromLong((long) id);
+}
+
+PyDoc_STRVAR(al_Disconnect__doc__,
+"alDisconnect: delete a connection between two audio I/O resources.");
+
+static PyObject *
+al_Disconnect(PyObject *self, PyObject *args)
+{
+ int res;
+
+ if (!PyArg_ParseTuple(args, "i:Disconnect", &res))
+ return NULL;
+ if (alDisconnect(res) < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(al_GetParams__doc__,
+"alGetParams: get the values of audio resource parameters.");
+
+static PyObject *
+al_GetParams(PyObject *self, PyObject *args)
+{
+ int resource;
+ PyObject *pvslist, *item = NULL, *v = NULL;
+ ALpv *pvs;
+ int i, j, npvs;
+ ALparamInfo *pinfo;
+
+ if (!PyArg_ParseTuple(args, "iO!:GetParams", &resource, &PyList_Type, &pvslist))
+ return NULL;
+ npvs = PyList_Size(pvslist);
+ pvs = PyMem_NEW(ALpv, npvs);
+ pinfo = PyMem_NEW(ALparamInfo, npvs);
+ for (i = 0; i < npvs; i++) {
+ item = PyList_GetItem(pvslist, i);
+ if (!PyInt_Check(item)) {
+ item = NULL;
+ PyErr_SetString(ErrorObject, "list of integers expected");
+ goto error;
+ }
+ pvs[i].param = (int) PyInt_AsLong(item);
+ item = NULL; /* not needed anymore */
+ if (alGetParamInfo(resource, pvs[i].param, &pinfo[i]) < 0)
+ goto error;
+ switch (pinfo[i].valueType) {
+ case AL_NO_VAL:
+ break;
+ case AL_MATRIX_VAL:
+ pinfo[i].maxElems *= pinfo[i].maxElems2;
+ /* fall through */
+ case AL_STRING_VAL:
+ case AL_SET_VAL:
+ case AL_VECTOR_VAL:
+ switch (pinfo[i].elementType) {
+ case AL_INT32_ELEM:
+ case AL_RESOURCE_ELEM:
+ case AL_ENUM_ELEM:
+ pvs[i].value.ptr = PyMem_NEW(int, pinfo[i].maxElems);
+ pvs[i].sizeIn = pinfo[i].maxElems;
+ break;
+ case AL_INT64_ELEM:
+ case AL_FIXED_ELEM:
+ pvs[i].value.ptr = PyMem_NEW(long long, pinfo[i].maxElems);
+ pvs[i].sizeIn = pinfo[i].maxElems;
+ break;
+ case AL_CHAR_ELEM:
+ pvs[i].value.ptr = PyMem_NEW(char, 32);
+ pvs[i].sizeIn = 32;
+ break;
+ case AL_NO_ELEM:
+ case AL_PTR_ELEM:
+ default:
+ PyErr_SetString(ErrorObject, "internal error");
+ goto error;
+ }
+ break;
+ case AL_SCALAR_VAL:
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "internal error");
+ goto error;
+ }
+ if (pinfo[i].valueType == AL_MATRIX_VAL) {
+ pinfo[i].maxElems /= pinfo[i].maxElems2;
+ pvs[i].sizeIn /= pinfo[i].maxElems2;
+ pvs[i].size2In = pinfo[i].maxElems2;
+ }
+ }
+ if (alGetParams(resource, pvs, npvs) < 0)
+ goto error;
+ if (!(v = PyList_New(npvs)))
+ goto error;
+ for (i = 0; i < npvs; i++) {
+ if (pvs[i].sizeOut < 0) {
+ char buf[32];
+ PyOS_snprintf(buf, sizeof(buf),
+ "problem with param %d", i);
+ PyErr_SetString(ErrorObject, buf);
+ goto error;
+ }
+ switch (pinfo[i].valueType) {
+ case AL_NO_VAL:
+ item = Py_None;
+ Py_INCREF(item);
+ break;
+ case AL_STRING_VAL:
+ item = PyString_FromString(pvs[i].value.ptr);
+ PyMem_DEL(pvs[i].value.ptr);
+ break;
+ case AL_MATRIX_VAL:
+ /* XXXX this is not right */
+ pvs[i].sizeOut *= pvs[i].size2Out;
+ /* fall through */
+ case AL_SET_VAL:
+ case AL_VECTOR_VAL:
+ item = PyList_New(pvs[i].sizeOut);
+ for (j = 0; j < pvs[i].sizeOut; j++) {
+ switch (pinfo[i].elementType) {
+ case AL_INT32_ELEM:
+ case AL_RESOURCE_ELEM:
+ case AL_ENUM_ELEM:
+ PyList_SetItem(item, j, PyInt_FromLong((long) ((int *) pvs[i].value.ptr)[j]));
+ break;
+ case AL_INT64_ELEM:
+ PyList_SetItem(item, j, PyLong_FromLongLong(((long long *) pvs[i].value.ptr)[j]));
+ break;
+ case AL_FIXED_ELEM:
+ PyList_SetItem(item, j, PyFloat_FromDouble(alFixedToDouble(((long long *) pvs[i].value.ptr)[j])));
+ break;
+ default:
+ PyErr_SetString(ErrorObject, "internal error");
+ goto error;
+ }
+ }
+ PyMem_DEL(pvs[i].value.ptr);
+ break;
+ case AL_SCALAR_VAL:
+ item = param2python(resource, pvs[i].param, pvs[i].value, &pinfo[i]);
+ break;
+ }
+ if (PyErr_Occurred() ||
+ PyList_SetItem(v, i, Py_BuildValue("(iO)", pvs[i].param,
+ item)) < 0 ||
+ PyErr_Occurred())
+ goto error;
+ Py_DECREF(item);
+ }
+ PyMem_DEL(pvs);
+ PyMem_DEL(pinfo);
+ return v;
+
+ error:
+ Py_XDECREF(v);
+ Py_XDECREF(item);
+ if (pvs)
+ PyMem_DEL(pvs);
+ if (pinfo)
+ PyMem_DEL(pinfo);
+ return NULL;
+}
+
+PyDoc_STRVAR(al_SetParams__doc__,
+"alSetParams: set the values of audio resource parameters.");
+
+static PyObject *
+al_SetParams(PyObject *self, PyObject *args)
+{
+ int resource;
+ PyObject *pvslist;
+ ALpv *pvs;
+ ALparamInfo *pinfo;
+ int npvs, i;
+
+ if (!PyArg_ParseTuple(args, "iO!:SetParams", &resource, &PyList_Type, &pvslist))
+ return NULL;
+ npvs = python2params(resource, -1, pvslist, &pvs, &pinfo);
+ if (npvs < 0)
+ return NULL;
+
+ if (alSetParams(resource, pvs, npvs) < 0)
+ goto error;
+
+ /* cleanup */
+ for (i = 0; i < npvs; i++) {
+ switch (pinfo[i].valueType) {
+ case AL_SET_VAL:
+ case AL_VECTOR_VAL:
+ PyMem_DEL(pvs[i].value.ptr);
+ break;
+ }
+ }
+ PyMem_DEL(pvs);
+ PyMem_DEL(pinfo);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+ error:
+ /* XXXX we should clean up everything */
+ if (pvs)
+ PyMem_DEL(pvs);
+ if (pinfo)
+ PyMem_DEL(pinfo);
+ return NULL;
+}
+
+PyDoc_STRVAR(al_QueryValues__doc__,
+"alQueryValues: get the set of possible values for a parameter.");
+
+static PyObject *
+al_QueryValues(PyObject *self, PyObject *args)
+{
+ int resource, param;
+ ALvalue *return_set = NULL;
+ int setsize = 32, qualsize = 0, nvals, i;
+ ALpv *quals = NULL;
+ ALparamInfo pinfo;
+ ALparamInfo *qualinfo = NULL;
+ PyObject *qualobj = NULL;
+ PyObject *res = NULL, *item;
+
+ if (!PyArg_ParseTuple(args, "ii|O!:QueryValues", &resource, &param,
+ &PyList_Type, &qualobj))
+ return NULL;
+ if (qualobj != NULL) {
+ qualsize = python2params(resource, param, qualobj, &quals, &qualinfo);
+ if (qualsize < 0)
+ return NULL;
+ }
+ setsize = 32;
+ return_set = PyMem_NEW(ALvalue, setsize);
+ if (return_set == NULL) {
+ PyErr_NoMemory();
+ goto cleanup;
+ }
+
+ retry:
+ nvals = alQueryValues(resource, param, return_set, setsize, quals, qualsize);
+ if (nvals < 0)
+ goto cleanup;
+ if (nvals > setsize) {
+ setsize = nvals;
+ PyMem_RESIZE(return_set, ALvalue, setsize);
+ if (return_set == NULL) {
+ PyErr_NoMemory();
+ goto cleanup;
+ }
+ goto retry;
+ }
+
+ if (alGetParamInfo(resource, param, &pinfo) < 0)
+ goto cleanup;
+
+ res = PyList_New(nvals);
+ if (res == NULL)
+ goto cleanup;
+ for (i = 0; i < nvals; i++) {
+ item = param2python(resource, param, return_set[i], &pinfo);
+ if (item == NULL ||
+ PyList_SetItem(res, i, item) < 0) {
+ Py_DECREF(res);
+ res = NULL;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ if (return_set)
+ PyMem_DEL(return_set);
+ if (quals) {
+ for (i = 0; i < qualsize; i++) {
+ switch (qualinfo[i].valueType) {
+ case AL_SET_VAL:
+ case AL_VECTOR_VAL:
+ PyMem_DEL(quals[i].value.ptr);
+ break;
+ }
+ }
+ PyMem_DEL(quals);
+ PyMem_DEL(qualinfo);
+ }
+
+ return res;
+}
+
+PyDoc_STRVAR(al_GetParamInfo__doc__,
+"alGetParamInfo: get information about a parameter on "
+"a particular audio resource.");
+
+static PyObject *
+al_GetParamInfo(PyObject *self, PyObject *args)
+{
+ int res, param;
+ ALparamInfo pinfo;
+ PyObject *v, *item;
+
+ if (!PyArg_ParseTuple(args, "ii:GetParamInfo", &res, &param))
+ return NULL;
+ if (alGetParamInfo(res, param, &pinfo) < 0)
+ return NULL;
+ v = PyDict_New();
+ if (!v) return NULL;
+
+ item = PyInt_FromLong((long) pinfo.resource);
+ PyDict_SetItemString(v, "resource", item);
+ Py_DECREF(item);
+
+ item = PyInt_FromLong((long) pinfo.param);
+ PyDict_SetItemString(v, "param", item);
+ Py_DECREF(item);
+
+ item = PyInt_FromLong((long) pinfo.valueType);
+ PyDict_SetItemString(v, "valueType", item);
+ Py_DECREF(item);
+
+ if (pinfo.valueType != AL_NO_VAL && pinfo.valueType != AL_SCALAR_VAL) {
+ /* multiple values */
+ item = PyInt_FromLong((long) pinfo.maxElems);
+ PyDict_SetItemString(v, "maxElems", item);
+ Py_DECREF(item);
+
+ if (pinfo.valueType == AL_MATRIX_VAL) {
+ /* 2 dimensional */
+ item = PyInt_FromLong((long) pinfo.maxElems2);
+ PyDict_SetItemString(v, "maxElems2", item);
+ Py_DECREF(item);
+ }
+ }
+
+ item = PyInt_FromLong((long) pinfo.elementType);
+ PyDict_SetItemString(v, "elementType", item);
+ Py_DECREF(item);
+
+ item = PyString_FromString(pinfo.name);
+ PyDict_SetItemString(v, "name", item);
+ Py_DECREF(item);
+
+ item = param2python(res, param, pinfo.initial, &pinfo);
+ PyDict_SetItemString(v, "initial", item);
+ Py_DECREF(item);
+
+ if (pinfo.elementType != AL_ENUM_ELEM &&
+ pinfo.elementType != AL_RESOURCE_ELEM &&
+ pinfo.elementType != AL_CHAR_ELEM) {
+ /* range param */
+ item = param2python(res, param, pinfo.min, &pinfo);
+ PyDict_SetItemString(v, "min", item);
+ Py_DECREF(item);
+
+ item = param2python(res, param, pinfo.max, &pinfo);
+ PyDict_SetItemString(v, "max", item);
+ Py_DECREF(item);
+
+ item = param2python(res, param, pinfo.minDelta, &pinfo);
+ PyDict_SetItemString(v, "minDelta", item);
+ Py_DECREF(item);
+
+ item = param2python(res, param, pinfo.maxDelta, &pinfo);
+ PyDict_SetItemString(v, "maxDelta", item);
+ Py_DECREF(item);
+
+ item = PyInt_FromLong((long) pinfo.specialVals);
+ PyDict_SetItemString(v, "specialVals", item);
+ Py_DECREF(item);
+ }
+
+ return v;
+}
+
+PyDoc_STRVAR(al_GetResourceByName__doc__,
+"alGetResourceByName: find an audio resource by name.");
+
+static PyObject *
+al_GetResourceByName(PyObject *self, PyObject *args)
+{
+ int res, start_res, type;
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "isi:GetResourceByName", &start_res, &name, &type))
+ return NULL;
+ if ((res = alGetResourceByName(start_res, name, type)) == 0)
+ return NULL;
+ return PyInt_FromLong((long) res);
+}
+
+PyDoc_STRVAR(al_IsSubtype__doc__,
+"alIsSubtype: indicate if one resource type is a subtype of another.");
+
+static PyObject *
+al_IsSubtype(PyObject *self, PyObject *args)
+{
+ int type, subtype;
+
+ if (!PyArg_ParseTuple(args, "ii:IsSubtype", &type, &subtype))
+ return NULL;
+ return PyInt_FromLong((long) alIsSubtype(type, subtype));
+}
+
+PyDoc_STRVAR(al_SetErrorHandler__doc__, "");
+
+static PyObject *
+al_SetErrorHandler(PyObject *self, PyObject *args)
+{
+
+ if (!PyArg_ParseTuple(args, ":SetErrorHandler"))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#endif /* AL_NO_ELEM */
+
+#ifdef OLD_INTERFACE
+
+static PyObject *
+al_openport(PyObject *self, PyObject *args)
+{
+ char *name, *dir;
+ ALport port;
+ alcobject *config = NULL;
+
+ if (!PyArg_ParseTuple(args, "ss|O!:OpenPort", &name, &dir, &Alctype, &config))
+ return NULL;
+ if ((port = ALopenport(name, dir, config ? config->config : NULL)) == NULL)
+ return NULL;
+ return newalpobject(port);
+}
+
+static PyObject *
+al_newconfig(PyObject *self, PyObject *args)
+{
+ ALconfig config;
+
+ if (!PyArg_ParseTuple(args, ":NewConfig"))
+ return NULL;
+ if ((config = ALnewconfig ()) == NULL)
+ return NULL;
+ return newalcobject(config);
+}
+
+static PyObject *
+al_queryparams(PyObject *self, PyObject *args)
+{
+ long device;
+ long length;
+ long *PVbuffer;
+ long PVdummy[2];
+ PyObject *v = NULL;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "l:queryparams", &device))
+ return NULL;
+ if ((length = ALqueryparams(device, PVdummy, 2L)) == -1)
+ return NULL;
+ if ((PVbuffer = PyMem_NEW(long, length)) == NULL)
+ return PyErr_NoMemory();
+ if (ALqueryparams(device, PVbuffer, length) >= 0 &&
+ (v = PyList_New((int)length)) != NULL) {
+ for (i = 0; i < length; i++)
+ PyList_SetItem(v, i, PyInt_FromLong(PVbuffer[i]));
+ }
+ PyMem_DEL(PVbuffer);
+ return v;
+}
+
+static PyObject *
+doParams(PyObject *args, int (*func)(long, long *, long), int modified)
+{
+ long device;
+ PyObject *list, *v;
+ long *PVbuffer;
+ long length;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "lO!", &device, &PyList_Type, &list))
+ return NULL;
+ length = PyList_Size(list);
+ PVbuffer = PyMem_NEW(long, length);
+ if (PVbuffer == NULL)
+ return PyErr_NoMemory();
+ for (i = 0; i < length; i++) {
+ v = PyList_GetItem(list, i);
+ if (!PyInt_Check(v)) {
+ PyMem_DEL(PVbuffer);
+ PyErr_BadArgument();
+ return NULL;
+ }
+ PVbuffer[i] = PyInt_AsLong(v);
+ }
+
+ if ((*func)(device, PVbuffer, length) == -1) {
+ PyMem_DEL(PVbuffer);
+ return NULL;
+ }
+
+ if (modified) {
+ for (i = 0; i < length; i++)
+ PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+ }
+
+ PyMem_DEL(PVbuffer);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+al_getparams(PyObject *self, PyObject *args)
+{
+ return doParams(args, ALgetparams, 1);
+}
+
+static PyObject *
+al_setparams(PyObject *self, PyObject *args)
+{
+ return doParams(args, ALsetparams, 0);
+}
+
+static PyObject *
+al_getname(PyObject *self, PyObject *args)
+{
+ long device, descriptor;
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "ll:getname", &device, &descriptor))
+ return NULL;
+ if ((name = ALgetname(device, descriptor)) == NULL)
+ return NULL;
+ return PyString_FromString(name);
+}
+
+static PyObject *
+al_getdefault(PyObject *self, PyObject *args)
+{
+ long device, descriptor, value;
+
+ if (!PyArg_ParseTuple(args, "ll:getdefault", &device, &descriptor))
+ return NULL;
+ if ((value = ALgetdefault(device, descriptor)) == -1)
+ return NULL;
+ return PyLong_FromLong(value);
+}
+
+static PyObject *
+al_getminmax(PyObject *self, PyObject *args)
+{
+ long device, descriptor, min, max;
+
+ if (!PyArg_ParseTuple(args, "ll:getminmax", &device, &descriptor))
+ return NULL;
+ min = -1;
+ max = -1;
+ if (ALgetminmax(device, descriptor, &min, &max) == -1)
+ return NULL;
+ return Py_BuildValue("ll", min, max);
+}
+
+#endif /* OLD_INTERFACE */
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef al_methods[] = {
+#ifdef AL_NO_ELEM /* IRIX 6 */
+ {"NewConfig", (PyCFunction)al_NewConfig, METH_VARARGS, al_NewConfig__doc__},
+ {"OpenPort", (PyCFunction)al_OpenPort, METH_VARARGS, al_OpenPort__doc__},
+ {"Connect", (PyCFunction)al_Connect, METH_VARARGS, al_Connect__doc__},
+ {"Disconnect", (PyCFunction)al_Disconnect, METH_VARARGS, al_Disconnect__doc__},
+ {"GetParams", (PyCFunction)al_GetParams, METH_VARARGS, al_GetParams__doc__},
+ {"SetParams", (PyCFunction)al_SetParams, METH_VARARGS, al_SetParams__doc__},
+ {"QueryValues", (PyCFunction)al_QueryValues, METH_VARARGS, al_QueryValues__doc__},
+ {"GetParamInfo", (PyCFunction)al_GetParamInfo, METH_VARARGS, al_GetParamInfo__doc__},
+ {"GetResourceByName", (PyCFunction)al_GetResourceByName, METH_VARARGS, al_GetResourceByName__doc__},
+ {"IsSubtype", (PyCFunction)al_IsSubtype, METH_VARARGS, al_IsSubtype__doc__},
+#if 0
+ /* this one not supported */
+ {"SetErrorHandler", (PyCFunction)al_SetErrorHandler, METH_VARARGS, al_SetErrorHandler__doc__},
+#endif
+#endif /* AL_NO_ELEM */
+#ifdef OLD_INTERFACE
+ {"openport", (PyCFunction)al_openport, METH_VARARGS},
+ {"newconfig", (PyCFunction)al_newconfig, METH_VARARGS},
+ {"queryparams", (PyCFunction)al_queryparams, METH_VARARGS},
+ {"getparams", (PyCFunction)al_getparams, METH_VARARGS},
+ {"setparams", (PyCFunction)al_setparams, METH_VARARGS},
+ {"getname", (PyCFunction)al_getname, METH_VARARGS},
+ {"getdefault", (PyCFunction)al_getdefault, METH_VARARGS},
+ {"getminmax", (PyCFunction)al_getminmax, METH_VARARGS},
+#endif /* OLD_INTERFACE */
+
+ {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called inital) */
+
+PyDoc_STRVAR(al_module_documentation, "");
+
+void
+inital(void)
+{
+ PyObject *m, *d, *x;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule4("al", al_methods,
+ al_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ ErrorObject = PyErr_NewException("al.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", ErrorObject);
+
+ /* XXXX Add constants here */
+#ifdef AL_4CHANNEL
+ x = PyInt_FromLong((long) AL_4CHANNEL);
+ if (x == NULL || PyDict_SetItemString(d, "FOURCHANNEL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ADAT_IF_TYPE
+ x = PyInt_FromLong((long) AL_ADAT_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "ADAT_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ADAT_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_ADAT_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "ADAT_MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_AES_IF_TYPE
+ x = PyInt_FromLong((long) AL_AES_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "AES_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_AES_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_AES_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "AES_MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ANALOG_IF_TYPE
+ x = PyInt_FromLong((long) AL_ANALOG_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "ANALOG_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ASSOCIATE
+ x = PyInt_FromLong((long) AL_ASSOCIATE);
+ if (x == NULL || PyDict_SetItemString(d, "ASSOCIATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFER_NULL
+ x = PyInt_FromLong((long) AL_BAD_BUFFER_NULL);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_NULL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFERLENGTH
+ x = PyInt_FromLong((long) AL_BAD_BUFFERLENGTH);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFERLENGTH_NEG
+ x = PyInt_FromLong((long) AL_BAD_BUFFERLENGTH_NEG);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_NEG", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_BUFFERLENGTH_ODD
+ x = PyInt_FromLong((long) AL_BAD_BUFFERLENGTH_ODD);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_ODD", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_CHANNELS
+ x = PyInt_FromLong((long) AL_BAD_CHANNELS);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_CHANNELS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_CONFIG
+ x = PyInt_FromLong((long) AL_BAD_CONFIG);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_CONFIG", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_COUNT_NEG
+ x = PyInt_FromLong((long) AL_BAD_COUNT_NEG);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_COUNT_NEG", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_DEVICE
+ x = PyInt_FromLong((long) AL_BAD_DEVICE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_DEVICE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_DEVICE_ACCESS
+ x = PyInt_FromLong((long) AL_BAD_DEVICE_ACCESS);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_DEVICE_ACCESS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_DIRECTION
+ x = PyInt_FromLong((long) AL_BAD_DIRECTION);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_DIRECTION", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_FILLPOINT
+ x = PyInt_FromLong((long) AL_BAD_FILLPOINT);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_FILLPOINT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_FLOATMAX
+ x = PyInt_FromLong((long) AL_BAD_FLOATMAX);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_FLOATMAX", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_ILLEGAL_STATE
+ x = PyInt_FromLong((long) AL_BAD_ILLEGAL_STATE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_ILLEGAL_STATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_NO_PORTS
+ x = PyInt_FromLong((long) AL_BAD_NO_PORTS);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_NO_PORTS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_NOT_FOUND
+ x = PyInt_FromLong((long) AL_BAD_NOT_FOUND);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_NOT_FOUND", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_NOT_IMPLEMENTED
+ x = PyInt_FromLong((long) AL_BAD_NOT_IMPLEMENTED);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_NOT_IMPLEMENTED", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_OUT_OF_MEM
+ x = PyInt_FromLong((long) AL_BAD_OUT_OF_MEM);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_OUT_OF_MEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PARAM
+ x = PyInt_FromLong((long) AL_BAD_PARAM);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PERMISSIONS
+ x = PyInt_FromLong((long) AL_BAD_PERMISSIONS);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PERMISSIONS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PORT
+ x = PyInt_FromLong((long) AL_BAD_PORT);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PORT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PORTSTYLE
+ x = PyInt_FromLong((long) AL_BAD_PORTSTYLE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PORTSTYLE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_PVBUFFER
+ x = PyInt_FromLong((long) AL_BAD_PVBUFFER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PVBUFFER", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_QSIZE
+ x = PyInt_FromLong((long) AL_BAD_QSIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_QSIZE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_RATE
+ x = PyInt_FromLong((long) AL_BAD_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_RATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_RESOURCE
+ x = PyInt_FromLong((long) AL_BAD_RESOURCE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_RESOURCE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_SAMPFMT
+ x = PyInt_FromLong((long) AL_BAD_SAMPFMT);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_SAMPFMT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_TRANSFER_SIZE
+ x = PyInt_FromLong((long) AL_BAD_TRANSFER_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_TRANSFER_SIZE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_BAD_WIDTH
+ x = PyInt_FromLong((long) AL_BAD_WIDTH);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_WIDTH", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CHANNEL_MODE
+ x = PyInt_FromLong((long) AL_CHANNEL_MODE);
+ if (x == NULL || PyDict_SetItemString(d, "CHANNEL_MODE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CHANNELS
+ x = PyInt_FromLong((long) AL_CHANNELS);
+ if (x == NULL || PyDict_SetItemString(d, "CHANNELS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CHAR_ELEM
+ x = PyInt_FromLong((long) AL_CHAR_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "CHAR_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CLOCK_GEN
+ x = PyInt_FromLong((long) AL_CLOCK_GEN);
+ if (x == NULL || PyDict_SetItemString(d, "CLOCK_GEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CLOCKGEN_TYPE
+ x = PyInt_FromLong((long) AL_CLOCKGEN_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "CLOCKGEN_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CONNECT
+ x = PyInt_FromLong((long) AL_CONNECT);
+ if (x == NULL || PyDict_SetItemString(d, "CONNECT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CONNECTION_TYPE
+ x = PyInt_FromLong((long) AL_CONNECTION_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "CONNECTION_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CONNECTIONS
+ x = PyInt_FromLong((long) AL_CONNECTIONS);
+ if (x == NULL || PyDict_SetItemString(d, "CONNECTIONS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_CRYSTAL_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_CRYSTAL_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "CRYSTAL_MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DEFAULT_DEVICE
+ x = PyInt_FromLong((long) AL_DEFAULT_DEVICE);
+ if (x == NULL || PyDict_SetItemString(d, "DEFAULT_DEVICE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DEFAULT_INPUT
+ x = PyInt_FromLong((long) AL_DEFAULT_INPUT);
+ if (x == NULL || PyDict_SetItemString(d, "DEFAULT_INPUT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DEFAULT_OUTPUT
+ x = PyInt_FromLong((long) AL_DEFAULT_OUTPUT);
+ if (x == NULL || PyDict_SetItemString(d, "DEFAULT_OUTPUT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DEST
+ x = PyInt_FromLong((long) AL_DEST);
+ if (x == NULL || PyDict_SetItemString(d, "DEST", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DEVICE_TYPE
+ x = PyInt_FromLong((long) AL_DEVICE_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "DEVICE_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DEVICES
+ x = PyInt_FromLong((long) AL_DEVICES);
+ if (x == NULL || PyDict_SetItemString(d, "DEVICES", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DIGITAL_IF_TYPE
+ x = PyInt_FromLong((long) AL_DIGITAL_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "DIGITAL_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DIGITAL_INPUT_RATE
+ x = PyInt_FromLong((long) AL_DIGITAL_INPUT_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "DIGITAL_INPUT_RATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_DISCONNECT
+ x = PyInt_FromLong((long) AL_DISCONNECT);
+ if (x == NULL || PyDict_SetItemString(d, "DISCONNECT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ENUM_ELEM
+ x = PyInt_FromLong((long) AL_ENUM_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "ENUM_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ENUM_VALUE
+ x = PyInt_FromLong((long) AL_ENUM_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "ENUM_VALUE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_INPUT_OVERFLOW
+ x = PyInt_FromLong((long) AL_ERROR_INPUT_OVERFLOW);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_INPUT_OVERFLOW", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_LENGTH
+ x = PyInt_FromLong((long) AL_ERROR_LENGTH);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_LENGTH", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_LOCATION_LSP
+ x = PyInt_FromLong((long) AL_ERROR_LOCATION_LSP);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_LOCATION_LSP", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_LOCATION_MSP
+ x = PyInt_FromLong((long) AL_ERROR_LOCATION_MSP);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_LOCATION_MSP", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_NUMBER
+ x = PyInt_FromLong((long) AL_ERROR_NUMBER);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_NUMBER", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_OUTPUT_UNDERFLOW
+ x = PyInt_FromLong((long) AL_ERROR_OUTPUT_UNDERFLOW);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_OUTPUT_UNDERFLOW", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_ERROR_TYPE
+ x = PyInt_FromLong((long) AL_ERROR_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "ERROR_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_FIXED_ELEM
+ x = PyInt_FromLong((long) AL_FIXED_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "FIXED_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_FIXED_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_FIXED_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "FIXED_MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_GAIN
+ x = PyInt_FromLong((long) AL_GAIN);
+ if (x == NULL || PyDict_SetItemString(d, "GAIN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_GAIN_REF
+ x = PyInt_FromLong((long) AL_GAIN_REF);
+ if (x == NULL || PyDict_SetItemString(d, "GAIN_REF", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_HRB_TYPE
+ x = PyInt_FromLong((long) AL_HRB_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "HRB_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_COUNT
+ x = PyInt_FromLong((long) AL_INPUT_COUNT);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_COUNT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_DEVICE_TYPE
+ x = PyInt_FromLong((long) AL_INPUT_DEVICE_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_DEVICE_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_DIGITAL
+ x = PyInt_FromLong((long) AL_INPUT_DIGITAL);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_DIGITAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_HRB_TYPE
+ x = PyInt_FromLong((long) AL_INPUT_HRB_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_HRB_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_LINE
+ x = PyInt_FromLong((long) AL_INPUT_LINE);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_LINE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_MIC
+ x = PyInt_FromLong((long) AL_INPUT_MIC);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_MIC", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_PORT_TYPE
+ x = PyInt_FromLong((long) AL_INPUT_PORT_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_PORT_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_RATE
+ x = PyInt_FromLong((long) AL_INPUT_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_RATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INPUT_SOURCE
+ x = PyInt_FromLong((long) AL_INPUT_SOURCE);
+ if (x == NULL || PyDict_SetItemString(d, "INPUT_SOURCE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INT32_ELEM
+ x = PyInt_FromLong((long) AL_INT32_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "INT32_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INT64_ELEM
+ x = PyInt_FromLong((long) AL_INT64_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "INT64_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INTERFACE
+ x = PyInt_FromLong((long) AL_INTERFACE);
+ if (x == NULL || PyDict_SetItemString(d, "INTERFACE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INTERFACE_TYPE
+ x = PyInt_FromLong((long) AL_INTERFACE_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "INTERFACE_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INVALID_PARAM
+ x = PyInt_FromLong((long) AL_INVALID_PARAM);
+ if (x == NULL || PyDict_SetItemString(d, "INVALID_PARAM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_INVALID_VALUE
+ x = PyInt_FromLong((long) AL_INVALID_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "INVALID_VALUE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_JITTER
+ x = PyInt_FromLong((long) AL_JITTER);
+ if (x == NULL || PyDict_SetItemString(d, "JITTER", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LABEL
+ x = PyInt_FromLong((long) AL_LABEL);
+ if (x == NULL || PyDict_SetItemString(d, "LABEL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LEFT_INPUT_ATTEN
+ x = PyInt_FromLong((long) AL_LEFT_INPUT_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "LEFT_INPUT_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LEFT_MONITOR_ATTEN
+ x = PyInt_FromLong((long) AL_LEFT_MONITOR_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "LEFT_MONITOR_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LEFT_SPEAKER_GAIN
+ x = PyInt_FromLong((long) AL_LEFT_SPEAKER_GAIN);
+ if (x == NULL || PyDict_SetItemString(d, "LEFT_SPEAKER_GAIN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LEFT1_INPUT_ATTEN
+ x = PyInt_FromLong((long) AL_LEFT1_INPUT_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "LEFT1_INPUT_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LEFT2_INPUT_ATTEN
+ x = PyInt_FromLong((long) AL_LEFT2_INPUT_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "LEFT2_INPUT_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LINE_IF_TYPE
+ x = PyInt_FromLong((long) AL_LINE_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "LINE_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_LOCKED
+ x = PyInt_FromLong((long) AL_LOCKED);
+ if (x == NULL || PyDict_SetItemString(d, "LOCKED", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MASTER_CLOCK
+ x = PyInt_FromLong((long) AL_MASTER_CLOCK);
+ if (x == NULL || PyDict_SetItemString(d, "MASTER_CLOCK", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MATRIX_VAL
+ x = PyInt_FromLong((long) AL_MATRIX_VAL);
+ if (x == NULL || PyDict_SetItemString(d, "MATRIX_VAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_ERROR
+ x = PyInt_FromLong((long) AL_MAX_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_ERROR", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_EVENT_PARAM
+ x = PyInt_FromLong((long) AL_MAX_EVENT_PARAM);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_EVENT_PARAM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_PBUFSIZE
+ x = PyInt_FromLong((long) AL_MAX_PBUFSIZE);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_PBUFSIZE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_PORTS
+ x = PyInt_FromLong((long) AL_MAX_PORTS);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_PORTS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_RESOURCE_ID
+ x = PyInt_FromLong((long) AL_MAX_RESOURCE_ID);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_RESOURCE_ID", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_SETSIZE
+ x = PyInt_FromLong((long) AL_MAX_SETSIZE);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_SETSIZE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MAX_STRLEN
+ x = PyInt_FromLong((long) AL_MAX_STRLEN);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_STRLEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MIC_IF_TYPE
+ x = PyInt_FromLong((long) AL_MIC_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "MIC_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MONITOR_CTL
+ x = PyInt_FromLong((long) AL_MONITOR_CTL);
+ if (x == NULL || PyDict_SetItemString(d, "MONITOR_CTL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MONITOR_OFF
+ x = PyInt_FromLong((long) AL_MONITOR_OFF);
+ if (x == NULL || PyDict_SetItemString(d, "MONITOR_OFF", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MONITOR_ON
+ x = PyInt_FromLong((long) AL_MONITOR_ON);
+ if (x == NULL || PyDict_SetItemString(d, "MONITOR_ON", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MONO
+ x = PyInt_FromLong((long) AL_MONO);
+ if (x == NULL || PyDict_SetItemString(d, "MONO", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_MUTE
+ x = PyInt_FromLong((long) AL_MUTE);
+ if (x == NULL || PyDict_SetItemString(d, "MUTE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NAME
+ x = PyInt_FromLong((long) AL_NAME);
+ if (x == NULL || PyDict_SetItemString(d, "NAME", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NEG_INFINITY
+ x = PyInt_FromLong((long) AL_NEG_INFINITY);
+ if (x == NULL || PyDict_SetItemString(d, "NEG_INFINITY", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NEG_INFINITY_BIT
+ x = PyInt_FromLong((long) AL_NEG_INFINITY_BIT);
+ if (x == NULL || PyDict_SetItemString(d, "NEG_INFINITY_BIT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NO_CHANGE
+ x = PyInt_FromLong((long) AL_NO_CHANGE);
+ if (x == NULL || PyDict_SetItemString(d, "NO_CHANGE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NO_CHANGE_BIT
+ x = PyInt_FromLong((long) AL_NO_CHANGE_BIT);
+ if (x == NULL || PyDict_SetItemString(d, "NO_CHANGE_BIT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NO_ELEM
+ x = PyInt_FromLong((long) AL_NO_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "NO_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NO_ERRORS
+ x = PyInt_FromLong((long) AL_NO_ERRORS);
+ if (x == NULL || PyDict_SetItemString(d, "NO_ERRORS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NO_OP
+ x = PyInt_FromLong((long) AL_NO_OP);
+ if (x == NULL || PyDict_SetItemString(d, "NO_OP", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NO_VAL
+ x = PyInt_FromLong((long) AL_NO_VAL);
+ if (x == NULL || PyDict_SetItemString(d, "NO_VAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NULL_INTERFACE
+ x = PyInt_FromLong((long) AL_NULL_INTERFACE);
+ if (x == NULL || PyDict_SetItemString(d, "NULL_INTERFACE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_NULL_RESOURCE
+ x = PyInt_FromLong((long) AL_NULL_RESOURCE);
+ if (x == NULL || PyDict_SetItemString(d, "NULL_RESOURCE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_OPTICAL_IF_TYPE
+ x = PyInt_FromLong((long) AL_OPTICAL_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "OPTICAL_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_COUNT
+ x = PyInt_FromLong((long) AL_OUTPUT_COUNT);
+ if (x == NULL || PyDict_SetItemString(d, "OUTPUT_COUNT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_DEVICE_TYPE
+ x = PyInt_FromLong((long) AL_OUTPUT_DEVICE_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "OUTPUT_DEVICE_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_HRB_TYPE
+ x = PyInt_FromLong((long) AL_OUTPUT_HRB_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "OUTPUT_HRB_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_PORT_TYPE
+ x = PyInt_FromLong((long) AL_OUTPUT_PORT_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "OUTPUT_PORT_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_OUTPUT_RATE
+ x = PyInt_FromLong((long) AL_OUTPUT_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "OUTPUT_RATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PARAM_BIT
+ x = PyInt_FromLong((long) AL_PARAM_BIT);
+ if (x == NULL || PyDict_SetItemString(d, "PARAM_BIT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PARAMS
+ x = PyInt_FromLong((long) AL_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "PARAMS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PORT_COUNT
+ x = PyInt_FromLong((long) AL_PORT_COUNT);
+ if (x == NULL || PyDict_SetItemString(d, "PORT_COUNT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PORT_TYPE
+ x = PyInt_FromLong((long) AL_PORT_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "PORT_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PORTS
+ x = PyInt_FromLong((long) AL_PORTS);
+ if (x == NULL || PyDict_SetItemString(d, "PORTS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PORTSTYLE_DIRECT
+ x = PyInt_FromLong((long) AL_PORTSTYLE_DIRECT);
+ if (x == NULL || PyDict_SetItemString(d, "PORTSTYLE_DIRECT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PORTSTYLE_SERIAL
+ x = PyInt_FromLong((long) AL_PORTSTYLE_SERIAL);
+ if (x == NULL || PyDict_SetItemString(d, "PORTSTYLE_SERIAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PRINT_ERRORS
+ x = PyInt_FromLong((long) AL_PRINT_ERRORS);
+ if (x == NULL || PyDict_SetItemString(d, "PRINT_ERRORS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_PTR_ELEM
+ x = PyInt_FromLong((long) AL_PTR_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "PTR_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RANGE_VALUE
+ x = PyInt_FromLong((long) AL_RANGE_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "RANGE_VALUE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE
+ x = PyInt_FromLong((long) AL_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "RATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_11025
+ x = PyInt_FromLong((long) AL_RATE_11025);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_11025", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_16000
+ x = PyInt_FromLong((long) AL_RATE_16000);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_16000", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_22050
+ x = PyInt_FromLong((long) AL_RATE_22050);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_22050", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_32000
+ x = PyInt_FromLong((long) AL_RATE_32000);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_32000", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_44100
+ x = PyInt_FromLong((long) AL_RATE_44100);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_44100", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_48000
+ x = PyInt_FromLong((long) AL_RATE_48000);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_48000", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_8000
+ x = PyInt_FromLong((long) AL_RATE_8000);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_8000", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_1
+ x = PyInt_FromLong((long) AL_RATE_AES_1);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_AES_1", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_1s
+ x = PyInt_FromLong((long) AL_RATE_AES_1s);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_AES_1s", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_2
+ x = PyInt_FromLong((long) AL_RATE_AES_2);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_AES_2", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_3
+ x = PyInt_FromLong((long) AL_RATE_AES_3);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_AES_3", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_4
+ x = PyInt_FromLong((long) AL_RATE_AES_4);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_AES_4", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_AES_6
+ x = PyInt_FromLong((long) AL_RATE_AES_6);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_AES_6", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_FRACTION_D
+ x = PyInt_FromLong((long) AL_RATE_FRACTION_D);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_FRACTION_D", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_FRACTION_N
+ x = PyInt_FromLong((long) AL_RATE_FRACTION_N);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_FRACTION_N", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_INPUTRATE
+ x = PyInt_FromLong((long) AL_RATE_INPUTRATE);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_INPUTRATE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_NO_DIGITAL_INPUT
+ x = PyInt_FromLong((long) AL_RATE_NO_DIGITAL_INPUT);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_NO_DIGITAL_INPUT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_UNACQUIRED
+ x = PyInt_FromLong((long) AL_RATE_UNACQUIRED);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_UNACQUIRED", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RATE_UNDEFINED
+ x = PyInt_FromLong((long) AL_RATE_UNDEFINED);
+ if (x == NULL || PyDict_SetItemString(d, "RATE_UNDEFINED", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_REF_0DBV
+ x = PyInt_FromLong((long) AL_REF_0DBV);
+ if (x == NULL || PyDict_SetItemString(d, "REF_0DBV", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_REF_NONE
+ x = PyInt_FromLong((long) AL_REF_NONE);
+ if (x == NULL || PyDict_SetItemString(d, "REF_NONE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED1_TYPE
+ x = PyInt_FromLong((long) AL_RESERVED1_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "RESERVED1_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED2_TYPE
+ x = PyInt_FromLong((long) AL_RESERVED2_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "RESERVED2_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED3_TYPE
+ x = PyInt_FromLong((long) AL_RESERVED3_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "RESERVED3_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESERVED4_TYPE
+ x = PyInt_FromLong((long) AL_RESERVED4_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "RESERVED4_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESOURCE
+ x = PyInt_FromLong((long) AL_RESOURCE);
+ if (x == NULL || PyDict_SetItemString(d, "RESOURCE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESOURCE_ELEM
+ x = PyInt_FromLong((long) AL_RESOURCE_ELEM);
+ if (x == NULL || PyDict_SetItemString(d, "RESOURCE_ELEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RESOURCE_TYPE
+ x = PyInt_FromLong((long) AL_RESOURCE_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "RESOURCE_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT_INPUT_ATTEN
+ x = PyInt_FromLong((long) AL_RIGHT_INPUT_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "RIGHT_INPUT_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT_MONITOR_ATTEN
+ x = PyInt_FromLong((long) AL_RIGHT_MONITOR_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "RIGHT_MONITOR_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT_SPEAKER_GAIN
+ x = PyInt_FromLong((long) AL_RIGHT_SPEAKER_GAIN);
+ if (x == NULL || PyDict_SetItemString(d, "RIGHT_SPEAKER_GAIN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT1_INPUT_ATTEN
+ x = PyInt_FromLong((long) AL_RIGHT1_INPUT_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "RIGHT1_INPUT_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_RIGHT2_INPUT_ATTEN
+ x = PyInt_FromLong((long) AL_RIGHT2_INPUT_ATTEN);
+ if (x == NULL || PyDict_SetItemString(d, "RIGHT2_INPUT_ATTEN", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SAMPFMT_DOUBLE
+ x = PyInt_FromLong((long) AL_SAMPFMT_DOUBLE);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPFMT_DOUBLE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SAMPFMT_FLOAT
+ x = PyInt_FromLong((long) AL_SAMPFMT_FLOAT);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPFMT_FLOAT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SAMPFMT_TWOSCOMP
+ x = PyInt_FromLong((long) AL_SAMPFMT_TWOSCOMP);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPFMT_TWOSCOMP", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SAMPLE_16
+ x = PyInt_FromLong((long) AL_SAMPLE_16);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPLE_16", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SAMPLE_24
+ x = PyInt_FromLong((long) AL_SAMPLE_24);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPLE_24", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SAMPLE_8
+ x = PyInt_FromLong((long) AL_SAMPLE_8);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPLE_8", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SCALAR_VAL
+ x = PyInt_FromLong((long) AL_SCALAR_VAL);
+ if (x == NULL || PyDict_SetItemString(d, "SCALAR_VAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SET_VAL
+ x = PyInt_FromLong((long) AL_SET_VAL);
+ if (x == NULL || PyDict_SetItemString(d, "SET_VAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SHORT_NAME
+ x = PyInt_FromLong((long) AL_SHORT_NAME);
+ if (x == NULL || PyDict_SetItemString(d, "SHORT_NAME", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SMPTE272M_IF_TYPE
+ x = PyInt_FromLong((long) AL_SMPTE272M_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "SMPTE272M_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SOURCE
+ x = PyInt_FromLong((long) AL_SOURCE);
+ if (x == NULL || PyDict_SetItemString(d, "SOURCE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_IF_TYPE
+ x = PyInt_FromLong((long) AL_SPEAKER_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "SPEAKER_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_MUTE_CTL
+ x = PyInt_FromLong((long) AL_SPEAKER_MUTE_CTL);
+ if (x == NULL || PyDict_SetItemString(d, "SPEAKER_MUTE_CTL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_MUTE_OFF
+ x = PyInt_FromLong((long) AL_SPEAKER_MUTE_OFF);
+ if (x == NULL || PyDict_SetItemString(d, "SPEAKER_MUTE_OFF", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_MUTE_ON
+ x = PyInt_FromLong((long) AL_SPEAKER_MUTE_ON);
+ if (x == NULL || PyDict_SetItemString(d, "SPEAKER_MUTE_ON", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SPEAKER_PLUS_LINE_IF_TYPE
+ x = PyInt_FromLong((long) AL_SPEAKER_PLUS_LINE_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "SPEAKER_PLUS_LINE_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_STEREO
+ x = PyInt_FromLong((long) AL_STEREO);
+ if (x == NULL || PyDict_SetItemString(d, "STEREO", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_STRING_VAL
+ x = PyInt_FromLong((long) AL_STRING_VAL);
+ if (x == NULL || PyDict_SetItemString(d, "STRING_VAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SUBSYSTEM
+ x = PyInt_FromLong((long) AL_SUBSYSTEM);
+ if (x == NULL || PyDict_SetItemString(d, "SUBSYSTEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SUBSYSTEM_TYPE
+ x = PyInt_FromLong((long) AL_SUBSYSTEM_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "SUBSYSTEM_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SYNC_INPUT_TO_AES
+ x = PyInt_FromLong((long) AL_SYNC_INPUT_TO_AES);
+ if (x == NULL || PyDict_SetItemString(d, "SYNC_INPUT_TO_AES", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SYNC_OUTPUT_TO_AES
+ x = PyInt_FromLong((long) AL_SYNC_OUTPUT_TO_AES);
+ if (x == NULL || PyDict_SetItemString(d, "SYNC_OUTPUT_TO_AES", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SYSTEM
+ x = PyInt_FromLong((long) AL_SYSTEM);
+ if (x == NULL || PyDict_SetItemString(d, "SYSTEM", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_SYSTEM_TYPE
+ x = PyInt_FromLong((long) AL_SYSTEM_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "SYSTEM_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_TEST_IF_TYPE
+ x = PyInt_FromLong((long) AL_TEST_IF_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "TEST_IF_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_TYPE
+ x = PyInt_FromLong((long) AL_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_TYPE_BIT
+ x = PyInt_FromLong((long) AL_TYPE_BIT);
+ if (x == NULL || PyDict_SetItemString(d, "TYPE_BIT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_UNUSED_COUNT
+ x = PyInt_FromLong((long) AL_UNUSED_COUNT);
+ if (x == NULL || PyDict_SetItemString(d, "UNUSED_COUNT", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_UNUSED_PORTS
+ x = PyInt_FromLong((long) AL_UNUSED_PORTS);
+ if (x == NULL || PyDict_SetItemString(d, "UNUSED_PORTS", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_VARIABLE_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_VARIABLE_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "VARIABLE_MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_VECTOR_VAL
+ x = PyInt_FromLong((long) AL_VECTOR_VAL);
+ if (x == NULL || PyDict_SetItemString(d, "VECTOR_VAL", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_VIDEO_MCLK_TYPE
+ x = PyInt_FromLong((long) AL_VIDEO_MCLK_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "VIDEO_MCLK_TYPE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+#ifdef AL_WORDSIZE
+ x = PyInt_FromLong((long) AL_WORDSIZE);
+ if (x == NULL || PyDict_SetItemString(d, "WORDSIZE", x) < 0)
+ goto error;
+ Py_DECREF(x);
+#endif
+
+#ifdef AL_NO_ELEM /* IRIX 6 */
+ (void) alSetErrorHandler(ErrorHandler);
+#endif /* AL_NO_ELEM */
+#ifdef OLD_INTERFACE
+ (void) ALseterrorhandler(ErrorHandler);
+#endif /* OLD_INTERFACE */
+
+ error:
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/ar_beos b/sys/src/cmd/python/Modules/ar_beos
new file mode 100755
index 000000000..e7efa7540
--- /dev/null
+++ b/sys/src/cmd/python/Modules/ar_beos
@@ -0,0 +1,73 @@
+#!/bin/sh
+#
+# Truly fake ar, using a directory to store object files.
+#
+# Donn Cave, donn@oz.net
+
+usage='Usage: ar-fake cr libpython.dir obj.o ...
+ ar-fake d libpython.dir obj.o ...
+ ar-fake so libpython.dir libpython.so'
+
+case $# in
+0|1|2)
+ echo "$usage" >&2
+ exit 1
+ ;;
+esac
+
+command=$1
+library=$2
+shift 2
+
+case $command in
+cr)
+ if test -d $library
+ then :
+ else
+ mkdir $library
+ fi
+ if cp -p $* $library
+ then
+ # To force directory modify date, create or delete a file.
+ if test -e $library/.tch
+ then rm $library/.tch
+ else echo tch > $library/.tch
+ fi
+ exit 0
+ fi
+ ;;
+d)
+ if test -d $library
+ then
+ cd $library
+ rm -f $*
+ fi
+ ;;
+so)
+ case $BE_HOST_CPU in
+ ppc)
+ # In case your libpython.a refers to any exotic libraries,
+ # mwld needs to know that here. The following hack makes
+ # a couple of assumptions about Modules/Makefile. If it
+ # doesn't work, you may as well add the necessary libraries
+ # here explicitly instead.
+ extralibs=$(
+ (cd Modules; make -f Makefile -n link) |
+ sed -n 's/.*\.so \(.*\) -o python.*/\1/p'
+ )
+ mwld -xms -export pragma -nodup -o $1 $library/* $extralibs
+ ;;
+ x86)
+ ld -shared -soname $(basename $1) -o $1 $library/*
+ ;;
+ esac
+ status=$?
+ cd $(dirname $1)
+ ln -sf $PWD lib
+ exit $status
+ ;;
+*)
+ echo "$usage" >&2
+ exit 1
+ ;;
+esac
diff --git a/sys/src/cmd/python/Modules/arraymodule.c b/sys/src/cmd/python/Modules/arraymodule.c
new file mode 100644
index 000000000..3ba5cf88e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/arraymodule.c
@@ -0,0 +1,2141 @@
+/* Array object implementation */
+
+/* An array is a uniform list -- all items have the same type.
+ The item type is restricted to simple C types like int or float */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef STDC_HEADERS
+#include <stddef.h>
+#else /* !STDC_HEADERS */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h> /* For size_t */
+#endif /* HAVE_SYS_TYPES_H */
+#endif /* !STDC_HEADERS */
+
+struct arrayobject; /* Forward */
+
+/* All possible arraydescr values are defined in the vector "descriptors"
+ * below. That's defined later because the appropriate get and set
+ * functions aren't visible yet.
+ */
+struct arraydescr {
+ int typecode;
+ int itemsize;
+ PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
+ int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
+};
+
+typedef struct arrayobject {
+ PyObject_VAR_HEAD
+ char *ob_item;
+ Py_ssize_t allocated;
+ struct arraydescr *ob_descr;
+ PyObject *weakreflist; /* List of weak references */
+} arrayobject;
+
+static PyTypeObject Arraytype;
+
+#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
+#define array_CheckExact(op) ((op)->ob_type == &Arraytype)
+
+static int
+array_resize(arrayobject *self, Py_ssize_t newsize)
+{
+ char *items;
+ size_t _new_size;
+
+ /* Bypass realloc() when a previous overallocation is large enough
+ to accommodate the newsize. If the newsize is 16 smaller than the
+ current size, then proceed with the realloc() to shrink the list.
+ */
+
+ if (self->allocated >= newsize &&
+ self->ob_size < newsize + 16 &&
+ self->ob_item != NULL) {
+ self->ob_size = newsize;
+ return 0;
+ }
+
+ /* This over-allocates proportional to the array size, making room
+ * for additional growth. The over-allocation is mild, but is
+ * enough to give linear-time amortized behavior over a long
+ * sequence of appends() in the presence of a poorly-performing
+ * system realloc().
+ * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
+ * Note, the pattern starts out the same as for lists but then
+ * grows at a smaller rate so that larger arrays only overallocate
+ * by about 1/16th -- this is done because arrays are presumed to be more
+ * memory critical.
+ */
+
+ _new_size = (newsize >> 4) + (self->ob_size < 8 ? 3 : 7) + newsize;
+ items = self->ob_item;
+ /* XXX The following multiplication and division does not optimize away
+ like it does for lists since the size is not known at compile time */
+ if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
+ PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
+ else
+ items = NULL;
+ if (items == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->ob_item = items;
+ self->ob_size = newsize;
+ self->allocated = _new_size;
+ return 0;
+}
+
+/****************************************************************************
+Get and Set functions for each type.
+A Get function takes an arrayobject* and an integer index, returning the
+array value at that index wrapped in an appropriate PyObject*.
+A Set function takes an arrayobject, integer index, and PyObject*; sets
+the array value at that index to the raw C data extracted from the PyObject*,
+and returns 0 if successful, else nonzero on failure (PyObject* not of an
+appropriate type or value).
+Note that the basic Get and Set functions do NOT check that the index is
+in bounds; that's the responsibility of the caller.
+****************************************************************************/
+
+static PyObject *
+c_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
+}
+
+static int
+c_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ char x;
+ if (!PyArg_Parse(v, "c;array item must be char", &x))
+ return -1;
+ if (i >= 0)
+ ((char *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+b_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ long x = ((char *)ap->ob_item)[i];
+ if (x >= 128)
+ x -= 256;
+ return PyInt_FromLong(x);
+}
+
+static int
+b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ short x;
+ /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
+ must use the next size up that is signed ('h') and manually do
+ the overflow checking */
+ if (!PyArg_Parse(v, "h;array item must be integer", &x))
+ return -1;
+ else if (x < -128) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed char is less than minimum");
+ return -1;
+ }
+ else if (x > 127) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed char is greater than maximum");
+ return -1;
+ }
+ if (i >= 0)
+ ((char *)ap->ob_item)[i] = (char)x;
+ return 0;
+}
+
+static PyObject *
+BB_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ long x = ((unsigned char *)ap->ob_item)[i];
+ return PyInt_FromLong(x);
+}
+
+static int
+BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ unsigned char x;
+ /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
+ if (!PyArg_Parse(v, "b;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((char *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+u_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
+}
+
+static int
+u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ Py_UNICODE *p;
+ Py_ssize_t len;
+
+ if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
+ return -1;
+ if (len != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "array item must be unicode character");
+ return -1;
+ }
+ if (i >= 0)
+ ((Py_UNICODE *)ap->ob_item)[i] = p[0];
+ return 0;
+}
+#endif
+
+static PyObject *
+h_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
+}
+
+static int
+h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ short x;
+ /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
+ if (!PyArg_Parse(v, "h;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((short *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+HH_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
+}
+
+static int
+HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ int x;
+ /* PyArg_Parse's 'h' formatter is for a signed short, therefore
+ must use the next size up and manually do the overflow checking */
+ if (!PyArg_Parse(v, "i;array item must be integer", &x))
+ return -1;
+ else if (x < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned short is less than minimum");
+ return -1;
+ }
+ else if (x > USHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned short is greater than maximum");
+ return -1;
+ }
+ if (i >= 0)
+ ((short *)ap->ob_item)[i] = (short)x;
+ return 0;
+}
+
+static PyObject *
+i_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
+}
+
+static int
+i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ int x;
+ /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
+ if (!PyArg_Parse(v, "i;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((int *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+II_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyLong_FromUnsignedLong(
+ (unsigned long) ((unsigned int *)ap->ob_item)[i]);
+}
+
+static int
+II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ unsigned long x;
+ if (PyLong_Check(v)) {
+ x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return -1;
+ }
+ else {
+ long y;
+ if (!PyArg_Parse(v, "l;array item must be integer", &y))
+ return -1;
+ if (y < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned int is less than minimum");
+ return -1;
+ }
+ x = (unsigned long)y;
+
+ }
+ if (x > UINT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned int is greater than maximum");
+ return -1;
+ }
+
+ if (i >= 0)
+ ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
+ return 0;
+}
+
+static PyObject *
+l_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyInt_FromLong(((long *)ap->ob_item)[i]);
+}
+
+static int
+l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ long x;
+ if (!PyArg_Parse(v, "l;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((long *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+LL_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
+}
+
+static int
+LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ unsigned long x;
+ if (PyLong_Check(v)) {
+ x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return -1;
+ }
+ else {
+ long y;
+ if (!PyArg_Parse(v, "l;array item must be integer", &y))
+ return -1;
+ if (y < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned long is less than minimum");
+ return -1;
+ }
+ x = (unsigned long)y;
+
+ }
+ if (x > ULONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned long is greater than maximum");
+ return -1;
+ }
+
+ if (i >= 0)
+ ((unsigned long *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+f_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
+}
+
+static int
+f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ float x;
+ if (!PyArg_Parse(v, "f;array item must be float", &x))
+ return -1;
+ if (i >= 0)
+ ((float *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+d_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
+}
+
+static int
+d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ double x;
+ if (!PyArg_Parse(v, "d;array item must be float", &x))
+ return -1;
+ if (i >= 0)
+ ((double *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+/* Description of types */
+static struct arraydescr descriptors[] = {
+ {'c', sizeof(char), c_getitem, c_setitem},
+ {'b', sizeof(char), b_getitem, b_setitem},
+ {'B', sizeof(char), BB_getitem, BB_setitem},
+#ifdef Py_USING_UNICODE
+ {'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
+#endif
+ {'h', sizeof(short), h_getitem, h_setitem},
+ {'H', sizeof(short), HH_getitem, HH_setitem},
+ {'i', sizeof(int), i_getitem, i_setitem},
+ {'I', sizeof(int), II_getitem, II_setitem},
+ {'l', sizeof(long), l_getitem, l_setitem},
+ {'L', sizeof(long), LL_getitem, LL_setitem},
+ {'f', sizeof(float), f_getitem, f_setitem},
+ {'d', sizeof(double), d_getitem, d_setitem},
+ {'\0', 0, 0, 0} /* Sentinel */
+};
+
+/****************************************************************************
+Implementations of array object methods.
+****************************************************************************/
+
+static PyObject *
+newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
+{
+ arrayobject *op;
+ size_t nbytes;
+
+ if (size < 0) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ nbytes = size * descr->itemsize;
+ /* Check for overflow */
+ if (nbytes / descr->itemsize != (size_t)size) {
+ return PyErr_NoMemory();
+ }
+ op = (arrayobject *) type->tp_alloc(type, 0);
+ if (op == NULL) {
+ return NULL;
+ }
+ op->ob_size = size;
+ if (size <= 0) {
+ op->ob_item = NULL;
+ }
+ else {
+ op->ob_item = PyMem_NEW(char, nbytes);
+ if (op->ob_item == NULL) {
+ PyObject_Del(op);
+ return PyErr_NoMemory();
+ }
+ }
+ op->ob_descr = descr;
+ op->allocated = size;
+ op->weakreflist = NULL;
+ return (PyObject *) op;
+}
+
+static PyObject *
+getarrayitem(PyObject *op, Py_ssize_t i)
+{
+ register arrayobject *ap;
+ assert(array_Check(op));
+ ap = (arrayobject *)op;
+ assert(i>=0 && i<ap->ob_size);
+ return (*ap->ob_descr->getitem)(ap, i);
+}
+
+static int
+ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
+{
+ char *items;
+ Py_ssize_t n = self->ob_size;
+ if (v == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if ((*self->ob_descr->setitem)(self, -1, v) < 0)
+ return -1;
+
+ if (array_resize(self, n+1) == -1)
+ return -1;
+ items = self->ob_item;
+ if (where < 0) {
+ where += n;
+ if (where < 0)
+ where = 0;
+ }
+ if (where > n)
+ where = n;
+ /* appends don't need to call memmove() */
+ if (where != n)
+ memmove(items + (where+1)*self->ob_descr->itemsize,
+ items + where*self->ob_descr->itemsize,
+ (n-where)*self->ob_descr->itemsize);
+ return (*self->ob_descr->setitem)(self, where, v);
+}
+
+/* Methods */
+
+static void
+array_dealloc(arrayobject *op)
+{
+ if (op->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) op);
+ if (op->ob_item != NULL)
+ PyMem_DEL(op->ob_item);
+ op->ob_type->tp_free((PyObject *)op);
+}
+
+static PyObject *
+array_richcompare(PyObject *v, PyObject *w, int op)
+{
+ arrayobject *va, *wa;
+ PyObject *vi = NULL;
+ PyObject *wi = NULL;
+ Py_ssize_t i, k;
+ PyObject *res;
+
+ if (!array_Check(v) || !array_Check(w)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ va = (arrayobject *)v;
+ wa = (arrayobject *)w;
+
+ if (va->ob_size != wa->ob_size && (op == Py_EQ || op == Py_NE)) {
+ /* Shortcut: if the lengths differ, the arrays differ */
+ if (op == Py_EQ)
+ res = Py_False;
+ else
+ res = Py_True;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* Search for the first index where items are different */
+ k = 1;
+ for (i = 0; i < va->ob_size && i < wa->ob_size; i++) {
+ vi = getarrayitem(v, i);
+ wi = getarrayitem(w, i);
+ if (vi == NULL || wi == NULL) {
+ Py_XDECREF(vi);
+ Py_XDECREF(wi);
+ return NULL;
+ }
+ k = PyObject_RichCompareBool(vi, wi, Py_EQ);
+ if (k == 0)
+ break; /* Keeping vi and wi alive! */
+ Py_DECREF(vi);
+ Py_DECREF(wi);
+ if (k < 0)
+ return NULL;
+ }
+
+ if (k) {
+ /* No more items to compare -- compare sizes */
+ Py_ssize_t vs = va->ob_size;
+ Py_ssize_t ws = wa->ob_size;
+ int cmp;
+ switch (op) {
+ case Py_LT: cmp = vs < ws; break;
+ case Py_LE: cmp = vs <= ws; break;
+ case Py_EQ: cmp = vs == ws; break;
+ case Py_NE: cmp = vs != ws; break;
+ case Py_GT: cmp = vs > ws; break;
+ case Py_GE: cmp = vs >= ws; break;
+ default: return NULL; /* cannot happen */
+ }
+ if (cmp)
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* We have an item that differs. First, shortcuts for EQ/NE */
+ if (op == Py_EQ) {
+ Py_INCREF(Py_False);
+ res = Py_False;
+ }
+ else if (op == Py_NE) {
+ Py_INCREF(Py_True);
+ res = Py_True;
+ }
+ else {
+ /* Compare the final item again using the proper operator */
+ res = PyObject_RichCompare(vi, wi, op);
+ }
+ Py_DECREF(vi);
+ Py_DECREF(wi);
+ return res;
+}
+
+static Py_ssize_t
+array_length(arrayobject *a)
+{
+ return a->ob_size;
+}
+
+static PyObject *
+array_item(arrayobject *a, Py_ssize_t i)
+{
+ if (i < 0 || i >= a->ob_size) {
+ PyErr_SetString(PyExc_IndexError, "array index out of range");
+ return NULL;
+ }
+ return getarrayitem((PyObject *)a, i);
+}
+
+static PyObject *
+array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+ arrayobject *np;
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > a->ob_size)
+ ilow = a->ob_size;
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > a->ob_size)
+ ihigh = a->ob_size;
+ np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
+ if (np == NULL)
+ return NULL;
+ memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
+ (ihigh-ilow) * a->ob_descr->itemsize);
+ return (PyObject *)np;
+}
+
+static PyObject *
+array_copy(arrayobject *a, PyObject *unused)
+{
+ return array_slice(a, 0, a->ob_size);
+}
+
+PyDoc_STRVAR(copy_doc,
+"copy(array)\n\
+\n\
+ Return a copy of the array.");
+
+static PyObject *
+array_concat(arrayobject *a, PyObject *bb)
+{
+ Py_ssize_t size;
+ arrayobject *np;
+ if (!array_Check(bb)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only append array (not \"%.200s\") to array",
+ bb->ob_type->tp_name);
+ return NULL;
+ }
+#define b ((arrayobject *)bb)
+ if (a->ob_descr != b->ob_descr) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ size = a->ob_size + b->ob_size;
+ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
+ if (np == NULL) {
+ return NULL;
+ }
+ memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
+ memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
+ b->ob_item, b->ob_size*b->ob_descr->itemsize);
+ return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+array_repeat(arrayobject *a, Py_ssize_t n)
+{
+ Py_ssize_t i;
+ Py_ssize_t size;
+ arrayobject *np;
+ char *p;
+ Py_ssize_t nbytes;
+ if (n < 0)
+ n = 0;
+ size = a->ob_size * n;
+ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
+ if (np == NULL)
+ return NULL;
+ p = np->ob_item;
+ nbytes = a->ob_size * a->ob_descr->itemsize;
+ for (i = 0; i < n; i++) {
+ memcpy(p, a->ob_item, nbytes);
+ p += nbytes;
+ }
+ return (PyObject *) np;
+}
+
+static int
+array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+ char *item;
+ Py_ssize_t n; /* Size of replacement array */
+ Py_ssize_t d; /* Change in size */
+#define b ((arrayobject *)v)
+ if (v == NULL)
+ n = 0;
+ else if (array_Check(v)) {
+ n = b->ob_size;
+ if (a == b) {
+ /* Special case "a[i:j] = a" -- copy b first */
+ int ret;
+ v = array_slice(b, 0, n);
+ if (!v)
+ return -1;
+ ret = array_ass_slice(a, ilow, ihigh, v);
+ Py_DECREF(v);
+ return ret;
+ }
+ if (b->ob_descr != a->ob_descr) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "can only assign array (not \"%.200s\") to array slice",
+ v->ob_type->tp_name);
+ return -1;
+ }
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > a->ob_size)
+ ilow = a->ob_size;
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > a->ob_size)
+ ihigh = a->ob_size;
+ item = a->ob_item;
+ d = n - (ihigh-ilow);
+ if (d < 0) { /* Delete -d items */
+ memmove(item + (ihigh+d)*a->ob_descr->itemsize,
+ item + ihigh*a->ob_descr->itemsize,
+ (a->ob_size-ihigh)*a->ob_descr->itemsize);
+ a->ob_size += d;
+ PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
+ /* Can't fail */
+ a->ob_item = item;
+ a->allocated = a->ob_size;
+ }
+ else if (d > 0) { /* Insert d items */
+ PyMem_RESIZE(item, char,
+ (a->ob_size + d)*a->ob_descr->itemsize);
+ if (item == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ memmove(item + (ihigh+d)*a->ob_descr->itemsize,
+ item + ihigh*a->ob_descr->itemsize,
+ (a->ob_size-ihigh)*a->ob_descr->itemsize);
+ a->ob_item = item;
+ a->ob_size += d;
+ a->allocated = a->ob_size;
+ }
+ if (n > 0)
+ memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
+ n*b->ob_descr->itemsize);
+ return 0;
+#undef b
+}
+
+static int
+array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
+{
+ if (i < 0 || i >= a->ob_size) {
+ PyErr_SetString(PyExc_IndexError,
+ "array assignment index out of range");
+ return -1;
+ }
+ if (v == NULL)
+ return array_ass_slice(a, i, i+1, v);
+ return (*a->ob_descr->setitem)(a, i, v);
+}
+
+static int
+setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
+{
+ assert(array_Check(a));
+ return array_ass_item((arrayobject *)a, i, v);
+}
+
+static int
+array_iter_extend(arrayobject *self, PyObject *bb)
+{
+ PyObject *it, *v;
+
+ it = PyObject_GetIter(bb);
+ if (it == NULL)
+ return -1;
+
+ while ((v = PyIter_Next(it)) != NULL) {
+ if (ins1(self, (int) self->ob_size, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(it);
+ return -1;
+ }
+ Py_DECREF(v);
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return -1;
+ return 0;
+}
+
+static int
+array_do_extend(arrayobject *self, PyObject *bb)
+{
+ Py_ssize_t size;
+
+ if (!array_Check(bb))
+ return array_iter_extend(self, bb);
+#define b ((arrayobject *)bb)
+ if (self->ob_descr != b->ob_descr) {
+ PyErr_SetString(PyExc_TypeError,
+ "can only extend with array of same kind");
+ return -1;
+ }
+ size = self->ob_size + b->ob_size;
+ PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
+ if (self->ob_item == NULL) {
+ PyObject_Del(self);
+ PyErr_NoMemory();
+ return -1;
+ }
+ memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
+ b->ob_item, b->ob_size*b->ob_descr->itemsize);
+ self->ob_size = size;
+ self->allocated = size;
+
+ return 0;
+#undef b
+}
+
+static PyObject *
+array_inplace_concat(arrayobject *self, PyObject *bb)
+{
+ if (!array_Check(bb)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only extend array with array (not \"%.200s\")",
+ bb->ob_type->tp_name);
+ return NULL;
+ }
+ if (array_do_extend(self, bb) == -1)
+ return NULL;
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+static PyObject *
+array_inplace_repeat(arrayobject *self, Py_ssize_t n)
+{
+ char *items, *p;
+ Py_ssize_t size, i;
+
+ if (self->ob_size > 0) {
+ if (n < 0)
+ n = 0;
+ items = self->ob_item;
+ size = self->ob_size * self->ob_descr->itemsize;
+ if (n == 0) {
+ PyMem_FREE(items);
+ self->ob_item = NULL;
+ self->ob_size = 0;
+ self->allocated = 0;
+ }
+ else {
+ PyMem_Resize(items, char, n * size);
+ if (items == NULL)
+ return PyErr_NoMemory();
+ p = items;
+ for (i = 1; i < n; i++) {
+ p += size;
+ memcpy(p, items, size);
+ }
+ self->ob_item = items;
+ self->ob_size *= n;
+ self->allocated = self->ob_size;
+ }
+ }
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+
+static PyObject *
+ins(arrayobject *self, Py_ssize_t where, PyObject *v)
+{
+ if (ins1(self, where, v) != 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+array_count(arrayobject *self, PyObject *v)
+{
+ Py_ssize_t count = 0;
+ Py_ssize_t i;
+
+ for (i = 0; i < self->ob_size; i++) {
+ PyObject *selfi = getarrayitem((PyObject *)self, i);
+ int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ Py_DECREF(selfi);
+ if (cmp > 0)
+ count++;
+ else if (cmp < 0)
+ return NULL;
+ }
+ return PyInt_FromSsize_t(count);
+}
+
+PyDoc_STRVAR(count_doc,
+"count(x)\n\
+\n\
+Return number of occurences of x in the array.");
+
+static PyObject *
+array_index(arrayobject *self, PyObject *v)
+{
+ Py_ssize_t i;
+
+ for (i = 0; i < self->ob_size; i++) {
+ PyObject *selfi = getarrayitem((PyObject *)self, i);
+ int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ Py_DECREF(selfi);
+ if (cmp > 0) {
+ return PyInt_FromLong((long)i);
+ }
+ else if (cmp < 0)
+ return NULL;
+ }
+ PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
+ return NULL;
+}
+
+PyDoc_STRVAR(index_doc,
+"index(x)\n\
+\n\
+Return index of first occurence of x in the array.");
+
+static int
+array_contains(arrayobject *self, PyObject *v)
+{
+ Py_ssize_t i;
+ int cmp;
+
+ for (i = 0, cmp = 0 ; cmp == 0 && i < self->ob_size; i++) {
+ PyObject *selfi = getarrayitem((PyObject *)self, i);
+ cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ Py_DECREF(selfi);
+ }
+ return cmp;
+}
+
+static PyObject *
+array_remove(arrayobject *self, PyObject *v)
+{
+ int i;
+
+ for (i = 0; i < self->ob_size; i++) {
+ PyObject *selfi = getarrayitem((PyObject *)self,i);
+ int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ Py_DECREF(selfi);
+ if (cmp > 0) {
+ if (array_ass_slice(self, i, i+1,
+ (PyObject *)NULL) != 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else if (cmp < 0)
+ return NULL;
+ }
+ PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
+ return NULL;
+}
+
+PyDoc_STRVAR(remove_doc,
+"remove(x)\n\
+\n\
+Remove the first occurence of x in the array.");
+
+static PyObject *
+array_pop(arrayobject *self, PyObject *args)
+{
+ Py_ssize_t i = -1;
+ PyObject *v;
+ if (!PyArg_ParseTuple(args, "|n:pop", &i))
+ return NULL;
+ if (self->ob_size == 0) {
+ /* Special-case most common failure cause */
+ PyErr_SetString(PyExc_IndexError, "pop from empty array");
+ return NULL;
+ }
+ if (i < 0)
+ i += self->ob_size;
+ if (i < 0 || i >= self->ob_size) {
+ PyErr_SetString(PyExc_IndexError, "pop index out of range");
+ return NULL;
+ }
+ v = getarrayitem((PyObject *)self,i);
+ if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ return v;
+}
+
+PyDoc_STRVAR(pop_doc,
+"pop([i])\n\
+\n\
+Return the i-th element and delete it from the array. i defaults to -1.");
+
+static PyObject *
+array_extend(arrayobject *self, PyObject *bb)
+{
+ if (array_do_extend(self, bb) == -1)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(extend_doc,
+"extend(array or iterable)\n\
+\n\
+ Append items to the end of the array.");
+
+static PyObject *
+array_insert(arrayobject *self, PyObject *args)
+{
+ Py_ssize_t i;
+ PyObject *v;
+ if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
+ return NULL;
+ return ins(self, i, v);
+}
+
+PyDoc_STRVAR(insert_doc,
+"insert(i,x)\n\
+\n\
+Insert a new item x into the array before position i.");
+
+
+static PyObject *
+array_buffer_info(arrayobject *self, PyObject *unused)
+{
+ PyObject* retval = NULL;
+ retval = PyTuple_New(2);
+ if (!retval)
+ return NULL;
+
+ PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
+ PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
+
+ return retval;
+}
+
+PyDoc_STRVAR(buffer_info_doc,
+"buffer_info() -> (address, length)\n\
+\n\
+Return a tuple (address, length) giving the current memory address and\n\
+the length in items of the buffer used to hold array's contents\n\
+The length should be multiplied by the itemsize attribute to calculate\n\
+the buffer length in bytes.");
+
+
+static PyObject *
+array_append(arrayobject *self, PyObject *v)
+{
+ return ins(self, (int) self->ob_size, v);
+}
+
+PyDoc_STRVAR(append_doc,
+"append(x)\n\
+\n\
+Append new value x to the end of the array.");
+
+
+static PyObject *
+array_byteswap(arrayobject *self, PyObject *unused)
+{
+ char *p;
+ Py_ssize_t i;
+
+ switch (self->ob_descr->itemsize) {
+ case 1:
+ break;
+ case 2:
+ for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
+ char p0 = p[0];
+ p[0] = p[1];
+ p[1] = p0;
+ }
+ break;
+ case 4:
+ for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
+ char p0 = p[0];
+ char p1 = p[1];
+ p[0] = p[3];
+ p[1] = p[2];
+ p[2] = p1;
+ p[3] = p0;
+ }
+ break;
+ case 8:
+ for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
+ char p0 = p[0];
+ char p1 = p[1];
+ char p2 = p[2];
+ char p3 = p[3];
+ p[0] = p[7];
+ p[1] = p[6];
+ p[2] = p[5];
+ p[3] = p[4];
+ p[4] = p3;
+ p[5] = p2;
+ p[6] = p1;
+ p[7] = p0;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_RuntimeError,
+ "don't know how to byteswap this array type");
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(byteswap_doc,
+"byteswap()\n\
+\n\
+Byteswap all items of the array. If the items in the array are not 1, 2,\n\
+4, or 8 bytes in size, RuntimeError is raised.");
+
+static PyObject *
+array_reduce(arrayobject *array)
+{
+ PyObject *dict, *result;
+
+ dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
+ if (dict == NULL) {
+ PyErr_Clear();
+ dict = Py_None;
+ Py_INCREF(dict);
+ }
+ if (array->ob_size > 0) {
+ result = Py_BuildValue("O(cs#)O",
+ array->ob_type,
+ array->ob_descr->typecode,
+ array->ob_item,
+ array->ob_size * array->ob_descr->itemsize,
+ dict);
+ } else {
+ result = Py_BuildValue("O(c)O",
+ array->ob_type,
+ array->ob_descr->typecode,
+ dict);
+ }
+ Py_DECREF(dict);
+ return result;
+}
+
+PyDoc_STRVAR(array_doc, "Return state information for pickling.");
+
+static PyObject *
+array_reverse(arrayobject *self, PyObject *unused)
+{
+ register Py_ssize_t itemsize = self->ob_descr->itemsize;
+ register char *p, *q;
+ /* little buffer to hold items while swapping */
+ char tmp[256]; /* 8 is probably enough -- but why skimp */
+ assert((size_t)itemsize <= sizeof(tmp));
+
+ if (self->ob_size > 1) {
+ for (p = self->ob_item,
+ q = self->ob_item + (self->ob_size - 1)*itemsize;
+ p < q;
+ p += itemsize, q -= itemsize) {
+ /* memory areas guaranteed disjoint, so memcpy
+ * is safe (& memmove may be slower).
+ */
+ memcpy(tmp, p, itemsize);
+ memcpy(p, q, itemsize);
+ memcpy(q, tmp, itemsize);
+ }
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(reverse_doc,
+"reverse()\n\
+\n\
+Reverse the order of the items in the array.");
+
+static PyObject *
+array_fromfile(arrayobject *self, PyObject *args)
+{
+ PyObject *f;
+ Py_ssize_t n;
+ FILE *fp;
+ if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
+ return NULL;
+ fp = PyFile_AsFile(f);
+ if (fp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
+ return NULL;
+ }
+ if (n > 0) {
+ char *item = self->ob_item;
+ Py_ssize_t itemsize = self->ob_descr->itemsize;
+ size_t nread;
+ Py_ssize_t newlength;
+ size_t newbytes;
+ /* Be careful here about overflow */
+ if ((newlength = self->ob_size + n) <= 0 ||
+ (newbytes = newlength * itemsize) / itemsize !=
+ (size_t)newlength)
+ goto nomem;
+ PyMem_RESIZE(item, char, newbytes);
+ if (item == NULL) {
+ nomem:
+ PyErr_NoMemory();
+ return NULL;
+ }
+ self->ob_item = item;
+ self->ob_size += n;
+ self->allocated = self->ob_size;
+ nread = fread(item + (self->ob_size - n) * itemsize,
+ itemsize, n, fp);
+ if (nread < (size_t)n) {
+ self->ob_size -= (n - nread);
+ PyMem_RESIZE(item, char, self->ob_size*itemsize);
+ self->ob_item = item;
+ self->allocated = self->ob_size;
+ PyErr_SetString(PyExc_EOFError,
+ "not enough items in file");
+ return NULL;
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(fromfile_doc,
+"fromfile(f, n)\n\
+\n\
+Read n objects from the file object f and append them to the end of the\n\
+array. Also called as read.");
+
+
+static PyObject *
+array_tofile(arrayobject *self, PyObject *f)
+{
+ FILE *fp;
+
+ fp = PyFile_AsFile(f);
+ if (fp == NULL) {
+ PyErr_SetString(PyExc_TypeError, "arg must be open file");
+ return NULL;
+ }
+ if (self->ob_size > 0) {
+ if (fwrite(self->ob_item, self->ob_descr->itemsize,
+ self->ob_size, fp) != (size_t)self->ob_size) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(fp);
+ return NULL;
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(tofile_doc,
+"tofile(f)\n\
+\n\
+Write all items (as machine values) to the file object f. Also called as\n\
+write.");
+
+
+static PyObject *
+array_fromlist(arrayobject *self, PyObject *list)
+{
+ Py_ssize_t n;
+ Py_ssize_t itemsize = self->ob_descr->itemsize;
+
+ if (!PyList_Check(list)) {
+ PyErr_SetString(PyExc_TypeError, "arg must be list");
+ return NULL;
+ }
+ n = PyList_Size(list);
+ if (n > 0) {
+ char *item = self->ob_item;
+ Py_ssize_t i;
+ PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
+ if (item == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ self->ob_item = item;
+ self->ob_size += n;
+ self->allocated = self->ob_size;
+ for (i = 0; i < n; i++) {
+ PyObject *v = PyList_GetItem(list, i);
+ if ((*self->ob_descr->setitem)(self,
+ self->ob_size - n + i, v) != 0) {
+ self->ob_size -= n;
+ PyMem_RESIZE(item, char,
+ self->ob_size * itemsize);
+ self->ob_item = item;
+ self->allocated = self->ob_size;
+ return NULL;
+ }
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(fromlist_doc,
+"fromlist(list)\n\
+\n\
+Append items to array from list.");
+
+
+static PyObject *
+array_tolist(arrayobject *self, PyObject *unused)
+{
+ PyObject *list = PyList_New(self->ob_size);
+ Py_ssize_t i;
+
+ if (list == NULL)
+ return NULL;
+ for (i = 0; i < self->ob_size; i++) {
+ PyObject *v = getarrayitem((PyObject *)self, i);
+ if (v == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ PyList_SetItem(list, i, v);
+ }
+ return list;
+}
+
+PyDoc_STRVAR(tolist_doc,
+"tolist() -> list\n\
+\n\
+Convert array to an ordinary list with the same items.");
+
+
+static PyObject *
+array_fromstring(arrayobject *self, PyObject *args)
+{
+ char *str;
+ Py_ssize_t n;
+ int itemsize = self->ob_descr->itemsize;
+ if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n))
+ return NULL;
+ if (n % itemsize != 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "string length not a multiple of item size");
+ return NULL;
+ }
+ n = n / itemsize;
+ if (n > 0) {
+ char *item = self->ob_item;
+ PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
+ if (item == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ self->ob_item = item;
+ self->ob_size += n;
+ self->allocated = self->ob_size;
+ memcpy(item + (self->ob_size - n) * itemsize,
+ str, itemsize*n);
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(fromstring_doc,
+"fromstring(string)\n\
+\n\
+Appends items from the string, interpreting it as an array of machine\n\
+values,as if it had been read from a file using the fromfile() method).");
+
+
+static PyObject *
+array_tostring(arrayobject *self, PyObject *unused)
+{
+ return PyString_FromStringAndSize(self->ob_item,
+ self->ob_size * self->ob_descr->itemsize);
+}
+
+PyDoc_STRVAR(tostring_doc,
+"tostring() -> string\n\
+\n\
+Convert the array to an array of machine values and return the string\n\
+representation.");
+
+
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+array_fromunicode(arrayobject *self, PyObject *args)
+{
+ Py_UNICODE *ustr;
+ Py_ssize_t n;
+
+ if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
+ return NULL;
+ if (self->ob_descr->typecode != 'u') {
+ PyErr_SetString(PyExc_ValueError,
+ "fromunicode() may only be called on "
+ "type 'u' arrays");
+ return NULL;
+ }
+ if (n > 0) {
+ Py_UNICODE *item = (Py_UNICODE *) self->ob_item;
+ PyMem_RESIZE(item, Py_UNICODE, self->ob_size + n);
+ if (item == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ self->ob_item = (char *) item;
+ self->ob_size += n;
+ self->allocated = self->ob_size;
+ memcpy(item + self->ob_size - n,
+ ustr, n * sizeof(Py_UNICODE));
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(fromunicode_doc,
+"fromunicode(ustr)\n\
+\n\
+Extends this array with data from the unicode string ustr.\n\
+The array must be a type 'u' array; otherwise a ValueError\n\
+is raised. Use array.fromstring(ustr.decode(...)) to\n\
+append Unicode data to an array of some other type.");
+
+
+static PyObject *
+array_tounicode(arrayobject *self, PyObject *unused)
+{
+ if (self->ob_descr->typecode != 'u') {
+ PyErr_SetString(PyExc_ValueError,
+ "tounicode() may only be called on type 'u' arrays");
+ return NULL;
+ }
+ return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, self->ob_size);
+}
+
+PyDoc_STRVAR(tounicode_doc,
+"tounicode() -> unicode\n\
+\n\
+Convert the array to a unicode string. The array must be\n\
+a type 'u' array; otherwise a ValueError is raised. Use\n\
+array.tostring().decode() to obtain a unicode string from\n\
+an array of some other type.");
+
+#endif /* Py_USING_UNICODE */
+
+
+static PyObject *
+array_get_typecode(arrayobject *a, void *closure)
+{
+ char tc = a->ob_descr->typecode;
+ return PyString_FromStringAndSize(&tc, 1);
+}
+
+static PyObject *
+array_get_itemsize(arrayobject *a, void *closure)
+{
+ return PyInt_FromLong((long)a->ob_descr->itemsize);
+}
+
+static PyGetSetDef array_getsets [] = {
+ {"typecode", (getter) array_get_typecode, NULL,
+ "the typecode character used to create the array"},
+ {"itemsize", (getter) array_get_itemsize, NULL,
+ "the size, in bytes, of one array item"},
+ {NULL}
+};
+
+PyMethodDef array_methods[] = {
+ {"append", (PyCFunction)array_append, METH_O,
+ append_doc},
+ {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,
+ buffer_info_doc},
+ {"byteswap", (PyCFunction)array_byteswap, METH_NOARGS,
+ byteswap_doc},
+ {"__copy__", (PyCFunction)array_copy, METH_NOARGS,
+ copy_doc},
+ {"count", (PyCFunction)array_count, METH_O,
+ count_doc},
+ {"__deepcopy__",(PyCFunction)array_copy, METH_O,
+ copy_doc},
+ {"extend", (PyCFunction)array_extend, METH_O,
+ extend_doc},
+ {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS,
+ fromfile_doc},
+ {"fromlist", (PyCFunction)array_fromlist, METH_O,
+ fromlist_doc},
+ {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS,
+ fromstring_doc},
+#ifdef Py_USING_UNICODE
+ {"fromunicode", (PyCFunction)array_fromunicode, METH_VARARGS,
+ fromunicode_doc},
+#endif
+ {"index", (PyCFunction)array_index, METH_O,
+ index_doc},
+ {"insert", (PyCFunction)array_insert, METH_VARARGS,
+ insert_doc},
+ {"pop", (PyCFunction)array_pop, METH_VARARGS,
+ pop_doc},
+ {"read", (PyCFunction)array_fromfile, METH_VARARGS,
+ fromfile_doc},
+ {"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
+ array_doc},
+ {"remove", (PyCFunction)array_remove, METH_O,
+ remove_doc},
+ {"reverse", (PyCFunction)array_reverse, METH_NOARGS,
+ reverse_doc},
+/* {"sort", (PyCFunction)array_sort, METH_VARARGS,
+ sort_doc},*/
+ {"tofile", (PyCFunction)array_tofile, METH_O,
+ tofile_doc},
+ {"tolist", (PyCFunction)array_tolist, METH_NOARGS,
+ tolist_doc},
+ {"tostring", (PyCFunction)array_tostring, METH_NOARGS,
+ tostring_doc},
+#ifdef Py_USING_UNICODE
+ {"tounicode", (PyCFunction)array_tounicode, METH_NOARGS,
+ tounicode_doc},
+#endif
+ {"write", (PyCFunction)array_tofile, METH_O,
+ tofile_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+array_repr(arrayobject *a)
+{
+ char buf[256], typecode;
+ PyObject *s, *t, *v = NULL;
+ Py_ssize_t len;
+
+ len = a->ob_size;
+ typecode = a->ob_descr->typecode;
+ if (len == 0) {
+ PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
+ return PyString_FromString(buf);
+ }
+
+ if (typecode == 'c')
+ v = array_tostring(a, NULL);
+#ifdef Py_USING_UNICODE
+ else if (typecode == 'u')
+ v = array_tounicode(a, NULL);
+#endif
+ else
+ v = array_tolist(a, NULL);
+ t = PyObject_Repr(v);
+ Py_XDECREF(v);
+
+ PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode);
+ s = PyString_FromString(buf);
+ PyString_ConcatAndDel(&s, t);
+ PyString_ConcatAndDel(&s, PyString_FromString(")"));
+ return s;
+}
+
+static PyObject*
+array_subscr(arrayobject* self, PyObject* item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i==-1 && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (i < 0)
+ i += self->ob_size;
+ return array_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+ PyObject* result;
+ arrayobject* ar;
+ int itemsize = self->ob_descr->itemsize;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return newarrayobject(&Arraytype, 0, self->ob_descr);
+ }
+ else {
+ result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
+ if (!result) return NULL;
+
+ ar = (arrayobject*)result;
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ memcpy(ar->ob_item + i*itemsize,
+ self->ob_item + cur*itemsize,
+ itemsize);
+ }
+
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "list indices must be integers");
+ return NULL;
+ }
+}
+
+static int
+array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i==-1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += self->ob_size;
+ return array_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+ int itemsize = self->ob_descr->itemsize;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ /* treat A[slice(a,b)] = v _exactly_ like A[a:b] = v */
+ if (step == 1 && ((PySliceObject*)item)->step == Py_None)
+ return array_ass_slice(self, start, stop, value);
+
+ if (value == NULL) {
+ /* delete slice */
+ Py_ssize_t cur, i, extra;
+
+ if (slicelength <= 0)
+ return 0;
+
+ if (step < 0) {
+ stop = start + 1;
+ start = stop + step*(slicelength - 1) - 1;
+ step = -step;
+ }
+
+ for (cur = start, i = 0; i < slicelength - 1;
+ cur += step, i++) {
+ memmove(self->ob_item + (cur - i)*itemsize,
+ self->ob_item + (cur + 1)*itemsize,
+ (step - 1) * itemsize);
+ }
+ extra = self->ob_size - (cur + 1);
+ if (extra > 0) {
+ memmove(self->ob_item + (cur - i)*itemsize,
+ self->ob_item + (cur + 1)*itemsize,
+ extra*itemsize);
+ }
+
+ self->ob_size -= slicelength;
+ self->ob_item = (char *)PyMem_REALLOC(self->ob_item,
+ itemsize*self->ob_size);
+ self->allocated = self->ob_size;
+
+ return 0;
+ }
+ else {
+ /* assign slice */
+ Py_ssize_t cur, i;
+ arrayobject* av;
+
+ if (!array_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "must assign array (not \"%.200s\") to slice",
+ value->ob_type->tp_name);
+ return -1;
+ }
+
+ av = (arrayobject*)value;
+
+ if (av->ob_size != slicelength) {
+ PyErr_Format(PyExc_ValueError,
+ "attempt to assign array of size %ld to extended slice of size %ld",
+ /*XXX*/(long)av->ob_size, /*XXX*/(long)slicelength);
+ return -1;
+ }
+
+ if (!slicelength)
+ return 0;
+
+ /* protect against a[::-1] = a */
+ if (self == av) {
+ value = array_slice(av, 0, av->ob_size);
+ av = (arrayobject*)value;
+ if (!av)
+ return -1;
+ }
+ else {
+ Py_INCREF(value);
+ }
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ memcpy(self->ob_item + cur*itemsize,
+ av->ob_item + i*itemsize,
+ itemsize);
+ }
+
+ Py_DECREF(value);
+
+ return 0;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "list indices must be integers");
+ return -1;
+ }
+}
+
+static PyMappingMethods array_as_mapping = {
+ (lenfunc)array_length,
+ (binaryfunc)array_subscr,
+ (objobjargproc)array_ass_subscr
+};
+
+static const void *emptybuf = "";
+
+static Py_ssize_t
+array_buffer_getreadbuf(arrayobject *self, Py_ssize_t index, const void **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Accessing non-existent array segment");
+ return -1;
+ }
+ *ptr = (void *)self->ob_item;
+ if (*ptr == NULL)
+ *ptr = emptybuf;
+ return self->ob_size*self->ob_descr->itemsize;
+}
+
+static Py_ssize_t
+array_buffer_getwritebuf(arrayobject *self, Py_ssize_t index, const void **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Accessing non-existent array segment");
+ return -1;
+ }
+ *ptr = (void *)self->ob_item;
+ if (*ptr == NULL)
+ *ptr = emptybuf;
+ return self->ob_size*self->ob_descr->itemsize;
+}
+
+static Py_ssize_t
+array_buffer_getsegcount(arrayobject *self, Py_ssize_t *lenp)
+{
+ if ( lenp )
+ *lenp = self->ob_size*self->ob_descr->itemsize;
+ return 1;
+}
+
+static PySequenceMethods array_as_sequence = {
+ (lenfunc)array_length, /*sq_length*/
+ (binaryfunc)array_concat, /*sq_concat*/
+ (ssizeargfunc)array_repeat, /*sq_repeat*/
+ (ssizeargfunc)array_item, /*sq_item*/
+ (ssizessizeargfunc)array_slice, /*sq_slice*/
+ (ssizeobjargproc)array_ass_item, /*sq_ass_item*/
+ (ssizessizeobjargproc)array_ass_slice, /*sq_ass_slice*/
+ (objobjproc)array_contains, /*sq_contains*/
+ (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/
+ (ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/
+};
+
+static PyBufferProcs array_as_buffer = {
+ (readbufferproc)array_buffer_getreadbuf,
+ (writebufferproc)array_buffer_getwritebuf,
+ (segcountproc)array_buffer_getsegcount,
+ NULL,
+};
+
+static PyObject *
+array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ char c;
+ PyObject *initial = NULL, *it = NULL;
+ struct arraydescr *descr;
+
+ if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
+ return NULL;
+
+ if (!(initial == NULL || PyList_Check(initial)
+ || PyString_Check(initial) || PyTuple_Check(initial)
+ || (c == 'u' && PyUnicode_Check(initial)))) {
+ it = PyObject_GetIter(initial);
+ if (it == NULL)
+ return NULL;
+ /* We set initial to NULL so that the subsequent code
+ will create an empty array of the appropriate type
+ and afterwards we can use array_iter_extend to populate
+ the array.
+ */
+ initial = NULL;
+ }
+ for (descr = descriptors; descr->typecode != '\0'; descr++) {
+ if (descr->typecode == c) {
+ PyObject *a;
+ Py_ssize_t len;
+
+ if (initial == NULL || !(PyList_Check(initial)
+ || PyTuple_Check(initial)))
+ len = 0;
+ else
+ len = PySequence_Size(initial);
+
+ a = newarrayobject(type, len, descr);
+ if (a == NULL)
+ return NULL;
+
+ if (len > 0) {
+ Py_ssize_t i;
+ for (i = 0; i < len; i++) {
+ PyObject *v =
+ PySequence_GetItem(initial, i);
+ if (v == NULL) {
+ Py_DECREF(a);
+ return NULL;
+ }
+ if (setarrayitem(a, i, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(a);
+ return NULL;
+ }
+ Py_DECREF(v);
+ }
+ } else if (initial != NULL && PyString_Check(initial)) {
+ PyObject *t_initial, *v;
+ t_initial = PyTuple_Pack(1, initial);
+ if (t_initial == NULL) {
+ Py_DECREF(a);
+ return NULL;
+ }
+ v = array_fromstring((arrayobject *)a,
+ t_initial);
+ Py_DECREF(t_initial);
+ if (v == NULL) {
+ Py_DECREF(a);
+ return NULL;
+ }
+ Py_DECREF(v);
+#ifdef Py_USING_UNICODE
+ } else if (initial != NULL && PyUnicode_Check(initial)) {
+ Py_ssize_t n = PyUnicode_GET_DATA_SIZE(initial);
+ if (n > 0) {
+ arrayobject *self = (arrayobject *)a;
+ char *item = self->ob_item;
+ item = (char *)PyMem_Realloc(item, n);
+ if (item == NULL) {
+ PyErr_NoMemory();
+ Py_DECREF(a);
+ return NULL;
+ }
+ self->ob_item = item;
+ self->ob_size = n / sizeof(Py_UNICODE);
+ memcpy(item, PyUnicode_AS_DATA(initial), n);
+ self->allocated = self->ob_size;
+ }
+#endif
+ }
+ if (it != NULL) {
+ if (array_iter_extend((arrayobject *)a, it) == -1) {
+ Py_DECREF(it);
+ Py_DECREF(a);
+ return NULL;
+ }
+ Py_DECREF(it);
+ }
+ return a;
+ }
+ }
+ PyErr_SetString(PyExc_ValueError,
+ "bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)");
+ return NULL;
+}
+
+
+PyDoc_STRVAR(module_doc,
+"This module defines an object type which can efficiently represent\n\
+an array of basic values: characters, integers, floating point\n\
+numbers. Arrays are sequence types and behave very much like lists,\n\
+except that the type of objects stored in them is constrained. The\n\
+type is specified at object creation time by using a type code, which\n\
+is a single character. The following type codes are defined:\n\
+\n\
+ Type code C Type Minimum size in bytes \n\
+ 'c' character 1 \n\
+ 'b' signed integer 1 \n\
+ 'B' unsigned integer 1 \n\
+ 'u' Unicode character 2 \n\
+ 'h' signed integer 2 \n\
+ 'H' unsigned integer 2 \n\
+ 'i' signed integer 2 \n\
+ 'I' unsigned integer 2 \n\
+ 'l' signed integer 4 \n\
+ 'L' unsigned integer 4 \n\
+ 'f' floating point 4 \n\
+ 'd' floating point 8 \n\
+\n\
+The constructor is:\n\
+\n\
+array(typecode [, initializer]) -- create a new array\n\
+");
+
+PyDoc_STRVAR(arraytype_doc,
+"array(typecode [, initializer]) -> array\n\
+\n\
+Return a new array whose items are restricted by typecode, and\n\
+initialized from the optional initializer value, which must be a list,\n\
+string. or iterable over elements of the appropriate type.\n\
+\n\
+Arrays represent basic values and behave very much like lists, except\n\
+the type of objects stored in them is constrained.\n\
+\n\
+Methods:\n\
+\n\
+append() -- append a new item to the end of the array\n\
+buffer_info() -- return information giving the current memory info\n\
+byteswap() -- byteswap all the items of the array\n\
+count() -- return number of occurences of an object\n\
+extend() -- extend array by appending multiple elements from an iterable\n\
+fromfile() -- read items from a file object\n\
+fromlist() -- append items from the list\n\
+fromstring() -- append items from the string\n\
+index() -- return index of first occurence of an object\n\
+insert() -- insert a new item into the array at a provided position\n\
+pop() -- remove and return item (default last)\n\
+read() -- DEPRECATED, use fromfile()\n\
+remove() -- remove first occurence of an object\n\
+reverse() -- reverse the order of the items in the array\n\
+tofile() -- write all items to a file object\n\
+tolist() -- return the array converted to an ordinary list\n\
+tostring() -- return the array converted to a string\n\
+write() -- DEPRECATED, use tofile()\n\
+\n\
+Attributes:\n\
+\n\
+typecode -- the typecode character used to create the array\n\
+itemsize -- the length in bytes of one array item\n\
+");
+
+static PyObject *array_iter(arrayobject *ao);
+
+static PyTypeObject Arraytype = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "array.array",
+ sizeof(arrayobject),
+ 0,
+ (destructor)array_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)array_repr, /* tp_repr */
+ 0, /* tp_as_number*/
+ &array_as_sequence, /* tp_as_sequence*/
+ &array_as_mapping, /* tp_as_mapping*/
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &array_as_buffer, /* tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ arraytype_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ array_richcompare, /* tp_richcompare */
+ offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)array_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ array_methods, /* tp_methods */
+ 0, /* tp_members */
+ array_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ array_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+
+/*********************** Array Iterator **************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t index;
+ arrayobject *ao;
+ PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
+} arrayiterobject;
+
+static PyTypeObject PyArrayIter_Type;
+
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+static PyObject *
+array_iter(arrayobject *ao)
+{
+ arrayiterobject *it;
+
+ if (!array_Check(ao)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type);
+ if (it == NULL)
+ return NULL;
+
+ Py_INCREF(ao);
+ it->ao = ao;
+ it->index = 0;
+ it->getitem = ao->ob_descr->getitem;
+ PyObject_GC_Track(it);
+ return (PyObject *)it;
+}
+
+static PyObject *
+arrayiter_next(arrayiterobject *it)
+{
+ assert(PyArrayIter_Check(it));
+ if (it->index < it->ao->ob_size)
+ return (*it->getitem)(it->ao, it->index++);
+ return NULL;
+}
+
+static void
+arrayiter_dealloc(arrayiterobject *it)
+{
+ PyObject_GC_UnTrack(it);
+ Py_XDECREF(it->ao);
+ PyObject_GC_Del(it);
+}
+
+static int
+arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->ao);
+ return 0;
+}
+
+static PyTypeObject PyArrayIter_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "arrayiterator", /* tp_name */
+ sizeof(arrayiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)arrayiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)arrayiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)arrayiter_next, /* tp_iternext */
+ 0, /* tp_methods */
+};
+
+
+/*********************** Install Module **************************/
+
+/* No functions in array module. */
+static PyMethodDef a_methods[] = {
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+
+PyMODINIT_FUNC
+initarray(void)
+{
+ PyObject *m;
+
+ Arraytype.ob_type = &PyType_Type;
+ PyArrayIter_Type.ob_type = &PyType_Type;
+ m = Py_InitModule3("array", a_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ Py_INCREF((PyObject *)&Arraytype);
+ PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
+ Py_INCREF((PyObject *)&Arraytype);
+ PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
+ /* No need to check the error here, the caller will do that */
+}
diff --git a/sys/src/cmd/python/Modules/audioop.c b/sys/src/cmd/python/Modules/audioop.c
new file mode 100644
index 000000000..8f5d30c80
--- /dev/null
+++ b/sys/src/cmd/python/Modules/audioop.c
@@ -0,0 +1,1612 @@
+
+/* audioopmodule - Module to detect peak values in arrays */
+
+#include "Python.h"
+
+#if SIZEOF_INT == 4
+typedef int Py_Int32;
+typedef unsigned int Py_UInt32;
+#else
+#if SIZEOF_LONG == 4
+typedef long Py_Int32;
+typedef unsigned long Py_UInt32;
+#else
+#error "No 4-byte integral type"
+#endif
+#endif
+
+typedef short PyInt16;
+
+#if defined(__CHAR_UNSIGNED__)
+#if defined(signed)
+/* This module currently does not work on systems where only unsigned
+ characters are available. Take it out of Setup. Sorry. */
+#endif
+#endif
+
+/* Code shamelessly stolen from sox, 12.17.7, g711.c
+** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
+
+/* From g711.c:
+ *
+ * December 30, 1994:
+ * Functions linear2alaw, linear2ulaw have been updated to correctly
+ * convert unquantized 16 bit values.
+ * Tables for direct u- to A-law and A- to u-law conversions have been
+ * corrected.
+ * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
+ * bli@cpk.auc.dk
+ *
+ */
+#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
+#define QUANT_MASK (0xf) /* Quantization field mask. */
+#define SEG_SHIFT (4) /* Left shift for segment number. */
+#define SEG_MASK (0x70) /* Segment field mask. */
+
+static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
+ 0x1FF, 0x3FF, 0x7FF, 0xFFF};
+static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
+ 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
+
+static PyInt16
+search(PyInt16 val, PyInt16 *table, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (val <= *table++)
+ return (i);
+ }
+ return (size);
+}
+#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
+#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
+
+static PyInt16 _st_ulaw2linear16[256] = {
+ -32124, -31100, -30076, -29052, -28028, -27004, -25980,
+ -24956, -23932, -22908, -21884, -20860, -19836, -18812,
+ -17788, -16764, -15996, -15484, -14972, -14460, -13948,
+ -13436, -12924, -12412, -11900, -11388, -10876, -10364,
+ -9852, -9340, -8828, -8316, -7932, -7676, -7420,
+ -7164, -6908, -6652, -6396, -6140, -5884, -5628,
+ -5372, -5116, -4860, -4604, -4348, -4092, -3900,
+ -3772, -3644, -3516, -3388, -3260, -3132, -3004,
+ -2876, -2748, -2620, -2492, -2364, -2236, -2108,
+ -1980, -1884, -1820, -1756, -1692, -1628, -1564,
+ -1500, -1436, -1372, -1308, -1244, -1180, -1116,
+ -1052, -988, -924, -876, -844, -812, -780,
+ -748, -716, -684, -652, -620, -588, -556,
+ -524, -492, -460, -428, -396, -372, -356,
+ -340, -324, -308, -292, -276, -260, -244,
+ -228, -212, -196, -180, -164, -148, -132,
+ -120, -112, -104, -96, -88, -80, -72,
+ -64, -56, -48, -40, -32, -24, -16,
+ -8, 0, 32124, 31100, 30076, 29052, 28028,
+ 27004, 25980, 24956, 23932, 22908, 21884, 20860,
+ 19836, 18812, 17788, 16764, 15996, 15484, 14972,
+ 14460, 13948, 13436, 12924, 12412, 11900, 11388,
+ 10876, 10364, 9852, 9340, 8828, 8316, 7932,
+ 7676, 7420, 7164, 6908, 6652, 6396, 6140,
+ 5884, 5628, 5372, 5116, 4860, 4604, 4348,
+ 4092, 3900, 3772, 3644, 3516, 3388, 3260,
+ 3132, 3004, 2876, 2748, 2620, 2492, 2364,
+ 2236, 2108, 1980, 1884, 1820, 1756, 1692,
+ 1628, 1564, 1500, 1436, 1372, 1308, 1244,
+ 1180, 1116, 1052, 988, 924, 876, 844,
+ 812, 780, 748, 716, 684, 652, 620,
+ 588, 556, 524, 492, 460, 428, 396,
+ 372, 356, 340, 324, 308, 292, 276,
+ 260, 244, 228, 212, 196, 180, 164,
+ 148, 132, 120, 112, 104, 96, 88,
+ 80, 72, 64, 56, 48, 40, 32,
+ 24, 16, 8, 0
+};
+
+/*
+ * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
+ * stored in a unsigned char. This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 14-bits.
+ *
+ * In order to simplify the encoding process, the original linear magnitude
+ * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ * (33 - 8191). The result can be seen in the following encoding table:
+ *
+ * Biased Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 00000001wxyza 000wxyz
+ * 0000001wxyzab 001wxyz
+ * 000001wxyzabc 010wxyz
+ * 00001wxyzabcd 011wxyz
+ * 0001wxyzabcde 100wxyz
+ * 001wxyzabcdef 101wxyz
+ * 01wxyzabcdefg 110wxyz
+ * 1wxyzabcdefgh 111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz. * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+static unsigned char
+st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
+{
+ PyInt16 mask;
+ PyInt16 seg;
+ unsigned char uval;
+
+ /* The original sox code does this in the calling function, not here */
+ pcm_val = pcm_val >> 2;
+
+ /* u-law inverts all bits */
+ /* Get the sign and the magnitude of the value. */
+ if (pcm_val < 0) {
+ pcm_val = -pcm_val;
+ mask = 0x7F;
+ } else {
+ mask = 0xFF;
+ }
+ if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
+ pcm_val += (BIAS >> 2);
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_uend, 8);
+
+ /*
+ * Combine the sign, segment, quantization bits;
+ * and complement the code word.
+ */
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (unsigned char) (0x7F ^ mask);
+ else {
+ uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
+ return (uval ^ mask);
+ }
+
+}
+
+static PyInt16 _st_alaw2linear16[256] = {
+ -5504, -5248, -6016, -5760, -4480, -4224, -4992,
+ -4736, -7552, -7296, -8064, -7808, -6528, -6272,
+ -7040, -6784, -2752, -2624, -3008, -2880, -2240,
+ -2112, -2496, -2368, -3776, -3648, -4032, -3904,
+ -3264, -3136, -3520, -3392, -22016, -20992, -24064,
+ -23040, -17920, -16896, -19968, -18944, -30208, -29184,
+ -32256, -31232, -26112, -25088, -28160, -27136, -11008,
+ -10496, -12032, -11520, -8960, -8448, -9984, -9472,
+ -15104, -14592, -16128, -15616, -13056, -12544, -14080,
+ -13568, -344, -328, -376, -360, -280, -264,
+ -312, -296, -472, -456, -504, -488, -408,
+ -392, -440, -424, -88, -72, -120, -104,
+ -24, -8, -56, -40, -216, -200, -248,
+ -232, -152, -136, -184, -168, -1376, -1312,
+ -1504, -1440, -1120, -1056, -1248, -1184, -1888,
+ -1824, -2016, -1952, -1632, -1568, -1760, -1696,
+ -688, -656, -752, -720, -560, -528, -624,
+ -592, -944, -912, -1008, -976, -816, -784,
+ -880, -848, 5504, 5248, 6016, 5760, 4480,
+ 4224, 4992, 4736, 7552, 7296, 8064, 7808,
+ 6528, 6272, 7040, 6784, 2752, 2624, 3008,
+ 2880, 2240, 2112, 2496, 2368, 3776, 3648,
+ 4032, 3904, 3264, 3136, 3520, 3392, 22016,
+ 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160,
+ 27136, 11008, 10496, 12032, 11520, 8960, 8448,
+ 9984, 9472, 15104, 14592, 16128, 15616, 13056,
+ 12544, 14080, 13568, 344, 328, 376, 360,
+ 280, 264, 312, 296, 472, 456, 504,
+ 488, 408, 392, 440, 424, 88, 72,
+ 120, 104, 24, 8, 56, 40, 216,
+ 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248,
+ 1184, 1888, 1824, 2016, 1952, 1632, 1568,
+ 1760, 1696, 688, 656, 752, 720, 560,
+ 528, 624, 592, 944, 912, 1008, 976,
+ 816, 784, 880, 848
+};
+
+/*
+ * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
+ * stored in a unsigned char. This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 13-bits.
+ *
+ * Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 0000000wxyza 000wxyz
+ * 0000001wxyza 001wxyz
+ * 000001wxyzab 010wxyz
+ * 00001wxyzabc 011wxyz
+ * 0001wxyzabcd 100wxyz
+ * 001wxyzabcde 101wxyz
+ * 01wxyzabcdef 110wxyz
+ * 1wxyzabcdefg 111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+static unsigned char
+st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
+{
+ PyInt16 mask;
+ short seg;
+ unsigned char aval;
+
+ /* The original sox code does this in the calling function, not here */
+ pcm_val = pcm_val >> 3;
+
+ /* A-law using even bit inversion */
+ if (pcm_val >= 0) {
+ mask = 0xD5; /* sign (7th) bit = 1 */
+ } else {
+ mask = 0x55; /* sign bit = 0 */
+ pcm_val = -pcm_val - 1;
+ }
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_aend, 8);
+
+ /* Combine the sign, segment, and quantization bits. */
+
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (unsigned char) (0x7F ^ mask);
+ else {
+ aval = (unsigned char) seg << SEG_SHIFT;
+ if (seg < 2)
+ aval |= (pcm_val >> 1) & QUANT_MASK;
+ else
+ aval |= (pcm_val >> seg) & QUANT_MASK;
+ return (aval ^ mask);
+ }
+}
+/* End of code taken from sox */
+
+/* Intel ADPCM step variation table */
+static int indexTable[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+static int stepsizeTable[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+#define CHARP(cp, i) ((signed char *)(cp+i))
+#define SHORTP(cp, i) ((short *)(cp+i))
+#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
+
+
+
+static PyObject *AudioopError;
+
+static PyObject *
+audioop_getsample(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ if ( i < 0 || i >= len/size ) {
+ PyErr_SetString(AudioopError, "Index out of range");
+ return 0;
+ }
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+audioop_max(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0;
+ int i;
+ int max = 0;
+
+ if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ for ( i=0; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ if ( val < 0 ) val = (-val);
+ if ( val > max ) max = val;
+ }
+ return PyInt_FromLong(max);
+}
+
+static PyObject *
+audioop_minmax(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0;
+ int i;
+ int min = 0x7fffffff, max = -0x7fffffff;
+
+ if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
+ return NULL;
+ if (size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return NULL;
+ }
+ for (i = 0; i < len; i += size) {
+ if (size == 1) val = (int) *CHARP(cp, i);
+ else if (size == 2) val = (int) *SHORTP(cp, i);
+ else if (size == 4) val = (int) *LONGP(cp, i);
+ if (val > max) max = val;
+ if (val < min) min = val;
+ }
+ return Py_BuildValue("(ii)", min, max);
+}
+
+static PyObject *
+audioop_avg(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0;
+ int i;
+ double avg = 0.0;
+
+ if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ for ( i=0; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ avg += val;
+ }
+ if ( len == 0 )
+ val = 0;
+ else
+ val = (int)(avg / (double)(len/size));
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+audioop_rms(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0;
+ int i;
+ double sum_squares = 0.0;
+
+ if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ for ( i=0; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ sum_squares += (double)val*(double)val;
+ }
+ if ( len == 0 )
+ val = 0;
+ else
+ val = (int)sqrt(sum_squares / (double)(len/size));
+ return PyInt_FromLong(val);
+}
+
+static double _sum2(short *a, short *b, int len)
+{
+ int i;
+ double sum = 0.0;
+
+ for( i=0; i<len; i++) {
+ sum = sum + (double)a[i]*(double)b[i];
+ }
+ return sum;
+}
+
+/*
+** Findfit tries to locate a sample within another sample. Its main use
+** is in echo-cancellation (to find the feedback of the output signal in
+** the input signal).
+** The method used is as follows:
+**
+** let R be the reference signal (length n) and A the input signal (length N)
+** with N > n, and let all sums be over i from 0 to n-1.
+**
+** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
+** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
+** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
+**
+** Next, we compute the relative distance between the original signal and
+** the modified signal and minimize that over j:
+** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
+** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
+**
+** In the code variables correspond as follows:
+** cp1 A
+** cp2 R
+** len1 N
+** len2 n
+** aj_m1 A[j-1]
+** aj_lm1 A[j+n-1]
+** sum_ri_2 sum(R[i]^2)
+** sum_aij_2 sum(A[i+j]^2)
+** sum_aij_ri sum(A[i+j]R[i])
+**
+** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
+** is completely recalculated each step.
+*/
+static PyObject *
+audioop_findfit(PyObject *self, PyObject *args)
+{
+ short *cp1, *cp2;
+ int len1, len2;
+ int j, best_j;
+ double aj_m1, aj_lm1;
+ double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
+
+ if ( !PyArg_ParseTuple(args, "s#s#:findfit",
+ &cp1, &len1, &cp2, &len2) )
+ return 0;
+ if ( len1 & 1 || len2 & 1 ) {
+ PyErr_SetString(AudioopError, "Strings should be even-sized");
+ return 0;
+ }
+ len1 >>= 1;
+ len2 >>= 1;
+
+ if ( len1 < len2 ) {
+ PyErr_SetString(AudioopError, "First sample should be longer");
+ return 0;
+ }
+ sum_ri_2 = _sum2(cp2, cp2, len2);
+ sum_aij_2 = _sum2(cp1, cp1, len2);
+ sum_aij_ri = _sum2(cp1, cp2, len2);
+
+ result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
+
+ best_result = result;
+ best_j = 0;
+ j = 0;
+
+ for ( j=1; j<=len1-len2; j++) {
+ aj_m1 = (double)cp1[j-1];
+ aj_lm1 = (double)cp1[j+len2-1];
+
+ sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
+ sum_aij_ri = _sum2(cp1+j, cp2, len2);
+
+ result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
+ / sum_aij_2;
+
+ if ( result < best_result ) {
+ best_result = result;
+ best_j = j;
+ }
+
+ }
+
+ factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
+
+ return Py_BuildValue("(if)", best_j, factor);
+}
+
+/*
+** findfactor finds a factor f so that the energy in A-fB is minimal.
+** See the comment for findfit for details.
+*/
+static PyObject *
+audioop_findfactor(PyObject *self, PyObject *args)
+{
+ short *cp1, *cp2;
+ int len1, len2;
+ double sum_ri_2, sum_aij_ri, result;
+
+ if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
+ &cp1, &len1, &cp2, &len2) )
+ return 0;
+ if ( len1 & 1 || len2 & 1 ) {
+ PyErr_SetString(AudioopError, "Strings should be even-sized");
+ return 0;
+ }
+ if ( len1 != len2 ) {
+ PyErr_SetString(AudioopError, "Samples should be same size");
+ return 0;
+ }
+ len2 >>= 1;
+ sum_ri_2 = _sum2(cp2, cp2, len2);
+ sum_aij_ri = _sum2(cp1, cp2, len2);
+
+ result = sum_aij_ri / sum_ri_2;
+
+ return PyFloat_FromDouble(result);
+}
+
+/*
+** findmax returns the index of the n-sized segment of the input sample
+** that contains the most energy.
+*/
+static PyObject *
+audioop_findmax(PyObject *self, PyObject *args)
+{
+ short *cp1;
+ int len1, len2;
+ int j, best_j;
+ double aj_m1, aj_lm1;
+ double result, best_result;
+
+ if ( !PyArg_ParseTuple(args, "s#i:findmax", &cp1, &len1, &len2) )
+ return 0;
+ if ( len1 & 1 ) {
+ PyErr_SetString(AudioopError, "Strings should be even-sized");
+ return 0;
+ }
+ len1 >>= 1;
+
+ if ( len1 < len2 ) {
+ PyErr_SetString(AudioopError, "Input sample should be longer");
+ return 0;
+ }
+
+ result = _sum2(cp1, cp1, len2);
+
+ best_result = result;
+ best_j = 0;
+ j = 0;
+
+ for ( j=1; j<=len1-len2; j++) {
+ aj_m1 = (double)cp1[j-1];
+ aj_lm1 = (double)cp1[j+len2-1];
+
+ result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
+
+ if ( result > best_result ) {
+ best_result = result;
+ best_j = j;
+ }
+
+ }
+
+ return PyInt_FromLong(best_j);
+}
+
+static PyObject *
+audioop_avgpp(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0, prevval = 0, prevextremevalid = 0,
+ prevextreme = 0;
+ int i;
+ double avg = 0.0;
+ int diff, prevdiff, extremediff, nextreme = 0;
+
+ if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ /* Compute first delta value ahead. Also automatically makes us
+ ** skip the first extreme value
+ */
+ if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
+ else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
+ else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
+ if ( size == 1 ) val = (int)*CHARP(cp, size);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, size);
+ else if ( size == 4 ) val = (int)*LONGP(cp, size);
+ prevdiff = val - prevval;
+
+ for ( i=size; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ diff = val - prevval;
+ if ( diff*prevdiff < 0 ) {
+ /* Derivative changed sign. Compute difference to last
+ ** extreme value and remember.
+ */
+ if ( prevextremevalid ) {
+ extremediff = prevval - prevextreme;
+ if ( extremediff < 0 )
+ extremediff = -extremediff;
+ avg += extremediff;
+ nextreme++;
+ }
+ prevextremevalid = 1;
+ prevextreme = prevval;
+ }
+ prevval = val;
+ if ( diff != 0 )
+ prevdiff = diff;
+ }
+ if ( nextreme == 0 )
+ val = 0;
+ else
+ val = (int)(avg / (double)nextreme);
+ return PyInt_FromLong(val);
+}
+
+static PyObject *
+audioop_maxpp(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0, prevval = 0, prevextremevalid = 0,
+ prevextreme = 0;
+ int i;
+ int max = 0;
+ int diff, prevdiff, extremediff;
+
+ if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ /* Compute first delta value ahead. Also automatically makes us
+ ** skip the first extreme value
+ */
+ if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
+ else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
+ else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
+ if ( size == 1 ) val = (int)*CHARP(cp, size);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, size);
+ else if ( size == 4 ) val = (int)*LONGP(cp, size);
+ prevdiff = val - prevval;
+
+ for ( i=size; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ diff = val - prevval;
+ if ( diff*prevdiff < 0 ) {
+ /* Derivative changed sign. Compute difference to
+ ** last extreme value and remember.
+ */
+ if ( prevextremevalid ) {
+ extremediff = prevval - prevextreme;
+ if ( extremediff < 0 )
+ extremediff = -extremediff;
+ if ( extremediff > max )
+ max = extremediff;
+ }
+ prevextremevalid = 1;
+ prevextreme = prevval;
+ }
+ prevval = val;
+ if ( diff != 0 )
+ prevdiff = diff;
+ }
+ return PyInt_FromLong(max);
+}
+
+static PyObject *
+audioop_cross(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ int len, size, val = 0;
+ int i;
+ int prevval, ncross;
+
+ if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ ncross = -1;
+ prevval = 17; /* Anything <> 0,1 */
+ for ( i=0; i<len; i+= size) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
+ else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
+ val = val & 1;
+ if ( val != prevval ) ncross++;
+ prevval = val;
+ }
+ return PyInt_FromLong(ncross);
+}
+
+static PyObject *
+audioop_mul(PyObject *self, PyObject *args)
+{
+ signed char *cp, *ncp;
+ int len, size, val = 0;
+ double factor, fval, maxval;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
+ return 0;
+
+ if ( size == 1 ) maxval = (double) 0x7f;
+ else if ( size == 2 ) maxval = (double) 0x7fff;
+ else if ( size == 4 ) maxval = (double) 0x7fffffff;
+ else {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ fval = (double)val*factor;
+ if ( fval > maxval ) fval = maxval;
+ else if ( fval < -maxval ) fval = -maxval;
+ val = (int)fval;
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_tomono(PyObject *self, PyObject *args)
+{
+ signed char *cp, *ncp;
+ int len, size, val1 = 0, val2 = 0;
+ double fac1, fac2, fval, maxval;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#idd:tomono",
+ &cp, &len, &size, &fac1, &fac2 ) )
+ return 0;
+
+ if ( size == 1 ) maxval = (double) 0x7f;
+ else if ( size == 2 ) maxval = (double) 0x7fff;
+ else if ( size == 4 ) maxval = (double) 0x7fffffff;
+ else {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len/2);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+
+ for ( i=0; i < len; i += size*2 ) {
+ if ( size == 1 ) val1 = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
+ if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
+ else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
+ else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
+ fval = (double)val1*fac1 + (double)val2*fac2;
+ if ( fval > maxval ) fval = maxval;
+ else if ( fval < -maxval ) fval = -maxval;
+ val1 = (int)fval;
+ if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
+ else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
+ else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_tostereo(PyObject *self, PyObject *args)
+{
+ signed char *cp, *ncp;
+ int len, size, val1, val2, val = 0;
+ double fac1, fac2, fval, maxval;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
+ &cp, &len, &size, &fac1, &fac2 ) )
+ return 0;
+
+ if ( size == 1 ) maxval = (double) 0x7f;
+ else if ( size == 2 ) maxval = (double) 0x7fff;
+ else if ( size == 4 ) maxval = (double) 0x7fffffff;
+ else {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len*2);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+
+ fval = (double)val*fac1;
+ if ( fval > maxval ) fval = maxval;
+ else if ( fval < -maxval ) fval = -maxval;
+ val1 = (int)fval;
+
+ fval = (double)val*fac2;
+ if ( fval > maxval ) fval = maxval;
+ else if ( fval < -maxval ) fval = -maxval;
+ val2 = (int)fval;
+
+ if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
+ else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
+ else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
+
+ if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
+ else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
+ else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_add(PyObject *self, PyObject *args)
+{
+ signed char *cp1, *cp2, *ncp;
+ int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#s#i:add",
+ &cp1, &len1, &cp2, &len2, &size ) )
+ return 0;
+
+ if ( len1 != len2 ) {
+ PyErr_SetString(AudioopError, "Lengths should be the same");
+ return 0;
+ }
+
+ if ( size == 1 ) maxval = 0x7f;
+ else if ( size == 2 ) maxval = 0x7fff;
+ else if ( size == 4 ) maxval = 0x7fffffff;
+ else {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len1);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+ for ( i=0; i < len1; i += size ) {
+ if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
+ else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
+ else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
+
+ if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
+ else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
+ else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
+
+ newval = val1 + val2;
+ /* truncate in case of overflow */
+ if (newval > maxval) newval = maxval;
+ else if (newval < -maxval) newval = -maxval;
+ else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
+ newval = val1 > 0 ? maxval : - maxval;
+
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_bias(PyObject *self, PyObject *args)
+{
+ signed char *cp, *ncp;
+ int len, size, val = 0;
+ PyObject *rv;
+ int i;
+ int bias;
+
+ if ( !PyArg_ParseTuple(args, "s#ii:bias",
+ &cp, &len, &size , &bias) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_reverse(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ unsigned char *ncp;
+ int len, size, val = 0;
+ PyObject *rv;
+ int i, j;
+
+ if ( !PyArg_ParseTuple(args, "s#i:reverse",
+ &cp, &len, &size) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+ j = len - i - size;
+
+ if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
+ else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
+ else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_lin2lin(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ unsigned char *ncp;
+ int len, size, size2, val = 0;
+ PyObject *rv;
+ int i, j;
+
+ if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
+ &cp, &len, &size, &size2) )
+ return 0;
+
+ if ( (size != 1 && size != 2 && size != 4) ||
+ (size2 != 1 && size2 != 2 && size2 != 4)) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0, j=0; i < len; i += size, j += size2 ) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+ if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
+ else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
+ else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
+ }
+ return rv;
+}
+
+static int
+gcd(int a, int b)
+{
+ while (b > 0) {
+ int tmp = a % b;
+ a = b;
+ b = tmp;
+ }
+ return a;
+}
+
+static PyObject *
+audioop_ratecv(PyObject *self, PyObject *args)
+{
+ char *cp, *ncp;
+ int len, size, nchannels, inrate, outrate, weightA, weightB;
+ int chan, d, *prev_i, *cur_i, cur_o;
+ PyObject *state, *samps, *str, *rv = NULL;
+ int bytes_per_frame;
+
+ weightA = 1;
+ weightB = 0;
+ if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
+ &nchannels, &inrate, &outrate, &state,
+ &weightA, &weightB))
+ return NULL;
+ if (size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return NULL;
+ }
+ if (nchannels < 1) {
+ PyErr_SetString(AudioopError, "# of channels should be >= 1");
+ return NULL;
+ }
+ bytes_per_frame = size * nchannels;
+ if (bytes_per_frame / nchannels != size) {
+ /* This overflow test is rigorously correct because
+ both multiplicands are >= 1. Use the argument names
+ from the docs for the error msg. */
+ PyErr_SetString(PyExc_OverflowError,
+ "width * nchannels too big for a C int");
+ return NULL;
+ }
+ if (weightA < 1 || weightB < 0) {
+ PyErr_SetString(AudioopError,
+ "weightA should be >= 1, weightB should be >= 0");
+ return NULL;
+ }
+ if (len % bytes_per_frame != 0) {
+ PyErr_SetString(AudioopError, "not a whole number of frames");
+ return NULL;
+ }
+ if (inrate <= 0 || outrate <= 0) {
+ PyErr_SetString(AudioopError, "sampling rate not > 0");
+ return NULL;
+ }
+ /* divide inrate and outrate by their greatest common divisor */
+ d = gcd(inrate, outrate);
+ inrate /= d;
+ outrate /= d;
+
+ prev_i = (int *) malloc(nchannels * sizeof(int));
+ cur_i = (int *) malloc(nchannels * sizeof(int));
+ if (prev_i == NULL || cur_i == NULL) {
+ (void) PyErr_NoMemory();
+ goto exit;
+ }
+
+ len /= bytes_per_frame; /* # of frames */
+
+ if (state == Py_None) {
+ d = -outrate;
+ for (chan = 0; chan < nchannels; chan++)
+ prev_i[chan] = cur_i[chan] = 0;
+ }
+ else {
+ if (!PyArg_ParseTuple(state,
+ "iO!;audioop.ratecv: illegal state argument",
+ &d, &PyTuple_Type, &samps))
+ goto exit;
+ if (PyTuple_Size(samps) != nchannels) {
+ PyErr_SetString(AudioopError,
+ "illegal state argument");
+ goto exit;
+ }
+ for (chan = 0; chan < nchannels; chan++) {
+ if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
+ "ii:ratecv", &prev_i[chan],
+ &cur_i[chan]))
+ goto exit;
+ }
+ }
+
+ /* str <- Space for the output buffer. */
+ {
+ /* There are len input frames, so we need (mathematically)
+ ceiling(len*outrate/inrate) output frames, and each frame
+ requires bytes_per_frame bytes. Computing this
+ without spurious overflow is the challenge; we can
+ settle for a reasonable upper bound, though. */
+ int ceiling; /* the number of output frames */
+ int nbytes; /* the number of output bytes needed */
+ int q = len / inrate;
+ /* Now len = q * inrate + r exactly (with r = len % inrate),
+ and this is less than q * inrate + inrate = (q+1)*inrate.
+ So a reasonable upper bound on len*outrate/inrate is
+ ((q+1)*inrate)*outrate/inrate =
+ (q+1)*outrate.
+ */
+ ceiling = (q+1) * outrate;
+ nbytes = ceiling * bytes_per_frame;
+ /* See whether anything overflowed; if not, get the space. */
+ if (q+1 < 0 ||
+ ceiling / outrate != q+1 ||
+ nbytes / bytes_per_frame != ceiling)
+ str = NULL;
+ else
+ str = PyString_FromStringAndSize(NULL, nbytes);
+
+ if (str == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "not enough memory for output buffer");
+ goto exit;
+ }
+ }
+ ncp = PyString_AsString(str);
+
+ for (;;) {
+ while (d < 0) {
+ if (len == 0) {
+ samps = PyTuple_New(nchannels);
+ if (samps == NULL)
+ goto exit;
+ for (chan = 0; chan < nchannels; chan++)
+ PyTuple_SetItem(samps, chan,
+ Py_BuildValue("(ii)",
+ prev_i[chan],
+ cur_i[chan]));
+ if (PyErr_Occurred())
+ goto exit;
+ /* We have checked before that the length
+ * of the string fits into int. */
+ len = (int)(ncp - PyString_AsString(str));
+ if (len == 0) {
+ /*don't want to resize to zero length*/
+ rv = PyString_FromStringAndSize("", 0);
+ Py_DECREF(str);
+ str = rv;
+ } else if (_PyString_Resize(&str, len) < 0)
+ goto exit;
+ rv = Py_BuildValue("(O(iO))", str, d, samps);
+ Py_DECREF(samps);
+ Py_DECREF(str);
+ goto exit; /* return rv */
+ }
+ for (chan = 0; chan < nchannels; chan++) {
+ prev_i[chan] = cur_i[chan];
+ if (size == 1)
+ cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
+ else if (size == 2)
+ cur_i[chan] = (int)*SHORTP(cp, 0);
+ else if (size == 4)
+ cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
+ cp += size;
+ /* implements a simple digital filter */
+ cur_i[chan] =
+ (weightA * cur_i[chan] +
+ weightB * prev_i[chan]) /
+ (weightA + weightB);
+ }
+ len--;
+ d += outrate;
+ }
+ while (d >= 0) {
+ for (chan = 0; chan < nchannels; chan++) {
+ cur_o = (prev_i[chan] * d +
+ cur_i[chan] * (outrate - d)) /
+ outrate;
+ if (size == 1)
+ *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
+ else if (size == 2)
+ *SHORTP(ncp, 0) = (short)(cur_o);
+ else if (size == 4)
+ *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
+ ncp += size;
+ }
+ d -= inrate;
+ }
+ }
+ exit:
+ if (prev_i != NULL)
+ free(prev_i);
+ if (cur_i != NULL)
+ free(cur_i);
+ return rv;
+}
+
+static PyObject *
+audioop_lin2ulaw(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ unsigned char *ncp;
+ int len, size, val = 0;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
+ &cp, &len, &size) )
+ return 0 ;
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len/size);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+ *ncp++ = st_14linear2ulaw(val);
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_ulaw2lin(PyObject *self, PyObject *args)
+{
+ unsigned char *cp;
+ unsigned char cval;
+ signed char *ncp;
+ int len, size, val;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
+ &cp, &len, &size) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len*size);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+ for ( i=0; i < len*size; i += size ) {
+ cval = *cp++;
+ val = st_ulaw2linear16(cval);
+
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_lin2alaw(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ unsigned char *ncp;
+ int len, size, val = 0;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
+ &cp, &len, &size) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len/size);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+ *ncp++ = st_linear2alaw(val);
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_alaw2lin(PyObject *self, PyObject *args)
+{
+ unsigned char *cp;
+ unsigned char cval;
+ signed char *ncp;
+ int len, size, val;
+ PyObject *rv;
+ int i;
+
+ if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
+ &cp, &len, &size) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len*size);
+ if ( rv == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(rv);
+
+ for ( i=0; i < len*size; i += size ) {
+ cval = *cp++;
+ val = st_alaw2linear16(cval);
+
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
+ }
+ return rv;
+}
+
+static PyObject *
+audioop_lin2adpcm(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ signed char *ncp;
+ int len, size, val = 0, step, valpred, delta,
+ index, sign, vpdiff, diff;
+ PyObject *rv, *state, *str;
+ int i, outputbuffer = 0, bufferstep;
+
+ if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
+ &cp, &len, &size, &state) )
+ return 0;
+
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ str = PyString_FromStringAndSize(NULL, len/(size*2));
+ if ( str == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(str);
+
+ /* Decode state, should have (value, step) */
+ if ( state == Py_None ) {
+ /* First time, it seems. Set defaults */
+ valpred = 0;
+ step = 7;
+ index = 0;
+ } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
+ return 0;
+
+ step = stepsizeTable[index];
+ bufferstep = 1;
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+ /* Step 1 - compute difference with previous value */
+ diff = val - valpred;
+ sign = (diff < 0) ? 8 : 0;
+ if ( sign ) diff = (-diff);
+
+ /* Step 2 - Divide and clamp */
+ /* Note:
+ ** This code *approximately* computes:
+ ** delta = diff*4/step;
+ ** vpdiff = (delta+0.5)*step/4;
+ ** but in shift step bits are dropped. The net result of this
+ ** is that even if you have fast mul/div hardware you cannot
+ ** put it to good use since the fixup would be too expensive.
+ */
+ delta = 0;
+ vpdiff = (step >> 3);
+
+ if ( diff >= step ) {
+ delta = 4;
+ diff -= step;
+ vpdiff += step;
+ }
+ step >>= 1;
+ if ( diff >= step ) {
+ delta |= 2;
+ diff -= step;
+ vpdiff += step;
+ }
+ step >>= 1;
+ if ( diff >= step ) {
+ delta |= 1;
+ vpdiff += step;
+ }
+
+ /* Step 3 - Update previous value */
+ if ( sign )
+ valpred -= vpdiff;
+ else
+ valpred += vpdiff;
+
+ /* Step 4 - Clamp previous value to 16 bits */
+ if ( valpred > 32767 )
+ valpred = 32767;
+ else if ( valpred < -32768 )
+ valpred = -32768;
+
+ /* Step 5 - Assemble value, update index and step values */
+ delta |= sign;
+
+ index += indexTable[delta];
+ if ( index < 0 ) index = 0;
+ if ( index > 88 ) index = 88;
+ step = stepsizeTable[index];
+
+ /* Step 6 - Output value */
+ if ( bufferstep ) {
+ outputbuffer = (delta << 4) & 0xf0;
+ } else {
+ *ncp++ = (delta & 0x0f) | outputbuffer;
+ }
+ bufferstep = !bufferstep;
+ }
+ rv = Py_BuildValue("(O(ii))", str, valpred, index);
+ Py_DECREF(str);
+ return rv;
+}
+
+static PyObject *
+audioop_adpcm2lin(PyObject *self, PyObject *args)
+{
+ signed char *cp;
+ signed char *ncp;
+ int len, size, valpred, step, delta, index, sign, vpdiff;
+ PyObject *rv, *str, *state;
+ int i, inputbuffer = 0, bufferstep;
+
+ if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
+ &cp, &len, &size, &state) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4) {
+ PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+
+ /* Decode state, should have (value, step) */
+ if ( state == Py_None ) {
+ /* First time, it seems. Set defaults */
+ valpred = 0;
+ step = 7;
+ index = 0;
+ } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
+ return 0;
+
+ str = PyString_FromStringAndSize(NULL, len*size*2);
+ if ( str == 0 )
+ return 0;
+ ncp = (signed char *)PyString_AsString(str);
+
+ step = stepsizeTable[index];
+ bufferstep = 0;
+
+ for ( i=0; i < len*size*2; i += size ) {
+ /* Step 1 - get the delta value and compute next index */
+ if ( bufferstep ) {
+ delta = inputbuffer & 0xf;
+ } else {
+ inputbuffer = *cp++;
+ delta = (inputbuffer >> 4) & 0xf;
+ }
+
+ bufferstep = !bufferstep;
+
+ /* Step 2 - Find new index value (for later) */
+ index += indexTable[delta];
+ if ( index < 0 ) index = 0;
+ if ( index > 88 ) index = 88;
+
+ /* Step 3 - Separate sign and magnitude */
+ sign = delta & 8;
+ delta = delta & 7;
+
+ /* Step 4 - Compute difference and new predicted value */
+ /*
+ ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
+ ** in adpcm_coder.
+ */
+ vpdiff = step >> 3;
+ if ( delta & 4 ) vpdiff += step;
+ if ( delta & 2 ) vpdiff += step>>1;
+ if ( delta & 1 ) vpdiff += step>>2;
+
+ if ( sign )
+ valpred -= vpdiff;
+ else
+ valpred += vpdiff;
+
+ /* Step 5 - clamp output value */
+ if ( valpred > 32767 )
+ valpred = 32767;
+ else if ( valpred < -32768 )
+ valpred = -32768;
+
+ /* Step 6 - Update step value */
+ step = stepsizeTable[index];
+
+ /* Step 6 - Output value */
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
+ }
+
+ rv = Py_BuildValue("(O(ii))", str, valpred, index);
+ Py_DECREF(str);
+ return rv;
+}
+
+static PyMethodDef audioop_methods[] = {
+ { "max", audioop_max, METH_VARARGS },
+ { "minmax", audioop_minmax, METH_VARARGS },
+ { "avg", audioop_avg, METH_VARARGS },
+ { "maxpp", audioop_maxpp, METH_VARARGS },
+ { "avgpp", audioop_avgpp, METH_VARARGS },
+ { "rms", audioop_rms, METH_VARARGS },
+ { "findfit", audioop_findfit, METH_VARARGS },
+ { "findmax", audioop_findmax, METH_VARARGS },
+ { "findfactor", audioop_findfactor, METH_VARARGS },
+ { "cross", audioop_cross, METH_VARARGS },
+ { "mul", audioop_mul, METH_VARARGS },
+ { "add", audioop_add, METH_VARARGS },
+ { "bias", audioop_bias, METH_VARARGS },
+ { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
+ { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
+ { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
+ { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
+ { "lin2lin", audioop_lin2lin, METH_VARARGS },
+ { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
+ { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
+ { "tomono", audioop_tomono, METH_VARARGS },
+ { "tostereo", audioop_tostereo, METH_VARARGS },
+ { "getsample", audioop_getsample, METH_VARARGS },
+ { "reverse", audioop_reverse, METH_VARARGS },
+ { "ratecv", audioop_ratecv, METH_VARARGS },
+ { 0, 0 }
+};
+
+PyMODINIT_FUNC
+initaudioop(void)
+{
+ PyObject *m, *d;
+ m = Py_InitModule("audioop", audioop_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ if (d == NULL)
+ return;
+ AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
+ if (AudioopError != NULL)
+ PyDict_SetItemString(d,"error",AudioopError);
+}
diff --git a/sys/src/cmd/python/Modules/binascii.c b/sys/src/cmd/python/Modules/binascii.c
new file mode 100644
index 000000000..4dee45198
--- /dev/null
+++ b/sys/src/cmd/python/Modules/binascii.c
@@ -0,0 +1,1350 @@
+/*
+** Routines to represent binary data in ASCII and vice-versa
+**
+** This module currently supports the following encodings:
+** uuencode:
+** each line encodes 45 bytes (except possibly the last)
+** First char encodes (binary) length, rest data
+** each char encodes 6 bits, as follows:
+** binary: 01234567 abcdefgh ijklmnop
+** ascii: 012345 67abcd efghij klmnop
+** ASCII encoding method is "excess-space": 000000 is encoded as ' ', etc.
+** short binary data is zero-extended (so the bits are always in the
+** right place), this does *not* reflect in the length.
+** base64:
+** Line breaks are insignificant, but lines are at most 76 chars
+** each char encodes 6 bits, in similar order as uucode/hqx. Encoding
+** is done via a table.
+** Short binary data is filled (in ASCII) with '='.
+** hqx:
+** File starts with introductory text, real data starts and ends
+** with colons.
+** Data consists of three similar parts: info, datafork, resourcefork.
+** Each part is protected (at the end) with a 16-bit crc
+** The binary data is run-length encoded, and then ascii-fied:
+** binary: 01234567 abcdefgh ijklmnop
+** ascii: 012345 67abcd efghij klmnop
+** ASCII encoding is table-driven, see the code.
+** Short binary data results in the runt ascii-byte being output with
+** the bits in the right place.
+**
+** While I was reading dozens of programs that encode or decode the formats
+** here (documentation? hihi:-) I have formulated Jansen's Observation:
+**
+** Programs that encode binary data in ASCII are written in
+** such a style that they are as unreadable as possible. Devices used
+** include unnecessary global variables, burying important tables
+** in unrelated sourcefiles, putting functions in include files,
+** using seemingly-descriptive variable names for different purposes,
+** calls to empty subroutines and a host of others.
+**
+** I have attempted to break with this tradition, but I guess that that
+** does make the performance sub-optimal. Oh well, too bad...
+**
+** Jack Jansen, CWI, July 1995.
+**
+** Added support for quoted-printable encoding, based on rfc 1521 et al
+** quoted-printable encoding specifies that non printable characters (anything
+** below 32 and above 126) be encoded as =XX where XX is the hexadecimal value
+** of the character. It also specifies some other behavior to enable 8bit data
+** in a mail message with little difficulty (maximum line sizes, protecting
+** some cases of whitespace, etc).
+**
+** Brandon Long, September 2001.
+*/
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+
+static PyObject *Error;
+static PyObject *Incomplete;
+
+/*
+** hqx lookup table, ascii->binary.
+*/
+
+#define RUNCHAR 0x90
+
+#define DONE 0x7F
+#define SKIP 0x7E
+#define FAIL 0x7D
+
+static unsigned char table_a2b_hqx[256] = {
+/* ^@ ^A ^B ^C ^D ^E ^F ^G */
+/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/* \b \t \n ^K ^L \r ^N ^O */
+/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
+/* ^P ^Q ^R ^S ^T ^U ^V ^W */
+/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
+/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/* ! " # $ % & ' */
+/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+/* ( ) * + , - . / */
+/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
+/* 0 1 2 3 4 5 6 7 */
+/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
+/* 8 9 : ; < = > ? */
+/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
+/* @ A B C D E F G */
+/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
+/* H I J K L M N O */
+/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
+/* P Q R S T U V W */
+/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
+/* X Y Z [ \ ] ^ _ */
+/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
+/* ` a b c d e f g */
+/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
+/* h i j k l m n o */
+/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
+/* p q r s t u v w */
+/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
+/* x y z { | } ~ ^? */
+/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+};
+
+static unsigned char table_b2a_hqx[] =
+"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
+
+static char table_a2b_base64[] = {
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
+ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+};
+
+#define BASE64_PAD '='
+
+/* Max binary chunk size; limited only by available memory */
+#define BASE64_MAXBIN (INT_MAX/2 - sizeof(PyStringObject) - 3)
+
+static unsigned char table_b2a_base64[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+
+
+static unsigned short crctab_hqx[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
+};
+
+PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data");
+
+static PyObject *
+binascii_a2b_uu(PyObject *self, PyObject *args)
+{
+ unsigned char *ascii_data, *bin_data;
+ int leftbits = 0;
+ unsigned char this_ch;
+ unsigned int leftchar = 0;
+ PyObject *rv;
+ Py_ssize_t ascii_len, bin_len;
+
+ if ( !PyArg_ParseTuple(args, "t#:a2b_uu", &ascii_data, &ascii_len) )
+ return NULL;
+
+ /* First byte: binary data length (in bytes) */
+ bin_len = (*ascii_data++ - ' ') & 077;
+ ascii_len--;
+
+ /* Allocate the buffer */
+ if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
+ return NULL;
+ bin_data = (unsigned char *)PyString_AsString(rv);
+
+ for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
+ /* XXX is it really best to add NULs if there's no more data */
+ this_ch = (ascii_len > 0) ? *ascii_data : 0;
+ if ( this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) {
+ /*
+ ** Whitespace. Assume some spaces got eaten at
+ ** end-of-line. (We check this later)
+ */
+ this_ch = 0;
+ } else {
+ /* Check the character for legality
+ ** The 64 in stead of the expected 63 is because
+ ** there are a few uuencodes out there that use
+ ** '`' as zero instead of space.
+ */
+ if ( this_ch < ' ' || this_ch > (' ' + 64)) {
+ PyErr_SetString(Error, "Illegal char");
+ Py_DECREF(rv);
+ return NULL;
+ }
+ this_ch = (this_ch - ' ') & 077;
+ }
+ /*
+ ** Shift it in on the low end, and see if there's
+ ** a byte ready for output.
+ */
+ leftchar = (leftchar << 6) | (this_ch);
+ leftbits += 6;
+ if ( leftbits >= 8 ) {
+ leftbits -= 8;
+ *bin_data++ = (leftchar >> leftbits) & 0xff;
+ leftchar &= ((1 << leftbits) - 1);
+ bin_len--;
+ }
+ }
+ /*
+ ** Finally, check that if there's anything left on the line
+ ** that it's whitespace only.
+ */
+ while( ascii_len-- > 0 ) {
+ this_ch = *ascii_data++;
+ /* Extra '`' may be written as padding in some cases */
+ if ( this_ch != ' ' && this_ch != ' '+64 &&
+ this_ch != '\n' && this_ch != '\r' ) {
+ PyErr_SetString(Error, "Trailing garbage");
+ Py_DECREF(rv);
+ return NULL;
+ }
+ }
+ return rv;
+}
+
+PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data");
+
+static PyObject *
+binascii_b2a_uu(PyObject *self, PyObject *args)
+{
+ unsigned char *ascii_data, *bin_data;
+ int leftbits = 0;
+ unsigned char this_ch;
+ unsigned int leftchar = 0;
+ PyObject *rv;
+ Py_ssize_t bin_len;
+
+ if ( !PyArg_ParseTuple(args, "s#:b2a_uu", &bin_data, &bin_len) )
+ return NULL;
+ if ( bin_len > 45 ) {
+ /* The 45 is a limit that appears in all uuencode's */
+ PyErr_SetString(Error, "At most 45 bytes at once");
+ return NULL;
+ }
+
+ /* We're lazy and allocate to much (fixed up later) */
+ if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2+2)) == NULL )
+ return NULL;
+ ascii_data = (unsigned char *)PyString_AsString(rv);
+
+ /* Store the length */
+ *ascii_data++ = ' ' + (bin_len & 077);
+
+ for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) {
+ /* Shift the data (or padding) into our buffer */
+ if ( bin_len > 0 ) /* Data */
+ leftchar = (leftchar << 8) | *bin_data;
+ else /* Padding */
+ leftchar <<= 8;
+ leftbits += 8;
+
+ /* See if there are 6-bit groups ready */
+ while ( leftbits >= 6 ) {
+ this_ch = (leftchar >> (leftbits-6)) & 0x3f;
+ leftbits -= 6;
+ *ascii_data++ = this_ch + ' ';
+ }
+ }
+ *ascii_data++ = '\n'; /* Append a courtesy newline */
+
+ _PyString_Resize(&rv, (ascii_data -
+ (unsigned char *)PyString_AsString(rv)));
+ return rv;
+}
+
+
+static int
+binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num)
+{
+ /* Finds & returns the (num+1)th
+ ** valid character for base64, or -1 if none.
+ */
+
+ int ret = -1;
+ unsigned char c, b64val;
+
+ while ((slen > 0) && (ret == -1)) {
+ c = *s;
+ b64val = table_a2b_base64[c & 0x7f];
+ if ( ((c <= 0x7f) && (b64val != (unsigned char)-1)) ) {
+ if (num == 0)
+ ret = *s;
+ num--;
+ }
+
+ s++;
+ slen--;
+ }
+ return ret;
+}
+
+PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data");
+
+static PyObject *
+binascii_a2b_base64(PyObject *self, PyObject *args)
+{
+ unsigned char *ascii_data, *bin_data;
+ int leftbits = 0;
+ unsigned char this_ch;
+ unsigned int leftchar = 0;
+ PyObject *rv;
+ Py_ssize_t ascii_len, bin_len;
+ int quad_pos = 0;
+
+ if ( !PyArg_ParseTuple(args, "t#:a2b_base64", &ascii_data, &ascii_len) )
+ return NULL;
+
+ bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
+
+ /* Allocate the buffer */
+ if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL )
+ return NULL;
+ bin_data = (unsigned char *)PyString_AsString(rv);
+ bin_len = 0;
+
+ for( ; ascii_len > 0; ascii_len--, ascii_data++) {
+ this_ch = *ascii_data;
+
+ if (this_ch > 0x7f ||
+ this_ch == '\r' || this_ch == '\n' || this_ch == ' ')
+ continue;
+
+ /* Check for pad sequences and ignore
+ ** the invalid ones.
+ */
+ if (this_ch == BASE64_PAD) {
+ if ( (quad_pos < 2) ||
+ ((quad_pos == 2) &&
+ (binascii_find_valid(ascii_data, ascii_len, 1)
+ != BASE64_PAD)) )
+ {
+ continue;
+ }
+ else {
+ /* A pad sequence means no more input.
+ ** We've already interpreted the data
+ ** from the quad at this point.
+ */
+ leftbits = 0;
+ break;
+ }
+ }
+
+ this_ch = table_a2b_base64[*ascii_data];
+ if ( this_ch == (unsigned char) -1 )
+ continue;
+
+ /*
+ ** Shift it in on the low end, and see if there's
+ ** a byte ready for output.
+ */
+ quad_pos = (quad_pos + 1) & 0x03;
+ leftchar = (leftchar << 6) | (this_ch);
+ leftbits += 6;
+
+ if ( leftbits >= 8 ) {
+ leftbits -= 8;
+ *bin_data++ = (leftchar >> leftbits) & 0xff;
+ bin_len++;
+ leftchar &= ((1 << leftbits) - 1);
+ }
+ }
+
+ if (leftbits != 0) {
+ PyErr_SetString(Error, "Incorrect padding");
+ Py_DECREF(rv);
+ return NULL;
+ }
+
+ /* And set string size correctly. If the result string is empty
+ ** (because the input was all invalid) return the shared empty
+ ** string instead; _PyString_Resize() won't do this for us.
+ */
+ if (bin_len > 0)
+ _PyString_Resize(&rv, bin_len);
+ else {
+ Py_DECREF(rv);
+ rv = PyString_FromString("");
+ }
+ return rv;
+}
+
+PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data");
+
+static PyObject *
+binascii_b2a_base64(PyObject *self, PyObject *args)
+{
+ unsigned char *ascii_data, *bin_data;
+ int leftbits = 0;
+ unsigned char this_ch;
+ unsigned int leftchar = 0;
+ PyObject *rv;
+ Py_ssize_t bin_len;
+
+ if ( !PyArg_ParseTuple(args, "s#:b2a_base64", &bin_data, &bin_len) )
+ return NULL;
+ if ( bin_len > BASE64_MAXBIN ) {
+ PyErr_SetString(Error, "Too much data for base64 line");
+ return NULL;
+ }
+
+ /* We're lazy and allocate too much (fixed up later).
+ "+3" leaves room for up to two pad characters and a trailing
+ newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
+ if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL )
+ return NULL;
+ ascii_data = (unsigned char *)PyString_AsString(rv);
+
+ for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
+ /* Shift the data into our buffer */
+ leftchar = (leftchar << 8) | *bin_data;
+ leftbits += 8;
+
+ /* See if there are 6-bit groups ready */
+ while ( leftbits >= 6 ) {
+ this_ch = (leftchar >> (leftbits-6)) & 0x3f;
+ leftbits -= 6;
+ *ascii_data++ = table_b2a_base64[this_ch];
+ }
+ }
+ if ( leftbits == 2 ) {
+ *ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
+ *ascii_data++ = BASE64_PAD;
+ *ascii_data++ = BASE64_PAD;
+ } else if ( leftbits == 4 ) {
+ *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
+ *ascii_data++ = BASE64_PAD;
+ }
+ *ascii_data++ = '\n'; /* Append a courtesy newline */
+
+ _PyString_Resize(&rv, (ascii_data -
+ (unsigned char *)PyString_AsString(rv)));
+ return rv;
+}
+
+PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding");
+
+static PyObject *
+binascii_a2b_hqx(PyObject *self, PyObject *args)
+{
+ unsigned char *ascii_data, *bin_data;
+ int leftbits = 0;
+ unsigned char this_ch;
+ unsigned int leftchar = 0;
+ PyObject *rv;
+ Py_ssize_t len;
+ int done = 0;
+
+ if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) )
+ return NULL;
+
+ /* Allocate a string that is too big (fixed later)
+ Add two to the initial length to prevent interning which
+ would preclude subsequent resizing. */
+ if ( (rv=PyString_FromStringAndSize(NULL, len+2)) == NULL )
+ return NULL;
+ bin_data = (unsigned char *)PyString_AsString(rv);
+
+ for( ; len > 0 ; len--, ascii_data++ ) {
+ /* Get the byte and look it up */
+ this_ch = table_a2b_hqx[*ascii_data];
+ if ( this_ch == SKIP )
+ continue;
+ if ( this_ch == FAIL ) {
+ PyErr_SetString(Error, "Illegal char");
+ Py_DECREF(rv);
+ return NULL;
+ }
+ if ( this_ch == DONE ) {
+ /* The terminating colon */
+ done = 1;
+ break;
+ }
+
+ /* Shift it into the buffer and see if any bytes are ready */
+ leftchar = (leftchar << 6) | (this_ch);
+ leftbits += 6;
+ if ( leftbits >= 8 ) {
+ leftbits -= 8;
+ *bin_data++ = (leftchar >> leftbits) & 0xff;
+ leftchar &= ((1 << leftbits) - 1);
+ }
+ }
+
+ if ( leftbits && !done ) {
+ PyErr_SetString(Incomplete,
+ "String has incomplete number of bytes");
+ Py_DECREF(rv);
+ return NULL;
+ }
+ _PyString_Resize(
+ &rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
+ if (rv) {
+ PyObject *rrv = Py_BuildValue("Oi", rv, done);
+ Py_DECREF(rv);
+ return rrv;
+ }
+
+ return NULL;
+}
+
+PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data");
+
+static PyObject *
+binascii_rlecode_hqx(PyObject *self, PyObject *args)
+{
+ unsigned char *in_data, *out_data;
+ PyObject *rv;
+ unsigned char ch;
+ Py_ssize_t in, inend, len;
+
+ if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) )
+ return NULL;
+
+ /* Worst case: output is twice as big as input (fixed later) */
+ if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
+ return NULL;
+ out_data = (unsigned char *)PyString_AsString(rv);
+
+ for( in=0; in<len; in++) {
+ ch = in_data[in];
+ if ( ch == RUNCHAR ) {
+ /* RUNCHAR. Escape it. */
+ *out_data++ = RUNCHAR;
+ *out_data++ = 0;
+ } else {
+ /* Check how many following are the same */
+ for(inend=in+1;
+ inend<len && in_data[inend] == ch &&
+ inend < in+255;
+ inend++) ;
+ if ( inend - in > 3 ) {
+ /* More than 3 in a row. Output RLE. */
+ *out_data++ = ch;
+ *out_data++ = RUNCHAR;
+ *out_data++ = inend-in;
+ in = inend-1;
+ } else {
+ /* Less than 3. Output the byte itself */
+ *out_data++ = ch;
+ }
+ }
+ }
+ _PyString_Resize(&rv, (out_data -
+ (unsigned char *)PyString_AsString(rv)));
+ return rv;
+}
+
+PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data");
+
+static PyObject *
+binascii_b2a_hqx(PyObject *self, PyObject *args)
+{
+ unsigned char *ascii_data, *bin_data;
+ int leftbits = 0;
+ unsigned char this_ch;
+ unsigned int leftchar = 0;
+ PyObject *rv;
+ Py_ssize_t len;
+
+ if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
+ return NULL;
+
+ /* Allocate a buffer that is at least large enough */
+ if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
+ return NULL;
+ ascii_data = (unsigned char *)PyString_AsString(rv);
+
+ for( ; len > 0 ; len--, bin_data++ ) {
+ /* Shift into our buffer, and output any 6bits ready */
+ leftchar = (leftchar << 8) | *bin_data;
+ leftbits += 8;
+ while ( leftbits >= 6 ) {
+ this_ch = (leftchar >> (leftbits-6)) & 0x3f;
+ leftbits -= 6;
+ *ascii_data++ = table_b2a_hqx[this_ch];
+ }
+ }
+ /* Output a possible runt byte */
+ if ( leftbits ) {
+ leftchar <<= (6-leftbits);
+ *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
+ }
+ _PyString_Resize(&rv, (ascii_data -
+ (unsigned char *)PyString_AsString(rv)));
+ return rv;
+}
+
+PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string");
+
+static PyObject *
+binascii_rledecode_hqx(PyObject *self, PyObject *args)
+{
+ unsigned char *in_data, *out_data;
+ unsigned char in_byte, in_repeat;
+ PyObject *rv;
+ Py_ssize_t in_len, out_len, out_len_left;
+
+ if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) )
+ return NULL;
+
+ /* Empty string is a special case */
+ if ( in_len == 0 )
+ return PyString_FromString("");
+
+ /* Allocate a buffer of reasonable size. Resized when needed */
+ out_len = in_len*2;
+ if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
+ return NULL;
+ out_len_left = out_len;
+ out_data = (unsigned char *)PyString_AsString(rv);
+
+ /*
+ ** We need two macros here to get/put bytes and handle
+ ** end-of-buffer for input and output strings.
+ */
+#define INBYTE(b) \
+ do { \
+ if ( --in_len < 0 ) { \
+ PyErr_SetString(Incomplete, ""); \
+ Py_DECREF(rv); \
+ return NULL; \
+ } \
+ b = *in_data++; \
+ } while(0)
+
+#define OUTBYTE(b) \
+ do { \
+ if ( --out_len_left < 0 ) { \
+ _PyString_Resize(&rv, 2*out_len); \
+ if ( rv == NULL ) return NULL; \
+ out_data = (unsigned char *)PyString_AsString(rv) \
+ + out_len; \
+ out_len_left = out_len-1; \
+ out_len = out_len * 2; \
+ } \
+ *out_data++ = b; \
+ } while(0)
+
+ /*
+ ** Handle first byte separately (since we have to get angry
+ ** in case of an orphaned RLE code).
+ */
+ INBYTE(in_byte);
+
+ if (in_byte == RUNCHAR) {
+ INBYTE(in_repeat);
+ if (in_repeat != 0) {
+ /* Note Error, not Incomplete (which is at the end
+ ** of the string only). This is a programmer error.
+ */
+ PyErr_SetString(Error, "Orphaned RLE code at start");
+ Py_DECREF(rv);
+ return NULL;
+ }
+ OUTBYTE(RUNCHAR);
+ } else {
+ OUTBYTE(in_byte);
+ }
+
+ while( in_len > 0 ) {
+ INBYTE(in_byte);
+
+ if (in_byte == RUNCHAR) {
+ INBYTE(in_repeat);
+ if ( in_repeat == 0 ) {
+ /* Just an escaped RUNCHAR value */
+ OUTBYTE(RUNCHAR);
+ } else {
+ /* Pick up value and output a sequence of it */
+ in_byte = out_data[-1];
+ while ( --in_repeat > 0 )
+ OUTBYTE(in_byte);
+ }
+ } else {
+ /* Normal byte */
+ OUTBYTE(in_byte);
+ }
+ }
+ _PyString_Resize(&rv, (out_data -
+ (unsigned char *)PyString_AsString(rv)));
+ return rv;
+}
+
+PyDoc_STRVAR(doc_crc_hqx,
+"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally");
+
+static PyObject *
+binascii_crc_hqx(PyObject *self, PyObject *args)
+{
+ unsigned char *bin_data;
+ unsigned int crc;
+ Py_ssize_t len;
+
+ if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) )
+ return NULL;
+
+ while(len--) {
+ crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
+ }
+
+ return Py_BuildValue("i", crc);
+}
+
+PyDoc_STRVAR(doc_crc32,
+"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally");
+
+/* Crc - 32 BIT ANSI X3.66 CRC checksum files
+ Also known as: ISO 3307
+**********************************************************************|
+* *|
+* Demonstration program to compute the 32-bit CRC used as the frame *|
+* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
+* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
+* protocol). The 32-bit FCS was added via the Federal Register, *|
+* 1 June 1982, p.23798. I presume but don't know for certain that *|
+* this polynomial is or will be included in CCITT V.41, which *|
+* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
+* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
+* errors by a factor of 10^-5 over 16-bit FCS. *|
+* *|
+**********************************************************************|
+
+ Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ code or tables extracted from it, as desired without restriction.
+
+ First, the polynomial itself and its table of feedback terms. The
+ polynomial is
+ X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
+ Note that we take it "backwards" and put the highest-order term in
+ the lowest-order bit. The X^32 term is "implied"; the LSB is the
+ X^31 term, etc. The X^0 term (usually shown as "+1") results in
+ the MSB being 1.
+
+ Note that the usual hardware shift register implementation, which
+ is what we're using (we're merely optimizing it by doing eight-bit
+ chunks at a time) shifts bits into the lowest-order term. In our
+ implementation, that means shifting towards the right. Why do we
+ do it this way? Because the calculated CRC must be transmitted in
+ order from highest-order term to lowest-order term. UARTs transmit
+ characters in order from LSB to MSB. By storing the CRC this way,
+ we hand it to the UART in the order low-byte to high-byte; the UART
+ sends each low-bit to hight-bit; and the result is transmission bit
+ by bit from highest- to lowest-order term without requiring any bit
+ shuffling on our part. Reception works similarly.
+
+ The feedback terms table consists of 256, 32-bit entries. Notes:
+
+ 1. The table can be generated at runtime if desired; code to do so
+ is shown later. It might not be obvious, but the feedback
+ terms simply represent the results of eight shift/xor opera-
+ tions for all combinations of data and CRC register values.
+
+ 2. The CRC accumulation logic is the same for all CRC polynomials,
+ be they sixteen or thirty-two bits wide. You simply choose the
+ appropriate table. Alternatively, because the table can be
+ generated at runtime, you can start by generating the table for
+ the polynomial in question and use exactly the same "updcrc",
+ if your application needn't simultaneously handle two CRC
+ polynomials. (Note, however, that XMODEM is strange.)
+
+ 3. For 16-bit CRCs, the table entries need be only 16 bits wide;
+ of course, 32-bit entries work OK if the high 16 bits are zero.
+
+ 4. The values must be right-shifted by eight bits by the "updcrc"
+ logic; the shift must be unsigned (bring in zeroes). On some
+ hardware you could probably optimize the shift in assembler by
+ using byte-swap instructions.
+********************************************************************/
+
+static unsigned long crc_32_tab[256] = {
+0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+0x2d02ef8dUL
+};
+
+static PyObject *
+binascii_crc32(PyObject *self, PyObject *args)
+{ /* By Jim Ahlstrom; All rights transferred to CNRI */
+ unsigned char *bin_data;
+ unsigned long crc = 0UL; /* initial value of CRC */
+ Py_ssize_t len;
+ long result;
+
+ if ( !PyArg_ParseTuple(args, "s#|l:crc32", &bin_data, &len, &crc) )
+ return NULL;
+
+ crc = ~ crc;
+#if SIZEOF_LONG > 4
+ /* only want the trailing 32 bits */
+ crc &= 0xFFFFFFFFUL;
+#endif
+ while (len--)
+ crc = crc_32_tab[(crc ^ *bin_data++) & 0xffUL] ^ (crc >> 8);
+ /* Note: (crc >> 8) MUST zero fill on left */
+
+ result = (long)(crc ^ 0xFFFFFFFFUL);
+#if SIZEOF_LONG > 4
+ /* Extend the sign bit. This is one way to ensure the result is the
+ * same across platforms. The other way would be to return an
+ * unbounded unsigned long, but the evidence suggests that lots of
+ * code outside this treats the result as if it were a signed 4-byte
+ * integer.
+ */
+ result |= -(result & (1L << 31));
+#endif
+ return PyInt_FromLong(result);
+}
+
+
+static PyObject *
+binascii_hexlify(PyObject *self, PyObject *args)
+{
+ char* argbuf;
+ Py_ssize_t arglen;
+ PyObject *retval;
+ char* retbuf;
+ Py_ssize_t i, j;
+
+ if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen))
+ return NULL;
+
+ retval = PyString_FromStringAndSize(NULL, arglen*2);
+ if (!retval)
+ return NULL;
+ retbuf = PyString_AsString(retval);
+ if (!retbuf)
+ goto finally;
+
+ /* make hex version of string, taken from shamodule.c */
+ for (i=j=0; i < arglen; i++) {
+ char c;
+ c = (argbuf[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ retbuf[j++] = c;
+ c = argbuf[i] & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ retbuf[j++] = c;
+ }
+ return retval;
+
+ finally:
+ Py_DECREF(retval);
+ return NULL;
+}
+
+PyDoc_STRVAR(doc_hexlify,
+"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\
+\n\
+This function is also available as \"hexlify()\".");
+
+
+static int
+to_int(int c)
+{
+ if (isdigit(c))
+ return c - '0';
+ else {
+ if (isupper(c))
+ c = tolower(c);
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ }
+ return -1;
+}
+
+
+static PyObject *
+binascii_unhexlify(PyObject *self, PyObject *args)
+{
+ char* argbuf;
+ Py_ssize_t arglen;
+ PyObject *retval;
+ char* retbuf;
+ Py_ssize_t i, j;
+
+ if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
+ return NULL;
+
+ /* XXX What should we do about strings with an odd length? Should
+ * we add an implicit leading zero, or a trailing zero? For now,
+ * raise an exception.
+ */
+ if (arglen % 2) {
+ PyErr_SetString(PyExc_TypeError, "Odd-length string");
+ return NULL;
+ }
+
+ retval = PyString_FromStringAndSize(NULL, (arglen/2));
+ if (!retval)
+ return NULL;
+ retbuf = PyString_AsString(retval);
+ if (!retbuf)
+ goto finally;
+
+ for (i=j=0; i < arglen; i += 2) {
+ int top = to_int(Py_CHARMASK(argbuf[i]));
+ int bot = to_int(Py_CHARMASK(argbuf[i+1]));
+ if (top == -1 || bot == -1) {
+ PyErr_SetString(PyExc_TypeError,
+ "Non-hexadecimal digit found");
+ goto finally;
+ }
+ retbuf[j++] = (top << 4) + bot;
+ }
+ return retval;
+
+ finally:
+ Py_DECREF(retval);
+ return NULL;
+}
+
+PyDoc_STRVAR(doc_unhexlify,
+"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\
+\n\
+hexstr must contain an even number of hex digits (upper or lower case).\n\
+This function is also available as \"unhexlify()\"");
+
+static int table_hex[128] = {
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1,
+ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
+};
+
+#define hexval(c) table_hex[(unsigned int)(c)]
+
+#define MAXLINESIZE 76
+
+PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data");
+
+static PyObject*
+binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ Py_ssize_t in, out;
+ char ch;
+ unsigned char *data, *odata;
+ Py_ssize_t datalen = 0;
+ PyObject *rv;
+ static char *kwlist[] = {"data", "header", NULL};
+ int header = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i", kwlist, &data,
+ &datalen, &header))
+ return NULL;
+
+ /* We allocate the output same size as input, this is overkill.
+ * The previous implementation used calloc() so we'll zero out the
+ * memory here too, since PyMem_Malloc() does not guarantee that.
+ */
+ odata = (unsigned char *) PyMem_Malloc(datalen);
+ if (odata == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(odata, 0, datalen);
+
+ in = out = 0;
+ while (in < datalen) {
+ if (data[in] == '=') {
+ in++;
+ if (in >= datalen) break;
+ /* Soft line breaks */
+ if ((data[in] == '\n') || (data[in] == '\r')) {
+ if (data[in] != '\n') {
+ while (in < datalen && data[in] != '\n') in++;
+ }
+ if (in < datalen) in++;
+ }
+ else if (data[in] == '=') {
+ /* broken case from broken python qp */
+ odata[out++] = '=';
+ in++;
+ }
+ else if (((data[in] >= 'A' && data[in] <= 'F') ||
+ (data[in] >= 'a' && data[in] <= 'f') ||
+ (data[in] >= '0' && data[in] <= '9')) &&
+ ((data[in+1] >= 'A' && data[in+1] <= 'F') ||
+ (data[in+1] >= 'a' && data[in+1] <= 'f') ||
+ (data[in+1] >= '0' && data[in+1] <= '9'))) {
+ /* hexval */
+ ch = hexval(data[in]) << 4;
+ in++;
+ ch |= hexval(data[in]);
+ in++;
+ odata[out++] = ch;
+ }
+ else {
+ odata[out++] = '=';
+ }
+ }
+ else if (header && data[in] == '_') {
+ odata[out++] = ' ';
+ in++;
+ }
+ else {
+ odata[out] = data[in];
+ in++;
+ out++;
+ }
+ }
+ if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) {
+ PyMem_Free(odata);
+ return NULL;
+ }
+ PyMem_Free(odata);
+ return rv;
+}
+
+static int
+to_hex (unsigned char ch, unsigned char *s)
+{
+ unsigned int uvalue = ch;
+
+ s[1] = "0123456789ABCDEF"[uvalue % 16];
+ uvalue = (uvalue / 16);
+ s[0] = "0123456789ABCDEF"[uvalue % 16];
+ return 0;
+}
+
+PyDoc_STRVAR(doc_b2a_qp,
+"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\
+ Encode a string using quoted-printable encoding. \n\
+\n\
+On encoding, when istext is set, newlines are not encoded, and white \n\
+space at end of lines is. When istext is not set, \\r and \\n (CR/LF) are \n\
+both encoded. When quotetabs is set, space and tabs are encoded.");
+
+/* XXX: This is ridiculously complicated to be backward compatible
+ * (mostly) with the quopri module. It doesn't re-create the quopri
+ * module bug where text ending in CRLF has the CR encoded */
+static PyObject*
+binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ Py_ssize_t in, out;
+ unsigned char *data, *odata;
+ Py_ssize_t datalen = 0, odatalen = 0;
+ PyObject *rv;
+ unsigned int linelen = 0;
+ static char *kwlist[] = {"data", "quotetabs", "istext",
+ "header", NULL};
+ int istext = 1;
+ int quotetabs = 0;
+ int header = 0;
+ unsigned char ch;
+ int crlf = 0;
+ unsigned char *p;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|iii", kwlist, &data,
+ &datalen, &quotetabs, &istext, &header))
+ return NULL;
+
+ /* See if this string is using CRLF line ends */
+ /* XXX: this function has the side effect of converting all of
+ * the end of lines to be the same depending on this detection
+ * here */
+ p = (unsigned char *) strchr((char *)data, '\n');
+ if ((p != NULL) && (p > data) && (*(p-1) == '\r'))
+ crlf = 1;
+
+ /* First, scan to see how many characters need to be encoded */
+ in = 0;
+ while (in < datalen) {
+ if ((data[in] > 126) ||
+ (data[in] == '=') ||
+ (header && data[in] == '_') ||
+ ((data[in] == '.') && (linelen == 1)) ||
+ (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
+ ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
+ ((data[in] < 33) &&
+ (data[in] != '\r') && (data[in] != '\n') &&
+ (quotetabs && ((data[in] != '\t') || (data[in] != ' ')))))
+ {
+ if ((linelen + 3) >= MAXLINESIZE) {
+ linelen = 0;
+ if (crlf)
+ odatalen += 3;
+ else
+ odatalen += 2;
+ }
+ linelen += 3;
+ odatalen += 3;
+ in++;
+ }
+ else {
+ if (istext &&
+ ((data[in] == '\n') ||
+ ((in+1 < datalen) && (data[in] == '\r') &&
+ (data[in+1] == '\n'))))
+ {
+ linelen = 0;
+ /* Protect against whitespace on end of line */
+ if (in && ((data[in-1] == ' ') || (data[in-1] == '\t')))
+ odatalen += 2;
+ if (crlf)
+ odatalen += 2;
+ else
+ odatalen += 1;
+ if (data[in] == '\r')
+ in += 2;
+ else
+ in++;
+ }
+ else {
+ if ((in + 1 != datalen) &&
+ (data[in+1] != '\n') &&
+ (linelen + 1) >= MAXLINESIZE) {
+ linelen = 0;
+ if (crlf)
+ odatalen += 3;
+ else
+ odatalen += 2;
+ }
+ linelen++;
+ odatalen++;
+ in++;
+ }
+ }
+ }
+
+ /* We allocate the output same size as input, this is overkill.
+ * The previous implementation used calloc() so we'll zero out the
+ * memory here too, since PyMem_Malloc() does not guarantee that.
+ */
+ odata = (unsigned char *) PyMem_Malloc(odatalen);
+ if (odata == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(odata, 0, odatalen);
+
+ in = out = linelen = 0;
+ while (in < datalen) {
+ if ((data[in] > 126) ||
+ (data[in] == '=') ||
+ (header && data[in] == '_') ||
+ ((data[in] == '.') && (linelen == 1)) ||
+ (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
+ ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
+ ((data[in] < 33) &&
+ (data[in] != '\r') && (data[in] != '\n') &&
+ (quotetabs && ((data[in] != '\t') || (data[in] != ' ')))))
+ {
+ if ((linelen + 3 )>= MAXLINESIZE) {
+ odata[out++] = '=';
+ if (crlf) odata[out++] = '\r';
+ odata[out++] = '\n';
+ linelen = 0;
+ }
+ odata[out++] = '=';
+ to_hex(data[in], &odata[out]);
+ out += 2;
+ in++;
+ linelen += 3;
+ }
+ else {
+ if (istext &&
+ ((data[in] == '\n') ||
+ ((in+1 < datalen) && (data[in] == '\r') &&
+ (data[in+1] == '\n'))))
+ {
+ linelen = 0;
+ /* Protect against whitespace on end of line */
+ if (out && ((odata[out-1] == ' ') || (odata[out-1] == '\t'))) {
+ ch = odata[out-1];
+ odata[out-1] = '=';
+ to_hex(ch, &odata[out]);
+ out += 2;
+ }
+
+ if (crlf) odata[out++] = '\r';
+ odata[out++] = '\n';
+ if (data[in] == '\r')
+ in += 2;
+ else
+ in++;
+ }
+ else {
+ if ((in + 1 != datalen) &&
+ (data[in+1] != '\n') &&
+ (linelen + 1) >= MAXLINESIZE) {
+ odata[out++] = '=';
+ if (crlf) odata[out++] = '\r';
+ odata[out++] = '\n';
+ linelen = 0;
+ }
+ linelen++;
+ if (header && data[in] == ' ') {
+ odata[out++] = '_';
+ in++;
+ }
+ else {
+ odata[out++] = data[in++];
+ }
+ }
+ }
+ }
+ if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) {
+ PyMem_Free(odata);
+ return NULL;
+ }
+ PyMem_Free(odata);
+ return rv;
+}
+
+/* List of functions defined in the module */
+
+static struct PyMethodDef binascii_module_methods[] = {
+ {"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu},
+ {"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu},
+ {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64},
+ {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64},
+ {"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx},
+ {"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx},
+ {"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify},
+ {"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify},
+ {"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify},
+ {"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify},
+ {"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx},
+ {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS,
+ doc_rledecode_hqx},
+ {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx},
+ {"crc32", binascii_crc32, METH_VARARGS, doc_crc32},
+ {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS,
+ doc_a2b_qp},
+ {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS,
+ doc_b2a_qp},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initbinascii) */
+PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII");
+
+PyMODINIT_FUNC
+initbinascii(void)
+{
+ PyObject *m, *d, *x;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("binascii", binascii_module_methods);
+ if (m == NULL)
+ return;
+
+ d = PyModule_GetDict(m);
+ x = PyString_FromString(doc_binascii);
+ PyDict_SetItemString(d, "__doc__", x);
+ Py_XDECREF(x);
+
+ Error = PyErr_NewException("binascii.Error", NULL, NULL);
+ PyDict_SetItemString(d, "Error", Error);
+ Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL);
+ PyDict_SetItemString(d, "Incomplete", Incomplete);
+}
diff --git a/sys/src/cmd/python/Modules/bsddbmodule.c b/sys/src/cmd/python/Modules/bsddbmodule.c
new file mode 100644
index 000000000..61c656437
--- /dev/null
+++ b/sys/src/cmd/python/Modules/bsddbmodule.c
@@ -0,0 +1,858 @@
+/* Berkeley DB interface.
+ Author: Michael McLay
+ Hacked: Guido van Rossum
+ Btree and Recno additions plus sequence methods: David Ely
+ Hacked by Gustavo Niemeyer <niemeyer@conectiva.com> fixing recno
+ support.
+
+ XXX To do:
+ - provide a way to access the various hash functions
+ - support more open flags
+
+ The windows port of the Berkeley DB code is hard to find on the web:
+ www.nightmare.com/software.html
+*/
+
+#include "Python.h"
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_DB_185_H
+#include <db_185.h>
+#else
+#include <db.h>
+#endif
+/* Please don't include internal header files of the Berkeley db package
+ (it messes up the info required in the Setup file) */
+
+typedef struct {
+ PyObject_HEAD
+ DB *di_bsddb;
+ int di_size; /* -1 means recompute */
+ int di_type;
+#ifdef WITH_THREAD
+ PyThread_type_lock di_lock;
+#endif
+} bsddbobject;
+
+static PyTypeObject Bsddbtype;
+
+#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
+#define check_bsddbobject_open(v, r) if ((v)->di_bsddb == NULL) \
+ { PyErr_SetString(BsddbError, \
+ "BSDDB object has already been closed"); \
+ return r; }
+
+static PyObject *BsddbError;
+
+static PyObject *
+newdbhashobject(char *file, int flags, int mode,
+ int bsize, int ffactor, int nelem, int cachesize,
+ int hash, int lorder)
+{
+ bsddbobject *dp;
+ HASHINFO info;
+
+ if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
+ return NULL;
+
+ info.bsize = bsize;
+ info.ffactor = ffactor;
+ info.nelem = nelem;
+ info.cachesize = cachesize;
+ info.hash = NULL; /* XXX should derive from hash argument */
+ info.lorder = lorder;
+
+#ifdef O_BINARY
+ flags |= O_BINARY;
+#endif
+ Py_BEGIN_ALLOW_THREADS
+ dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
+ Py_END_ALLOW_THREADS
+ if (dp->di_bsddb == NULL) {
+ PyErr_SetFromErrno(BsddbError);
+#ifdef WITH_THREAD
+ dp->di_lock = NULL;
+#endif
+ Py_DECREF(dp);
+ return NULL;
+ }
+
+ dp->di_size = -1;
+ dp->di_type = DB_HASH;
+
+#ifdef WITH_THREAD
+ dp->di_lock = PyThread_allocate_lock();
+ if (dp->di_lock == NULL) {
+ PyErr_SetString(BsddbError, "can't allocate lock");
+ Py_DECREF(dp);
+ return NULL;
+ }
+#endif
+
+ return (PyObject *)dp;
+}
+
+static PyObject *
+newdbbtobject(char *file, int flags, int mode,
+ int btflags, int cachesize, int maxkeypage,
+ int minkeypage, int psize, int lorder)
+{
+ bsddbobject *dp;
+ BTREEINFO info;
+
+ if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
+ return NULL;
+
+ info.flags = btflags;
+ info.cachesize = cachesize;
+ info.maxkeypage = maxkeypage;
+ info.minkeypage = minkeypage;
+ info.psize = psize;
+ info.lorder = lorder;
+ info.compare = 0; /* Use default comparison functions, for now..*/
+ info.prefix = 0;
+
+#ifdef O_BINARY
+ flags |= O_BINARY;
+#endif
+ Py_BEGIN_ALLOW_THREADS
+ dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
+ Py_END_ALLOW_THREADS
+ if (dp->di_bsddb == NULL) {
+ PyErr_SetFromErrno(BsddbError);
+#ifdef WITH_THREAD
+ dp->di_lock = NULL;
+#endif
+ Py_DECREF(dp);
+ return NULL;
+ }
+
+ dp->di_size = -1;
+ dp->di_type = DB_BTREE;
+
+#ifdef WITH_THREAD
+ dp->di_lock = PyThread_allocate_lock();
+ if (dp->di_lock == NULL) {
+ PyErr_SetString(BsddbError, "can't allocate lock");
+ Py_DECREF(dp);
+ return NULL;
+ }
+#endif
+
+ return (PyObject *)dp;
+}
+
+static PyObject *
+newdbrnobject(char *file, int flags, int mode,
+ int rnflags, int cachesize, int psize, int lorder,
+ size_t reclen, u_char bval, char *bfname)
+{
+ bsddbobject *dp;
+ RECNOINFO info;
+ int fd;
+
+ if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
+ return NULL;
+
+ info.flags = rnflags;
+ info.cachesize = cachesize;
+ info.psize = psize;
+ info.lorder = lorder;
+ info.reclen = reclen;
+ info.bval = bval;
+ info.bfname = bfname;
+
+#ifdef O_BINARY
+ flags |= O_BINARY;
+#endif
+ /* This is a hack to avoid a dbopen() bug that happens when
+ * it fails. */
+ fd = open(file, flags);
+ if (fd == -1) {
+ dp->di_bsddb = NULL;
+ }
+ else {
+ close(fd);
+ Py_BEGIN_ALLOW_THREADS
+ dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
+ Py_END_ALLOW_THREADS
+ }
+ if (dp->di_bsddb == NULL) {
+ PyErr_SetFromErrno(BsddbError);
+#ifdef WITH_THREAD
+ dp->di_lock = NULL;
+#endif
+ Py_DECREF(dp);
+ return NULL;
+ }
+
+ dp->di_size = -1;
+ dp->di_type = DB_RECNO;
+
+#ifdef WITH_THREAD
+ dp->di_lock = PyThread_allocate_lock();
+ if (dp->di_lock == NULL) {
+ PyErr_SetString(BsddbError, "can't allocate lock");
+ Py_DECREF(dp);
+ return NULL;
+ }
+#endif
+
+ return (PyObject *)dp;
+}
+
+static void
+bsddb_dealloc(bsddbobject *dp)
+{
+#ifdef WITH_THREAD
+ if (dp->di_lock) {
+ PyThread_acquire_lock(dp->di_lock, 0);
+ PyThread_release_lock(dp->di_lock);
+ PyThread_free_lock(dp->di_lock);
+ dp->di_lock = NULL;
+ }
+#endif
+ if (dp->di_bsddb != NULL) {
+ int status;
+ Py_BEGIN_ALLOW_THREADS
+ status = (dp->di_bsddb->close)(dp->di_bsddb);
+ Py_END_ALLOW_THREADS
+ if (status != 0)
+ fprintf(stderr,
+ "Python bsddb: close errno %d in dealloc\n",
+ errno);
+ }
+ PyObject_Del(dp);
+}
+
+#ifdef WITH_THREAD
+#define BSDDB_BGN_SAVE(_dp) \
+ Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
+#define BSDDB_END_SAVE(_dp) \
+ PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
+#else
+#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
+#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
+#endif
+
+static Py_ssize_t
+bsddb_length(bsddbobject *dp)
+{
+ check_bsddbobject_open(dp, -1);
+ if (dp->di_size < 0) {
+ DBT krec, drec;
+ int status;
+ int size = 0;
+ BSDDB_BGN_SAVE(dp)
+ for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
+ &krec, &drec,R_FIRST);
+ status == 0;
+ status = (dp->di_bsddb->seq)(dp->di_bsddb,
+ &krec, &drec, R_NEXT))
+ size++;
+ BSDDB_END_SAVE(dp)
+ if (status < 0) {
+ PyErr_SetFromErrno(BsddbError);
+ return -1;
+ }
+ dp->di_size = size;
+ }
+ return dp->di_size;
+}
+
+static PyObject *
+bsddb_subscript(bsddbobject *dp, PyObject *key)
+{
+ int status;
+ DBT krec, drec;
+ char *data,buf[4096];
+ int size;
+ PyObject *result;
+ recno_t recno;
+
+ if (dp->di_type == DB_RECNO) {
+ if (!PyArg_Parse(key, "i", &recno)) {
+ PyErr_SetString(PyExc_TypeError,
+ "key type must be integer");
+ return NULL;
+ }
+ krec.data = &recno;
+ krec.size = sizeof(recno);
+ }
+ else {
+ if (!PyArg_Parse(key, "s#", &data, &size)) {
+ PyErr_SetString(PyExc_TypeError,
+ "key type must be string");
+ return NULL;
+ }
+ krec.data = data;
+ krec.size = size;
+ }
+ check_bsddbobject_open(dp, NULL);
+
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
+ if (status == 0) {
+ if (drec.size > sizeof(buf)) data = malloc(drec.size);
+ else data = buf;
+ if (data!=NULL) memcpy(data,drec.data,drec.size);
+ }
+ BSDDB_END_SAVE(dp)
+ if (data==NULL) return PyErr_NoMemory();
+ if (status != 0) {
+ if (status < 0)
+ PyErr_SetFromErrno(BsddbError);
+ else
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ }
+
+ result = PyString_FromStringAndSize(data, (int)drec.size);
+ if (data != buf) free(data);
+ return result;
+}
+
+static int
+bsddb_ass_sub(bsddbobject *dp, PyObject *key, PyObject *value)
+{
+ int status;
+ DBT krec, drec;
+ char *data;
+ int size;
+ recno_t recno;
+
+ if (dp->di_type == DB_RECNO) {
+ if (!PyArg_Parse(key, "i", &recno)) {
+ PyErr_SetString(PyExc_TypeError,
+ "bsddb key type must be integer");
+ return -1;
+ }
+ krec.data = &recno;
+ krec.size = sizeof(recno);
+ }
+ else {
+ if (!PyArg_Parse(key, "s#", &data, &size)) {
+ PyErr_SetString(PyExc_TypeError,
+ "bsddb key type must be string");
+ return -1;
+ }
+ krec.data = data;
+ krec.size = size;
+ }
+ check_bsddbobject_open(dp, -1);
+ dp->di_size = -1;
+ if (value == NULL) {
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
+ BSDDB_END_SAVE(dp)
+ }
+ else {
+ if (!PyArg_Parse(value, "s#", &data, &size)) {
+ PyErr_SetString(PyExc_TypeError,
+ "bsddb value type must be string");
+ return -1;
+ }
+ drec.data = data;
+ drec.size = size;
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
+ BSDDB_END_SAVE(dp)
+ }
+ if (status != 0) {
+ if (status < 0)
+ PyErr_SetFromErrno(BsddbError);
+ else
+ PyErr_SetObject(PyExc_KeyError, key);
+ return -1;
+ }
+ return 0;
+}
+
+static PyMappingMethods bsddb_as_mapping = {
+ (lenfunc)bsddb_length, /*mp_length*/
+ (binaryfunc)bsddb_subscript, /*mp_subscript*/
+ (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
+};
+
+static PyObject *
+bsddb_close(bsddbobject *dp)
+{
+ if (dp->di_bsddb != NULL) {
+ int status;
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->close)(dp->di_bsddb);
+ BSDDB_END_SAVE(dp)
+ if (status != 0) {
+ dp->di_bsddb = NULL;
+ PyErr_SetFromErrno(BsddbError);
+ return NULL;
+ }
+ }
+ dp->di_bsddb = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+bsddb_keys(bsddbobject *dp)
+{
+ PyObject *list, *item=NULL;
+ DBT krec, drec;
+ char *data=NULL,buf[4096];
+ int status;
+ int err;
+
+ check_bsddbobject_open(dp, NULL);
+ list = PyList_New(0);
+ if (list == NULL)
+ return NULL;
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
+ if (status == 0) {
+ if (krec.size > sizeof(buf)) data = malloc(krec.size);
+ else data = buf;
+ if (data != NULL) memcpy(data,krec.data,krec.size);
+ }
+ BSDDB_END_SAVE(dp)
+ if (status == 0 && data==NULL) return PyErr_NoMemory();
+ while (status == 0) {
+ if (dp->di_type == DB_RECNO)
+ item = PyInt_FromLong(*((int*)data));
+ else
+ item = PyString_FromStringAndSize(data,
+ (int)krec.size);
+ if (data != buf) free(data);
+ if (item == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ err = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (err != 0) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->seq)
+ (dp->di_bsddb, &krec, &drec, R_NEXT);
+ if (status == 0) {
+ if (krec.size > sizeof(buf))
+ data = malloc(krec.size);
+ else data = buf;
+ if (data != NULL)
+ memcpy(data,krec.data,krec.size);
+ }
+ BSDDB_END_SAVE(dp)
+ if (data == NULL) return PyErr_NoMemory();
+ }
+ if (status < 0) {
+ PyErr_SetFromErrno(BsddbError);
+ Py_DECREF(list);
+ return NULL;
+ }
+ if (dp->di_size < 0)
+ dp->di_size = PyList_Size(list); /* We just did the work */
+ return list;
+}
+
+static PyObject *
+bsddb_has_key(bsddbobject *dp, PyObject *args)
+{
+ DBT krec, drec;
+ int status;
+ char *data;
+ int size;
+ recno_t recno;
+
+ if (dp->di_type == DB_RECNO) {
+ if (!PyArg_ParseTuple(args, "i;key type must be integer",
+ &recno)) {
+ return NULL;
+ }
+ krec.data = &recno;
+ krec.size = sizeof(recno);
+ }
+ else {
+ if (!PyArg_ParseTuple(args, "s#;key type must be string",
+ &data, &size)) {
+ return NULL;
+ }
+ krec.data = data;
+ krec.size = size;
+ }
+ check_bsddbobject_open(dp, NULL);
+
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
+ BSDDB_END_SAVE(dp)
+ if (status < 0) {
+ PyErr_SetFromErrno(BsddbError);
+ return NULL;
+ }
+
+ return PyInt_FromLong(status == 0);
+}
+
+static PyObject *
+bsddb_set_location(bsddbobject *dp, PyObject *key)
+{
+ int status;
+ DBT krec, drec;
+ char *data,buf[4096];
+ int size;
+ PyObject *result;
+ recno_t recno;
+
+ if (dp->di_type == DB_RECNO) {
+ if (!PyArg_ParseTuple(key, "i;key type must be integer",
+ &recno)) {
+ return NULL;
+ }
+ krec.data = &recno;
+ krec.size = sizeof(recno);
+ }
+ else {
+ if (!PyArg_ParseTuple(key, "s#;key type must be string",
+ &data, &size)) {
+ return NULL;
+ }
+ krec.data = data;
+ krec.size = size;
+ }
+ check_bsddbobject_open(dp, NULL);
+
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
+ if (status == 0) {
+ if (drec.size > sizeof(buf)) data = malloc(drec.size);
+ else data = buf;
+ if (data!=NULL) memcpy(data,drec.data,drec.size);
+ }
+ BSDDB_END_SAVE(dp)
+ if (data==NULL) return PyErr_NoMemory();
+ if (status != 0) {
+ if (status < 0)
+ PyErr_SetFromErrno(BsddbError);
+ else
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ }
+
+ if (dp->di_type == DB_RECNO)
+ result = Py_BuildValue("is#", *((int*)krec.data),
+ data, drec.size);
+ else
+ result = Py_BuildValue("s#s#", krec.data, krec.size,
+ data, drec.size);
+ if (data != buf) free(data);
+ return result;
+}
+
+static PyObject *
+bsddb_seq(bsddbobject *dp, int sequence_request)
+{
+ int status;
+ DBT krec, drec;
+ char *kdata=NULL,kbuf[4096];
+ char *ddata=NULL,dbuf[4096];
+ PyObject *result;
+
+ check_bsddbobject_open(dp, NULL);
+ krec.data = 0;
+ krec.size = 0;
+
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
+ &drec, sequence_request);
+ if (status == 0) {
+ if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
+ else kdata = kbuf;
+ if (kdata != NULL) memcpy(kdata,krec.data,krec.size);
+ if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
+ else ddata = dbuf;
+ if (ddata != NULL) memcpy(ddata,drec.data,drec.size);
+ }
+ BSDDB_END_SAVE(dp)
+ if (status == 0) {
+ if ((kdata == NULL) || (ddata == NULL))
+ return PyErr_NoMemory();
+ }
+ else {
+ /* (status != 0) */
+ if (status < 0)
+ PyErr_SetFromErrno(BsddbError);
+ else
+ PyErr_SetString(PyExc_KeyError, "no key/data pairs");
+ return NULL;
+ }
+
+ if (dp->di_type == DB_RECNO)
+ result = Py_BuildValue("is#", *((int*)kdata),
+ ddata, drec.size);
+ else
+ result = Py_BuildValue("s#s#", kdata, krec.size,
+ ddata, drec.size);
+ if (kdata != kbuf) free(kdata);
+ if (ddata != dbuf) free(ddata);
+ return result;
+}
+
+static PyObject *
+bsddb_next(bsddbobject *dp)
+{
+ return bsddb_seq(dp, R_NEXT);
+}
+static PyObject *
+bsddb_previous(bsddbobject *dp)
+{
+ return bsddb_seq(dp, R_PREV);
+}
+static PyObject *
+bsddb_first(bsddbobject *dp)
+{
+ return bsddb_seq(dp, R_FIRST);
+}
+static PyObject *
+bsddb_last(bsddbobject *dp)
+{
+ return bsddb_seq(dp, R_LAST);
+}
+static PyObject *
+bsddb_sync(bsddbobject *dp)
+{
+ int status;
+
+ check_bsddbobject_open(dp, NULL);
+ BSDDB_BGN_SAVE(dp)
+ status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
+ BSDDB_END_SAVE(dp)
+ if (status != 0) {
+ PyErr_SetFromErrno(BsddbError);
+ return NULL;
+ }
+ return PyInt_FromLong(status = 0);
+}
+static PyMethodDef bsddb_methods[] = {
+ {"close", (PyCFunction)bsddb_close, METH_NOARGS},
+ {"keys", (PyCFunction)bsddb_keys, METH_NOARGS},
+ {"has_key", (PyCFunction)bsddb_has_key, METH_VARARGS},
+ {"set_location", (PyCFunction)bsddb_set_location, METH_VARARGS},
+ {"next", (PyCFunction)bsddb_next, METH_NOARGS},
+ {"previous", (PyCFunction)bsddb_previous, METH_NOARGS},
+ {"first", (PyCFunction)bsddb_first, METH_NOARGS},
+ {"last", (PyCFunction)bsddb_last, METH_NOARGS},
+ {"sync", (PyCFunction)bsddb_sync, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+bsddb_getattr(PyObject *dp, char *name)
+{
+ return Py_FindMethod(bsddb_methods, dp, name);
+}
+
+static PyTypeObject Bsddbtype = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "bsddb.bsddb",
+ sizeof(bsddbobject),
+ 0,
+ (destructor)bsddb_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)bsddb_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &bsddb_as_mapping, /*tp_as_mapping*/
+};
+
+static PyObject *
+bsdhashopen(PyObject *self, PyObject *args)
+{
+ char *file;
+ char *flag = NULL;
+ int flags = O_RDONLY;
+ int mode = 0666;
+ int bsize = 0;
+ int ffactor = 0;
+ int nelem = 0;
+ int cachesize = 0;
+ int hash = 0; /* XXX currently ignored */
+ int lorder = 0;
+
+ if (!PyArg_ParseTuple(args, "z|siiiiiii:hashopen",
+ &file, &flag, &mode,
+ &bsize, &ffactor, &nelem, &cachesize,
+ &hash, &lorder))
+ return NULL;
+ if (flag != NULL) {
+ /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
+ if (flag[0] == 'r')
+ flags = O_RDONLY;
+ else if (flag[0] == 'w')
+ flags = O_RDWR;
+ else if (flag[0] == 'c')
+ flags = O_RDWR|O_CREAT;
+ else if (flag[0] == 'n')
+ flags = O_RDWR|O_CREAT|O_TRUNC;
+ else {
+ PyErr_SetString(BsddbError,
+ "Flag should begin with 'r', 'w', 'c' or 'n'");
+ return NULL;
+ }
+ if (flag[1] == 'l') {
+#if defined(O_EXLOCK) && defined(O_SHLOCK)
+ if (flag[0] == 'r')
+ flags |= O_SHLOCK;
+ else
+ flags |= O_EXLOCK;
+#else
+ PyErr_SetString(BsddbError,
+ "locking not supported on this platform");
+ return NULL;
+#endif
+ }
+ }
+ return newdbhashobject(file, flags, mode,
+ bsize, ffactor, nelem, cachesize, hash, lorder);
+}
+
+static PyObject *
+bsdbtopen(PyObject *self, PyObject *args)
+{
+ char *file;
+ char *flag = NULL;
+ int flags = O_RDONLY;
+ int mode = 0666;
+ int cachesize = 0;
+ int maxkeypage = 0;
+ int minkeypage = 0;
+ int btflags = 0;
+ unsigned int psize = 0;
+ int lorder = 0;
+
+ if (!PyArg_ParseTuple(args, "z|siiiiiii:btopen",
+ &file, &flag, &mode,
+ &btflags, &cachesize, &maxkeypage, &minkeypage,
+ &psize, &lorder))
+ return NULL;
+ if (flag != NULL) {
+ /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
+ if (flag[0] == 'r')
+ flags = O_RDONLY;
+ else if (flag[0] == 'w')
+ flags = O_RDWR;
+ else if (flag[0] == 'c')
+ flags = O_RDWR|O_CREAT;
+ else if (flag[0] == 'n')
+ flags = O_RDWR|O_CREAT|O_TRUNC;
+ else {
+ PyErr_SetString(BsddbError,
+ "Flag should begin with 'r', 'w', 'c' or 'n'");
+ return NULL;
+ }
+ if (flag[1] == 'l') {
+#if defined(O_EXLOCK) && defined(O_SHLOCK)
+ if (flag[0] == 'r')
+ flags |= O_SHLOCK;
+ else
+ flags |= O_EXLOCK;
+#else
+ PyErr_SetString(BsddbError,
+ "locking not supported on this platform");
+ return NULL;
+#endif
+ }
+ }
+ return newdbbtobject(file, flags, mode,
+ btflags, cachesize, maxkeypage, minkeypage,
+ psize, lorder);
+}
+
+static PyObject *
+bsdrnopen(PyObject *self, PyObject *args)
+{
+ char *file;
+ char *flag = NULL;
+ int flags = O_RDONLY;
+ int mode = 0666;
+ int cachesize = 0;
+ int rnflags = 0;
+ unsigned int psize = 0;
+ int lorder = 0;
+ size_t reclen = 0;
+ char *bval = "";
+ char *bfname = NULL;
+
+ if (!PyArg_ParseTuple(args, "z|siiiiiiss:rnopen",
+ &file, &flag, &mode,
+ &rnflags, &cachesize, &psize, &lorder,
+ &reclen, &bval, &bfname))
+ return NULL;
+
+ if (flag != NULL) {
+ /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
+ if (flag[0] == 'r')
+ flags = O_RDONLY;
+ else if (flag[0] == 'w')
+ flags = O_RDWR;
+ else if (flag[0] == 'c')
+ flags = O_RDWR|O_CREAT;
+ else if (flag[0] == 'n')
+ flags = O_RDWR|O_CREAT|O_TRUNC;
+ else {
+ PyErr_SetString(BsddbError,
+ "Flag should begin with 'r', 'w', 'c' or 'n'");
+ return NULL;
+ }
+ if (flag[1] == 'l') {
+#if defined(O_EXLOCK) && defined(O_SHLOCK)
+ if (flag[0] == 'r')
+ flags |= O_SHLOCK;
+ else
+ flags |= O_EXLOCK;
+#else
+ PyErr_SetString(BsddbError,
+ "locking not supported on this platform");
+ return NULL;
+#endif
+ }
+ else if (flag[1] != '\0') {
+ PyErr_SetString(BsddbError,
+ "Flag char 2 should be 'l' or absent");
+ return NULL;
+ }
+ }
+ return newdbrnobject(file, flags, mode, rnflags, cachesize,
+ psize, lorder, reclen, bval[0], bfname);
+}
+
+static PyMethodDef bsddbmodule_methods[] = {
+ {"hashopen", (PyCFunction)bsdhashopen, METH_VARARGS},
+ {"btopen", (PyCFunction)bsdbtopen, METH_VARARGS},
+ {"rnopen", (PyCFunction)bsdrnopen, METH_VARARGS},
+ /* strictly for use by dbhhash!!! */
+ {"open", (PyCFunction)bsdhashopen, METH_VARARGS},
+ {0, 0},
+};
+
+PyMODINIT_FUNC
+initbsddb185(void) {
+ PyObject *m, *d;
+
+ Bsddbtype.ob_type = &PyType_Type;
+ m = Py_InitModule("bsddb185", bsddbmodule_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
+ if (BsddbError != NULL)
+ PyDict_SetItemString(d, "error", BsddbError);
+}
diff --git a/sys/src/cmd/python/Modules/bz2module.c b/sys/src/cmd/python/Modules/bz2module.c
new file mode 100644
index 000000000..9d92cf6bb
--- /dev/null
+++ b/sys/src/cmd/python/Modules/bz2module.c
@@ -0,0 +1,2230 @@
+/*
+
+python-bz2 - python bz2 library interface
+
+Copyright (c) 2002 Gustavo Niemeyer <niemeyer@conectiva.com>
+Copyright (c) 2002 Python Software Foundation; All Rights Reserved
+
+*/
+
+#include "Python.h"
+#include <stdio.h>
+#include <bzlib.h>
+#include "structmember.h"
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
+static char __author__[] =
+"The bz2 python module was written by:\n\
+\n\
+ Gustavo Niemeyer <niemeyer@conectiva.com>\n\
+";
+
+/* Our very own off_t-like type, 64-bit if possible */
+/* copied from Objects/fileobject.c */
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+typedef off_t Py_off_t;
+#elif SIZEOF_OFF_T >= 8
+typedef off_t Py_off_t;
+#elif SIZEOF_FPOS_T >= 8
+typedef fpos_t Py_off_t;
+#else
+#error "Large file support, but neither off_t nor fpos_t is large enough."
+#endif
+
+#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
+
+#define MODE_CLOSED 0
+#define MODE_READ 1
+#define MODE_READ_EOF 2
+#define MODE_WRITE 3
+
+#define BZ2FileObject_Check(v) ((v)->ob_type == &BZ2File_Type)
+
+
+#ifdef BZ_CONFIG_ERROR
+
+#if SIZEOF_LONG >= 8
+#define BZS_TOTAL_OUT(bzs) \
+ (((long)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
+#elif SIZEOF_LONG_LONG >= 8
+#define BZS_TOTAL_OUT(bzs) \
+ (((PY_LONG_LONG)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
+#else
+#define BZS_TOTAL_OUT(bzs) \
+ bzs->total_out_lo32
+#endif
+
+#else /* ! BZ_CONFIG_ERROR */
+
+#define BZ2_bzRead bzRead
+#define BZ2_bzReadOpen bzReadOpen
+#define BZ2_bzReadClose bzReadClose
+#define BZ2_bzWrite bzWrite
+#define BZ2_bzWriteOpen bzWriteOpen
+#define BZ2_bzWriteClose bzWriteClose
+#define BZ2_bzCompress bzCompress
+#define BZ2_bzCompressInit bzCompressInit
+#define BZ2_bzCompressEnd bzCompressEnd
+#define BZ2_bzDecompress bzDecompress
+#define BZ2_bzDecompressInit bzDecompressInit
+#define BZ2_bzDecompressEnd bzDecompressEnd
+
+#define BZS_TOTAL_OUT(bzs) bzs->total_out
+
+#endif /* ! BZ_CONFIG_ERROR */
+
+
+#ifdef WITH_THREAD
+#define ACQUIRE_LOCK(obj) PyThread_acquire_lock(obj->lock, 1)
+#define RELEASE_LOCK(obj) PyThread_release_lock(obj->lock)
+#else
+#define ACQUIRE_LOCK(obj)
+#define RELEASE_LOCK(obj)
+#endif
+
+/* Bits in f_newlinetypes */
+#define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
+#define NEWLINE_CR 1 /* \r newline seen */
+#define NEWLINE_LF 2 /* \n newline seen */
+#define NEWLINE_CRLF 4 /* \r\n newline seen */
+
+/* ===================================================================== */
+/* Structure definitions. */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *file;
+
+ char* f_buf; /* Allocated readahead buffer */
+ char* f_bufend; /* Points after last occupied position */
+ char* f_bufptr; /* Current buffer position */
+
+ int f_softspace; /* Flag used by 'print' command */
+
+ int f_univ_newline; /* Handle any newline convention */
+ int f_newlinetypes; /* Types of newlines seen */
+ int f_skipnextlf; /* Skip next \n */
+
+ BZFILE *fp;
+ int mode;
+ Py_off_t pos;
+ Py_off_t size;
+#ifdef WITH_THREAD
+ PyThread_type_lock lock;
+#endif
+} BZ2FileObject;
+
+typedef struct {
+ PyObject_HEAD
+ bz_stream bzs;
+ int running;
+#ifdef WITH_THREAD
+ PyThread_type_lock lock;
+#endif
+} BZ2CompObject;
+
+typedef struct {
+ PyObject_HEAD
+ bz_stream bzs;
+ int running;
+ PyObject *unused_data;
+#ifdef WITH_THREAD
+ PyThread_type_lock lock;
+#endif
+} BZ2DecompObject;
+
+/* ===================================================================== */
+/* Utility functions. */
+
+static int
+Util_CatchBZ2Error(int bzerror)
+{
+ int ret = 0;
+ switch(bzerror) {
+ case BZ_OK:
+ case BZ_STREAM_END:
+ break;
+
+#ifdef BZ_CONFIG_ERROR
+ case BZ_CONFIG_ERROR:
+ PyErr_SetString(PyExc_SystemError,
+ "the bz2 library was not compiled "
+ "correctly");
+ ret = 1;
+ break;
+#endif
+
+ case BZ_PARAM_ERROR:
+ PyErr_SetString(PyExc_ValueError,
+ "the bz2 library has received wrong "
+ "parameters");
+ ret = 1;
+ break;
+
+ case BZ_MEM_ERROR:
+ PyErr_NoMemory();
+ ret = 1;
+ break;
+
+ case BZ_DATA_ERROR:
+ case BZ_DATA_ERROR_MAGIC:
+ PyErr_SetString(PyExc_IOError, "invalid data stream");
+ ret = 1;
+ break;
+
+ case BZ_IO_ERROR:
+ PyErr_SetString(PyExc_IOError, "unknown IO error");
+ ret = 1;
+ break;
+
+ case BZ_UNEXPECTED_EOF:
+ PyErr_SetString(PyExc_EOFError,
+ "compressed file ended before the "
+ "logical end-of-stream was detected");
+ ret = 1;
+ break;
+
+ case BZ_SEQUENCE_ERROR:
+ PyErr_SetString(PyExc_RuntimeError,
+ "wrong sequence of bz2 library "
+ "commands used");
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+
+#if BUFSIZ < 8192
+#define SMALLCHUNK 8192
+#else
+#define SMALLCHUNK BUFSIZ
+#endif
+
+#if SIZEOF_INT < 4
+#define BIGCHUNK (512 * 32)
+#else
+#define BIGCHUNK (512 * 1024)
+#endif
+
+/* This is a hacked version of Python's fileobject.c:new_buffersize(). */
+static size_t
+Util_NewBufferSize(size_t currentsize)
+{
+ if (currentsize > SMALLCHUNK) {
+ /* Keep doubling until we reach BIGCHUNK;
+ then keep adding BIGCHUNK. */
+ if (currentsize <= BIGCHUNK)
+ return currentsize + currentsize;
+ else
+ return currentsize + BIGCHUNK;
+ }
+ return currentsize + SMALLCHUNK;
+}
+
+/* This is a hacked version of Python's fileobject.c:get_line(). */
+static PyObject *
+Util_GetLine(BZ2FileObject *f, int n)
+{
+ char c;
+ char *buf, *end;
+ size_t total_v_size; /* total # of slots in buffer */
+ size_t used_v_size; /* # used slots in buffer */
+ size_t increment; /* amount to increment the buffer */
+ PyObject *v;
+ int bzerror;
+ int newlinetypes = f->f_newlinetypes;
+ int skipnextlf = f->f_skipnextlf;
+ int univ_newline = f->f_univ_newline;
+
+ total_v_size = n > 0 ? n : 100;
+ v = PyString_FromStringAndSize((char *)NULL, total_v_size);
+ if (v == NULL)
+ return NULL;
+
+ buf = BUF(v);
+ end = buf + total_v_size;
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ if (univ_newline) {
+ while (1) {
+ BZ2_bzRead(&bzerror, f->fp, &c, 1);
+ f->pos++;
+ if (bzerror != BZ_OK || buf == end)
+ break;
+ if (skipnextlf) {
+ skipnextlf = 0;
+ if (c == '\n') {
+ /* Seeing a \n here with
+ * skipnextlf true means we
+ * saw a \r before.
+ */
+ newlinetypes |= NEWLINE_CRLF;
+ BZ2_bzRead(&bzerror, f->fp,
+ &c, 1);
+ if (bzerror != BZ_OK)
+ break;
+ } else {
+ newlinetypes |= NEWLINE_CR;
+ }
+ }
+ if (c == '\r') {
+ skipnextlf = 1;
+ c = '\n';
+ } else if ( c == '\n')
+ newlinetypes |= NEWLINE_LF;
+ *buf++ = c;
+ if (c == '\n') break;
+ }
+ if (bzerror == BZ_STREAM_END && skipnextlf)
+ newlinetypes |= NEWLINE_CR;
+ } else /* If not universal newlines use the normal loop */
+ do {
+ BZ2_bzRead(&bzerror, f->fp, &c, 1);
+ f->pos++;
+ *buf++ = c;
+ } while (bzerror == BZ_OK && c != '\n' && buf != end);
+ Py_END_ALLOW_THREADS
+ f->f_newlinetypes = newlinetypes;
+ f->f_skipnextlf = skipnextlf;
+ if (bzerror == BZ_STREAM_END) {
+ f->size = f->pos;
+ f->mode = MODE_READ_EOF;
+ break;
+ } else if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ Py_DECREF(v);
+ return NULL;
+ }
+ if (c == '\n')
+ break;
+ /* Must be because buf == end */
+ if (n > 0)
+ break;
+ used_v_size = total_v_size;
+ increment = total_v_size >> 2; /* mild exponential growth */
+ total_v_size += increment;
+ if (total_v_size > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "line is longer than a Python string can hold");
+ Py_DECREF(v);
+ return NULL;
+ }
+ if (_PyString_Resize(&v, total_v_size) < 0)
+ return NULL;
+ buf = BUF(v) + used_v_size;
+ end = BUF(v) + total_v_size;
+ }
+
+ used_v_size = buf - BUF(v);
+ if (used_v_size != total_v_size)
+ _PyString_Resize(&v, used_v_size);
+ return v;
+}
+
+/* This is a hacked version of Python's
+ * fileobject.c:Py_UniversalNewlineFread(). */
+size_t
+Util_UnivNewlineRead(int *bzerror, BZFILE *stream,
+ char* buf, size_t n, BZ2FileObject *f)
+{
+ char *dst = buf;
+ int newlinetypes, skipnextlf;
+
+ assert(buf != NULL);
+ assert(stream != NULL);
+
+ if (!f->f_univ_newline)
+ return BZ2_bzRead(bzerror, stream, buf, n);
+
+ newlinetypes = f->f_newlinetypes;
+ skipnextlf = f->f_skipnextlf;
+
+ /* Invariant: n is the number of bytes remaining to be filled
+ * in the buffer.
+ */
+ while (n) {
+ size_t nread;
+ int shortread;
+ char *src = dst;
+
+ nread = BZ2_bzRead(bzerror, stream, dst, n);
+ assert(nread <= n);
+ n -= nread; /* assuming 1 byte out for each in; will adjust */
+ shortread = n != 0; /* true iff EOF or error */
+ while (nread--) {
+ char c = *src++;
+ if (c == '\r') {
+ /* Save as LF and set flag to skip next LF. */
+ *dst++ = '\n';
+ skipnextlf = 1;
+ }
+ else if (skipnextlf && c == '\n') {
+ /* Skip LF, and remember we saw CR LF. */
+ skipnextlf = 0;
+ newlinetypes |= NEWLINE_CRLF;
+ ++n;
+ }
+ else {
+ /* Normal char to be stored in buffer. Also
+ * update the newlinetypes flag if either this
+ * is an LF or the previous char was a CR.
+ */
+ if (c == '\n')
+ newlinetypes |= NEWLINE_LF;
+ else if (skipnextlf)
+ newlinetypes |= NEWLINE_CR;
+ *dst++ = c;
+ skipnextlf = 0;
+ }
+ }
+ if (shortread) {
+ /* If this is EOF, update type flags. */
+ if (skipnextlf && *bzerror == BZ_STREAM_END)
+ newlinetypes |= NEWLINE_CR;
+ break;
+ }
+ }
+ f->f_newlinetypes = newlinetypes;
+ f->f_skipnextlf = skipnextlf;
+ return dst - buf;
+}
+
+/* This is a hacked version of Python's fileobject.c:drop_readahead(). */
+static void
+Util_DropReadAhead(BZ2FileObject *f)
+{
+ if (f->f_buf != NULL) {
+ PyMem_Free(f->f_buf);
+ f->f_buf = NULL;
+ }
+}
+
+/* This is a hacked version of Python's fileobject.c:readahead(). */
+static int
+Util_ReadAhead(BZ2FileObject *f, int bufsize)
+{
+ int chunksize;
+ int bzerror;
+
+ if (f->f_buf != NULL) {
+ if((f->f_bufend - f->f_bufptr) >= 1)
+ return 0;
+ else
+ Util_DropReadAhead(f);
+ }
+ if (f->mode == MODE_READ_EOF) {
+ f->f_bufptr = f->f_buf;
+ f->f_bufend = f->f_buf;
+ return 0;
+ }
+ if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
+ return -1;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ chunksize = Util_UnivNewlineRead(&bzerror, f->fp, f->f_buf,
+ bufsize, f);
+ Py_END_ALLOW_THREADS
+ f->pos += chunksize;
+ if (bzerror == BZ_STREAM_END) {
+ f->size = f->pos;
+ f->mode = MODE_READ_EOF;
+ } else if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ Util_DropReadAhead(f);
+ return -1;
+ }
+ f->f_bufptr = f->f_buf;
+ f->f_bufend = f->f_buf + chunksize;
+ return 0;
+}
+
+/* This is a hacked version of Python's
+ * fileobject.c:readahead_get_line_skip(). */
+static PyStringObject *
+Util_ReadAheadGetLineSkip(BZ2FileObject *f, int skip, int bufsize)
+{
+ PyStringObject* s;
+ char *bufptr;
+ char *buf;
+ int len;
+
+ if (f->f_buf == NULL)
+ if (Util_ReadAhead(f, bufsize) < 0)
+ return NULL;
+
+ len = f->f_bufend - f->f_bufptr;
+ if (len == 0)
+ return (PyStringObject *)
+ PyString_FromStringAndSize(NULL, skip);
+ bufptr = memchr(f->f_bufptr, '\n', len);
+ if (bufptr != NULL) {
+ bufptr++; /* Count the '\n' */
+ len = bufptr - f->f_bufptr;
+ s = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, skip+len);
+ if (s == NULL)
+ return NULL;
+ memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
+ f->f_bufptr = bufptr;
+ if (bufptr == f->f_bufend)
+ Util_DropReadAhead(f);
+ } else {
+ bufptr = f->f_bufptr;
+ buf = f->f_buf;
+ f->f_buf = NULL; /* Force new readahead buffer */
+ s = Util_ReadAheadGetLineSkip(f, skip+len,
+ bufsize + (bufsize>>2));
+ if (s == NULL) {
+ PyMem_Free(buf);
+ return NULL;
+ }
+ memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
+ PyMem_Free(buf);
+ }
+ return s;
+}
+
+/* ===================================================================== */
+/* Methods of BZ2File. */
+
+PyDoc_STRVAR(BZ2File_read__doc__,
+"read([size]) -> string\n\
+\n\
+Read at most size uncompressed bytes, returned as a string. If the size\n\
+argument is negative or omitted, read until EOF is reached.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_read(). */
+static PyObject *
+BZ2File_read(BZ2FileObject *self, PyObject *args)
+{
+ long bytesrequested = -1;
+ size_t bytesread, buffersize, chunksize;
+ int bzerror;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
+ return NULL;
+
+ ACQUIRE_LOCK(self);
+ switch (self->mode) {
+ case MODE_READ:
+ break;
+ case MODE_READ_EOF:
+ ret = PyString_FromString("");
+ goto cleanup;
+ case MODE_CLOSED:
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto cleanup;
+ default:
+ PyErr_SetString(PyExc_IOError,
+ "file is not ready for reading");
+ goto cleanup;
+ }
+
+ if (bytesrequested < 0)
+ buffersize = Util_NewBufferSize((size_t)0);
+ else
+ buffersize = bytesrequested;
+ if (buffersize > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "requested number of bytes is "
+ "more than a Python string can hold");
+ goto cleanup;
+ }
+ ret = PyString_FromStringAndSize((char *)NULL, buffersize);
+ if (ret == NULL)
+ goto cleanup;
+ bytesread = 0;
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
+ BUF(ret)+bytesread,
+ buffersize-bytesread,
+ self);
+ self->pos += chunksize;
+ Py_END_ALLOW_THREADS
+ bytesread += chunksize;
+ if (bzerror == BZ_STREAM_END) {
+ self->size = self->pos;
+ self->mode = MODE_READ_EOF;
+ break;
+ } else if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ Py_DECREF(ret);
+ ret = NULL;
+ goto cleanup;
+ }
+ if (bytesrequested < 0) {
+ buffersize = Util_NewBufferSize(buffersize);
+ if (_PyString_Resize(&ret, buffersize) < 0)
+ goto cleanup;
+ } else {
+ break;
+ }
+ }
+ if (bytesread != buffersize)
+ _PyString_Resize(&ret, bytesread);
+
+cleanup:
+ RELEASE_LOCK(self);
+ return ret;
+}
+
+PyDoc_STRVAR(BZ2File_readline__doc__,
+"readline([size]) -> string\n\
+\n\
+Return the next line from the file, as a string, retaining newline.\n\
+A non-negative size argument will limit the maximum number of bytes to\n\
+return (an incomplete line may be returned then). Return an empty\n\
+string at EOF.\n\
+");
+
+static PyObject *
+BZ2File_readline(BZ2FileObject *self, PyObject *args)
+{
+ PyObject *ret = NULL;
+ int sizehint = -1;
+
+ if (!PyArg_ParseTuple(args, "|i:readline", &sizehint))
+ return NULL;
+
+ ACQUIRE_LOCK(self);
+ switch (self->mode) {
+ case MODE_READ:
+ break;
+ case MODE_READ_EOF:
+ ret = PyString_FromString("");
+ goto cleanup;
+ case MODE_CLOSED:
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto cleanup;
+ default:
+ PyErr_SetString(PyExc_IOError,
+ "file is not ready for reading");
+ goto cleanup;
+ }
+
+ if (sizehint == 0)
+ ret = PyString_FromString("");
+ else
+ ret = Util_GetLine(self, (sizehint < 0) ? 0 : sizehint);
+
+cleanup:
+ RELEASE_LOCK(self);
+ return ret;
+}
+
+PyDoc_STRVAR(BZ2File_readlines__doc__,
+"readlines([size]) -> list\n\
+\n\
+Call readline() repeatedly and return a list of lines read.\n\
+The optional size argument, if given, is an approximate bound on the\n\
+total number of bytes in the lines returned.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_readlines(). */
+static PyObject *
+BZ2File_readlines(BZ2FileObject *self, PyObject *args)
+{
+ long sizehint = 0;
+ PyObject *list = NULL;
+ PyObject *line;
+ char small_buffer[SMALLCHUNK];
+ char *buffer = small_buffer;
+ size_t buffersize = SMALLCHUNK;
+ PyObject *big_buffer = NULL;
+ size_t nfilled = 0;
+ size_t nread;
+ size_t totalread = 0;
+ char *p, *q, *end;
+ int err;
+ int shortread = 0;
+ int bzerror;
+
+ if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
+ return NULL;
+
+ ACQUIRE_LOCK(self);
+ switch (self->mode) {
+ case MODE_READ:
+ break;
+ case MODE_READ_EOF:
+ list = PyList_New(0);
+ goto cleanup;
+ case MODE_CLOSED:
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto cleanup;
+ default:
+ PyErr_SetString(PyExc_IOError,
+ "file is not ready for reading");
+ goto cleanup;
+ }
+
+ if ((list = PyList_New(0)) == NULL)
+ goto cleanup;
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ nread = Util_UnivNewlineRead(&bzerror, self->fp,
+ buffer+nfilled,
+ buffersize-nfilled, self);
+ self->pos += nread;
+ Py_END_ALLOW_THREADS
+ if (bzerror == BZ_STREAM_END) {
+ self->size = self->pos;
+ self->mode = MODE_READ_EOF;
+ if (nread == 0) {
+ sizehint = 0;
+ break;
+ }
+ shortread = 1;
+ } else if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ error:
+ Py_DECREF(list);
+ list = NULL;
+ goto cleanup;
+ }
+ totalread += nread;
+ p = memchr(buffer+nfilled, '\n', nread);
+ if (!shortread && p == NULL) {
+ /* Need a larger buffer to fit this line */
+ nfilled += nread;
+ buffersize *= 2;
+ if (buffersize > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "line is longer than a Python string can hold");
+ goto error;
+ }
+ if (big_buffer == NULL) {
+ /* Create the big buffer */
+ big_buffer = PyString_FromStringAndSize(
+ NULL, buffersize);
+ if (big_buffer == NULL)
+ goto error;
+ buffer = PyString_AS_STRING(big_buffer);
+ memcpy(buffer, small_buffer, nfilled);
+ }
+ else {
+ /* Grow the big buffer */
+ _PyString_Resize(&big_buffer, buffersize);
+ buffer = PyString_AS_STRING(big_buffer);
+ }
+ continue;
+ }
+ end = buffer+nfilled+nread;
+ q = buffer;
+ while (p != NULL) {
+ /* Process complete lines */
+ p++;
+ line = PyString_FromStringAndSize(q, p-q);
+ if (line == NULL)
+ goto error;
+ err = PyList_Append(list, line);
+ Py_DECREF(line);
+ if (err != 0)
+ goto error;
+ q = p;
+ p = memchr(q, '\n', end-q);
+ }
+ /* Move the remaining incomplete line to the start */
+ nfilled = end-q;
+ memmove(buffer, q, nfilled);
+ if (sizehint > 0)
+ if (totalread >= (size_t)sizehint)
+ break;
+ if (shortread) {
+ sizehint = 0;
+ break;
+ }
+ }
+ if (nfilled != 0) {
+ /* Partial last line */
+ line = PyString_FromStringAndSize(buffer, nfilled);
+ if (line == NULL)
+ goto error;
+ if (sizehint > 0) {
+ /* Need to complete the last line */
+ PyObject *rest = Util_GetLine(self, 0);
+ if (rest == NULL) {
+ Py_DECREF(line);
+ goto error;
+ }
+ PyString_Concat(&line, rest);
+ Py_DECREF(rest);
+ if (line == NULL)
+ goto error;
+ }
+ err = PyList_Append(list, line);
+ Py_DECREF(line);
+ if (err != 0)
+ goto error;
+ }
+
+ cleanup:
+ RELEASE_LOCK(self);
+ if (big_buffer) {
+ Py_DECREF(big_buffer);
+ }
+ return list;
+}
+
+PyDoc_STRVAR(BZ2File_xreadlines__doc__,
+"xreadlines() -> self\n\
+\n\
+For backward compatibility. BZ2File objects now include the performance\n\
+optimizations previously implemented in the xreadlines module.\n\
+");
+
+PyDoc_STRVAR(BZ2File_write__doc__,
+"write(data) -> None\n\
+\n\
+Write the 'data' string to file. Note that due to buffering, close() may\n\
+be needed before the file on disk reflects the data written.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_write(). */
+static PyObject *
+BZ2File_write(BZ2FileObject *self, PyObject *args)
+{
+ PyObject *ret = NULL;
+ char *buf;
+ int len;
+ int bzerror;
+
+ if (!PyArg_ParseTuple(args, "s#:write", &buf, &len))
+ return NULL;
+
+ ACQUIRE_LOCK(self);
+ switch (self->mode) {
+ case MODE_WRITE:
+ break;
+
+ case MODE_CLOSED:
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto cleanup;
+
+ default:
+ PyErr_SetString(PyExc_IOError,
+ "file is not ready for writing");
+ goto cleanup;
+ }
+
+ self->f_softspace = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+ BZ2_bzWrite (&bzerror, self->fp, buf, len);
+ self->pos += len;
+ Py_END_ALLOW_THREADS
+
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto cleanup;
+ }
+
+ Py_INCREF(Py_None);
+ ret = Py_None;
+
+cleanup:
+ RELEASE_LOCK(self);
+ return ret;
+}
+
+PyDoc_STRVAR(BZ2File_writelines__doc__,
+"writelines(sequence_of_strings) -> None\n\
+\n\
+Write the sequence of strings to the file. Note that newlines are not\n\
+added. The sequence can be any iterable object producing strings. This is\n\
+equivalent to calling write() for each string.\n\
+");
+
+/* This is a hacked version of Python's fileobject.c:file_writelines(). */
+static PyObject *
+BZ2File_writelines(BZ2FileObject *self, PyObject *seq)
+{
+#define CHUNKSIZE 1000
+ PyObject *list = NULL;
+ PyObject *iter = NULL;
+ PyObject *ret = NULL;
+ PyObject *line;
+ int i, j, index, len, islist;
+ int bzerror;
+
+ ACQUIRE_LOCK(self);
+ switch (self->mode) {
+ case MODE_WRITE:
+ break;
+
+ case MODE_CLOSED:
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto error;
+
+ default:
+ PyErr_SetString(PyExc_IOError,
+ "file is not ready for writing");
+ goto error;
+ }
+
+ islist = PyList_Check(seq);
+ if (!islist) {
+ iter = PyObject_GetIter(seq);
+ if (iter == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "writelines() requires an iterable argument");
+ goto error;
+ }
+ list = PyList_New(CHUNKSIZE);
+ if (list == NULL)
+ goto error;
+ }
+
+ /* Strategy: slurp CHUNKSIZE lines into a private list,
+ checking that they are all strings, then write that list
+ without holding the interpreter lock, then come back for more. */
+ for (index = 0; ; index += CHUNKSIZE) {
+ if (islist) {
+ Py_XDECREF(list);
+ list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
+ if (list == NULL)
+ goto error;
+ j = PyList_GET_SIZE(list);
+ }
+ else {
+ for (j = 0; j < CHUNKSIZE; j++) {
+ line = PyIter_Next(iter);
+ if (line == NULL) {
+ if (PyErr_Occurred())
+ goto error;
+ break;
+ }
+ PyList_SetItem(list, j, line);
+ }
+ }
+ if (j == 0)
+ break;
+
+ /* Check that all entries are indeed strings. If not,
+ apply the same rules as for file.write() and
+ convert the rets to strings. This is slow, but
+ seems to be the only way since all conversion APIs
+ could potentially execute Python code. */
+ for (i = 0; i < j; i++) {
+ PyObject *v = PyList_GET_ITEM(list, i);
+ if (!PyString_Check(v)) {
+ const char *buffer;
+ Py_ssize_t len;
+ if (PyObject_AsCharBuffer(v, &buffer, &len)) {
+ PyErr_SetString(PyExc_TypeError,
+ "writelines() "
+ "argument must be "
+ "a sequence of "
+ "strings");
+ goto error;
+ }
+ line = PyString_FromStringAndSize(buffer,
+ len);
+ if (line == NULL)
+ goto error;
+ Py_DECREF(v);
+ PyList_SET_ITEM(list, i, line);
+ }
+ }
+
+ self->f_softspace = 0;
+
+ /* Since we are releasing the global lock, the
+ following code may *not* execute Python code. */
+ Py_BEGIN_ALLOW_THREADS
+ for (i = 0; i < j; i++) {
+ line = PyList_GET_ITEM(list, i);
+ len = PyString_GET_SIZE(line);
+ BZ2_bzWrite (&bzerror, self->fp,
+ PyString_AS_STRING(line), len);
+ if (bzerror != BZ_OK) {
+ Py_BLOCK_THREADS
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+ }
+ Py_END_ALLOW_THREADS
+
+ if (j < CHUNKSIZE)
+ break;
+ }
+
+ Py_INCREF(Py_None);
+ ret = Py_None;
+
+ error:
+ RELEASE_LOCK(self);
+ Py_XDECREF(list);
+ Py_XDECREF(iter);
+ return ret;
+#undef CHUNKSIZE
+}
+
+PyDoc_STRVAR(BZ2File_seek__doc__,
+"seek(offset [, whence]) -> None\n\
+\n\
+Move to new file position. Argument offset is a byte count. Optional\n\
+argument whence defaults to 0 (offset from start of file, offset\n\
+should be >= 0); other values are 1 (move relative to current position,\n\
+positive or negative), and 2 (move relative to end of file, usually\n\
+negative, although many platforms allow seeking beyond the end of a file).\n\
+\n\
+Note that seeking of bz2 files is emulated, and depending on the parameters\n\
+the operation may be extremely slow.\n\
+");
+
+static PyObject *
+BZ2File_seek(BZ2FileObject *self, PyObject *args)
+{
+ int where = 0;
+ PyObject *offobj;
+ Py_off_t offset;
+ char small_buffer[SMALLCHUNK];
+ char *buffer = small_buffer;
+ size_t buffersize = SMALLCHUNK;
+ Py_off_t bytesread = 0;
+ size_t readsize;
+ int chunksize;
+ int bzerror;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &where))
+ return NULL;
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ offset = PyInt_AsLong(offobj);
+#else
+ offset = PyLong_Check(offobj) ?
+ PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ ACQUIRE_LOCK(self);
+ Util_DropReadAhead(self);
+ switch (self->mode) {
+ case MODE_READ:
+ case MODE_READ_EOF:
+ break;
+
+ case MODE_CLOSED:
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto cleanup;
+
+ default:
+ PyErr_SetString(PyExc_IOError,
+ "seek works only while reading");
+ goto cleanup;
+ }
+
+ if (where == 2) {
+ if (self->size == -1) {
+ assert(self->mode != MODE_READ_EOF);
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ chunksize = Util_UnivNewlineRead(
+ &bzerror, self->fp,
+ buffer, buffersize,
+ self);
+ self->pos += chunksize;
+ Py_END_ALLOW_THREADS
+
+ bytesread += chunksize;
+ if (bzerror == BZ_STREAM_END) {
+ break;
+ } else if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto cleanup;
+ }
+ }
+ self->mode = MODE_READ_EOF;
+ self->size = self->pos;
+ bytesread = 0;
+ }
+ offset = self->size + offset;
+ } else if (where == 1) {
+ offset = self->pos + offset;
+ }
+
+ /* Before getting here, offset must be the absolute position the file
+ * pointer should be set to. */
+
+ if (offset >= self->pos) {
+ /* we can move forward */
+ offset -= self->pos;
+ } else {
+ /* we cannot move back, so rewind the stream */
+ BZ2_bzReadClose(&bzerror, self->fp);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto cleanup;
+ }
+ ret = PyObject_CallMethod(self->file, "seek", "(i)", 0);
+ if (!ret)
+ goto cleanup;
+ Py_DECREF(ret);
+ ret = NULL;
+ self->pos = 0;
+ self->fp = BZ2_bzReadOpen(&bzerror, PyFile_AsFile(self->file),
+ 0, 0, NULL, 0);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto cleanup;
+ }
+ self->mode = MODE_READ;
+ }
+
+ if (offset <= 0 || self->mode == MODE_READ_EOF)
+ goto exit;
+
+ /* Before getting here, offset must be set to the number of bytes
+ * to walk forward. */
+ for (;;) {
+ if (offset-bytesread > buffersize)
+ readsize = buffersize;
+ else
+ /* offset might be wider that readsize, but the result
+ * of the subtraction is bound by buffersize (see the
+ * condition above). buffersize is 8192. */
+ readsize = (size_t)(offset-bytesread);
+ Py_BEGIN_ALLOW_THREADS
+ chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
+ buffer, readsize, self);
+ self->pos += chunksize;
+ Py_END_ALLOW_THREADS
+ bytesread += chunksize;
+ if (bzerror == BZ_STREAM_END) {
+ self->size = self->pos;
+ self->mode = MODE_READ_EOF;
+ break;
+ } else if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto cleanup;
+ }
+ if (bytesread == offset)
+ break;
+ }
+
+exit:
+ Py_INCREF(Py_None);
+ ret = Py_None;
+
+cleanup:
+ RELEASE_LOCK(self);
+ return ret;
+}
+
+PyDoc_STRVAR(BZ2File_tell__doc__,
+"tell() -> int\n\
+\n\
+Return the current file position, an integer (may be a long integer).\n\
+");
+
+static PyObject *
+BZ2File_tell(BZ2FileObject *self, PyObject *args)
+{
+ PyObject *ret = NULL;
+
+ if (self->mode == MODE_CLOSED) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto cleanup;
+ }
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ ret = PyInt_FromLong(self->pos);
+#else
+ ret = PyLong_FromLongLong(self->pos);
+#endif
+
+cleanup:
+ return ret;
+}
+
+PyDoc_STRVAR(BZ2File_close__doc__,
+"close() -> None or (perhaps) an integer\n\
+\n\
+Close the file. Sets data attribute .closed to true. A closed file\n\
+cannot be used for further I/O operations. close() may be called more\n\
+than once without error.\n\
+");
+
+static PyObject *
+BZ2File_close(BZ2FileObject *self)
+{
+ PyObject *ret = NULL;
+ int bzerror = BZ_OK;
+
+ ACQUIRE_LOCK(self);
+ switch (self->mode) {
+ case MODE_READ:
+ case MODE_READ_EOF:
+ BZ2_bzReadClose(&bzerror, self->fp);
+ break;
+ case MODE_WRITE:
+ BZ2_bzWriteClose(&bzerror, self->fp,
+ 0, NULL, NULL);
+ break;
+ }
+ self->mode = MODE_CLOSED;
+ ret = PyObject_CallMethod(self->file, "close", NULL);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ Py_XDECREF(ret);
+ ret = NULL;
+ }
+
+ RELEASE_LOCK(self);
+ return ret;
+}
+
+static PyObject *BZ2File_getiter(BZ2FileObject *self);
+
+static PyMethodDef BZ2File_methods[] = {
+ {"read", (PyCFunction)BZ2File_read, METH_VARARGS, BZ2File_read__doc__},
+ {"readline", (PyCFunction)BZ2File_readline, METH_VARARGS, BZ2File_readline__doc__},
+ {"readlines", (PyCFunction)BZ2File_readlines, METH_VARARGS, BZ2File_readlines__doc__},
+ {"xreadlines", (PyCFunction)BZ2File_getiter, METH_VARARGS, BZ2File_xreadlines__doc__},
+ {"write", (PyCFunction)BZ2File_write, METH_VARARGS, BZ2File_write__doc__},
+ {"writelines", (PyCFunction)BZ2File_writelines, METH_O, BZ2File_writelines__doc__},
+ {"seek", (PyCFunction)BZ2File_seek, METH_VARARGS, BZ2File_seek__doc__},
+ {"tell", (PyCFunction)BZ2File_tell, METH_NOARGS, BZ2File_tell__doc__},
+ {"close", (PyCFunction)BZ2File_close, METH_NOARGS, BZ2File_close__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* ===================================================================== */
+/* Getters and setters of BZ2File. */
+
+/* This is a hacked version of Python's fileobject.c:get_newlines(). */
+static PyObject *
+BZ2File_get_newlines(BZ2FileObject *self, void *closure)
+{
+ switch (self->f_newlinetypes) {
+ case NEWLINE_UNKNOWN:
+ Py_INCREF(Py_None);
+ return Py_None;
+ case NEWLINE_CR:
+ return PyString_FromString("\r");
+ case NEWLINE_LF:
+ return PyString_FromString("\n");
+ case NEWLINE_CR|NEWLINE_LF:
+ return Py_BuildValue("(ss)", "\r", "\n");
+ case NEWLINE_CRLF:
+ return PyString_FromString("\r\n");
+ case NEWLINE_CR|NEWLINE_CRLF:
+ return Py_BuildValue("(ss)", "\r", "\r\n");
+ case NEWLINE_LF|NEWLINE_CRLF:
+ return Py_BuildValue("(ss)", "\n", "\r\n");
+ case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
+ return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "Unknown newlines value 0x%x\n",
+ self->f_newlinetypes);
+ return NULL;
+ }
+}
+
+static PyObject *
+BZ2File_get_closed(BZ2FileObject *self, void *closure)
+{
+ return PyInt_FromLong(self->mode == MODE_CLOSED);
+}
+
+static PyObject *
+BZ2File_get_mode(BZ2FileObject *self, void *closure)
+{
+ return PyObject_GetAttrString(self->file, "mode");
+}
+
+static PyObject *
+BZ2File_get_name(BZ2FileObject *self, void *closure)
+{
+ return PyObject_GetAttrString(self->file, "name");
+}
+
+static PyGetSetDef BZ2File_getset[] = {
+ {"closed", (getter)BZ2File_get_closed, NULL,
+ "True if the file is closed"},
+ {"newlines", (getter)BZ2File_get_newlines, NULL,
+ "end-of-line convention used in this file"},
+ {"mode", (getter)BZ2File_get_mode, NULL,
+ "file mode ('r', 'w', or 'U')"},
+ {"name", (getter)BZ2File_get_name, NULL,
+ "file name"},
+ {NULL} /* Sentinel */
+};
+
+
+/* ===================================================================== */
+/* Members of BZ2File_Type. */
+
+#undef OFF
+#define OFF(x) offsetof(BZ2FileObject, x)
+
+static PyMemberDef BZ2File_members[] = {
+ {"softspace", T_INT, OFF(f_softspace), 0,
+ "flag indicating that a space needs to be printed; used by print"},
+ {NULL} /* Sentinel */
+};
+
+/* ===================================================================== */
+/* Slot definitions for BZ2File_Type. */
+
+static int
+BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"filename", "mode", "buffering",
+ "compresslevel", 0};
+ PyObject *name;
+ char *mode = "r";
+ int buffering = -1;
+ int compresslevel = 9;
+ int bzerror;
+ int mode_char = 0;
+
+ self->size = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sii:BZ2File",
+ kwlist, &name, &mode, &buffering,
+ &compresslevel))
+ return -1;
+
+ if (compresslevel < 1 || compresslevel > 9) {
+ PyErr_SetString(PyExc_ValueError,
+ "compresslevel must be between 1 and 9");
+ return -1;
+ }
+
+ for (;;) {
+ int error = 0;
+ switch (*mode) {
+ case 'r':
+ case 'w':
+ if (mode_char)
+ error = 1;
+ mode_char = *mode;
+ break;
+
+ case 'b':
+ break;
+
+ case 'U':
+#ifdef __VMS
+ self->f_univ_newline = 0;
+#else
+ self->f_univ_newline = 1;
+#endif
+ break;
+
+ default:
+ error = 1;
+ break;
+ }
+ if (error) {
+ PyErr_Format(PyExc_ValueError,
+ "invalid mode char %c", *mode);
+ return -1;
+ }
+ mode++;
+ if (*mode == '\0')
+ break;
+ }
+
+ if (mode_char == 0) {
+ mode_char = 'r';
+ }
+
+ mode = (mode_char == 'r') ? "rb" : "wb";
+
+ self->file = PyObject_CallFunction((PyObject*)&PyFile_Type, "(Osi)",
+ name, mode, buffering);
+ if (self->file == NULL)
+ return -1;
+
+ /* From now on, we have stuff to dealloc, so jump to error label
+ * instead of returning */
+
+#ifdef WITH_THREAD
+ self->lock = PyThread_allocate_lock();
+ if (!self->lock) {
+ PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
+ goto error;
+ }
+#endif
+
+ if (mode_char == 'r')
+ self->fp = BZ2_bzReadOpen(&bzerror,
+ PyFile_AsFile(self->file),
+ 0, 0, NULL, 0);
+ else
+ self->fp = BZ2_bzWriteOpen(&bzerror,
+ PyFile_AsFile(self->file),
+ compresslevel, 0, 0);
+
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+
+ self->mode = (mode_char == 'r') ? MODE_READ : MODE_WRITE;
+
+ return 0;
+
+error:
+ Py_CLEAR(self->file);
+#ifdef WITH_THREAD
+ if (self->lock) {
+ PyThread_free_lock(self->lock);
+ self->lock = NULL;
+ }
+#endif
+ return -1;
+}
+
+static void
+BZ2File_dealloc(BZ2FileObject *self)
+{
+ int bzerror;
+#ifdef WITH_THREAD
+ if (self->lock)
+ PyThread_free_lock(self->lock);
+#endif
+ switch (self->mode) {
+ case MODE_READ:
+ case MODE_READ_EOF:
+ BZ2_bzReadClose(&bzerror, self->fp);
+ break;
+ case MODE_WRITE:
+ BZ2_bzWriteClose(&bzerror, self->fp,
+ 0, NULL, NULL);
+ break;
+ }
+ Util_DropReadAhead(self);
+ Py_XDECREF(self->file);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+/* This is a hacked version of Python's fileobject.c:file_getiter(). */
+static PyObject *
+BZ2File_getiter(BZ2FileObject *self)
+{
+ if (self->mode == MODE_CLOSED) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ return NULL;
+ }
+ Py_INCREF((PyObject*)self);
+ return (PyObject *)self;
+}
+
+/* This is a hacked version of Python's fileobject.c:file_iternext(). */
+#define READAHEAD_BUFSIZE 8192
+static PyObject *
+BZ2File_iternext(BZ2FileObject *self)
+{
+ PyStringObject* ret;
+ ACQUIRE_LOCK(self);
+ if (self->mode == MODE_CLOSED) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ return NULL;
+ }
+ ret = Util_ReadAheadGetLineSkip(self, 0, READAHEAD_BUFSIZE);
+ RELEASE_LOCK(self);
+ if (ret == NULL || PyString_GET_SIZE(ret) == 0) {
+ Py_XDECREF(ret);
+ return NULL;
+ }
+ return (PyObject *)ret;
+}
+
+/* ===================================================================== */
+/* BZ2File_Type definition. */
+
+PyDoc_VAR(BZ2File__doc__) =
+PyDoc_STR(
+"BZ2File(name [, mode='r', buffering=0, compresslevel=9]) -> file object\n\
+\n\
+Open a bz2 file. The mode can be 'r' or 'w', for reading (default) or\n\
+writing. When opened for writing, the file will be created if it doesn't\n\
+exist, and truncated otherwise. If the buffering argument is given, 0 means\n\
+unbuffered, and larger numbers specify the buffer size. If compresslevel\n\
+is given, must be a number between 1 and 9.\n\
+")
+PyDoc_STR(
+"\n\
+Add a 'U' to mode to open the file for input with universal newline\n\
+support. Any line ending in the input file will be seen as a '\\n' in\n\
+Python. Also, a file so opened gains the attribute 'newlines'; the value\n\
+for this attribute is one of None (no newline read yet), '\\r', '\\n',\n\
+'\\r\\n' or a tuple containing all the newline types seen. Universal\n\
+newlines are available only when reading.\n\
+")
+;
+
+static PyTypeObject BZ2File_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "bz2.BZ2File", /*tp_name*/
+ sizeof(BZ2FileObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)BZ2File_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr,/*tp_getattro*/
+ PyObject_GenericSetAttr,/*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ BZ2File__doc__, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ (getiterfunc)BZ2File_getiter, /*tp_iter*/
+ (iternextfunc)BZ2File_iternext, /*tp_iternext*/
+ BZ2File_methods, /*tp_methods*/
+ BZ2File_members, /*tp_members*/
+ BZ2File_getset, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ (initproc)BZ2File_init, /*tp_init*/
+ PyType_GenericAlloc, /*tp_alloc*/
+ PyType_GenericNew, /*tp_new*/
+ _PyObject_Del, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+
+/* ===================================================================== */
+/* Methods of BZ2Comp. */
+
+PyDoc_STRVAR(BZ2Comp_compress__doc__,
+"compress(data) -> string\n\
+\n\
+Provide more data to the compressor object. It will return chunks of\n\
+compressed data whenever possible. When you've finished providing data\n\
+to compress, call the flush() method to finish the compression process,\n\
+and return what is left in the internal buffers.\n\
+");
+
+static PyObject *
+BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
+{
+ char *data;
+ int datasize;
+ int bufsize = SMALLCHUNK;
+ PY_LONG_LONG totalout;
+ PyObject *ret = NULL;
+ bz_stream *bzs = &self->bzs;
+ int bzerror;
+
+ if (!PyArg_ParseTuple(args, "s#:compress", &data, &datasize))
+ return NULL;
+
+ if (datasize == 0)
+ return PyString_FromString("");
+
+ ACQUIRE_LOCK(self);
+ if (!self->running) {
+ PyErr_SetString(PyExc_ValueError,
+ "this object was already flushed");
+ goto error;
+ }
+
+ ret = PyString_FromStringAndSize(NULL, bufsize);
+ if (!ret)
+ goto error;
+
+ bzs->next_in = data;
+ bzs->avail_in = datasize;
+ bzs->next_out = BUF(ret);
+ bzs->avail_out = bufsize;
+
+ totalout = BZS_TOTAL_OUT(bzs);
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ bzerror = BZ2_bzCompress(bzs, BZ_RUN);
+ Py_END_ALLOW_THREADS
+ if (bzerror != BZ_RUN_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+ if (bzs->avail_in == 0)
+ break; /* no more input data */
+ if (bzs->avail_out == 0) {
+ bufsize = Util_NewBufferSize(bufsize);
+ if (_PyString_Resize(&ret, bufsize) < 0) {
+ BZ2_bzCompressEnd(bzs);
+ goto error;
+ }
+ bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
+ - totalout);
+ bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+ }
+ }
+
+ _PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
+
+ RELEASE_LOCK(self);
+ return ret;
+
+error:
+ RELEASE_LOCK(self);
+ Py_XDECREF(ret);
+ return NULL;
+}
+
+PyDoc_STRVAR(BZ2Comp_flush__doc__,
+"flush() -> string\n\
+\n\
+Finish the compression process and return what is left in internal buffers.\n\
+You must not use the compressor object after calling this method.\n\
+");
+
+static PyObject *
+BZ2Comp_flush(BZ2CompObject *self)
+{
+ int bufsize = SMALLCHUNK;
+ PyObject *ret = NULL;
+ bz_stream *bzs = &self->bzs;
+ PY_LONG_LONG totalout;
+ int bzerror;
+
+ ACQUIRE_LOCK(self);
+ if (!self->running) {
+ PyErr_SetString(PyExc_ValueError, "object was already "
+ "flushed");
+ goto error;
+ }
+ self->running = 0;
+
+ ret = PyString_FromStringAndSize(NULL, bufsize);
+ if (!ret)
+ goto error;
+
+ bzs->next_out = BUF(ret);
+ bzs->avail_out = bufsize;
+
+ totalout = BZS_TOTAL_OUT(bzs);
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
+ Py_END_ALLOW_THREADS
+ if (bzerror == BZ_STREAM_END) {
+ break;
+ } else if (bzerror != BZ_FINISH_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+ if (bzs->avail_out == 0) {
+ bufsize = Util_NewBufferSize(bufsize);
+ if (_PyString_Resize(&ret, bufsize) < 0)
+ goto error;
+ bzs->next_out = BUF(ret);
+ bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
+ - totalout);
+ bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+ }
+ }
+
+ if (bzs->avail_out != 0)
+ _PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
+
+ RELEASE_LOCK(self);
+ return ret;
+
+error:
+ RELEASE_LOCK(self);
+ Py_XDECREF(ret);
+ return NULL;
+}
+
+static PyMethodDef BZ2Comp_methods[] = {
+ {"compress", (PyCFunction)BZ2Comp_compress, METH_VARARGS,
+ BZ2Comp_compress__doc__},
+ {"flush", (PyCFunction)BZ2Comp_flush, METH_NOARGS,
+ BZ2Comp_flush__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* ===================================================================== */
+/* Slot definitions for BZ2Comp_Type. */
+
+static int
+BZ2Comp_init(BZ2CompObject *self, PyObject *args, PyObject *kwargs)
+{
+ int compresslevel = 9;
+ int bzerror;
+ static char *kwlist[] = {"compresslevel", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:BZ2Compressor",
+ kwlist, &compresslevel))
+ return -1;
+
+ if (compresslevel < 1 || compresslevel > 9) {
+ PyErr_SetString(PyExc_ValueError,
+ "compresslevel must be between 1 and 9");
+ goto error;
+ }
+
+#ifdef WITH_THREAD
+ self->lock = PyThread_allocate_lock();
+ if (!self->lock) {
+ PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
+ goto error;
+ }
+#endif
+
+ memset(&self->bzs, 0, sizeof(bz_stream));
+ bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+
+ self->running = 1;
+
+ return 0;
+error:
+#ifdef WITH_THREAD
+ if (self->lock) {
+ PyThread_free_lock(self->lock);
+ self->lock = NULL;
+ }
+#endif
+ return -1;
+}
+
+static void
+BZ2Comp_dealloc(BZ2CompObject *self)
+{
+#ifdef WITH_THREAD
+ if (self->lock)
+ PyThread_free_lock(self->lock);
+#endif
+ BZ2_bzCompressEnd(&self->bzs);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+
+/* ===================================================================== */
+/* BZ2Comp_Type definition. */
+
+PyDoc_STRVAR(BZ2Comp__doc__,
+"BZ2Compressor([compresslevel=9]) -> compressor object\n\
+\n\
+Create a new compressor object. This object may be used to compress\n\
+data sequentially. If you want to compress data in one shot, use the\n\
+compress() function instead. The compresslevel parameter, if given,\n\
+must be a number between 1 and 9.\n\
+");
+
+static PyTypeObject BZ2Comp_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "bz2.BZ2Compressor", /*tp_name*/
+ sizeof(BZ2CompObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)BZ2Comp_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr,/*tp_getattro*/
+ PyObject_GenericSetAttr,/*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ BZ2Comp__doc__, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ BZ2Comp_methods, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ (initproc)BZ2Comp_init, /*tp_init*/
+ PyType_GenericAlloc, /*tp_alloc*/
+ PyType_GenericNew, /*tp_new*/
+ _PyObject_Del, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+
+/* ===================================================================== */
+/* Members of BZ2Decomp. */
+
+#undef OFF
+#define OFF(x) offsetof(BZ2DecompObject, x)
+
+static PyMemberDef BZ2Decomp_members[] = {
+ {"unused_data", T_OBJECT, OFF(unused_data), RO},
+ {NULL} /* Sentinel */
+};
+
+
+/* ===================================================================== */
+/* Methods of BZ2Decomp. */
+
+PyDoc_STRVAR(BZ2Decomp_decompress__doc__,
+"decompress(data) -> string\n\
+\n\
+Provide more data to the decompressor object. It will return chunks\n\
+of decompressed data whenever possible. If you try to decompress data\n\
+after the end of stream is found, EOFError will be raised. If any data\n\
+was found after the end of stream, it'll be ignored and saved in\n\
+unused_data attribute.\n\
+");
+
+static PyObject *
+BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
+{
+ char *data;
+ int datasize;
+ int bufsize = SMALLCHUNK;
+ PY_LONG_LONG totalout;
+ PyObject *ret = NULL;
+ bz_stream *bzs = &self->bzs;
+ int bzerror;
+
+ if (!PyArg_ParseTuple(args, "s#:decompress", &data, &datasize))
+ return NULL;
+
+ ACQUIRE_LOCK(self);
+ if (!self->running) {
+ PyErr_SetString(PyExc_EOFError, "end of stream was "
+ "already found");
+ goto error;
+ }
+
+ ret = PyString_FromStringAndSize(NULL, bufsize);
+ if (!ret)
+ goto error;
+
+ bzs->next_in = data;
+ bzs->avail_in = datasize;
+ bzs->next_out = BUF(ret);
+ bzs->avail_out = bufsize;
+
+ totalout = BZS_TOTAL_OUT(bzs);
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ bzerror = BZ2_bzDecompress(bzs);
+ Py_END_ALLOW_THREADS
+ if (bzerror == BZ_STREAM_END) {
+ if (bzs->avail_in != 0) {
+ Py_DECREF(self->unused_data);
+ self->unused_data =
+ PyString_FromStringAndSize(bzs->next_in,
+ bzs->avail_in);
+ }
+ self->running = 0;
+ break;
+ }
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+ if (bzs->avail_in == 0)
+ break; /* no more input data */
+ if (bzs->avail_out == 0) {
+ bufsize = Util_NewBufferSize(bufsize);
+ if (_PyString_Resize(&ret, bufsize) < 0) {
+ BZ2_bzDecompressEnd(bzs);
+ goto error;
+ }
+ bzs->next_out = BUF(ret);
+ bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
+ - totalout);
+ bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+ }
+ }
+
+ if (bzs->avail_out != 0)
+ _PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
+
+ RELEASE_LOCK(self);
+ return ret;
+
+error:
+ RELEASE_LOCK(self);
+ Py_XDECREF(ret);
+ return NULL;
+}
+
+static PyMethodDef BZ2Decomp_methods[] = {
+ {"decompress", (PyCFunction)BZ2Decomp_decompress, METH_VARARGS, BZ2Decomp_decompress__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* ===================================================================== */
+/* Slot definitions for BZ2Decomp_Type. */
+
+static int
+BZ2Decomp_init(BZ2DecompObject *self, PyObject *args, PyObject *kwargs)
+{
+ int bzerror;
+
+ if (!PyArg_ParseTuple(args, ":BZ2Decompressor"))
+ return -1;
+
+#ifdef WITH_THREAD
+ self->lock = PyThread_allocate_lock();
+ if (!self->lock) {
+ PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
+ goto error;
+ }
+#endif
+
+ self->unused_data = PyString_FromString("");
+ if (!self->unused_data)
+ goto error;
+
+ memset(&self->bzs, 0, sizeof(bz_stream));
+ bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ goto error;
+ }
+
+ self->running = 1;
+
+ return 0;
+
+error:
+#ifdef WITH_THREAD
+ if (self->lock) {
+ PyThread_free_lock(self->lock);
+ self->lock = NULL;
+ }
+#endif
+ Py_CLEAR(self->unused_data);
+ return -1;
+}
+
+static void
+BZ2Decomp_dealloc(BZ2DecompObject *self)
+{
+#ifdef WITH_THREAD
+ if (self->lock)
+ PyThread_free_lock(self->lock);
+#endif
+ Py_XDECREF(self->unused_data);
+ BZ2_bzDecompressEnd(&self->bzs);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+
+/* ===================================================================== */
+/* BZ2Decomp_Type definition. */
+
+PyDoc_STRVAR(BZ2Decomp__doc__,
+"BZ2Decompressor() -> decompressor object\n\
+\n\
+Create a new decompressor object. This object may be used to decompress\n\
+data sequentially. If you want to decompress data in one shot, use the\n\
+decompress() function instead.\n\
+");
+
+static PyTypeObject BZ2Decomp_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "bz2.BZ2Decompressor", /*tp_name*/
+ sizeof(BZ2DecompObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)BZ2Decomp_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr,/*tp_getattro*/
+ PyObject_GenericSetAttr,/*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ BZ2Decomp__doc__, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ BZ2Decomp_methods, /*tp_methods*/
+ BZ2Decomp_members, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ (initproc)BZ2Decomp_init, /*tp_init*/
+ PyType_GenericAlloc, /*tp_alloc*/
+ PyType_GenericNew, /*tp_new*/
+ _PyObject_Del, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+
+/* ===================================================================== */
+/* Module functions. */
+
+PyDoc_STRVAR(bz2_compress__doc__,
+"compress(data [, compresslevel=9]) -> string\n\
+\n\
+Compress data in one shot. If you want to compress data sequentially,\n\
+use an instance of BZ2Compressor instead. The compresslevel parameter, if\n\
+given, must be a number between 1 and 9.\n\
+");
+
+static PyObject *
+bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ int compresslevel=9;
+ char *data;
+ int datasize;
+ int bufsize;
+ PyObject *ret = NULL;
+ bz_stream _bzs;
+ bz_stream *bzs = &_bzs;
+ int bzerror;
+ static char *kwlist[] = {"data", "compresslevel", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i",
+ kwlist, &data, &datasize,
+ &compresslevel))
+ return NULL;
+
+ if (compresslevel < 1 || compresslevel > 9) {
+ PyErr_SetString(PyExc_ValueError,
+ "compresslevel must be between 1 and 9");
+ return NULL;
+ }
+
+ /* Conforming to bz2 manual, this is large enough to fit compressed
+ * data in one shot. We will check it later anyway. */
+ bufsize = datasize + (datasize/100+1) + 600;
+
+ ret = PyString_FromStringAndSize(NULL, bufsize);
+ if (!ret)
+ return NULL;
+
+ memset(bzs, 0, sizeof(bz_stream));
+
+ bzs->next_in = data;
+ bzs->avail_in = datasize;
+ bzs->next_out = BUF(ret);
+ bzs->avail_out = bufsize;
+
+ bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ Py_DECREF(ret);
+ return NULL;
+ }
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
+ Py_END_ALLOW_THREADS
+ if (bzerror == BZ_STREAM_END) {
+ break;
+ } else if (bzerror != BZ_FINISH_OK) {
+ BZ2_bzCompressEnd(bzs);
+ Util_CatchBZ2Error(bzerror);
+ Py_DECREF(ret);
+ return NULL;
+ }
+ if (bzs->avail_out == 0) {
+ bufsize = Util_NewBufferSize(bufsize);
+ if (_PyString_Resize(&ret, bufsize) < 0) {
+ BZ2_bzCompressEnd(bzs);
+ Py_DECREF(ret);
+ return NULL;
+ }
+ bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
+ bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+ }
+ }
+
+ if (bzs->avail_out != 0)
+ _PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
+ BZ2_bzCompressEnd(bzs);
+
+ return ret;
+}
+
+PyDoc_STRVAR(bz2_decompress__doc__,
+"decompress(data) -> decompressed data\n\
+\n\
+Decompress data in one shot. If you want to decompress data sequentially,\n\
+use an instance of BZ2Decompressor instead.\n\
+");
+
+static PyObject *
+bz2_decompress(PyObject *self, PyObject *args)
+{
+ char *data;
+ int datasize;
+ int bufsize = SMALLCHUNK;
+ PyObject *ret;
+ bz_stream _bzs;
+ bz_stream *bzs = &_bzs;
+ int bzerror;
+
+ if (!PyArg_ParseTuple(args, "s#:decompress", &data, &datasize))
+ return NULL;
+
+ if (datasize == 0)
+ return PyString_FromString("");
+
+ ret = PyString_FromStringAndSize(NULL, bufsize);
+ if (!ret)
+ return NULL;
+
+ memset(bzs, 0, sizeof(bz_stream));
+
+ bzs->next_in = data;
+ bzs->avail_in = datasize;
+ bzs->next_out = BUF(ret);
+ bzs->avail_out = bufsize;
+
+ bzerror = BZ2_bzDecompressInit(bzs, 0, 0);
+ if (bzerror != BZ_OK) {
+ Util_CatchBZ2Error(bzerror);
+ Py_DECREF(ret);
+ return NULL;
+ }
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ bzerror = BZ2_bzDecompress(bzs);
+ Py_END_ALLOW_THREADS
+ if (bzerror == BZ_STREAM_END) {
+ break;
+ } else if (bzerror != BZ_OK) {
+ BZ2_bzDecompressEnd(bzs);
+ Util_CatchBZ2Error(bzerror);
+ Py_DECREF(ret);
+ return NULL;
+ }
+ if (bzs->avail_in == 0) {
+ BZ2_bzDecompressEnd(bzs);
+ PyErr_SetString(PyExc_ValueError,
+ "couldn't find end of stream");
+ Py_DECREF(ret);
+ return NULL;
+ }
+ if (bzs->avail_out == 0) {
+ bufsize = Util_NewBufferSize(bufsize);
+ if (_PyString_Resize(&ret, bufsize) < 0) {
+ BZ2_bzDecompressEnd(bzs);
+ Py_DECREF(ret);
+ return NULL;
+ }
+ bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
+ bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
+ }
+ }
+
+ if (bzs->avail_out != 0)
+ _PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
+ BZ2_bzDecompressEnd(bzs);
+
+ return ret;
+}
+
+static PyMethodDef bz2_methods[] = {
+ {"compress", (PyCFunction) bz2_compress, METH_VARARGS|METH_KEYWORDS,
+ bz2_compress__doc__},
+ {"decompress", (PyCFunction) bz2_decompress, METH_VARARGS,
+ bz2_decompress__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+/* ===================================================================== */
+/* Initialization function. */
+
+PyDoc_STRVAR(bz2__doc__,
+"The python bz2 module provides a comprehensive interface for\n\
+the bz2 compression library. It implements a complete file\n\
+interface, one shot (de)compression functions, and types for\n\
+sequential (de)compression.\n\
+");
+
+PyMODINIT_FUNC
+initbz2(void)
+{
+ PyObject *m;
+
+ BZ2File_Type.ob_type = &PyType_Type;
+ BZ2Comp_Type.ob_type = &PyType_Type;
+ BZ2Decomp_Type.ob_type = &PyType_Type;
+
+ m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
+ if (m == NULL)
+ return;
+
+ PyModule_AddObject(m, "__author__", PyString_FromString(__author__));
+
+ Py_INCREF(&BZ2File_Type);
+ PyModule_AddObject(m, "BZ2File", (PyObject *)&BZ2File_Type);
+
+ Py_INCREF(&BZ2Comp_Type);
+ PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Comp_Type);
+
+ Py_INCREF(&BZ2Decomp_Type);
+ PyModule_AddObject(m, "BZ2Decompressor", (PyObject *)&BZ2Decomp_Type);
+}
diff --git a/sys/src/cmd/python/Modules/cPickle.c b/sys/src/cmd/python/Modules/cPickle.c
new file mode 100644
index 000000000..4f7d1f198
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cPickle.c
@@ -0,0 +1,5757 @@
+#include "Python.h"
+#include "cStringIO.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(cPickle_module_documentation,
+"C implementation and optimization of the Python pickle module.");
+
+#ifndef Py_eval_input
+#include <graminit.h>
+#define Py_eval_input eval_input
+#endif /* Py_eval_input */
+
+#define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL))
+
+#define WRITE_BUF_SIZE 256
+
+/* Bump this when new opcodes are added to the pickle protocol. */
+#define HIGHEST_PROTOCOL 2
+
+/*
+ * Pickle opcodes. These must be kept in synch with pickle.py. Extensive
+ * docs are in pickletools.py.
+ */
+#define MARK '('
+#define STOP '.'
+#define POP '0'
+#define POP_MARK '1'
+#define DUP '2'
+#define FLOAT 'F'
+#define BINFLOAT 'G'
+#define INT 'I'
+#define BININT 'J'
+#define BININT1 'K'
+#define LONG 'L'
+#define BININT2 'M'
+#define NONE 'N'
+#define PERSID 'P'
+#define BINPERSID 'Q'
+#define REDUCE 'R'
+#define STRING 'S'
+#define BINSTRING 'T'
+#define SHORT_BINSTRING 'U'
+#define UNICODE 'V'
+#define BINUNICODE 'X'
+#define APPEND 'a'
+#define BUILD 'b'
+#define GLOBAL 'c'
+#define DICT 'd'
+#define EMPTY_DICT '}'
+#define APPENDS 'e'
+#define GET 'g'
+#define BINGET 'h'
+#define INST 'i'
+#define LONG_BINGET 'j'
+#define LIST 'l'
+#define EMPTY_LIST ']'
+#define OBJ 'o'
+#define PUT 'p'
+#define BINPUT 'q'
+#define LONG_BINPUT 'r'
+#define SETITEM 's'
+#define TUPLE 't'
+#define EMPTY_TUPLE ')'
+#define SETITEMS 'u'
+
+/* Protocol 2. */
+#define PROTO '\x80' /* identify pickle protocol */
+#define NEWOBJ '\x81' /* build object by applying cls.__new__ to argtuple */
+#define EXT1 '\x82' /* push object from extension registry; 1-byte index */
+#define EXT2 '\x83' /* ditto, but 2-byte index */
+#define EXT4 '\x84' /* ditto, but 4-byte index */
+#define TUPLE1 '\x85' /* build 1-tuple from stack top */
+#define TUPLE2 '\x86' /* build 2-tuple from two topmost stack items */
+#define TUPLE3 '\x87' /* build 3-tuple from three topmost stack items */
+#define NEWTRUE '\x88' /* push True */
+#define NEWFALSE '\x89' /* push False */
+#define LONG1 '\x8a' /* push long from < 256 bytes */
+#define LONG4 '\x8b' /* push really big long */
+
+/* There aren't opcodes -- they're ways to pickle bools before protocol 2,
+ * so that unpicklers written before bools were introduced unpickle them
+ * as ints, but unpicklers after can recognize that bools were intended.
+ * Note that protocol 2 added direct ways to pickle bools.
+ */
+#undef TRUE
+#define TRUE "I01\n"
+#undef FALSE
+#define FALSE "I00\n"
+
+/* Keep in synch with pickle.Pickler._BATCHSIZE. This is how many elements
+ * batch_list/dict() pumps out before doing APPENDS/SETITEMS. Nothing will
+ * break if this gets out of synch with pickle.py, but it's unclear that
+ * would help anything either.
+ */
+#define BATCHSIZE 1000
+
+static char MARKv = MARK;
+
+static PyObject *PickleError;
+static PyObject *PicklingError;
+static PyObject *UnpickleableError;
+static PyObject *UnpicklingError;
+static PyObject *BadPickleGet;
+
+/* As the name says, an empty tuple. */
+static PyObject *empty_tuple;
+
+/* copy_reg.dispatch_table, {type_object: pickling_function} */
+static PyObject *dispatch_table;
+
+/* For EXT[124] opcodes. */
+/* copy_reg._extension_registry, {(module_name, function_name): code} */
+static PyObject *extension_registry;
+/* copy_reg._inverted_registry, {code: (module_name, function_name)} */
+static PyObject *inverted_registry;
+/* copy_reg._extension_cache, {code: object} */
+static PyObject *extension_cache;
+
+/* For looking up name pairs in copy_reg._extension_registry. */
+static PyObject *two_tuple;
+
+static PyObject *__class___str, *__getinitargs___str, *__dict___str,
+ *__getstate___str, *__setstate___str, *__name___str, *__reduce___str,
+ *__reduce_ex___str,
+ *write_str, *append_str,
+ *read_str, *readline_str, *__main___str,
+ *copy_reg_str, *dispatch_table_str;
+
+/*************************************************************************
+ Internal Data type for pickle data. */
+
+typedef struct {
+ PyObject_HEAD
+ int length; /* number of initial slots in data currently used */
+ int size; /* number of slots in data allocated */
+ PyObject **data;
+} Pdata;
+
+static void
+Pdata_dealloc(Pdata *self)
+{
+ int i;
+ PyObject **p;
+
+ for (i = self->length, p = self->data; --i >= 0; p++) {
+ Py_DECREF(*p);
+ }
+ if (self->data)
+ free(self->data);
+ PyObject_Del(self);
+}
+
+static PyTypeObject PdataType = {
+ PyObject_HEAD_INIT(NULL) 0, "cPickle.Pdata", sizeof(Pdata), 0,
+ (destructor)Pdata_dealloc,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0L,0L,0L,0L, ""
+};
+
+#define Pdata_Check(O) ((O)->ob_type == &PdataType)
+
+static PyObject *
+Pdata_New(void)
+{
+ Pdata *self;
+
+ if (!(self = PyObject_New(Pdata, &PdataType)))
+ return NULL;
+ self->size = 8;
+ self->length = 0;
+ self->data = malloc(self->size * sizeof(PyObject*));
+ if (self->data)
+ return (PyObject*)self;
+ Py_DECREF(self);
+ return PyErr_NoMemory();
+}
+
+static int
+stackUnderflow(void)
+{
+ PyErr_SetString(UnpicklingError, "unpickling stack underflow");
+ return -1;
+}
+
+/* Retain only the initial clearto items. If clearto >= the current
+ * number of items, this is a (non-erroneous) NOP.
+ */
+static int
+Pdata_clear(Pdata *self, int clearto)
+{
+ int i;
+ PyObject **p;
+
+ if (clearto < 0) return stackUnderflow();
+ if (clearto >= self->length) return 0;
+
+ for (i = self->length, p = self->data + clearto;
+ --i >= clearto;
+ p++) {
+ Py_CLEAR(*p);
+ }
+ self->length = clearto;
+
+ return 0;
+}
+
+static int
+Pdata_grow(Pdata *self)
+{
+ int bigger;
+ size_t nbytes;
+ PyObject **tmp;
+
+ bigger = self->size << 1;
+ if (bigger <= 0) /* was 0, or new value overflows */
+ goto nomemory;
+ if ((int)(size_t)bigger != bigger)
+ goto nomemory;
+ nbytes = (size_t)bigger * sizeof(PyObject *);
+ if (nbytes / sizeof(PyObject *) != (size_t)bigger)
+ goto nomemory;
+ tmp = realloc(self->data, nbytes);
+ if (tmp == NULL)
+ goto nomemory;
+ self->data = tmp;
+ self->size = bigger;
+ return 0;
+
+ nomemory:
+ PyErr_NoMemory();
+ return -1;
+}
+
+/* D is a Pdata*. Pop the topmost element and store it into V, which
+ * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError
+ * is raised and V is set to NULL. D and V may be evaluated several times.
+ */
+#define PDATA_POP(D, V) { \
+ if ((D)->length) \
+ (V) = (D)->data[--((D)->length)]; \
+ else { \
+ PyErr_SetString(UnpicklingError, "bad pickle data"); \
+ (V) = NULL; \
+ } \
+}
+
+/* PDATA_PUSH and PDATA_APPEND both push rvalue PyObject* O on to Pdata*
+ * D. If the Pdata stack can't be grown to hold the new value, both
+ * raise MemoryError and execute "return ER". The difference is in ownership
+ * of O after: _PUSH transfers ownership of O from the caller to the stack
+ * (no incref of O is done, and in case of error O is decrefed), while
+ * _APPEND pushes a new reference.
+ */
+
+/* Push O on stack D, giving ownership of O to the stack. */
+#define PDATA_PUSH(D, O, ER) { \
+ if (((Pdata*)(D))->length == ((Pdata*)(D))->size && \
+ Pdata_grow((Pdata*)(D)) < 0) { \
+ Py_DECREF(O); \
+ return ER; \
+ } \
+ ((Pdata*)(D))->data[((Pdata*)(D))->length++] = (O); \
+}
+
+/* Push O on stack D, pushing a new reference. */
+#define PDATA_APPEND(D, O, ER) { \
+ if (((Pdata*)(D))->length == ((Pdata*)(D))->size && \
+ Pdata_grow((Pdata*)(D)) < 0) \
+ return ER; \
+ Py_INCREF(O); \
+ ((Pdata*)(D))->data[((Pdata*)(D))->length++] = (O); \
+}
+
+
+static PyObject *
+Pdata_popTuple(Pdata *self, int start)
+{
+ PyObject *r;
+ int i, j, l;
+
+ l = self->length-start;
+ r = PyTuple_New(l);
+ if (r == NULL)
+ return NULL;
+ for (i = start, j = 0 ; j < l; i++, j++)
+ PyTuple_SET_ITEM(r, j, self->data[i]);
+
+ self->length = start;
+ return r;
+}
+
+static PyObject *
+Pdata_popList(Pdata *self, int start)
+{
+ PyObject *r;
+ int i, j, l;
+
+ l=self->length-start;
+ if (!( r=PyList_New(l))) return NULL;
+ for (i=start, j=0 ; j < l; i++, j++)
+ PyList_SET_ITEM(r, j, self->data[i]);
+
+ self->length=start;
+ return r;
+}
+
+/*************************************************************************/
+
+#define ARG_TUP(self, o) { \
+ if (self->arg || (self->arg=PyTuple_New(1))) { \
+ Py_XDECREF(PyTuple_GET_ITEM(self->arg,0)); \
+ PyTuple_SET_ITEM(self->arg,0,o); \
+ } \
+ else { \
+ Py_DECREF(o); \
+ } \
+}
+
+#define FREE_ARG_TUP(self) { \
+ if (self->arg->ob_refcnt > 1) { \
+ Py_DECREF(self->arg); \
+ self->arg=NULL; \
+ } \
+ }
+
+typedef struct Picklerobject {
+ PyObject_HEAD
+ FILE *fp;
+ PyObject *write;
+ PyObject *file;
+ PyObject *memo;
+ PyObject *arg;
+ PyObject *pers_func;
+ PyObject *inst_pers_func;
+
+ /* pickle protocol number, >= 0 */
+ int proto;
+
+ /* bool, true if proto > 0 */
+ int bin;
+
+ int fast; /* Fast mode doesn't save in memo, don't use if circ ref */
+ int nesting;
+ int (*write_func)(struct Picklerobject *, const char *, Py_ssize_t);
+ char *write_buf;
+ int buf_size;
+ PyObject *dispatch_table;
+ int fast_container; /* count nested container dumps */
+ PyObject *fast_memo;
+} Picklerobject;
+
+#ifndef PY_CPICKLE_FAST_LIMIT
+#define PY_CPICKLE_FAST_LIMIT 50
+#endif
+
+static PyTypeObject Picklertype;
+
+typedef struct Unpicklerobject {
+ PyObject_HEAD
+ FILE *fp;
+ PyObject *file;
+ PyObject *readline;
+ PyObject *read;
+ PyObject *memo;
+ PyObject *arg;
+ Pdata *stack;
+ PyObject *mark;
+ PyObject *pers_func;
+ PyObject *last_string;
+ int *marks;
+ int num_marks;
+ int marks_size;
+ Py_ssize_t (*read_func)(struct Unpicklerobject *, char **, Py_ssize_t);
+ Py_ssize_t (*readline_func)(struct Unpicklerobject *, char **);
+ int buf_size;
+ char *buf;
+ PyObject *find_class;
+} Unpicklerobject;
+
+static PyTypeObject Unpicklertype;
+
+/* Forward decls that need the above structs */
+static int save(Picklerobject *, PyObject *, int);
+static int put2(Picklerobject *, PyObject *);
+
+static
+PyObject *
+cPickle_ErrFormat(PyObject *ErrType, char *stringformat, char *format, ...)
+{
+ va_list va;
+ PyObject *args=0, *retval=0;
+ va_start(va, format);
+
+ if (format) args = Py_VaBuildValue(format, va);
+ va_end(va);
+ if (format && ! args) return NULL;
+ if (stringformat && !(retval=PyString_FromString(stringformat)))
+ return NULL;
+
+ if (retval) {
+ if (args) {
+ PyObject *v;
+ v=PyString_Format(retval, args);
+ Py_DECREF(retval);
+ Py_DECREF(args);
+ if (! v) return NULL;
+ retval=v;
+ }
+ }
+ else
+ if (args) retval=args;
+ else {
+ PyErr_SetObject(ErrType,Py_None);
+ return NULL;
+ }
+ PyErr_SetObject(ErrType,retval);
+ Py_DECREF(retval);
+ return NULL;
+}
+
+static int
+write_file(Picklerobject *self, const char *s, Py_ssize_t n)
+{
+ size_t nbyteswritten;
+
+ if (s == NULL) {
+ return 0;
+ }
+
+ if (n > INT_MAX) {
+ /* String too large */
+ return -1;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ nbyteswritten = fwrite(s, sizeof(char), n, self->fp);
+ Py_END_ALLOW_THREADS
+ if (nbyteswritten != (size_t)n) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+
+ return (int)n;
+}
+
+static int
+write_cStringIO(Picklerobject *self, const char *s, Py_ssize_t n)
+{
+ if (s == NULL) {
+ return 0;
+ }
+
+ if (PycStringIO->cwrite((PyObject *)self->file, s, n) != n) {
+ return -1;
+ }
+
+ return (int)n;
+}
+
+static int
+write_none(Picklerobject *self, const char *s, Py_ssize_t n)
+{
+ if (s == NULL) return 0;
+ if (n > INT_MAX) return -1;
+ return (int)n;
+}
+
+static int
+write_other(Picklerobject *self, const char *s, Py_ssize_t _n)
+{
+ PyObject *py_str = 0, *junk = 0;
+ int n;
+
+ if (_n > INT_MAX)
+ return -1;
+ n = (int)_n;
+ if (s == NULL) {
+ if (!( self->buf_size )) return 0;
+ py_str = PyString_FromStringAndSize(self->write_buf,
+ self->buf_size);
+ if (!py_str)
+ return -1;
+ }
+ else {
+ if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
+ if (write_other(self, NULL, 0) < 0)
+ return -1;
+ }
+
+ if (n > WRITE_BUF_SIZE) {
+ if (!( py_str =
+ PyString_FromStringAndSize(s, n)))
+ return -1;
+ }
+ else {
+ memcpy(self->write_buf + self->buf_size, s, n);
+ self->buf_size += n;
+ return n;
+ }
+ }
+
+ if (self->write) {
+ /* object with write method */
+ ARG_TUP(self, py_str);
+ if (self->arg) {
+ junk = PyObject_Call(self->write, self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ if (junk) Py_DECREF(junk);
+ else return -1;
+ }
+ else
+ PDATA_PUSH(self->file, py_str, -1);
+
+ self->buf_size = 0;
+ return n;
+}
+
+
+static Py_ssize_t
+read_file(Unpicklerobject *self, char **s, Py_ssize_t n)
+{
+ size_t nbytesread;
+
+ if (self->buf_size == 0) {
+ int size;
+
+ size = ((n < 32) ? 32 : n);
+ if (!( self->buf = (char *)malloc(size))) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ self->buf_size = size;
+ }
+ else if (n > self->buf_size) {
+ self->buf = (char *)realloc(self->buf, n);
+ if (!self->buf) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->buf_size = n;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ nbytesread = fread(self->buf, sizeof(char), n, self->fp);
+ Py_END_ALLOW_THREADS
+ if (nbytesread != (size_t)n) {
+ if (feof(self->fp)) {
+ PyErr_SetNone(PyExc_EOFError);
+ return -1;
+ }
+
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+
+ *s = self->buf;
+
+ return n;
+}
+
+
+static Py_ssize_t
+readline_file(Unpicklerobject *self, char **s)
+{
+ int i;
+
+ if (self->buf_size == 0) {
+ if (!( self->buf = (char *)malloc(40))) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->buf_size = 40;
+ }
+
+ i = 0;
+ while (1) {
+ int bigger;
+ for (; i < (self->buf_size - 1); i++) {
+ if (feof(self->fp) ||
+ (self->buf[i] = getc(self->fp)) == '\n') {
+ self->buf[i + 1] = '\0';
+ *s = self->buf;
+ return i + 1;
+ }
+ }
+ bigger = self->buf_size << 1;
+ if (bigger <= 0) { /* overflow */
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->buf = (char *)realloc(self->buf, bigger);
+ if (!self->buf) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->buf_size = bigger;
+ }
+}
+
+
+static Py_ssize_t
+read_cStringIO(Unpicklerobject *self, char **s, Py_ssize_t n)
+{
+ char *ptr;
+
+ if (PycStringIO->cread((PyObject *)self->file, &ptr, n) != n) {
+ PyErr_SetNone(PyExc_EOFError);
+ return -1;
+ }
+
+ *s = ptr;
+
+ return n;
+}
+
+
+static Py_ssize_t
+readline_cStringIO(Unpicklerobject *self, char **s)
+{
+ Py_ssize_t n;
+ char *ptr;
+
+ if ((n = PycStringIO->creadline((PyObject *)self->file, &ptr)) < 0) {
+ return -1;
+ }
+
+ *s = ptr;
+
+ return n;
+}
+
+
+static Py_ssize_t
+read_other(Unpicklerobject *self, char **s, Py_ssize_t n)
+{
+ PyObject *bytes, *str=0;
+
+ if (!( bytes = PyInt_FromSsize_t(n))) return -1;
+
+ ARG_TUP(self, bytes);
+ if (self->arg) {
+ str = PyObject_Call(self->read, self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ if (! str) return -1;
+
+ Py_XDECREF(self->last_string);
+ self->last_string = str;
+
+ if (! (*s = PyString_AsString(str))) return -1;
+ return n;
+}
+
+
+static Py_ssize_t
+readline_other(Unpicklerobject *self, char **s)
+{
+ PyObject *str;
+ Py_ssize_t str_size;
+
+ if (!( str = PyObject_CallObject(self->readline, empty_tuple))) {
+ return -1;
+ }
+
+ if ((str_size = PyString_Size(str)) < 0)
+ return -1;
+
+ Py_XDECREF(self->last_string);
+ self->last_string = str;
+
+ if (! (*s = PyString_AsString(str)))
+ return -1;
+
+ return str_size;
+}
+
+/* Copy the first n bytes from s into newly malloc'ed memory, plus a
+ * trailing 0 byte. Return a pointer to that, or NULL if out of memory.
+ * The caller is responsible for free()'ing the return value.
+ */
+static char *
+pystrndup(const char *s, int n)
+{
+ char *r = (char *)malloc(n+1);
+ if (r == NULL)
+ return (char*)PyErr_NoMemory();
+ memcpy(r, s, n);
+ r[n] = 0;
+ return r;
+}
+
+
+static int
+get(Picklerobject *self, PyObject *id)
+{
+ PyObject *value, *mv;
+ long c_value;
+ char s[30];
+ size_t len;
+
+ if (!( mv = PyDict_GetItem(self->memo, id))) {
+ PyErr_SetObject(PyExc_KeyError, id);
+ return -1;
+ }
+
+ if (!( value = PyTuple_GetItem(mv, 0)))
+ return -1;
+
+ if (!( PyInt_Check(value))) {
+ PyErr_SetString(PicklingError, "no int where int expected in memo");
+ return -1;
+ }
+ c_value = PyInt_AS_LONG((PyIntObject*)value);
+
+ if (!self->bin) {
+ s[0] = GET;
+ PyOS_snprintf(s + 1, sizeof(s) - 1, "%ld\n", c_value);
+ len = strlen(s);
+ }
+ else if (Pdata_Check(self->file)) {
+ if (write_other(self, NULL, 0) < 0) return -1;
+ PDATA_APPEND(self->file, mv, -1);
+ return 0;
+ }
+ else {
+ if (c_value < 256) {
+ s[0] = BINGET;
+ s[1] = (int)(c_value & 0xff);
+ len = 2;
+ }
+ else {
+ s[0] = LONG_BINGET;
+ s[1] = (int)(c_value & 0xff);
+ s[2] = (int)((c_value >> 8) & 0xff);
+ s[3] = (int)((c_value >> 16) & 0xff);
+ s[4] = (int)((c_value >> 24) & 0xff);
+ len = 5;
+ }
+ }
+
+ if (self->write_func(self, s, len) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+put(Picklerobject *self, PyObject *ob)
+{
+ if (ob->ob_refcnt < 2 || self->fast)
+ return 0;
+
+ return put2(self, ob);
+}
+
+
+static int
+put2(Picklerobject *self, PyObject *ob)
+{
+ char c_str[30];
+ int p;
+ size_t len;
+ int res = -1;
+ PyObject *py_ob_id = 0, *memo_len = 0, *t = 0;
+
+ if (self->fast)
+ return 0;
+
+ if ((p = PyDict_Size(self->memo)) < 0)
+ goto finally;
+
+ /* Make sure memo keys are positive! */
+ /* XXX Why?
+ * XXX And does "positive" really mean non-negative?
+ * XXX pickle.py starts with PUT index 0, not 1. This makes for
+ * XXX gratuitous differences between the pickling modules.
+ */
+ p++;
+
+ if (!( py_ob_id = PyLong_FromVoidPtr(ob)))
+ goto finally;
+
+ if (!( memo_len = PyInt_FromLong(p)))
+ goto finally;
+
+ if (!( t = PyTuple_New(2)))
+ goto finally;
+
+ PyTuple_SET_ITEM(t, 0, memo_len);
+ Py_INCREF(memo_len);
+ PyTuple_SET_ITEM(t, 1, ob);
+ Py_INCREF(ob);
+
+ if (PyDict_SetItem(self->memo, py_ob_id, t) < 0)
+ goto finally;
+
+ if (!self->bin) {
+ c_str[0] = PUT;
+ PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%d\n", p);
+ len = strlen(c_str);
+ }
+ else if (Pdata_Check(self->file)) {
+ if (write_other(self, NULL, 0) < 0) return -1;
+ PDATA_APPEND(self->file, memo_len, -1);
+ res=0; /* Job well done ;) */
+ goto finally;
+ }
+ else {
+ if (p >= 256) {
+ c_str[0] = LONG_BINPUT;
+ c_str[1] = (int)(p & 0xff);
+ c_str[2] = (int)((p >> 8) & 0xff);
+ c_str[3] = (int)((p >> 16) & 0xff);
+ c_str[4] = (int)((p >> 24) & 0xff);
+ len = 5;
+ }
+ else {
+ c_str[0] = BINPUT;
+ c_str[1] = p;
+ len = 2;
+ }
+ }
+
+ if (self->write_func(self, c_str, len) < 0)
+ goto finally;
+
+ res = 0;
+
+ finally:
+ Py_XDECREF(py_ob_id);
+ Py_XDECREF(memo_len);
+ Py_XDECREF(t);
+
+ return res;
+}
+
+static PyObject *
+whichmodule(PyObject *global, PyObject *global_name)
+{
+ Py_ssize_t i, j;
+ PyObject *module = 0, *modules_dict = 0,
+ *global_name_attr = 0, *name = 0;
+
+ module = PyObject_GetAttrString(global, "__module__");
+ if (module)
+ return module;
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+
+ if (!( modules_dict = PySys_GetObject("modules")))
+ return NULL;
+
+ i = 0;
+ while ((j = PyDict_Next(modules_dict, &i, &name, &module))) {
+
+ if (PyObject_Compare(name, __main___str)==0) continue;
+
+ global_name_attr = PyObject_GetAttr(module, global_name);
+ if (!global_name_attr) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ continue;
+ }
+
+ if (global_name_attr != global) {
+ Py_DECREF(global_name_attr);
+ continue;
+ }
+
+ Py_DECREF(global_name_attr);
+
+ break;
+ }
+
+ /* The following implements the rule in pickle.py added in 1.5
+ that used __main__ if no module is found. I don't actually
+ like this rule. jlf
+ */
+ if (!j) {
+ j=1;
+ name=__main___str;
+ }
+
+ Py_INCREF(name);
+ return name;
+}
+
+
+static int
+fast_save_enter(Picklerobject *self, PyObject *obj)
+{
+ /* if fast_container < 0, we're doing an error exit. */
+ if (++self->fast_container >= PY_CPICKLE_FAST_LIMIT) {
+ PyObject *key = NULL;
+ if (self->fast_memo == NULL) {
+ self->fast_memo = PyDict_New();
+ if (self->fast_memo == NULL) {
+ self->fast_container = -1;
+ return 0;
+ }
+ }
+ key = PyLong_FromVoidPtr(obj);
+ if (key == NULL)
+ return 0;
+ if (PyDict_GetItem(self->fast_memo, key)) {
+ Py_DECREF(key);
+ PyErr_Format(PyExc_ValueError,
+ "fast mode: can't pickle cyclic objects "
+ "including object type %s at %p",
+ obj->ob_type->tp_name, obj);
+ self->fast_container = -1;
+ return 0;
+ }
+ if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
+ Py_DECREF(key);
+ self->fast_container = -1;
+ return 0;
+ }
+ Py_DECREF(key);
+ }
+ return 1;
+}
+
+int
+fast_save_leave(Picklerobject *self, PyObject *obj)
+{
+ if (self->fast_container-- >= PY_CPICKLE_FAST_LIMIT) {
+ PyObject *key = PyLong_FromVoidPtr(obj);
+ if (key == NULL)
+ return 0;
+ if (PyDict_DelItem(self->fast_memo, key) < 0) {
+ Py_DECREF(key);
+ return 0;
+ }
+ Py_DECREF(key);
+ }
+ return 1;
+}
+
+static int
+save_none(Picklerobject *self, PyObject *args)
+{
+ static char none = NONE;
+ if (self->write_func(self, &none, 1) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int
+save_bool(Picklerobject *self, PyObject *args)
+{
+ static const char *buf[2] = {FALSE, TRUE};
+ static char len[2] = {sizeof(FALSE)-1, sizeof(TRUE)-1};
+ long l = PyInt_AS_LONG((PyIntObject *)args);
+
+ if (self->proto >= 2) {
+ char opcode = l ? NEWTRUE : NEWFALSE;
+ if (self->write_func(self, &opcode, 1) < 0)
+ return -1;
+ }
+ else if (self->write_func(self, buf[l], len[l]) < 0)
+ return -1;
+ return 0;
+}
+
+static int
+save_int(Picklerobject *self, PyObject *args)
+{
+ char c_str[32];
+ long l = PyInt_AS_LONG((PyIntObject *)args);
+ int len = 0;
+
+ if (!self->bin
+#if SIZEOF_LONG > 4
+ || l > 0x7fffffffL
+ || l < -0x80000000L
+#endif
+ ) {
+ /* Text-mode pickle, or long too big to fit in the 4-byte
+ * signed BININT format: store as a string.
+ */
+ c_str[0] = INT;
+ PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%ld\n", l);
+ if (self->write_func(self, c_str, strlen(c_str)) < 0)
+ return -1;
+ }
+ else {
+ /* Binary pickle and l fits in a signed 4-byte int. */
+ c_str[1] = (int)( l & 0xff);
+ c_str[2] = (int)((l >> 8) & 0xff);
+ c_str[3] = (int)((l >> 16) & 0xff);
+ c_str[4] = (int)((l >> 24) & 0xff);
+
+ if ((c_str[4] == 0) && (c_str[3] == 0)) {
+ if (c_str[2] == 0) {
+ c_str[0] = BININT1;
+ len = 2;
+ }
+ else {
+ c_str[0] = BININT2;
+ len = 3;
+ }
+ }
+ else {
+ c_str[0] = BININT;
+ len = 5;
+ }
+
+ if (self->write_func(self, c_str, len) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+save_long(Picklerobject *self, PyObject *args)
+{
+ Py_ssize_t size;
+ int res = -1;
+ PyObject *repr = NULL;
+
+ static char l = LONG;
+
+ if (self->proto >= 2) {
+ /* Linear-time pickling. */
+ size_t nbits;
+ size_t nbytes;
+ unsigned char *pdata;
+ char c_str[5];
+ int i;
+ int sign = _PyLong_Sign(args);
+
+ if (sign == 0) {
+ /* It's 0 -- an empty bytestring. */
+ c_str[0] = LONG1;
+ c_str[1] = 0;
+ i = self->write_func(self, c_str, 2);
+ if (i < 0) goto finally;
+ res = 0;
+ goto finally;
+ }
+ nbits = _PyLong_NumBits(args);
+ if (nbits == (size_t)-1 && PyErr_Occurred())
+ goto finally;
+ /* How many bytes do we need? There are nbits >> 3 full
+ * bytes of data, and nbits & 7 leftover bits. If there
+ * are any leftover bits, then we clearly need another
+ * byte. Wnat's not so obvious is that we *probably*
+ * need another byte even if there aren't any leftovers:
+ * the most-significant bit of the most-significant byte
+ * acts like a sign bit, and it's usually got a sense
+ * opposite of the one we need. The exception is longs
+ * of the form -(2**(8*j-1)) for j > 0. Such a long is
+ * its own 256's-complement, so has the right sign bit
+ * even without the extra byte. That's a pain to check
+ * for in advance, though, so we always grab an extra
+ * byte at the start, and cut it back later if possible.
+ */
+ nbytes = (nbits >> 3) + 1;
+ if (nbytes > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "long too large "
+ "to pickle");
+ goto finally;
+ }
+ repr = PyString_FromStringAndSize(NULL, (int)nbytes);
+ if (repr == NULL) goto finally;
+ pdata = (unsigned char *)PyString_AS_STRING(repr);
+ i = _PyLong_AsByteArray((PyLongObject *)args,
+ pdata, nbytes,
+ 1 /* little endian */, 1 /* signed */);
+ if (i < 0) goto finally;
+ /* If the long is negative, this may be a byte more than
+ * needed. This is so iff the MSB is all redundant sign
+ * bits.
+ */
+ if (sign < 0 && nbytes > 1 && pdata[nbytes - 1] == 0xff &&
+ (pdata[nbytes - 2] & 0x80) != 0)
+ --nbytes;
+
+ if (nbytes < 256) {
+ c_str[0] = LONG1;
+ c_str[1] = (char)nbytes;
+ size = 2;
+ }
+ else {
+ c_str[0] = LONG4;
+ size = (int)nbytes;
+ for (i = 1; i < 5; i++) {
+ c_str[i] = (char)(size & 0xff);
+ size >>= 8;
+ }
+ size = 5;
+ }
+ i = self->write_func(self, c_str, size);
+ if (i < 0) goto finally;
+ i = self->write_func(self, (char *)pdata, (int)nbytes);
+ if (i < 0) goto finally;
+ res = 0;
+ goto finally;
+ }
+
+ /* proto < 2: write the repr and newline. This is quadratic-time
+ * (in the number of digits), in both directions.
+ */
+ if (!( repr = PyObject_Repr(args)))
+ goto finally;
+
+ if ((size = PyString_Size(repr)) < 0)
+ goto finally;
+
+ if (self->write_func(self, &l, 1) < 0)
+ goto finally;
+
+ if (self->write_func(self,
+ PyString_AS_STRING((PyStringObject *)repr),
+ size) < 0)
+ goto finally;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto finally;
+
+ res = 0;
+
+ finally:
+ Py_XDECREF(repr);
+ return res;
+}
+
+
+static int
+save_float(Picklerobject *self, PyObject *args)
+{
+ double x = PyFloat_AS_DOUBLE((PyFloatObject *)args);
+
+ if (self->bin) {
+ char str[9];
+ str[0] = BINFLOAT;
+ if (_PyFloat_Pack8(x, (unsigned char *)&str[1], 0) < 0)
+ return -1;
+ if (self->write_func(self, str, 9) < 0)
+ return -1;
+ }
+ else {
+ char c_str[250];
+ c_str[0] = FLOAT;
+ PyOS_ascii_formatd(c_str + 1, sizeof(c_str) - 2, "%.17g", x);
+ /* Extend the formatted string with a newline character */
+ strcat(c_str, "\n");
+
+ if (self->write_func(self, c_str, strlen(c_str)) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+save_string(Picklerobject *self, PyObject *args, int doput)
+{
+ int size, len;
+ PyObject *repr=0;
+
+ if ((size = PyString_Size(args)) < 0)
+ return -1;
+
+ if (!self->bin) {
+ char *repr_str;
+
+ static char string = STRING;
+
+ if (!( repr = PyObject_Repr(args)))
+ return -1;
+
+ if ((len = PyString_Size(repr)) < 0)
+ goto err;
+ repr_str = PyString_AS_STRING((PyStringObject *)repr);
+
+ if (self->write_func(self, &string, 1) < 0)
+ goto err;
+
+ if (self->write_func(self, repr_str, len) < 0)
+ goto err;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto err;
+
+ Py_XDECREF(repr);
+ }
+ else {
+ int i;
+ char c_str[5];
+
+ if ((size = PyString_Size(args)) < 0)
+ return -1;
+
+ if (size < 256) {
+ c_str[0] = SHORT_BINSTRING;
+ c_str[1] = size;
+ len = 2;
+ }
+ else if (size <= INT_MAX) {
+ c_str[0] = BINSTRING;
+ for (i = 1; i < 5; i++)
+ c_str[i] = (int)(size >> ((i - 1) * 8));
+ len = 5;
+ }
+ else
+ return -1; /* string too large */
+
+ if (self->write_func(self, c_str, len) < 0)
+ return -1;
+
+ if (size > 128 && Pdata_Check(self->file)) {
+ if (write_other(self, NULL, 0) < 0) return -1;
+ PDATA_APPEND(self->file, args, -1);
+ }
+ else {
+ if (self->write_func(self,
+ PyString_AS_STRING(
+ (PyStringObject *)args),
+ size) < 0)
+ return -1;
+ }
+ }
+
+ if (doput)
+ if (put(self, args) < 0)
+ return -1;
+
+ return 0;
+
+ err:
+ Py_XDECREF(repr);
+ return -1;
+}
+
+
+#ifdef Py_USING_UNICODE
+/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
+ backslash and newline characters to \uXXXX escapes. */
+static PyObject *
+modified_EncodeRawUnicodeEscape(const Py_UNICODE *s, int size)
+{
+ PyObject *repr;
+ char *p;
+ char *q;
+
+ static const char *hexdigit = "0123456789ABCDEF";
+
+ repr = PyString_FromStringAndSize(NULL, 6 * size);
+ if (repr == NULL)
+ return NULL;
+ if (size == 0)
+ return repr;
+
+ p = q = PyString_AS_STRING(repr);
+ while (size-- > 0) {
+ Py_UNICODE ch = *s++;
+ /* Map 16-bit characters to '\uxxxx' */
+ if (ch >= 256 || ch == '\\' || ch == '\n') {
+ *p++ = '\\';
+ *p++ = 'u';
+ *p++ = hexdigit[(ch >> 12) & 0xf];
+ *p++ = hexdigit[(ch >> 8) & 0xf];
+ *p++ = hexdigit[(ch >> 4) & 0xf];
+ *p++ = hexdigit[ch & 15];
+ }
+ /* Copy everything else as-is */
+ else
+ *p++ = (char) ch;
+ }
+ *p = '\0';
+ _PyString_Resize(&repr, p - q);
+ return repr;
+}
+
+
+static int
+save_unicode(Picklerobject *self, PyObject *args, int doput)
+{
+ Py_ssize_t size, len;
+ PyObject *repr=0;
+
+ if (!PyUnicode_Check(args))
+ return -1;
+
+ if (!self->bin) {
+ char *repr_str;
+ static char string = UNICODE;
+
+ repr = modified_EncodeRawUnicodeEscape(
+ PyUnicode_AS_UNICODE(args), PyUnicode_GET_SIZE(args));
+ if (!repr)
+ return -1;
+
+ if ((len = PyString_Size(repr)) < 0)
+ goto err;
+ repr_str = PyString_AS_STRING((PyStringObject *)repr);
+
+ if (self->write_func(self, &string, 1) < 0)
+ goto err;
+
+ if (self->write_func(self, repr_str, len) < 0)
+ goto err;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto err;
+
+ Py_XDECREF(repr);
+ }
+ else {
+ int i;
+ char c_str[5];
+
+ if (!( repr = PyUnicode_AsUTF8String(args)))
+ return -1;
+
+ if ((size = PyString_Size(repr)) < 0)
+ goto err;
+ if (size > INT_MAX)
+ return -1; /* string too large */
+
+ c_str[0] = BINUNICODE;
+ for (i = 1; i < 5; i++)
+ c_str[i] = (int)(size >> ((i - 1) * 8));
+ len = 5;
+
+ if (self->write_func(self, c_str, len) < 0)
+ goto err;
+
+ if (size > 128 && Pdata_Check(self->file)) {
+ if (write_other(self, NULL, 0) < 0)
+ goto err;
+ PDATA_APPEND(self->file, repr, -1);
+ }
+ else {
+ if (self->write_func(self, PyString_AS_STRING(repr),
+ size) < 0)
+ goto err;
+ }
+
+ Py_DECREF(repr);
+ }
+
+ if (doput)
+ if (put(self, args) < 0)
+ return -1;
+
+ return 0;
+
+ err:
+ Py_XDECREF(repr);
+ return -1;
+}
+#endif
+
+/* A helper for save_tuple. Push the len elements in tuple t on the stack. */
+static int
+store_tuple_elements(Picklerobject *self, PyObject *t, int len)
+{
+ int i;
+ int res = -1; /* guilty until proved innocent */
+
+ assert(PyTuple_Size(t) == len);
+
+ for (i = 0; i < len; i++) {
+ PyObject *element = PyTuple_GET_ITEM(t, i);
+
+ if (element == NULL)
+ goto finally;
+ if (save(self, element, 0) < 0)
+ goto finally;
+ }
+ res = 0;
+
+ finally:
+ return res;
+}
+
+/* Tuples are ubiquitous in the pickle protocols, so many techniques are
+ * used across protocols to minimize the space needed to pickle them.
+ * Tuples are also the only builtin immutable type that can be recursive
+ * (a tuple can be reached from itself), and that requires some subtle
+ * magic so that it works in all cases. IOW, this is a long routine.
+ */
+static int
+save_tuple(Picklerobject *self, PyObject *args)
+{
+ PyObject *py_tuple_id = NULL;
+ int len, i;
+ int res = -1;
+
+ static char tuple = TUPLE;
+ static char pop = POP;
+ static char pop_mark = POP_MARK;
+ static char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
+
+ if ((len = PyTuple_Size(args)) < 0)
+ goto finally;
+
+ if (len == 0) {
+ char c_str[2];
+
+ if (self->proto) {
+ c_str[0] = EMPTY_TUPLE;
+ len = 1;
+ }
+ else {
+ c_str[0] = MARK;
+ c_str[1] = TUPLE;
+ len = 2;
+ }
+ if (self->write_func(self, c_str, len) >= 0)
+ res = 0;
+ /* Don't memoize an empty tuple. */
+ goto finally;
+ }
+
+ /* A non-empty tuple. */
+
+ /* id(tuple) isn't in the memo now. If it shows up there after
+ * saving the tuple elements, the tuple must be recursive, in
+ * which case we'll pop everything we put on the stack, and fetch
+ * its value from the memo.
+ */
+ py_tuple_id = PyLong_FromVoidPtr(args);
+ if (py_tuple_id == NULL)
+ goto finally;
+
+ if (len <= 3 && self->proto >= 2) {
+ /* Use TUPLE{1,2,3} opcodes. */
+ if (store_tuple_elements(self, args, len) < 0)
+ goto finally;
+ if (PyDict_GetItem(self->memo, py_tuple_id)) {
+ /* pop the len elements */
+ for (i = 0; i < len; ++i)
+ if (self->write_func(self, &pop, 1) < 0)
+ goto finally;
+ /* fetch from memo */
+ if (get(self, py_tuple_id) < 0)
+ goto finally;
+ res = 0;
+ goto finally;
+ }
+ /* Not recursive. */
+ if (self->write_func(self, len2opcode + len, 1) < 0)
+ goto finally;
+ goto memoize;
+ }
+
+ /* proto < 2 and len > 0, or proto >= 2 and len > 3.
+ * Generate MARK elt1 elt2 ... TUPLE
+ */
+ if (self->write_func(self, &MARKv, 1) < 0)
+ goto finally;
+
+ if (store_tuple_elements(self, args, len) < 0)
+ goto finally;
+
+ if (PyDict_GetItem(self->memo, py_tuple_id)) {
+ /* pop the stack stuff we pushed */
+ if (self->bin) {
+ if (self->write_func(self, &pop_mark, 1) < 0)
+ goto finally;
+ }
+ else {
+ /* Note that we pop one more than len, to remove
+ * the MARK too.
+ */
+ for (i = 0; i <= len; i++)
+ if (self->write_func(self, &pop, 1) < 0)
+ goto finally;
+ }
+ /* fetch from memo */
+ if (get(self, py_tuple_id) >= 0)
+ res = 0;
+ goto finally;
+ }
+
+ /* Not recursive. */
+ if (self->write_func(self, &tuple, 1) < 0)
+ goto finally;
+
+ memoize:
+ if (put(self, args) >= 0)
+ res = 0;
+
+ finally:
+ Py_XDECREF(py_tuple_id);
+ return res;
+}
+
+/* iter is an iterator giving items, and we batch up chunks of
+ * MARK item item ... item APPENDS
+ * opcode sequences. Calling code should have arranged to first create an
+ * empty list, or list-like object, for the APPENDS to operate on.
+ * Returns 0 on success, <0 on error.
+ */
+static int
+batch_list(Picklerobject *self, PyObject *iter)
+{
+ PyObject *obj;
+ PyObject *slice[BATCHSIZE];
+ int i, n;
+
+ static char append = APPEND;
+ static char appends = APPENDS;
+
+ assert(iter != NULL);
+
+ if (self->proto == 0) {
+ /* APPENDS isn't available; do one at a time. */
+ for (;;) {
+ obj = PyIter_Next(iter);
+ if (obj == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ break;
+ }
+ i = save(self, obj, 0);
+ Py_DECREF(obj);
+ if (i < 0)
+ return -1;
+ if (self->write_func(self, &append, 1) < 0)
+ return -1;
+ }
+ return 0;
+ }
+
+ /* proto > 0: write in batches of BATCHSIZE. */
+ do {
+ /* Get next group of (no more than) BATCHSIZE elements. */
+ for (n = 0; n < BATCHSIZE; ++n) {
+ obj = PyIter_Next(iter);
+ if (obj == NULL) {
+ if (PyErr_Occurred())
+ goto BatchFailed;
+ break;
+ }
+ slice[n] = obj;
+ }
+
+ if (n > 1) {
+ /* Pump out MARK, slice[0:n], APPENDS. */
+ if (self->write_func(self, &MARKv, 1) < 0)
+ goto BatchFailed;
+ for (i = 0; i < n; ++i) {
+ if (save(self, slice[i], 0) < 0)
+ goto BatchFailed;
+ }
+ if (self->write_func(self, &appends, 1) < 0)
+ goto BatchFailed;
+ }
+ else if (n == 1) {
+ if (save(self, slice[0], 0) < 0)
+ goto BatchFailed;
+ if (self->write_func(self, &append, 1) < 0)
+ goto BatchFailed;
+ }
+
+ for (i = 0; i < n; ++i) {
+ Py_DECREF(slice[i]);
+ }
+ } while (n == BATCHSIZE);
+ return 0;
+
+BatchFailed:
+ while (--n >= 0) {
+ Py_DECREF(slice[n]);
+ }
+ return -1;
+}
+
+static int
+save_list(Picklerobject *self, PyObject *args)
+{
+ int res = -1;
+ char s[3];
+ int len;
+ PyObject *iter;
+
+ if (self->fast && !fast_save_enter(self, args))
+ goto finally;
+
+ /* Create an empty list. */
+ if (self->bin) {
+ s[0] = EMPTY_LIST;
+ len = 1;
+ }
+ else {
+ s[0] = MARK;
+ s[1] = LIST;
+ len = 2;
+ }
+
+ if (self->write_func(self, s, len) < 0)
+ goto finally;
+
+ /* Get list length, and bow out early if empty. */
+ if ((len = PyList_Size(args)) < 0)
+ goto finally;
+
+ /* Memoize. */
+ if (len == 0) {
+ if (put(self, args) >= 0)
+ res = 0;
+ goto finally;
+ }
+ if (put2(self, args) < 0)
+ goto finally;
+
+ /* Materialize the list elements. */
+ iter = PyObject_GetIter(args);
+ if (iter == NULL)
+ goto finally;
+ res = batch_list(self, iter);
+ Py_DECREF(iter);
+
+ finally:
+ if (self->fast && !fast_save_leave(self, args))
+ res = -1;
+
+ return res;
+}
+
+
+/* iter is an iterator giving (key, value) pairs, and we batch up chunks of
+ * MARK key value ... key value SETITEMS
+ * opcode sequences. Calling code should have arranged to first create an
+ * empty dict, or dict-like object, for the SETITEMS to operate on.
+ * Returns 0 on success, <0 on error.
+ *
+ * This is very much like batch_list(). The difference between saving
+ * elements directly, and picking apart two-tuples, is so long-winded at
+ * the C level, though, that attempts to combine these routines were too
+ * ugly to bear.
+ */
+static int
+batch_dict(Picklerobject *self, PyObject *iter)
+{
+ PyObject *p;
+ PyObject *slice[BATCHSIZE];
+ int i, n;
+
+ static char setitem = SETITEM;
+ static char setitems = SETITEMS;
+
+ assert(iter != NULL);
+
+ if (self->proto == 0) {
+ /* SETITEMS isn't available; do one at a time. */
+ for (;;) {
+ p = PyIter_Next(iter);
+ if (p == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ break;
+ }
+ if (!PyTuple_Check(p) || PyTuple_Size(p) != 2) {
+ PyErr_SetString(PyExc_TypeError, "dict items "
+ "iterator must return 2-tuples");
+ return -1;
+ }
+ i = save(self, PyTuple_GET_ITEM(p, 0), 0);
+ if (i >= 0)
+ i = save(self, PyTuple_GET_ITEM(p, 1), 0);
+ Py_DECREF(p);
+ if (i < 0)
+ return -1;
+ if (self->write_func(self, &setitem, 1) < 0)
+ return -1;
+ }
+ return 0;
+ }
+
+ /* proto > 0: write in batches of BATCHSIZE. */
+ do {
+ /* Get next group of (no more than) BATCHSIZE elements. */
+ for (n = 0; n < BATCHSIZE; ++n) {
+ p = PyIter_Next(iter);
+ if (p == NULL) {
+ if (PyErr_Occurred())
+ goto BatchFailed;
+ break;
+ }
+ if (!PyTuple_Check(p) || PyTuple_Size(p) != 2) {
+ PyErr_SetString(PyExc_TypeError, "dict items "
+ "iterator must return 2-tuples");
+ goto BatchFailed;
+ }
+ slice[n] = p;
+ }
+
+ if (n > 1) {
+ /* Pump out MARK, slice[0:n], SETITEMS. */
+ if (self->write_func(self, &MARKv, 1) < 0)
+ goto BatchFailed;
+ for (i = 0; i < n; ++i) {
+ p = slice[i];
+ if (save(self, PyTuple_GET_ITEM(p, 0), 0) < 0)
+ goto BatchFailed;
+ if (save(self, PyTuple_GET_ITEM(p, 1), 0) < 0)
+ goto BatchFailed;
+ }
+ if (self->write_func(self, &setitems, 1) < 0)
+ goto BatchFailed;
+ }
+ else if (n == 1) {
+ p = slice[0];
+ if (save(self, PyTuple_GET_ITEM(p, 0), 0) < 0)
+ goto BatchFailed;
+ if (save(self, PyTuple_GET_ITEM(p, 1), 0) < 0)
+ goto BatchFailed;
+ if (self->write_func(self, &setitem, 1) < 0)
+ goto BatchFailed;
+ }
+
+ for (i = 0; i < n; ++i) {
+ Py_DECREF(slice[i]);
+ }
+ } while (n == BATCHSIZE);
+ return 0;
+
+BatchFailed:
+ while (--n >= 0) {
+ Py_DECREF(slice[n]);
+ }
+ return -1;
+}
+
+static int
+save_dict(Picklerobject *self, PyObject *args)
+{
+ int res = -1;
+ char s[3];
+ int len;
+ PyObject *iter;
+
+ if (self->fast && !fast_save_enter(self, args))
+ goto finally;
+
+ /* Create an empty dict. */
+ if (self->bin) {
+ s[0] = EMPTY_DICT;
+ len = 1;
+ }
+ else {
+ s[0] = MARK;
+ s[1] = DICT;
+ len = 2;
+ }
+
+ if (self->write_func(self, s, len) < 0)
+ goto finally;
+
+ /* Get dict size, and bow out early if empty. */
+ if ((len = PyDict_Size(args)) < 0)
+ goto finally;
+
+ if (len == 0) {
+ if (put(self, args) >= 0)
+ res = 0;
+ goto finally;
+ }
+ if (put2(self, args) < 0)
+ goto finally;
+
+ /* Materialize the dict items. */
+ iter = PyObject_CallMethod(args, "iteritems", "()");
+ if (iter == NULL)
+ goto finally;
+ res = batch_dict(self, iter);
+ Py_DECREF(iter);
+
+ finally:
+ if (self->fast && !fast_save_leave(self, args))
+ res = -1;
+
+ return res;
+}
+
+
+static int
+save_inst(Picklerobject *self, PyObject *args)
+{
+ PyObject *class = 0, *module = 0, *name = 0, *state = 0,
+ *getinitargs_func = 0, *getstate_func = 0, *class_args = 0;
+ char *module_str, *name_str;
+ int module_size, name_size, res = -1;
+
+ static char inst = INST, obj = OBJ, build = BUILD;
+
+ if (self->fast && !fast_save_enter(self, args))
+ goto finally;
+
+ if (self->write_func(self, &MARKv, 1) < 0)
+ goto finally;
+
+ if (!( class = PyObject_GetAttr(args, __class___str)))
+ goto finally;
+
+ if (self->bin) {
+ if (save(self, class, 0) < 0)
+ goto finally;
+ }
+
+ if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) {
+ PyObject *element = 0;
+ int i, len;
+
+ if (!( class_args =
+ PyObject_Call(getinitargs_func, empty_tuple, NULL)))
+ goto finally;
+
+ if ((len = PyObject_Size(class_args)) < 0)
+ goto finally;
+
+ for (i = 0; i < len; i++) {
+ if (!( element = PySequence_GetItem(class_args, i)))
+ goto finally;
+
+ if (save(self, element, 0) < 0) {
+ Py_DECREF(element);
+ goto finally;
+ }
+
+ Py_DECREF(element);
+ }
+ }
+ else {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ goto finally;
+ }
+
+ if (!self->bin) {
+ if (!( name = ((PyClassObject *)class)->cl_name )) {
+ PyErr_SetString(PicklingError, "class has no name");
+ goto finally;
+ }
+
+ if (!( module = whichmodule(class, name)))
+ goto finally;
+
+
+ if ((module_size = PyString_Size(module)) < 0 ||
+ (name_size = PyString_Size(name)) < 0)
+ goto finally;
+
+ module_str = PyString_AS_STRING((PyStringObject *)module);
+ name_str = PyString_AS_STRING((PyStringObject *)name);
+
+ if (self->write_func(self, &inst, 1) < 0)
+ goto finally;
+
+ if (self->write_func(self, module_str, module_size) < 0)
+ goto finally;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto finally;
+
+ if (self->write_func(self, name_str, name_size) < 0)
+ goto finally;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto finally;
+ }
+ else if (self->write_func(self, &obj, 1) < 0) {
+ goto finally;
+ }
+
+ if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) {
+ state = PyObject_Call(getstate_func, empty_tuple, NULL);
+ if (!state)
+ goto finally;
+ }
+ else {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ goto finally;
+
+ if (!( state = PyObject_GetAttr(args, __dict___str))) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ goto finally;
+ res = 0;
+ goto finally;
+ }
+ }
+
+ if (!PyDict_Check(state)) {
+ if (put2(self, args) < 0)
+ goto finally;
+ }
+ else {
+ if (put(self, args) < 0)
+ goto finally;
+ }
+
+ if (save(self, state, 0) < 0)
+ goto finally;
+
+ if (self->write_func(self, &build, 1) < 0)
+ goto finally;
+
+ res = 0;
+
+ finally:
+ if (self->fast && !fast_save_leave(self, args))
+ res = -1;
+
+ Py_XDECREF(module);
+ Py_XDECREF(class);
+ Py_XDECREF(state);
+ Py_XDECREF(getinitargs_func);
+ Py_XDECREF(getstate_func);
+ Py_XDECREF(class_args);
+
+ return res;
+}
+
+
+static int
+save_global(Picklerobject *self, PyObject *args, PyObject *name)
+{
+ PyObject *global_name = 0, *module = 0, *mod = 0, *klass = 0;
+ char *name_str, *module_str;
+ int module_size, name_size, res = -1;
+
+ static char global = GLOBAL;
+
+ if (name) {
+ global_name = name;
+ Py_INCREF(global_name);
+ }
+ else {
+ if (!( global_name = PyObject_GetAttr(args, __name___str)))
+ goto finally;
+ }
+
+ if (!( module = whichmodule(args, global_name)))
+ goto finally;
+
+ if ((module_size = PyString_Size(module)) < 0 ||
+ (name_size = PyString_Size(global_name)) < 0)
+ goto finally;
+
+ module_str = PyString_AS_STRING((PyStringObject *)module);
+ name_str = PyString_AS_STRING((PyStringObject *)global_name);
+
+ /* XXX This can be doing a relative import. Clearly it shouldn't,
+ but I don't know how to stop it. :-( */
+ mod = PyImport_ImportModule(module_str);
+ if (mod == NULL) {
+ cPickle_ErrFormat(PicklingError,
+ "Can't pickle %s: import of module %s "
+ "failed",
+ "OS", args, module);
+ goto finally;
+ }
+ klass = PyObject_GetAttrString(mod, name_str);
+ if (klass == NULL) {
+ cPickle_ErrFormat(PicklingError,
+ "Can't pickle %s: attribute lookup %s.%s "
+ "failed",
+ "OSS", args, module, global_name);
+ goto finally;
+ }
+ if (klass != args) {
+ Py_DECREF(klass);
+ cPickle_ErrFormat(PicklingError,
+ "Can't pickle %s: it's not the same object "
+ "as %s.%s",
+ "OSS", args, module, global_name);
+ goto finally;
+ }
+ Py_DECREF(klass);
+
+ if (self->proto >= 2) {
+ /* See whether this is in the extension registry, and if
+ * so generate an EXT opcode.
+ */
+ PyObject *py_code; /* extension code as Python object */
+ long code; /* extension code as C value */
+ char c_str[5];
+ int n;
+
+ PyTuple_SET_ITEM(two_tuple, 0, module);
+ PyTuple_SET_ITEM(two_tuple, 1, global_name);
+ py_code = PyDict_GetItem(extension_registry, two_tuple);
+ if (py_code == NULL)
+ goto gen_global; /* not registered */
+
+ /* Verify py_code has the right type and value. */
+ if (!PyInt_Check(py_code)) {
+ cPickle_ErrFormat(PicklingError, "Can't pickle %s: "
+ "extension code %s isn't an integer",
+ "OO", args, py_code);
+ goto finally;
+ }
+ code = PyInt_AS_LONG(py_code);
+ if (code <= 0 || code > 0x7fffffffL) {
+ cPickle_ErrFormat(PicklingError, "Can't pickle %s: "
+ "extension code %ld is out of range",
+ "Ol", args, code);
+ goto finally;
+ }
+
+ /* Generate an EXT opcode. */
+ if (code <= 0xff) {
+ c_str[0] = EXT1;
+ c_str[1] = (char)code;
+ n = 2;
+ }
+ else if (code <= 0xffff) {
+ c_str[0] = EXT2;
+ c_str[1] = (char)(code & 0xff);
+ c_str[2] = (char)((code >> 8) & 0xff);
+ n = 3;
+ }
+ else {
+ c_str[0] = EXT4;
+ c_str[1] = (char)(code & 0xff);
+ c_str[2] = (char)((code >> 8) & 0xff);
+ c_str[3] = (char)((code >> 16) & 0xff);
+ c_str[4] = (char)((code >> 24) & 0xff);
+ n = 5;
+ }
+
+ if (self->write_func(self, c_str, n) >= 0)
+ res = 0;
+ goto finally; /* and don't memoize */
+ }
+
+ gen_global:
+ if (self->write_func(self, &global, 1) < 0)
+ goto finally;
+
+ if (self->write_func(self, module_str, module_size) < 0)
+ goto finally;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto finally;
+
+ if (self->write_func(self, name_str, name_size) < 0)
+ goto finally;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto finally;
+
+ if (put(self, args) < 0)
+ goto finally;
+
+ res = 0;
+
+ finally:
+ Py_XDECREF(module);
+ Py_XDECREF(global_name);
+ Py_XDECREF(mod);
+
+ return res;
+}
+
+static int
+save_pers(Picklerobject *self, PyObject *args, PyObject *f)
+{
+ PyObject *pid = 0;
+ int size, res = -1;
+
+ static char persid = PERSID, binpersid = BINPERSID;
+
+ Py_INCREF(args);
+ ARG_TUP(self, args);
+ if (self->arg) {
+ pid = PyObject_Call(f, self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ if (! pid) return -1;
+
+ if (pid != Py_None) {
+ if (!self->bin) {
+ if (!PyString_Check(pid)) {
+ PyErr_SetString(PicklingError,
+ "persistent id must be string");
+ goto finally;
+ }
+
+ if (self->write_func(self, &persid, 1) < 0)
+ goto finally;
+
+ if ((size = PyString_Size(pid)) < 0)
+ goto finally;
+
+ if (self->write_func(self,
+ PyString_AS_STRING(
+ (PyStringObject *)pid),
+ size) < 0)
+ goto finally;
+
+ if (self->write_func(self, "\n", 1) < 0)
+ goto finally;
+
+ res = 1;
+ goto finally;
+ }
+ else if (save(self, pid, 1) >= 0) {
+ if (self->write_func(self, &binpersid, 1) < 0)
+ res = -1;
+ else
+ res = 1;
+ }
+
+ goto finally;
+ }
+
+ res = 0;
+
+ finally:
+ Py_XDECREF(pid);
+
+ return res;
+}
+
+/* We're saving ob, and args is the 2-thru-5 tuple returned by the
+ * appropriate __reduce__ method for ob.
+ */
+static int
+save_reduce(Picklerobject *self, PyObject *args, PyObject *ob)
+{
+ PyObject *callable;
+ PyObject *argtup;
+ PyObject *state = NULL;
+ PyObject *listitems = NULL;
+ PyObject *dictitems = NULL;
+
+ int use_newobj = self->proto >= 2;
+
+ static char reduce = REDUCE;
+ static char build = BUILD;
+ static char newobj = NEWOBJ;
+
+ if (! PyArg_UnpackTuple(args, "save_reduce", 2, 5,
+ &callable,
+ &argtup,
+ &state,
+ &listitems,
+ &dictitems))
+ return -1;
+
+ if (!PyTuple_Check(argtup)) {
+ PyErr_SetString(PicklingError,
+ "args from reduce() should be a tuple");
+ return -1;
+ }
+
+ if (state == Py_None)
+ state = NULL;
+ if (listitems == Py_None)
+ listitems = NULL;
+ if (dictitems == Py_None)
+ dictitems = NULL;
+
+ /* Protocol 2 special case: if callable's name is __newobj__, use
+ * NEWOBJ. This consumes a lot of code.
+ */
+ if (use_newobj) {
+ PyObject *temp = PyObject_GetAttr(callable, __name___str);
+
+ if (temp == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return -1;
+ use_newobj = 0;
+ }
+ else {
+ use_newobj = PyString_Check(temp) &&
+ strcmp(PyString_AS_STRING(temp),
+ "__newobj__") == 0;
+ Py_DECREF(temp);
+ }
+ }
+ if (use_newobj) {
+ PyObject *cls;
+ PyObject *newargtup;
+ int n, i;
+
+ /* Sanity checks. */
+ n = PyTuple_Size(argtup);
+ if (n < 1) {
+ PyErr_SetString(PicklingError, "__newobj__ arglist "
+ "is empty");
+ return -1;
+ }
+
+ cls = PyTuple_GET_ITEM(argtup, 0);
+ if (! PyObject_HasAttrString(cls, "__new__")) {
+ PyErr_SetString(PicklingError, "args[0] from "
+ "__newobj__ args has no __new__");
+ return -1;
+ }
+
+ /* XXX How could ob be NULL? */
+ if (ob != NULL) {
+ PyObject *ob_dot_class;
+
+ ob_dot_class = PyObject_GetAttr(ob, __class___str);
+ if (ob_dot_class == NULL) {
+ if (PyErr_ExceptionMatches(
+ PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return -1;
+ }
+ i = ob_dot_class != cls; /* true iff a problem */
+ Py_XDECREF(ob_dot_class);
+ if (i) {
+ PyErr_SetString(PicklingError, "args[0] from "
+ "__newobj__ args has the wrong class");
+ return -1;
+ }
+ }
+
+ /* Save the class and its __new__ arguments. */
+ if (save(self, cls, 0) < 0)
+ return -1;
+
+ newargtup = PyTuple_New(n-1); /* argtup[1:] */
+ if (newargtup == NULL)
+ return -1;
+ for (i = 1; i < n; ++i) {
+ PyObject *temp = PyTuple_GET_ITEM(argtup, i);
+ Py_INCREF(temp);
+ PyTuple_SET_ITEM(newargtup, i-1, temp);
+ }
+ i = save(self, newargtup, 0) < 0;
+ Py_DECREF(newargtup);
+ if (i < 0)
+ return -1;
+
+ /* Add NEWOBJ opcode. */
+ if (self->write_func(self, &newobj, 1) < 0)
+ return -1;
+ }
+ else {
+ /* Not using NEWOBJ. */
+ if (save(self, callable, 0) < 0 ||
+ save(self, argtup, 0) < 0 ||
+ self->write_func(self, &reduce, 1) < 0)
+ return -1;
+ }
+
+ /* Memoize. */
+ /* XXX How can ob be NULL? */
+ if (ob != NULL) {
+ if (state && !PyDict_Check(state)) {
+ if (put2(self, ob) < 0)
+ return -1;
+ }
+ else if (put(self, ob) < 0)
+ return -1;
+ }
+
+
+ if (listitems && batch_list(self, listitems) < 0)
+ return -1;
+
+ if (dictitems && batch_dict(self, dictitems) < 0)
+ return -1;
+
+ if (state) {
+ if (save(self, state, 0) < 0 ||
+ self->write_func(self, &build, 1) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+save(Picklerobject *self, PyObject *args, int pers_save)
+{
+ PyTypeObject *type;
+ PyObject *py_ob_id = 0, *__reduce__ = 0, *t = 0;
+ PyObject *arg_tup;
+ int res = -1;
+ int tmp, size;
+
+ if (self->nesting++ > Py_GetRecursionLimit()){
+ PyErr_SetString(PyExc_RuntimeError,
+ "maximum recursion depth exceeded");
+ goto finally;
+ }
+
+ if (!pers_save && self->pers_func) {
+ if ((tmp = save_pers(self, args, self->pers_func)) != 0) {
+ res = tmp;
+ goto finally;
+ }
+ }
+
+ if (args == Py_None) {
+ res = save_none(self, args);
+ goto finally;
+ }
+
+ type = args->ob_type;
+
+ switch (type->tp_name[0]) {
+ case 'b':
+ if (args == Py_False || args == Py_True) {
+ res = save_bool(self, args);
+ goto finally;
+ }
+ break;
+ case 'i':
+ if (type == &PyInt_Type) {
+ res = save_int(self, args);
+ goto finally;
+ }
+ break;
+
+ case 'l':
+ if (type == &PyLong_Type) {
+ res = save_long(self, args);
+ goto finally;
+ }
+ break;
+
+ case 'f':
+ if (type == &PyFloat_Type) {
+ res = save_float(self, args);
+ goto finally;
+ }
+ break;
+
+ case 't':
+ if (type == &PyTuple_Type && PyTuple_Size(args) == 0) {
+ res = save_tuple(self, args);
+ goto finally;
+ }
+ break;
+
+ case 's':
+ if ((type == &PyString_Type) && (PyString_GET_SIZE(args) < 2)) {
+ res = save_string(self, args, 0);
+ goto finally;
+ }
+
+#ifdef Py_USING_UNICODE
+ case 'u':
+ if ((type == &PyUnicode_Type) && (PyString_GET_SIZE(args) < 2)) {
+ res = save_unicode(self, args, 0);
+ goto finally;
+ }
+#endif
+ }
+
+ if (args->ob_refcnt > 1) {
+ if (!( py_ob_id = PyLong_FromVoidPtr(args)))
+ goto finally;
+
+ if (PyDict_GetItem(self->memo, py_ob_id)) {
+ if (get(self, py_ob_id) < 0)
+ goto finally;
+
+ res = 0;
+ goto finally;
+ }
+ }
+
+ switch (type->tp_name[0]) {
+ case 's':
+ if (type == &PyString_Type) {
+ res = save_string(self, args, 1);
+ goto finally;
+ }
+ break;
+
+#ifdef Py_USING_UNICODE
+ case 'u':
+ if (type == &PyUnicode_Type) {
+ res = save_unicode(self, args, 1);
+ goto finally;
+ }
+ break;
+#endif
+
+ case 't':
+ if (type == &PyTuple_Type) {
+ res = save_tuple(self, args);
+ goto finally;
+ }
+ if (type == &PyType_Type) {
+ res = save_global(self, args, NULL);
+ goto finally;
+ }
+ break;
+
+ case 'l':
+ if (type == &PyList_Type) {
+ res = save_list(self, args);
+ goto finally;
+ }
+ break;
+
+ case 'd':
+ if (type == &PyDict_Type) {
+ res = save_dict(self, args);
+ goto finally;
+ }
+ break;
+
+ case 'i':
+ if (type == &PyInstance_Type) {
+ res = save_inst(self, args);
+ goto finally;
+ }
+ break;
+
+ case 'c':
+ if (type == &PyClass_Type) {
+ res = save_global(self, args, NULL);
+ goto finally;
+ }
+ break;
+
+ case 'f':
+ if (type == &PyFunction_Type) {
+ res = save_global(self, args, NULL);
+ if (res && PyErr_ExceptionMatches(PickleError)) {
+ /* fall back to reduce */
+ PyErr_Clear();
+ break;
+ }
+ goto finally;
+ }
+ break;
+
+ case 'b':
+ if (type == &PyCFunction_Type) {
+ res = save_global(self, args, NULL);
+ goto finally;
+ }
+ }
+
+ if (!pers_save && self->inst_pers_func) {
+ if ((tmp = save_pers(self, args, self->inst_pers_func)) != 0) {
+ res = tmp;
+ goto finally;
+ }
+ }
+
+ if (PyType_IsSubtype(type, &PyType_Type)) {
+ res = save_global(self, args, NULL);
+ goto finally;
+ }
+
+ /* Get a reduction callable, and call it. This may come from
+ * copy_reg.dispatch_table, the object's __reduce_ex__ method,
+ * or the object's __reduce__ method.
+ */
+ __reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type);
+ if (__reduce__ != NULL) {
+ Py_INCREF(__reduce__);
+ Py_INCREF(args);
+ ARG_TUP(self, args);
+ if (self->arg) {
+ t = PyObject_Call(__reduce__, self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ }
+ else {
+ /* Check for a __reduce_ex__ method. */
+ __reduce__ = PyObject_GetAttr(args, __reduce_ex___str);
+ if (__reduce__ != NULL) {
+ t = PyInt_FromLong(self->proto);
+ if (t != NULL) {
+ ARG_TUP(self, t);
+ t = NULL;
+ if (self->arg) {
+ t = PyObject_Call(__reduce__,
+ self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ }
+ }
+ else {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ goto finally;
+ /* Check for a __reduce__ method. */
+ __reduce__ = PyObject_GetAttr(args, __reduce___str);
+ if (__reduce__ != NULL) {
+ t = PyObject_Call(__reduce__,
+ empty_tuple, NULL);
+ }
+ else {
+ PyErr_SetObject(UnpickleableError, args);
+ goto finally;
+ }
+ }
+ }
+
+ if (t == NULL)
+ goto finally;
+
+ if (PyString_Check(t)) {
+ res = save_global(self, args, t);
+ goto finally;
+ }
+
+ if (! PyTuple_Check(t)) {
+ cPickle_ErrFormat(PicklingError, "Value returned by "
+ "%s must be string or tuple",
+ "O", __reduce__);
+ goto finally;
+ }
+
+ size = PyTuple_Size(t);
+ if (size < 2 || size > 5) {
+ cPickle_ErrFormat(PicklingError, "tuple returned by "
+ "%s must contain 2 through 5 elements",
+ "O", __reduce__);
+ goto finally;
+ }
+
+ arg_tup = PyTuple_GET_ITEM(t, 1);
+ if (!(PyTuple_Check(arg_tup) || arg_tup == Py_None)) {
+ cPickle_ErrFormat(PicklingError, "Second element of "
+ "tuple returned by %s must be a tuple",
+ "O", __reduce__);
+ goto finally;
+ }
+
+ res = save_reduce(self, t, args);
+
+ finally:
+ self->nesting--;
+ Py_XDECREF(py_ob_id);
+ Py_XDECREF(__reduce__);
+ Py_XDECREF(t);
+
+ return res;
+}
+
+
+static int
+dump(Picklerobject *self, PyObject *args)
+{
+ static char stop = STOP;
+
+ if (self->proto >= 2) {
+ char bytes[2];
+
+ bytes[0] = PROTO;
+ assert(self->proto >= 0 && self->proto < 256);
+ bytes[1] = (char)self->proto;
+ if (self->write_func(self, bytes, 2) < 0)
+ return -1;
+ }
+
+ if (save(self, args, 0) < 0)
+ return -1;
+
+ if (self->write_func(self, &stop, 1) < 0)
+ return -1;
+
+ if (self->write_func(self, NULL, 0) < 0)
+ return -1;
+
+ return 0;
+}
+
+static PyObject *
+Pickle_clear_memo(Picklerobject *self, PyObject *args)
+{
+ if (self->memo)
+ PyDict_Clear(self->memo);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Pickle_getvalue(Picklerobject *self, PyObject *args)
+{
+ int l, i, rsize, ssize, clear=1, lm;
+ long ik;
+ PyObject *k, *r;
+ char *s, *p, *have_get;
+ Pdata *data;
+
+ /* Can be called by Python code or C code */
+ if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear))
+ return NULL;
+
+ /* Check to make sure we are based on a list */
+ if (! Pdata_Check(self->file)) {
+ PyErr_SetString(PicklingError,
+ "Attempt to getvalue() a non-list-based pickler");
+ return NULL;
+ }
+
+ /* flush write buffer */
+ if (write_other(self, NULL, 0) < 0) return NULL;
+
+ data=(Pdata*)self->file;
+ l=data->length;
+
+ /* set up an array to hold get/put status */
+ lm = PyDict_Size(self->memo);
+ if (lm < 0) return NULL;
+ lm++;
+ have_get = malloc(lm);
+ if (have_get == NULL) return PyErr_NoMemory();
+ memset(have_get, 0, lm);
+
+ /* Scan for gets. */
+ for (rsize = 0, i = l; --i >= 0; ) {
+ k = data->data[i];
+
+ if (PyString_Check(k))
+ rsize += PyString_GET_SIZE(k);
+
+ else if (PyInt_Check(k)) { /* put */
+ ik = PyInt_AS_LONG((PyIntObject*)k);
+ if (ik >= lm || ik == 0) {
+ PyErr_SetString(PicklingError,
+ "Invalid get data");
+ goto err;
+ }
+ if (have_get[ik]) /* with matching get */
+ rsize += ik < 256 ? 2 : 5;
+ }
+
+ else if (! (PyTuple_Check(k) &&
+ PyTuple_GET_SIZE(k) == 2 &&
+ PyInt_Check((k = PyTuple_GET_ITEM(k, 0))))
+ ) {
+ PyErr_SetString(PicklingError,
+ "Unexpected data in internal list");
+ goto err;
+ }
+
+ else { /* put */
+ ik = PyInt_AS_LONG((PyIntObject *)k);
+ if (ik >= lm || ik == 0) {
+ PyErr_SetString(PicklingError,
+ "Invalid get data");
+ return NULL;
+ }
+ have_get[ik] = 1;
+ rsize += ik < 256 ? 2 : 5;
+ }
+ }
+
+ /* Now generate the result */
+ r = PyString_FromStringAndSize(NULL, rsize);
+ if (r == NULL) goto err;
+ s = PyString_AS_STRING((PyStringObject *)r);
+
+ for (i = 0; i < l; i++) {
+ k = data->data[i];
+
+ if (PyString_Check(k)) {
+ ssize = PyString_GET_SIZE(k);
+ if (ssize) {
+ p=PyString_AS_STRING((PyStringObject *)k);
+ while (--ssize >= 0)
+ *s++ = *p++;
+ }
+ }
+
+ else if (PyTuple_Check(k)) { /* get */
+ ik = PyInt_AS_LONG((PyIntObject *)
+ PyTuple_GET_ITEM(k, 0));
+ if (ik < 256) {
+ *s++ = BINGET;
+ *s++ = (int)(ik & 0xff);
+ }
+ else {
+ *s++ = LONG_BINGET;
+ *s++ = (int)(ik & 0xff);
+ *s++ = (int)((ik >> 8) & 0xff);
+ *s++ = (int)((ik >> 16) & 0xff);
+ *s++ = (int)((ik >> 24) & 0xff);
+ }
+ }
+
+ else { /* put */
+ ik = PyInt_AS_LONG((PyIntObject*)k);
+
+ if (have_get[ik]) { /* with matching get */
+ if (ik < 256) {
+ *s++ = BINPUT;
+ *s++ = (int)(ik & 0xff);
+ }
+ else {
+ *s++ = LONG_BINPUT;
+ *s++ = (int)(ik & 0xff);
+ *s++ = (int)((ik >> 8) & 0xff);
+ *s++ = (int)((ik >> 16) & 0xff);
+ *s++ = (int)((ik >> 24) & 0xff);
+ }
+ }
+ }
+ }
+
+ if (clear) {
+ PyDict_Clear(self->memo);
+ Pdata_clear(data, 0);
+ }
+
+ free(have_get);
+ return r;
+ err:
+ free(have_get);
+ return NULL;
+}
+
+static PyObject *
+Pickler_dump(Picklerobject *self, PyObject *args)
+{
+ PyObject *ob;
+ int get=0;
+
+ if (!( PyArg_ParseTuple(args, "O|i:dump", &ob, &get)))
+ return NULL;
+
+ if (dump(self, ob) < 0)
+ return NULL;
+
+ if (get) return Pickle_getvalue(self, NULL);
+
+ /* XXX Why does dump() return self? */
+ Py_INCREF(self);
+ return (PyObject*)self;
+}
+
+
+static struct PyMethodDef Pickler_methods[] =
+{
+ {"dump", (PyCFunction)Pickler_dump, METH_VARARGS,
+ PyDoc_STR("dump(object) -- "
+ "Write an object in pickle format to the object's pickle stream")},
+ {"clear_memo", (PyCFunction)Pickle_clear_memo, METH_NOARGS,
+ PyDoc_STR("clear_memo() -- Clear the picklers memo")},
+ {"getvalue", (PyCFunction)Pickle_getvalue, METH_VARARGS,
+ PyDoc_STR("getvalue() -- Finish picking a list-based pickle")},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static Picklerobject *
+newPicklerobject(PyObject *file, int proto)
+{
+ Picklerobject *self;
+
+ if (proto < 0)
+ proto = HIGHEST_PROTOCOL;
+ if (proto > HIGHEST_PROTOCOL) {
+ PyErr_Format(PyExc_ValueError, "pickle protocol %d asked for; "
+ "the highest available protocol is %d",
+ proto, HIGHEST_PROTOCOL);
+ return NULL;
+ }
+
+ self = PyObject_GC_New(Picklerobject, &Picklertype);
+ if (self == NULL)
+ return NULL;
+ self->proto = proto;
+ self->bin = proto > 0;
+ self->fp = NULL;
+ self->write = NULL;
+ self->memo = NULL;
+ self->arg = NULL;
+ self->pers_func = NULL;
+ self->inst_pers_func = NULL;
+ self->write_buf = NULL;
+ self->fast = 0;
+ self->nesting = 0;
+ self->fast_container = 0;
+ self->fast_memo = NULL;
+ self->buf_size = 0;
+ self->dispatch_table = NULL;
+
+ self->file = NULL;
+ if (file)
+ Py_INCREF(file);
+ else {
+ file = Pdata_New();
+ if (file == NULL)
+ goto err;
+ }
+ self->file = file;
+
+ if (!( self->memo = PyDict_New()))
+ goto err;
+
+ if (PyFile_Check(file)) {
+ self->fp = PyFile_AsFile(file);
+ if (self->fp == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto err;
+ }
+ self->write_func = write_file;
+ }
+ else if (PycStringIO_OutputCheck(file)) {
+ self->write_func = write_cStringIO;
+ }
+ else if (file == Py_None) {
+ self->write_func = write_none;
+ }
+ else {
+ self->write_func = write_other;
+
+ if (! Pdata_Check(file)) {
+ self->write = PyObject_GetAttr(file, write_str);
+ if (!self->write) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "argument must have 'write' "
+ "attribute");
+ goto err;
+ }
+ }
+
+ self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE);
+ if (self->write_buf == NULL) {
+ PyErr_NoMemory();
+ goto err;
+ }
+ }
+
+ if (PyEval_GetRestricted()) {
+ /* Restricted execution, get private tables */
+ PyObject *m = PyImport_Import(copy_reg_str);
+
+ if (m == NULL)
+ goto err;
+ self->dispatch_table = PyObject_GetAttr(m, dispatch_table_str);
+ Py_DECREF(m);
+ if (self->dispatch_table == NULL)
+ goto err;
+ }
+ else {
+ self->dispatch_table = dispatch_table;
+ Py_INCREF(dispatch_table);
+ }
+ PyObject_GC_Track(self);
+
+ return self;
+
+ err:
+ Py_DECREF(self);
+ return NULL;
+}
+
+
+static PyObject *
+get_Pickler(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"file", "protocol", NULL};
+ PyObject *file = NULL;
+ int proto = 0;
+
+ /* XXX
+ * The documented signature is Pickler(file, protocol=0), but this
+ * accepts Pickler() and Pickler(integer) too. The meaning then
+ * is clear as mud, undocumented, and not supported by pickle.py.
+ * I'm told Zope uses this, but I haven't traced into this code
+ * far enough to figure out what it means.
+ */
+ if (!PyArg_ParseTuple(args, "|i:Pickler", &proto)) {
+ PyErr_Clear();
+ proto = 0;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:Pickler",
+ kwlist, &file, &proto))
+ return NULL;
+ }
+ return (PyObject *)newPicklerobject(file, proto);
+}
+
+
+static void
+Pickler_dealloc(Picklerobject *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->write);
+ Py_XDECREF(self->memo);
+ Py_XDECREF(self->fast_memo);
+ Py_XDECREF(self->arg);
+ Py_XDECREF(self->file);
+ Py_XDECREF(self->pers_func);
+ Py_XDECREF(self->inst_pers_func);
+ Py_XDECREF(self->dispatch_table);
+ PyMem_Free(self->write_buf);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+Pickler_traverse(Picklerobject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->write);
+ Py_VISIT(self->memo);
+ Py_VISIT(self->fast_memo);
+ Py_VISIT(self->arg);
+ Py_VISIT(self->file);
+ Py_VISIT(self->pers_func);
+ Py_VISIT(self->inst_pers_func);
+ Py_VISIT(self->dispatch_table);
+ return 0;
+}
+
+static int
+Pickler_clear(Picklerobject *self)
+{
+ Py_CLEAR(self->write);
+ Py_CLEAR(self->memo);
+ Py_CLEAR(self->fast_memo);
+ Py_CLEAR(self->arg);
+ Py_CLEAR(self->file);
+ Py_CLEAR(self->pers_func);
+ Py_CLEAR(self->inst_pers_func);
+ Py_CLEAR(self->dispatch_table);
+ return 0;
+}
+
+static PyObject *
+Pickler_get_pers_func(Picklerobject *p)
+{
+ if (p->pers_func == NULL)
+ PyErr_SetString(PyExc_AttributeError, "persistent_id");
+ else
+ Py_INCREF(p->pers_func);
+ return p->pers_func;
+}
+
+static int
+Pickler_set_pers_func(Picklerobject *p, PyObject *v)
+{
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "attribute deletion is not supported");
+ return -1;
+ }
+ Py_XDECREF(p->pers_func);
+ Py_INCREF(v);
+ p->pers_func = v;
+ return 0;
+}
+
+static int
+Pickler_set_inst_pers_func(Picklerobject *p, PyObject *v)
+{
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "attribute deletion is not supported");
+ return -1;
+ }
+ Py_XDECREF(p->inst_pers_func);
+ Py_INCREF(v);
+ p->inst_pers_func = v;
+ return 0;
+}
+
+static PyObject *
+Pickler_get_memo(Picklerobject *p)
+{
+ if (p->memo == NULL)
+ PyErr_SetString(PyExc_AttributeError, "memo");
+ else
+ Py_INCREF(p->memo);
+ return p->memo;
+}
+
+static int
+Pickler_set_memo(Picklerobject *p, PyObject *v)
+{
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "attribute deletion is not supported");
+ return -1;
+ }
+ if (!PyDict_Check(v)) {
+ PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
+ return -1;
+ }
+ Py_XDECREF(p->memo);
+ Py_INCREF(v);
+ p->memo = v;
+ return 0;
+}
+
+static PyObject *
+Pickler_get_error(Picklerobject *p)
+{
+ /* why is this an attribute on the Pickler? */
+ Py_INCREF(PicklingError);
+ return PicklingError;
+}
+
+static PyMemberDef Pickler_members[] = {
+ {"binary", T_INT, offsetof(Picklerobject, bin)},
+ {"fast", T_INT, offsetof(Picklerobject, fast)},
+ {NULL}
+};
+
+static PyGetSetDef Pickler_getsets[] = {
+ {"persistent_id", (getter)Pickler_get_pers_func,
+ (setter)Pickler_set_pers_func},
+ {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func},
+ {"memo", (getter)Pickler_get_memo, (setter)Pickler_set_memo},
+ {"PicklingError", (getter)Pickler_get_error, NULL},
+ {NULL}
+};
+
+PyDoc_STRVAR(Picklertype__doc__,
+"Objects that know how to pickle objects\n");
+
+static PyTypeObject Picklertype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "cPickle.Pickler", /*tp_name*/
+ sizeof(Picklerobject), /*tp_basicsize*/
+ 0,
+ (destructor)Pickler_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ Picklertype__doc__, /* tp_doc */
+ (traverseproc)Pickler_traverse, /* tp_traverse */
+ (inquiry)Pickler_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Pickler_methods, /* tp_methods */
+ Pickler_members, /* tp_members */
+ Pickler_getsets, /* tp_getset */
+};
+
+static PyObject *
+find_class(PyObject *py_module_name, PyObject *py_global_name, PyObject *fc)
+{
+ PyObject *global = 0, *module;
+
+ if (fc) {
+ if (fc==Py_None) {
+ PyErr_SetString(UnpicklingError, "Global and instance "
+ "pickles are not supported.");
+ return NULL;
+ }
+ return PyObject_CallFunctionObjArgs(fc, py_module_name,
+ py_global_name, NULL);
+ }
+
+ module = PySys_GetObject("modules");
+ if (module == NULL)
+ return NULL;
+
+ module = PyDict_GetItem(module, py_module_name);
+ if (module == NULL) {
+ module = PyImport_Import(py_module_name);
+ if (!module)
+ return NULL;
+ global = PyObject_GetAttr(module, py_global_name);
+ Py_DECREF(module);
+ }
+ else
+ global = PyObject_GetAttr(module, py_global_name);
+ return global;
+}
+
+static int
+marker(Unpicklerobject *self)
+{
+ if (self->num_marks < 1) {
+ PyErr_SetString(UnpicklingError, "could not find MARK");
+ return -1;
+ }
+
+ return self->marks[--self->num_marks];
+}
+
+
+static int
+load_none(Unpicklerobject *self)
+{
+ PDATA_APPEND(self->stack, Py_None, -1);
+ return 0;
+}
+
+static int
+bad_readline(void)
+{
+ PyErr_SetString(UnpicklingError, "pickle data was truncated");
+ return -1;
+}
+
+static int
+load_int(Unpicklerobject *self)
+{
+ PyObject *py_int = 0;
+ char *endptr, *s;
+ int len, res = -1;
+ long l;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+ if (!( s=pystrndup(s,len))) return -1;
+
+ errno = 0;
+ l = strtol(s, &endptr, 0);
+
+ if (errno || (*endptr != '\n') || (endptr[1] != '\0')) {
+ /* Hm, maybe we've got something long. Let's try reading
+ it as a Python long object. */
+ errno = 0;
+ py_int = PyLong_FromString(s, NULL, 0);
+ if (py_int == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "could not convert string to int");
+ goto finally;
+ }
+ }
+ else {
+ if (len == 3 && (l == 0 || l == 1)) {
+ if (!( py_int = PyBool_FromLong(l))) goto finally;
+ }
+ else {
+ if (!( py_int = PyInt_FromLong(l))) goto finally;
+ }
+ }
+
+ free(s);
+ PDATA_PUSH(self->stack, py_int, -1);
+ return 0;
+
+ finally:
+ free(s);
+
+ return res;
+}
+
+static int
+load_bool(Unpicklerobject *self, PyObject *boolean)
+{
+ assert(boolean == Py_True || boolean == Py_False);
+ PDATA_APPEND(self->stack, boolean, -1);
+ return 0;
+}
+
+/* s contains x bytes of a little-endian integer. Return its value as a
+ * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian
+ * int, but when x is 4 it's a signed one. This is an historical source
+ * of x-platform bugs.
+ */
+static long
+calc_binint(char *s, int x)
+{
+ unsigned char c;
+ int i;
+ long l;
+
+ for (i = 0, l = 0L; i < x; i++) {
+ c = (unsigned char)s[i];
+ l |= (long)c << (i * 8);
+ }
+#if SIZEOF_LONG > 4
+ /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
+ * is signed, so on a box with longs bigger than 4 bytes we need
+ * to extend a BININT's sign bit to the full width.
+ */
+ if (x == 4 && l & (1L << 31))
+ l |= (~0L) << 32;
+#endif
+ return l;
+}
+
+
+static int
+load_binintx(Unpicklerobject *self, char *s, int x)
+{
+ PyObject *py_int = 0;
+ long l;
+
+ l = calc_binint(s, x);
+
+ if (!( py_int = PyInt_FromLong(l)))
+ return -1;
+
+ PDATA_PUSH(self->stack, py_int, -1);
+ return 0;
+}
+
+
+static int
+load_binint(Unpicklerobject *self)
+{
+ char *s;
+
+ if (self->read_func(self, &s, 4) < 0)
+ return -1;
+
+ return load_binintx(self, s, 4);
+}
+
+
+static int
+load_binint1(Unpicklerobject *self)
+{
+ char *s;
+
+ if (self->read_func(self, &s, 1) < 0)
+ return -1;
+
+ return load_binintx(self, s, 1);
+}
+
+
+static int
+load_binint2(Unpicklerobject *self)
+{
+ char *s;
+
+ if (self->read_func(self, &s, 2) < 0)
+ return -1;
+
+ return load_binintx(self, s, 2);
+}
+
+static int
+load_long(Unpicklerobject *self)
+{
+ PyObject *l = 0;
+ char *end, *s;
+ int len, res = -1;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+ if (!( s=pystrndup(s,len))) return -1;
+
+ if (!( l = PyLong_FromString(s, &end, 0)))
+ goto finally;
+
+ free(s);
+ PDATA_PUSH(self->stack, l, -1);
+ return 0;
+
+ finally:
+ free(s);
+
+ return res;
+}
+
+/* 'size' bytes contain the # of bytes of little-endian 256's-complement
+ * data following.
+ */
+static int
+load_counted_long(Unpicklerobject *self, int size)
+{
+ Py_ssize_t i;
+ char *nbytes;
+ unsigned char *pdata;
+ PyObject *along;
+
+ assert(size == 1 || size == 4);
+ i = self->read_func(self, &nbytes, size);
+ if (i < 0) return -1;
+
+ size = calc_binint(nbytes, size);
+ if (size < 0) {
+ /* Corrupt or hostile pickle -- we never write one like
+ * this.
+ */
+ PyErr_SetString(UnpicklingError, "LONG pickle has negative "
+ "byte count");
+ return -1;
+ }
+
+ if (size == 0)
+ along = PyLong_FromLong(0L);
+ else {
+ /* Read the raw little-endian bytes & convert. */
+ i = self->read_func(self, (char **)&pdata, size);
+ if (i < 0) return -1;
+ along = _PyLong_FromByteArray(pdata, (size_t)size,
+ 1 /* little endian */, 1 /* signed */);
+ }
+ if (along == NULL)
+ return -1;
+ PDATA_PUSH(self->stack, along, -1);
+ return 0;
+}
+
+static int
+load_float(Unpicklerobject *self)
+{
+ PyObject *py_float = 0;
+ char *endptr, *s;
+ int len, res = -1;
+ double d;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+ if (!( s=pystrndup(s,len))) return -1;
+
+ errno = 0;
+ d = PyOS_ascii_strtod(s, &endptr);
+
+ if (errno || (endptr[0] != '\n') || (endptr[1] != '\0')) {
+ PyErr_SetString(PyExc_ValueError,
+ "could not convert string to float");
+ goto finally;
+ }
+
+ if (!( py_float = PyFloat_FromDouble(d)))
+ goto finally;
+
+ free(s);
+ PDATA_PUSH(self->stack, py_float, -1);
+ return 0;
+
+ finally:
+ free(s);
+
+ return res;
+}
+
+static int
+load_binfloat(Unpicklerobject *self)
+{
+ PyObject *py_float;
+ double x;
+ char *p;
+
+ if (self->read_func(self, &p, 8) < 0)
+ return -1;
+
+ x = _PyFloat_Unpack8((unsigned char *)p, 0);
+ if (x == -1.0 && PyErr_Occurred())
+ return -1;
+
+ py_float = PyFloat_FromDouble(x);
+ if (py_float == NULL)
+ return -1;
+
+ PDATA_PUSH(self->stack, py_float, -1);
+ return 0;
+}
+
+static int
+load_string(Unpicklerobject *self)
+{
+ PyObject *str = 0;
+ int len, res = -1;
+ char *s, *p;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+ if (!( s=pystrndup(s,len))) return -1;
+
+
+ /* Strip outermost quotes */
+ while (s[len-1] <= ' ')
+ len--;
+ if(s[0]=='"' && s[len-1]=='"'){
+ s[len-1] = '\0';
+ p = s + 1 ;
+ len -= 2;
+ } else if(s[0]=='\'' && s[len-1]=='\''){
+ s[len-1] = '\0';
+ p = s + 1 ;
+ len -= 2;
+ } else
+ goto insecure;
+ /********************************************/
+
+ str = PyString_DecodeEscape(p, len, NULL, 0, NULL);
+ free(s);
+ if (str) {
+ PDATA_PUSH(self->stack, str, -1);
+ res = 0;
+ }
+ return res;
+
+ insecure:
+ free(s);
+ PyErr_SetString(PyExc_ValueError,"insecure string pickle");
+ return -1;
+}
+
+
+static int
+load_binstring(Unpicklerobject *self)
+{
+ PyObject *py_string = 0;
+ long l;
+ char *s;
+
+ if (self->read_func(self, &s, 4) < 0) return -1;
+
+ l = calc_binint(s, 4);
+
+ if (self->read_func(self, &s, l) < 0)
+ return -1;
+
+ if (!( py_string = PyString_FromStringAndSize(s, l)))
+ return -1;
+
+ PDATA_PUSH(self->stack, py_string, -1);
+ return 0;
+}
+
+
+static int
+load_short_binstring(Unpicklerobject *self)
+{
+ PyObject *py_string = 0;
+ unsigned char l;
+ char *s;
+
+ if (self->read_func(self, &s, 1) < 0)
+ return -1;
+
+ l = (unsigned char)s[0];
+
+ if (self->read_func(self, &s, l) < 0) return -1;
+
+ if (!( py_string = PyString_FromStringAndSize(s, l))) return -1;
+
+ PDATA_PUSH(self->stack, py_string, -1);
+ return 0;
+}
+
+
+#ifdef Py_USING_UNICODE
+static int
+load_unicode(Unpicklerobject *self)
+{
+ PyObject *str = 0;
+ int len, res = -1;
+ char *s;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 1) return bad_readline();
+
+ if (!( str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL)))
+ goto finally;
+
+ PDATA_PUSH(self->stack, str, -1);
+ return 0;
+
+ finally:
+ return res;
+}
+#endif
+
+
+#ifdef Py_USING_UNICODE
+static int
+load_binunicode(Unpicklerobject *self)
+{
+ PyObject *unicode;
+ long l;
+ char *s;
+
+ if (self->read_func(self, &s, 4) < 0) return -1;
+
+ l = calc_binint(s, 4);
+
+ if (self->read_func(self, &s, l) < 0)
+ return -1;
+
+ if (!( unicode = PyUnicode_DecodeUTF8(s, l, NULL)))
+ return -1;
+
+ PDATA_PUSH(self->stack, unicode, -1);
+ return 0;
+}
+#endif
+
+
+static int
+load_tuple(Unpicklerobject *self)
+{
+ PyObject *tup;
+ int i;
+
+ if ((i = marker(self)) < 0) return -1;
+ if (!( tup=Pdata_popTuple(self->stack, i))) return -1;
+ PDATA_PUSH(self->stack, tup, -1);
+ return 0;
+}
+
+static int
+load_counted_tuple(Unpicklerobject *self, int len)
+{
+ PyObject *tup = PyTuple_New(len);
+
+ if (tup == NULL)
+ return -1;
+
+ while (--len >= 0) {
+ PyObject *element;
+
+ PDATA_POP(self->stack, element);
+ if (element == NULL)
+ return -1;
+ PyTuple_SET_ITEM(tup, len, element);
+ }
+ PDATA_PUSH(self->stack, tup, -1);
+ return 0;
+}
+
+static int
+load_empty_list(Unpicklerobject *self)
+{
+ PyObject *list;
+
+ if (!( list=PyList_New(0))) return -1;
+ PDATA_PUSH(self->stack, list, -1);
+ return 0;
+}
+
+static int
+load_empty_dict(Unpicklerobject *self)
+{
+ PyObject *dict;
+
+ if (!( dict=PyDict_New())) return -1;
+ PDATA_PUSH(self->stack, dict, -1);
+ return 0;
+}
+
+
+static int
+load_list(Unpicklerobject *self)
+{
+ PyObject *list = 0;
+ int i;
+
+ if ((i = marker(self)) < 0) return -1;
+ if (!( list=Pdata_popList(self->stack, i))) return -1;
+ PDATA_PUSH(self->stack, list, -1);
+ return 0;
+}
+
+static int
+load_dict(Unpicklerobject *self)
+{
+ PyObject *dict, *key, *value;
+ int i, j, k;
+
+ if ((i = marker(self)) < 0) return -1;
+ j=self->stack->length;
+
+ if (!( dict = PyDict_New())) return -1;
+
+ for (k = i+1; k < j; k += 2) {
+ key =self->stack->data[k-1];
+ value=self->stack->data[k ];
+ if (PyDict_SetItem(dict, key, value) < 0) {
+ Py_DECREF(dict);
+ return -1;
+ }
+ }
+ Pdata_clear(self->stack, i);
+ PDATA_PUSH(self->stack, dict, -1);
+ return 0;
+}
+
+static PyObject *
+Instance_New(PyObject *cls, PyObject *args)
+{
+ PyObject *r = 0;
+
+ if (PyClass_Check(cls)) {
+ int l;
+
+ if ((l=PyObject_Size(args)) < 0) goto err;
+ if (!( l )) {
+ PyObject *__getinitargs__;
+
+ __getinitargs__ = PyObject_GetAttr(cls,
+ __getinitargs___str);
+ if (!__getinitargs__) {
+ /* We have a class with no __getinitargs__,
+ so bypass usual construction */
+ PyObject *inst;
+
+ PyErr_Clear();
+ if (!( inst=PyInstance_NewRaw(cls, NULL)))
+ goto err;
+ return inst;
+ }
+ Py_DECREF(__getinitargs__);
+ }
+
+ if ((r=PyInstance_New(cls, args, NULL))) return r;
+ else goto err;
+ }
+
+ if ((r=PyObject_CallObject(cls, args))) return r;
+
+ err:
+ {
+ PyObject *tp, *v, *tb, *tmp_value;
+
+ PyErr_Fetch(&tp, &v, &tb);
+ tmp_value = v;
+ /* NULL occurs when there was a KeyboardInterrupt */
+ if (tmp_value == NULL)
+ tmp_value = Py_None;
+ if ((r = PyTuple_Pack(3, tmp_value, cls, args))) {
+ Py_XDECREF(v);
+ v=r;
+ }
+ PyErr_Restore(tp,v,tb);
+ }
+ return NULL;
+}
+
+
+static int
+load_obj(Unpicklerobject *self)
+{
+ PyObject *class, *tup, *obj=0;
+ int i;
+
+ if ((i = marker(self)) < 0) return -1;
+ if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1;
+ PDATA_POP(self->stack, class);
+ if (class) {
+ obj = Instance_New(class, tup);
+ Py_DECREF(class);
+ }
+ Py_DECREF(tup);
+
+ if (! obj) return -1;
+ PDATA_PUSH(self->stack, obj, -1);
+ return 0;
+}
+
+
+static int
+load_inst(Unpicklerobject *self)
+{
+ PyObject *tup, *class=0, *obj=0, *module_name, *class_name;
+ int i, len;
+ char *s;
+
+ if ((i = marker(self)) < 0) return -1;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+ module_name = PyString_FromStringAndSize(s, len - 1);
+ if (!module_name) return -1;
+
+ if ((len = self->readline_func(self, &s)) >= 0) {
+ if (len < 2) return bad_readline();
+ if ((class_name = PyString_FromStringAndSize(s, len - 1))) {
+ class = find_class(module_name, class_name,
+ self->find_class);
+ Py_DECREF(class_name);
+ }
+ }
+ Py_DECREF(module_name);
+
+ if (! class) return -1;
+
+ if ((tup=Pdata_popTuple(self->stack, i))) {
+ obj = Instance_New(class, tup);
+ Py_DECREF(tup);
+ }
+ Py_DECREF(class);
+
+ if (! obj) return -1;
+
+ PDATA_PUSH(self->stack, obj, -1);
+ return 0;
+}
+
+static int
+load_newobj(Unpicklerobject *self)
+{
+ PyObject *args = NULL;
+ PyObject *clsraw = NULL;
+ PyTypeObject *cls; /* clsraw cast to its true type */
+ PyObject *obj;
+
+ /* Stack is ... cls argtuple, and we want to call
+ * cls.__new__(cls, *argtuple).
+ */
+ PDATA_POP(self->stack, args);
+ if (args == NULL) goto Fail;
+ if (! PyTuple_Check(args)) {
+ PyErr_SetString(UnpicklingError, "NEWOBJ expected an arg "
+ "tuple.");
+ goto Fail;
+ }
+
+ PDATA_POP(self->stack, clsraw);
+ cls = (PyTypeObject *)clsraw;
+ if (cls == NULL) goto Fail;
+ if (! PyType_Check(cls)) {
+ PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
+ "isn't a type object");
+ goto Fail;
+ }
+ if (cls->tp_new == NULL) {
+ PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
+ "has NULL tp_new");
+ goto Fail;
+ }
+
+ /* Call __new__. */
+ obj = cls->tp_new(cls, args, NULL);
+ if (obj == NULL) goto Fail;
+
+ Py_DECREF(args);
+ Py_DECREF(clsraw);
+ PDATA_PUSH(self->stack, obj, -1);
+ return 0;
+
+ Fail:
+ Py_XDECREF(args);
+ Py_XDECREF(clsraw);
+ return -1;
+}
+
+static int
+load_global(Unpicklerobject *self)
+{
+ PyObject *class = 0, *module_name = 0, *class_name = 0;
+ int len;
+ char *s;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+ module_name = PyString_FromStringAndSize(s, len - 1);
+ if (!module_name) return -1;
+
+ if ((len = self->readline_func(self, &s)) >= 0) {
+ if (len < 2) {
+ Py_DECREF(module_name);
+ return bad_readline();
+ }
+ if ((class_name = PyString_FromStringAndSize(s, len - 1))) {
+ class = find_class(module_name, class_name,
+ self->find_class);
+ Py_DECREF(class_name);
+ }
+ }
+ Py_DECREF(module_name);
+
+ if (! class) return -1;
+ PDATA_PUSH(self->stack, class, -1);
+ return 0;
+}
+
+
+static int
+load_persid(Unpicklerobject *self)
+{
+ PyObject *pid = 0;
+ int len;
+ char *s;
+
+ if (self->pers_func) {
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+
+ pid = PyString_FromStringAndSize(s, len - 1);
+ if (!pid) return -1;
+
+ if (PyList_Check(self->pers_func)) {
+ if (PyList_Append(self->pers_func, pid) < 0) {
+ Py_DECREF(pid);
+ return -1;
+ }
+ }
+ else {
+ ARG_TUP(self, pid);
+ if (self->arg) {
+ pid = PyObject_Call(self->pers_func, self->arg,
+ NULL);
+ FREE_ARG_TUP(self);
+ }
+ }
+
+ if (! pid) return -1;
+
+ PDATA_PUSH(self->stack, pid, -1);
+ return 0;
+ }
+ else {
+ PyErr_SetString(UnpicklingError,
+ "A load persistent id instruction was encountered,\n"
+ "but no persistent_load function was specified.");
+ return -1;
+ }
+}
+
+static int
+load_binpersid(Unpicklerobject *self)
+{
+ PyObject *pid = 0;
+
+ if (self->pers_func) {
+ PDATA_POP(self->stack, pid);
+ if (! pid) return -1;
+
+ if (PyList_Check(self->pers_func)) {
+ if (PyList_Append(self->pers_func, pid) < 0) {
+ Py_DECREF(pid);
+ return -1;
+ }
+ }
+ else {
+ ARG_TUP(self, pid);
+ if (self->arg) {
+ pid = PyObject_Call(self->pers_func, self->arg,
+ NULL);
+ FREE_ARG_TUP(self);
+ }
+ if (! pid) return -1;
+ }
+
+ PDATA_PUSH(self->stack, pid, -1);
+ return 0;
+ }
+ else {
+ PyErr_SetString(UnpicklingError,
+ "A load persistent id instruction was encountered,\n"
+ "but no persistent_load function was specified.");
+ return -1;
+ }
+}
+
+
+static int
+load_pop(Unpicklerobject *self)
+{
+ int len;
+
+ if (!( (len=self->stack->length) > 0 )) return stackUnderflow();
+
+ /* Note that we split the (pickle.py) stack into two stacks,
+ an object stack and a mark stack. We have to be clever and
+ pop the right one. We do this by looking at the top of the
+ mark stack.
+ */
+
+ if ((self->num_marks > 0) &&
+ (self->marks[self->num_marks - 1] == len))
+ self->num_marks--;
+ else {
+ len--;
+ Py_DECREF(self->stack->data[len]);
+ self->stack->length=len;
+ }
+
+ return 0;
+}
+
+
+static int
+load_pop_mark(Unpicklerobject *self)
+{
+ int i;
+
+ if ((i = marker(self)) < 0)
+ return -1;
+
+ Pdata_clear(self->stack, i);
+
+ return 0;
+}
+
+
+static int
+load_dup(Unpicklerobject *self)
+{
+ PyObject *last;
+ int len;
+
+ if ((len = self->stack->length) <= 0) return stackUnderflow();
+ last=self->stack->data[len-1];
+ Py_INCREF(last);
+ PDATA_PUSH(self->stack, last, -1);
+ return 0;
+}
+
+
+static int
+load_get(Unpicklerobject *self)
+{
+ PyObject *py_str = 0, *value = 0;
+ int len;
+ char *s;
+ int rc;
+
+ if ((len = self->readline_func(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+
+ if (!( py_str = PyString_FromStringAndSize(s, len - 1))) return -1;
+
+ value = PyDict_GetItem(self->memo, py_str);
+ if (! value) {
+ PyErr_SetObject(BadPickleGet, py_str);
+ rc = -1;
+ }
+ else {
+ PDATA_APPEND(self->stack, value, -1);
+ rc = 0;
+ }
+
+ Py_DECREF(py_str);
+ return rc;
+}
+
+
+static int
+load_binget(Unpicklerobject *self)
+{
+ PyObject *py_key = 0, *value = 0;
+ unsigned char key;
+ char *s;
+ int rc;
+
+ if (self->read_func(self, &s, 1) < 0) return -1;
+
+ key = (unsigned char)s[0];
+ if (!( py_key = PyInt_FromLong((long)key))) return -1;
+
+ value = PyDict_GetItem(self->memo, py_key);
+ if (! value) {
+ PyErr_SetObject(BadPickleGet, py_key);
+ rc = -1;
+ }
+ else {
+ PDATA_APPEND(self->stack, value, -1);
+ rc = 0;
+ }
+
+ Py_DECREF(py_key);
+ return rc;
+}
+
+
+static int
+load_long_binget(Unpicklerobject *self)
+{
+ PyObject *py_key = 0, *value = 0;
+ unsigned char c;
+ char *s;
+ long key;
+ int rc;
+
+ if (self->read_func(self, &s, 4) < 0) return -1;
+
+ c = (unsigned char)s[0];
+ key = (long)c;
+ c = (unsigned char)s[1];
+ key |= (long)c << 8;
+ c = (unsigned char)s[2];
+ key |= (long)c << 16;
+ c = (unsigned char)s[3];
+ key |= (long)c << 24;
+
+ if (!( py_key = PyInt_FromLong((long)key))) return -1;
+
+ value = PyDict_GetItem(self->memo, py_key);
+ if (! value) {
+ PyErr_SetObject(BadPickleGet, py_key);
+ rc = -1;
+ }
+ else {
+ PDATA_APPEND(self->stack, value, -1);
+ rc = 0;
+ }
+
+ Py_DECREF(py_key);
+ return rc;
+}
+
+/* Push an object from the extension registry (EXT[124]). nbytes is
+ * the number of bytes following the opcode, holding the index (code) value.
+ */
+static int
+load_extension(Unpicklerobject *self, int nbytes)
+{
+ char *codebytes; /* the nbytes bytes after the opcode */
+ long code; /* calc_binint returns long */
+ PyObject *py_code; /* code as a Python int */
+ PyObject *obj; /* the object to push */
+ PyObject *pair; /* (module_name, class_name) */
+ PyObject *module_name, *class_name;
+
+ assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+ if (self->read_func(self, &codebytes, nbytes) < 0) return -1;
+ code = calc_binint(codebytes, nbytes);
+ if (code <= 0) { /* note that 0 is forbidden */
+ /* Corrupt or hostile pickle. */
+ PyErr_SetString(UnpicklingError, "EXT specifies code <= 0");
+ return -1;
+ }
+
+ /* Look for the code in the cache. */
+ py_code = PyInt_FromLong(code);
+ if (py_code == NULL) return -1;
+ obj = PyDict_GetItem(extension_cache, py_code);
+ if (obj != NULL) {
+ /* Bingo. */
+ Py_DECREF(py_code);
+ PDATA_APPEND(self->stack, obj, -1);
+ return 0;
+ }
+
+ /* Look up the (module_name, class_name) pair. */
+ pair = PyDict_GetItem(inverted_registry, py_code);
+ if (pair == NULL) {
+ Py_DECREF(py_code);
+ PyErr_Format(PyExc_ValueError, "unregistered extension "
+ "code %ld", code);
+ return -1;
+ }
+ /* Since the extension registry is manipulable via Python code,
+ * confirm that pair is really a 2-tuple of strings.
+ */
+ if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 ||
+ !PyString_Check(module_name = PyTuple_GET_ITEM(pair, 0)) ||
+ !PyString_Check(class_name = PyTuple_GET_ITEM(pair, 1))) {
+ Py_DECREF(py_code);
+ PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
+ "isn't a 2-tuple of strings", code);
+ return -1;
+ }
+ /* Load the object. */
+ obj = find_class(module_name, class_name, self->find_class);
+ if (obj == NULL) {
+ Py_DECREF(py_code);
+ return -1;
+ }
+ /* Cache code -> obj. */
+ code = PyDict_SetItem(extension_cache, py_code, obj);
+ Py_DECREF(py_code);
+ if (code < 0) {
+ Py_DECREF(obj);
+ return -1;
+ }
+ PDATA_PUSH(self->stack, obj, -1);
+ return 0;
+}
+
+static int
+load_put(Unpicklerobject *self)
+{
+ PyObject *py_str = 0, *value = 0;
+ int len, l;
+ char *s;
+
+ if ((l = self->readline_func(self, &s)) < 0) return -1;
+ if (l < 2) return bad_readline();
+ if (!( len=self->stack->length )) return stackUnderflow();
+ if (!( py_str = PyString_FromStringAndSize(s, l - 1))) return -1;
+ value=self->stack->data[len-1];
+ l=PyDict_SetItem(self->memo, py_str, value);
+ Py_DECREF(py_str);
+ return l;
+}
+
+
+static int
+load_binput(Unpicklerobject *self)
+{
+ PyObject *py_key = 0, *value = 0;
+ unsigned char key;
+ char *s;
+ int len;
+
+ if (self->read_func(self, &s, 1) < 0) return -1;
+ if (!( (len=self->stack->length) > 0 )) return stackUnderflow();
+
+ key = (unsigned char)s[0];
+
+ if (!( py_key = PyInt_FromLong((long)key))) return -1;
+ value=self->stack->data[len-1];
+ len=PyDict_SetItem(self->memo, py_key, value);
+ Py_DECREF(py_key);
+ return len;
+}
+
+
+static int
+load_long_binput(Unpicklerobject *self)
+{
+ PyObject *py_key = 0, *value = 0;
+ long key;
+ unsigned char c;
+ char *s;
+ int len;
+
+ if (self->read_func(self, &s, 4) < 0) return -1;
+ if (!( len=self->stack->length )) return stackUnderflow();
+
+ c = (unsigned char)s[0];
+ key = (long)c;
+ c = (unsigned char)s[1];
+ key |= (long)c << 8;
+ c = (unsigned char)s[2];
+ key |= (long)c << 16;
+ c = (unsigned char)s[3];
+ key |= (long)c << 24;
+
+ if (!( py_key = PyInt_FromLong(key))) return -1;
+ value=self->stack->data[len-1];
+ len=PyDict_SetItem(self->memo, py_key, value);
+ Py_DECREF(py_key);
+ return len;
+}
+
+
+static int
+do_append(Unpicklerobject *self, int x)
+{
+ PyObject *value = 0, *list = 0, *append_method = 0;
+ int len, i;
+
+ len=self->stack->length;
+ if (!( len >= x && x > 0 )) return stackUnderflow();
+ /* nothing to do */
+ if (len==x) return 0;
+
+ list=self->stack->data[x-1];
+
+ if (PyList_Check(list)) {
+ PyObject *slice;
+ int list_len;
+
+ slice=Pdata_popList(self->stack, x);
+ if (! slice) return -1;
+ list_len = PyList_GET_SIZE(list);
+ i=PyList_SetSlice(list, list_len, list_len, slice);
+ Py_DECREF(slice);
+ return i;
+ }
+ else {
+
+ if (!( append_method = PyObject_GetAttr(list, append_str)))
+ return -1;
+
+ for (i = x; i < len; i++) {
+ PyObject *junk;
+
+ value=self->stack->data[i];
+ junk=0;
+ ARG_TUP(self, value);
+ if (self->arg) {
+ junk = PyObject_Call(append_method, self->arg,
+ NULL);
+ FREE_ARG_TUP(self);
+ }
+ if (! junk) {
+ Pdata_clear(self->stack, i+1);
+ self->stack->length=x;
+ Py_DECREF(append_method);
+ return -1;
+ }
+ Py_DECREF(junk);
+ }
+ self->stack->length=x;
+ Py_DECREF(append_method);
+ }
+
+ return 0;
+}
+
+
+static int
+load_append(Unpicklerobject *self)
+{
+ return do_append(self, self->stack->length - 1);
+}
+
+
+static int
+load_appends(Unpicklerobject *self)
+{
+ return do_append(self, marker(self));
+}
+
+
+static int
+do_setitems(Unpicklerobject *self, int x)
+{
+ PyObject *value = 0, *key = 0, *dict = 0;
+ int len, i, r=0;
+
+ if (!( (len=self->stack->length) >= x
+ && x > 0 )) return stackUnderflow();
+
+ dict=self->stack->data[x-1];
+
+ for (i = x+1; i < len; i += 2) {
+ key =self->stack->data[i-1];
+ value=self->stack->data[i ];
+ if (PyObject_SetItem(dict, key, value) < 0) {
+ r=-1;
+ break;
+ }
+ }
+
+ Pdata_clear(self->stack, x);
+
+ return r;
+}
+
+
+static int
+load_setitem(Unpicklerobject *self)
+{
+ return do_setitems(self, self->stack->length - 2);
+}
+
+static int
+load_setitems(Unpicklerobject *self)
+{
+ return do_setitems(self, marker(self));
+}
+
+
+static int
+load_build(Unpicklerobject *self)
+{
+ PyObject *state, *inst, *slotstate;
+ PyObject *__setstate__;
+ PyObject *d_key, *d_value;
+ Py_ssize_t i;
+ int res = -1;
+
+ /* Stack is ... instance, state. We want to leave instance at
+ * the stack top, possibly mutated via instance.__setstate__(state).
+ */
+ if (self->stack->length < 2)
+ return stackUnderflow();
+ PDATA_POP(self->stack, state);
+ if (state == NULL)
+ return -1;
+ inst = self->stack->data[self->stack->length - 1];
+
+ __setstate__ = PyObject_GetAttr(inst, __setstate___str);
+ if (__setstate__ != NULL) {
+ PyObject *junk = NULL;
+
+ /* The explicit __setstate__ is responsible for everything. */
+ ARG_TUP(self, state);
+ if (self->arg) {
+ junk = PyObject_Call(__setstate__, self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ Py_DECREF(__setstate__);
+ if (junk == NULL)
+ return -1;
+ Py_DECREF(junk);
+ return 0;
+ }
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+
+ /* A default __setstate__. First see whether state embeds a
+ * slot state dict too (a proto 2 addition).
+ */
+ if (PyTuple_Check(state) && PyTuple_Size(state) == 2) {
+ PyObject *temp = state;
+ state = PyTuple_GET_ITEM(temp, 0);
+ slotstate = PyTuple_GET_ITEM(temp, 1);
+ Py_INCREF(state);
+ Py_INCREF(slotstate);
+ Py_DECREF(temp);
+ }
+ else
+ slotstate = NULL;
+
+ /* Set inst.__dict__ from the state dict (if any). */
+ if (state != Py_None) {
+ PyObject *dict;
+ if (! PyDict_Check(state)) {
+ PyErr_SetString(UnpicklingError, "state is not a "
+ "dictionary");
+ goto finally;
+ }
+ dict = PyObject_GetAttr(inst, __dict___str);
+ if (dict == NULL)
+ goto finally;
+
+ i = 0;
+ while (PyDict_Next(state, &i, &d_key, &d_value)) {
+ if (PyObject_SetItem(dict, d_key, d_value) < 0)
+ goto finally;
+ }
+ Py_DECREF(dict);
+ }
+
+ /* Also set instance attributes from the slotstate dict (if any). */
+ if (slotstate != NULL) {
+ if (! PyDict_Check(slotstate)) {
+ PyErr_SetString(UnpicklingError, "slot state is not "
+ "a dictionary");
+ goto finally;
+ }
+ i = 0;
+ while (PyDict_Next(slotstate, &i, &d_key, &d_value)) {
+ if (PyObject_SetAttr(inst, d_key, d_value) < 0)
+ goto finally;
+ }
+ }
+ res = 0;
+
+ finally:
+ Py_DECREF(state);
+ Py_XDECREF(slotstate);
+ return res;
+}
+
+
+static int
+load_mark(Unpicklerobject *self)
+{
+ int s;
+
+ /* Note that we split the (pickle.py) stack into two stacks, an
+ object stack and a mark stack. Here we push a mark onto the
+ mark stack.
+ */
+
+ if ((self->num_marks + 1) >= self->marks_size) {
+ s=self->marks_size+20;
+ if (s <= self->num_marks) s=self->num_marks + 1;
+ if (self->marks == NULL)
+ self->marks=(int *)malloc(s * sizeof(int));
+ else
+ self->marks=(int *)realloc(self->marks,
+ s * sizeof(int));
+ if (! self->marks) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->marks_size = s;
+ }
+
+ self->marks[self->num_marks++] = self->stack->length;
+
+ return 0;
+}
+
+static int
+load_reduce(Unpicklerobject *self)
+{
+ PyObject *callable = 0, *arg_tup = 0, *ob = 0;
+
+ PDATA_POP(self->stack, arg_tup);
+ if (! arg_tup) return -1;
+ PDATA_POP(self->stack, callable);
+ if (callable) {
+ ob = Instance_New(callable, arg_tup);
+ Py_DECREF(callable);
+ }
+ Py_DECREF(arg_tup);
+
+ if (! ob) return -1;
+
+ PDATA_PUSH(self->stack, ob, -1);
+ return 0;
+}
+
+/* Just raises an error if we don't know the protocol specified. PROTO
+ * is the first opcode for protocols >= 2.
+ */
+static int
+load_proto(Unpicklerobject *self)
+{
+ int i;
+ char *protobyte;
+
+ i = self->read_func(self, &protobyte, 1);
+ if (i < 0)
+ return -1;
+
+ i = calc_binint(protobyte, 1);
+ /* No point checking for < 0, since calc_binint returns an unsigned
+ * int when chewing on 1 byte.
+ */
+ assert(i >= 0);
+ if (i <= HIGHEST_PROTOCOL)
+ return 0;
+
+ PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
+ return -1;
+}
+
+static PyObject *
+load(Unpicklerobject *self)
+{
+ PyObject *err = 0, *val = 0;
+ char *s;
+
+ self->num_marks = 0;
+ if (self->stack->length) Pdata_clear(self->stack, 0);
+
+ while (1) {
+ if (self->read_func(self, &s, 1) < 0)
+ break;
+
+ switch (s[0]) {
+ case NONE:
+ if (load_none(self) < 0)
+ break;
+ continue;
+
+ case BININT:
+ if (load_binint(self) < 0)
+ break;
+ continue;
+
+ case BININT1:
+ if (load_binint1(self) < 0)
+ break;
+ continue;
+
+ case BININT2:
+ if (load_binint2(self) < 0)
+ break;
+ continue;
+
+ case INT:
+ if (load_int(self) < 0)
+ break;
+ continue;
+
+ case LONG:
+ if (load_long(self) < 0)
+ break;
+ continue;
+
+ case LONG1:
+ if (load_counted_long(self, 1) < 0)
+ break;
+ continue;
+
+ case LONG4:
+ if (load_counted_long(self, 4) < 0)
+ break;
+ continue;
+
+ case FLOAT:
+ if (load_float(self) < 0)
+ break;
+ continue;
+
+ case BINFLOAT:
+ if (load_binfloat(self) < 0)
+ break;
+ continue;
+
+ case BINSTRING:
+ if (load_binstring(self) < 0)
+ break;
+ continue;
+
+ case SHORT_BINSTRING:
+ if (load_short_binstring(self) < 0)
+ break;
+ continue;
+
+ case STRING:
+ if (load_string(self) < 0)
+ break;
+ continue;
+
+#ifdef Py_USING_UNICODE
+ case UNICODE:
+ if (load_unicode(self) < 0)
+ break;
+ continue;
+
+ case BINUNICODE:
+ if (load_binunicode(self) < 0)
+ break;
+ continue;
+#endif
+
+ case EMPTY_TUPLE:
+ if (load_counted_tuple(self, 0) < 0)
+ break;
+ continue;
+
+ case TUPLE1:
+ if (load_counted_tuple(self, 1) < 0)
+ break;
+ continue;
+
+ case TUPLE2:
+ if (load_counted_tuple(self, 2) < 0)
+ break;
+ continue;
+
+ case TUPLE3:
+ if (load_counted_tuple(self, 3) < 0)
+ break;
+ continue;
+
+ case TUPLE:
+ if (load_tuple(self) < 0)
+ break;
+ continue;
+
+ case EMPTY_LIST:
+ if (load_empty_list(self) < 0)
+ break;
+ continue;
+
+ case LIST:
+ if (load_list(self) < 0)
+ break;
+ continue;
+
+ case EMPTY_DICT:
+ if (load_empty_dict(self) < 0)
+ break;
+ continue;
+
+ case DICT:
+ if (load_dict(self) < 0)
+ break;
+ continue;
+
+ case OBJ:
+ if (load_obj(self) < 0)
+ break;
+ continue;
+
+ case INST:
+ if (load_inst(self) < 0)
+ break;
+ continue;
+
+ case NEWOBJ:
+ if (load_newobj(self) < 0)
+ break;
+ continue;
+
+ case GLOBAL:
+ if (load_global(self) < 0)
+ break;
+ continue;
+
+ case APPEND:
+ if (load_append(self) < 0)
+ break;
+ continue;
+
+ case APPENDS:
+ if (load_appends(self) < 0)
+ break;
+ continue;
+
+ case BUILD:
+ if (load_build(self) < 0)
+ break;
+ continue;
+
+ case DUP:
+ if (load_dup(self) < 0)
+ break;
+ continue;
+
+ case BINGET:
+ if (load_binget(self) < 0)
+ break;
+ continue;
+
+ case LONG_BINGET:
+ if (load_long_binget(self) < 0)
+ break;
+ continue;
+
+ case GET:
+ if (load_get(self) < 0)
+ break;
+ continue;
+
+ case EXT1:
+ if (load_extension(self, 1) < 0)
+ break;
+ continue;
+
+ case EXT2:
+ if (load_extension(self, 2) < 0)
+ break;
+ continue;
+
+ case EXT4:
+ if (load_extension(self, 4) < 0)
+ break;
+ continue;
+ case MARK:
+ if (load_mark(self) < 0)
+ break;
+ continue;
+
+ case BINPUT:
+ if (load_binput(self) < 0)
+ break;
+ continue;
+
+ case LONG_BINPUT:
+ if (load_long_binput(self) < 0)
+ break;
+ continue;
+
+ case PUT:
+ if (load_put(self) < 0)
+ break;
+ continue;
+
+ case POP:
+ if (load_pop(self) < 0)
+ break;
+ continue;
+
+ case POP_MARK:
+ if (load_pop_mark(self) < 0)
+ break;
+ continue;
+
+ case SETITEM:
+ if (load_setitem(self) < 0)
+ break;
+ continue;
+
+ case SETITEMS:
+ if (load_setitems(self) < 0)
+ break;
+ continue;
+
+ case STOP:
+ break;
+
+ case PERSID:
+ if (load_persid(self) < 0)
+ break;
+ continue;
+
+ case BINPERSID:
+ if (load_binpersid(self) < 0)
+ break;
+ continue;
+
+ case REDUCE:
+ if (load_reduce(self) < 0)
+ break;
+ continue;
+
+ case PROTO:
+ if (load_proto(self) < 0)
+ break;
+ continue;
+
+ case NEWTRUE:
+ if (load_bool(self, Py_True) < 0)
+ break;
+ continue;
+
+ case NEWFALSE:
+ if (load_bool(self, Py_False) < 0)
+ break;
+ continue;
+
+ case '\0':
+ /* end of file */
+ PyErr_SetNone(PyExc_EOFError);
+ break;
+
+ default:
+ cPickle_ErrFormat(UnpicklingError,
+ "invalid load key, '%s'.",
+ "c", s[0]);
+ return NULL;
+ }
+
+ break;
+ }
+
+ if ((err = PyErr_Occurred())) {
+ if (err == PyExc_EOFError) {
+ PyErr_SetNone(PyExc_EOFError);
+ }
+ return NULL;
+ }
+
+ PDATA_POP(self->stack, val);
+ return val;
+}
+
+
+/* No-load functions to support noload, which is used to
+ find persistent references. */
+
+static int
+noload_obj(Unpicklerobject *self)
+{
+ int i;
+
+ if ((i = marker(self)) < 0) return -1;
+ return Pdata_clear(self->stack, i+1);
+}
+
+
+static int
+noload_inst(Unpicklerobject *self)
+{
+ int i;
+ char *s;
+
+ if ((i = marker(self)) < 0) return -1;
+ Pdata_clear(self->stack, i);
+ if (self->readline_func(self, &s) < 0) return -1;
+ if (self->readline_func(self, &s) < 0) return -1;
+ PDATA_APPEND(self->stack, Py_None, -1);
+ return 0;
+}
+
+static int
+noload_newobj(Unpicklerobject *self)
+{
+ PyObject *obj;
+
+ PDATA_POP(self->stack, obj); /* pop argtuple */
+ if (obj == NULL) return -1;
+ Py_DECREF(obj);
+
+ PDATA_POP(self->stack, obj); /* pop cls */
+ if (obj == NULL) return -1;
+ Py_DECREF(obj);
+
+ PDATA_APPEND(self->stack, Py_None, -1);
+ return 0;
+}
+
+static int
+noload_global(Unpicklerobject *self)
+{
+ char *s;
+
+ if (self->readline_func(self, &s) < 0) return -1;
+ if (self->readline_func(self, &s) < 0) return -1;
+ PDATA_APPEND(self->stack, Py_None,-1);
+ return 0;
+}
+
+static int
+noload_reduce(Unpicklerobject *self)
+{
+
+ if (self->stack->length < 2) return stackUnderflow();
+ Pdata_clear(self->stack, self->stack->length-2);
+ PDATA_APPEND(self->stack, Py_None,-1);
+ return 0;
+}
+
+static int
+noload_build(Unpicklerobject *self) {
+
+ if (self->stack->length < 1) return stackUnderflow();
+ Pdata_clear(self->stack, self->stack->length-1);
+ return 0;
+}
+
+static int
+noload_extension(Unpicklerobject *self, int nbytes)
+{
+ char *codebytes;
+
+ assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+ if (self->read_func(self, &codebytes, nbytes) < 0) return -1;
+ PDATA_APPEND(self->stack, Py_None, -1);
+ return 0;
+}
+
+
+static PyObject *
+noload(Unpicklerobject *self)
+{
+ PyObject *err = 0, *val = 0;
+ char *s;
+
+ self->num_marks = 0;
+ Pdata_clear(self->stack, 0);
+
+ while (1) {
+ if (self->read_func(self, &s, 1) < 0)
+ break;
+
+ switch (s[0]) {
+ case NONE:
+ if (load_none(self) < 0)
+ break;
+ continue;
+
+ case BININT:
+ if (load_binint(self) < 0)
+ break;
+ continue;
+
+ case BININT1:
+ if (load_binint1(self) < 0)
+ break;
+ continue;
+
+ case BININT2:
+ if (load_binint2(self) < 0)
+ break;
+ continue;
+
+ case INT:
+ if (load_int(self) < 0)
+ break;
+ continue;
+
+ case LONG:
+ if (load_long(self) < 0)
+ break;
+ continue;
+
+ case LONG1:
+ if (load_counted_long(self, 1) < 0)
+ break;
+ continue;
+
+ case LONG4:
+ if (load_counted_long(self, 4) < 0)
+ break;
+ continue;
+
+ case FLOAT:
+ if (load_float(self) < 0)
+ break;
+ continue;
+
+ case BINFLOAT:
+ if (load_binfloat(self) < 0)
+ break;
+ continue;
+
+ case BINSTRING:
+ if (load_binstring(self) < 0)
+ break;
+ continue;
+
+ case SHORT_BINSTRING:
+ if (load_short_binstring(self) < 0)
+ break;
+ continue;
+
+ case STRING:
+ if (load_string(self) < 0)
+ break;
+ continue;
+
+#ifdef Py_USING_UNICODE
+ case UNICODE:
+ if (load_unicode(self) < 0)
+ break;
+ continue;
+
+ case BINUNICODE:
+ if (load_binunicode(self) < 0)
+ break;
+ continue;
+#endif
+
+ case EMPTY_TUPLE:
+ if (load_counted_tuple(self, 0) < 0)
+ break;
+ continue;
+
+ case TUPLE1:
+ if (load_counted_tuple(self, 1) < 0)
+ break;
+ continue;
+
+ case TUPLE2:
+ if (load_counted_tuple(self, 2) < 0)
+ break;
+ continue;
+
+ case TUPLE3:
+ if (load_counted_tuple(self, 3) < 0)
+ break;
+ continue;
+
+ case TUPLE:
+ if (load_tuple(self) < 0)
+ break;
+ continue;
+
+ case EMPTY_LIST:
+ if (load_empty_list(self) < 0)
+ break;
+ continue;
+
+ case LIST:
+ if (load_list(self) < 0)
+ break;
+ continue;
+
+ case EMPTY_DICT:
+ if (load_empty_dict(self) < 0)
+ break;
+ continue;
+
+ case DICT:
+ if (load_dict(self) < 0)
+ break;
+ continue;
+
+ case OBJ:
+ if (noload_obj(self) < 0)
+ break;
+ continue;
+
+ case INST:
+ if (noload_inst(self) < 0)
+ break;
+ continue;
+
+ case NEWOBJ:
+ if (noload_newobj(self) < 0)
+ break;
+ continue;
+
+ case GLOBAL:
+ if (noload_global(self) < 0)
+ break;
+ continue;
+
+ case APPEND:
+ if (load_append(self) < 0)
+ break;
+ continue;
+
+ case APPENDS:
+ if (load_appends(self) < 0)
+ break;
+ continue;
+
+ case BUILD:
+ if (noload_build(self) < 0)
+ break;
+ continue;
+
+ case DUP:
+ if (load_dup(self) < 0)
+ break;
+ continue;
+
+ case BINGET:
+ if (load_binget(self) < 0)
+ break;
+ continue;
+
+ case LONG_BINGET:
+ if (load_long_binget(self) < 0)
+ break;
+ continue;
+
+ case GET:
+ if (load_get(self) < 0)
+ break;
+ continue;
+
+ case EXT1:
+ if (noload_extension(self, 1) < 0)
+ break;
+ continue;
+
+ case EXT2:
+ if (noload_extension(self, 2) < 0)
+ break;
+ continue;
+
+ case EXT4:
+ if (noload_extension(self, 4) < 0)
+ break;
+ continue;
+
+ case MARK:
+ if (load_mark(self) < 0)
+ break;
+ continue;
+
+ case BINPUT:
+ if (load_binput(self) < 0)
+ break;
+ continue;
+
+ case LONG_BINPUT:
+ if (load_long_binput(self) < 0)
+ break;
+ continue;
+
+ case PUT:
+ if (load_put(self) < 0)
+ break;
+ continue;
+
+ case POP:
+ if (load_pop(self) < 0)
+ break;
+ continue;
+
+ case POP_MARK:
+ if (load_pop_mark(self) < 0)
+ break;
+ continue;
+
+ case SETITEM:
+ if (load_setitem(self) < 0)
+ break;
+ continue;
+
+ case SETITEMS:
+ if (load_setitems(self) < 0)
+ break;
+ continue;
+
+ case STOP:
+ break;
+
+ case PERSID:
+ if (load_persid(self) < 0)
+ break;
+ continue;
+
+ case BINPERSID:
+ if (load_binpersid(self) < 0)
+ break;
+ continue;
+
+ case REDUCE:
+ if (noload_reduce(self) < 0)
+ break;
+ continue;
+
+ case PROTO:
+ if (load_proto(self) < 0)
+ break;
+ continue;
+
+ case NEWTRUE:
+ if (load_bool(self, Py_True) < 0)
+ break;
+ continue;
+
+ case NEWFALSE:
+ if (load_bool(self, Py_False) < 0)
+ break;
+ continue;
+ default:
+ cPickle_ErrFormat(UnpicklingError,
+ "invalid load key, '%s'.",
+ "c", s[0]);
+ return NULL;
+ }
+
+ break;
+ }
+
+ if ((err = PyErr_Occurred())) {
+ if (err == PyExc_EOFError) {
+ PyErr_SetNone(PyExc_EOFError);
+ }
+ return NULL;
+ }
+
+ PDATA_POP(self->stack, val);
+ return val;
+}
+
+
+static PyObject *
+Unpickler_load(Unpicklerobject *self, PyObject *unused)
+{
+ return load(self);
+}
+
+static PyObject *
+Unpickler_noload(Unpicklerobject *self, PyObject *unused)
+{
+ return noload(self);
+}
+
+
+static struct PyMethodDef Unpickler_methods[] = {
+ {"load", (PyCFunction)Unpickler_load, METH_NOARGS,
+ PyDoc_STR("load() -- Load a pickle")
+ },
+ {"noload", (PyCFunction)Unpickler_noload, METH_NOARGS,
+ PyDoc_STR(
+ "noload() -- not load a pickle, but go through most of the motions\n"
+ "\n"
+ "This function can be used to read past a pickle without instantiating\n"
+ "any objects or importing any modules. It can also be used to find all\n"
+ "persistent references without instantiating any objects or importing\n"
+ "any modules.\n")
+ },
+ {NULL, NULL} /* sentinel */
+};
+
+
+static Unpicklerobject *
+newUnpicklerobject(PyObject *f)
+{
+ Unpicklerobject *self;
+
+ if (!( self = PyObject_GC_New(Unpicklerobject, &Unpicklertype)))
+ return NULL;
+
+ self->file = NULL;
+ self->arg = NULL;
+ self->stack = (Pdata*)Pdata_New();
+ self->pers_func = NULL;
+ self->last_string = NULL;
+ self->marks = NULL;
+ self->num_marks = 0;
+ self->marks_size = 0;
+ self->buf_size = 0;
+ self->read = NULL;
+ self->readline = NULL;
+ self->find_class = NULL;
+
+ if (!( self->memo = PyDict_New()))
+ goto err;
+
+ if (!self->stack)
+ goto err;
+
+ Py_INCREF(f);
+ self->file = f;
+
+ /* Set read, readline based on type of f */
+ if (PyFile_Check(f)) {
+ self->fp = PyFile_AsFile(f);
+ if (self->fp == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ goto err;
+ }
+ self->read_func = read_file;
+ self->readline_func = readline_file;
+ }
+ else if (PycStringIO_InputCheck(f)) {
+ self->fp = NULL;
+ self->read_func = read_cStringIO;
+ self->readline_func = readline_cStringIO;
+ }
+ else {
+
+ self->fp = NULL;
+ self->read_func = read_other;
+ self->readline_func = readline_other;
+
+ if (!( (self->readline = PyObject_GetAttr(f, readline_str)) &&
+ (self->read = PyObject_GetAttr(f, read_str)))) {
+ PyErr_Clear();
+ PyErr_SetString( PyExc_TypeError,
+ "argument must have 'read' and "
+ "'readline' attributes" );
+ goto err;
+ }
+ }
+ PyObject_GC_Track(self);
+
+ return self;
+
+ err:
+ Py_DECREF((PyObject *)self);
+ return NULL;
+}
+
+
+static PyObject *
+get_Unpickler(PyObject *self, PyObject *file)
+{
+ return (PyObject *)newUnpicklerobject(file);
+}
+
+
+static void
+Unpickler_dealloc(Unpicklerobject *self)
+{
+ PyObject_GC_UnTrack((PyObject *)self);
+ Py_XDECREF(self->readline);
+ Py_XDECREF(self->read);
+ Py_XDECREF(self->file);
+ Py_XDECREF(self->memo);
+ Py_XDECREF(self->stack);
+ Py_XDECREF(self->pers_func);
+ Py_XDECREF(self->arg);
+ Py_XDECREF(self->last_string);
+ Py_XDECREF(self->find_class);
+
+ if (self->marks) {
+ free(self->marks);
+ }
+
+ if (self->buf_size) {
+ free(self->buf);
+ }
+
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+Unpickler_traverse(Unpicklerobject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->readline);
+ Py_VISIT(self->read);
+ Py_VISIT(self->file);
+ Py_VISIT(self->memo);
+ Py_VISIT(self->stack);
+ Py_VISIT(self->pers_func);
+ Py_VISIT(self->arg);
+ Py_VISIT(self->last_string);
+ Py_VISIT(self->find_class);
+ return 0;
+}
+
+static int
+Unpickler_clear(Unpicklerobject *self)
+{
+ Py_CLEAR(self->readline);
+ Py_CLEAR(self->read);
+ Py_CLEAR(self->file);
+ Py_CLEAR(self->memo);
+ Py_CLEAR(self->stack);
+ Py_CLEAR(self->pers_func);
+ Py_CLEAR(self->arg);
+ Py_CLEAR(self->last_string);
+ Py_CLEAR(self->find_class);
+ return 0;
+}
+
+static PyObject *
+Unpickler_getattr(Unpicklerobject *self, char *name)
+{
+ if (!strcmp(name, "persistent_load")) {
+ if (!self->pers_func) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+ }
+
+ Py_INCREF(self->pers_func);
+ return self->pers_func;
+ }
+
+ if (!strcmp(name, "find_global")) {
+ if (!self->find_class) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+ }
+
+ Py_INCREF(self->find_class);
+ return self->find_class;
+ }
+
+ if (!strcmp(name, "memo")) {
+ if (!self->memo) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+ }
+
+ Py_INCREF(self->memo);
+ return self->memo;
+ }
+
+ if (!strcmp(name, "UnpicklingError")) {
+ Py_INCREF(UnpicklingError);
+ return UnpicklingError;
+ }
+
+ return Py_FindMethod(Unpickler_methods, (PyObject *)self, name);
+}
+
+
+static int
+Unpickler_setattr(Unpicklerobject *self, char *name, PyObject *value)
+{
+
+ if (!strcmp(name, "persistent_load")) {
+ Py_XDECREF(self->pers_func);
+ self->pers_func = value;
+ Py_XINCREF(value);
+ return 0;
+ }
+
+ if (!strcmp(name, "find_global")) {
+ Py_XDECREF(self->find_class);
+ self->find_class = value;
+ Py_XINCREF(value);
+ return 0;
+ }
+
+ if (! value) {
+ PyErr_SetString(PyExc_TypeError,
+ "attribute deletion is not supported");
+ return -1;
+ }
+
+ if (strcmp(name, "memo") == 0) {
+ if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "memo must be a dictionary");
+ return -1;
+ }
+ Py_XDECREF(self->memo);
+ self->memo = value;
+ Py_INCREF(value);
+ return 0;
+ }
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+}
+
+/* ---------------------------------------------------------------------------
+ * Module-level functions.
+ */
+
+/* dump(obj, file, protocol=0). */
+static PyObject *
+cpm_dump(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"obj", "file", "protocol", NULL};
+ PyObject *ob, *file, *res = NULL;
+ Picklerobject *pickler = 0;
+ int proto = 0;
+
+ if (!( PyArg_ParseTupleAndKeywords(args, kwds, "OO|i", kwlist,
+ &ob, &file, &proto)))
+ goto finally;
+
+ if (!( pickler = newPicklerobject(file, proto)))
+ goto finally;
+
+ if (dump(pickler, ob) < 0)
+ goto finally;
+
+ Py_INCREF(Py_None);
+ res = Py_None;
+
+ finally:
+ Py_XDECREF(pickler);
+
+ return res;
+}
+
+
+/* dumps(obj, protocol=0). */
+static PyObject *
+cpm_dumps(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"obj", "protocol", NULL};
+ PyObject *ob, *file = 0, *res = NULL;
+ Picklerobject *pickler = 0;
+ int proto = 0;
+
+ if (!( PyArg_ParseTupleAndKeywords(args, kwds, "O|i:dumps", kwlist,
+ &ob, &proto)))
+ goto finally;
+
+ if (!( file = PycStringIO->NewOutput(128)))
+ goto finally;
+
+ if (!( pickler = newPicklerobject(file, proto)))
+ goto finally;
+
+ if (dump(pickler, ob) < 0)
+ goto finally;
+
+ res = PycStringIO->cgetvalue(file);
+
+ finally:
+ Py_XDECREF(pickler);
+ Py_XDECREF(file);
+
+ return res;
+}
+
+
+/* load(fileobj). */
+static PyObject *
+cpm_load(PyObject *self, PyObject *ob)
+{
+ Unpicklerobject *unpickler = 0;
+ PyObject *res = NULL;
+
+ if (!( unpickler = newUnpicklerobject(ob)))
+ goto finally;
+
+ res = load(unpickler);
+
+ finally:
+ Py_XDECREF(unpickler);
+
+ return res;
+}
+
+
+/* loads(string) */
+static PyObject *
+cpm_loads(PyObject *self, PyObject *args)
+{
+ PyObject *ob, *file = 0, *res = NULL;
+ Unpicklerobject *unpickler = 0;
+
+ if (!( PyArg_ParseTuple(args, "S:loads", &ob)))
+ goto finally;
+
+ if (!( file = PycStringIO->NewInput(ob)))
+ goto finally;
+
+ if (!( unpickler = newUnpicklerobject(file)))
+ goto finally;
+
+ res = load(unpickler);
+
+ finally:
+ Py_XDECREF(file);
+ Py_XDECREF(unpickler);
+
+ return res;
+}
+
+
+PyDoc_STRVAR(Unpicklertype__doc__,
+"Objects that know how to unpickle");
+
+static PyTypeObject Unpicklertype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "cPickle.Unpickler", /*tp_name*/
+ sizeof(Unpicklerobject), /*tp_basicsize*/
+ 0,
+ (destructor)Unpickler_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc)Unpickler_getattr, /* tp_getattr */
+ (setattrfunc)Unpickler_setattr, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ Unpicklertype__doc__, /* tp_doc */
+ (traverseproc)Unpickler_traverse, /* tp_traverse */
+ (inquiry)Unpickler_clear, /* tp_clear */
+};
+
+static struct PyMethodDef cPickle_methods[] = {
+ {"dump", (PyCFunction)cpm_dump, METH_VARARGS | METH_KEYWORDS,
+ PyDoc_STR("dump(obj, file, protocol=0) -- "
+ "Write an object in pickle format to the given file.\n"
+ "\n"
+ "See the Pickler docstring for the meaning of optional argument proto.")
+ },
+
+ {"dumps", (PyCFunction)cpm_dumps, METH_VARARGS | METH_KEYWORDS,
+ PyDoc_STR("dumps(obj, protocol=0) -- "
+ "Return a string containing an object in pickle format.\n"
+ "\n"
+ "See the Pickler docstring for the meaning of optional argument proto.")
+ },
+
+ {"load", (PyCFunction)cpm_load, METH_O,
+ PyDoc_STR("load(file) -- Load a pickle from the given file")},
+
+ {"loads", (PyCFunction)cpm_loads, METH_VARARGS,
+ PyDoc_STR("loads(string) -- Load a pickle from the given string")},
+
+ {"Pickler", (PyCFunction)get_Pickler, METH_VARARGS | METH_KEYWORDS,
+ PyDoc_STR("Pickler(file, protocol=0) -- Create a pickler.\n"
+ "\n"
+ "This takes a file-like object for writing a pickle data stream.\n"
+ "The optional proto argument tells the pickler to use the given\n"
+ "protocol; supported protocols are 0, 1, 2. The default\n"
+ "protocol is 0, to be backwards compatible. (Protocol 0 is the\n"
+ "only protocol that can be written to a file opened in text\n"
+ "mode and read back successfully. When using a protocol higher\n"
+ "than 0, make sure the file is opened in binary mode, both when\n"
+ "pickling and unpickling.)\n"
+ "\n"
+ "Protocol 1 is more efficient than protocol 0; protocol 2 is\n"
+ "more efficient than protocol 1.\n"
+ "\n"
+ "Specifying a negative protocol version selects the highest\n"
+ "protocol version supported. The higher the protocol used, the\n"
+ "more recent the version of Python needed to read the pickle\n"
+ "produced.\n"
+ "\n"
+ "The file parameter must have a write() method that accepts a single\n"
+ "string argument. It can thus be an open file object, a StringIO\n"
+ "object, or any other custom object that meets this interface.\n")
+ },
+
+ {"Unpickler", (PyCFunction)get_Unpickler, METH_O,
+ PyDoc_STR("Unpickler(file) -- Create an unpickler.")},
+
+ { NULL, NULL }
+};
+
+static int
+init_stuff(PyObject *module_dict)
+{
+ PyObject *copy_reg, *t, *r;
+
+#define INIT_STR(S) if (!( S ## _str=PyString_InternFromString(#S))) return -1;
+
+ if (PyType_Ready(&Unpicklertype) < 0)
+ return -1;
+ if (PyType_Ready(&Picklertype) < 0)
+ return -1;
+
+ INIT_STR(__class__);
+ INIT_STR(__getinitargs__);
+ INIT_STR(__dict__);
+ INIT_STR(__getstate__);
+ INIT_STR(__setstate__);
+ INIT_STR(__name__);
+ INIT_STR(__main__);
+ INIT_STR(__reduce__);
+ INIT_STR(__reduce_ex__);
+ INIT_STR(write);
+ INIT_STR(append);
+ INIT_STR(read);
+ INIT_STR(readline);
+ INIT_STR(copy_reg);
+ INIT_STR(dispatch_table);
+
+ if (!( copy_reg = PyImport_ImportModule("copy_reg")))
+ return -1;
+
+ /* This is special because we want to use a different
+ one in restricted mode. */
+ dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str);
+ if (!dispatch_table) return -1;
+
+ extension_registry = PyObject_GetAttrString(copy_reg,
+ "_extension_registry");
+ if (!extension_registry) return -1;
+
+ inverted_registry = PyObject_GetAttrString(copy_reg,
+ "_inverted_registry");
+ if (!inverted_registry) return -1;
+
+ extension_cache = PyObject_GetAttrString(copy_reg,
+ "_extension_cache");
+ if (!extension_cache) return -1;
+
+ Py_DECREF(copy_reg);
+
+ if (!(empty_tuple = PyTuple_New(0)))
+ return -1;
+
+ two_tuple = PyTuple_New(2);
+ if (two_tuple == NULL)
+ return -1;
+ /* We use this temp container with no regard to refcounts, or to
+ * keeping containees alive. Exempt from GC, because we don't
+ * want anything looking at two_tuple() by magic.
+ */
+ PyObject_GC_UnTrack(two_tuple);
+
+ /* Ugh */
+ if (!( t=PyImport_ImportModule("__builtin__"))) return -1;
+ if (PyDict_SetItemString(module_dict, "__builtins__", t) < 0)
+ return -1;
+
+ if (!( t=PyDict_New())) return -1;
+ if (!( r=PyRun_String(
+ "def __str__(self):\n"
+ " return self.args and ('%s' % self.args[0]) or '(what)'\n",
+ Py_file_input,
+ module_dict, t) )) return -1;
+ Py_DECREF(r);
+
+ PickleError = PyErr_NewException("cPickle.PickleError", NULL, t);
+ if (!PickleError)
+ return -1;
+
+ Py_DECREF(t);
+
+ PicklingError = PyErr_NewException("cPickle.PicklingError",
+ PickleError, NULL);
+ if (!PicklingError)
+ return -1;
+
+ if (!( t=PyDict_New())) return -1;
+ if (!( r=PyRun_String(
+ "def __str__(self):\n"
+ " a=self.args\n"
+ " a=a and type(a[0]) or '(what)'\n"
+ " return 'Cannot pickle %s objects' % a\n"
+ , Py_file_input,
+ module_dict, t) )) return -1;
+ Py_DECREF(r);
+
+ if (!( UnpickleableError = PyErr_NewException(
+ "cPickle.UnpickleableError", PicklingError, t)))
+ return -1;
+
+ Py_DECREF(t);
+
+ if (!( UnpicklingError = PyErr_NewException("cPickle.UnpicklingError",
+ PickleError, NULL)))
+ return -1;
+
+ if (!( BadPickleGet = PyErr_NewException("cPickle.BadPickleGet",
+ UnpicklingError, NULL)))
+ return -1;
+
+ if (PyDict_SetItemString(module_dict, "PickleError",
+ PickleError) < 0)
+ return -1;
+
+ if (PyDict_SetItemString(module_dict, "PicklingError",
+ PicklingError) < 0)
+ return -1;
+
+ if (PyDict_SetItemString(module_dict, "UnpicklingError",
+ UnpicklingError) < 0)
+ return -1;
+
+ if (PyDict_SetItemString(module_dict, "UnpickleableError",
+ UnpickleableError) < 0)
+ return -1;
+
+ if (PyDict_SetItemString(module_dict, "BadPickleGet",
+ BadPickleGet) < 0)
+ return -1;
+
+ PycString_IMPORT;
+
+ return 0;
+}
+
+#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initcPickle(void)
+{
+ PyObject *m, *d, *di, *v, *k;
+ Py_ssize_t i;
+ char *rev = "1.71"; /* XXX when does this change? */
+ PyObject *format_version;
+ PyObject *compatible_formats;
+
+ Picklertype.ob_type = &PyType_Type;
+ Unpicklertype.ob_type = &PyType_Type;
+ PdataType.ob_type = &PyType_Type;
+
+ /* Initialize some pieces. We need to do this before module creation,
+ * so we're forced to use a temporary dictionary. :(
+ */
+ di = PyDict_New();
+ if (!di) return;
+ if (init_stuff(di) < 0) return;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule4("cPickle", cPickle_methods,
+ cPickle_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ v = PyString_FromString(rev);
+ PyDict_SetItemString(d, "__version__", v);
+ Py_XDECREF(v);
+
+ /* Copy data from di. Waaa. */
+ for (i=0; PyDict_Next(di, &i, &k, &v); ) {
+ if (PyObject_SetItem(d, k, v) < 0) {
+ Py_DECREF(di);
+ return;
+ }
+ }
+ Py_DECREF(di);
+
+ i = PyModule_AddIntConstant(m, "HIGHEST_PROTOCOL", HIGHEST_PROTOCOL);
+ if (i < 0)
+ return;
+
+ /* These are purely informational; no code uses them. */
+ /* File format version we write. */
+ format_version = PyString_FromString("2.0");
+ /* Format versions we can read. */
+ compatible_formats = Py_BuildValue("[sssss]",
+ "1.0", /* Original protocol 0 */
+ "1.1", /* Protocol 0 + INST */
+ "1.2", /* Original protocol 1 */
+ "1.3", /* Protocol 1 + BINFLOAT */
+ "2.0"); /* Original protocol 2 */
+ PyDict_SetItemString(d, "format_version", format_version);
+ PyDict_SetItemString(d, "compatible_formats", compatible_formats);
+ Py_XDECREF(format_version);
+ Py_XDECREF(compatible_formats);
+}
diff --git a/sys/src/cmd/python/Modules/cStringIO.c b/sys/src/cmd/python/Modules/cStringIO.c
new file mode 100644
index 000000000..100891ba4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cStringIO.c
@@ -0,0 +1,745 @@
+
+#include "Python.h"
+#include "import.h"
+#include "cStringIO.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(cStringIO_module_documentation,
+"A simple fast partial StringIO replacement.\n"
+"\n"
+"This module provides a simple useful replacement for\n"
+"the StringIO module that is written in C. It does not provide the\n"
+"full generality of StringIO, but it provides enough for most\n"
+"applications and is especially useful in conjunction with the\n"
+"pickle module.\n"
+"\n"
+"Usage:\n"
+"\n"
+" from cStringIO import StringIO\n"
+"\n"
+" an_output_stream=StringIO()\n"
+" an_output_stream.write(some_stuff)\n"
+" ...\n"
+" value=an_output_stream.getvalue()\n"
+"\n"
+" an_input_stream=StringIO(a_string)\n"
+" spam=an_input_stream.readline()\n"
+" spam=an_input_stream.read(5)\n"
+" an_input_stream.seek(0) # OK, start over\n"
+" spam=an_input_stream.read() # and read it all\n"
+" \n"
+"If someone else wants to provide a more complete implementation,\n"
+"go for it. :-) \n"
+"\n"
+"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
+
+/* Declaration for file-like objects that manage data as strings
+
+ The IOobject type should be though of as a common base type for
+ Iobjects, which provide input (read-only) StringIO objects and
+ Oobjects, which provide read-write objects. Most of the methods
+ depend only on common data.
+*/
+
+typedef struct {
+ PyObject_HEAD
+ char *buf;
+ Py_ssize_t pos, string_size;
+} IOobject;
+
+#define IOOOBJECT(O) ((IOobject*)(O))
+
+/* Declarations for objects of type StringO */
+
+typedef struct { /* Subtype of IOobject */
+ PyObject_HEAD
+ char *buf;
+ Py_ssize_t pos, string_size;
+
+ Py_ssize_t buf_size;
+ int softspace;
+} Oobject;
+
+/* Declarations for objects of type StringI */
+
+typedef struct { /* Subtype of IOobject */
+ PyObject_HEAD
+ char *buf;
+ Py_ssize_t pos, string_size;
+ /* We store a reference to the object here in order to keep
+ the buffer alive during the lifetime of the Iobject. */
+ PyObject *pbuf;
+} Iobject;
+
+/* IOobject (common) methods */
+
+PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
+
+static int
+IO__opencheck(IOobject *self) {
+ if (!self->buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "I/O operation on closed file");
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject *
+IO_get_closed(IOobject *self, void *closure)
+{
+ PyObject *result = Py_False;
+
+ if (self->buf == NULL)
+ result = Py_True;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyGetSetDef file_getsetlist[] = {
+ {"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
+ {0},
+};
+
+static PyObject *
+IO_flush(IOobject *self, PyObject *unused) {
+
+ if (!IO__opencheck(self)) return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(IO_getval__doc__,
+"getvalue([use_pos]) -- Get the string value."
+"\n"
+"If use_pos is specified and is a true value, then the string returned\n"
+"will include only the text up to the current file position.\n");
+
+static PyObject *
+IO_cgetval(PyObject *self) {
+ if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+ return PyString_FromStringAndSize(((IOobject*)self)->buf,
+ ((IOobject*)self)->pos);
+}
+
+static PyObject *
+IO_getval(IOobject *self, PyObject *args) {
+ PyObject *use_pos=Py_None;
+ Py_ssize_t s;
+
+ if (!IO__opencheck(self)) return NULL;
+ if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
+
+ if (PyObject_IsTrue(use_pos)) {
+ s=self->pos;
+ if (s > self->string_size) s=self->string_size;
+ }
+ else
+ s=self->string_size;
+ return PyString_FromStringAndSize(self->buf, s);
+}
+
+PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
+
+static PyObject *
+IO_isatty(IOobject *self, PyObject *unused) {
+ if (!IO__opencheck(self)) return NULL;
+ Py_INCREF(Py_False);
+ return Py_False;
+}
+
+PyDoc_STRVAR(IO_read__doc__,
+"read([s]) -- Read s characters, or the rest of the string");
+
+static int
+IO_cread(PyObject *self, char **output, Py_ssize_t n) {
+ Py_ssize_t l;
+
+ if (!IO__opencheck(IOOOBJECT(self))) return -1;
+ l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
+ if (n < 0 || n > l) {
+ n = l;
+ if (n < 0) n=0;
+ }
+
+ *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
+ ((IOobject*)self)->pos += n;
+ return n;
+}
+
+static PyObject *
+IO_read(IOobject *self, PyObject *args) {
+ Py_ssize_t n = -1;
+ char *output = NULL;
+
+ if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
+
+ if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
+
+ return PyString_FromStringAndSize(output, n);
+}
+
+PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
+
+static int
+IO_creadline(PyObject *self, char **output) {
+ char *n, *s;
+ Py_ssize_t l;
+
+ if (!IO__opencheck(IOOOBJECT(self))) return -1;
+
+ for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
+ s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
+ n < s && *n != '\n'; n++);
+ if (n < s) n++;
+
+ *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
+ l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
+ assert(((IOobject*)self)->pos + l < INT_MAX);
+ ((IOobject*)self)->pos += (int)l;
+ return (int)l;
+}
+
+static PyObject *
+IO_readline(IOobject *self, PyObject *args) {
+ int n, m=-1;
+ char *output;
+
+ if (args)
+ if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
+
+ if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
+ if (m >= 0 && m < n) {
+ m = n - m;
+ n -= m;
+ self->pos -= m;
+ }
+ return PyString_FromStringAndSize(output, n);
+}
+
+PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
+
+static PyObject *
+IO_readlines(IOobject *self, PyObject *args) {
+ int n;
+ char *output;
+ PyObject *result, *line;
+ int hint = 0, length = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
+
+ result = PyList_New(0);
+ if (!result)
+ return NULL;
+
+ while (1){
+ if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
+ goto err;
+ if (n == 0)
+ break;
+ line = PyString_FromStringAndSize (output, n);
+ if (!line)
+ goto err;
+ if (PyList_Append (result, line) == -1) {
+ Py_DECREF (line);
+ goto err;
+ }
+ Py_DECREF (line);
+ length += n;
+ if (hint > 0 && length >= hint)
+ break;
+ }
+ return result;
+ err:
+ Py_DECREF(result);
+ return NULL;
+}
+
+PyDoc_STRVAR(IO_reset__doc__,
+"reset() -- Reset the file position to the beginning");
+
+static PyObject *
+IO_reset(IOobject *self, PyObject *unused) {
+
+ if (!IO__opencheck(self)) return NULL;
+
+ self->pos = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
+
+static PyObject *
+IO_tell(IOobject *self, PyObject *unused) {
+
+ if (!IO__opencheck(self)) return NULL;
+
+ return PyInt_FromSsize_t(self->pos);
+}
+
+PyDoc_STRVAR(IO_truncate__doc__,
+"truncate(): truncate the file at the current position.");
+
+static PyObject *
+IO_truncate(IOobject *self, PyObject *args) {
+ Py_ssize_t pos = -1;
+
+ if (!IO__opencheck(self)) return NULL;
+ if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
+ if (pos < 0) pos = self->pos;
+
+ if (self->string_size > pos) self->string_size = pos;
+ self->pos = self->string_size;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+IO_iternext(Iobject *self)
+{
+ PyObject *next;
+ next = IO_readline((IOobject *)self, NULL);
+ if (!next)
+ return NULL;
+ if (!PyString_GET_SIZE(next)) {
+ Py_DECREF(next);
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
+ return next;
+}
+
+
+
+
+/* Read-write object methods */
+
+PyDoc_STRVAR(O_seek__doc__,
+"seek(position) -- set the current position\n"
+"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
+
+static PyObject *
+O_seek(Oobject *self, PyObject *args) {
+ Py_ssize_t position;
+ int mode = 0;
+
+ if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+ if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
+ return NULL;
+
+ if (mode == 2) {
+ position += self->string_size;
+ }
+ else if (mode == 1) {
+ position += self->pos;
+ }
+
+ if (position > self->buf_size) {
+ self->buf_size*=2;
+ if (self->buf_size <= position) self->buf_size=position+1;
+ self->buf = (char*) realloc(self->buf,self->buf_size);
+ if (!self->buf) {
+ self->buf_size=self->pos=0;
+ return PyErr_NoMemory();
+ }
+ }
+ else if (position < 0) position=0;
+
+ self->pos=position;
+
+ while (--position >= self->string_size) self->buf[position]=0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(O_write__doc__,
+"write(s) -- Write a string to the file"
+"\n\nNote (hack:) writing None resets the buffer");
+
+
+static int
+O_cwrite(PyObject *self, const char *c, Py_ssize_t l) {
+ Py_ssize_t newl;
+ Oobject *oself;
+
+ if (!IO__opencheck(IOOOBJECT(self))) return -1;
+ oself = (Oobject *)self;
+
+ newl = oself->pos+l;
+ if (newl >= oself->buf_size) {
+ oself->buf_size *= 2;
+ if (oself->buf_size <= newl) {
+ assert(newl + 1 < INT_MAX);
+ oself->buf_size = (int)(newl+1);
+ }
+ oself->buf = (char*)realloc(oself->buf, oself->buf_size);
+ if (!oself->buf) {
+ PyErr_SetString(PyExc_MemoryError,"out of memory");
+ oself->buf_size = oself->pos = 0;
+ return -1;
+ }
+ }
+
+ memcpy(oself->buf+oself->pos,c,l);
+
+ assert(oself->pos + l < INT_MAX);
+ oself->pos += (int)l;
+
+ if (oself->string_size < oself->pos) {
+ oself->string_size = oself->pos;
+ }
+
+ return (int)l;
+}
+
+static PyObject *
+O_write(Oobject *self, PyObject *args) {
+ char *c;
+ int l;
+
+ if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
+
+ if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
+
+static PyObject *
+O_close(Oobject *self, PyObject *unused) {
+ if (self->buf != NULL) free(self->buf);
+ self->buf = NULL;
+
+ self->pos = self->string_size = self->buf_size = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(O_writelines__doc__,
+"writelines(sequence_of_strings) -> None. Write the strings to the file.\n"
+"\n"
+"Note that newlines are not added. The sequence can be any iterable object\n"
+"producing strings. This is equivalent to calling write() for each string.");
+static PyObject *
+O_writelines(Oobject *self, PyObject *args) {
+ PyObject *it, *s;
+
+ it = PyObject_GetIter(args);
+ if (it == NULL)
+ return NULL;
+ while ((s = PyIter_Next(it)) != NULL) {
+ Py_ssize_t n;
+ char *c;
+ if (PyString_AsStringAndSize(s, &c, &n) == -1) {
+ Py_DECREF(it);
+ Py_DECREF(s);
+ return NULL;
+ }
+ if (O_cwrite((PyObject *)self, c, n) == -1) {
+ Py_DECREF(it);
+ Py_DECREF(s);
+ return NULL;
+ }
+ Py_DECREF(s);
+ }
+
+ Py_DECREF(it);
+
+ /* See if PyIter_Next failed */
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+static struct PyMethodDef O_methods[] = {
+ /* Common methods: */
+ {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
+ {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
+ {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
+ {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
+ {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
+ {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
+ {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
+ {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
+ {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
+
+ /* Read-write StringIO specific methods: */
+ {"close", (PyCFunction)O_close, METH_NOARGS, O_close__doc__},
+ {"seek", (PyCFunction)O_seek, METH_VARARGS, O_seek__doc__},
+ {"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__},
+ {"writelines", (PyCFunction)O_writelines, METH_O, O_writelines__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyMemberDef O_memberlist[] = {
+ {"softspace", T_INT, offsetof(Oobject, softspace), 0,
+ "flag indicating that a space needs to be printed; used by print"},
+ /* getattr(f, "closed") is implemented without this table */
+ {NULL} /* Sentinel */
+};
+
+static void
+O_dealloc(Oobject *self) {
+ if (self->buf != NULL)
+ free(self->buf);
+ PyObject_Del(self);
+}
+
+PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
+
+static PyTypeObject Otype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "cStringIO.StringO", /*tp_name*/
+ sizeof(Oobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)O_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr */
+ 0, /*tp_setattr */
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0 , /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro */
+ 0, /*tp_setattro */
+ 0, /*tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Otype__doc__, /*tp_doc */
+ 0, /*tp_traverse */
+ 0, /*tp_clear */
+ 0, /*tp_richcompare */
+ 0, /*tp_weaklistoffset */
+ PyObject_SelfIter, /*tp_iter */
+ (iternextfunc)IO_iternext, /*tp_iternext */
+ O_methods, /*tp_methods */
+ O_memberlist, /*tp_members */
+ file_getsetlist, /*tp_getset */
+};
+
+static PyObject *
+newOobject(int size) {
+ Oobject *self;
+
+ self = PyObject_New(Oobject, &Otype);
+ if (self == NULL)
+ return NULL;
+ self->pos=0;
+ self->string_size = 0;
+ self->softspace = 0;
+
+ self->buf = (char *)malloc(size);
+ if (!self->buf) {
+ PyErr_SetString(PyExc_MemoryError,"out of memory");
+ self->buf_size = 0;
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ self->buf_size=size;
+ return (PyObject*)self;
+}
+
+/* End of code for StringO objects */
+/* -------------------------------------------------------- */
+
+static PyObject *
+I_close(Iobject *self, PyObject *unused) {
+ Py_XDECREF(self->pbuf);
+ self->pbuf = NULL;
+ self->buf = NULL;
+
+ self->pos = self->string_size = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+I_seek(Iobject *self, PyObject *args) {
+ Py_ssize_t position;
+ int mode = 0;
+
+ if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+ if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
+ return NULL;
+
+ if (mode == 2) position += self->string_size;
+ else if (mode == 1) position += self->pos;
+
+ if (position < 0) position=0;
+
+ self->pos=position;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static struct PyMethodDef I_methods[] = {
+ /* Common methods: */
+ {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
+ {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
+ {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
+ {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
+ {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
+ {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
+ {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
+ {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
+ {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
+
+ /* Read-only StringIO specific methods: */
+ {"close", (PyCFunction)I_close, METH_NOARGS, O_close__doc__},
+ {"seek", (PyCFunction)I_seek, METH_VARARGS, O_seek__doc__},
+ {NULL, NULL}
+};
+
+static void
+I_dealloc(Iobject *self) {
+ Py_XDECREF(self->pbuf);
+ PyObject_Del(self);
+}
+
+
+PyDoc_STRVAR(Itype__doc__,
+"Simple type for treating strings as input file streams");
+
+static PyTypeObject Itype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "cStringIO.StringI", /*tp_name*/
+ sizeof(Iobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)I_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /* tp_getattr */
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Itype__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)IO_iternext, /* tp_iternext */
+ I_methods, /* tp_methods */
+ 0, /* tp_members */
+ file_getsetlist, /* tp_getset */
+};
+
+static PyObject *
+newIobject(PyObject *s) {
+ Iobject *self;
+ char *buf;
+ Py_ssize_t size;
+
+ if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
+ return NULL;
+
+ self = PyObject_New(Iobject, &Itype);
+ if (!self) return NULL;
+ Py_INCREF(s);
+ self->buf=buf;
+ self->string_size=size;
+ self->pbuf=s;
+ self->pos=0;
+
+ return (PyObject*)self;
+}
+
+/* End of code for StringI objects */
+/* -------------------------------------------------------- */
+
+
+PyDoc_STRVAR(IO_StringIO__doc__,
+"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
+
+static PyObject *
+IO_StringIO(PyObject *self, PyObject *args) {
+ PyObject *s=0;
+
+ if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
+
+ if (s) return newIobject(s);
+ return newOobject(128);
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef IO_methods[] = {
+ {"StringIO", (PyCFunction)IO_StringIO,
+ METH_VARARGS, IO_StringIO__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initcStringIO) */
+
+static struct PycStringIO_CAPI CAPI = {
+ IO_cread,
+ IO_creadline,
+ O_cwrite,
+ IO_cgetval,
+ newOobject,
+ newIobject,
+ &Itype,
+ &Otype,
+};
+
+#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initcStringIO(void) {
+ PyObject *m, *d, *v;
+
+
+ /* Create the module and add the functions */
+ m = Py_InitModule4("cStringIO", IO_methods,
+ cStringIO_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+ if (m == NULL) return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+
+ /* Export C API */
+ Itype.ob_type=&PyType_Type;
+ Otype.ob_type=&PyType_Type;
+ if (PyType_Ready(&Otype) < 0) return;
+ if (PyType_Ready(&Itype) < 0) return;
+ PyDict_SetItemString(d,"cStringIO_CAPI",
+ v = PyCObject_FromVoidPtr(&CAPI,NULL));
+ Py_XDECREF(v);
+
+ /* Export Types */
+ PyDict_SetItemString(d,"InputType", (PyObject*)&Itype);
+ PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
+
+ /* Maybe make certain warnings go away */
+ if (0) PycString_IMPORT;
+}
diff --git a/sys/src/cmd/python/Modules/cdmodule.c b/sys/src/cmd/python/Modules/cdmodule.c
new file mode 100644
index 000000000..f8efd395a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cdmodule.c
@@ -0,0 +1,796 @@
+/* CD module -- interface to Mark Callow's and Roger Chickering's */
+ /* CD Audio Library (CD). */
+
+#include <sys/types.h>
+#include <cdaudio.h>
+#include "Python.h"
+
+#define NCALLBACKS 8
+
+typedef struct {
+ PyObject_HEAD
+ CDPLAYER *ob_cdplayer;
+} cdplayerobject;
+
+static PyObject *CdError; /* exception cd.error */
+
+static PyObject *
+CD_allowremoval(cdplayerobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":allowremoval"))
+ return NULL;
+
+ CDallowremoval(self->ob_cdplayer);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_preventremoval(cdplayerobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":preventremoval"))
+ return NULL;
+
+ CDpreventremoval(self->ob_cdplayer);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_bestreadsize(cdplayerobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":bestreadsize"))
+ return NULL;
+
+ return PyInt_FromLong((long) CDbestreadsize(self->ob_cdplayer));
+}
+
+static PyObject *
+CD_close(cdplayerobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":close"))
+ return NULL;
+
+ if (!CDclose(self->ob_cdplayer)) {
+ PyErr_SetFromErrno(CdError); /* XXX - ??? */
+ return NULL;
+ }
+ self->ob_cdplayer = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_eject(cdplayerobject *self, PyObject *args)
+{
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, ":eject"))
+ return NULL;
+
+ if (!CDeject(self->ob_cdplayer)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "eject failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_getstatus(cdplayerobject *self, PyObject *args)
+{
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, ":getstatus"))
+ return NULL;
+
+ if (!CDgetstatus(self->ob_cdplayer, &status)) {
+ PyErr_SetFromErrno(CdError); /* XXX - ??? */
+ return NULL;
+ }
+
+ return Py_BuildValue("(ii(iii)(iii)(iii)iiii)", status.state,
+ status.track, status.min, status.sec, status.frame,
+ status.abs_min, status.abs_sec, status.abs_frame,
+ status.total_min, status.total_sec, status.total_frame,
+ status.first, status.last, status.scsi_audio,
+ status.cur_block);
+}
+
+static PyObject *
+CD_gettrackinfo(cdplayerobject *self, PyObject *args)
+{
+ int track;
+ CDTRACKINFO info;
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "i:gettrackinfo", &track))
+ return NULL;
+
+ if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "gettrackinfo failed");
+ return NULL;
+ }
+
+ return Py_BuildValue("((iii)(iii))",
+ info.start_min, info.start_sec, info.start_frame,
+ info.total_min, info.total_sec, info.total_frame);
+}
+
+static PyObject *
+CD_msftoblock(cdplayerobject *self, PyObject *args)
+{
+ int min, sec, frame;
+
+ if (!PyArg_ParseTuple(args, "iii:msftoblock", &min, &sec, &frame))
+ return NULL;
+
+ return PyInt_FromLong((long) CDmsftoblock(self->ob_cdplayer,
+ min, sec, frame));
+}
+
+static PyObject *
+CD_play(cdplayerobject *self, PyObject *args)
+{
+ int start, play;
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "ii:play", &start, &play))
+ return NULL;
+
+ if (!CDplay(self->ob_cdplayer, start, play)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "play failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_playabs(cdplayerobject *self, PyObject *args)
+{
+ int min, sec, frame, play;
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "iiii:playabs", &min, &sec, &frame, &play))
+ return NULL;
+
+ if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "playabs failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_playtrack(cdplayerobject *self, PyObject *args)
+{
+ int start, play;
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "ii:playtrack", &start, &play))
+ return NULL;
+
+ if (!CDplaytrack(self->ob_cdplayer, start, play)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "playtrack failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_playtrackabs(cdplayerobject *self, PyObject *args)
+{
+ int track, min, sec, frame, play;
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, "iiiii:playtrackabs", &track, &min, &sec,
+ &frame, &play))
+ return NULL;
+
+ if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "playtrackabs failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_readda(cdplayerobject *self, PyObject *args)
+{
+ int numframes, n;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "i:readda", &numframes))
+ return NULL;
+
+ result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME));
+ if (result == NULL)
+ return NULL;
+
+ n = CDreadda(self->ob_cdplayer,
+ (CDFRAME *) PyString_AsString(result), numframes);
+ if (n == -1) {
+ Py_DECREF(result);
+ PyErr_SetFromErrno(CdError);
+ return NULL;
+ }
+ if (n < numframes)
+ _PyString_Resize(&result, n * sizeof(CDFRAME));
+
+ return result;
+}
+
+static PyObject *
+CD_seek(cdplayerobject *self, PyObject *args)
+{
+ int min, sec, frame;
+ long PyTryBlock;
+
+ if (!PyArg_ParseTuple(args, "iii:seek", &min, &sec, &frame))
+ return NULL;
+
+ PyTryBlock = CDseek(self->ob_cdplayer, min, sec, frame);
+ if (PyTryBlock == -1) {
+ PyErr_SetFromErrno(CdError);
+ return NULL;
+ }
+
+ return PyInt_FromLong(PyTryBlock);
+}
+
+static PyObject *
+CD_seektrack(cdplayerobject *self, PyObject *args)
+{
+ int track;
+ long PyTryBlock;
+
+ if (!PyArg_ParseTuple(args, "i:seektrack", &track))
+ return NULL;
+
+ PyTryBlock = CDseektrack(self->ob_cdplayer, track);
+ if (PyTryBlock == -1) {
+ PyErr_SetFromErrno(CdError);
+ return NULL;
+ }
+
+ return PyInt_FromLong(PyTryBlock);
+}
+
+static PyObject *
+CD_seekblock(cdplayerobject *self, PyObject *args)
+{
+ unsigned long PyTryBlock;
+
+ if (!PyArg_ParseTuple(args, "l:seekblock", &PyTryBlock))
+ return NULL;
+
+ PyTryBlock = CDseekblock(self->ob_cdplayer, PyTryBlock);
+ if (PyTryBlock == (unsigned long) -1) {
+ PyErr_SetFromErrno(CdError);
+ return NULL;
+ }
+
+ return PyInt_FromLong(PyTryBlock);
+}
+
+static PyObject *
+CD_stop(cdplayerobject *self, PyObject *args)
+{
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, ":stop"))
+ return NULL;
+
+ if (!CDstop(self->ob_cdplayer)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "stop failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_togglepause(cdplayerobject *self, PyObject *args)
+{
+ CDSTATUS status;
+
+ if (!PyArg_ParseTuple(args, ":togglepause"))
+ return NULL;
+
+ if (!CDtogglepause(self->ob_cdplayer)) {
+ if (CDgetstatus(self->ob_cdplayer, &status) &&
+ status.state == CD_NODISC)
+ PyErr_SetString(CdError, "no disc in player");
+ else
+ PyErr_SetString(CdError, "togglepause failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef cdplayer_methods[] = {
+ {"allowremoval", (PyCFunction)CD_allowremoval, METH_VARARGS},
+ {"bestreadsize", (PyCFunction)CD_bestreadsize, METH_VARARGS},
+ {"close", (PyCFunction)CD_close, METH_VARARGS},
+ {"eject", (PyCFunction)CD_eject, METH_VARARGS},
+ {"getstatus", (PyCFunction)CD_getstatus, METH_VARARGS},
+ {"gettrackinfo", (PyCFunction)CD_gettrackinfo, METH_VARARGS},
+ {"msftoblock", (PyCFunction)CD_msftoblock, METH_VARARGS},
+ {"play", (PyCFunction)CD_play, METH_VARARGS},
+ {"playabs", (PyCFunction)CD_playabs, METH_VARARGS},
+ {"playtrack", (PyCFunction)CD_playtrack, METH_VARARGS},
+ {"playtrackabs", (PyCFunction)CD_playtrackabs, METH_VARARGS},
+ {"preventremoval", (PyCFunction)CD_preventremoval, METH_VARARGS},
+ {"readda", (PyCFunction)CD_readda, METH_VARARGS},
+ {"seek", (PyCFunction)CD_seek, METH_VARARGS},
+ {"seekblock", (PyCFunction)CD_seekblock, METH_VARARGS},
+ {"seektrack", (PyCFunction)CD_seektrack, METH_VARARGS},
+ {"stop", (PyCFunction)CD_stop, METH_VARARGS},
+ {"togglepause", (PyCFunction)CD_togglepause, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+cdplayer_dealloc(cdplayerobject *self)
+{
+ if (self->ob_cdplayer != NULL)
+ CDclose(self->ob_cdplayer);
+ PyObject_Del(self);
+}
+
+static PyObject *
+cdplayer_getattr(cdplayerobject *self, char *name)
+{
+ if (self->ob_cdplayer == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "no player active");
+ return NULL;
+ }
+ return Py_FindMethod(cdplayer_methods, (PyObject *)self, name);
+}
+
+PyTypeObject CdPlayertype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "cd.cdplayer", /*tp_name*/
+ sizeof(cdplayerobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cdplayer_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)cdplayer_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyObject *
+newcdplayerobject(CDPLAYER *cdp)
+{
+ cdplayerobject *p;
+
+ p = PyObject_New(cdplayerobject, &CdPlayertype);
+ if (p == NULL)
+ return NULL;
+ p->ob_cdplayer = cdp;
+ return (PyObject *) p;
+}
+
+static PyObject *
+CD_open(PyObject *self, PyObject *args)
+{
+ char *dev, *direction;
+ CDPLAYER *cdp;
+
+ /*
+ * Variable number of args.
+ * First defaults to "None", second defaults to "r".
+ */
+ dev = NULL;
+ direction = "r";
+ if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction))
+ return NULL;
+
+ cdp = CDopen(dev, direction);
+ if (cdp == NULL) {
+ PyErr_SetFromErrno(CdError);
+ return NULL;
+ }
+
+ return newcdplayerobject(cdp);
+}
+
+typedef struct {
+ PyObject_HEAD
+ CDPARSER *ob_cdparser;
+ struct {
+ PyObject *ob_cdcallback;
+ PyObject *ob_cdcallbackarg;
+ } ob_cdcallbacks[NCALLBACKS];
+} cdparserobject;
+
+static void
+CD_callback(void *arg, CDDATATYPES type, void *data)
+{
+ PyObject *result, *args, *v = NULL;
+ char *p;
+ int i;
+ cdparserobject *self;
+
+ self = (cdparserobject *) arg;
+ args = PyTuple_New(3);
+ if (args == NULL)
+ return;
+ Py_INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+ PyTuple_SetItem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
+ PyTuple_SetItem(args, 1, PyInt_FromLong((long) type));
+ switch (type) {
+ case cd_audio:
+ v = PyString_FromStringAndSize(data, CDDA_DATASIZE);
+ break;
+ case cd_pnum:
+ case cd_index:
+ v = PyInt_FromLong(((CDPROGNUM *) data)->value);
+ break;
+ case cd_ptime:
+ case cd_atime:
+#define ptr ((struct cdtimecode *) data)
+ v = Py_BuildValue("(iii)",
+ ptr->mhi * 10 + ptr->mlo,
+ ptr->shi * 10 + ptr->slo,
+ ptr->fhi * 10 + ptr->flo);
+#undef ptr
+ break;
+ case cd_catalog:
+ v = PyString_FromStringAndSize(NULL, 13);
+ p = PyString_AsString(v);
+ for (i = 0; i < 13; i++)
+ *p++ = ((char *) data)[i] + '0';
+ break;
+ case cd_ident:
+#define ptr ((struct cdident *) data)
+ v = PyString_FromStringAndSize(NULL, 12);
+ p = PyString_AsString(v);
+ CDsbtoa(p, ptr->country, 2);
+ p += 2;
+ CDsbtoa(p, ptr->owner, 3);
+ p += 3;
+ *p++ = ptr->year[0] + '0';
+ *p++ = ptr->year[1] + '0';
+ *p++ = ptr->serial[0] + '0';
+ *p++ = ptr->serial[1] + '0';
+ *p++ = ptr->serial[2] + '0';
+ *p++ = ptr->serial[3] + '0';
+ *p++ = ptr->serial[4] + '0';
+#undef ptr
+ break;
+ case cd_control:
+ v = PyInt_FromLong((long) *((unchar *) data));
+ break;
+ }
+ PyTuple_SetItem(args, 2, v);
+ if (PyErr_Occurred()) {
+ Py_DECREF(args);
+ return;
+ }
+
+ result = PyEval_CallObject(self->ob_cdcallbacks[type].ob_cdcallback,
+ args);
+ Py_DECREF(args);
+ Py_XDECREF(result);
+}
+
+static PyObject *
+CD_deleteparser(cdparserobject *self, PyObject *args)
+{
+ int i;
+
+ if (!PyArg_ParseTuple(args, ":deleteparser"))
+ return NULL;
+
+ CDdeleteparser(self->ob_cdparser);
+ self->ob_cdparser = NULL;
+
+ /* no sense in keeping the callbacks, so remove them */
+ for (i = 0; i < NCALLBACKS; i++) {
+ Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
+ self->ob_cdcallbacks[i].ob_cdcallback = NULL;
+ Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
+ self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_parseframe(cdparserobject *self, PyObject *args)
+{
+ char *cdfp;
+ int length;
+ CDFRAME *p;
+
+ if (!PyArg_ParseTuple(args, "s#:parseframe", &cdfp, &length))
+ return NULL;
+
+ if (length % sizeof(CDFRAME) != 0) {
+ PyErr_SetString(PyExc_TypeError, "bad length");
+ return NULL;
+ }
+
+ p = (CDFRAME *) cdfp;
+ while (length > 0) {
+ CDparseframe(self->ob_cdparser, p);
+ length -= sizeof(CDFRAME);
+ p++;
+ if (PyErr_Occurred())
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_removecallback(cdparserobject *self, PyObject *args)
+{
+ int type;
+
+ if (!PyArg_ParseTuple(args, "i:removecallback", &type))
+ return NULL;
+
+ if (type < 0 || type >= NCALLBACKS) {
+ PyErr_SetString(PyExc_TypeError, "bad type");
+ return NULL;
+ }
+
+ CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
+
+ Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
+ self->ob_cdcallbacks[type].ob_cdcallback = NULL;
+
+ Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+ self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_resetparser(cdparserobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":resetparser"))
+ return NULL;
+
+ CDresetparser(self->ob_cdparser);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+CD_addcallback(cdparserobject *self, PyObject *args)
+{
+ int type;
+ PyObject *func, *funcarg;
+
+ /* XXX - more work here */
+ if (!PyArg_ParseTuple(args, "iOO:addcallback", &type, &func, &funcarg))
+ return NULL;
+
+ if (type < 0 || type >= NCALLBACKS) {
+ PyErr_SetString(PyExc_TypeError, "argument out of range");
+ return NULL;
+ }
+
+#ifdef CDsetcallback
+ CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
+ (void *) self);
+#else
+ CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
+ (void *) self);
+#endif
+ Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
+ Py_INCREF(func);
+ self->ob_cdcallbacks[type].ob_cdcallback = func;
+ Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+ Py_INCREF(funcarg);
+ self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
+
+/*
+ if (type == cd_audio) {
+ sigfpe_[_UNDERFL].repls = _ZERO;
+ handle_sigfpes(_ON, _EN_UNDERFL, NULL,
+ _ABORT_ON_ERROR, NULL);
+ }
+*/
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef cdparser_methods[] = {
+ {"addcallback", (PyCFunction)CD_addcallback, METH_VARARGS},
+ {"deleteparser", (PyCFunction)CD_deleteparser, METH_VARARGS},
+ {"parseframe", (PyCFunction)CD_parseframe, METH_VARARGS},
+ {"removecallback", (PyCFunction)CD_removecallback, METH_VARARGS},
+ {"resetparser", (PyCFunction)CD_resetparser, METH_VARARGS},
+ /* backward compatibility */
+ {"setcallback", (PyCFunction)CD_addcallback, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+cdparser_dealloc(cdparserobject *self)
+{
+ int i;
+
+ for (i = 0; i < NCALLBACKS; i++) {
+ Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
+ self->ob_cdcallbacks[i].ob_cdcallback = NULL;
+ Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
+ self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
+ }
+ CDdeleteparser(self->ob_cdparser);
+ PyObject_Del(self);
+}
+
+static PyObject *
+cdparser_getattr(cdparserobject *self, char *name)
+{
+ if (self->ob_cdparser == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "no parser active");
+ return NULL;
+ }
+
+ return Py_FindMethod(cdparser_methods, (PyObject *)self, name);
+}
+
+PyTypeObject CdParsertype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "cd.cdparser", /*tp_name*/
+ sizeof(cdparserobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cdparser_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)cdparser_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyObject *
+newcdparserobject(CDPARSER *cdp)
+{
+ cdparserobject *p;
+ int i;
+
+ p = PyObject_New(cdparserobject, &CdParsertype);
+ if (p == NULL)
+ return NULL;
+ p->ob_cdparser = cdp;
+ for (i = 0; i < NCALLBACKS; i++) {
+ p->ob_cdcallbacks[i].ob_cdcallback = NULL;
+ p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
+ }
+ return (PyObject *) p;
+}
+
+static PyObject *
+CD_createparser(PyObject *self, PyObject *args)
+{
+ CDPARSER *cdp;
+
+ if (!PyArg_ParseTuple(args, ":createparser"))
+ return NULL;
+ cdp = CDcreateparser();
+ if (cdp == NULL) {
+ PyErr_SetString(CdError, "createparser failed");
+ return NULL;
+ }
+
+ return newcdparserobject(cdp);
+}
+
+static PyObject *
+CD_msftoframe(PyObject *self, PyObject *args)
+{
+ int min, sec, frame;
+
+ if (!PyArg_ParseTuple(args, "iii:msftoframe", &min, &sec, &frame))
+ return NULL;
+
+ return PyInt_FromLong((long) CDmsftoframe(min, sec, frame));
+}
+
+static PyMethodDef CD_methods[] = {
+ {"open", (PyCFunction)CD_open, METH_VARARGS},
+ {"createparser", (PyCFunction)CD_createparser, METH_VARARGS},
+ {"msftoframe", (PyCFunction)CD_msftoframe, METH_VARARGS},
+ {NULL, NULL} /* Sentinel */
+};
+
+void
+initcd(void)
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule("cd", CD_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ CdError = PyErr_NewException("cd.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", CdError);
+
+ /* Identifiers for the different types of callbacks from the parser */
+ PyDict_SetItemString(d, "audio", PyInt_FromLong((long) cd_audio));
+ PyDict_SetItemString(d, "pnum", PyInt_FromLong((long) cd_pnum));
+ PyDict_SetItemString(d, "index", PyInt_FromLong((long) cd_index));
+ PyDict_SetItemString(d, "ptime", PyInt_FromLong((long) cd_ptime));
+ PyDict_SetItemString(d, "atime", PyInt_FromLong((long) cd_atime));
+ PyDict_SetItemString(d, "catalog", PyInt_FromLong((long) cd_catalog));
+ PyDict_SetItemString(d, "ident", PyInt_FromLong((long) cd_ident));
+ PyDict_SetItemString(d, "control", PyInt_FromLong((long) cd_control));
+
+ /* Block size information for digital audio data */
+ PyDict_SetItemString(d, "DATASIZE",
+ PyInt_FromLong((long) CDDA_DATASIZE));
+ PyDict_SetItemString(d, "BLOCKSIZE",
+ PyInt_FromLong((long) CDDA_BLOCKSIZE));
+
+ /* Possible states for the cd player */
+ PyDict_SetItemString(d, "ERROR", PyInt_FromLong((long) CD_ERROR));
+ PyDict_SetItemString(d, "NODISC", PyInt_FromLong((long) CD_NODISC));
+ PyDict_SetItemString(d, "READY", PyInt_FromLong((long) CD_READY));
+ PyDict_SetItemString(d, "PLAYING", PyInt_FromLong((long) CD_PLAYING));
+ PyDict_SetItemString(d, "PAUSED", PyInt_FromLong((long) CD_PAUSED));
+ PyDict_SetItemString(d, "STILL", PyInt_FromLong((long) CD_STILL));
+#ifdef CD_CDROM /* only newer versions of the library */
+ PyDict_SetItemString(d, "CDROM", PyInt_FromLong((long) CD_CDROM));
+#endif
+}
diff --git a/sys/src/cmd/python/Modules/cgen.py b/sys/src/cmd/python/Modules/cgen.py
new file mode 100644
index 000000000..f07d9843b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cgen.py
@@ -0,0 +1,520 @@
+########################################################################
+# Copyright (c) 2000, BeOpen.com.
+# Copyright (c) 1995-2000, Corporation for National Research Initiatives.
+# Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
+# All rights reserved.
+#
+# See the file "Misc/COPYRIGHT" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+########################################################################
+
+# Python script to parse cstubs file for gl and generate C stubs.
+# usage: python cgen.py <cstubs >glmodule.c
+#
+# NOTE: You must first make a python binary without the "GL" option
+# before you can run this, when building Python for the first time.
+# See comments in the Makefile.
+#
+# XXX BUG return arrays generate wrong code
+# XXX need to change error returns into gotos to free mallocked arrays
+
+
+import string
+import sys
+
+
+# Function to print to stderr
+#
+def err(*args):
+ savestdout = sys.stdout
+ try:
+ sys.stdout = sys.stderr
+ for i in args:
+ print i,
+ print
+ finally:
+ sys.stdout = savestdout
+
+
+# The set of digits that form a number
+#
+digits = '0123456789'
+
+
+# Function to extract a string of digits from the front of the string.
+# Returns the leading string of digits and the remaining string.
+# If no number is found, returns '' and the original string.
+#
+def getnum(s):
+ n = ''
+ while s and s[0] in digits:
+ n = n + s[0]
+ s = s[1:]
+ return n, s
+
+
+# Function to check if a string is a number
+#
+def isnum(s):
+ if not s: return False
+ for c in s:
+ if not c in digits: return False
+ return True
+
+
+# Allowed function return types
+#
+return_types = ['void', 'short', 'long']
+
+
+# Allowed function argument types
+#
+arg_types = ['char', 'string', 'short', 'u_short', 'float', 'long', 'double']
+
+
+# Need to classify arguments as follows
+# simple input variable
+# simple output variable
+# input array
+# output array
+# input giving size of some array
+#
+# Array dimensions can be specified as follows
+# constant
+# argN
+# constant * argN
+# retval
+# constant * retval
+#
+# The dimensions given as constants * something are really
+# arrays of points where points are 2- 3- or 4-tuples
+#
+# We have to consider three lists:
+# python input arguments
+# C stub arguments (in & out)
+# python output arguments (really return values)
+#
+# There is a mapping from python input arguments to the input arguments
+# of the C stub, and a further mapping from C stub arguments to the
+# python return values
+
+
+# Exception raised by checkarg() and generate()
+#
+arg_error = 'bad arg'
+
+
+# Function to check one argument.
+# Arguments: the type and the arg "name" (really mode plus subscript).
+# Raises arg_error if something's wrong.
+# Return type, mode, factor, rest of subscript; factor and rest may be empty.
+#
+def checkarg(type, arg):
+ #
+ # Turn "char *x" into "string x".
+ #
+ if type == 'char' and arg[0] == '*':
+ type = 'string'
+ arg = arg[1:]
+ #
+ # Check that the type is supported.
+ #
+ if type not in arg_types:
+ raise arg_error, ('bad type', type)
+ if type[:2] == 'u_':
+ type = 'unsigned ' + type[2:]
+ #
+ # Split it in the mode (first character) and the rest.
+ #
+ mode, rest = arg[:1], arg[1:]
+ #
+ # The mode must be 's' for send (= input) or 'r' for return argument.
+ #
+ if mode not in ('r', 's'):
+ raise arg_error, ('bad arg mode', mode)
+ #
+ # Is it a simple argument: if so, we are done.
+ #
+ if not rest:
+ return type, mode, '', ''
+ #
+ # Not a simple argument; must be an array.
+ # The 'rest' must be a subscript enclosed in [ and ].
+ # The subscript must be one of the following forms,
+ # otherwise we don't handle it (where N is a number):
+ # N
+ # argN
+ # retval
+ # N*argN
+ # N*retval
+ #
+ if rest[:1] <> '[' or rest[-1:] <> ']':
+ raise arg_error, ('subscript expected', rest)
+ sub = rest[1:-1]
+ #
+ # Is there a leading number?
+ #
+ num, sub = getnum(sub)
+ if num:
+ # There is a leading number
+ if not sub:
+ # The subscript is just a number
+ return type, mode, num, ''
+ if sub[:1] == '*':
+ # There is a factor prefix
+ sub = sub[1:]
+ else:
+ raise arg_error, ('\'*\' expected', sub)
+ if sub == 'retval':
+ # size is retval -- must be a reply argument
+ if mode <> 'r':
+ raise arg_error, ('non-r mode with [retval]', mode)
+ elif not isnum(sub) and (sub[:3] <> 'arg' or not isnum(sub[3:])):
+ raise arg_error, ('bad subscript', sub)
+ #
+ return type, mode, num, sub
+
+
+# List of functions for which we have generated stubs
+#
+functions = []
+
+
+# Generate the stub for the given function, using the database of argument
+# information build by successive calls to checkarg()
+#
+def generate(type, func, database):
+ #
+ # Check that we can handle this case:
+ # no variable size reply arrays yet
+ #
+ n_in_args = 0
+ n_out_args = 0
+ #
+ for a_type, a_mode, a_factor, a_sub in database:
+ if a_mode == 's':
+ n_in_args = n_in_args + 1
+ elif a_mode == 'r':
+ n_out_args = n_out_args + 1
+ else:
+ # Can't happen
+ raise arg_error, ('bad a_mode', a_mode)
+ if (a_mode == 'r' and a_sub) or a_sub == 'retval':
+ err('Function', func, 'too complicated:',
+ a_type, a_mode, a_factor, a_sub)
+ print '/* XXX Too complicated to generate code for */'
+ return
+ #
+ functions.append(func)
+ #
+ # Stub header
+ #
+ print
+ print 'static PyObject *'
+ print 'gl_' + func + '(self, args)'
+ print '\tPyObject *self;'
+ print '\tPyObject *args;'
+ print '{'
+ #
+ # Declare return value if any
+ #
+ if type <> 'void':
+ print '\t' + type, 'retval;'
+ #
+ # Declare arguments
+ #
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ print '\t' + a_type,
+ brac = ket = ''
+ if a_sub and not isnum(a_sub):
+ if a_factor:
+ brac = '('
+ ket = ')'
+ print brac + '*',
+ print 'arg' + repr(i+1) + ket,
+ if a_sub and isnum(a_sub):
+ print '[', a_sub, ']',
+ if a_factor:
+ print '[', a_factor, ']',
+ print ';'
+ #
+ # Find input arguments derived from array sizes
+ #
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_mode == 's' and a_sub[:3] == 'arg' and isnum(a_sub[3:]):
+ # Sending a variable-length array
+ n = eval(a_sub[3:])
+ if 1 <= n <= len(database):
+ b_type, b_mode, b_factor, b_sub = database[n-1]
+ if b_mode == 's':
+ database[n-1] = b_type, 'i', a_factor, repr(i)
+ n_in_args = n_in_args - 1
+ #
+ # Assign argument positions in the Python argument list
+ #
+ in_pos = []
+ i_in = 0
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_mode == 's':
+ in_pos.append(i_in)
+ i_in = i_in + 1
+ else:
+ in_pos.append(-1)
+ #
+ # Get input arguments
+ #
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_type[:9] == 'unsigned ':
+ xtype = a_type[9:]
+ else:
+ xtype = a_type
+ if a_mode == 'i':
+ #
+ # Implicit argument;
+ # a_factor is divisor if present,
+ # a_sub indicates which arg (`database index`)
+ #
+ j = eval(a_sub)
+ print '\tif',
+ print '(!geti' + xtype + 'arraysize(args,',
+ print repr(n_in_args) + ',',
+ print repr(in_pos[j]) + ',',
+ if xtype <> a_type:
+ print '('+xtype+' *)',
+ print '&arg' + repr(i+1) + '))'
+ print '\t\treturn NULL;'
+ if a_factor:
+ print '\targ' + repr(i+1),
+ print '= arg' + repr(i+1),
+ print '/', a_factor + ';'
+ elif a_mode == 's':
+ if a_sub and not isnum(a_sub):
+ # Allocate memory for varsize array
+ print '\tif ((arg' + repr(i+1), '=',
+ if a_factor:
+ print '('+a_type+'(*)['+a_factor+'])',
+ print 'PyMem_NEW(' + a_type, ',',
+ if a_factor:
+ print a_factor, '*',
+ print a_sub, ')) == NULL)'
+ print '\t\treturn PyErr_NoMemory();'
+ print '\tif',
+ if a_factor or a_sub: # Get a fixed-size array array
+ print '(!geti' + xtype + 'array(args,',
+ print repr(n_in_args) + ',',
+ print repr(in_pos[i]) + ',',
+ if a_factor: print a_factor,
+ if a_factor and a_sub: print '*',
+ if a_sub: print a_sub,
+ print ',',
+ if (a_sub and a_factor) or xtype <> a_type:
+ print '('+xtype+' *)',
+ print 'arg' + repr(i+1) + '))'
+ else: # Get a simple variable
+ print '(!geti' + xtype + 'arg(args,',
+ print repr(n_in_args) + ',',
+ print repr(in_pos[i]) + ',',
+ if xtype <> a_type:
+ print '('+xtype+' *)',
+ print '&arg' + repr(i+1) + '))'
+ print '\t\treturn NULL;'
+ #
+ # Begin of function call
+ #
+ if type <> 'void':
+ print '\tretval =', func + '(',
+ else:
+ print '\t' + func + '(',
+ #
+ # Argument list
+ #
+ for i in range(len(database)):
+ if i > 0: print ',',
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_mode == 'r' and not a_factor:
+ print '&',
+ print 'arg' + repr(i+1),
+ #
+ # End of function call
+ #
+ print ');'
+ #
+ # Free varsize arrays
+ #
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_mode == 's' and a_sub and not isnum(a_sub):
+ print '\tPyMem_DEL(arg' + repr(i+1) + ');'
+ #
+ # Return
+ #
+ if n_out_args:
+ #
+ # Multiple return values -- construct a tuple
+ #
+ if type <> 'void':
+ n_out_args = n_out_args + 1
+ if n_out_args == 1:
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_mode == 'r':
+ break
+ else:
+ raise arg_error, 'expected r arg not found'
+ print '\treturn',
+ print mkobject(a_type, 'arg' + repr(i+1)) + ';'
+ else:
+ print '\t{ PyObject *v = PyTuple_New(',
+ print n_out_args, ');'
+ print '\t if (v == NULL) return NULL;'
+ i_out = 0
+ if type <> 'void':
+ print '\t PyTuple_SetItem(v,',
+ print repr(i_out) + ',',
+ print mkobject(type, 'retval') + ');'
+ i_out = i_out + 1
+ for i in range(len(database)):
+ a_type, a_mode, a_factor, a_sub = database[i]
+ if a_mode == 'r':
+ print '\t PyTuple_SetItem(v,',
+ print repr(i_out) + ',',
+ s = mkobject(a_type, 'arg' + repr(i+1))
+ print s + ');'
+ i_out = i_out + 1
+ print '\t return v;'
+ print '\t}'
+ else:
+ #
+ # Simple function return
+ # Return None or return value
+ #
+ if type == 'void':
+ print '\tPy_INCREF(Py_None);'
+ print '\treturn Py_None;'
+ else:
+ print '\treturn', mkobject(type, 'retval') + ';'
+ #
+ # Stub body closing brace
+ #
+ print '}'
+
+
+# Subroutine to return a function call to mknew<type>object(<arg>)
+#
+def mkobject(type, arg):
+ if type[:9] == 'unsigned ':
+ type = type[9:]
+ return 'mknew' + type + 'object((' + type + ') ' + arg + ')'
+ return 'mknew' + type + 'object(' + arg + ')'
+
+
+defined_archs = []
+
+# usage: cgen [ -Dmach ... ] [ file ]
+for arg in sys.argv[1:]:
+ if arg[:2] == '-D':
+ defined_archs.append(arg[2:])
+ else:
+ # Open optional file argument
+ sys.stdin = open(arg, 'r')
+
+
+# Input line number
+lno = 0
+
+
+# Input is divided in two parts, separated by a line containing '%%'.
+# <part1> -- literally copied to stdout
+# <part2> -- stub definitions
+
+# Variable indicating the current input part.
+#
+part = 1
+
+# Main loop over the input
+#
+while 1:
+ try:
+ line = raw_input()
+ except EOFError:
+ break
+ #
+ lno = lno+1
+ words = string.split(line)
+ #
+ if part == 1:
+ #
+ # In part 1, copy everything literally
+ # except look for a line of just '%%'
+ #
+ if words == ['%%']:
+ part = part + 1
+ else:
+ #
+ # Look for names of manually written
+ # stubs: a single percent followed by the name
+ # of the function in Python.
+ # The stub name is derived by prefixing 'gl_'.
+ #
+ if words and words[0][0] == '%':
+ func = words[0][1:]
+ if (not func) and words[1:]:
+ func = words[1]
+ if func:
+ functions.append(func)
+ else:
+ print line
+ continue
+ if not words:
+ continue # skip empty line
+ elif words[0] == 'if':
+ # if XXX rest
+ # if !XXX rest
+ if words[1][0] == '!':
+ if words[1][1:] in defined_archs:
+ continue
+ elif words[1] not in defined_archs:
+ continue
+ words = words[2:]
+ if words[0] == '#include':
+ print line
+ elif words[0][:1] == '#':
+ pass # ignore comment
+ elif words[0] not in return_types:
+ err('Line', lno, ': bad return type :', words[0])
+ elif len(words) < 2:
+ err('Line', lno, ': no funcname :', line)
+ else:
+ if len(words) % 2 <> 0:
+ err('Line', lno, ': odd argument list :', words[2:])
+ else:
+ database = []
+ try:
+ for i in range(2, len(words), 2):
+ x = checkarg(words[i], words[i+1])
+ database.append(x)
+ print
+ print '/*',
+ for w in words: print w,
+ print '*/'
+ generate(words[0], words[1], database)
+ except arg_error, msg:
+ err('Line', lno, ':', msg)
+
+
+print
+print 'static struct PyMethodDef gl_methods[] = {'
+for func in functions:
+ print '\t{"' + func + '", gl_' + func + '},'
+print '\t{NULL, NULL} /* Sentinel */'
+print '};'
+print
+print 'void'
+print 'initgl()'
+print '{'
+print '\t(void) Py_InitModule("gl", gl_methods);'
+print '}'
diff --git a/sys/src/cmd/python/Modules/cgensupport.c b/sys/src/cmd/python/Modules/cgensupport.c
new file mode 100644
index 000000000..7e7d0ff9f
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cgensupport.c
@@ -0,0 +1,310 @@
+
+/* Functions used by cgen output */
+
+#include "Python.h"
+#include "cgensupport.h"
+
+
+/* Functions to extract arguments.
+ These needs to know the total number of arguments supplied,
+ since the argument list is a tuple only of there is more than
+ one argument. */
+
+int
+PyArg_GetObject(register PyObject *args, int nargs, int i, PyObject **p_arg)
+{
+ if (nargs != 1) {
+ if (args == NULL || !PyTuple_Check(args) ||
+ nargs != PyTuple_Size(args) ||
+ i < 0 || i >= nargs) {
+ return PyErr_BadArgument();
+ }
+ else {
+ args = PyTuple_GetItem(args, i);
+ }
+ }
+ if (args == NULL) {
+ return PyErr_BadArgument();
+ }
+ *p_arg = args;
+ return 1;
+}
+
+int
+PyArg_GetLong(register PyObject *args, int nargs, int i, long *p_arg)
+{
+ if (nargs != 1) {
+ if (args == NULL || !PyTuple_Check(args) ||
+ nargs != PyTuple_Size(args) ||
+ i < 0 || i >= nargs) {
+ return PyErr_BadArgument();
+ }
+ args = PyTuple_GetItem(args, i);
+ }
+ if (args == NULL || !PyInt_Check(args)) {
+ return PyErr_BadArgument();
+ }
+ *p_arg = PyInt_AsLong(args);
+ return 1;
+}
+
+int
+PyArg_GetShort(register PyObject *args, int nargs, int i, short *p_arg)
+{
+ long x;
+ if (!PyArg_GetLong(args, nargs, i, &x))
+ return 0;
+ *p_arg = (short) x;
+ return 1;
+}
+
+static int
+extractdouble(register PyObject *v, double *p_arg)
+{
+ if (v == NULL) {
+ /* Fall through to error return at end of function */
+ }
+ else if (PyFloat_Check(v)) {
+ *p_arg = PyFloat_AS_DOUBLE((PyFloatObject *)v);
+ return 1;
+ }
+ else if (PyInt_Check(v)) {
+ *p_arg = PyInt_AS_LONG((PyIntObject *)v);
+ return 1;
+ }
+ else if (PyLong_Check(v)) {
+ *p_arg = PyLong_AsDouble(v);
+ return 1;
+ }
+ return PyErr_BadArgument();
+}
+
+static int
+extractfloat(register PyObject *v, float *p_arg)
+{
+ if (v == NULL) {
+ /* Fall through to error return at end of function */
+ }
+ else if (PyFloat_Check(v)) {
+ *p_arg = (float) PyFloat_AS_DOUBLE((PyFloatObject *)v);
+ return 1;
+ }
+ else if (PyInt_Check(v)) {
+ *p_arg = (float) PyInt_AS_LONG((PyIntObject *)v);
+ return 1;
+ }
+ else if (PyLong_Check(v)) {
+ *p_arg = (float) PyLong_AsDouble(v);
+ return 1;
+ }
+ return PyErr_BadArgument();
+}
+
+int
+PyArg_GetFloat(register PyObject *args, int nargs, int i, float *p_arg)
+{
+ PyObject *v;
+ float x;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (!extractfloat(v, &x))
+ return 0;
+ *p_arg = x;
+ return 1;
+}
+
+int
+PyArg_GetString(PyObject *args, int nargs, int i, string *p_arg)
+{
+ PyObject *v;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (!PyString_Check(v)) {
+ return PyErr_BadArgument();
+ }
+ *p_arg = PyString_AsString(v);
+ return 1;
+}
+
+int
+PyArg_GetChar(PyObject *args, int nargs, int i, char *p_arg)
+{
+ string x;
+ if (!PyArg_GetString(args, nargs, i, &x))
+ return 0;
+ if (x[0] == '\0' || x[1] != '\0') {
+ /* Not exactly one char */
+ return PyErr_BadArgument();
+ }
+ *p_arg = x[0];
+ return 1;
+}
+
+int
+PyArg_GetLongArraySize(PyObject *args, int nargs, int i, long *p_arg)
+{
+ PyObject *v;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (PyTuple_Check(v)) {
+ *p_arg = PyTuple_Size(v);
+ return 1;
+ }
+ if (PyList_Check(v)) {
+ *p_arg = PyList_Size(v);
+ return 1;
+ }
+ return PyErr_BadArgument();
+}
+
+int
+PyArg_GetShortArraySize(PyObject *args, int nargs, int i, short *p_arg)
+{
+ long x;
+ if (!PyArg_GetLongArraySize(args, nargs, i, &x))
+ return 0;
+ *p_arg = (short) x;
+ return 1;
+}
+
+/* XXX The following four are too similar. Should share more code. */
+
+int
+PyArg_GetLongArray(PyObject *args, int nargs, int i, int n, long *p_arg)
+{
+ PyObject *v, *w;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (PyTuple_Check(v)) {
+ if (PyTuple_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyTuple_GetItem(v, i);
+ if (!PyInt_Check(w)) {
+ return PyErr_BadArgument();
+ }
+ p_arg[i] = PyInt_AsLong(w);
+ }
+ return 1;
+ }
+ else if (PyList_Check(v)) {
+ if (PyList_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyList_GetItem(v, i);
+ if (!PyInt_Check(w)) {
+ return PyErr_BadArgument();
+ }
+ p_arg[i] = PyInt_AsLong(w);
+ }
+ return 1;
+ }
+ else {
+ return PyErr_BadArgument();
+ }
+}
+
+int
+PyArg_GetShortArray(PyObject *args, int nargs, int i, int n, short *p_arg)
+{
+ PyObject *v, *w;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (PyTuple_Check(v)) {
+ if (PyTuple_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyTuple_GetItem(v, i);
+ if (!PyInt_Check(w)) {
+ return PyErr_BadArgument();
+ }
+ p_arg[i] = (short) PyInt_AsLong(w);
+ }
+ return 1;
+ }
+ else if (PyList_Check(v)) {
+ if (PyList_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyList_GetItem(v, i);
+ if (!PyInt_Check(w)) {
+ return PyErr_BadArgument();
+ }
+ p_arg[i] = (short) PyInt_AsLong(w);
+ }
+ return 1;
+ }
+ else {
+ return PyErr_BadArgument();
+ }
+}
+
+int
+PyArg_GetDoubleArray(PyObject *args, int nargs, int i, int n, double *p_arg)
+{
+ PyObject *v, *w;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (PyTuple_Check(v)) {
+ if (PyTuple_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyTuple_GetItem(v, i);
+ if (!extractdouble(w, &p_arg[i]))
+ return 0;
+ }
+ return 1;
+ }
+ else if (PyList_Check(v)) {
+ if (PyList_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyList_GetItem(v, i);
+ if (!extractdouble(w, &p_arg[i]))
+ return 0;
+ }
+ return 1;
+ }
+ else {
+ return PyErr_BadArgument();
+ }
+}
+
+int
+PyArg_GetFloatArray(PyObject *args, int nargs, int i, int n, float *p_arg)
+{
+ PyObject *v, *w;
+ if (!PyArg_GetObject(args, nargs, i, &v))
+ return 0;
+ if (PyTuple_Check(v)) {
+ if (PyTuple_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyTuple_GetItem(v, i);
+ if (!extractfloat(w, &p_arg[i]))
+ return 0;
+ }
+ return 1;
+ }
+ else if (PyList_Check(v)) {
+ if (PyList_Size(v) != n) {
+ return PyErr_BadArgument();
+ }
+ for (i = 0; i < n; i++) {
+ w = PyList_GetItem(v, i);
+ if (!extractfloat(w, &p_arg[i]))
+ return 0;
+ }
+ return 1;
+ }
+ else {
+ return PyErr_BadArgument();
+ }
+}
diff --git a/sys/src/cmd/python/Modules/cgensupport.h b/sys/src/cmd/python/Modules/cgensupport.h
new file mode 100644
index 000000000..bc901f6e8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cgensupport.h
@@ -0,0 +1,64 @@
+#ifndef Py_CGENSUPPORT_H
+#define Py_CGENSUPPORT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Definitions used by cgen output */
+
+/* XXX This file is obsolete. It is *only* used by glmodule.c. */
+
+typedef char *string;
+
+#define mknewlongobject(x) PyInt_FromLong(x)
+#define mknewshortobject(x) PyInt_FromLong((long)x)
+#define mknewfloatobject(x) PyFloat_FromDouble(x)
+#define mknewcharobject(ch) Py_BuildValue("c", ch)
+
+#define getichararg PyArg_GetChar
+#define getidoublearray PyArg_GetDoubleArray
+#define getifloatarg PyArg_GetFloat
+#define getifloatarray PyArg_GetFloatArray
+#define getilongarg PyArg_GetLong
+#define getilongarray PyArg_GetLongArray
+#define getilongarraysize PyArg_GetLongArraySize
+#define getiobjectarg PyArg_GetObject
+#define getishortarg PyArg_GetShort
+#define getishortarray PyArg_GetShortArray
+#define getishortarraysize PyArg_GetShortArraySize
+#define getistringarg PyArg_GetString
+
+extern int PyArg_GetObject(PyObject *args, int nargs,
+ int i, PyObject **p_a);
+extern int PyArg_GetLong(PyObject *args, int nargs,
+ int i, long *p_a);
+extern int PyArg_GetShort(PyObject *args, int nargs,
+ int i, short *p_a);
+extern int PyArg_GetFloat(PyObject *args, int nargs,
+ int i, float *p_a);
+extern int PyArg_GetString(PyObject *args, int nargs,
+ int i, string *p_a);
+extern int PyArg_GetChar(PyObject *args, int nargs,
+ int i, char *p_a);
+extern int PyArg_GetLongArray(PyObject *args, int nargs,
+ int i, int n, long *p_a);
+extern int PyArg_GetShortArray(PyObject *args, int nargs,
+ int i, int n, short *p_a);
+extern int PyArg_GetDoubleArray(PyObject *args, int nargs,
+ int i, int n, double *p_a);
+extern int PyArg_GetFloatArray(PyObject *args, int nargs,
+ int i, int n, float *p_a);
+extern int PyArg_GetLongArraySize(PyObject *args, int nargs,
+ int i, long *p_a);
+extern int PyArg_GetShortArraySize(PyObject *args, int nargs,
+ int i, short *p_a);
+extern int PyArg_GetDoubleArraySize(PyObject *args, int nargs,
+ int i, double *p_a);
+extern int PyArg_GetFloatArraySize(PyObject *args, int nargs,
+ int i, float *p_a);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CGENSUPPORT_H */
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/README b/sys/src/cmd/python/Modules/cjkcodecs/README
new file mode 100644
index 000000000..b2370bc29
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/README
@@ -0,0 +1,79 @@
+To generate or modify mapping headers
+-------------------------------------
+Mapping headers are imported from CJKCodecs as pre-generated form.
+If you need to tweak or add something on it, please look at tools/
+subdirectory of CJKCodecs' distribution.
+
+
+
+Notes on implmentation characteristics of each codecs
+-----------------------------------------------------
+
+1) Big5 codec
+
+ The big5 codec maps the following characters as cp950 does rather
+ than conforming Unicode.org's that maps to 0xFFFD.
+
+ BIG5 Unicode Description
+
+ 0xA15A 0x2574 SPACING UNDERSCORE
+ 0xA1C3 0xFFE3 SPACING HEAVY OVERSCORE
+ 0xA1C5 0x02CD SPACING HEAVY UNDERSCORE
+ 0xA1FE 0xFF0F LT DIAG UP RIGHT TO LOW LEFT
+ 0xA240 0xFF3C LT DIAG UP LEFT TO LOW RIGHT
+ 0xA2CC 0x5341 HANGZHOU NUMERAL TEN
+ 0xA2CE 0x5345 HANGZHOU NUMERAL THIRTY
+
+ Because unicode 0x5341, 0x5345, 0xFF0F, 0xFF3C is mapped to another
+ big5 codes already, a roundtrip compatibility is not guaranteed for
+ them.
+
+
+2) cp932 codec
+
+ To conform to Windows's real mapping, cp932 codec maps the following
+ codepoints in addition of the official cp932 mapping.
+
+ CP932 Unicode Description
+
+ 0x80 0x80 UNDEFINED
+ 0xA0 0xF8F0 UNDEFINED
+ 0xFD 0xF8F1 UNDEFINED
+ 0xFE 0xF8F2 UNDEFINED
+ 0xFF 0xF8F3 UNDEFINED
+
+
+3) euc-jisx0213 codec
+
+ The euc-jisx0213 codec maps JIS X 0213 Plane 1 code 0x2140 into
+ unicode U+FF3C instead of U+005C as on unicode.org's mapping.
+ Because euc-jisx0213 has REVERSE SOLIDUS on 0x5c already and A140
+ is shown as a full width character, mapping to U+FF3C can make
+ more sense.
+
+ The euc-jisx0213 codec is enabled to decode JIS X 0212 codes on
+ codeset 2. Because JIS X 0212 and JIS X 0213 Plane 2 don't have
+ overlapped by each other, it doesn't bother standard conformations
+ (and JIS X 0213 Plane 2 is intended to use so.) On encoding
+ sessions, the codec will try to encode kanji characters in this
+ order:
+
+ JIS X 0213 Plane 1 -> JIS X 0213 Plane 2 -> JIS X 0212
+
+
+4) euc-jp codec
+
+ The euc-jp codec is a compatibility instance on these points:
+ - U+FF3C FULLWIDTH REVERSE SOLIDUS is mapped to EUC-JP A1C0 (vice versa)
+ - U+00A5 YEN SIGN is mapped to EUC-JP 0x5c. (one way)
+ - U+203E OVERLINE is mapped to EUC-JP 0x7e. (one way)
+
+
+5) shift-jis codec
+
+ The shift-jis codec is mapping 0x20-0x7e area to U+20-U+7E directly
+ instead of using JIS X 0201 for compatibility. The differences are:
+ - U+005C REVERSE SOLIDUS is mapped to SHIFT-JIS 0x5c.
+ - U+007E TILDE is mapped to SHIFT-JIS 0x7e.
+ - U+FF3C FULL-WIDTH REVERSE SOLIDUS is mapped to SHIFT-JIS 815f.
+
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/_codecs_cn.c b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_cn.c
new file mode 100644
index 000000000..c811a67ed
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_cn.c
@@ -0,0 +1,443 @@
+/*
+ * _codecs_cn.c: Codecs collection for Mainland Chinese encodings
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#include "cjkcodecs.h"
+#include "mappings_cn.h"
+
+/**
+ * hz is predefined as 100 on AIX. So we undefine it to avoid
+ * conflict against hz codec's.
+ */
+#ifdef _AIX
+#undef hz
+#endif
+
+/* GBK and GB2312 map differently in few codepoints that are listed below:
+ *
+ * gb2312 gbk
+ * A1A4 U+30FB KATAKANA MIDDLE DOT U+00B7 MIDDLE DOT
+ * A1AA U+2015 HORIZONTAL BAR U+2014 EM DASH
+ * A844 undefined U+2015 HORIZONTAL BAR
+ */
+
+#define GBK_DECODE(dc1, dc2, assi) \
+ if ((dc1) == 0xa1 && (dc2) == 0xaa) (assi) = 0x2014; \
+ else if ((dc1) == 0xa8 && (dc2) == 0x44) (assi) = 0x2015; \
+ else if ((dc1) == 0xa1 && (dc2) == 0xa4) (assi) = 0x00b7; \
+ else TRYMAP_DEC(gb2312, assi, dc1 ^ 0x80, dc2 ^ 0x80); \
+ else TRYMAP_DEC(gbkext, assi, dc1, dc2);
+
+#define GBK_ENCODE(code, assi) \
+ if ((code) == 0x2014) (assi) = 0xa1aa; \
+ else if ((code) == 0x2015) (assi) = 0xa844; \
+ else if ((code) == 0x00b7) (assi) = 0xa1a4; \
+ else if ((code) != 0x30fb && TRYMAP_ENC_COND(gbcommon, assi, code));
+
+/*
+ * GB2312 codec
+ */
+
+ENCODER(gb2312)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+ TRYMAP_ENC(gbcommon, code, c);
+ else return 1;
+
+ if (code & 0x8000) /* MSB set: GBK */
+ return 1;
+
+ OUT1((code >> 8) | 0x80)
+ OUT2((code & 0xFF) | 0x80)
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(gb2312)
+{
+ while (inleft > 0) {
+ unsigned char c = **inbuf;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+ TRYMAP_DEC(gb2312, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
+ NEXT(2, 1)
+ }
+ else return 2;
+ }
+
+ return 0;
+}
+
+
+/*
+ * GBK codec
+ */
+
+ENCODER(gbk)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+
+ GBK_ENCODE(c, code)
+ else return 1;
+
+ OUT1((code >> 8) | 0x80)
+ if (code & 0x8000)
+ OUT2((code & 0xFF)) /* MSB set: GBK */
+ else
+ OUT2((code & 0xFF) | 0x80) /* MSB unset: GB2312 */
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(gbk)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+
+ GBK_DECODE(c, IN2, **outbuf)
+ else return 2;
+
+ NEXT(2, 1)
+ }
+
+ return 0;
+}
+
+
+/*
+ * GB18030 codec
+ */
+
+ENCODER(gb18030)
+{
+ while (inleft > 0) {
+ ucs4_t c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ DECODE_SURROGATE(c)
+ if (c > 0x10FFFF)
+#if Py_UNICODE_SIZE == 2
+ return 2; /* surrogates pair */
+#else
+ return 1;
+#endif
+ else if (c >= 0x10000) {
+ ucs4_t tc = c - 0x10000;
+
+ REQUIRE_OUTBUF(4)
+
+ OUT4((unsigned char)(tc % 10) + 0x30)
+ tc /= 10;
+ OUT3((unsigned char)(tc % 126) + 0x81)
+ tc /= 126;
+ OUT2((unsigned char)(tc % 10) + 0x30)
+ tc /= 10;
+ OUT1((unsigned char)(tc + 0x90))
+
+#if Py_UNICODE_SIZE == 2
+ NEXT(2, 4) /* surrogates pair */
+#else
+ NEXT(1, 4)
+#endif
+ continue;
+ }
+
+ REQUIRE_OUTBUF(2)
+
+ GBK_ENCODE(c, code)
+ else {
+ const struct _gb18030_to_unibmp_ranges *utrrange;
+
+ REQUIRE_OUTBUF(4)
+
+ for (utrrange = gb18030_to_unibmp_ranges;
+ utrrange->first != 0;
+ utrrange++)
+ if (utrrange->first <= c &&
+ c <= utrrange->last) {
+ Py_UNICODE tc;
+
+ tc = c - utrrange->first +
+ utrrange->base;
+
+ OUT4((unsigned char)(tc % 10) + 0x30)
+ tc /= 10;
+ OUT3((unsigned char)(tc % 126) + 0x81)
+ tc /= 126;
+ OUT2((unsigned char)(tc % 10) + 0x30)
+ tc /= 10;
+ OUT1((unsigned char)tc + 0x81)
+
+ NEXT(1, 4)
+ break;
+ }
+
+ if (utrrange->first == 0)
+ return 1;
+ continue;
+ }
+
+ OUT1((code >> 8) | 0x80)
+ if (code & 0x8000)
+ OUT2((code & 0xFF)) /* MSB set: GBK or GB18030ext */
+ else
+ OUT2((code & 0xFF) | 0x80) /* MSB unset: GB2312 */
+
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(gb18030)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1, c2;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+
+ c2 = IN2;
+ if (c2 >= 0x30 && c2 <= 0x39) { /* 4 bytes seq */
+ const struct _gb18030_to_unibmp_ranges *utr;
+ unsigned char c3, c4;
+ ucs4_t lseq;
+
+ REQUIRE_INBUF(4)
+ c3 = IN3;
+ c4 = IN4;
+ if (c < 0x81 || c3 < 0x81 || c4 < 0x30 || c4 > 0x39)
+ return 4;
+ c -= 0x81; c2 -= 0x30;
+ c3 -= 0x81; c4 -= 0x30;
+
+ if (c < 4) { /* U+0080 - U+FFFF */
+ lseq = ((ucs4_t)c * 10 + c2) * 1260 +
+ (ucs4_t)c3 * 10 + c4;
+ if (lseq < 39420) {
+ for (utr = gb18030_to_unibmp_ranges;
+ lseq >= (utr + 1)->base;
+ utr++) ;
+ OUT1(utr->first - utr->base + lseq)
+ NEXT(4, 1)
+ continue;
+ }
+ }
+ else if (c >= 15) { /* U+10000 - U+10FFFF */
+ lseq = 0x10000 + (((ucs4_t)c-15) * 10 + c2)
+ * 1260 + (ucs4_t)c3 * 10 + c4;
+ if (lseq <= 0x10FFFF) {
+ WRITEUCS4(lseq);
+ NEXT_IN(4)
+ continue;
+ }
+ }
+ return 4;
+ }
+
+ GBK_DECODE(c, c2, **outbuf)
+ else TRYMAP_DEC(gb18030ext, **outbuf, c, c2);
+ else return 2;
+
+ NEXT(2, 1)
+ }
+
+ return 0;
+}
+
+
+/*
+ * HZ codec
+ */
+
+ENCODER_INIT(hz)
+{
+ state->i = 0;
+ return 0;
+}
+
+ENCODER_RESET(hz)
+{
+ if (state->i != 0) {
+ WRITE2('~', '}')
+ state->i = 0;
+ NEXT_OUT(2)
+ }
+ return 0;
+}
+
+ENCODER(hz)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ if (state->i == 0) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ }
+ else {
+ WRITE3('~', '}', (unsigned char)c)
+ NEXT(1, 3)
+ state->i = 0;
+ }
+ continue;
+ }
+
+ UCS4INVALID(c)
+
+ TRYMAP_ENC(gbcommon, code, c);
+ else return 1;
+
+ if (code & 0x8000) /* MSB set: GBK */
+ return 1;
+
+ if (state->i == 0) {
+ WRITE4('~', '{', code >> 8, code & 0xff)
+ NEXT(1, 4)
+ state->i = 1;
+ }
+ else {
+ WRITE2(code >> 8, code & 0xff)
+ NEXT(1, 2)
+ }
+ }
+
+ return 0;
+}
+
+DECODER_INIT(hz)
+{
+ state->i = 0;
+ return 0;
+}
+
+DECODER_RESET(hz)
+{
+ state->i = 0;
+ return 0;
+}
+
+DECODER(hz)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ if (c == '~') {
+ unsigned char c2 = IN2;
+
+ REQUIRE_INBUF(2)
+ if (c2 == '~') {
+ WRITE1('~')
+ NEXT(2, 1)
+ continue;
+ }
+ else if (c2 == '{' && state->i == 0)
+ state->i = 1; /* set GB */
+ else if (c2 == '}' && state->i == 1)
+ state->i = 0; /* set ASCII */
+ else if (c2 == '\n')
+ ; /* line-continuation */
+ else
+ return 2;
+ NEXT(2, 0);
+ continue;
+ }
+
+ if (c & 0x80)
+ return 1;
+
+ if (state->i == 0) { /* ASCII mode */
+ WRITE1(c)
+ NEXT(1, 1)
+ }
+ else { /* GB mode */
+ REQUIRE_INBUF(2)
+ REQUIRE_OUTBUF(1)
+ TRYMAP_DEC(gb2312, **outbuf, c, IN2) {
+ NEXT(2, 1)
+ }
+ else
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+
+BEGIN_MAPPINGS_LIST
+ MAPPING_DECONLY(gb2312)
+ MAPPING_DECONLY(gbkext)
+ MAPPING_ENCONLY(gbcommon)
+ MAPPING_ENCDEC(gb18030ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+ CODEC_STATELESS(gb2312)
+ CODEC_STATELESS(gbk)
+ CODEC_STATELESS(gb18030)
+ CODEC_STATEFUL(hz)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(cn)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/_codecs_hk.c b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_hk.c
new file mode 100644
index 000000000..221eced3c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_hk.c
@@ -0,0 +1,143 @@
+/*
+ * _codecs_hk.c: Codecs collection for encodings from Hong Kong
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#define USING_IMPORTED_MAPS
+
+#include "cjkcodecs.h"
+#include "mappings_hk.h"
+
+/*
+ * BIG5HKSCS codec
+ */
+
+static const encode_map *big5_encmap = NULL;
+static const decode_map *big5_decmap = NULL;
+
+CODEC_INIT(big5hkscs)
+{
+ static int initialized = 0;
+
+ if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap))
+ return -1;
+ initialized = 1;
+ return 0;
+}
+
+ENCODER(big5hkscs)
+{
+ while (inleft > 0) {
+ ucs4_t c = **inbuf;
+ DBCHAR code;
+ Py_ssize_t insize;
+
+ if (c < 0x80) {
+ REQUIRE_OUTBUF(1)
+ **outbuf = (unsigned char)c;
+ NEXT(1, 1)
+ continue;
+ }
+
+ DECODE_SURROGATE(c)
+ insize = GET_INSIZE(c);
+
+ REQUIRE_OUTBUF(2)
+
+ if (c < 0x10000) {
+ TRYMAP_ENC(big5hkscs_bmp, code, c);
+ else TRYMAP_ENC(big5, code, c);
+ else return 1;
+ }
+ else if (c < 0x20000)
+ return insize;
+ else if (c < 0x30000) {
+ TRYMAP_ENC(big5hkscs_nonbmp, code, c & 0xffff);
+ else return insize;
+ }
+ else
+ return insize;
+
+ OUT1(code >> 8)
+ OUT2(code & 0xFF)
+ NEXT(insize, 2)
+ }
+
+ return 0;
+}
+
+#define BH2S(c1, c2) (((c1) - 0x88) * (0xfe - 0x40 + 1) + ((c2) - 0x40))
+
+DECODER(big5hkscs)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+ ucs4_t decoded;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+
+ if (0xc6 <= c && c <= 0xc8 && (c >= 0xc7 || IN2 >= 0xa1))
+ goto hkscsdec;
+
+ TRYMAP_DEC(big5, **outbuf, c, IN2) {
+ NEXT(2, 1)
+ }
+ else
+hkscsdec: TRYMAP_DEC(big5hkscs, decoded, c, IN2) {
+ int s = BH2S(c, IN2);
+ const unsigned char *hintbase;
+
+ assert(0x88 <= c && c <= 0xfe);
+ assert(0x40 <= IN2 && IN2 <= 0xfe);
+
+ if (BH2S(0x88, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) {
+ hintbase = big5hkscs_phint_0;
+ s -= BH2S(0x88, 0x40);
+ }
+ else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){
+ hintbase = big5hkscs_phint_11939;
+ s -= BH2S(0xc6, 0xa1);
+ }
+ else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){
+ hintbase = big5hkscs_phint_21733;
+ s -= BH2S(0xf9, 0xd6);
+ }
+ else
+ return MBERR_INTERNAL;
+
+ if (hintbase[s >> 3] & (1 << (s & 7))) {
+ WRITEUCS4(decoded | 0x20000)
+ NEXT_IN(2)
+ }
+ else {
+ OUT1(decoded)
+ NEXT(2, 1)
+ }
+ }
+ else return 2;
+ }
+
+ return 0;
+}
+
+
+BEGIN_MAPPINGS_LIST
+ MAPPING_DECONLY(big5hkscs)
+ MAPPING_ENCONLY(big5hkscs_bmp)
+ MAPPING_ENCONLY(big5hkscs_nonbmp)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+ CODEC_STATELESS_WINIT(big5hkscs)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(hk)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/_codecs_iso2022.c b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_iso2022.c
new file mode 100644
index 000000000..55196a9ea
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_iso2022.c
@@ -0,0 +1,1131 @@
+/*
+ * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings.
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#define USING_IMPORTED_MAPS
+#define USING_BINARY_PAIR_SEARCH
+#define EXTERN_JISX0213_PAIR
+#define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE
+#define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE
+
+#include "cjkcodecs.h"
+#include "alg_jisx0201.h"
+#include "emu_jisx0213_2000.h"
+#include "mappings_jisx0213_pair.h"
+
+/* STATE
+
+ state->c[0-3]
+
+ 00000000
+ ||^^^^^|
+ |+-----+---- G0-3 Character Set
+ +----------- Is G0-3 double byte?
+
+ state->c[4]
+
+ 00000000
+ ||
+ |+---- Locked-Shift?
+ +----- ESC Throughout
+*/
+
+#define ESC 0x1B
+#define SO 0x0E
+#define SI 0x0F
+#define LF 0x0A
+
+#define MAX_ESCSEQLEN 16
+
+#define CHARSET_ISO8859_1 'A'
+#define CHARSET_ASCII 'B'
+#define CHARSET_ISO8859_7 'F'
+#define CHARSET_JISX0201_K 'I'
+#define CHARSET_JISX0201_R 'J'
+
+#define CHARSET_GB2312 ('A'|CHARSET_DBCS)
+#define CHARSET_JISX0208 ('B'|CHARSET_DBCS)
+#define CHARSET_KSX1001 ('C'|CHARSET_DBCS)
+#define CHARSET_JISX0212 ('D'|CHARSET_DBCS)
+#define CHARSET_GB2312_8565 ('E'|CHARSET_DBCS)
+#define CHARSET_CNS11643_1 ('G'|CHARSET_DBCS)
+#define CHARSET_CNS11643_2 ('H'|CHARSET_DBCS)
+#define CHARSET_JISX0213_2000_1 ('O'|CHARSET_DBCS)
+#define CHARSET_JISX0213_2 ('P'|CHARSET_DBCS)
+#define CHARSET_JISX0213_2004_1 ('Q'|CHARSET_DBCS)
+#define CHARSET_JISX0208_O ('@'|CHARSET_DBCS)
+
+#define CHARSET_DBCS 0x80
+#define ESCMARK(mark) ((mark) & 0x7f)
+
+#define IS_ESCEND(c) (((c) >= 'A' && (c) <= 'Z') || (c) == '@')
+#define IS_ISO2022ESC(c2) \
+ ((c2) == '(' || (c2) == ')' || (c2) == '$' || \
+ (c2) == '.' || (c2) == '&')
+ /* this is not a complete list of ISO-2022 escape sequence headers.
+ * but, it's enough to implement CJK instances of iso-2022. */
+
+#define MAP_UNMAPPABLE 0xFFFF
+#define MAP_MULTIPLE_AVAIL 0xFFFE /* for JIS X 0213 */
+
+#define F_SHIFTED 0x01
+#define F_ESCTHROUGHOUT 0x02
+
+#define STATE_SETG(dn, v) ((state)->c[dn]) = (v);
+#define STATE_GETG(dn) ((state)->c[dn])
+
+#define STATE_G0 STATE_GETG(0)
+#define STATE_G1 STATE_GETG(1)
+#define STATE_G2 STATE_GETG(2)
+#define STATE_G3 STATE_GETG(3)
+#define STATE_SETG0(v) STATE_SETG(0, v)
+#define STATE_SETG1(v) STATE_SETG(1, v)
+#define STATE_SETG2(v) STATE_SETG(2, v)
+#define STATE_SETG3(v) STATE_SETG(3, v)
+
+#define STATE_SETFLAG(f) ((state)->c[4]) |= (f);
+#define STATE_GETFLAG(f) ((state)->c[4] & (f))
+#define STATE_CLEARFLAG(f) ((state)->c[4]) &= ~(f);
+#define STATE_CLEARFLAGS() ((state)->c[4]) = 0;
+
+#define ISO2022_CONFIG ((const struct iso2022_config *)config)
+#define CONFIG_ISSET(flag) (ISO2022_CONFIG->flags & (flag))
+#define CONFIG_DESIGNATIONS (ISO2022_CONFIG->designations)
+
+/* iso2022_config.flags */
+#define NO_SHIFT 0x01
+#define USE_G2 0x02
+#define USE_JISX0208_EXT 0x04
+
+/*-*- internal data structures -*-*/
+
+typedef int (*iso2022_init_func)(void);
+typedef ucs4_t (*iso2022_decode_func)(const unsigned char *data);
+typedef DBCHAR (*iso2022_encode_func)(const ucs4_t *data, Py_ssize_t *length);
+
+struct iso2022_designation {
+ unsigned char mark;
+ unsigned char plane;
+ unsigned char width;
+ iso2022_init_func initializer;
+ iso2022_decode_func decoder;
+ iso2022_encode_func encoder;
+};
+
+struct iso2022_config {
+ int flags;
+ const struct iso2022_designation *designations; /* non-ascii desigs */
+};
+
+/*-*- iso-2022 codec implementation -*-*/
+
+CODEC_INIT(iso2022)
+{
+ const struct iso2022_designation *desig = CONFIG_DESIGNATIONS;
+ for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++)
+ if (desig->initializer != NULL && desig->initializer() != 0)
+ return -1;
+ return 0;
+}
+
+ENCODER_INIT(iso2022)
+{
+ STATE_CLEARFLAGS()
+ STATE_SETG0(CHARSET_ASCII)
+ STATE_SETG1(CHARSET_ASCII)
+ return 0;
+}
+
+ENCODER_RESET(iso2022)
+{
+ if (STATE_GETFLAG(F_SHIFTED)) {
+ WRITE1(SI)
+ NEXT_OUT(1)
+ STATE_CLEARFLAG(F_SHIFTED)
+ }
+ if (STATE_G0 != CHARSET_ASCII) {
+ WRITE3(ESC, '(', 'B')
+ NEXT_OUT(3)
+ STATE_SETG0(CHARSET_ASCII)
+ }
+ return 0;
+}
+
+ENCODER(iso2022)
+{
+ while (inleft > 0) {
+ const struct iso2022_designation *dsg;
+ DBCHAR encoded;
+ ucs4_t c = **inbuf;
+ Py_ssize_t insize;
+
+ if (c < 0x80) {
+ if (STATE_G0 != CHARSET_ASCII) {
+ WRITE3(ESC, '(', 'B')
+ STATE_SETG0(CHARSET_ASCII)
+ NEXT_OUT(3)
+ }
+ if (STATE_GETFLAG(F_SHIFTED)) {
+ WRITE1(SI)
+ STATE_CLEARFLAG(F_SHIFTED)
+ NEXT_OUT(1)
+ }
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ DECODE_SURROGATE(c)
+ insize = GET_INSIZE(c);
+
+ encoded = MAP_UNMAPPABLE;
+ for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) {
+ Py_ssize_t length = 1;
+ encoded = dsg->encoder(&c, &length);
+ if (encoded == MAP_MULTIPLE_AVAIL) {
+ /* this implementation won't work for pair
+ * of non-bmp characters. */
+ if (inleft < 2) {
+ if (!(flags & MBENC_FLUSH))
+ return MBERR_TOOFEW;
+ length = -1;
+ }
+ else
+ length = 2;
+#if Py_UNICODE_SIZE == 2
+ if (length == 2) {
+ ucs4_t u4in[2];
+ u4in[0] = (ucs4_t)IN1;
+ u4in[1] = (ucs4_t)IN2;
+ encoded = dsg->encoder(u4in, &length);
+ } else
+ encoded = dsg->encoder(&c, &length);
+#else
+ encoded = dsg->encoder(*inbuf, &length);
+#endif
+ if (encoded != MAP_UNMAPPABLE) {
+ insize = length;
+ break;
+ }
+ }
+ else if (encoded != MAP_UNMAPPABLE)
+ break;
+ }
+
+ if (!dsg->mark)
+ return 1;
+ assert(dsg->width == 1 || dsg->width == 2);
+
+ switch (dsg->plane) {
+ case 0: /* G0 */
+ if (STATE_GETFLAG(F_SHIFTED)) {
+ WRITE1(SI)
+ STATE_CLEARFLAG(F_SHIFTED)
+ NEXT_OUT(1)
+ }
+ if (STATE_G0 != dsg->mark) {
+ if (dsg->width == 1) {
+ WRITE3(ESC, '(', ESCMARK(dsg->mark))
+ STATE_SETG0(dsg->mark)
+ NEXT_OUT(3)
+ }
+ else if (dsg->mark == CHARSET_JISX0208) {
+ WRITE3(ESC, '$', ESCMARK(dsg->mark))
+ STATE_SETG0(dsg->mark)
+ NEXT_OUT(3)
+ }
+ else {
+ WRITE4(ESC, '$', '(',
+ ESCMARK(dsg->mark))
+ STATE_SETG0(dsg->mark)
+ NEXT_OUT(4)
+ }
+ }
+ break;
+ case 1: /* G1 */
+ if (STATE_G1 != dsg->mark) {
+ if (dsg->width == 1) {
+ WRITE3(ESC, ')', ESCMARK(dsg->mark))
+ STATE_SETG1(dsg->mark)
+ NEXT_OUT(3)
+ }
+ else {
+ WRITE4(ESC, '$', ')',
+ ESCMARK(dsg->mark))
+ STATE_SETG1(dsg->mark)
+ NEXT_OUT(4)
+ }
+ }
+ if (!STATE_GETFLAG(F_SHIFTED)) {
+ WRITE1(SO)
+ STATE_SETFLAG(F_SHIFTED)
+ NEXT_OUT(1)
+ }
+ break;
+ default: /* G2 and G3 is not supported: no encoding in
+ * CJKCodecs are using them yet */
+ return MBERR_INTERNAL;
+ }
+
+ if (dsg->width == 1) {
+ WRITE1((unsigned char)encoded)
+ NEXT_OUT(1)
+ }
+ else {
+ WRITE2(encoded >> 8, encoded & 0xff)
+ NEXT_OUT(2)
+ }
+ NEXT_IN(insize)
+ }
+
+ return 0;
+}
+
+DECODER_INIT(iso2022)
+{
+ STATE_CLEARFLAGS()
+ STATE_SETG0(CHARSET_ASCII)
+ STATE_SETG1(CHARSET_ASCII)
+ STATE_SETG2(CHARSET_ASCII)
+ return 0;
+}
+
+DECODER_RESET(iso2022)
+{
+ STATE_SETG0(CHARSET_ASCII)
+ STATE_CLEARFLAG(F_SHIFTED)
+ return 0;
+}
+
+static Py_ssize_t
+iso2022processesc(const void *config, MultibyteCodec_State *state,
+ const unsigned char **inbuf, Py_ssize_t *inleft)
+{
+ unsigned char charset, designation;
+ Py_ssize_t i, esclen;
+
+ for (i = 1;i < MAX_ESCSEQLEN;i++) {
+ if (i >= *inleft)
+ return MBERR_TOOFEW;
+ if (IS_ESCEND((*inbuf)[i])) {
+ esclen = i + 1;
+ break;
+ }
+ else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft &&
+ (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@')
+ i += 2;
+ }
+
+ if (i >= MAX_ESCSEQLEN)
+ return 1; /* unterminated escape sequence */
+
+ switch (esclen) {
+ case 3:
+ if (IN2 == '$') {
+ charset = IN3 | CHARSET_DBCS;
+ designation = 0;
+ }
+ else {
+ charset = IN3;
+ if (IN2 == '(') designation = 0;
+ else if (IN2 == ')') designation = 1;
+ else if (CONFIG_ISSET(USE_G2) && IN2 == '.')
+ designation = 2;
+ else return 3;
+ }
+ break;
+ case 4:
+ if (IN2 != '$')
+ return 4;
+
+ charset = IN4 | CHARSET_DBCS;
+ if (IN3 == '(') designation = 0;
+ else if (IN3 == ')') designation = 1;
+ else return 4;
+ break;
+ case 6: /* designation with prefix */
+ if (CONFIG_ISSET(USE_JISX0208_EXT) &&
+ (*inbuf)[3] == ESC && (*inbuf)[4] == '$' &&
+ (*inbuf)[5] == 'B') {
+ charset = 'B' | CHARSET_DBCS;
+ designation = 0;
+ }
+ else
+ return 6;
+ break;
+ default:
+ return esclen;
+ }
+
+ /* raise error when the charset is not designated for this encoding */
+ if (charset != CHARSET_ASCII) {
+ const struct iso2022_designation *dsg;
+
+ for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++)
+ if (dsg->mark == charset)
+ break;
+ if (!dsg->mark)
+ return esclen;
+ }
+
+ STATE_SETG(designation, charset)
+ *inleft -= esclen;
+ (*inbuf) += esclen;
+ return 0;
+}
+
+#define ISO8859_7_DECODE(c, assi) \
+ if ((c) < 0xa0) (assi) = (c); \
+ else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0)))) \
+ (assi) = (c); \
+ else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 || \
+ (0xbffffd77L & (1L << ((c)-0xb4))))) \
+ (assi) = 0x02d0 + (c); \
+ else if ((c) == 0xa1) (assi) = 0x2018; \
+ else if ((c) == 0xa2) (assi) = 0x2019; \
+ else if ((c) == 0xaf) (assi) = 0x2015;
+
+static Py_ssize_t
+iso2022processg2(const void *config, MultibyteCodec_State *state,
+ const unsigned char **inbuf, Py_ssize_t *inleft,
+ Py_UNICODE **outbuf, Py_ssize_t *outleft)
+{
+ /* not written to use encoder, decoder functions because only few
+ * encodings use G2 designations in CJKCodecs */
+ if (STATE_G2 == CHARSET_ISO8859_1) {
+ if (IN3 < 0x80)
+ OUT1(IN3 + 0x80)
+ else
+ return 3;
+ }
+ else if (STATE_G2 == CHARSET_ISO8859_7) {
+ ISO8859_7_DECODE(IN3 ^ 0x80, **outbuf)
+ else return 3;
+ }
+ else if (STATE_G2 == CHARSET_ASCII) {
+ if (IN3 & 0x80) return 3;
+ else **outbuf = IN3;
+ }
+ else
+ return MBERR_INTERNAL;
+
+ (*inbuf) += 3;
+ *inleft -= 3;
+ (*outbuf) += 1;
+ *outleft -= 1;
+ return 0;
+}
+
+DECODER(iso2022)
+{
+ const struct iso2022_designation *dsgcache = NULL;
+
+ while (inleft > 0) {
+ unsigned char c = IN1;
+ Py_ssize_t err;
+
+ if (STATE_GETFLAG(F_ESCTHROUGHOUT)) {
+ /* ESC throughout mode:
+ * for non-iso2022 escape sequences */
+ WRITE1(c) /* assume as ISO-8859-1 */
+ NEXT(1, 1)
+ if (IS_ESCEND(c)) {
+ STATE_CLEARFLAG(F_ESCTHROUGHOUT)
+ }
+ continue;
+ }
+
+ switch (c) {
+ case ESC:
+ REQUIRE_INBUF(2)
+ if (IS_ISO2022ESC(IN2)) {
+ err = iso2022processesc(config, state,
+ inbuf, &inleft);
+ if (err != 0)
+ return err;
+ }
+ else if (CONFIG_ISSET(USE_G2) && IN2 == 'N') {/* SS2 */
+ REQUIRE_INBUF(3)
+ err = iso2022processg2(config, state,
+ inbuf, &inleft, outbuf, &outleft);
+ if (err != 0)
+ return err;
+ }
+ else {
+ WRITE1(ESC)
+ STATE_SETFLAG(F_ESCTHROUGHOUT)
+ NEXT(1, 1)
+ }
+ break;
+ case SI:
+ if (CONFIG_ISSET(NO_SHIFT))
+ goto bypass;
+ STATE_CLEARFLAG(F_SHIFTED)
+ NEXT_IN(1)
+ break;
+ case SO:
+ if (CONFIG_ISSET(NO_SHIFT))
+ goto bypass;
+ STATE_SETFLAG(F_SHIFTED)
+ NEXT_IN(1)
+ break;
+ case LF:
+ STATE_CLEARFLAG(F_SHIFTED)
+ WRITE1(LF)
+ NEXT(1, 1)
+ break;
+ default:
+ if (c < 0x20) /* C0 */
+ goto bypass;
+ else if (c >= 0x80)
+ return 1;
+ else {
+ const struct iso2022_designation *dsg;
+ unsigned char charset;
+ ucs4_t decoded;
+
+ if (STATE_GETFLAG(F_SHIFTED))
+ charset = STATE_G1;
+ else
+ charset = STATE_G0;
+
+ if (charset == CHARSET_ASCII) {
+bypass: WRITE1(c)
+ NEXT(1, 1)
+ break;
+ }
+
+ if (dsgcache != NULL &&
+ dsgcache->mark == charset)
+ dsg = dsgcache;
+ else {
+ for (dsg = CONFIG_DESIGNATIONS;
+ dsg->mark != charset
+#ifdef Py_DEBUG
+ && dsg->mark != '\0'
+#endif
+ ;dsg++)
+ /* noop */;
+ assert(dsg->mark != '\0');
+ dsgcache = dsg;
+ }
+
+ REQUIRE_INBUF(dsg->width)
+ decoded = dsg->decoder(*inbuf);
+ if (decoded == MAP_UNMAPPABLE)
+ return dsg->width;
+
+ if (decoded < 0x10000) {
+ WRITE1(decoded)
+ NEXT_OUT(1)
+ }
+ else if (decoded < 0x30000) {
+ WRITEUCS4(decoded)
+ }
+ else { /* JIS X 0213 pairs */
+ WRITE2(decoded >> 16, decoded & 0xffff)
+ NEXT_OUT(2)
+ }
+ NEXT_IN(dsg->width)
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+/*-*- mapping table holders -*-*/
+
+#define ENCMAP(enc) static const encode_map *enc##_encmap = NULL;
+#define DECMAP(enc) static const decode_map *enc##_decmap = NULL;
+
+/* kr */
+ENCMAP(cp949)
+DECMAP(ksx1001)
+
+/* jp */
+ENCMAP(jisxcommon)
+DECMAP(jisx0208)
+DECMAP(jisx0212)
+ENCMAP(jisx0213_bmp)
+DECMAP(jisx0213_1_bmp)
+DECMAP(jisx0213_2_bmp)
+ENCMAP(jisx0213_emp)
+DECMAP(jisx0213_1_emp)
+DECMAP(jisx0213_2_emp)
+
+/* cn */
+ENCMAP(gbcommon)
+DECMAP(gb2312)
+
+/* tw */
+
+/*-*- mapping access functions -*-*/
+
+static int
+ksx1001_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized && (
+ IMPORT_MAP(kr, cp949, &cp949_encmap, NULL) ||
+ IMPORT_MAP(kr, ksx1001, NULL, &ksx1001_decmap)))
+ return -1;
+ initialized = 1;
+ return 0;
+}
+
+static ucs4_t
+ksx1001_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ TRYMAP_DEC(ksx1001, u, data[0], data[1])
+ return u;
+ else
+ return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+ksx1001_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ assert(*length == 1);
+ if (*data < 0x10000) {
+ TRYMAP_ENC(cp949, coded, *data)
+ if (!(coded & 0x8000))
+ return coded;
+ }
+ return MAP_UNMAPPABLE;
+}
+
+static int
+jisx0208_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized && (
+ IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) ||
+ IMPORT_MAP(jp, jisx0208, NULL, &jisx0208_decmap)))
+ return -1;
+ initialized = 1;
+ return 0;
+}
+
+static ucs4_t
+jisx0208_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
+ return 0xff3c;
+ else TRYMAP_DEC(jisx0208, u, data[0], data[1])
+ return u;
+ else
+ return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+jisx0208_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ assert(*length == 1);
+ if (*data < 0x10000) {
+ if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */
+ return 0x2140;
+ else TRYMAP_ENC(jisxcommon, coded, *data) {
+ if (!(coded & 0x8000))
+ return coded;
+ }
+ }
+ return MAP_UNMAPPABLE;
+}
+
+static int
+jisx0212_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized && (
+ IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) ||
+ IMPORT_MAP(jp, jisx0212, NULL, &jisx0212_decmap)))
+ return -1;
+ initialized = 1;
+ return 0;
+}
+
+static ucs4_t
+jisx0212_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ TRYMAP_DEC(jisx0212, u, data[0], data[1])
+ return u;
+ else
+ return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+jisx0212_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ assert(*length == 1);
+ if (*data < 0x10000) {
+ TRYMAP_ENC(jisxcommon, coded, *data) {
+ if (coded & 0x8000)
+ return coded & 0x7fff;
+ }
+ }
+ return MAP_UNMAPPABLE;
+}
+
+static int
+jisx0213_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized && (
+ jisx0208_init() ||
+ IMPORT_MAP(jp, jisx0213_bmp,
+ &jisx0213_bmp_encmap, NULL) ||
+ IMPORT_MAP(jp, jisx0213_1_bmp,
+ NULL, &jisx0213_1_bmp_decmap) ||
+ IMPORT_MAP(jp, jisx0213_2_bmp,
+ NULL, &jisx0213_2_bmp_decmap) ||
+ IMPORT_MAP(jp, jisx0213_emp,
+ &jisx0213_emp_encmap, NULL) ||
+ IMPORT_MAP(jp, jisx0213_1_emp,
+ NULL, &jisx0213_1_emp_decmap) ||
+ IMPORT_MAP(jp, jisx0213_2_emp,
+ NULL, &jisx0213_2_emp_decmap) ||
+ IMPORT_MAP(jp, jisx0213_pair, &jisx0213_pair_encmap,
+ &jisx0213_pair_decmap)))
+ return -1;
+ initialized = 1;
+ return 0;
+}
+
+#define config ((void *)2000)
+static ucs4_t
+jisx0213_2000_1_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ EMULATE_JISX0213_2000_DECODE_PLANE1(u, data[0], data[1])
+ else if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
+ return 0xff3c;
+ else TRYMAP_DEC(jisx0208, u, data[0], data[1]);
+ else TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1]);
+ else TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])
+ u |= 0x20000;
+ else TRYMAP_DEC(jisx0213_pair, u, data[0], data[1]);
+ else
+ return MAP_UNMAPPABLE;
+ return u;
+}
+
+static ucs4_t
+jisx0213_2000_2_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ EMULATE_JISX0213_2000_DECODE_PLANE2(u, data[0], data[1])
+ TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1]);
+ else TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])
+ u |= 0x20000;
+ else
+ return MAP_UNMAPPABLE;
+ return u;
+}
+#undef config
+
+static ucs4_t
+jisx0213_2004_1_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
+ return 0xff3c;
+ else TRYMAP_DEC(jisx0208, u, data[0], data[1]);
+ else TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1]);
+ else TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])
+ u |= 0x20000;
+ else TRYMAP_DEC(jisx0213_pair, u, data[0], data[1]);
+ else
+ return MAP_UNMAPPABLE;
+ return u;
+}
+
+static ucs4_t
+jisx0213_2004_2_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1]);
+ else TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])
+ u |= 0x20000;
+ else
+ return MAP_UNMAPPABLE;
+ return u;
+}
+
+static DBCHAR
+jisx0213_encoder(const ucs4_t *data, Py_ssize_t *length, void *config)
+{
+ DBCHAR coded;
+
+ switch (*length) {
+ case 1: /* first character */
+ if (*data >= 0x10000) {
+ if ((*data) >> 16 == 0x20000 >> 16) {
+ EMULATE_JISX0213_2000_ENCODE_EMP(coded, *data)
+ else TRYMAP_ENC(jisx0213_emp, coded,
+ (*data) & 0xffff)
+ return coded;
+ }
+ return MAP_UNMAPPABLE;
+ }
+
+ EMULATE_JISX0213_2000_ENCODE_BMP(coded, *data)
+ else TRYMAP_ENC(jisx0213_bmp, coded, *data) {
+ if (coded == MULTIC)
+ return MAP_MULTIPLE_AVAIL;
+ }
+ else TRYMAP_ENC(jisxcommon, coded, *data) {
+ if (coded & 0x8000)
+ return MAP_UNMAPPABLE;
+ }
+ else
+ return MAP_UNMAPPABLE;
+ return coded;
+ case 2: /* second character of unicode pair */
+ coded = find_pairencmap((ucs2_t)data[0], (ucs2_t)data[1],
+ jisx0213_pair_encmap, JISX0213_ENCPAIRS);
+ if (coded == DBCINV) {
+ *length = 1;
+ coded = find_pairencmap((ucs2_t)data[0], 0,
+ jisx0213_pair_encmap, JISX0213_ENCPAIRS);
+ if (coded == DBCINV)
+ return MAP_UNMAPPABLE;
+ }
+ else
+ return coded;
+ case -1: /* flush unterminated */
+ *length = 1;
+ coded = find_pairencmap((ucs2_t)data[0], 0,
+ jisx0213_pair_encmap, JISX0213_ENCPAIRS);
+ if (coded == DBCINV)
+ return MAP_UNMAPPABLE;
+ else
+ return coded;
+ default:
+ return MAP_UNMAPPABLE;
+ }
+}
+
+static DBCHAR
+jisx0213_2000_1_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded = jisx0213_encoder(data, length, (void *)2000);
+ if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+ return coded;
+ else if (coded & 0x8000)
+ return MAP_UNMAPPABLE;
+ else
+ return coded;
+}
+
+static DBCHAR
+jisx0213_2000_1_encoder_paironly(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ Py_ssize_t ilength = *length;
+
+ coded = jisx0213_encoder(data, length, (void *)2000);
+ switch (ilength) {
+ case 1:
+ if (coded == MAP_MULTIPLE_AVAIL)
+ return MAP_MULTIPLE_AVAIL;
+ else
+ return MAP_UNMAPPABLE;
+ case 2:
+ if (*length != 2)
+ return MAP_UNMAPPABLE;
+ else
+ return coded;
+ default:
+ return MAP_UNMAPPABLE;
+ }
+}
+
+static DBCHAR
+jisx0213_2000_2_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded = jisx0213_encoder(data, length, (void *)2000);
+ if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+ return coded;
+ else if (coded & 0x8000)
+ return coded & 0x7fff;
+ else
+ return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+jisx0213_2004_1_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded = jisx0213_encoder(data, length, NULL);
+ if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+ return coded;
+ else if (coded & 0x8000)
+ return MAP_UNMAPPABLE;
+ else
+ return coded;
+}
+
+static DBCHAR
+jisx0213_2004_1_encoder_paironly(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ Py_ssize_t ilength = *length;
+
+ coded = jisx0213_encoder(data, length, NULL);
+ switch (ilength) {
+ case 1:
+ if (coded == MAP_MULTIPLE_AVAIL)
+ return MAP_MULTIPLE_AVAIL;
+ else
+ return MAP_UNMAPPABLE;
+ case 2:
+ if (*length != 2)
+ return MAP_UNMAPPABLE;
+ else
+ return coded;
+ default:
+ return MAP_UNMAPPABLE;
+ }
+}
+
+static DBCHAR
+jisx0213_2004_2_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded = jisx0213_encoder(data, length, NULL);
+ if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
+ return coded;
+ else if (coded & 0x8000)
+ return coded & 0x7fff;
+ else
+ return MAP_UNMAPPABLE;
+}
+
+static ucs4_t
+jisx0201_r_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ JISX0201_R_DECODE(*data, u)
+ else return MAP_UNMAPPABLE;
+ return u;
+}
+
+static DBCHAR
+jisx0201_r_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ JISX0201_R_ENCODE(*data, coded)
+ else return MAP_UNMAPPABLE;
+ return coded;
+}
+
+static ucs4_t
+jisx0201_k_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ JISX0201_K_DECODE(*data ^ 0x80, u)
+ else return MAP_UNMAPPABLE;
+ return u;
+}
+
+static DBCHAR
+jisx0201_k_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ JISX0201_K_ENCODE(*data, coded)
+ else return MAP_UNMAPPABLE;
+ return coded - 0x80;
+}
+
+static int
+gb2312_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized && (
+ IMPORT_MAP(cn, gbcommon, &gbcommon_encmap, NULL) ||
+ IMPORT_MAP(cn, gb2312, NULL, &gb2312_decmap)))
+ return -1;
+ initialized = 1;
+ return 0;
+}
+
+static ucs4_t
+gb2312_decoder(const unsigned char *data)
+{
+ ucs4_t u;
+ TRYMAP_DEC(gb2312, u, data[0], data[1])
+ return u;
+ else
+ return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+gb2312_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ DBCHAR coded;
+ assert(*length == 1);
+ if (*data < 0x10000) {
+ TRYMAP_ENC(gbcommon, coded, *data) {
+ if (!(coded & 0x8000))
+ return coded;
+ }
+ }
+ return MAP_UNMAPPABLE;
+}
+
+
+static ucs4_t
+dummy_decoder(const unsigned char *data)
+{
+ return MAP_UNMAPPABLE;
+}
+
+static DBCHAR
+dummy_encoder(const ucs4_t *data, Py_ssize_t *length)
+{
+ return MAP_UNMAPPABLE;
+}
+
+/*-*- registry tables -*-*/
+
+#define REGISTRY_KSX1001_G0 { CHARSET_KSX1001, 0, 2, \
+ ksx1001_init, \
+ ksx1001_decoder, ksx1001_encoder }
+#define REGISTRY_KSX1001_G1 { CHARSET_KSX1001, 1, 2, \
+ ksx1001_init, \
+ ksx1001_decoder, ksx1001_encoder }
+#define REGISTRY_JISX0201_R { CHARSET_JISX0201_R, 0, 1, \
+ NULL, \
+ jisx0201_r_decoder, jisx0201_r_encoder }
+#define REGISTRY_JISX0201_K { CHARSET_JISX0201_K, 0, 1, \
+ NULL, \
+ jisx0201_k_decoder, jisx0201_k_encoder }
+#define REGISTRY_JISX0208 { CHARSET_JISX0208, 0, 2, \
+ jisx0208_init, \
+ jisx0208_decoder, jisx0208_encoder }
+#define REGISTRY_JISX0208_O { CHARSET_JISX0208_O, 0, 2, \
+ jisx0208_init, \
+ jisx0208_decoder, jisx0208_encoder }
+#define REGISTRY_JISX0212 { CHARSET_JISX0212, 0, 2, \
+ jisx0212_init, \
+ jisx0212_decoder, jisx0212_encoder }
+#define REGISTRY_JISX0213_2000_1 { CHARSET_JISX0213_2000_1, 0, 2, \
+ jisx0213_init, \
+ jisx0213_2000_1_decoder, \
+ jisx0213_2000_1_encoder }
+#define REGISTRY_JISX0213_2000_1_PAIRONLY { CHARSET_JISX0213_2000_1, 0, 2, \
+ jisx0213_init, \
+ jisx0213_2000_1_decoder, \
+ jisx0213_2000_1_encoder_paironly }
+#define REGISTRY_JISX0213_2000_2 { CHARSET_JISX0213_2, 0, 2, \
+ jisx0213_init, \
+ jisx0213_2000_2_decoder, \
+ jisx0213_2000_2_encoder }
+#define REGISTRY_JISX0213_2004_1 { CHARSET_JISX0213_2004_1, 0, 2, \
+ jisx0213_init, \
+ jisx0213_2004_1_decoder, \
+ jisx0213_2004_1_encoder }
+#define REGISTRY_JISX0213_2004_1_PAIRONLY { CHARSET_JISX0213_2004_1, 0, 2, \
+ jisx0213_init, \
+ jisx0213_2004_1_decoder, \
+ jisx0213_2004_1_encoder_paironly }
+#define REGISTRY_JISX0213_2004_2 { CHARSET_JISX0213_2, 0, 2, \
+ jisx0213_init, \
+ jisx0213_2004_2_decoder, \
+ jisx0213_2004_2_encoder }
+#define REGISTRY_GB2312 { CHARSET_GB2312, 0, 2, \
+ gb2312_init, \
+ gb2312_decoder, gb2312_encoder }
+#define REGISTRY_CNS11643_1 { CHARSET_CNS11643_1, 1, 2, \
+ cns11643_init, \
+ cns11643_1_decoder, cns11643_1_encoder }
+#define REGISTRY_CNS11643_2 { CHARSET_CNS11643_2, 2, 2, \
+ cns11643_init, \
+ cns11643_2_decoder, cns11643_2_encoder }
+#define REGISTRY_ISO8859_1 { CHARSET_ISO8859_1, 2, 1, \
+ NULL, dummy_decoder, dummy_encoder }
+#define REGISTRY_ISO8859_7 { CHARSET_ISO8859_7, 2, 1, \
+ NULL, dummy_decoder, dummy_encoder }
+#define REGISTRY_SENTINEL { 0, }
+#define CONFIGDEF(var, attrs) \
+ static const struct iso2022_config iso2022_##var##_config = { \
+ attrs, iso2022_##var##_designations \
+ };
+
+static const struct iso2022_designation iso2022_kr_designations[] = {
+ REGISTRY_KSX1001_G1, REGISTRY_SENTINEL
+};
+CONFIGDEF(kr, 0)
+
+static const struct iso2022_designation iso2022_jp_designations[] = {
+ REGISTRY_JISX0208, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O,
+ REGISTRY_SENTINEL
+};
+CONFIGDEF(jp, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_1_designations[] = {
+ REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R,
+ REGISTRY_JISX0208_O, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_1, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_2_designations[] = {
+ REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001_G0,
+ REGISTRY_GB2312, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O,
+ REGISTRY_ISO8859_1, REGISTRY_ISO8859_7, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_2, NO_SHIFT | USE_G2 | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_2004_designations[] = {
+ REGISTRY_JISX0213_2004_1_PAIRONLY, REGISTRY_JISX0208,
+ REGISTRY_JISX0213_2004_1, REGISTRY_JISX0213_2004_2, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_2004, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_3_designations[] = {
+ REGISTRY_JISX0213_2000_1_PAIRONLY, REGISTRY_JISX0208,
+ REGISTRY_JISX0213_2000_1, REGISTRY_JISX0213_2000_2, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_3, NO_SHIFT | USE_JISX0208_EXT)
+
+static const struct iso2022_designation iso2022_jp_ext_designations[] = {
+ REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R,
+ REGISTRY_JISX0201_K, REGISTRY_JISX0208_O, REGISTRY_SENTINEL
+};
+CONFIGDEF(jp_ext, NO_SHIFT | USE_JISX0208_EXT)
+
+
+BEGIN_MAPPINGS_LIST
+ /* no mapping table here */
+END_MAPPINGS_LIST
+
+#define ISO2022_CODEC(variation) { \
+ "iso2022_" #variation, \
+ &iso2022_##variation##_config, \
+ iso2022_codec_init, \
+ _STATEFUL_METHODS(iso2022) \
+},
+
+BEGIN_CODECS_LIST
+ ISO2022_CODEC(kr)
+ ISO2022_CODEC(jp)
+ ISO2022_CODEC(jp_1)
+ ISO2022_CODEC(jp_2)
+ ISO2022_CODEC(jp_2004)
+ ISO2022_CODEC(jp_3)
+ ISO2022_CODEC(jp_ext)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(iso2022)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/_codecs_jp.c b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_jp.c
new file mode 100644
index 000000000..f49a10b10
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_jp.c
@@ -0,0 +1,731 @@
+/*
+ * _codecs_jp.c: Codecs collection for Japanese encodings
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#define USING_BINARY_PAIR_SEARCH
+#define EMPBASE 0x20000
+
+#include "cjkcodecs.h"
+#include "mappings_jp.h"
+#include "mappings_jisx0213_pair.h"
+#include "alg_jisx0201.h"
+#include "emu_jisx0213_2000.h"
+
+/*
+ * CP932 codec
+ */
+
+ENCODER(cp932)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+ unsigned char c1, c2;
+
+ if (c <= 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ else if (c >= 0xff61 && c <= 0xff9f) {
+ WRITE1(c - 0xfec0)
+ NEXT(1, 1)
+ continue;
+ }
+ else if (c >= 0xf8f0 && c <= 0xf8f3) {
+ /* Windows compatibility */
+ REQUIRE_OUTBUF(1)
+ if (c == 0xf8f0)
+ OUT1(0xa0)
+ else
+ OUT1(c - 0xfef1 + 0xfd)
+ NEXT(1, 1)
+ continue;
+ }
+
+ UCS4INVALID(c)
+ REQUIRE_OUTBUF(2)
+
+ TRYMAP_ENC(cp932ext, code, c) {
+ OUT1(code >> 8)
+ OUT2(code & 0xff)
+ }
+ else TRYMAP_ENC(jisxcommon, code, c) {
+ if (code & 0x8000) /* MSB set: JIS X 0212 */
+ return 1;
+
+ /* JIS X 0208 */
+ c1 = code >> 8;
+ c2 = code & 0xff;
+ c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
+ c1 = (c1 - 0x21) >> 1;
+ OUT1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1)
+ OUT2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41)
+ }
+ else if (c >= 0xe000 && c < 0xe758) {
+ /* User-defined area */
+ c1 = (Py_UNICODE)(c - 0xe000) / 188;
+ c2 = (Py_UNICODE)(c - 0xe000) % 188;
+ OUT1(c1 + 0xf0)
+ OUT2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41)
+ }
+ else
+ return 1;
+
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(cp932)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1, c2;
+
+ REQUIRE_OUTBUF(1)
+ if (c <= 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+ else if (c >= 0xa0 && c <= 0xdf) {
+ if (c == 0xa0)
+ OUT1(0xf8f0) /* half-width katakana */
+ else
+ OUT1(0xfec0 + c)
+ NEXT(1, 1)
+ continue;
+ }
+ else if (c >= 0xfd/* && c <= 0xff*/) {
+ /* Windows compatibility */
+ OUT1(0xf8f1 - 0xfd + c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+
+ TRYMAP_DEC(cp932ext, **outbuf, c, c2);
+ else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){
+ if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+ return 2;
+
+ c = (c < 0xe0 ? c - 0x81 : c - 0xc1);
+ c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
+ c = (2 * c + (c2 < 0x5e ? 0 : 1) + 0x21);
+ c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
+
+ TRYMAP_DEC(jisx0208, **outbuf, c, c2);
+ else return 2;
+ }
+ else if (c >= 0xf0 && c <= 0xf9) {
+ if ((c2 >= 0x40 && c2 <= 0x7e) ||
+ (c2 >= 0x80 && c2 <= 0xfc))
+ OUT1(0xe000 + 188 * (c - 0xf0) +
+ (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41))
+ else
+ return 2;
+ }
+ else
+ return 2;
+
+ NEXT(2, 1)
+ }
+
+ return 0;
+}
+
+
+/*
+ * EUC-JIS-2004 codec
+ */
+
+ENCODER(euc_jis_2004)
+{
+ while (inleft > 0) {
+ ucs4_t c = IN1;
+ DBCHAR code;
+ Py_ssize_t insize;
+
+ if (c < 0x80) {
+ WRITE1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ DECODE_SURROGATE(c)
+ insize = GET_INSIZE(c);
+
+ if (c <= 0xFFFF) {
+ EMULATE_JISX0213_2000_ENCODE_BMP(code, c)
+ else TRYMAP_ENC(jisx0213_bmp, code, c) {
+ if (code == MULTIC) {
+ if (inleft < 2) {
+ if (flags & MBENC_FLUSH) {
+ code = find_pairencmap(
+ (ucs2_t)c, 0,
+ jisx0213_pair_encmap,
+ JISX0213_ENCPAIRS);
+ if (code == DBCINV)
+ return 1;
+ }
+ else
+ return MBERR_TOOFEW;
+ }
+ else {
+ code = find_pairencmap(
+ (ucs2_t)c, (*inbuf)[1],
+ jisx0213_pair_encmap,
+ JISX0213_ENCPAIRS);
+ if (code == DBCINV) {
+ code = find_pairencmap(
+ (ucs2_t)c, 0,
+ jisx0213_pair_encmap,
+ JISX0213_ENCPAIRS);
+ if (code == DBCINV)
+ return 1;
+ } else
+ insize = 2;
+ }
+ }
+ }
+ else TRYMAP_ENC(jisxcommon, code, c);
+ else if (c >= 0xff61 && c <= 0xff9f) {
+ /* JIS X 0201 half-width katakana */
+ WRITE2(0x8e, c - 0xfec0)
+ NEXT(1, 2)
+ continue;
+ }
+ else if (c == 0xff3c)
+ /* F/W REVERSE SOLIDUS (see NOTES) */
+ code = 0x2140;
+ else if (c == 0xff5e)
+ /* F/W TILDE (see NOTES) */
+ code = 0x2232;
+ else
+ return 1;
+ }
+ else if (c >> 16 == EMPBASE >> 16) {
+ EMULATE_JISX0213_2000_ENCODE_EMP(code, c)
+ else TRYMAP_ENC(jisx0213_emp, code, c & 0xffff);
+ else return insize;
+ }
+ else
+ return insize;
+
+ if (code & 0x8000) {
+ /* Codeset 2 */
+ WRITE3(0x8f, code >> 8, (code & 0xFF) | 0x80)
+ NEXT(insize, 3)
+ } else {
+ /* Codeset 1 */
+ WRITE2((code >> 8) | 0x80, (code & 0xFF) | 0x80)
+ NEXT(insize, 2)
+ }
+ }
+
+ return 0;
+}
+
+DECODER(euc_jis_2004)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+ ucs4_t code;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ if (c == 0x8e) {
+ /* JIS X 0201 half-width katakana */
+ unsigned char c2;
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+ if (c2 >= 0xa1 && c2 <= 0xdf) {
+ OUT1(0xfec0 + c2)
+ NEXT(2, 1)
+ }
+ else
+ return 2;
+ }
+ else if (c == 0x8f) {
+ unsigned char c2, c3;
+
+ REQUIRE_INBUF(3)
+ c2 = IN2 ^ 0x80;
+ c3 = IN3 ^ 0x80;
+
+ /* JIS X 0213 Plane 2 or JIS X 0212 (see NOTES) */
+ EMULATE_JISX0213_2000_DECODE_PLANE2(**outbuf, c2, c3)
+ else TRYMAP_DEC(jisx0213_2_bmp, **outbuf, c2, c3) ;
+ else TRYMAP_DEC(jisx0213_2_emp, code, c2, c3) {
+ WRITEUCS4(EMPBASE | code)
+ NEXT_IN(3)
+ continue;
+ }
+ else TRYMAP_DEC(jisx0212, **outbuf, c2, c3) ;
+ else return 3;
+ NEXT(3, 1)
+ }
+ else {
+ unsigned char c2;
+
+ REQUIRE_INBUF(2)
+ c ^= 0x80;
+ c2 = IN2 ^ 0x80;
+
+ /* JIS X 0213 Plane 1 */
+ EMULATE_JISX0213_2000_DECODE_PLANE1(**outbuf, c, c2)
+ else if (c == 0x21 && c2 == 0x40) **outbuf = 0xff3c;
+ else if (c == 0x22 && c2 == 0x32) **outbuf = 0xff5e;
+ else TRYMAP_DEC(jisx0208, **outbuf, c, c2);
+ else TRYMAP_DEC(jisx0213_1_bmp, **outbuf, c, c2);
+ else TRYMAP_DEC(jisx0213_1_emp, code, c, c2) {
+ WRITEUCS4(EMPBASE | code)
+ NEXT_IN(2)
+ continue;
+ }
+ else TRYMAP_DEC(jisx0213_pair, code, c, c2) {
+ WRITE2(code >> 16, code & 0xffff)
+ NEXT(2, 2)
+ continue;
+ }
+ else return 2;
+ NEXT(2, 1)
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * EUC-JP codec
+ */
+
+ENCODER(euc_jp)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ UCS4INVALID(c)
+
+ TRYMAP_ENC(jisxcommon, code, c);
+ else if (c >= 0xff61 && c <= 0xff9f) {
+ /* JIS X 0201 half-width katakana */
+ WRITE2(0x8e, c - 0xfec0)
+ NEXT(1, 2)
+ continue;
+ }
+#ifndef STRICT_BUILD
+ else if (c == 0xff3c) /* FULL-WIDTH REVERSE SOLIDUS */
+ code = 0x2140;
+ else if (c == 0xa5) { /* YEN SIGN */
+ WRITE1(0x5c);
+ NEXT(1, 1)
+ continue;
+ } else if (c == 0x203e) { /* OVERLINE */
+ WRITE1(0x7e);
+ NEXT(1, 1)
+ continue;
+ }
+#endif
+ else
+ return 1;
+
+ if (code & 0x8000) {
+ /* JIS X 0212 */
+ WRITE3(0x8f, code >> 8, (code & 0xFF) | 0x80)
+ NEXT(1, 3)
+ } else {
+ /* JIS X 0208 */
+ WRITE2((code >> 8) | 0x80, (code & 0xFF) | 0x80)
+ NEXT(1, 2)
+ }
+ }
+
+ return 0;
+}
+
+DECODER(euc_jp)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ if (c == 0x8e) {
+ /* JIS X 0201 half-width katakana */
+ unsigned char c2;
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+ if (c2 >= 0xa1 && c2 <= 0xdf) {
+ OUT1(0xfec0 + c2)
+ NEXT(2, 1)
+ }
+ else
+ return 2;
+ }
+ else if (c == 0x8f) {
+ unsigned char c2, c3;
+
+ REQUIRE_INBUF(3)
+ c2 = IN2;
+ c3 = IN3;
+ /* JIS X 0212 */
+ TRYMAP_DEC(jisx0212, **outbuf, c2 ^ 0x80, c3 ^ 0x80) {
+ NEXT(3, 1)
+ }
+ else
+ return 3;
+ }
+ else {
+ unsigned char c2;
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+ /* JIS X 0208 */
+#ifndef STRICT_BUILD
+ if (c == 0xa1 && c2 == 0xc0)
+ /* FULL-WIDTH REVERSE SOLIDUS */
+ **outbuf = 0xff3c;
+ else
+#endif
+ TRYMAP_DEC(jisx0208, **outbuf,
+ c ^ 0x80, c2 ^ 0x80) ;
+ else return 2;
+ NEXT(2, 1)
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * SHIFT_JIS codec
+ */
+
+ENCODER(shift_jis)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+ unsigned char c1, c2;
+
+#ifdef STRICT_BUILD
+ JISX0201_R_ENCODE(c, code)
+#else
+ if (c < 0x80) code = c;
+ else if (c == 0x00a5) code = 0x5c; /* YEN SIGN */
+ else if (c == 0x203e) code = 0x7e; /* OVERLINE */
+#endif
+ else JISX0201_K_ENCODE(c, code)
+ else UCS4INVALID(c)
+ else code = NOCHAR;
+
+ if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) {
+ REQUIRE_OUTBUF(1)
+
+ OUT1((unsigned char)code)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_OUTBUF(2)
+
+ if (code == NOCHAR) {
+ TRYMAP_ENC(jisxcommon, code, c);
+#ifndef STRICT_BUILD
+ else if (c == 0xff3c)
+ code = 0x2140; /* FULL-WIDTH REVERSE SOLIDUS */
+#endif
+ else
+ return 1;
+
+ if (code & 0x8000) /* MSB set: JIS X 0212 */
+ return 1;
+ }
+
+ c1 = code >> 8;
+ c2 = code & 0xff;
+ c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
+ c1 = (c1 - 0x21) >> 1;
+ OUT1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1)
+ OUT2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41)
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(shift_jis)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+#ifdef STRICT_BUILD
+ JISX0201_R_DECODE(c, **outbuf)
+#else
+ if (c < 0x80) **outbuf = c;
+#endif
+ else JISX0201_K_DECODE(c, **outbuf)
+ else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){
+ unsigned char c1, c2;
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+ if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+ return 2;
+
+ c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1);
+ c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
+ c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1) + 0x21);
+ c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
+
+#ifndef STRICT_BUILD
+ if (c1 == 0x21 && c2 == 0x40) {
+ /* FULL-WIDTH REVERSE SOLIDUS */
+ OUT1(0xff3c)
+ NEXT(2, 1)
+ continue;
+ }
+#endif
+ TRYMAP_DEC(jisx0208, **outbuf, c1, c2) {
+ NEXT(2, 1)
+ continue;
+ }
+ else
+ return 2;
+ }
+ else
+ return 2;
+
+ NEXT(1, 1) /* JIS X 0201 */
+ }
+
+ return 0;
+}
+
+
+/*
+ * SHIFT_JIS-2004 codec
+ */
+
+ENCODER(shift_jis_2004)
+{
+ while (inleft > 0) {
+ ucs4_t c = IN1;
+ DBCHAR code = NOCHAR;
+ int c1, c2;
+ Py_ssize_t insize;
+
+ JISX0201_ENCODE(c, code)
+ else DECODE_SURROGATE(c)
+
+ if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) {
+ WRITE1((unsigned char)code)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_OUTBUF(2)
+ insize = GET_INSIZE(c);
+
+ if (code == NOCHAR) {
+ if (c <= 0xffff) {
+ EMULATE_JISX0213_2000_ENCODE_BMP(code, c)
+ else TRYMAP_ENC(jisx0213_bmp, code, c) {
+ if (code == MULTIC) {
+ if (inleft < 2) {
+ if (flags & MBENC_FLUSH) {
+ code = find_pairencmap
+ ((ucs2_t)c, 0,
+ jisx0213_pair_encmap,
+ JISX0213_ENCPAIRS);
+ if (code == DBCINV)
+ return 1;
+ }
+ else
+ return MBERR_TOOFEW;
+ }
+ else {
+ code = find_pairencmap(
+ (ucs2_t)c, IN2,
+ jisx0213_pair_encmap,
+ JISX0213_ENCPAIRS);
+ if (code == DBCINV) {
+ code = find_pairencmap(
+ (ucs2_t)c, 0,
+ jisx0213_pair_encmap,
+ JISX0213_ENCPAIRS);
+ if (code == DBCINV)
+ return 1;
+ }
+ else
+ insize = 2;
+ }
+ }
+ }
+ else TRYMAP_ENC(jisxcommon, code, c) {
+ /* abandon JIS X 0212 codes */
+ if (code & 0x8000)
+ return 1;
+ }
+ else return 1;
+ }
+ else if (c >> 16 == EMPBASE >> 16) {
+ EMULATE_JISX0213_2000_ENCODE_EMP(code, c)
+ else TRYMAP_ENC(jisx0213_emp, code, c&0xffff);
+ else return insize;
+ }
+ else
+ return insize;
+ }
+
+ c1 = code >> 8;
+ c2 = (code & 0xff) - 0x21;
+
+ if (c1 & 0x80) { /* Plane 2 */
+ if (c1 >= 0xee) c1 -= 0x87;
+ else if (c1 >= 0xac || c1 == 0xa8) c1 -= 0x49;
+ else c1 -= 0x43;
+ }
+ else /* Plane 1 */
+ c1 -= 0x21;
+
+ if (c1 & 1) c2 += 0x5e;
+ c1 >>= 1;
+ OUT1(c1 + (c1 < 0x1f ? 0x81 : 0xc1))
+ OUT2(c2 + (c2 < 0x3f ? 0x40 : 0x41))
+
+ NEXT(insize, 2)
+ }
+
+ return 0;
+}
+
+DECODER(shift_jis_2004)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+ JISX0201_DECODE(c, **outbuf)
+ else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)){
+ unsigned char c1, c2;
+ ucs4_t code;
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+ if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+ return 2;
+
+ c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1);
+ c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
+ c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1));
+ c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
+
+ if (c1 < 0x5e) { /* Plane 1 */
+ c1 += 0x21;
+ EMULATE_JISX0213_2000_DECODE_PLANE1(**outbuf,
+ c1, c2)
+ else TRYMAP_DEC(jisx0208, **outbuf, c1, c2) {
+ NEXT_OUT(1)
+ }
+ else TRYMAP_DEC(jisx0213_1_bmp, **outbuf,
+ c1, c2) {
+ NEXT_OUT(1)
+ }
+ else TRYMAP_DEC(jisx0213_1_emp, code, c1, c2) {
+ WRITEUCS4(EMPBASE | code)
+ }
+ else TRYMAP_DEC(jisx0213_pair, code, c1, c2) {
+ WRITE2(code >> 16, code & 0xffff)
+ NEXT_OUT(2)
+ }
+ else
+ return 2;
+ NEXT_IN(2)
+ }
+ else { /* Plane 2 */
+ if (c1 >= 0x67) c1 += 0x07;
+ else if (c1 >= 0x63 || c1 == 0x5f) c1 -= 0x37;
+ else c1 -= 0x3d;
+
+ EMULATE_JISX0213_2000_DECODE_PLANE2(**outbuf,
+ c1, c2)
+ else TRYMAP_DEC(jisx0213_2_bmp, **outbuf,
+ c1, c2) ;
+ else TRYMAP_DEC(jisx0213_2_emp, code, c1, c2) {
+ WRITEUCS4(EMPBASE | code)
+ NEXT_IN(2)
+ continue;
+ }
+ else
+ return 2;
+ NEXT(2, 1)
+ }
+ continue;
+ }
+ else
+ return 2;
+
+ NEXT(1, 1) /* JIS X 0201 */
+ }
+
+ return 0;
+}
+
+
+BEGIN_MAPPINGS_LIST
+ MAPPING_DECONLY(jisx0208)
+ MAPPING_DECONLY(jisx0212)
+ MAPPING_ENCONLY(jisxcommon)
+ MAPPING_DECONLY(jisx0213_1_bmp)
+ MAPPING_DECONLY(jisx0213_2_bmp)
+ MAPPING_ENCONLY(jisx0213_bmp)
+ MAPPING_DECONLY(jisx0213_1_emp)
+ MAPPING_DECONLY(jisx0213_2_emp)
+ MAPPING_ENCONLY(jisx0213_emp)
+ MAPPING_ENCDEC(jisx0213_pair)
+ MAPPING_ENCDEC(cp932ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+ CODEC_STATELESS(shift_jis)
+ CODEC_STATELESS(cp932)
+ CODEC_STATELESS(euc_jp)
+ CODEC_STATELESS(shift_jis_2004)
+ CODEC_STATELESS(euc_jis_2004)
+ { "euc_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(euc_jis_2004) },
+ { "shift_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(shift_jis_2004) },
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(jp)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/_codecs_kr.c b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_kr.c
new file mode 100644
index 000000000..2a95bbe9b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_kr.c
@@ -0,0 +1,355 @@
+/*
+ * _codecs_kr.c: Codecs collection for Korean encodings
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#include "cjkcodecs.h"
+#include "mappings_kr.h"
+
+/*
+ * EUC-KR codec
+ */
+
+ENCODER(euc_kr)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+ TRYMAP_ENC(cp949, code, c);
+ else return 1;
+
+ if (code & 0x8000) /* MSB set: CP949 */
+ return 1;
+
+ OUT1((code >> 8) | 0x80)
+ OUT2((code & 0xFF) | 0x80)
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(euc_kr)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+
+ TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
+ NEXT(2, 1)
+ } else return 2;
+ }
+
+ return 0;
+}
+
+
+/*
+ * CP949 codec
+ */
+
+ENCODER(cp949)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+ TRYMAP_ENC(cp949, code, c);
+ else return 1;
+
+ OUT1((code >> 8) | 0x80)
+ if (code & 0x8000)
+ OUT2(code & 0xFF) /* MSB set: CP949 */
+ else
+ OUT2((code & 0xFF) | 0x80) /* MSB unset: ks x 1001 */
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(cp949)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+ TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80);
+ else TRYMAP_DEC(cp949ext, **outbuf, c, IN2);
+ else return 2;
+
+ NEXT(2, 1)
+ }
+
+ return 0;
+}
+
+
+/*
+ * JOHAB codec
+ */
+
+static const unsigned char u2johabidx_choseong[32] = {
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14,
+};
+static const unsigned char u2johabidx_jungseong[32] = {
+ 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x1a, 0x1b, 0x1c, 0x1d,
+};
+static const unsigned char u2johabidx_jongseong[32] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+};
+static const DBCHAR u2johabjamo[] = {
+ 0x8841, 0x8c41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441,
+ 0x9841, 0x9c41, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f,
+ 0x8450, 0xa041, 0xa441, 0xa841, 0x8454, 0xac41, 0xb041, 0xb441,
+ 0xb841, 0xbc41, 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041, 0x8461,
+ 0x8481, 0x84a1, 0x84c1, 0x84e1, 0x8541, 0x8561, 0x8581, 0x85a1,
+ 0x85c1, 0x85e1, 0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1,
+ 0x8741, 0x8761, 0x8781, 0x87a1,
+};
+
+ENCODER(johab)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+
+ if (c >= 0xac00 && c <= 0xd7a3) {
+ c -= 0xac00;
+ code = 0x8000 |
+ (u2johabidx_choseong[c / 588] << 10) |
+ (u2johabidx_jungseong[(c / 28) % 21] << 5) |
+ u2johabidx_jongseong[c % 28];
+ }
+ else if (c >= 0x3131 && c <= 0x3163)
+ code = u2johabjamo[c - 0x3131];
+ else TRYMAP_ENC(cp949, code, c) {
+ unsigned char c1, c2, t2;
+ unsigned short t1;
+
+ assert((code & 0x8000) == 0);
+ c1 = code >> 8;
+ c2 = code & 0xff;
+ if (((c1 >= 0x21 && c1 <= 0x2c) ||
+ (c1 >= 0x4a && c1 <= 0x7d)) &&
+ (c2 >= 0x21 && c2 <= 0x7e)) {
+ t1 = (c1 < 0x4a ? (c1 - 0x21 + 0x1b2) :
+ (c1 - 0x21 + 0x197));
+ t2 = ((t1 & 1) ? 0x5e : 0) + (c2 - 0x21);
+ OUT1(t1 >> 1)
+ OUT2(t2 < 0x4e ? t2 + 0x31 : t2 + 0x43)
+ NEXT(1, 2)
+ continue;
+ }
+ else
+ return 1;
+ }
+ else
+ return 1;
+
+ OUT1(code >> 8)
+ OUT2(code & 0xff)
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+#define FILL 0xfd
+#define NONE 0xff
+
+static const unsigned char johabidx_choseong[32] = {
+ NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0e, 0x0f, 0x10, 0x11, 0x12, NONE, NONE, NONE,
+ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
+};
+static const unsigned char johabidx_jungseong[32] = {
+ NONE, NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04,
+ NONE, NONE, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ NONE, NONE, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ NONE, NONE, 0x11, 0x12, 0x13, 0x14, NONE, NONE,
+};
+static const unsigned char johabidx_jongseong[32] = {
+ NONE, FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, NONE, 0x11, 0x12, 0x13, 0x14, 0x15,
+ 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, NONE, NONE,
+};
+
+static const unsigned char johabjamo_choseong[32] = {
+ NONE, FILL, 0x31, 0x32, 0x34, 0x37, 0x38, 0x39,
+ 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, NONE,
+ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
+};
+static const unsigned char johabjamo_jungseong[32] = {
+ NONE, NONE, FILL, 0x4f, 0x50, 0x51, 0x52, 0x53,
+ NONE, NONE, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ NONE, NONE, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ NONE, NONE, 0x60, 0x61, 0x62, 0x63, NONE, NONE,
+};
+static const unsigned char johabjamo_jongseong[32] = {
+ NONE, FILL, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, NONE, 0x42, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE,
+};
+
+DECODER(johab)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1, c2;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+ c2 = IN2;
+
+ if (c < 0xd8) {
+ /* johab hangul */
+ unsigned char c_cho, c_jung, c_jong;
+ unsigned char i_cho, i_jung, i_jong;
+
+ c_cho = (c >> 2) & 0x1f;
+ c_jung = ((c << 3) | c2 >> 5) & 0x1f;
+ c_jong = c2 & 0x1f;
+
+ i_cho = johabidx_choseong[c_cho];
+ i_jung = johabidx_jungseong[c_jung];
+ i_jong = johabidx_jongseong[c_jong];
+
+ if (i_cho == NONE || i_jung == NONE || i_jong == NONE)
+ return 2;
+
+ /* we don't use U+1100 hangul jamo yet. */
+ if (i_cho == FILL) {
+ if (i_jung == FILL) {
+ if (i_jong == FILL)
+ OUT1(0x3000)
+ else
+ OUT1(0x3100 |
+ johabjamo_jongseong[c_jong])
+ }
+ else {
+ if (i_jong == FILL)
+ OUT1(0x3100 |
+ johabjamo_jungseong[c_jung])
+ else
+ return 2;
+ }
+ } else {
+ if (i_jung == FILL) {
+ if (i_jong == FILL)
+ OUT1(0x3100 |
+ johabjamo_choseong[c_cho])
+ else
+ return 2;
+ }
+ else
+ OUT1(0xac00 +
+ i_cho * 588 +
+ i_jung * 28 +
+ (i_jong == FILL ? 0 : i_jong))
+ }
+ NEXT(2, 1)
+ } else {
+ /* KS X 1001 except hangul jamos and syllables */
+ if (c == 0xdf || c > 0xf9 ||
+ c2 < 0x31 || (c2 >= 0x80 && c2 < 0x91) ||
+ (c2 & 0x7f) == 0x7f ||
+ (c == 0xda && (c2 >= 0xa1 && c2 <= 0xd3)))
+ return 2;
+ else {
+ unsigned char t1, t2;
+
+ t1 = (c < 0xe0 ? 2 * (c - 0xd9) :
+ 2 * c - 0x197);
+ t2 = (c2 < 0x91 ? c2 - 0x31 : c2 - 0x43);
+ t1 = t1 + (t2 < 0x5e ? 0 : 1) + 0x21;
+ t2 = (t2 < 0x5e ? t2 : t2 - 0x5e) + 0x21;
+
+ TRYMAP_DEC(ksx1001, **outbuf, t1, t2);
+ else return 2;
+ NEXT(2, 1)
+ }
+ }
+ }
+
+ return 0;
+}
+#undef NONE
+#undef FILL
+
+
+BEGIN_MAPPINGS_LIST
+ MAPPING_DECONLY(ksx1001)
+ MAPPING_ENCONLY(cp949)
+ MAPPING_DECONLY(cp949ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+ CODEC_STATELESS(euc_kr)
+ CODEC_STATELESS(cp949)
+ CODEC_STATELESS(johab)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(kr)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/_codecs_tw.c b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_tw.c
new file mode 100644
index 000000000..8ccbca1df
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/_codecs_tw.c
@@ -0,0 +1,132 @@
+/*
+ * _codecs_tw.c: Codecs collection for Taiwan's encodings
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#include "cjkcodecs.h"
+#include "mappings_tw.h"
+
+/*
+ * BIG5 codec
+ */
+
+ENCODER(big5)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = **inbuf;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ REQUIRE_OUTBUF(1)
+ **outbuf = (unsigned char)c;
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+
+ TRYMAP_ENC(big5, code, c);
+ else return 1;
+
+ OUT1(code >> 8)
+ OUT2(code & 0xFF)
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(big5)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+ TRYMAP_DEC(big5, **outbuf, c, IN2) {
+ NEXT(2, 1)
+ }
+ else return 2;
+ }
+
+ return 0;
+}
+
+
+/*
+ * CP950 codec
+ */
+
+ENCODER(cp950)
+{
+ while (inleft > 0) {
+ Py_UNICODE c = IN1;
+ DBCHAR code;
+
+ if (c < 0x80) {
+ WRITE1((unsigned char)c)
+ NEXT(1, 1)
+ continue;
+ }
+ UCS4INVALID(c)
+
+ REQUIRE_OUTBUF(2)
+ TRYMAP_ENC(cp950ext, code, c);
+ else TRYMAP_ENC(big5, code, c);
+ else return 1;
+
+ OUT1(code >> 8)
+ OUT2(code & 0xFF)
+ NEXT(1, 2)
+ }
+
+ return 0;
+}
+
+DECODER(cp950)
+{
+ while (inleft > 0) {
+ unsigned char c = IN1;
+
+ REQUIRE_OUTBUF(1)
+
+ if (c < 0x80) {
+ OUT1(c)
+ NEXT(1, 1)
+ continue;
+ }
+
+ REQUIRE_INBUF(2)
+
+ TRYMAP_DEC(cp950ext, **outbuf, c, IN2);
+ else TRYMAP_DEC(big5, **outbuf, c, IN2);
+ else return 2;
+
+ NEXT(2, 1)
+ }
+
+ return 0;
+}
+
+
+
+BEGIN_MAPPINGS_LIST
+ MAPPING_ENCDEC(big5)
+ MAPPING_ENCDEC(cp950ext)
+END_MAPPINGS_LIST
+
+BEGIN_CODECS_LIST
+ CODEC_STATELESS(big5)
+ CODEC_STATELESS(cp950)
+END_CODECS_LIST
+
+I_AM_A_MODULE_FOR(tw)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/alg_jisx0201.h b/sys/src/cmd/python/Modules/cjkcodecs/alg_jisx0201.h
new file mode 100644
index 000000000..1fca06bce
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/alg_jisx0201.h
@@ -0,0 +1,24 @@
+#define JISX0201_R_ENCODE(c, assi) \
+ if ((c) < 0x80 && (c) != 0x5c && (c) != 0x7e) \
+ (assi) = (c); \
+ else if ((c) == 0x00a5) (assi) = 0x5c; \
+ else if ((c) == 0x203e) (assi) = 0x7e;
+#define JISX0201_K_ENCODE(c, assi) \
+ if ((c) >= 0xff61 && (c) <= 0xff9f) \
+ (assi) = (c) - 0xfec0;
+#define JISX0201_ENCODE(c, assi) \
+ JISX0201_R_ENCODE(c, assi) \
+ else JISX0201_K_ENCODE(c, assi)
+
+#define JISX0201_R_DECODE(c, assi) \
+ if ((c) < 0x5c) (assi) = (c); \
+ else if ((c) == 0x5c) (assi) = 0x00a5; \
+ else if ((c) < 0x7e) (assi) = (c); \
+ else if ((c) == 0x7e) (assi) = 0x203e; \
+ else if ((c) == 0x7f) (assi) = 0x7f;
+#define JISX0201_K_DECODE(c, assi) \
+ if ((c) >= 0xa1 && (c) <= 0xdf) \
+ (assi) = 0xfec0 + (c);
+#define JISX0201_DECODE(c, assi) \
+ JISX0201_R_DECODE(c, assi) \
+ else JISX0201_K_DECODE(c, assi)
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/cjkcodecs.h b/sys/src/cmd/python/Modules/cjkcodecs/cjkcodecs.h
new file mode 100644
index 000000000..71c54f093
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/cjkcodecs.h
@@ -0,0 +1,398 @@
+/*
+ * cjkcodecs.h: common header for cjkcodecs
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#ifndef _CJKCODECS_H_
+#define _CJKCODECS_H_
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "multibytecodec.h"
+
+
+/* a unicode "undefined" codepoint */
+#define UNIINV 0xFFFE
+
+/* internal-use DBCS codepoints which aren't used by any charsets */
+#define NOCHAR 0xFFFF
+#define MULTIC 0xFFFE
+#define DBCINV 0xFFFD
+
+/* shorter macros to save source size of mapping tables */
+#define U UNIINV
+#define N NOCHAR
+#define M MULTIC
+#define D DBCINV
+
+struct dbcs_index {
+ const ucs2_t *map;
+ unsigned char bottom, top;
+};
+typedef struct dbcs_index decode_map;
+
+struct widedbcs_index {
+ const ucs4_t *map;
+ unsigned char bottom, top;
+};
+typedef struct widedbcs_index widedecode_map;
+
+struct unim_index {
+ const DBCHAR *map;
+ unsigned char bottom, top;
+};
+typedef struct unim_index encode_map;
+
+struct unim_index_bytebased {
+ const unsigned char *map;
+ unsigned char bottom, top;
+};
+
+struct dbcs_map {
+ const char *charset;
+ const struct unim_index *encmap;
+ const struct dbcs_index *decmap;
+};
+
+struct pair_encodemap {
+ ucs4_t uniseq;
+ DBCHAR code;
+};
+
+static const MultibyteCodec *codec_list;
+static const struct dbcs_map *mapping_list;
+
+#define CODEC_INIT(encoding) \
+ static int encoding##_codec_init(const void *config)
+
+#define ENCODER_INIT(encoding) \
+ static int encoding##_encode_init( \
+ MultibyteCodec_State *state, const void *config)
+#define ENCODER(encoding) \
+ static Py_ssize_t encoding##_encode( \
+ MultibyteCodec_State *state, const void *config, \
+ const Py_UNICODE **inbuf, Py_ssize_t inleft, \
+ unsigned char **outbuf, Py_ssize_t outleft, int flags)
+#define ENCODER_RESET(encoding) \
+ static Py_ssize_t encoding##_encode_reset( \
+ MultibyteCodec_State *state, const void *config, \
+ unsigned char **outbuf, Py_ssize_t outleft)
+
+#define DECODER_INIT(encoding) \
+ static int encoding##_decode_init( \
+ MultibyteCodec_State *state, const void *config)
+#define DECODER(encoding) \
+ static Py_ssize_t encoding##_decode( \
+ MultibyteCodec_State *state, const void *config, \
+ const unsigned char **inbuf, Py_ssize_t inleft, \
+ Py_UNICODE **outbuf, Py_ssize_t outleft)
+#define DECODER_RESET(encoding) \
+ static Py_ssize_t encoding##_decode_reset( \
+ MultibyteCodec_State *state, const void *config)
+
+#if Py_UNICODE_SIZE == 4
+#define UCS4INVALID(code) \
+ if ((code) > 0xFFFF) \
+ return 1;
+#else
+#define UCS4INVALID(code) \
+ if (0) ;
+#endif
+
+#define NEXT_IN(i) \
+ (*inbuf) += (i); \
+ (inleft) -= (i);
+#define NEXT_OUT(o) \
+ (*outbuf) += (o); \
+ (outleft) -= (o);
+#define NEXT(i, o) \
+ NEXT_IN(i) NEXT_OUT(o)
+
+#define REQUIRE_INBUF(n) \
+ if (inleft < (n)) \
+ return MBERR_TOOFEW;
+#define REQUIRE_OUTBUF(n) \
+ if (outleft < (n)) \
+ return MBERR_TOOSMALL;
+
+#define IN1 ((*inbuf)[0])
+#define IN2 ((*inbuf)[1])
+#define IN3 ((*inbuf)[2])
+#define IN4 ((*inbuf)[3])
+
+#define OUT1(c) ((*outbuf)[0]) = (c);
+#define OUT2(c) ((*outbuf)[1]) = (c);
+#define OUT3(c) ((*outbuf)[2]) = (c);
+#define OUT4(c) ((*outbuf)[3]) = (c);
+
+#define WRITE1(c1) \
+ REQUIRE_OUTBUF(1) \
+ (*outbuf)[0] = (c1);
+#define WRITE2(c1, c2) \
+ REQUIRE_OUTBUF(2) \
+ (*outbuf)[0] = (c1); \
+ (*outbuf)[1] = (c2);
+#define WRITE3(c1, c2, c3) \
+ REQUIRE_OUTBUF(3) \
+ (*outbuf)[0] = (c1); \
+ (*outbuf)[1] = (c2); \
+ (*outbuf)[2] = (c3);
+#define WRITE4(c1, c2, c3, c4) \
+ REQUIRE_OUTBUF(4) \
+ (*outbuf)[0] = (c1); \
+ (*outbuf)[1] = (c2); \
+ (*outbuf)[2] = (c3); \
+ (*outbuf)[3] = (c4);
+
+#if Py_UNICODE_SIZE == 2
+# define WRITEUCS4(c) \
+ REQUIRE_OUTBUF(2) \
+ (*outbuf)[0] = 0xd800 + (((c) - 0x10000) >> 10); \
+ (*outbuf)[1] = 0xdc00 + (((c) - 0x10000) & 0x3ff); \
+ NEXT_OUT(2)
+#else
+# define WRITEUCS4(c) \
+ REQUIRE_OUTBUF(1) \
+ **outbuf = (Py_UNICODE)(c); \
+ NEXT_OUT(1)
+#endif
+
+#define _TRYMAP_ENC(m, assi, val) \
+ ((m)->map != NULL && (val) >= (m)->bottom && \
+ (val)<= (m)->top && ((assi) = (m)->map[(val) - \
+ (m)->bottom]) != NOCHAR)
+#define TRYMAP_ENC_COND(charset, assi, uni) \
+ _TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff)
+#define TRYMAP_ENC(charset, assi, uni) \
+ if TRYMAP_ENC_COND(charset, assi, uni)
+
+#define _TRYMAP_DEC(m, assi, val) \
+ ((m)->map != NULL && (val) >= (m)->bottom && \
+ (val)<= (m)->top && ((assi) = (m)->map[(val) - \
+ (m)->bottom]) != UNIINV)
+#define TRYMAP_DEC(charset, assi, c1, c2) \
+ if _TRYMAP_DEC(&charset##_decmap[c1], assi, c2)
+
+#define _TRYMAP_ENC_MPLANE(m, assplane, asshi, asslo, val) \
+ ((m)->map != NULL && (val) >= (m)->bottom && \
+ (val)<= (m)->top && \
+ ((assplane) = (m)->map[((val) - (m)->bottom)*3]) != 0 && \
+ (((asshi) = (m)->map[((val) - (m)->bottom)*3 + 1]), 1) && \
+ (((asslo) = (m)->map[((val) - (m)->bottom)*3 + 2]), 1))
+#define TRYMAP_ENC_MPLANE(charset, assplane, asshi, asslo, uni) \
+ if _TRYMAP_ENC_MPLANE(&charset##_encmap[(uni) >> 8], \
+ assplane, asshi, asslo, (uni) & 0xff)
+#define TRYMAP_DEC_MPLANE(charset, assi, plane, c1, c2) \
+ if _TRYMAP_DEC(&charset##_decmap[plane][c1], assi, c2)
+
+#if Py_UNICODE_SIZE == 2
+#define DECODE_SURROGATE(c) \
+ if (c >> 10 == 0xd800 >> 10) { /* high surrogate */ \
+ REQUIRE_INBUF(2) \
+ if (IN2 >> 10 == 0xdc00 >> 10) { /* low surrogate */ \
+ c = 0x10000 + ((ucs4_t)(c - 0xd800) << 10) + \
+ ((ucs4_t)(IN2) - 0xdc00); \
+ } \
+ }
+#define GET_INSIZE(c) ((c) > 0xffff ? 2 : 1)
+#else
+#define DECODE_SURROGATE(c) {;}
+#define GET_INSIZE(c) 1
+#endif
+
+#define BEGIN_MAPPINGS_LIST static const struct dbcs_map _mapping_list[] = {
+#define MAPPING_ENCONLY(enc) {#enc, (void*)enc##_encmap, NULL},
+#define MAPPING_DECONLY(enc) {#enc, NULL, (void*)enc##_decmap},
+#define MAPPING_ENCDEC(enc) {#enc, (void*)enc##_encmap, (void*)enc##_decmap},
+#define END_MAPPINGS_LIST \
+ {"", NULL, NULL} }; \
+ static const struct dbcs_map *mapping_list = \
+ (const struct dbcs_map *)_mapping_list;
+
+#define BEGIN_CODECS_LIST static const MultibyteCodec _codec_list[] = {
+#define _STATEFUL_METHODS(enc) \
+ enc##_encode, \
+ enc##_encode_init, \
+ enc##_encode_reset, \
+ enc##_decode, \
+ enc##_decode_init, \
+ enc##_decode_reset,
+#define _STATELESS_METHODS(enc) \
+ enc##_encode, NULL, NULL, \
+ enc##_decode, NULL, NULL,
+#define CODEC_STATEFUL(enc) { \
+ #enc, NULL, NULL, \
+ _STATEFUL_METHODS(enc) \
+},
+#define CODEC_STATELESS(enc) { \
+ #enc, NULL, NULL, \
+ _STATELESS_METHODS(enc) \
+},
+#define CODEC_STATELESS_WINIT(enc) { \
+ #enc, NULL, \
+ enc##_codec_init, \
+ _STATELESS_METHODS(enc) \
+},
+#define END_CODECS_LIST \
+ {"", NULL,} }; \
+ static const MultibyteCodec *codec_list = \
+ (const MultibyteCodec *)_codec_list;
+
+static PyObject *
+getmultibytecodec(void)
+{
+ static PyObject *cofunc = NULL;
+
+ if (cofunc == NULL) {
+ PyObject *mod = PyImport_ImportModule("_multibytecodec");
+ if (mod == NULL)
+ return NULL;
+ cofunc = PyObject_GetAttrString(mod, "__create_codec");
+ Py_DECREF(mod);
+ }
+ return cofunc;
+}
+
+static PyObject *
+getcodec(PyObject *self, PyObject *encoding)
+{
+ PyObject *codecobj, *r, *cofunc;
+ const MultibyteCodec *codec;
+ const char *enc;
+
+ if (!PyString_Check(encoding)) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoding name must be a string.");
+ return NULL;
+ }
+
+ cofunc = getmultibytecodec();
+ if (cofunc == NULL)
+ return NULL;
+
+ enc = PyString_AS_STRING(encoding);
+ for (codec = codec_list; codec->encoding[0]; codec++)
+ if (strcmp(codec->encoding, enc) == 0)
+ break;
+
+ if (codec->encoding[0] == '\0') {
+ PyErr_SetString(PyExc_LookupError,
+ "no such codec is supported.");
+ return NULL;
+ }
+
+ codecobj = PyCObject_FromVoidPtr((void *)codec, NULL);
+ if (codecobj == NULL)
+ return NULL;
+
+ r = PyObject_CallFunctionObjArgs(cofunc, codecobj, NULL);
+ Py_DECREF(codecobj);
+
+ return r;
+}
+
+static struct PyMethodDef __methods[] = {
+ {"getcodec", (PyCFunction)getcodec, METH_O, ""},
+ {NULL, NULL},
+};
+
+static int
+register_maps(PyObject *module)
+{
+ const struct dbcs_map *h;
+
+ for (h = mapping_list; h->charset[0] != '\0'; h++) {
+ char mhname[256] = "__map_";
+ int r;
+ strcpy(mhname + sizeof("__map_") - 1, h->charset);
+ r = PyModule_AddObject(module, mhname,
+ PyCObject_FromVoidPtr((void *)h, NULL));
+ if (r == -1)
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef USING_BINARY_PAIR_SEARCH
+static DBCHAR
+find_pairencmap(ucs2_t body, ucs2_t modifier,
+ const struct pair_encodemap *haystack, int haystacksize)
+{
+ int pos, min, max;
+ ucs4_t value = body << 16 | modifier;
+
+ min = 0;
+ max = haystacksize;
+
+ for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1)
+ if (value < haystack[pos].uniseq) {
+ if (max == pos) break;
+ else max = pos;
+ }
+ else if (value > haystack[pos].uniseq) {
+ if (min == pos) break;
+ else min = pos;
+ }
+ else
+ break;
+
+ if (value == haystack[pos].uniseq)
+ return haystack[pos].code;
+ else
+ return DBCINV;
+}
+#endif
+
+#ifdef USING_IMPORTED_MAPS
+#define IMPORT_MAP(locale, charset, encmap, decmap) \
+ importmap("_codecs_" #locale, "__map_" #charset, \
+ (const void**)encmap, (const void**)decmap)
+
+static int
+importmap(const char *modname, const char *symbol,
+ const void **encmap, const void **decmap)
+{
+ PyObject *o, *mod;
+
+ mod = PyImport_ImportModule((char *)modname);
+ if (mod == NULL)
+ return -1;
+
+ o = PyObject_GetAttrString(mod, (char*)symbol);
+ if (o == NULL)
+ goto errorexit;
+ else if (!PyCObject_Check(o)) {
+ PyErr_SetString(PyExc_ValueError,
+ "map data must be a CObject.");
+ goto errorexit;
+ }
+ else {
+ struct dbcs_map *map;
+ map = PyCObject_AsVoidPtr(o);
+ if (encmap != NULL)
+ *encmap = map->encmap;
+ if (decmap != NULL)
+ *decmap = map->decmap;
+ Py_DECREF(o);
+ }
+
+ Py_DECREF(mod);
+ return 0;
+
+errorexit:
+ Py_DECREF(mod);
+ return -1;
+}
+#endif
+
+#define I_AM_A_MODULE_FOR(loc) \
+ void \
+ init_codecs_##loc(void) \
+ { \
+ PyObject *m = Py_InitModule("_codecs_" #loc, __methods);\
+ if (m != NULL) \
+ (void)register_maps(m); \
+ }
+
+#endif
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/emu_jisx0213_2000.h b/sys/src/cmd/python/Modules/cjkcodecs/emu_jisx0213_2000.h
new file mode 100644
index 000000000..250c67304
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/emu_jisx0213_2000.h
@@ -0,0 +1,43 @@
+/* These routines may be quite inefficient, but it's used only to emulate old
+ * standards. */
+
+#ifndef EMULATE_JISX0213_2000_ENCODE_INVALID
+#define EMULATE_JISX0213_2000_ENCODE_INVALID 1
+#endif
+
+#define EMULATE_JISX0213_2000_ENCODE_BMP(assi, c) \
+ if (config == (void *)2000 && ( \
+ (c) == 0x9B1C || (c) == 0x4FF1 || \
+ (c) == 0x525D || (c) == 0x541E || \
+ (c) == 0x5653 || (c) == 0x59F8 || \
+ (c) == 0x5C5B || (c) == 0x5E77 || \
+ (c) == 0x7626 || (c) == 0x7E6B)) \
+ return EMULATE_JISX0213_2000_ENCODE_INVALID; \
+ else if (config == (void *)2000 && (c) == 0x9B1D) \
+ (assi) = 0x8000 | 0x7d3b; \
+
+#define EMULATE_JISX0213_2000_ENCODE_EMP(assi, c) \
+ if (config == (void *)2000 && (c) == 0x20B9F) \
+ return EMULATE_JISX0213_2000_ENCODE_INVALID;
+
+#ifndef EMULATE_JISX0213_2000_DECODE_INVALID
+#define EMULATE_JISX0213_2000_DECODE_INVALID 2
+#endif
+
+#define EMULATE_JISX0213_2000_DECODE_PLANE1(assi, c1, c2) \
+ if (config == (void *)2000 && \
+ (((c1) == 0x2E && (c2) == 0x21) || \
+ ((c1) == 0x2F && (c2) == 0x7E) || \
+ ((c1) == 0x4F && (c2) == 0x54) || \
+ ((c1) == 0x4F && (c2) == 0x7E) || \
+ ((c1) == 0x74 && (c2) == 0x27) || \
+ ((c1) == 0x7E && (c2) == 0x7A) || \
+ ((c1) == 0x7E && (c2) == 0x7B) || \
+ ((c1) == 0x7E && (c2) == 0x7C) || \
+ ((c1) == 0x7E && (c2) == 0x7D) || \
+ ((c1) == 0x7E && (c2) == 0x7E))) \
+ return EMULATE_JISX0213_2000_DECODE_INVALID;
+
+#define EMULATE_JISX0213_2000_DECODE_PLANE2(assi, c1, c2) \
+ if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) \
+ (assi) = 0x9B1D;
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/mappings_cn.h b/sys/src/cmd/python/Modules/cjkcodecs/mappings_cn.h
new file mode 100644
index 000000000..a6dcebfe4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/mappings_cn.h
@@ -0,0 +1,4103 @@
+static const ucs2_t __gb2312_decmap[7482] = {
+12288,12289,12290,12539,713,711,168,12291,12293,8213,65374,8214,8230,8216,
+8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,
+12310,12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712,
+8759,8730,8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800,
+8814,8815,8804,8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164,
+65504,65505,8240,167,8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,8251,8594,8592,8593,8595,12307,9352,9353,9354,9355,9356,9357,9358,9359,
+9360,9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9332,9333,9334,
+9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,
+9350,9351,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,U,U,12832,12833,
+12834,12835,12836,12837,12838,12839,12840,12841,U,U,8544,8545,8546,8547,8548,
+8549,8550,8551,8552,8553,8554,8555,65281,65282,65283,65509,65285,65286,65287,
+65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300,
+65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313,
+65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,
+65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339,
+65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352,
+65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,
+65366,65367,65368,65369,65370,65371,65372,65373,65507,12353,12354,12355,12356,
+12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,
+12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,
+12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,
+12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,
+12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,
+12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,
+12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,
+12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,
+12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,
+12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,
+12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,
+12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,
+12526,12527,12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918,
+919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U,
+U,U,U,U,U,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,
+963,964,965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,
+1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,
+1064,1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,
+1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,
+1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,
+1102,1103,257,225,462,224,275,233,283,232,299,237,464,236,333,243,466,242,363,
+250,468,249,470,472,474,476,252,234,U,U,U,U,U,U,U,U,U,U,12549,12550,12551,
+12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,
+12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,
+12578,12579,12580,12581,12582,12583,12584,12585,9472,9473,9474,9475,9476,9477,
+9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,
+9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,
+9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,
+9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,
+9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,21834,38463,22467,25384,
+21710,21769,21696,30353,30284,34108,30702,33406,30861,29233,38552,38797,27688,
+23433,20474,25353,26263,23736,33018,26696,32942,26114,30414,20985,25942,29100,
+32753,34948,20658,22885,25034,28595,33453,25420,25170,21485,21543,31494,20843,
+30116,24052,25300,36299,38774,25226,32793,22365,38712,32610,29240,30333,26575,
+30334,25670,20336,36133,25308,31255,26001,29677,25644,25203,33324,39041,26495,
+29256,25198,25292,20276,29923,21322,21150,32458,37030,24110,26758,27036,33152,
+32465,26834,30917,34444,38225,20621,35876,33502,32990,21253,35090,21093,34180,
+38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,26479,30865,
+24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,28953,34987,
+22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,40763,27604,
+37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,30201,38381,
+25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,36140,25153,
+20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,40150,24971,
+21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,19993,31177,
+39292,28851,30149,24182,29627,33760,25773,25320,38069,27874,21338,21187,25615,
+38082,31636,20271,24091,33334,33046,33162,28196,27850,39539,25429,21340,21754,
+34917,22496,19981,24067,27493,31807,37096,24598,25830,29468,35009,26448,25165,
+36130,30572,36393,37319,24425,33756,34081,39184,21442,34453,27531,24813,24808,
+28799,33485,33329,20179,27815,34255,25805,31961,27133,26361,33609,21397,31574,
+20391,20876,27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519,
+23700,24046,35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130,
+20135,38416,39076,26124,29462,22330,23581,24120,38271,20607,32928,21378,25950,
+30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,21557,28818,36710,
+25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,24561,27785,38472,
+36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,24809,28548,35802,
+25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,24347,39536,32827,
+40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,23815,23456,25277,
+37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,33261,21021,20986,
+27249,21416,36487,38148,38607,28353,38500,26970,30784,20648,30679,25616,35302,
+22788,25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202,
+38383,21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431,
+34850,25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050,
+36176,27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419,
+36479,31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384,
+23544,30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823,
+21574,27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,24608,32829,
+25285,20025,21333,37112,25528,32966,26086,27694,20294,24814,28129,35806,24377,
+34507,24403,25377,20826,33633,26723,20992,25443,36424,20498,23707,31095,23548,
+21040,31291,24764,36947,30423,24503,24471,30340,36460,28783,30331,31561,30634,
+20979,37011,22564,20302,28404,36842,25932,31515,29380,28068,32735,23265,25269,
+24213,22320,33922,31532,24093,24351,36882,32532,39072,25474,28359,30872,28857,
+20856,38747,22443,30005,20291,30008,24215,24806,22880,28096,27583,30857,21500,
+38613,20939,20993,25481,21514,38035,35843,36300,29241,30879,34678,36845,35853,
+21472,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908,
+33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910,
+36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208,
+32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431,
+23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810,
+22842,22427,36530,26421,36346,33333,21057,24816,22549,34558,23784,40517,20420,
+39069,35769,23077,24694,21380,25212,36943,37122,39295,24681,32780,20799,32819,
+23572,39285,27953,20108,36144,21457,32602,31567,20240,20047,38400,27861,29648,
+34281,24070,30058,32763,27146,30718,38034,32321,20961,28902,21453,36820,33539,
+36137,29359,39277,27867,22346,33459,26041,32938,25151,38450,22952,20223,35775,
+32442,25918,33778,38750,21857,39134,32933,21290,35837,21536,32954,24223,27832,
+36153,33452,37210,21545,27675,20998,32439,22367,28954,27774,31881,22859,20221,
+24575,24868,31914,20016,23553,26539,34562,23792,38155,39118,30127,28925,36898,
+20911,32541,35773,22857,20964,20315,21542,22827,25975,32932,23413,25206,25282,
+36752,24133,27679,31526,20239,20440,26381,28014,28074,31119,34993,24343,29995,
+25242,36741,20463,37340,26023,33071,33105,24220,33104,36212,21103,35206,36171,
+22797,20613,20184,38428,29238,33145,36127,23500,35747,38468,22919,32538,21648,
+22134,22030,35813,25913,27010,38041,30422,28297,24178,29976,26438,26577,31487,
+32925,36214,24863,31174,25954,36195,20872,21018,38050,32568,32923,32434,23703,
+28207,26464,31705,30347,39640,33167,32660,31957,25630,38224,31295,21578,21733,
+27468,25601,25096,40509,33011,30105,21106,38761,33883,26684,34532,38401,38548,
+38124,20010,21508,32473,26681,36319,32789,26356,24218,32697,22466,32831,26775,
+24037,25915,21151,24685,40858,20379,36524,20844,23467,24339,24041,27742,25329,
+36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,33735,
+21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,25925,
+39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,26874,
+20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,36891,
+29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,26588,
+36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,21704,
+39608,23401,28023,27686,20133,23475,39559,37219,25000,37039,38889,21547,28085,
+23506,20989,21898,32597,32752,25788,25421,26097,25022,24717,28938,27735,27721,
+22831,26477,33322,22741,22158,35946,27627,37085,22909,32791,21495,28009,21621,
+21917,33655,33743,26680,31166,21644,20309,21512,30418,35977,38402,27827,28088,
+36203,35088,40548,36154,22079,40657,30165,24456,29408,24680,21756,20136,27178,
+34913,24658,36720,21700,28888,34425,40511,27946,23439,24344,32418,21897,20399,
+29492,21564,21402,20505,21518,21628,20046,24573,29786,22774,33899,32993,34676,
+29392,31946,28246,24359,34382,21804,25252,20114,27818,25143,33457,21719,21326,
+29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,27426,29615,
+26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,24187,33618,
+24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,24653,35854,
+28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,24800,26214,
+36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,39746,27985,
+28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,20987,22334,
+22522,26426,30072,31293,31215,31637,32908,39269,36857,28608,35749,40481,23020,
+32489,32521,21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363,
+23241,32423,25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058,
+24760,27982,23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025,
+26551,22841,20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215,
+26550,39550,23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392,
+22904,32516,33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943,
+33616,27099,37492,36341,36145,35265,38190,31661,20214,20581,33328,21073,39279,
+28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,33931,26728,22870,
+35762,21280,37233,38477,34121,26898,30977,28966,33014,20132,37066,27975,39556,
+23047,22204,25605,38128,30699,20389,33050,29409,35282,39290,32564,32478,21119,
+25945,37237,36735,36739,21483,31382,25581,25509,30342,31224,34903,38454,25130,
+21163,33410,26708,26480,25463,30571,31469,27905,32467,35299,22992,25106,34249,
+33445,30028,20511,20171,30117,35819,23626,24062,31563,26020,37329,20170,27941,
+35167,32039,38182,20165,35880,36827,38771,26187,31105,36817,28908,28024,23613,
+21170,33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117,
+35686,26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928,
+28847,31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937,
+26087,33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738,
+23616,21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191,
+20465,21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733,
+25899,25225,25496,20500,29237,35273,20915,35776,32477,22343,33740,38055,20891,
+21531,23803,20426,31459,27994,37089,39567,21888,21654,21345,21679,24320,25577,
+26999,20975,24936,21002,22570,21208,22350,30733,30475,24247,24951,31968,25179,
+25239,20130,28821,32771,25335,28900,38752,22391,33499,26607,26869,30933,39063,
+31185,22771,21683,21487,28212,20811,21051,23458,35838,32943,21827,22438,24691,
+22353,21549,31354,24656,23380,25511,25248,21475,25187,23495,26543,21741,31391,
+33510,37239,24211,35044,22840,22446,25358,36328,33007,22359,31607,20393,24555,
+23485,27454,21281,31568,29378,26694,30719,30518,26103,20917,20111,30420,23743,
+31397,33909,22862,39745,20608,39304,24871,28291,22372,26118,25414,22256,25324,
+25193,24275,38420,22403,25289,21895,34593,33098,36771,21862,33713,26469,36182,
+34013,23146,26639,25318,31726,38417,20848,28572,35888,25597,35272,25042,32518,
+28866,28389,29701,27028,29436,24266,37070,26391,28010,25438,21171,29282,32769,
+20332,23013,37226,28889,28061,21202,20048,38647,38253,34174,30922,32047,20769,
+22418,25794,32907,31867,27882,26865,26974,20919,21400,26792,29313,40654,31729,
+29432,31163,28435,29702,26446,37324,40100,31036,33673,33620,21519,26647,20029,
+21385,21169,30782,21382,21033,20616,20363,20432,30178,31435,31890,27813,38582,
+21147,29827,21737,20457,32852,33714,36830,38256,24265,24604,28063,24088,25947,
+33080,38142,24651,28860,32451,31918,20937,26753,31921,33391,20004,36742,37327,
+26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730,
+38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020,
+37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278,
+32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311,
+30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,38534,22404,
+25314,38471,27004,23044,25602,31699,28431,38475,33446,21346,39045,24208,28809,
+25523,21348,34383,40065,40595,30860,38706,36335,36162,40575,28510,31108,24405,
+38470,25134,39540,21525,38109,20387,26053,23653,23649,32533,34385,27695,24459,
+29575,28388,32511,23782,25371,23402,28390,21365,20081,25504,30053,25249,36718,
+20262,20177,27814,32438,35770,33821,34746,32599,36923,38179,31657,39585,35064,
+33853,27931,39558,32476,22920,40635,29595,30721,34434,39532,39554,22043,21527,
+22475,20080,40614,21334,36808,33033,30610,39314,34542,28385,34067,26364,24930,
+28459,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,30683,
+38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,38665,
+29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,38391,
+20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,31964,
+36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,32501,
+20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,24217,
+22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,38125,
+21517,21629,35884,25720,25721,34321,27169,33180,30952,25705,39764,25273,26411,
+33707,22696,40664,27819,28448,23518,38476,35851,29279,26576,25287,29281,20137,
+22982,27597,22675,26286,24149,21215,24917,26408,30446,30566,29287,31302,25343,
+21738,21584,38048,37027,23068,32435,27670,20035,22902,32784,22856,21335,30007,
+38590,22218,25376,33041,24700,38393,28118,21602,39297,20869,23273,33021,22958,
+38675,20522,27877,23612,25311,20320,21311,33147,36870,28346,34091,25288,24180,
+30910,25781,25467,24565,23064,37247,40479,23615,25423,32834,23421,21870,38218,
+38221,28037,24744,26592,29406,20957,23425,25319,27870,29275,25197,38062,32445,
+33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,25386,25062,
+31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,36276,29228,
+24085,24597,29750,25293,25490,29260,24472,28227,27966,25856,28504,30424,30928,
+30460,30036,21028,21467,20051,24222,26049,32810,32982,25243,21638,21032,28846,
+34957,36305,27873,21624,32986,22521,35060,36180,38506,37197,20329,27803,21943,
+30406,30768,25256,28921,28558,24429,34028,26842,30844,31735,33192,26379,40527,
+25447,30896,22383,30738,38713,25209,25259,21128,29749,27607,21860,33086,30130,
+30382,21305,30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922,
+31080,25735,30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179,
+20973,29942,35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078,
+25169,38138,20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889,
+26333,28689,26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854,
+26827,22855,27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682,
+20062,20225,21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488,
+24688,27965,29301,25190,38030,38085,21315,36801,31614,20191,35878,20094,40660,
+38065,38067,21069,28508,36963,27973,35892,22545,23884,27424,27465,26538,21595,
+33108,32652,22681,34103,24378,25250,27207,38201,25970,24708,26725,30631,20052,
+20392,24039,38808,25772,32728,23789,20431,31373,20999,33540,19988,24623,31363,
+38054,20405,20146,31206,29748,21220,33465,25810,31165,23517,27777,38738,36731,
+27682,20542,21375,28165,25806,26228,27696,24773,39031,35831,24198,29756,31351,
+31179,19992,37041,29699,27714,22234,37195,27845,36235,21306,34502,26354,36527,
+23624,39537,28192,21462,23094,40843,36259,21435,22280,39079,26435,37275,27849,
+20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,40522,27063,30830,
+38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,22199,35753,39286,
+25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,35748,20995,22922,
+32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,28342,23481,32466,
+20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,20083,27741,20837,
+35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,25746,27922,33832,
+33134,40131,22622,36187,19977,21441,20254,25955,26705,21971,20007,25620,39578,
+25195,23234,29791,33394,28073,26862,20711,33678,30722,26432,21049,27801,32433,
+20667,21861,29022,31579,26194,29642,33515,26441,23665,21024,29053,34923,38378,
+38485,25797,36193,33203,21892,27733,25159,32558,22674,20260,21830,36175,26188,
+19978,23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045,
+32461,22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774,
+30775,30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978,
+32958,24910,28183,22768,29983,29989,29298,21319,32499,30465,30427,21097,32988,
+22307,24072,22833,29422,26045,28287,35799,23608,34417,21313,30707,25342,26102,
+20160,39135,34432,23454,35782,21490,30690,20351,23630,39542,22987,24335,31034,
+22763,19990,26623,20107,25325,35475,36893,21183,26159,21980,22124,36866,20181,
+20365,37322,39280,27663,24066,24643,23460,35270,35797,25910,25163,39318,23432,
+23551,25480,21806,21463,30246,20861,34092,26530,26803,27530,25234,36755,21460,
+33298,28113,30095,20070,36174,23408,29087,34223,26257,26329,32626,34560,40653,
+40736,23646,26415,36848,26641,26463,25101,31446,22661,24246,25968,28465,24661,
+21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700,
+30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070,
+24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051,
+26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487,
+37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948,
+31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385,
+25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427,
+22905,22612,29549,25374,36427,36367,32974,33492,25260,21488,27888,37214,22826,
+24577,27760,22349,25674,36138,30251,28393,22363,27264,30192,28525,35885,35848,
+22374,27631,34962,30899,25506,21497,28845,27748,22616,25642,22530,26848,33179,
+21776,31958,20504,36538,28108,36255,28907,25487,28059,28372,32486,33796,26691,
+36867,28120,38518,35752,22871,29305,34276,33150,30140,35466,26799,21076,36386,
+38161,25552,39064,36420,21884,20307,26367,22159,24789,28053,21059,23625,22825,
+28155,22635,30000,29980,24684,33300,33094,25361,26465,36834,30522,36339,36148,
+38081,24086,21381,21548,28867,27712,24311,20572,20141,24237,25402,33351,36890,
+26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,20599,
+25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,21520,
+20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,25302,
+25176,33073,40501,38464,39534,39548,26925,22949,25299,21822,25366,21703,34521,
+27964,23043,29926,34972,27498,22806,35916,24367,28286,29609,39037,20024,28919,
+23436,30871,25405,26202,30358,24779,23451,23113,19975,33109,27754,29579,20129,
+26505,32593,24448,26106,26395,24536,22916,23041,24013,24494,21361,38886,36829,
+26693,22260,21807,24799,20026,28493,32500,33479,33806,22996,20255,20266,23614,
+32428,26410,34074,21619,30031,32963,21890,39759,20301,28205,35859,23561,24944,
+21355,30239,28201,34442,25991,38395,32441,21563,31283,32010,38382,21985,32705,
+29934,25373,34583,28065,31389,25105,26017,21351,25569,27779,24043,21596,38056,
+20044,27745,35820,23627,26080,33436,26791,21566,21556,27595,27494,20116,25410,
+21320,33310,20237,20398,22366,25098,38654,26212,29289,21247,21153,24735,35823,
+26132,29081,26512,35199,30802,30717,26224,22075,21560,38177,29306,31232,24687,
+24076,24713,33181,22805,24796,29060,28911,28330,27728,29312,27268,34989,24109,
+20064,23219,21916,38115,27927,31995,38553,25103,32454,30606,34430,21283,38686,
+36758,26247,23777,20384,29421,19979,21414,22799,21523,25472,38184,20808,20185,
+40092,32420,21688,36132,34900,33335,38386,28046,24358,23244,26174,38505,29616,
+29486,21439,33146,39301,32673,23466,38519,38480,32447,30456,21410,38262,39321,
+31665,35140,28248,20065,32724,31077,35814,24819,21709,20139,39033,24055,27233,
+20687,21521,35937,33831,30813,38660,21066,21742,22179,38144,28040,23477,28102,
+26195,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,34638,38795,
+21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,25032,27844,
+27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,20449,34885,
+26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,24184,26447,
+24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,32670,26429,
+21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,24464,35768,
+33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,36713,21927,
+23459,24748,26059,29572,36873,30307,30505,32474,38772,34203,23398,31348,38634,
+34880,21195,29071,24490,26092,35810,23547,39535,24033,27529,27739,35757,35759,
+36874,36805,21387,25276,40486,40493,21568,20011,33469,29273,34460,23830,34905,
+28079,38597,21713,20122,35766,28937,21693,38409,28895,28153,30416,20005,30740,
+34578,23721,24310,35328,39068,38414,28814,27839,22852,25513,30524,34893,28436,
+33395,22576,29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523,
+22830,40495,31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162,
+20859,26679,28478,36992,33136,22934,29814,25671,23591,36965,31377,35875,23002,
+21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,20918,20063,39029,
+25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,25558,38129,20381,
+20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,23452,23016,24413,
+26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,37009,23673,20159,
+24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,20041,30410,28322,
+35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,22240,27575,38899,
+38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,21360,33521,27185,
+23156,40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433,
+39062,30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647,
+27891,28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038,
+38080,29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188,
+36802,28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841,
+28189,28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577,
+22495,33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465,
+28020,23507,35029,39044,35947,39533,40499,28170,20900,20803,22435,34945,21407,
+25588,36757,22253,21592,22278,29503,28304,32536,36828,33489,24895,24616,38498,
+26352,32422,36234,36291,38053,23731,31908,26376,24742,38405,32792,20113,37095,
+21248,38504,20801,36816,34164,37213,26197,38901,23381,21277,30776,26434,26685,
+21705,28798,23472,36733,20877,22312,21681,25874,26242,36190,36163,33039,33900,
+36973,31967,20991,34299,26531,26089,28577,34468,36481,22122,36896,30338,28790,
+29157,36131,25321,21017,27901,36156,24590,22686,24974,26366,36192,25166,21939,
+28195,26413,36711,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688,
+25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759,
+23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467,
+24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157,
+25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761,
+32773,38167,34071,36825,27993,29645,26015,30495,29956,30759,33275,36126,38024,
+20390,26517,30137,35786,38663,25391,38215,38453,33976,25379,30529,24449,29424,
+20105,24596,25972,25327,27491,25919,24103,30151,37073,35777,33437,26525,25903,
+21553,34584,30693,32930,33026,27713,20043,32455,32844,30452,26893,27542,25191,
+20540,20356,22336,25351,27490,36286,21482,26088,32440,24535,25370,25527,33267,
+33268,32622,24092,23769,21046,26234,31209,31258,36136,28825,30164,28382,27835,
+31378,20013,30405,24544,38047,34935,32456,31181,32959,37325,20210,20247,33311,
+21608,24030,27954,35788,31909,36724,32920,24090,21650,30385,23449,26172,39588,
+29664,26666,34523,26417,29482,35832,35803,36880,31481,28891,29038,25284,30633,
+22065,20027,33879,26609,21161,34496,36142,38136,31569,20303,27880,31069,39547,
+25235,29226,25341,19987,30742,36716,25776,36186,31686,26729,24196,35013,22918,
+25758,22766,29366,26894,38181,36861,36184,22368,32512,35846,20934,25417,25305,
+21331,26700,29730,33537,37196,21828,30528,28796,27978,20857,21672,36164,23039,
+28363,28100,23388,32043,20180,31869,28371,23376,33258,28173,23383,39683,26837,
+36394,23447,32508,24635,32437,37049,36208,22863,25549,31199,36275,21330,26063,
+31062,35781,38459,32452,38075,32386,22068,37257,26368,32618,23562,36981,26152,
+24038,20304,26590,20570,20316,22352,24231,20109,19980,20800,19984,24319,21317,
+19989,20120,19998,39730,23404,22121,20008,31162,20031,21269,20039,22829,29243,
+21358,27664,22239,32996,39319,27603,30590,40727,20022,20127,40720,20060,20073,
+20115,33416,23387,21868,22031,20164,21389,21405,21411,21413,21422,38757,36189,
+21274,21493,21286,21294,21310,36188,21350,21347,20994,21000,21006,21037,21043,
+21055,21056,21068,21086,21089,21084,33967,21117,21122,21121,21136,21139,20866,
+32596,20155,20163,20169,20162,20200,20193,20203,20190,20251,20211,20258,20324,
+20213,20261,20263,20233,20267,20318,20327,25912,20314,20317,20319,20311,20274,
+20285,20342,20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372,
+20454,20456,20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467,
+20524,20495,20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552,
+20558,20588,20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718,
+20743,20747,20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649,
+39320,20865,22804,21241,21261,35335,21264,20971,22809,20821,20128,20822,20147,
+34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,20925,20924,
+20935,20886,20898,20901,35744,35750,35751,35754,35764,35765,35767,35778,35779,
+35787,35791,35790,35794,35795,35796,35798,35800,35801,35804,35807,35808,35812,
+35816,35817,35822,35824,35827,35830,35833,35836,35839,35840,35842,35844,35847,
+35852,35855,35857,35858,35860,35861,35862,35865,35867,35864,35869,35871,35872,
+35873,35877,35879,35882,35883,35886,35887,35890,35891,35893,35894,21353,21370,
+38429,38434,38433,38449,38442,38461,38460,38466,38473,38484,38495,38503,38508,
+38514,38516,38536,38541,38551,38576,37015,37019,37021,37017,37036,37025,37044,
+37043,37046,37050,37048,37040,37071,37061,37054,37072,37060,37063,37075,37094,
+37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,37155,37169,37167,
+37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,21200,21206,21232,
+21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,24047,22348,22441,
+22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,22318,22319,22364,
+22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,22390,22387,22445,
+22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,22490,22489,22482,
+22456,22516,22511,22520,22500,22493,22539,22541,22525,22509,22528,22558,22553,
+22596,22560,22629,22636,22657,22665,22682,22656,39336,40729,25087,33401,33405,
+33407,33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456,
+33480,33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450,
+33439,33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490,
+33496,33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617,
+33627,33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603,
+33631,33600,33559,33632,33581,33594,33587,33638,33637,33640,33563,33641,33644,
+33642,33645,33646,33712,33656,33715,33716,33696,33706,33683,33692,33669,33660,
+33718,33705,33661,33720,33659,33688,33694,33704,33722,33724,33729,33793,33765,
+33752,22535,33816,33803,33757,33789,33750,33820,33848,33809,33798,33748,33759,
+33807,33795,33784,33785,33770,33733,33728,33830,33776,33761,33884,33873,33882,
+33881,33907,33927,33928,33914,33929,33912,33852,33862,33897,33910,33932,33934,
+33841,33901,33985,33997,34000,34022,33981,34003,33994,33983,33978,34016,33953,
+33977,33972,33943,34021,34019,34060,29965,34104,34032,34105,34079,34106,34134,
+34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,
+34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,
+34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,
+22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,
+25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,
+25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,
+25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,
+25709,25750,25722,25783,25784,25753,25786,25792,25808,25815,25828,25826,25865,
+25893,25902,24331,24530,29977,24337,21343,21489,21501,21481,21480,21499,21522,
+21526,21510,21579,21586,21587,21588,21590,21571,21537,21591,21593,21539,21554,
+21634,21652,21623,21617,21604,21658,21659,21636,21622,21606,21661,21712,21677,
+21698,21684,21714,21671,21670,21715,21716,21618,21667,21717,21691,21695,21708,
+21721,21722,21724,21673,21674,21668,21725,21711,21726,21787,21735,21792,21757,
+21780,21747,21794,21795,21775,21777,21799,21802,21863,21903,21941,21833,21869,
+21825,21845,21823,21840,21820,21815,21846,21877,21878,21879,21811,21808,21852,
+21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,21983,
+21949,21950,21908,21913,21994,22007,21961,22047,21969,21995,21996,21972,21990,
+21981,21956,21999,21989,22002,22003,21964,21965,21992,22005,21988,36756,22046,
+22024,22028,22017,22052,22051,22014,22016,22055,22061,22104,22073,22103,22060,
+22093,22114,22105,22108,22092,22100,22150,22116,22129,22123,22139,22140,22149,
+22163,22191,22228,22231,22237,22241,22261,22251,22265,22271,22276,22282,22281,
+22300,24079,24089,24084,24081,24113,24123,24124,24119,24132,24148,24155,24158,
+24161,23692,23674,23693,23696,23702,23688,23704,23705,23697,23706,23708,23733,
+23714,23741,23724,23723,23729,23715,23745,23735,23748,23762,23780,23755,23781,
+23810,23811,23847,23846,23854,23844,23838,23814,23835,23896,23870,23860,23869,
+23916,23899,23919,23901,23915,23883,23882,23913,23924,23938,23961,23965,35955,
+23991,24005,24435,24439,24450,24455,24457,24460,24469,24473,24476,24488,24493,
+24501,24508,34914,24417,29357,29360,29364,29367,29368,29379,29377,29390,29389,
+29394,29416,29423,29417,29426,29428,29431,29441,29427,29443,29434,29435,29463,
+29459,29473,29450,29470,29469,29461,29474,29497,29477,29484,29496,29489,29520,
+29517,29527,29536,29548,29551,29566,33307,22821,39143,22820,22786,39267,39271,
+39272,39273,39274,39275,39276,39284,39287,39293,39296,39300,39303,39306,39309,
+39312,39313,39315,39316,39317,24192,24209,24203,24214,24229,24224,24249,24245,
+24254,24243,36179,24274,24273,24283,24296,24298,33210,24516,24521,24534,24527,
+24579,24558,24580,24545,24548,24574,24581,24582,24554,24557,24568,24601,24629,
+24614,24603,24591,24589,24617,24619,24586,24639,24609,24696,24697,24699,24698,
+24642,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,24812,24763,
+24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,24832,24846,
+24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,38377,38379,
+38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,38411,38412,
+38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,27701,27732,
+27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,27782,27817,
+27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,27883,27886,
+27825,27859,27887,27902,27961,27943,27916,27971,27976,27911,27908,27929,27918,
+27947,27981,27950,27957,27930,27983,27986,27988,27955,28049,28015,28062,28064,
+27998,28051,28052,27996,28000,28028,28003,28186,28103,28101,28126,28174,28095,
+28128,28177,28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267,
+28338,28255,28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461,
+28386,28325,28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514,
+28486,28487,28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553,
+28557,28556,28536,28530,28540,28538,28625,28617,28583,28601,28598,28610,28641,
+28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,28766,23424,23428,
+23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,23536,36423,35591,
+36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,36869,36868,36875,
+36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,36945,36946,36944,
+36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,37003,24400,24407,
+24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,24362,24361,24365,
+33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,22935,22986,22955,
+22942,22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000,
+23033,23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100,
+23138,23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224,
+23264,23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360,
+23573,23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551,
+39549,39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580,
+39581,39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425,
+32429,32432,32446,32448,32449,32450,32457,32459,32460,32464,32468,32471,32475,
+32480,32481,32488,32491,32494,32495,32497,32498,32525,32502,32506,32507,32510,
+32513,32514,32515,32519,32520,32523,32524,32527,32529,32530,32535,32537,32540,
+32539,32543,32545,32546,32547,32548,32549,32550,32551,32554,32555,32556,32557,
+32559,32560,32561,32562,32563,32565,24186,30079,24027,30014,37013,29582,29585,
+29614,29602,29599,29647,29634,29649,29623,29619,29632,29641,29640,29669,29657,
+39036,29706,29673,29671,29662,29626,29682,29711,29738,29787,29734,29733,29736,
+29744,29742,29740,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,
+29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,
+38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,
+26535,26485,26536,26526,26541,26507,26487,26492,26608,26633,26584,26634,26601,
+26544,26636,26585,26549,26586,26547,26589,26624,26563,26552,26594,26638,26561,
+26621,26674,26675,26720,26721,26702,26722,26692,26724,26755,26653,26709,26726,
+26689,26727,26688,26686,26698,26697,26665,26805,26767,26740,26743,26771,26731,
+26818,26990,26876,26911,26912,26873,26916,26864,26891,26881,26967,26851,26896,
+26993,26937,26976,26946,26973,27012,26987,27008,27032,27000,26932,27084,27015,
+27016,27086,27017,26982,26979,27001,27035,27047,27067,27051,27053,27092,27057,
+27073,27082,27103,27029,27104,27021,27135,27183,27117,27159,27160,27237,27122,
+27204,27198,27296,27216,27227,27189,27278,27257,27197,27176,27224,27260,27281,
+27280,27305,27287,27307,29495,29522,27521,27522,27527,27524,27538,27539,27533,
+27546,27547,27553,27562,36715,36717,36721,36722,36723,36725,36726,36728,36727,
+36729,36730,36732,36734,36737,36738,36740,36743,36747,36749,36750,36751,36760,
+36762,36558,25099,25111,25115,25119,25122,25121,25125,25124,25132,33255,29935,
+29940,29951,29967,29969,29971,25908,26094,26095,26096,26122,26137,26482,26115,
+26133,26112,28805,26359,26141,26164,26161,26166,26165,32774,26207,26196,26177,
+26191,26198,26209,26199,26231,26244,26252,26279,26269,26302,26331,26332,26342,
+26345,36146,36147,36150,36155,36157,36160,36165,36166,36168,36169,36167,36173,
+36181,36185,35271,35274,35275,35276,35278,35279,35280,35281,29294,29343,29277,
+29286,29295,29310,29311,29316,29323,29325,29327,29330,25352,25394,25520,25663,
+25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,27672,
+27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,29270,
+29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,32948,
+32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,32989,
+33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,33054,
+33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,33148,
+33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,26406,
+33226,33211,33217,33190,27428,27447,27449,27459,27462,27481,39121,39122,39123,
+39125,39129,39130,27571,24384,27586,35315,26000,40785,26003,26044,26054,26052,
+26051,26060,26062,26066,26070,28800,28828,28822,28829,28859,28864,28855,28843,
+28849,28904,28874,28944,28947,28950,28975,28977,29043,29020,29032,28997,29042,
+29002,29048,29050,29080,29107,29109,29096,29088,29152,29140,29159,29177,29213,
+29224,28780,28952,29030,29113,25150,25149,25155,25160,25161,31035,31040,31046,
+31049,31067,31068,31059,31066,31074,31063,31072,31087,31079,31098,31109,31114,
+31130,31143,31155,24529,24528,24636,24669,24666,24679,24641,24665,24675,24747,
+24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,27894,28156,
+30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,30777,30778,
+30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,30758,30800,
+30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,30905,30885,
+30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,40859,40697,
+40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,30509,30502,
+30517,30520,30544,30545,30535,30531,30554,30568,30562,30565,30591,30605,30589,
+30592,30604,30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024,
+30043,30066,30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641,
+32638,30413,30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032,
+38036,38039,38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063,
+38064,38066,38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088,
+38089,38090,38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105,
+38104,38107,38110,38111,38112,38114,38116,38117,38119,38120,38122,38121,38123,
+38126,38127,38131,38132,38133,38135,38137,38140,38141,38143,38147,38146,38150,
+38151,38153,38154,38157,38158,38159,38162,38163,38164,38165,38166,38168,38171,
+38173,38174,38175,38178,38186,38187,38185,38188,38193,38194,38196,38198,38199,
+38200,38204,38206,38207,38210,38197,38212,38213,38214,38217,38220,38222,38223,
+38226,38227,38228,38230,38231,38232,38233,38235,38238,38239,38237,38241,38242,
+38244,38245,38246,38247,38248,38249,38250,38251,38252,38255,38257,38258,38259,
+38202,30695,30700,38601,31189,31213,31203,31211,31238,23879,31235,31234,31262,
+31252,31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,
+29920,29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,
+40503,40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,
+40526,40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,
+40554,40555,40556,40561,40557,40563,30098,30100,30102,30112,30109,30124,30115,
+30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,30179,30184,30182,
+30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,30220,30231,30218,
+30245,30232,30229,30233,30235,30268,30242,30240,30272,30253,30256,30271,30261,
+30275,30270,30259,30285,30302,30292,30300,30294,30315,30319,32714,31462,31352,
+31353,31360,31366,31368,31381,31398,31392,31404,31400,31405,31411,34916,34921,
+34930,34941,34943,34946,34978,35014,34999,35004,35017,35042,35022,35043,35045,
+35057,35098,35068,35048,35070,35056,35105,35097,35091,35099,35082,35124,35115,
+35126,35137,35174,35195,30091,32997,30386,30388,30684,32786,32788,32790,32796,
+32800,32802,32805,32806,32807,32809,32808,32817,32779,32821,32835,32838,32845,
+32850,32873,32881,35203,39032,39040,39043,39049,39052,39053,39055,39060,39066,
+39067,39070,39071,39073,39074,39077,39078,34381,34388,34412,34414,34431,34426,
+34428,34427,34472,34445,34443,34476,34461,34471,34467,34474,34451,34473,34486,
+34500,34485,34510,34480,34490,34481,34479,34505,34511,34484,34537,34545,34546,
+34541,34547,34512,34579,34526,34548,34527,34520,34513,34563,34567,34552,34568,
+34570,34573,34569,34595,34619,34590,34597,34606,34586,34622,34632,34612,34609,
+34601,34615,34623,34690,34594,34685,34686,34683,34656,34672,34636,34670,34699,
+34643,34659,34684,34660,34649,34661,34707,34735,34728,34770,34758,34696,34693,
+34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752,
+34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876,
+32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531,
+31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518,
+31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632,
+31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697,
+31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755,
+31775,31786,31782,31800,31809,31808,33278,33281,33282,33284,33260,34884,33313,
+33314,33315,33325,33327,33320,33323,33336,33339,33331,33332,33342,33348,33353,
+33355,33359,33370,33375,33384,34942,34949,34952,35032,35039,35166,32669,32671,
+32679,32687,32688,32690,31868,25929,31889,31901,31900,31902,31906,31922,31932,
+31933,31937,31943,31948,31949,31944,31941,31959,31976,33390,26280,32703,32718,
+32725,32741,32737,32742,32745,32750,32755,31992,32119,32166,32174,32327,32411,
+40632,40628,36211,36228,36244,36241,36273,36199,36205,35911,35913,37194,37200,
+37198,37199,37220,37218,37217,37232,37225,37231,37245,37246,37234,37236,37241,
+37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,37300,
+37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,36292,
+36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,36345,
+36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,36416,
+36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,36476,
+36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,35992,
+35988,26011,35286,35294,35290,35292,35301,35307,35311,35390,35622,38739,38633,
+38643,38639,38662,38657,38664,38671,38670,38698,38701,38704,38718,40832,40835,
+40837,40838,40839,40840,40841,40842,40844,40702,40715,40717,38585,38588,38589,
+38606,38610,30655,38624,37518,37550,37576,37694,37738,37834,37775,37950,37995,
+40063,40066,40069,40070,40071,40072,31267,40075,40078,40080,40081,40082,40084,
+40085,40090,40091,40094,40095,40096,40097,40098,40099,40101,40102,40103,40104,
+40105,40107,40109,40110,40112,40113,40114,40115,40116,40117,40118,40119,40122,
+40123,40124,40125,40132,40133,40134,40135,40138,40139,40140,40141,40142,40143,
+40144,40147,40148,40149,40151,40152,40153,40156,40157,40159,40162,38780,38789,
+38801,38802,38804,38831,38827,38819,38834,38836,39601,39600,39607,40536,39606,
+39610,39612,39617,39616,39621,39618,39627,39628,39633,39749,39747,39751,39753,
+39752,39757,39761,39144,39181,39214,39253,39252,39647,39649,39654,39663,39659,
+39675,39661,39673,39688,39695,39699,39711,39715,40637,40638,32315,40578,40583,
+40584,40587,40594,37846,40605,40607,40667,40668,40669,40672,40671,40674,40681,
+40679,40677,40682,40687,40738,40748,40751,40761,40759,40765,40766,40772,
+};
+
+static const struct dbcs_index gb2312_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+0,33,126},{__gb2312_decmap+94,
+49,124},{__gb2312_decmap+170,33,126},{__gb2312_decmap+264,33,115},{
+__gb2312_decmap+347,33,118},{__gb2312_decmap+433,33,88},{__gb2312_decmap+489,
+33,113},{__gb2312_decmap+570,33,105},{__gb2312_decmap+643,36,111},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+719,33,126},{
+__gb2312_decmap+813,33,126},{__gb2312_decmap+907,33,126},{__gb2312_decmap+1001
+,33,126},{__gb2312_decmap+1095,33,126},{__gb2312_decmap+1189,33,126},{
+__gb2312_decmap+1283,33,126},{__gb2312_decmap+1377,33,126},{__gb2312_decmap+
+1471,33,126},{__gb2312_decmap+1565,33,126},{__gb2312_decmap+1659,33,126},{
+__gb2312_decmap+1753,33,126},{__gb2312_decmap+1847,33,126},{__gb2312_decmap+
+1941,33,126},{__gb2312_decmap+2035,33,126},{__gb2312_decmap+2129,33,126},{
+__gb2312_decmap+2223,33,126},{__gb2312_decmap+2317,33,126},{__gb2312_decmap+
+2411,33,126},{__gb2312_decmap+2505,33,126},{__gb2312_decmap+2599,33,126},{
+__gb2312_decmap+2693,33,126},{__gb2312_decmap+2787,33,126},{__gb2312_decmap+
+2881,33,126},{__gb2312_decmap+2975,33,126},{__gb2312_decmap+3069,33,126},{
+__gb2312_decmap+3163,33,126},{__gb2312_decmap+3257,33,126},{__gb2312_decmap+
+3351,33,126},{__gb2312_decmap+3445,33,126},{__gb2312_decmap+3539,33,126},{
+__gb2312_decmap+3633,33,126},{__gb2312_decmap+3727,33,126},{__gb2312_decmap+
+3821,33,126},{__gb2312_decmap+3915,33,126},{__gb2312_decmap+4009,33,126},{
+__gb2312_decmap+4103,33,126},{__gb2312_decmap+4197,33,126},{__gb2312_decmap+
+4291,33,126},{__gb2312_decmap+4385,33,121},{__gb2312_decmap+4474,33,126},{
+__gb2312_decmap+4568,33,126},{__gb2312_decmap+4662,33,126},{__gb2312_decmap+
+4756,33,126},{__gb2312_decmap+4850,33,126},{__gb2312_decmap+4944,33,126},{
+__gb2312_decmap+5038,33,126},{__gb2312_decmap+5132,33,126},{__gb2312_decmap+
+5226,33,126},{__gb2312_decmap+5320,33,126},{__gb2312_decmap+5414,33,126},{
+__gb2312_decmap+5508,33,126},{__gb2312_decmap+5602,33,126},{__gb2312_decmap+
+5696,33,126},{__gb2312_decmap+5790,33,126},{__gb2312_decmap+5884,33,126},{
+__gb2312_decmap+5978,33,126},{__gb2312_decmap+6072,33,126},{__gb2312_decmap+
+6166,33,126},{__gb2312_decmap+6260,33,126},{__gb2312_decmap+6354,33,126},{
+__gb2312_decmap+6448,33,126},{__gb2312_decmap+6542,33,126},{__gb2312_decmap+
+6636,33,126},{__gb2312_decmap+6730,33,126},{__gb2312_decmap+6824,33,126},{
+__gb2312_decmap+6918,33,126},{__gb2312_decmap+7012,33,126},{__gb2312_decmap+
+7106,33,126},{__gb2312_decmap+7200,33,126},{__gb2312_decmap+7294,33,126},{
+__gb2312_decmap+7388,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __gbkext_decmap[14531] = {
+19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,
+20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,
+20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,
+20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,
+20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,U,20112,
+20118,20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,
+20151,20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,
+20188,20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,
+20218,20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,
+20242,20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,
+20270,20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,
+20293,20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,
+20328,20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,
+20352,20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,
+20374,20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,
+20401,20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,
+20416,20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,
+20437,20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,
+20468,20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,
+20484,20485,20486,20487,20488,20489,20490,U,20491,20494,20496,20497,20499,
+20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,20519,20523,20527,
+20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20539,20541,20543,
+20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,20560,20561,20562,
+20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,20576,20577,20578,
+20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,20591,20592,20593,
+20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,20610,20611,20612,
+20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,20626,20627,20628,
+20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,
+20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,20659,20660,20661,
+20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,20674,20675,20676,
+20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20688,20689,20690,
+20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,20703,20704,20705,
+20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,20721,20722,20724,
+20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,20737,20738,20739,
+20740,20741,20744,U,20745,20746,20748,20749,20750,20751,20752,20753,20755,
+20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,
+20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,
+20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,
+20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,20819,20823,
+20824,20825,20827,20829,20830,20831,20832,20833,20835,20836,20838,20839,20841,
+20842,20847,20850,20858,20862,20863,20867,20868,20870,20871,20874,20875,20878,
+20879,20880,20881,20883,20884,20888,20890,20893,20894,20895,20897,20899,20902,
+20903,20904,20905,20906,20909,20910,20916,20920,20921,20922,20926,20927,20929,
+20930,20931,20933,20936,20938,20941,20942,20944,20946,20947,20948,20949,20950,
+20951,20952,20953,20954,20956,20958,20959,20962,20963,20965,20966,20967,20968,
+20969,20970,20972,20974,20977,20978,20980,20983,20990,20996,20997,21001,21003,
+21004,21007,21008,21011,21012,21013,21020,21022,21023,21025,21026,21027,21029,
+21030,21031,21034,21036,21039,21041,21042,21044,21045,21052,21054,21060,21061,
+21062,21063,21064,21065,21067,21070,21071,21074,21075,21077,21079,21080,U,
+21081,21082,21083,21085,21087,21088,21090,21091,21092,21094,21096,21099,21100,
+21101,21102,21104,21105,21107,21108,21109,21110,21111,21112,21113,21114,21115,
+21116,21118,21120,21123,21124,21125,21126,21127,21129,21130,21131,21132,21133,
+21134,21135,21137,21138,21140,21141,21142,21143,21144,21145,21146,21148,21156,
+21157,21158,21159,21166,21167,21168,21172,21173,21174,21175,21176,21177,21178,
+21179,21180,21181,21184,21185,21186,21188,21189,21190,21192,21194,21196,21197,
+21198,21199,21201,21203,21204,21205,21207,21209,21210,21211,21212,21213,21214,
+21216,21217,21218,21219,21221,21222,21223,21224,21225,21226,21227,21228,21229,
+21230,21231,21233,21234,21235,21236,21237,21238,21239,21240,21243,21244,21245,
+21249,21250,21251,21252,21255,21257,21258,21259,21260,21262,21265,21266,21267,
+21268,21272,21275,21276,21278,21279,21282,21284,21285,21287,21288,21289,21291,
+21292,21293,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21308,
+21309,21312,21314,21316,21318,21323,21324,21325,21328,21332,21336,21337,21339,
+21341,21349,21352,21354,21356,21357,21362,21366,21369,21371,21372,21373,21374,
+21376,21377,21379,21383,21384,21386,21390,21391,U,21392,21393,21394,21395,
+21396,21398,21399,21401,21403,21404,21406,21408,21409,21412,21415,21418,21419,
+21420,21421,21423,21424,21425,21426,21427,21428,21429,21431,21432,21433,21434,
+21436,21437,21438,21440,21443,21444,21445,21446,21447,21454,21455,21456,21458,
+21459,21461,21466,21468,21469,21470,21473,21474,21479,21492,21498,21502,21503,
+21504,21506,21509,21511,21515,21524,21528,21529,21530,21532,21538,21540,21541,
+21546,21552,21555,21558,21559,21562,21565,21567,21569,21570,21572,21573,21575,
+21577,21580,21581,21582,21583,21585,21594,21597,21598,21599,21600,21601,21603,
+21605,21607,21609,21610,21611,21612,21613,21614,21615,21616,21620,21625,21626,
+21630,21631,21633,21635,21637,21639,21640,21641,21642,21645,21649,21651,21655,
+21656,21660,21662,21663,21664,21665,21666,21669,21678,21680,21682,21685,21686,
+21687,21689,21690,21692,21694,21699,21701,21706,21707,21718,21720,21723,21728,
+21729,21730,21731,21732,21739,21740,21743,21744,21745,21748,21749,21750,21751,
+21752,21753,21755,21758,21760,21762,21763,21764,21765,21768,21770,21771,21772,
+21773,21774,21778,21779,21781,21782,21783,21784,21785,21786,21788,21789,21790,
+21791,21793,21797,21798,U,21800,21801,21803,21805,21810,21812,21813,21814,
+21816,21817,21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837,
+21838,21839,21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854,
+21855,21856,21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876,
+21881,21882,21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909,
+21910,21911,21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928,
+21929,21930,21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946,
+21948,21951,21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967,
+21968,21973,21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997,
+21998,22000,22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019,
+22020,22021,22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037,
+22038,22039,22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057,
+22058,22059,22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078,
+22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095,
+22096,22097,22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113,
+U,22115,22117,22118,22119,22125,22126,22127,22128,22130,22131,22132,22133,
+22135,22136,22137,22138,22141,22142,22143,22144,22145,22146,22147,22148,22151,
+22152,22153,22154,22155,22156,22157,22160,22161,22162,22164,22165,22166,22167,
+22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22180,22181,
+22182,22183,22184,22185,22186,22187,22188,22189,22190,22192,22193,22194,22195,
+22196,22197,22198,22200,22201,22202,22203,22205,22206,22207,22208,22209,22210,
+22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,22224,
+22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,22248,
+22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,22272,
+22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,22291,
+22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,22306,
+22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,22332,
+22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,22356,
+22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,22386,
+22388,22389,22392,22393,22394,22397,22398,22399,22400,U,22401,22407,22408,
+22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425,
+22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451,
+22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468,
+22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487,
+22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507,
+22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527,
+22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547,
+22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566,
+22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582,
+22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,
+22597,22598,22599,22600,22601,22602,22603,22606,22607,22608,22610,22611,22613,
+22614,22615,22617,22618,22619,22620,22621,22623,22624,22625,22626,22627,22628,
+22630,22631,22632,22633,22634,22637,22638,22639,22640,22641,22642,22643,22644,
+22645,22646,22647,22648,22649,22650,22651,22652,22653,22655,22658,22660,22662,
+22663,22664,22666,22667,22668,U,22669,22670,22671,22672,22673,22676,22677,
+22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,22692,22693,22694,
+22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,
+22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,22722,22723,22724,
+22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22738,22739,
+22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753,
+22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,22769,22770,22772,
+22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,22785,22787,22789,
+22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,22803,22807,22808,
+22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,22832,22834,22835,
+22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,22858,22860,22861,
+22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,22883,22884,22886,
+22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22901,
+22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,22924,22926,22927,
+22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,22944,22945,22946,
+22950,U,22951,22956,22957,22960,22961,22963,22964,22965,22966,22967,22968,
+22970,22972,22973,22975,22976,22977,22978,22979,22980,22981,22983,22984,22985,
+22988,22989,22990,22991,22997,22998,23001,23003,23006,23007,23008,23009,23010,
+23012,23014,23015,23017,23018,23019,23021,23022,23023,23024,23025,23026,23027,
+23028,23029,23030,23031,23032,23034,23036,23037,23038,23040,23042,23050,23051,
+23053,23054,23055,23056,23058,23060,23061,23062,23063,23065,23066,23067,23069,
+23070,23073,23074,23076,23078,23079,23080,23082,23083,23084,23085,23086,23087,
+23088,23091,23093,23095,23096,23097,23098,23099,23101,23102,23103,23105,23106,
+23107,23108,23109,23111,23112,23115,23116,23117,23118,23119,23120,23121,23122,
+23123,23124,23126,23127,23128,23129,23131,23132,23133,23134,23135,23136,23137,
+23139,23140,23141,23142,23144,23145,23147,23148,23149,23150,23151,23152,23153,
+23154,23155,23160,23161,23163,23164,23165,23166,23168,23169,23170,23171,23172,
+23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185,
+23187,23188,23189,23190,23191,23192,23193,23196,23197,23198,23199,23200,23201,
+23202,23203,23204,23205,23206,23207,23208,23209,23211,23212,U,23213,23214,
+23215,23216,23217,23220,23222,23223,23225,23226,23227,23228,23229,23231,23232,
+23235,23236,23237,23238,23239,23240,23242,23243,23245,23246,23247,23248,23249,
+23251,23253,23255,23257,23258,23259,23261,23262,23263,23266,23268,23269,23271,
+23272,23274,23276,23277,23278,23279,23280,23282,23283,23284,23285,23286,23287,
+23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,
+23301,23302,23303,23304,23306,23307,23308,23309,23310,23311,23312,23313,23314,
+23315,23316,23317,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,
+23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342,
+23343,23344,23345,23347,23349,23350,23352,23353,23354,23355,23356,23357,23358,
+23359,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,
+23373,23374,23375,23378,23382,23390,23392,23393,23399,23400,23403,23405,23406,
+23407,23410,23412,23414,23415,23416,23417,23419,23420,23422,23423,23426,23430,
+23434,23437,23438,23440,23441,23442,23444,23446,23455,23463,23464,23465,23468,
+23469,23470,23471,23473,23474,23479,23482,23483,23484,23488,23489,23491,23496,
+23497,23498,23499,23501,23502,23503,U,23505,23508,23509,23510,23511,23512,
+23513,23514,23515,23516,23520,23522,23523,23526,23527,23529,23530,23531,23532,
+23533,23535,23537,23538,23539,23540,23541,23542,23543,23549,23550,23552,23554,
+23555,23557,23559,23560,23563,23564,23565,23566,23568,23570,23571,23575,23577,
+23579,23582,23583,23584,23585,23587,23590,23592,23593,23594,23595,23597,23598,
+23599,23600,23602,23603,23605,23606,23607,23619,23620,23622,23623,23628,23629,
+23634,23635,23636,23638,23639,23640,23642,23643,23644,23645,23647,23650,23652,
+23655,23656,23657,23658,23659,23660,23661,23664,23666,23667,23668,23669,23670,
+23671,23672,23675,23676,23677,23678,23680,23683,23684,23685,23686,23687,23689,
+23690,23691,23694,23695,23698,23699,23701,23709,23710,23711,23712,23713,23716,
+23717,23718,23719,23720,23722,23726,23727,23728,23730,23732,23734,23737,23738,
+23739,23740,23742,23744,23746,23747,23749,23750,23751,23752,23753,23754,23756,
+23757,23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771,
+23772,23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791,
+23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806,
+23807,23808,U,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,
+23824,23825,23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,
+23841,23842,23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,
+23861,23862,23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,
+23876,23877,23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,
+23893,23894,23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,
+23909,23910,23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,
+23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,
+23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,
+23954,23955,23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,
+23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,
+23982,23983,23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,
+23996,23997,23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,
+24010,24011,24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,
+24024,24025,24026,24028,24031,24032,24035,24036,24042,24044,24045,U,24048,
+24053,24054,24056,24057,24058,24059,24060,24063,24064,24068,24071,24073,24074,
+24075,24077,24078,24082,24083,24087,24094,24095,24096,24097,24098,24099,24100,
+24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,24118,
+24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,24139,
+24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,24156,
+24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,
+24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,24197,
+24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,24228,
+24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,24251,
+24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24267,
+24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,24285,
+24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,24300,
+24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,24317,
+24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,24346,
+24348,24349,24350,24353,24354,24355,24356,U,24360,24363,24364,24366,24368,
+24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,
+24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,
+24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,
+24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,
+24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,
+24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,
+24498,24499,24500,24502,24504,24505,24506,24507,24510,24511,24512,24513,24514,
+24519,24520,24522,24523,24526,24531,24532,24533,24538,24539,24540,24542,24543,
+24546,24547,24549,24550,24552,24553,24556,24559,24560,24562,24563,24564,24566,
+24567,24569,24570,24572,24583,24584,24585,24587,24588,24592,24593,24595,24599,
+24600,24602,24606,24607,24610,24611,24612,24620,24621,24622,24624,24625,24626,
+24627,24628,24630,24631,24632,24633,24634,24637,24638,24640,24644,24645,24646,
+24647,24648,24649,24650,24652,24654,24655,24657,24659,24660,24662,24663,24664,
+24667,24668,24670,24671,24672,24673,24677,24678,24686,24689,24690,24692,24693,
+24695,24702,24704,U,24705,24706,24709,24710,24711,24712,24714,24715,24718,
+24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,24737,24738,24740,
+24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,24761,24762,24765,
+24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,24780,24781,24782,
+24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,24801,24802,24803,
+24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,24829,24830,24831,
+24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,24850,24851,24852,
+24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,24869,24872,24873,
+24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,
+24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,24899,24900,24901,
+24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,24918,24919,24920,
+24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,24933,24934,24937,
+24938,24939,24940,24941,24942,24943,24945,24946,24947,24948,24950,24952,24953,
+24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,
+24967,24968,24969,24970,24972,24973,24975,24976,24977,24978,24979,24981,U,
+24982,24983,24984,24985,24986,24987,24988,24990,24991,24992,24993,24994,24995,
+24996,24997,24998,25002,25003,25005,25006,25007,25008,25009,25010,25011,25012,
+25013,25014,25016,25017,25018,25019,25020,25021,25023,25024,25025,25027,25028,
+25029,25030,25031,25033,25036,25037,25038,25039,25040,25043,25045,25046,25047,
+25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,
+25061,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,
+25075,25076,25078,25079,25080,25081,25082,25083,25084,25085,25086,25088,25089,
+25090,25091,25092,25093,25095,25097,25107,25108,25113,25116,25117,25118,25120,
+25123,25126,25127,25128,25129,25131,25133,25135,25136,25137,25138,25141,25142,
+25144,25145,25146,25147,25148,25154,25156,25157,25158,25162,25167,25168,25173,
+25174,25175,25177,25178,25180,25181,25182,25183,25184,25185,25186,25188,25189,
+25192,25201,25202,25204,25205,25207,25208,25210,25211,25213,25217,25218,25219,
+25221,25222,25223,25224,25227,25228,25229,25230,25231,25232,25236,25241,25244,
+25245,25246,25251,25254,25255,25257,25258,25261,25262,25263,25264,25266,25267,
+25268,25270,25271,25272,25274,25278,25280,25281,U,25283,25291,25295,25297,
+25301,25309,25310,25312,25313,25316,25322,25323,25328,25330,25333,25336,25337,
+25338,25339,25344,25347,25348,25349,25350,25354,25355,25356,25357,25359,25360,
+25362,25363,25364,25365,25367,25368,25369,25372,25382,25383,25385,25388,25389,
+25390,25392,25393,25395,25396,25397,25398,25399,25400,25403,25404,25406,25407,
+25408,25409,25412,25415,25416,25418,25425,25426,25427,25428,25430,25431,25432,
+25433,25434,25435,25436,25437,25440,25444,25445,25446,25448,25450,25451,25452,
+25455,25456,25458,25459,25460,25461,25464,25465,25468,25469,25470,25471,25473,
+25475,25476,25477,25478,25483,25485,25489,25491,25492,25493,25495,25497,25498,
+25499,25500,25501,25502,25503,25505,25508,25510,25515,25519,25521,25522,25525,
+25526,25529,25531,25533,25535,25536,25537,25538,25539,25541,25543,25544,25546,
+25547,25548,25553,25555,25556,25557,25559,25560,25561,25562,25563,25564,25565,
+25567,25570,25572,25573,25574,25575,25576,25579,25580,25582,25583,25584,25585,
+25587,25589,25591,25593,25594,25595,25596,25598,25603,25604,25606,25607,25608,
+25609,25610,25613,25614,25617,25618,25621,25622,25623,25624,25625,25626,25629,
+25631,25634,25635,25636,U,25637,25639,25640,25641,25643,25646,25647,25648,
+25649,25650,25651,25653,25654,25655,25656,25657,25659,25660,25662,25664,25666,
+25667,25673,25675,25676,25677,25678,25679,25680,25681,25683,25685,25686,25687,
+25689,25690,25691,25692,25693,25695,25696,25697,25698,25699,25700,25701,25702,
+25704,25706,25707,25708,25710,25711,25712,25713,25714,25715,25716,25717,25718,
+25719,25723,25724,25725,25726,25727,25728,25729,25731,25734,25736,25737,25738,
+25739,25740,25741,25742,25743,25744,25747,25748,25751,25752,25754,25755,25756,
+25757,25759,25760,25761,25762,25763,25765,25766,25767,25768,25770,25771,25775,
+25777,25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796,
+25798,25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814,
+25817,25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833,
+25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,
+25847,25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860,
+25861,25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875,
+25876,25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889,
+U,25890,25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905,
+25906,25907,25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927,
+25930,25931,25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951,
+25952,25953,25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971,
+25973,25974,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,
+25987,25988,25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005,
+26006,26008,26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030,
+26033,26034,26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048,
+26050,26055,26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073,
+26074,26075,26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099,
+26100,26101,26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119,
+26120,26121,26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140,
+26142,26145,26146,26147,26148,26150,26153,26154,26155,26156,26158,26160,26162,
+26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,26181,26182,
+26183,26184,26185,26186,26189,26190,26192,26193,26200,U,26201,26203,26204,
+26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,26225,
+26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,26245,
+26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,26261,
+26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,26277,
+26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,26294,
+26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,26309,
+26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,
+26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,26339,
+26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,26358,
+26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,26382,
+26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,26402,
+26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,26425,
+26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,26452,
+26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,26475,
+26476,26478,26481,26484,26486,U,26488,26489,26490,26491,26493,26496,26498,
+26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516,
+26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546,
+26548,26553,26554,26555,26556,26557,26558,26559,26560,26562,26565,26566,26567,
+26568,26569,26570,26571,26572,26573,26574,26581,26582,26583,26587,26591,26593,
+26595,26596,26598,26599,26600,26602,26603,26605,26606,26610,26613,26614,26615,
+26616,26617,26618,26619,26620,26622,26625,26626,26627,26628,26630,26637,26640,
+26642,26644,26645,26648,26649,26650,26651,26652,26654,26655,26656,26658,26659,
+26660,26661,26662,26663,26664,26667,26668,26669,26670,26671,26672,26673,26676,
+26677,26678,26682,26683,26687,26695,26699,26701,26703,26706,26710,26711,26712,
+26713,26714,26715,26716,26717,26718,26719,26730,26732,26733,26734,26735,26736,
+26737,26738,26739,26741,26744,26745,26746,26747,26748,26749,26750,26751,26752,
+26754,26756,26759,26760,26761,26762,26763,26764,26765,26766,26768,26769,26770,
+26772,26773,26774,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785,
+26787,26788,26789,26793,26794,26795,26796,26798,26801,26802,26804,26806,26807,
+26808,U,26809,26810,26811,26812,26813,26814,26815,26817,26819,26820,26821,
+26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,26836,26838,26839,
+26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,26854,26855,26856,
+26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,26871,26872,26875,
+26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,26889,26890,26892,
+26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,
+26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,26923,26924,26926,
+26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,26940,26942,26944,
+26945,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,
+26959,26960,26961,26962,26963,26965,26966,26968,26969,26971,26972,26975,26977,
+26978,26980,26981,26983,26984,26985,26986,26988,26989,26991,26992,26994,26995,
+26996,26997,26998,27002,27003,27005,27006,27007,27009,27011,27013,27018,27019,
+27020,27022,27023,27024,27025,27026,27027,27030,27031,27033,27034,27037,27038,
+27039,27040,27041,27042,27043,27044,27045,27046,27049,27050,27052,27054,27055,
+27056,27058,27059,27061,27062,27064,27065,27066,27068,27069,U,27070,27071,
+27072,27074,27075,27076,27077,27078,27079,27080,27081,27083,27085,27087,27089,
+27090,27091,27093,27094,27095,27096,27097,27098,27100,27101,27102,27105,27106,
+27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27118,27119,27120,
+27121,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27134,27136,
+27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,27149,27150,
+27151,27152,27153,27154,27155,27156,27157,27158,27161,27162,27163,27164,27165,
+27166,27168,27170,27171,27172,27173,27174,27175,27177,27179,27180,27181,27182,
+27184,27186,27187,27188,27190,27191,27192,27193,27194,27195,27196,27199,27200,
+27201,27202,27203,27205,27206,27208,27209,27210,27211,27212,27213,27214,27215,
+27217,27218,27219,27220,27221,27222,27223,27226,27228,27229,27230,27231,27232,
+27234,27235,27236,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,
+27248,27250,27251,27252,27253,27254,27255,27256,27258,27259,27261,27262,27263,
+27265,27266,27267,27269,27270,27271,27272,27273,27274,27275,27276,27277,27279,
+27282,27283,27284,27285,27286,27288,27289,27290,27291,27292,27293,27294,27295,
+27297,27298,27299,27300,27301,27302,U,27303,27304,27306,27309,27310,27311,
+27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324,
+27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337,
+27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350,
+27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363,
+27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376,
+27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,
+27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,
+27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,
+27416,27417,27418,27419,27420,27421,27422,27423,27429,27430,27432,27433,27434,
+27435,27436,27437,27438,27439,27440,27441,27443,27444,27445,27446,27448,27451,
+27452,27453,27455,27456,27457,27458,27460,27461,27464,27466,27467,27469,27470,
+27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27482,27483,27484,
+27485,27486,27487,27488,27489,27496,27497,27499,27500,27501,27502,27503,27504,
+27505,27506,27507,27508,27509,27510,27511,27512,27514,27517,27518,27519,27520,
+27525,27528,U,27532,27534,27535,27536,27537,27540,27541,27543,27544,27545,
+27548,27549,27550,27551,27552,27554,27555,27556,27557,27558,27559,27560,27561,
+27563,27564,27565,27566,27567,27568,27569,27570,27574,27576,27577,27578,27579,
+27580,27581,27582,27584,27587,27588,27590,27591,27592,27593,27594,27596,27598,
+27600,27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,
+27622,27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,
+27640,27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,
+27658,27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,
+27692,27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,
+27716,27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,
+27737,27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,
+27763,27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,
+27789,27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,
+27810,27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,
+27843,27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,U,27865,
+27866,27868,27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,
+27903,27904,27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,
+27923,27924,27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,
+27942,27944,27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,
+27968,27970,27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,
+28001,28002,28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,
+28021,28022,28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,
+28039,28042,28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,
+28066,28069,28076,28077,28080,28081,28083,28084,28086,28087,28089,28090,28091,
+28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,28111,28112,
+28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,28133,28135,
+28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,28154,28157,
+28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,28171,28175,
+28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,28199,28200,
+28202,28204,28206,28208,28209,28211,28213,U,28214,28215,28217,28219,28220,
+28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,28235,
+28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,28256,
+28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,28271,
+28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,
+28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,28305,
+28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,28321,
+28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,28344,
+28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,28364,
+28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,28394,
+28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,28408,
+28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,28424,
+28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,28442,
+28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,28460,
+28462,28464,28466,28468,28469,28471,28472,28473,28474,28475,28476,28477,28479,
+28480,28481,28482,U,28483,28484,28485,28488,28489,28490,28492,28494,28495,
+28496,28497,28498,28499,28500,28501,28502,28503,28505,28506,28507,28509,28511,
+28512,28513,28515,28516,28517,28519,28520,28521,28522,28523,28524,28527,28528,
+28529,28531,28533,28534,28535,28537,28539,28541,28542,28543,28544,28545,28546,
+28547,28549,28550,28551,28554,28555,28559,28560,28561,28562,28563,28564,28565,
+28566,28567,28568,28569,28570,28571,28573,28574,28575,28576,28578,28579,28580,
+28581,28582,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,
+28596,28597,28599,28600,28602,28603,28604,28605,28606,28607,28609,28611,28612,
+28613,28614,28615,28616,28618,28619,28620,28621,28622,28623,28624,28627,28628,
+28629,28630,28631,28632,28633,28634,28635,28636,28637,28639,28642,28643,28644,
+28645,28646,28647,28648,28649,28650,28651,28652,28653,28656,28657,28658,28659,
+28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,
+28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,
+28686,28687,28688,28690,28691,28692,28693,28694,28695,28696,28697,28700,28701,
+28702,28703,28704,28705,28706,28708,28709,28710,28711,28712,28713,28714,U,
+28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28726,28727,28728,
+28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742,
+28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,28755,28756,28757,
+28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,28769,28770,28771,
+28772,28773,28774,28775,28776,28777,28778,28782,28785,28786,28787,28788,28791,
+28793,28794,28795,28797,28801,28802,28803,28804,28806,28807,28808,28811,28812,
+28813,28815,28816,28817,28819,28823,28824,28826,28827,28830,28831,28832,28833,
+28834,28835,28836,28837,28838,28839,28840,28841,28842,28848,28850,28852,28853,
+28854,28858,28862,28863,28868,28869,28870,28871,28873,28875,28876,28877,28878,
+28879,28880,28881,28882,28883,28884,28885,28886,28887,28890,28892,28893,28894,
+28896,28897,28898,28899,28901,28906,28910,28912,28913,28914,28915,28916,28917,
+28918,28920,28922,28923,28924,28926,28927,28928,28929,28930,28931,28932,28933,
+28934,28935,28936,28939,28940,28941,28942,28943,28945,28946,28948,28951,28955,
+28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28967,28968,28969,
+28970,28971,28972,28973,28974,28978,28979,28980,U,28981,28983,28984,28985,
+28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28998,28999,
+29000,29001,29003,29005,29007,29008,29009,29010,29011,29012,29013,29014,29015,
+29016,29017,29018,29019,29021,29023,29024,29025,29026,29027,29029,29033,29034,
+29035,29036,29037,29039,29040,29041,29044,29045,29046,29047,29049,29051,29052,
+29054,29055,29056,29057,29058,29059,29061,29062,29063,29064,29065,29067,29068,
+29069,29070,29072,29073,29074,29075,29077,29078,29079,29082,29083,29084,29085,
+29086,29089,29090,29091,29092,29093,29094,29095,29097,29098,29099,29101,29102,
+29103,29104,29105,29106,29108,29110,29111,29112,29114,29115,29116,29117,29118,
+29119,29120,29121,29122,29124,29125,29126,29127,29128,29129,29130,29131,29132,
+29133,29135,29136,29137,29138,29139,29142,29143,29144,29145,29146,29147,29148,
+29149,29150,29151,29153,29154,29155,29156,29158,29160,29161,29162,29163,29164,
+29165,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29178,29179,
+29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29191,29192,29193,
+29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,
+29207,29208,29209,29210,U,29211,29212,29214,29215,29216,29217,29218,29219,
+29220,29221,29222,29223,29225,29227,29229,29230,29231,29234,29235,29236,29242,
+29244,29246,29248,29249,29250,29251,29252,29253,29254,29257,29258,29259,29262,
+29263,29264,29265,29267,29268,29269,29271,29272,29274,29276,29278,29280,29283,
+29284,29285,29288,29290,29291,29292,29293,29296,29297,29299,29300,29302,29303,
+29304,29307,29308,29309,29314,29315,29317,29318,29319,29320,29321,29324,29326,
+29328,29329,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341,
+29342,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355,
+29358,29361,29362,29363,29365,29370,29371,29372,29373,29374,29375,29376,29381,
+29382,29383,29385,29386,29387,29388,29391,29393,29395,29396,29397,29398,29400,
+29402,29403,183,U,U,U,U,U,8212,8560,8561,8562,8563,8564,8565,8566,8567,8568,
+8569,65077,65078,65081,65082,65087,65088,65085,65086,65089,65090,65091,65092,
+U,U,65083,65084,65079,65080,65073,U,65075,65076,714,715,729,8211,8213,8229,
+8245,8453,8457,8598,8599,8600,8601,8725,8735,8739,8786,8806,8807,8895,9552,
+9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,
+9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,
+9583,9584,9585,9586,9587,9601,9602,9603,9604,9605,9606,9607,U,9608,9609,9610,
+9611,9612,9613,9614,9615,9619,9620,9621,9660,9661,9698,9699,9700,9701,9737,
+8853,12306,12317,12318,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,593,U,324,328,U,609,12321,12322,12323,12324,12325,12326,
+12327,12328,12329,12963,13198,13199,13212,13213,13214,13217,13252,13262,13265,
+13266,13269,65072,65506,65508,U,8481,12849,U,8208,U,U,U,12540,12443,12444,
+12541,12542,12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104,
+65105,65106,65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119,
+65120,65121,U,65122,65123,65124,65125,65126,65128,65129,65130,65131,U,U,U,U,U,
+U,U,U,U,U,U,U,U,12295,29404,29405,29407,29410,29411,29412,29413,29414,29415,
+29418,29419,29429,29430,29433,29437,29438,29439,29440,29442,29444,29445,29446,
+29447,29448,29449,29451,29452,29453,29455,29456,29457,29458,29460,29464,29465,
+29466,29471,29472,29475,29476,29478,29479,29480,29485,29487,29488,29490,29491,
+29493,29494,29498,29499,29500,29501,29504,29505,29506,29507,29508,29509,29510,
+29511,29512,U,29513,29514,29515,29516,29518,29519,29521,29523,29524,29525,
+29526,29528,29529,29530,29531,29532,29533,29534,29535,29537,29538,29539,29540,
+29541,29542,29543,29544,29545,29546,29547,29550,29552,29553,29554,29555,29556,
+29557,29558,29559,29560,29561,29562,29563,29564,29565,29567,29568,29569,29570,
+29571,29573,29574,29576,29578,29580,29581,29583,29584,29586,29587,29588,29589,
+29591,29592,29593,29594,29596,29597,29598,29600,29601,29603,29604,29605,29606,
+29607,29608,29610,29612,29613,29617,29620,29621,29622,29624,29625,29628,29629,
+29630,29631,29633,29635,29636,29637,29638,29639,U,29643,29644,29646,29650,
+29651,29652,29653,29654,29655,29656,29658,29659,29660,29661,29663,29665,29666,
+29667,29668,29670,29672,29674,29675,29676,29678,29679,29680,29681,29683,29684,
+29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,
+29698,29700,29703,29704,29707,29708,29709,29710,29713,29714,29715,29716,29717,
+29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,29732,29735,
+29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,29757,29758,
+29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772,
+29773,U,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,29792,
+29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29806,
+29807,29809,29810,29811,29812,29813,29816,29817,29818,29819,29820,29821,29823,
+29826,29828,29829,29830,29832,29833,29834,29836,29837,29839,29841,29842,29843,
+29844,29845,29846,29847,29848,29849,29850,29851,29853,29855,29856,29857,29858,
+29859,29860,29861,29862,29866,29867,29868,29869,29870,29871,29872,29873,29874,
+29875,29876,29877,29878,29879,29880,29881,29883,29884,29885,29886,29887,29888,
+29889,29890,29891,29892,29893,29894,29895,U,29896,29897,29898,29899,29900,
+29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,29912,29913,29914,
+29915,29917,29919,29921,29925,29927,29928,29929,29930,29931,29932,29933,29936,
+29937,29938,29939,29941,29944,29945,29946,29947,29948,29949,29950,29952,29953,
+29954,29955,29957,29958,29959,29960,29961,29962,29963,29964,29966,29968,29970,
+29972,29973,29974,29975,29979,29981,29982,29984,29985,29986,29987,29988,29990,
+29991,29994,29998,30004,30006,30009,30012,30013,30015,30017,30018,30019,30020,
+30022,30023,30025,30026,30029,30032,30033,30034,30035,30037,30038,30039,30040,
+U,30045,30046,30047,30048,30049,30050,30051,30052,30055,30056,30057,30059,
+30060,30061,30062,30063,30064,30065,30067,30069,30070,30071,30074,30075,30076,
+30077,30078,30080,30081,30082,30084,30085,30087,30088,30089,30090,30092,30093,
+30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,30119,30120,30121,
+30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,30155,30156,30158,
+30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,30176,30177,30181,
+30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,30200,30202,30203,
+30205,30206,30210,30212,30214,30215,U,30216,30217,30219,30221,30222,30223,
+30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,30247,30248,
+30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,30273,30274,
+30276,30277,30278,30279,30280,30281,30282,30283,30286,30287,30288,30289,30290,
+30291,30293,30295,30296,30297,30298,30299,30301,30303,30304,30305,30306,30308,
+30309,30310,30311,30312,30313,30314,30316,30317,30318,30320,30321,30322,30323,
+30324,30325,30326,30327,30329,30330,30332,30335,30336,30337,30339,30341,30345,
+30346,30348,30349,30351,30352,30354,30356,30357,30359,30360,30362,30363,U,
+30364,30365,30366,30367,30368,30369,30370,30371,30373,30374,30375,30376,30377,
+30378,30379,30380,30381,30383,30384,30387,30389,30390,30391,30392,30393,30394,
+30395,30396,30397,30398,30400,30401,30403,30404,30407,30409,30411,30412,30419,
+30421,30425,30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439,
+30440,30441,30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459,
+30461,30463,30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481,
+30482,30483,30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499,
+30500,30501,30503,30506,30507,U,30508,30510,30512,30513,30514,30515,30516,
+30521,30523,30525,30526,30527,30530,30532,30533,30534,30536,30537,30538,30539,
+30540,30541,30542,30543,30546,30547,30548,30549,30550,30551,30552,30553,30556,
+30557,30558,30559,30560,30564,30567,30569,30570,30573,30574,30575,30576,30577,
+30578,30579,30580,30581,30582,30583,30584,30586,30587,30588,30593,30594,30595,
+30598,30599,30600,30601,30602,30603,30607,30608,30611,30612,30613,30614,30615,
+30616,30617,30618,30619,30620,30621,30622,30625,30627,30628,30630,30632,30635,
+30637,30638,30639,30641,30642,30644,30646,30647,30648,30649,30650,U,30652,
+30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,
+30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,30680,30681,30682,
+30685,30686,30687,30688,30689,30692,30694,30696,30698,30703,30704,30705,30706,
+30708,30709,30711,30713,30714,30715,30716,30723,30724,30725,30726,30727,30728,
+30730,30731,30734,30735,30736,30739,30741,30745,30747,30750,30752,30753,30754,
+30756,30760,30762,30763,30766,30767,30769,30770,30771,30773,30774,30781,30783,
+30785,30786,30787,30788,30790,30792,30793,30794,30795,30797,30799,30801,30803,
+30804,30808,30809,30810,U,30811,30812,30814,30815,30816,30817,30818,30819,
+30820,30821,30822,30823,30824,30825,30831,30832,30833,30834,30835,30836,30837,
+30838,30840,30841,30842,30843,30845,30846,30847,30848,30849,30850,30851,30852,
+30853,30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,
+30878,30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,
+30901,30902,30903,30904,30906,30907,30908,30909,30911,30912,30914,30915,30916,
+30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,30934,30935,30936,
+30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,U,30948,30949,
+30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,30965,30966,
+30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,30982,30983,
+30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30996,30997,
+30998,30999,31000,31001,31002,31003,31004,31005,31007,31008,31009,31010,31011,
+31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,
+31026,31027,31029,31030,31031,31032,31033,31037,31039,31042,31043,31044,31045,
+31047,31050,31051,31052,31053,31054,31055,31056,31057,31058,31060,31061,31064,
+31065,31073,31075,U,31076,31078,31081,31082,31083,31084,31086,31088,31089,
+31090,31091,31092,31093,31094,31097,31099,31100,31101,31102,31103,31106,31107,
+31110,31111,31112,31113,31115,31116,31117,31118,31120,31121,31122,31123,31124,
+31125,31126,31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138,
+31139,31140,31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152,
+31153,31154,31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175,
+31176,31178,31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195,
+31196,31197,31198,31200,31201,31202,31205,31208,31210,U,31212,31214,31217,
+31218,31219,31220,31221,31222,31223,31225,31226,31228,31230,31231,31233,31236,
+31237,31239,31240,31241,31242,31244,31247,31248,31249,31250,31251,31253,31254,
+31256,31257,31259,31260,31261,31263,31265,31266,31268,31269,31270,31271,31272,
+31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31284,31285,31286,
+31288,31290,31294,31296,31297,31298,31299,31300,31301,31303,31304,31305,31306,
+31307,31308,31309,31310,31311,31312,31314,31315,31316,31317,31318,31320,31321,
+31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334,
+31335,31336,U,31337,31338,31339,31340,31341,31342,31343,31345,31346,31347,
+31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,31371,31372,31374,
+31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,31395,31396,31399,
+31401,31402,31403,31406,31407,31408,31409,31410,31412,31413,31414,31415,31416,
+31417,31418,31419,31420,31421,31422,31424,31425,31426,31427,31428,31429,31430,
+31431,31432,31433,31434,31436,31437,31438,31439,31440,31441,31442,31443,31444,
+31445,31447,31448,31450,31451,31452,31453,31457,31458,31460,31463,31464,31465,
+31466,31467,31468,31470,31472,31473,31474,31475,U,31476,31477,31478,31479,
+31480,31483,31484,31486,31488,31489,31490,31493,31495,31497,31500,31501,31502,
+31504,31506,31507,31510,31511,31512,31514,31516,31517,31519,31521,31522,31523,
+31527,31529,31533,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549,
+31551,31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573,
+31575,31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593,
+31594,31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613,
+31615,31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630,
+31631,U,31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648,
+31651,31652,31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674,
+31675,31676,31677,31678,31679,31680,31682,31683,31684,31685,31688,31689,31690,
+31691,31693,31694,31695,31696,31698,31700,31701,31702,31703,31704,31707,31708,
+31710,31711,31712,31714,31715,31716,31719,31720,31721,31723,31724,31725,31727,
+31728,31730,31731,31732,31733,31734,31736,31737,31738,31739,31741,31743,31744,
+31745,31746,31747,31748,31749,31750,31752,31753,31754,31757,31758,31760,31761,
+31762,31763,31764,31765,31767,31768,31769,U,31770,31771,31772,31773,31774,
+31776,31777,31778,31779,31780,31781,31784,31785,31787,31788,31789,31790,31791,
+31792,31793,31794,31795,31796,31797,31798,31799,31801,31802,31803,31804,31805,
+31806,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,
+31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,
+31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,
+31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,
+31864,31865,31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,
+U,31880,31882,31883,31884,31885,31886,31887,31888,31891,31892,31894,31897,
+31898,31899,31904,31905,31907,31910,31911,31912,31913,31915,31916,31917,31919,
+31920,31924,31925,31926,31927,31928,31930,31931,31935,31936,31938,31939,31940,
+31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,
+31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,
+31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,
+31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,
+32011,32012,32013,32014,32015,32016,U,32017,32018,32019,32020,32021,32022,
+32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,32035,32036,32037,
+32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,32051,32052,32053,
+32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066,
+32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079,
+32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092,
+32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,
+32106,32107,32108,32109,32111,32112,32113,32114,32115,32116,32117,32118,U,
+32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132,
+32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145,
+32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158,
+32159,32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172,
+32173,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,
+32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,
+32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,
+32213,32214,32215,32216,32217,U,32218,32219,32220,32221,32222,32223,32224,
+32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,
+32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,
+32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,
+32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276,
+32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289,
+32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302,
+32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,U,32314,
+32316,32317,32318,32319,32320,32322,32323,32324,32325,32326,32328,32329,32330,
+32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343,
+32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356,
+32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,
+32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,
+32383,32384,32385,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396,
+32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409,
+32410,32412,32413,32414,U,32430,32436,32443,32444,32470,32484,32492,32505,
+32522,32528,32542,32567,32569,32571,32572,32573,32574,32575,32576,32577,32579,
+32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32594,32595,32598,
+32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,
+32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,
+32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,
+32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,
+32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,U,32691,32692,
+32693,32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712,
+32713,32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731,
+32732,32733,32734,32738,32739,32740,32743,32744,32746,32747,32748,32749,32751,
+32754,32756,32757,32758,32759,32760,32761,32762,32765,32766,32767,32770,32775,
+32776,32777,32778,32782,32783,32785,32787,32794,32795,32797,32798,32799,32801,
+32803,32804,32811,32812,32813,32814,32815,32816,32818,32820,32825,32826,32828,
+32830,32832,32833,32836,32837,32839,32840,32841,32846,32847,32848,32849,32851,
+32853,32854,32855,U,32857,32859,32860,32861,32862,32863,32864,32865,32866,
+32867,32868,32869,32870,32871,32872,32875,32876,32877,32878,32879,32880,32882,
+32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32897,
+32898,32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919,
+32921,32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953,
+32955,32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980,
+32981,32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022,
+33023,33024,33025,33027,33028,33029,33031,33032,33035,U,33036,33045,33047,
+33049,33051,33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,
+33064,33065,33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,
+33083,33084,33085,33087,33088,33089,33090,33091,33092,33093,33095,33097,33101,
+33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,33122,
+33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,33143,
+33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,33168,
+33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,33186,
+33188,33189,U,33191,33193,33195,33196,33197,33198,33199,33200,33201,33202,
+33204,33205,33206,33207,33208,33209,33212,33213,33214,33215,33220,33221,33223,
+33224,33225,33227,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238,
+33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33252,
+33253,33254,33256,33257,33259,33262,33263,33264,33265,33266,33269,33270,33271,
+33272,33273,33274,33277,33279,33283,33287,33288,33289,33290,33291,33294,33295,
+33297,33299,33301,33302,33303,33304,33305,33306,33309,33312,33316,33317,33318,
+33319,33321,33326,33330,33338,33340,33341,33343,U,33344,33345,33346,33347,
+33349,33350,33352,33354,33356,33357,33358,33360,33361,33362,33363,33364,33365,
+33366,33367,33369,33371,33372,33373,33374,33376,33377,33378,33379,33380,33381,
+33382,33383,33385,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403,
+33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429,
+33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467,
+33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501,
+33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526,
+33528,U,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554,
+33555,33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573,
+33574,33577,33578,33582,33584,33586,33591,33595,33597,33598,33599,33601,33602,
+33604,33605,33608,33610,33611,33612,33613,33614,33619,33621,33622,33623,33624,
+33625,33629,33634,33648,33649,33650,33651,33652,33653,33654,33657,33658,33662,
+33663,33664,33665,33666,33667,33668,33671,33672,33674,33675,33676,33677,33679,
+33680,33681,33684,33685,33686,33687,33689,33690,33693,33695,33697,33698,33699,
+33700,33701,33702,33703,33708,33709,33710,U,33711,33717,33723,33726,33727,
+33730,33731,33732,33734,33736,33737,33739,33741,33742,33744,33745,33746,33747,
+33749,33751,33753,33754,33755,33758,33762,33763,33764,33766,33767,33768,33771,
+33772,33773,33774,33775,33779,33780,33781,33782,33783,33786,33787,33788,33790,
+33791,33792,33794,33797,33799,33800,33801,33802,33808,33810,33811,33812,33813,
+33814,33815,33817,33818,33819,33822,33823,33824,33825,33826,33827,33833,33834,
+33835,33836,33837,33838,33839,33840,33842,33843,33844,33845,33846,33847,33849,
+33850,33851,33854,33855,33856,33857,33858,33859,33860,33861,33863,33864,33865,
+U,33866,33867,33868,33869,33870,33871,33872,33874,33875,33876,33877,33878,
+33880,33885,33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,
+33903,33904,33906,33908,33911,33913,33915,33916,33917,33918,33919,33920,33921,
+33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,33941,
+33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,33958,
+33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,33974,
+33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,33996,
+33998,33999,34002,34004,34005,34007,U,34008,34009,34010,34011,34012,34014,
+34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,
+34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,
+34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34061,34062,34063,
+34064,34066,34068,34069,34070,34072,34073,34075,34076,34077,34078,34080,34082,
+34083,34084,34085,34086,34087,34088,34089,34090,34093,34094,34095,34096,34097,
+34098,34099,34100,34101,34102,34110,34111,34112,34113,34114,34116,34117,34118,
+34119,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,U,
+34135,34136,34138,34139,34140,34141,34143,34144,34145,34146,34147,34149,34150,
+34151,34153,34154,34155,34156,34157,34158,34159,34160,34161,34163,34165,34166,
+34167,34168,34172,34173,34175,34176,34177,34178,34179,34182,34184,34185,34186,
+34187,34188,34189,34190,34192,34193,34194,34195,34196,34197,34198,34199,34200,
+34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217,
+34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236,
+34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251,
+34252,34253,34254,34257,34258,U,34260,34262,34263,34264,34265,34266,34267,
+34269,34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283,
+34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,
+34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,34311,34312,
+34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,34325,34327,
+34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340,
+34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355,
+34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,U,34369,
+34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,34387,
+34389,34390,34391,34392,34393,34395,34396,34397,34399,34400,34401,34403,34404,
+34405,34406,34407,34408,34409,34410,34413,34415,34416,34418,34419,34420,34421,
+34422,34423,34424,34435,34436,34437,34438,34439,34440,34441,34446,34447,34448,
+34449,34450,34452,34454,34455,34456,34457,34458,34459,34462,34463,34464,34465,
+34466,34469,34470,34475,34477,34478,34482,34483,34487,34488,34489,34491,34492,
+34493,34494,34495,34497,34498,34499,34501,34504,34508,34509,34514,34515,34517,
+34518,34519,34522,34524,U,34525,34528,34529,34530,34531,34533,34534,34535,
+34536,34538,34539,34540,34543,34549,34550,34551,34554,34555,34556,34557,34559,
+34561,34564,34565,34566,34571,34572,34574,34575,34576,34577,34580,34582,34585,
+34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,34607,
+34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,34626,
+34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,34645,
+34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,34664,
+34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,U,34679,34680,
+34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703,
+34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718,
+34720,34721,34722,34723,34724,34725,34726,34727,34729,34730,34734,34736,34737,
+34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,34753,34754,34755,
+34756,34757,34759,34760,34761,34764,34765,34766,34767,34768,34772,34773,34774,
+34775,34776,34777,34778,34780,34781,34782,34783,34785,34786,34787,34788,34790,
+34791,34792,34793,34795,34796,34797,34799,34800,34801,34802,34803,34804,34805,
+34806,34807,34808,U,34810,34811,34812,34813,34815,34816,34817,34818,34820,
+34821,34822,34823,34824,34825,34827,34828,34829,34830,34831,34832,34833,34834,
+34836,34839,34840,34841,34842,34844,34845,34846,34847,34848,34851,34852,34853,
+34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34867,
+34868,34869,34870,34871,34872,34874,34875,34877,34878,34879,34881,34882,34883,
+34886,34887,34888,34889,34890,34891,34894,34895,34896,34897,34898,34899,34901,
+34902,34904,34906,34907,34908,34909,34910,34911,34912,34918,34919,34922,34925,
+34927,34929,34931,34932,34933,34934,34936,34937,34938,U,34939,34940,34944,
+34947,34950,34951,34953,34954,34956,34958,34959,34960,34961,34963,34964,34965,
+34967,34968,34969,34970,34971,34973,34974,34975,34976,34977,34979,34981,34982,
+34983,34984,34985,34986,34988,34990,34991,34992,34994,34995,34996,34997,34998,
+35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,35016,35018,
+35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,35036,35037,
+35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,35055,35058,
+35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,35077,35078,
+35079,35080,U,35081,35083,35084,35085,35086,35087,35089,35092,35093,35094,
+35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,35112,
+35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,35128,35129,35130,
+35131,35132,35133,35134,35135,35136,35138,35139,35141,35142,35143,35144,35145,
+35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158,
+35159,35160,35161,35162,35163,35164,35165,35168,35169,35170,35171,35172,35173,
+35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187,
+35188,35189,35190,35191,35192,35193,35194,35196,U,35197,35198,35200,35202,
+35204,35205,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,
+35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230,
+35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,
+35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,
+35257,35258,35259,35260,35261,35262,35263,35264,35267,35277,35283,35284,35285,
+35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,35305,
+35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,35321,
+35322,U,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334,
+35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,
+35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361,
+35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374,
+35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387,
+35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,35399,35401,35402,
+35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415,
+35416,35417,35418,35419,35420,35421,35422,U,35423,35424,35425,35426,35427,
+35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440,
+35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,35453,35454,
+35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35467,35468,35469,
+35470,35471,35472,35473,35474,35476,35477,35478,35479,35480,35481,35482,35483,
+35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,
+35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,
+35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,
+U,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,
+35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,
+35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,
+35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,
+35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,
+35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,35599,35600,
+35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,
+35614,35615,35616,35617,35618,35619,U,35620,35621,35623,35624,35625,35626,
+35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,
+35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,
+35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665,
+35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678,
+35679,35680,35681,35682,35683,35684,35685,35687,35688,35689,35690,35691,35693,
+35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,
+35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,U,
+35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731,
+35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35756,
+35761,35771,35783,35792,35818,35849,35870,35896,35897,35898,35899,35900,35901,
+35902,35903,35904,35906,35907,35908,35909,35912,35914,35915,35917,35918,35919,
+35920,35921,35922,35923,35924,35926,35927,35928,35929,35931,35932,35933,35934,
+35935,35936,35939,35940,35941,35942,35943,35944,35945,35948,35949,35950,35951,
+35952,35953,35954,35956,35957,35958,35959,35963,35964,35965,35966,35967,35968,
+35969,35971,35972,35974,35975,U,35976,35979,35981,35982,35983,35984,35985,
+35986,35987,35989,35990,35991,35993,35994,35995,35996,35997,35998,35999,36000,
+36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013,
+36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026,
+36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039,
+36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052,
+36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065,
+36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,U,36077,
+36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090,
+36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103,
+36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116,
+36117,36118,36119,36120,36121,36122,36123,36124,36128,36177,36178,36183,36191,
+36197,36200,36201,36202,36204,36206,36207,36209,36210,36216,36217,36218,36219,
+36220,36221,36222,36223,36224,36226,36227,36230,36231,36232,36233,36236,36237,
+36238,36239,36240,36242,36243,36245,36246,36247,36248,36249,36250,36251,36252,
+36253,36254,36256,36257,U,36258,36260,36261,36262,36263,36264,36265,36266,
+36267,36268,36269,36270,36271,36272,36274,36278,36279,36281,36283,36285,36288,
+36289,36290,36293,36295,36296,36297,36298,36301,36304,36306,36307,36308,36309,
+36312,36313,36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,
+36337,36338,36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,
+36359,36360,36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,
+36377,36378,36379,36380,36384,36385,36388,36389,36390,36391,36392,36395,36397,
+36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,U,36415,36419,
+36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,36440,
+36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36455,
+36456,36458,36459,36462,36465,36467,36469,36471,36472,36473,36474,36475,36477,
+36478,36480,36482,36483,36484,36486,36488,36489,36490,36491,36492,36493,36494,
+36497,36498,36499,36501,36502,36503,36504,36505,36506,36507,36509,36511,36512,
+36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36525,36526,36528,
+36529,36531,36532,36533,36534,36535,36536,36537,36539,36540,36541,36542,36543,
+36544,36545,36546,U,36547,36548,36549,36550,36551,36552,36553,36554,36555,
+36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,
+36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582,
+36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,
+36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,
+36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,
+36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,
+36635,36636,36637,36638,36639,36640,36641,36642,36643,U,36644,36645,36646,
+36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,
+36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,
+36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685,
+36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698,
+36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36714,36736,
+36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,36778,36780,36781,
+36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,36796,36799,36800,
+36803,36806,U,36809,36810,36811,36812,36813,36815,36818,36822,36823,36826,
+36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,36858,36859,
+36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,36889,36892,36899,
+36900,36901,36903,36904,36905,36906,36907,36908,36912,36913,36914,36915,36916,
+36919,36921,36922,36925,36927,36928,36931,36933,36934,36936,36937,36938,36939,
+36940,36942,36948,36949,36950,36953,36954,36956,36957,36958,36959,36960,36961,
+36964,36966,36967,36969,36970,36971,36972,36975,36976,36977,36978,36979,36982,
+36983,36984,36985,36986,36987,36988,36990,36993,U,36996,36997,36998,36999,
+37001,37002,37004,37005,37006,37007,37008,37010,37012,37014,37016,37018,37020,
+37022,37023,37024,37028,37029,37031,37032,37033,37035,37037,37042,37047,37052,
+37053,37055,37056,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076,
+37077,37078,37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098,
+37100,37102,37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116,
+37119,37120,37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133,
+37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147,
+37148,U,37149,37151,37152,37153,37156,37157,37158,37159,37160,37161,37162,
+37163,37164,37165,37166,37168,37170,37171,37172,37173,37174,37175,37176,37178,
+37179,37180,37181,37182,37183,37184,37185,37186,37188,37189,37191,37192,37201,
+37203,37204,37205,37206,37208,37209,37211,37212,37215,37216,37222,37223,37224,
+37227,37229,37235,37242,37243,37244,37248,37249,37250,37251,37252,37254,37256,
+37258,37262,37263,37267,37268,37269,37270,37271,37272,37273,37276,37277,37278,
+37279,37280,37281,37284,37285,37286,37287,37288,37289,37291,37292,37296,37297,
+37298,37299,37302,37303,37304,37305,37307,U,37308,37309,37310,37311,37312,
+37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,37331,37332,37333,
+37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,37345,37346,37347,
+37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,
+37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,
+37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,
+37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,
+37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,
+U,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,
+37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,
+37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450,
+37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,
+37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,
+37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,
+37490,37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,
+37504,37505,37506,37507,37508,37509,U,37510,37511,37512,37513,37514,37515,
+37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,
+37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,
+37543,37544,37545,37546,37547,37548,37549,37551,37552,37553,37554,37555,37556,
+37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569,
+37570,37571,37572,37573,37574,37575,37577,37578,37579,37580,37581,37582,37583,
+37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596,
+37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,U,
+37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621,
+37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634,
+37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647,
+37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,
+37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,
+37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,
+37687,37688,37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700,
+37701,37702,37703,37704,37705,U,37706,37707,37708,37709,37710,37711,37712,
+37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,
+37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37739,
+37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752,
+37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765,
+37766,37767,37768,37769,37770,37771,37772,37773,37774,37776,37777,37778,37779,
+37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,
+37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,U,37804,
+37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817,
+37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830,
+37831,37832,37833,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844,
+37845,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858,
+37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871,
+37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884,
+37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897,
+37898,37899,37900,37901,U,37902,37903,37904,37905,37906,37907,37908,37909,
+37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922,
+37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935,
+37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,
+37949,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,
+37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,
+37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,
+37989,37990,37991,37992,37993,37994,37996,37997,37998,37999,U,38000,38001,
+38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,
+38015,38016,38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100,
+38106,38118,38139,38172,38176,38183,38195,38205,38211,38216,38219,38229,38234,
+38240,38254,38260,38261,38263,38264,38265,38266,38267,38268,38269,38270,38272,
+38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,
+38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,
+38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,
+38312,38313,38314,U,38315,38316,38317,38318,38319,38320,38321,38322,38323,
+38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,
+38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349,
+38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362,
+38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,
+38380,38399,38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439,
+38440,38441,38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465,
+38467,38474,38478,38479,38481,38482,38483,38486,38487,U,38488,38489,38490,
+38492,38493,38494,38496,38499,38501,38502,38507,38509,38510,38511,38512,38513,
+38515,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,
+38532,38535,38537,38538,38540,38542,38545,38546,38547,38549,38550,38554,38555,
+38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570,
+38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587,
+38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616,
+38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630,
+38631,38635,U,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650,
+38651,38652,38653,38655,38658,38659,38661,38666,38667,38668,38672,38673,38674,
+38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,38689,38690,38691,
+38692,38693,38694,38695,38696,38697,38699,38700,38702,38703,38705,38707,38708,
+38709,38710,38711,38714,38715,38716,38717,38719,38720,38721,38722,38723,38724,
+38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,
+38740,38741,38743,38744,38746,38748,38749,38751,38755,38756,38758,38759,38760,
+38762,38763,38764,38765,38766,38767,38768,38769,U,38770,38773,38775,38776,
+38777,38778,38779,38781,38782,38783,38784,38785,38786,38787,38788,38790,38791,
+38792,38793,38794,38796,38798,38799,38800,38803,38805,38806,38807,38809,38810,
+38811,38812,38813,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825,
+38826,38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843,
+38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,
+38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,
+38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,
+38883,U,38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904,
+38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,
+38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930,
+38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943,
+38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956,
+38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969,
+38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982,
+38983,38984,38985,38986,38987,38988,38989,U,38990,38991,38992,38993,38994,
+38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007,
+39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020,
+39021,39022,39023,39024,39025,39026,39027,39028,39051,39054,39058,39061,39065,
+39075,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,
+39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,
+39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,
+39119,39120,39124,39126,39127,39131,39132,39133,39136,39137,39138,39139,39140,
+U,39141,39142,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,
+39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,
+39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180,
+39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,
+39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,
+39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,
+39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,
+39236,39237,39238,39239,39240,39241,U,39242,39243,39244,39245,39246,39247,
+39248,39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,
+39263,39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,
+39305,39308,39310,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,
+39332,39334,39335,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346,
+39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359,
+39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372,
+39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,U,
+39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397,
+39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410,
+39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423,
+39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436,
+39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449,
+39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,
+39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,
+39476,39477,39478,39479,39480,U,39481,39482,39483,39484,39485,39486,39487,
+39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,
+39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,
+39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526,
+39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,39577,
+39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,39609,
+39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,39630,
+39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,U,39645,
+39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664,
+39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679,
+39680,39681,39682,39684,39685,39686,39687,39689,39690,39691,39692,39693,39694,
+39696,39697,39698,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709,
+39710,39712,39713,39714,39716,39717,39718,39719,39720,39721,39722,39723,39724,
+39725,39726,39728,39729,39731,39732,39733,39734,39735,39736,39737,39738,39741,
+39742,39743,39744,39750,39754,39755,39756,39758,39760,39762,39763,39765,39766,
+39767,39768,39769,39770,U,39771,39772,39773,39774,39775,39776,39777,39778,
+39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791,
+39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804,
+39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,
+39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,
+39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,
+39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,
+39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,U,39867,39868,
+39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,
+39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,
+39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,
+39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,
+39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,
+39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,
+39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,
+39960,39961,39962,U,39963,39964,39965,39966,39967,39968,39969,39970,39971,
+39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,
+39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997,
+39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010,
+40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023,
+40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036,
+40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049,
+40050,40051,40052,40053,40054,40055,40056,40057,40058,U,40059,40061,40062,
+40064,40067,40068,40073,40074,40076,40079,40083,40086,40087,40088,40089,40093,
+40106,40108,40111,40121,40126,40127,40128,40129,40130,40136,40137,40145,40146,
+40154,40155,40160,40161,40163,40164,40165,40166,40167,40168,40169,40170,40171,
+40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184,
+40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197,
+40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210,
+40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223,
+40224,40225,U,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,
+40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,
+40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261,
+40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274,
+40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287,
+40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300,
+40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313,
+40314,40315,40316,40317,40318,40319,40320,40321,U,40322,40323,40324,40325,
+40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338,
+40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351,
+40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364,
+40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377,
+40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390,
+40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403,
+40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,
+40417,U,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,
+40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,
+40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454,
+40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467,
+40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40484,40487,
+40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,40534,40537,
+40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,40566,40567,
+40568,40569,40570,40571,40572,40573,40576,U,40577,40579,40580,40581,40582,
+40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,40600,
+40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,40616,
+40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40629,40630,
+40631,40633,40634,40636,40639,40640,40641,40642,40643,40645,40646,40647,40648,
+40650,40651,40652,40656,40658,40659,40661,40662,40663,40665,40666,40670,40673,
+40675,40676,40678,40680,40683,40684,40685,40686,40688,40689,40690,40691,40692,
+40693,40694,40695,40696,40698,40701,40703,40704,40705,40706,40707,40708,40709,
+U,40710,40711,40712,40713,40714,40716,40719,40721,40722,40724,40725,40726,
+40728,40730,40731,40732,40733,40734,40735,40737,40739,40740,40741,40742,40743,
+40744,40745,40746,40747,40749,40750,40752,40753,40754,40755,40756,40757,40758,
+40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,40777,
+40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,40792,
+40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,
+40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,
+40819,40820,40821,40822,40823,40824,U,40825,40826,40827,40828,40829,40830,
+40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,
+40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,
+63985,64012,64013,64014,64015,64017,64019,64020,64024,64031,64032,64033,64035,
+64036,64039,64040,64041,
+};
+
+static const struct dbcs_index gbkext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{__gbkext_decmap+0,64,254},{__gbkext_decmap+191,64,
+254},{__gbkext_decmap+382,64,254},{__gbkext_decmap+573,64,254},{
+__gbkext_decmap+764,64,254},{__gbkext_decmap+955,64,254},{__gbkext_decmap+1146
+,64,254},{__gbkext_decmap+1337,64,254},{__gbkext_decmap+1528,64,254},{
+__gbkext_decmap+1719,64,254},{__gbkext_decmap+1910,64,254},{__gbkext_decmap+
+2101,64,254},{__gbkext_decmap+2292,64,254},{__gbkext_decmap+2483,64,254},{
+__gbkext_decmap+2674,64,254},{__gbkext_decmap+2865,64,254},{__gbkext_decmap+
+3056,64,254},{__gbkext_decmap+3247,64,254},{__gbkext_decmap+3438,64,254},{
+__gbkext_decmap+3629,64,254},{__gbkext_decmap+3820,64,254},{__gbkext_decmap+
+4011,64,254},{__gbkext_decmap+4202,64,254},{__gbkext_decmap+4393,64,254},{
+__gbkext_decmap+4584,64,254},{__gbkext_decmap+4775,64,254},{__gbkext_decmap+
+4966,64,254},{__gbkext_decmap+5157,64,254},{__gbkext_decmap+5348,64,254},{
+__gbkext_decmap+5539,64,254},{__gbkext_decmap+5730,64,254},{__gbkext_decmap+
+5921,64,254},{__gbkext_decmap+6112,164,170},{__gbkext_decmap+6119,161,170},{0,
+0,0},{0,0,0},{0,0,0},{__gbkext_decmap+6129,224,245},{0,0,0},{__gbkext_decmap+
+6151,64,192},{__gbkext_decmap+6280,64,150},{__gbkext_decmap+6367,64,160},{
+__gbkext_decmap+6464,64,160},{__gbkext_decmap+6561,64,160},{__gbkext_decmap+
+6658,64,160},{__gbkext_decmap+6755,64,160},{__gbkext_decmap+6852,64,160},{
+__gbkext_decmap+6949,64,160},{__gbkext_decmap+7046,64,160},{__gbkext_decmap+
+7143,64,160},{__gbkext_decmap+7240,64,160},{__gbkext_decmap+7337,64,160},{
+__gbkext_decmap+7434,64,160},{__gbkext_decmap+7531,64,160},{__gbkext_decmap+
+7628,64,160},{__gbkext_decmap+7725,64,160},{__gbkext_decmap+7822,64,160},{
+__gbkext_decmap+7919,64,160},{__gbkext_decmap+8016,64,160},{__gbkext_decmap+
+8113,64,160},{__gbkext_decmap+8210,64,160},{__gbkext_decmap+8307,64,160},{
+__gbkext_decmap+8404,64,160},{__gbkext_decmap+8501,64,160},{__gbkext_decmap+
+8598,64,160},{__gbkext_decmap+8695,64,160},{__gbkext_decmap+8792,64,160},{
+__gbkext_decmap+8889,64,160},{__gbkext_decmap+8986,64,160},{__gbkext_decmap+
+9083,64,160},{__gbkext_decmap+9180,64,160},{__gbkext_decmap+9277,64,160},{
+__gbkext_decmap+9374,64,160},{__gbkext_decmap+9471,64,160},{__gbkext_decmap+
+9568,64,160},{__gbkext_decmap+9665,64,160},{__gbkext_decmap+9762,64,160},{
+__gbkext_decmap+9859,64,160},{__gbkext_decmap+9956,64,160},{__gbkext_decmap+
+10053,64,160},{__gbkext_decmap+10150,64,160},{__gbkext_decmap+10247,64,160},{
+__gbkext_decmap+10344,64,160},{__gbkext_decmap+10441,64,160},{__gbkext_decmap+
+10538,64,160},{__gbkext_decmap+10635,64,160},{__gbkext_decmap+10732,64,160},{
+__gbkext_decmap+10829,64,160},{__gbkext_decmap+10926,64,160},{__gbkext_decmap+
+11023,64,160},{__gbkext_decmap+11120,64,160},{__gbkext_decmap+11217,64,160},{
+__gbkext_decmap+11314,64,160},{__gbkext_decmap+11411,64,160},{__gbkext_decmap+
+11508,64,160},{__gbkext_decmap+11605,64,160},{__gbkext_decmap+11702,64,160},{
+__gbkext_decmap+11799,64,160},{__gbkext_decmap+11896,64,160},{__gbkext_decmap+
+11993,64,160},{__gbkext_decmap+12090,64,160},{__gbkext_decmap+12187,64,160},{
+__gbkext_decmap+12284,64,160},{__gbkext_decmap+12381,64,160},{__gbkext_decmap+
+12478,64,160},{__gbkext_decmap+12575,64,160},{__gbkext_decmap+12672,64,160},{
+__gbkext_decmap+12769,64,160},{__gbkext_decmap+12866,64,160},{__gbkext_decmap+
+12963,64,160},{__gbkext_decmap+13060,64,160},{__gbkext_decmap+13157,64,160},{
+__gbkext_decmap+13254,64,160},{__gbkext_decmap+13351,64,160},{__gbkext_decmap+
+13448,64,160},{__gbkext_decmap+13545,64,160},{__gbkext_decmap+13642,64,160},{
+__gbkext_decmap+13739,64,160},{__gbkext_decmap+13836,64,160},{__gbkext_decmap+
+13933,64,160},{__gbkext_decmap+14030,64,160},{__gbkext_decmap+14127,64,160},{
+__gbkext_decmap+14224,64,160},{__gbkext_decmap+14321,64,160},{__gbkext_decmap+
+14418,64,160},{__gbkext_decmap+14515,64,79},{0,0,0},
+};
+
+static const DBCHAR __gbcommon_encmap[23231] = {
+8552,N,N,8556,8487,N,N,N,N,N,N,N,8547,8512,N,N,N,N,N,41380,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,10276,10274,
+N,N,N,N,N,N,10280,10278,10298,N,10284,10282,N,N,N,N,10288,10286,N,N,N,8514,N,
+10292,10290,N,10297,10273,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10277,N,N,N,N,N,N,
+N,10279,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,43197,N,N,N,43198,N,N,N,N,10285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,10289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10275,
+N,10283,N,10287,N,10291,N,10293,N,10294,N,10295,N,10296,43195,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,43200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8486,N,8485,
+43072,43073,N,N,N,N,N,N,N,N,N,N,N,N,N,43074,9761,9762,9763,9764,9765,9766,
+9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779,9780,9781,
+9782,9783,9784,N,N,N,N,N,N,N,9793,9794,9795,9796,9797,9798,9799,9800,9801,
+9802,9803,9804,9805,9806,9807,9808,9809,N,9810,9811,9812,9813,9814,9815,9816,
+10023,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10017,10018,10019,10020,10021,10022,10024,
+10025,10026,10027,10028,10029,10030,10031,10032,10033,10034,10035,10036,10037,
+10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,10049,10065,
+10066,10067,10068,10069,10070,10072,10073,10074,10075,10076,10077,10078,10079,
+10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092,
+10093,10094,10095,10096,10097,N,10071,43356,N,N,43075,41386,8490,8492,N,8494,
+8495,N,N,8496,8497,N,N,N,N,N,N,N,43077,8493,N,N,N,N,N,N,N,N,N,8555,N,8548,
+8549,N,43078,N,N,N,N,N,8569,8550,N,43079,N,N,N,43080,N,N,N,N,N,N,N,N,N,N,N,N,
+8557,N,N,N,N,N,N,N,N,N,N,43353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8817,8818,8819,8820,8821,8822,8823,8824,8825,8826,8827,8828,N,N,N,N,41633,
+41634,41635,41636,41637,41638,41639,41640,41641,41642,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,8571,8572,8570,8573,N,N,43081,43082,43083,43084,8522,N,N,
+N,N,N,N,8519,N,8518,N,N,N,43085,N,N,N,N,8524,N,N,8536,8542,43086,8527,N,N,
+43087,N,8526,N,8516,8517,8521,8520,8530,N,N,8531,N,N,N,N,N,8544,8543,8515,
+8523,N,N,N,N,N,8535,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,8533,N,N,N,N,N,43088,N,N,N,
+N,N,N,N,N,N,N,N,N,N,8537,8532,N,N,8540,8541,43089,43090,N,N,N,N,N,N,8538,8539,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43154,N,N,N,8529,N,N,N,N,N,N,N,N,N,N,N,8525,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,43091,8528,8793,8794,8795,8796,8797,8798,8799,8800,8801,8802,
+N,N,N,N,N,N,N,N,N,N,8773,8774,8775,8776,8777,8778,8779,8780,8781,8782,8783,
+8784,8785,8786,8787,8788,8789,8790,8791,8792,8753,8754,8755,8756,8757,8758,
+8759,8760,8761,8762,8763,8764,8765,8766,8767,8768,8769,8770,8771,8772,10532,
+10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,
+10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,
+10559,10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,
+10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,
+10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,
+10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,N,N,N,N,43092,
+43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105,
+43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118,
+43119,43120,43121,43122,43123,43124,43125,43126,43127,N,N,N,N,N,N,N,N,N,N,N,N,
+N,43128,43129,43130,43131,43132,43133,43134,43136,43137,43138,43139,43140,
+43141,43142,43143,N,N,N,43144,43145,43146,N,N,N,N,N,N,N,N,N,N,8566,8565,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8567,N,N,N,N,N,N,N,N,43147,43148,N,N,N,N,N,N,N,
+N,8564,8563,N,N,N,8560,N,N,8562,8561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43149,43150,43151,43152,8559,8558,N,N,43153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8546,N,8545,8481,8482,8483,8488,N,8489,43365,43414,8500,8501,8502,8503,8504,
+8505,8506,8507,8510,8511,43155,8574,8498,8499,8508,8509,N,N,N,N,N,43156,43157,
+N,N,43328,43329,43330,43331,43332,43333,43334,43335,43336,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,
+9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,
+9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,
+9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,
+9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,
+9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N,
+N,43361,43362,43366,43367,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513,
+9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,
+9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,
+9544,9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,
+9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,
+9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,
+9589,9590,N,N,N,N,8484,43360,43363,43364,10309,10310,10311,10312,10313,10314,
+10315,10316,10317,10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,
+10328,10329,10330,10331,10332,10333,10334,10335,10336,10337,10338,10339,10340,
+10341,10342,10343,10344,10345,8805,8806,8807,8808,8809,8810,8811,8812,8813,
+8814,N,N,N,N,N,N,N,43354,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,43337,43338,43339,N,N,N,N,N,N,N,N,N,N,N,N,43340,43341,43342,
+N,N,43343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43344,N,N,N,N,N,N,N,N,N,43345,N,N,43346,43347,N,N,43348,21051,13857,33088,
+18015,33089,33090,33091,19826,21833,18557,18767,20290,22562,12859,21355,33092,
+22564,13171,33093,22312,18258,22567,19008,33094,18288,12667,21045,13396,13867,
+19263,22569,33095,33096,33097,13866,33098,16701,20815,33099,18725,22573,33100,
+14454,20798,25436,22096,33101,33102,14177,33103,13358,33104,16729,33105,22588,
+33106,19816,13604,20010,22135,33107,16502,15961,22575,33108,33109,33110,17483,
+33111,15939,33112,22577,17204,21093,33113,22062,20058,21799,14965,14118,16470,
+33114,17977,17746,18247,33115,14676,33116,13131,21074,33117,33118,22591,15941,
+18034,21042,20272,20327,33119,33120,33121,33122,19049,33123,33124,22592,33125,
+33126,33127,33128,33129,33130,17010,16978,33131,18537,33132,33133,33134,33135,
+33136,33137,33138,33139,33140,33141,18220,33142,33143,33144,33145,33146,33147,
+33148,16715,33149,21352,21881,33150,19010,13950,22561,21338,16247,33152,21574,
+15141,22593,20069,15918,33153,33154,22568,33155,20807,20521,33156,33157,33158,
+22589,22895,19830,16186,33159,15675,14885,21088,12922,14944,17462,33160,20333,
+15913,19748,16705,33161,33162,33163,18263,22897,33164,22900,33165,33166,33167,
+33168,18507,22633,33169,33170,33171,21082,18994,18506,22636,22634,22598,15734,
+17997,13168,33172,22635,15729,15721,33173,18516,13395,33174,33175,16984,33176,
+12886,22352,19019,19323,21836,14390,20297,33177,33178,33179,22874,22640,18218,
+33180,22638,33181,13434,16750,21076,33182,33183,22637,33184,21063,22639,17223,
+33185,33186,33187,20854,33188,22105,22642,33189,22645,15486,15451,33190,33191,
+33192,18510,33193,14173,33194,14146,33195,18035,33196,33197,33198,33199,33200,
+33201,33202,22648,21057,33203,33204,20073,15423,14204,14117,20573,33205,33206,
+33207,33208,33209,22106,21317,15215,15201,22641,33210,33211,18721,20016,13355,
+33212,22643,33213,18763,22646,16983,22647,33214,33215,20017,22649,33216,33217,
+33218,12846,14656,33219,22819,33220,12393,33221,16742,33222,18796,33223,19269,
+33224,19270,22820,33225,33226,33227,33228,33229,13672,33230,33231,13611,33232,
+33233,33234,33235,33236,33237,20027,13645,22305,22388,21331,33238,19557,33239,
+14926,33240,22818,22876,21344,22653,14192,22391,22654,22650,22817,17507,33241,
+33242,21302,22644,22877,33243,22651,33244,17765,33245,33246,16464,33247,33248,
+20848,12379,33249,33250,15441,22822,33251,22821,33252,33253,33254,33255,22828,
+22830,33256,22827,19001,33257,33258,33259,22825,22070,33260,33261,33262,13150,
+22824,33263,16509,33264,19020,33265,22826,33266,22823,33267,33268,22832,33269,
+33270,13873,33271,33272,33273,14633,33274,21056,33275,33276,20288,33277,33278,
+16962,33344,15684,21868,12896,18248,16235,22829,33345,22831,33346,20074,14958,
+33347,33348,33349,33350,33351,18262,33352,33353,33354,33355,33356,33357,33358,
+33359,33360,12643,33361,33362,33363,13401,13933,22836,33364,33365,33366,33367,
+16161,33368,33369,33370,22878,18254,16510,22840,33371,33372,33373,33374,33375,
+19287,14205,33376,22837,33377,22839,12579,21345,22841,33378,20549,33379,22838,
+33380,33381,22833,33382,22834,16681,22835,33383,33384,15475,20574,14377,33385,
+15971,33386,22845,33387,33388,33389,33390,22842,33391,12339,33392,33393,33394,
+22850,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406,
+33408,22852,12598,33409,22847,33410,33411,13625,33412,15987,33413,33414,33415,
+19528,14962,21072,33416,22851,33417,33418,15720,33419,13099,33420,33421,33422,
+22853,15979,33423,22854,22843,17503,33424,22846,22849,22848,33425,33426,33427,
+33428,33429,33430,33431,33432,33433,33434,33435,21806,33436,22069,33437,18275,
+33438,33439,33440,33441,22856,33442,33443,33444,15449,22858,33445,33446,33447,
+22844,33448,22859,17963,33449,33450,33451,33452,33453,22857,33454,33455,33456,
+33457,22390,33458,19747,33459,33460,33461,33462,33463,33464,33465,33466,15649,
+33467,33468,33469,33470,33471,33472,22860,33473,33474,33475,33476,33477,33478,
+33479,33480,33481,17724,19765,33482,33483,33484,22861,33485,33486,22855,13093,
+16254,33487,33488,33489,33490,14389,33491,33492,16508,33493,33494,33495,33496,
+12408,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508,
+33509,33510,33511,33512,33513,33514,33515,33516,33517,13430,33518,22862,33519,
+22863,13346,22864,33520,33521,13407,33522,33523,33524,33525,33526,12353,33527,
+33528,33529,33530,33531,33532,33533,22865,18741,33534,33600,33601,33602,33603,
+33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616,
+33617,20337,33618,33619,33620,33621,33622,33623,22866,33624,33625,33626,16709,
+33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,22870,18734,
+33638,33639,33640,33641,22869,22868,22871,33642,33643,33644,33645,19291,33646,
+15657,33647,33648,33649,33650,33651,17959,33652,33653,33654,33655,33656,33657,
+33658,33659,33660,33661,22867,22872,33662,33664,33665,22873,33666,33667,33668,
+33669,33670,33671,18533,33672,33673,33674,33675,33676,33677,33678,33679,33680,
+33681,33682,33683,33684,33685,16476,33686,33687,33688,33689,33690,33691,33692,
+33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705,
+33706,33707,33708,33709,33710,33711,33712,33713,33714,13945,22563,21578,33715,
+21546,20566,13156,21847,33716,20296,14690,33717,16203,33718,17250,33719,33720,
+33721,13906,33722,33723,19779,22894,22896,33724,33725,33726,13619,33727,13877,
+33728,33729,33730,33731,33732,15908,33733,33734,18539,33735,33736,18475,33737,
+33738,12363,14635,16761,22882,33739,16444,14642,33740,14680,20555,12664,18020,
+15967,13668,22344,33741,20856,15462,19038,33742,33743,15421,22886,22631,33744,
+33745,17498,33746,33747,14420,18493,33748,33749,12897,21593,33750,33751,33752,
+33753,17200,33754,33755,17249,23074,18527,33756,20532,33757,15996,17705,33758,
+33759,33760,14682,33761,23075,33762,21545,23076,33763,33764,33765,33766,33767,
+22907,13868,33768,33769,14187,12665,22908,13157,15990,33770,16246,21041,16484,
+33771,33772,33773,13875,22910,22909,33774,33775,15931,33776,33777,33778,18016,
+33779,22332,23073,33780,16697,33781,13682,16744,33782,33783,15477,33784,13397,
+33785,33786,33787,33788,33789,33790,33856,33857,33858,16733,33859,17533,33860,
+33861,15416,14130,33862,33863,14191,33864,33865,33866,33867,33868,33869,22892,
+33870,17982,33871,16173,15179,33872,33873,13642,33874,23369,20567,33875,19769,
+12348,13174,15223,23370,14895,33876,21604,13622,13683,22614,18512,33877,33878,
+14166,18256,22615,33879,16175,33880,33881,23355,22616,33882,33883,20556,15150,
+33884,33885,33886,27454,16720,16757,21618,14421,13364,33887,13173,33888,33889,
+18750,33890,33891,33892,17744,33893,33894,33895,17753,16507,33896,12656,33897,
+22617,14670,33898,13629,33899,33900,22618,33901,33902,22086,19234,18479,18738,
+13388,16204,33903,14708,33904,22619,22620,13927,15425,19562,33905,33906,33907,
+33908,33909,33910,20343,33911,22621,18224,33912,33913,14672,15651,33914,33915,
+19550,33916,17994,33917,33918,33920,33921,33922,22624,33923,22622,33924,33925,
+22623,33926,33927,33928,12414,33929,15975,33930,18979,15476,33931,33932,33933,
+33934,14385,33935,33936,14446,33937,33938,33939,33940,33941,33942,33943,33944,
+33945,33946,22626,33947,15691,33948,22628,22627,33949,33950,33951,33952,33953,
+17788,33954,33955,33956,33957,33958,33959,33960,22629,33961,33962,22630,33963,
+33964,33965,33966,33967,33968,33969,16678,33970,18480,12396,14630,15443,20081,
+23357,16723,33971,33972,33973,33974,13871,22138,17708,15705,23358,23359,33975,
+33976,33977,16504,15906,16461,33978,33979,33980,33981,33982,33983,33984,33985,
+33986,33987,23360,19014,33988,33989,33990,12842,33991,33992,33993,21314,33994,
+17251,33995,20779,33996,33997,33998,33999,23362,34000,16469,34001,34002,34003,
+23363,34004,16177,34005,34006,34007,34008,34009,34010,17468,34011,34012,34013,
+34014,18266,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025,
+23364,34026,34027,34028,34029,34030,34031,34032,34033,22888,18775,34034,34035,
+34036,14644,20080,21576,34037,34038,34039,34040,12412,13394,34041,20569,34042,
+34043,34044,34045,22889,34046,24139,22891,34112,34113,34114,34115,22576,15151,
+12593,34116,13143,22606,34117,34118,21585,34119,34120,15667,16239,34121,20283,
+34122,34123,22608,34124,34125,34126,14155,34127,34128,34129,22609,34130,34131,
+34132,34133,34134,34135,34136,34137,34138,34139,17957,18296,21053,34140,34141,
+22610,17508,34142,18990,34143,18215,34144,22566,34145,18813,20071,15196,12395,
+34146,34147,34148,15146,20525,34149,12592,22372,22335,34150,13605,17012,17487,
+34151,34152,12841,34153,12855,34154,12645,24370,21820,16168,16940,22613,16945,
+34155,22612,20052,34156,23136,34157,20032,34158,34159,22580,17198,21281,20003,
+34160,15412,18484,16977,34161,15981,20534,34162,23137,34163,34164,34165,34166,
+18276,34167,34168,13095,34169,13938,19580,16506,34170,34171,16503,34172,20793,
+20833,22599,34173,34174,34176,34177,34178,34179,34180,12894,34181,34182,16485,
+34183,14961,34184,34185,22600,34186,21549,34187,34188,20321,22601,34189,22602,
+20291,34190,13176,15943,34191,34192,34193,34194,22603,34195,34196,34197,34198,
+34199,34200,34201,23372,34202,34203,34204,34205,18469,34206,34207,34208,20312,
+34209,18558,12878,34210,34211,34212,34213,34214,21334,12902,15408,21329,19243,
+14132,34215,34216,34217,14114,34218,34219,19045,34220,18465,19036,12644,20592,
+34221,17745,34222,34223,34224,23365,13694,34225,34226,16218,14661,15972,16749,
+34227,24374,24373,22075,15696,21849,12360,13859,16201,19496,24371,18999,21330,
+34228,22607,21046,14917,19262,19518,34229,24375,13680,24372,34230,34231,34232,
+21365,34233,13140,14455,34234,24378,34235,14927,15402,13685,34236,19756,17275,
+14963,16500,19778,20338,24376,20293,34237,16960,24377,17008,34238,34239,34240,
+15997,34241,16735,19788,21111,14157,24385,34242,24388,34243,34244,14193,12361,
+13910,14164,34245,14892,19581,16212,19249,18036,34246,22056,24389,34247,20066,
+13107,34248,34249,20092,13365,34250,20039,14960,34251,20065,34252,20797,34253,
+34254,24384,34255,34256,13428,34257,13130,34258,14438,24379,34259,34260,34261,
+34262,17477,34263,24380,24381,24382,17723,24383,24386,21553,24387,34264,18234,
+20056,34265,34266,34267,34268,34269,17496,34270,24394,34271,24399,34272,22108,
+34273,34274,34275,34276,34277,34278,34279,34280,24393,24410,20022,34281,14919,
+24398,24392,17758,34282,34283,18795,14964,17276,34284,34285,15959,34286,24390,
+34287,24397,34288,17752,34289,34290,34291,34292,21798,14925,34293,15948,21309,
+14400,34294,22116,34295,24391,14654,16167,34296,34297,16764,24395,24396,34298,
+24400,34299,34300,34301,34302,34368,24411,24421,34369,24407,24406,22345,24419,
+24420,25963,21031,24402,34370,16169,34371,21595,34372,16200,24404,34373,34374,
+34375,20300,34376,34377,24413,34378,20810,34379,24414,12327,17975,24403,34380,
+14949,34381,13919,19803,14718,21589,34382,34383,24415,20332,12325,24423,24401,
+20806,24405,24408,24409,24412,34384,15145,34385,24416,24417,34386,24418,24422,
+24424,21300,34387,34388,34389,34390,34391,14439,17718,24426,18778,16680,17476,
+34392,34393,16222,20344,34394,34395,34396,21852,24430,34397,34398,34399,34400,
+34401,34402,12856,34403,14943,24428,34404,23361,34405,20836,34406,34407,34408,
+34409,19316,13373,34410,12326,34411,34412,34413,34414,34415,24433,19526,24434,
+34416,34417,24429,34418,34419,34420,34421,34422,34423,24425,34424,34425,34426,
+34427,24427,34428,24431,24432,15165,34429,34430,24435,34432,34433,24436,34434,
+15139,34435,19035,20008,24615,13098,34436,24614,34437,34438,34439,24609,34440,
+34441,34442,34443,24446,34444,19801,24444,34445,24442,34446,16208,22340,34447,
+18764,34448,34449,24440,12321,34450,34451,34452,34453,34454,24445,34455,34456,
+34457,34458,24443,24610,34459,34460,34461,34462,34463,24616,34464,34465,34466,
+34467,14152,34468,34469,17953,18742,16434,24437,34470,34471,17726,34472,22596,
+24441,17526,34473,34474,34475,34476,34477,34478,24611,24612,24613,20517,34479,
+34480,24628,19556,34481,24625,34482,16166,24623,20025,24619,18758,34483,34484,
+16430,24622,14957,14896,24617,34485,34486,34487,24438,34488,24627,34489,34490,
+24632,34491,34492,34493,13357,24633,34494,34495,20274,14920,34496,24624,34497,
+34498,34499,34500,34501,34502,34503,20602,34504,34505,34506,34507,34508,34509,
+34510,34511,34512,24620,34513,21627,34514,24439,34515,17767,34516,24621,34517,
+21367,34518,24630,24631,34519,34520,34521,34522,34523,24644,20577,34524,34525,
+34526,24636,34527,34528,24649,24650,34529,34530,34531,24638,24618,18724,24641,
+34532,24626,34533,34534,34535,34536,34537,19016,24643,34538,24629,34539,20043,
+34540,19267,24653,24646,24642,34541,24651,34542,24634,24639,24640,34543,34544,
+24645,34545,34546,24647,24648,34547,24652,34548,24635,34549,34550,34551,34552,
+34553,19284,24661,34554,24662,24658,34555,34556,34557,34558,34624,34625,24656,
+15438,34626,34627,24657,34628,14402,22597,34629,34630,34631,34632,34633,34634,
+34635,34636,20586,34637,34638,17007,34639,34640,24655,24637,34641,34642,34643,
+24660,24659,34644,34645,24663,34646,34647,34648,34649,24668,24664,34650,34651,
+34652,22134,13104,34653,22380,34654,19259,34655,34656,24666,34657,20091,34658,
+34659,34660,14937,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670,
+34671,34672,24673,24669,21037,34673,34674,34675,34676,34677,24674,34678,34679,
+24667,24665,24671,34680,34681,24672,34682,34683,34684,34685,34686,24670,34688,
+24676,34689,34690,34691,18039,22572,21611,24678,19017,34692,34693,34694,34695,
+24677,34696,34697,34698,34699,14401,34700,34701,34702,34703,24679,24680,34704,
+34705,34706,34707,34708,34709,34710,34711,24681,24675,34712,34713,34714,34715,
+34716,34717,34718,14911,19559,34719,34720,34721,24682,34722,34723,34724,34725,
+34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,20345,34737,
+34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,24683,34748,34749,
+34750,34751,34752,34753,34754,18498,34755,34756,34757,34758,15680,34759,34760,
+34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,17490,34772,
+34773,34774,34775,34776,34777,34778,34779,34780,24684,34781,34782,24685,34783,
+34784,18292,19268,34785,24686,15192,22582,21106,24687,19781,34786,13914,34787,
+34788,34789,34790,34791,34792,24689,34793,21552,34794,34795,16423,13393,34796,
+34797,20007,24688,34798,34799,34800,24690,14668,34801,34802,14714,19772,24691,
+34803,34804,34805,18004,24692,34806,21554,34807,18470,24694,24693,34808,34809,
+34810,34811,34812,34813,34814,34880,34881,34882,34883,34884,34885,34886,34887,
+34888,34889,24695,34890,34891,19777,34892,34893,34894,18981,34895,34896,34897,
+34898,21594,23383,23385,34899,23384,14695,23388,23389,13656,34900,34901,23386,
+34902,34903,34904,34905,34906,23387,13089,23391,34907,34908,15224,34909,22071,
+34910,23392,34911,34912,34913,34914,15993,34915,34916,14139,34917,23376,19502,
+16178,15157,22392,16211,34918,34919,34920,34921,34922,16233,34923,34924,15457,
+19507,23390,12371,20075,14168,22329,17986,34925,34926,16420,34927,19513,34928,
+23399,23393,17978,23395,34929,23400,34930,17783,34931,34932,34933,23402,34934,
+34935,23401,16192,34936,34937,34938,23398,23397,34939,34940,34941,34942,34944,
+13369,16428,16930,23394,23396,34945,34946,34947,34948,20557,23405,34949,34950,
+34951,34952,34953,16477,23410,34954,34955,34956,34957,34958,34959,34960,13922,
+34961,34962,34963,34964,23411,23378,14648,21547,23404,34965,16209,23408,34966,
+23377,34967,13670,34968,23403,16229,34969,34970,34971,23406,34972,23409,34973,
+34974,34975,23417,34976,34977,34978,34979,34980,34981,34982,34983,34984,14625,
+12323,34985,34986,34987,34988,34989,34990,34991,17009,34992,34993,13127,23407,
+34994,34995,23416,34996,18002,23412,34997,34998,23413,23415,23414,34999,35000,
+23422,35001,21362,12858,35002,35003,35004,23421,35005,35006,35007,35008,35009,
+35010,35011,35012,23588,35013,23419,35014,35015,35016,35017,23418,35018,35019,
+35020,23420,17760,15225,35021,35022,23587,35023,35024,23589,35025,19523,35026,
+35027,35028,13905,23872,35029,35030,35031,23585,35032,23586,35033,35034,35035,
+18229,35036,35037,35038,13929,35039,35040,35041,23591,35042,35043,35044,35045,
+23590,35046,23593,12580,35047,35048,13644,35049,35050,35051,35052,35053,16176,
+35054,35055,35056,35057,35058,20831,35059,35060,35061,35062,13890,35063,35064,
+35065,35066,35067,35068,35069,35070,35136,35137,35138,35139,35140,35141,23592,
+35142,35143,35144,35145,35146,35147,35148,19322,27507,35149,35150,35151,19292,
+35152,35153,19326,35154,35155,35156,19521,35157,35158,35159,35160,35161,18555,
+35162,35163,35164,35165,35166,35167,23594,35168,35169,35170,35171,35172,19566,
+23595,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,
+35185,35186,35187,35188,35189,23379,35190,23599,23596,35191,15923,35192,19067,
+35193,35194,35195,23597,35196,35197,35198,35200,35201,35202,35203,35204,18762,
+17465,35205,35206,35207,35208,35209,18237,23598,35210,35211,35212,21622,20582,
+35213,35214,35215,35216,35217,35218,35219,35220,17451,13909,35221,35222,35223,
+35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236,
+35237,35238,23380,35239,35240,35241,35242,12634,35243,35244,35245,23381,35246,
+35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,23382,35257,35258,
+35259,14910,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270,
+35271,35272,35273,18496,35274,35275,35276,35277,35278,35279,19007,18505,35280,
+22323,35281,18809,35282,35283,16199,35284,35285,14968,35286,35287,21052,35288,
+35289,35290,35291,35292,35293,35294,35295,25146,35296,13350,35297,35298,12600,
+35299,35300,35301,35302,35303,14388,35304,20292,35305,35306,35307,35308,22887,
+20262,19810,35309,35310,22893,13920,35311,21049,35312,35313,14651,35314,35315,
+35316,35317,25145,25143,35318,13427,35319,19564,19499,14194,35320,22578,20843,
+14907,35321,18983,35322,35323,19767,35324,35325,21060,16228,15440,13921,35326,
+24133,35392,35393,35394,35395,24134,23356,35396,20825,35397,35398,18022,17486,
+14190,35399,14172,35400,35401,16252,22368,35402,18037,35403,35404,12604,24136,
+15665,19543,24138,35405,24137,35406,35407,35408,35409,35410,13676,35411,18781,
+35412,35413,12354,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,
+35424,35425,35426,17710,17707,35427,17484,35428,15465,19325,35429,35430,35431,
+14915,35432,35433,35434,25977,18535,25978,19837,35435,22321,14398,17000,35436,
+18513,35437,35438,25979,35439,35440,35441,35442,13898,15435,35443,35444,20861,
+26145,35445,17262,35446,35447,35448,35449,26148,35450,35451,35452,35453,25982,
+26149,19799,35454,35456,14145,25980,25981,26147,35457,35458,17501,26152,35459,
+35460,26151,35461,35462,35463,35464,35465,35466,17219,35467,18014,35468,35469,
+26154,35470,35471,35472,35473,35474,35475,35476,17463,35477,35478,35479,26146,
+19004,35480,35481,35482,35483,15715,14659,26150,20565,20015,35484,35485,26153,
+26160,35486,21030,35487,15658,26157,35488,35489,35490,35491,35492,26159,35493,
+16465,35494,35495,21068,35496,35497,35498,15399,35499,35500,35501,35502,35503,
+35504,35505,35506,35507,35508,35509,35510,26161,35511,21110,35512,35513,35514,
+22347,35515,19838,35516,19806,16934,26155,26156,15679,26158,26163,35517,35518,
+26162,35519,35520,35521,35522,26166,35523,26168,35524,35525,35526,35527,17519,
+35528,35529,35530,17480,35531,35532,15978,18799,35533,35534,26167,35535,13936,
+35536,35537,35538,17252,35539,35540,35541,35542,35543,35544,35545,21353,26164,
+35546,26165,35547,18466,35548,35549,35550,35551,35552,26173,35553,35554,35555,
+26169,35556,35557,35558,35559,35560,17989,35561,35562,19825,26171,35563,35564,
+35565,35566,35567,35568,35569,35570,35571,35572,26172,35573,35574,35575,35576,
+15209,35577,35578,35579,35580,35581,35582,35648,26174,35649,35650,35651,35652,
+26170,35653,35654,16439,35655,35656,35657,35658,35659,35660,35661,35662,35663,
+21284,26175,18804,26179,35664,35665,26180,35666,35667,35668,35669,20598,35670,
+35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683,
+35684,35685,35686,35687,17213,35688,35689,35690,35691,35692,35693,35694,17220,
+26178,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,
+35707,35708,26177,35709,35710,35712,35713,35714,35715,35716,26183,20273,35717,
+27508,35718,35719,26186,35720,35721,35722,35723,35724,26181,35725,35726,15454,
+18729,35727,35728,35729,35730,35731,35732,15413,35733,35734,20307,35735,35736,
+35737,35738,35739,26184,35740,26185,35741,26190,35742,26192,35743,35744,35745,
+26193,35746,35747,35748,26187,13653,35749,26188,35750,35751,26191,35752,35753,
+17499,35754,26182,35755,35756,35757,35758,35759,26189,35760,35761,35762,35763,
+35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776,
+35777,35778,35779,35780,35781,35782,26194,35783,35784,35785,35786,35787,35788,
+35789,35790,35791,35792,35793,35794,26196,26195,35795,35796,35797,35798,35799,
+35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812,
+35813,35814,35815,35816,35817,35818,35819,35820,26197,35821,22904,35822,35823,
+26198,35824,35825,35826,35827,35828,35829,35830,35831,26199,35832,35833,35834,
+35835,35836,35837,35838,35904,35905,35906,35907,35908,35909,35910,35911,22355,
+26205,35912,26206,16215,21584,35913,22358,13414,19311,26202,22595,22350,20514,
+35914,17231,35915,35916,26207,15422,14658,26203,20775,35917,35918,14882,16975,
+35919,22571,35920,35921,35922,19051,25966,35923,26204,35924,14197,35925,35926,
+35927,35928,18534,35929,35930,17525,35931,35932,25906,17534,35933,19324,25907,
+21804,35934,21358,19032,12338,35935,19278,19818,35936,35937,14954,35938,35939,
+35940,25909,35941,25908,35942,22362,14681,22118,13864,19824,21067,12582,18997,
+35943,13160,18803,16205,20603,19026,25910,15170,35944,35945,35946,20316,14636,
+35947,35948,35949,35950,21591,35951,35952,14886,20839,20348,15442,35953,25911,
+18525,35954,35955,35956,16237,12662,19294,35957,35958,15429,35959,15428,21114,
+17244,16220,35960,35961,35962,35963,14395,35964,35965,35966,17218,35968,14894,
+21538,35969,35970,35971,35972,35973,35974,35975,35976,35977,18270,17455,12908,
+35978,14673,35979,35980,25915,16712,35981,35982,21807,35983,35984,35985,35986,
+35987,25916,35988,25918,35989,35990,35991,35992,35993,35994,35995,13415,13908,
+19266,20784,13628,35996,35997,19033,35998,14178,35999,36000,18788,36001,15659,
+36002,36003,20030,22384,36004,36005,36006,36007,20513,36008,18777,36009,36010,
+13947,26200,15458,36011,13118,36012,18768,36013,26201,13090,36014,36015,36016,
+36017,24140,36018,21320,24141,36019,21026,36020,36021,36022,36023,24142,36024,
+36025,36026,36027,15949,36028,36029,24143,36030,36031,36032,18988,21116,13151,
+25962,17505,15905,20018,17522,15958,17960,12899,36033,36034,15955,36035,36036,
+18300,19563,15724,20061,36037,36038,19002,17985,25964,20540,36039,36040,36041,
+21817,36042,36043,36044,25965,36045,36046,36047,36048,19060,36049,19776,16965,
+36050,25967,36051,16964,25968,36052,36053,36054,36055,36056,36057,36058,25976,
+19789,36059,18749,36060,36061,36062,36063,36064,36065,36066,21081,24872,36067,
+36068,36069,36070,21356,36071,19306,18033,36072,36073,36074,36075,36076,24876,
+36077,36078,36079,24871,24873,36080,36081,24874,24879,36082,36083,12909,36084,
+24875,14426,24877,24878,24880,13626,24881,36085,36086,36087,36088,36089,24883,
+24888,36090,36091,36092,36093,36094,20818,36160,24886,24885,16747,36161,36162,
+36163,24887,36164,21568,36165,24882,36166,24890,12342,36167,36168,36169,36170,
+24884,36171,16249,36172,24889,36173,36174,24891,36175,36176,36177,36178,36179,
+36180,24894,36181,36182,36183,36184,36185,36186,24892,36187,36188,36189,36190,
+36191,36192,22085,36193,36194,36195,36196,36197,36198,36199,20287,36200,36201,
+24893,24895,16973,36202,13931,36203,21368,36204,36205,18253,36206,36207,14181,
+36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,15998,36218,36219,
+36220,36221,36222,36224,24896,24897,36225,36226,24903,13159,36227,36228,36229,
+36230,36231,36232,18025,36233,36234,36235,36236,36237,13406,36238,20802,36239,
+36240,36241,36242,24904,36243,36244,24902,36245,36246,36247,36248,36249,24901,
+36250,24899,24898,36251,12608,36252,36253,36254,21816,24900,36255,36256,36257,
+36258,36259,24907,36260,36261,36262,36263,36264,36265,36266,36267,24908,24906,
+36268,36269,36270,36271,36272,36273,36274,36275,28538,36276,36277,24915,24914,
+18230,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,24905,
+36289,36290,24910,36291,24912,36292,36293,36294,36295,36296,36297,36298,36299,
+36300,36301,36302,24916,36303,24913,24909,36304,36305,24911,36306,36307,36308,
+36309,24917,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320,
+36321,36322,24918,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332,
+36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,24919,
+36345,36346,36347,24920,36348,36349,36350,36416,36417,36418,36419,36420,36421,
+36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434,
+36435,36436,36437,24922,36438,36439,36440,36441,36442,36443,36444,36445,36446,
+36447,36448,36449,36450,24923,36451,36452,36453,36454,36455,36456,36457,20001,
+36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,
+26461,36471,13352,22109,36472,36473,20786,13106,36474,36475,14628,22387,18249,
+15966,14638,36476,20055,36477,36478,12910,23375,36480,15418,21073,19272,12365,
+36481,36482,20335,36483,36484,36485,36486,36487,22883,15725,36488,36489,12626,
+19024,12860,36490,19239,14123,36491,18982,36492,36493,36494,20259,36495,36496,
+24696,21834,24699,36497,36498,24698,17729,19579,36499,16689,24697,22115,12847,
+22084,13659,36500,36501,36502,36503,36504,36505,36506,36507,13432,22049,36508,
+36509,36510,36511,36512,20271,12399,36513,36514,24700,36515,36516,36517,36518,
+36519,24865,13091,36520,36521,24701,24702,17201,36522,36523,36524,36525,17245,
+36526,24866,14201,36527,36528,36529,36530,36531,36532,15183,36533,36534,36535,
+36536,36537,36538,36539,24867,17467,36540,36541,36542,36543,36544,24868,36545,
+36546,24869,36547,36548,24870,13361,36549,36550,36551,36552,36553,36554,36555,
+36556,36557,36558,36559,36560,36561,36562,36563,14409,17981,17514,36564,12834,
+36565,20562,36566,26459,15171,21335,21316,36567,14691,25167,36568,36569,36570,
+22319,36571,18284,12627,36572,36573,13362,25169,36574,36575,36576,20594,16942,
+25168,36577,16226,21286,13655,25170,13674,36578,17261,14461,36579,14382,36580,
+17747,14159,25172,36581,36582,36583,36584,25171,13896,22393,36585,36586,36587,
+36588,36589,19749,36590,36591,36592,36593,36594,25176,36595,25174,19068,16181,
+21305,25173,36596,36597,36598,36599,25175,36600,36601,36602,36603,36604,36605,
+36606,36672,36673,36674,16686,16456,36675,36676,36677,36678,36679,36680,25179,
+25178,16426,36681,36682,16718,36683,36684,36685,36686,25180,36687,36688,36689,
+36690,36691,36692,36693,36694,36695,36696,36697,36698,25181,36699,25182,36700,
+36701,36702,36703,36704,36705,36706,36707,36708,23368,36709,20819,19746,36710,
+36711,15656,36712,36713,36714,24131,22565,16170,23373,21100,18042,17706,36715,
+36716,36717,24132,36718,12631,24366,36719,36720,36721,19005,36722,24369,36723,
+14637,36724,21117,36725,14373,14955,36726,36727,13146,36728,36729,36730,13660,
+21829,36731,36732,36733,36734,17238,20306,15137,36736,25971,25970,36737,36738,
+25972,36739,19812,36740,18549,36741,36742,36743,36744,36745,36746,36747,13615,
+18239,36748,25974,36749,36750,36751,27696,36752,36753,36754,36755,36756,36757,
+36758,36759,36760,36761,36762,36763,36764,36765,36766,25958,36767,14697,13617,
+36768,16956,25960,25959,25961,36769,36770,36771,36772,21069,36773,36774,36775,
+24938,20558,36776,19758,36777,20837,36778,36779,12874,12651,36780,12658,17773,
+36781,36782,21827,21296,36783,24924,36784,36785,36786,24925,36787,21083,36788,
+13113,12619,36789,36790,36791,19833,21879,24926,36792,15926,13437,36793,24927,
+14940,24928,15154,16969,24929,36794,36795,36796,20588,36797,19773,36798,36799,
+24930,36800,13635,17735,24931,36801,36802,24932,36803,36804,36805,36806,21369,
+36807,36808,36809,36810,36811,36812,24933,36813,20781,36814,36815,24934,20002,
+36816,36817,36818,36819,36820,36821,24935,36822,13634,36823,36824,36825,36826,
+24936,15189,36827,36828,36829,36830,36831,20548,25184,12632,21092,36832,36833,
+25185,36834,36835,15433,18508,36836,25187,27774,27773,24367,36837,36838,36839,
+25186,22078,19836,17190,36840,36841,36842,25411,36843,36844,22098,25191,36845,
+36846,25192,36847,36848,21319,36849,36850,25196,16236,36851,25197,25189,36852,
+36853,13120,36854,36855,36856,17518,36857,36858,25198,36859,36860,20547,36861,
+14966,25193,14174,15155,19500,19275,25188,25190,25194,25195,36862,36928,36929,
+25207,36930,36931,25204,21621,25203,36932,36933,17709,36934,21882,17730,12864,
+36935,36936,25199,36937,25202,16687,19260,36938,36939,13601,25209,36940,36941,
+36942,15409,25201,20564,21561,25205,14678,25206,36943,36944,36945,18259,36946,
+36947,36948,36949,36950,25200,36951,36952,36953,36954,36955,22364,27937,36956,
+36957,25208,36958,27941,25214,19025,36959,36960,36961,36962,36963,36964,36965,
+16693,36966,15184,36967,36968,16214,36969,14947,36970,36971,19233,36972,36973,
+36974,27942,27939,36975,36976,27938,36977,36978,36979,36980,15190,27943,20596,
+36981,36982,27940,14942,13943,25377,13874,19569,14631,36983,20258,18209,36984,
+36985,16210,36986,36987,13937,36988,25210,25211,25213,25212,17493,25378,36989,
+21313,36990,36992,36993,25383,18244,36994,36995,36996,36997,20260,36998,36999,
+25385,14903,37000,37001,37002,37003,25384,37004,15194,37005,25379,37006,37007,
+37008,25380,25386,37009,25382,37010,20082,21318,37011,37012,15164,37013,37014,
+21571,37015,17530,37016,37017,27944,20604,25381,37018,17269,37019,25389,12591,
+37020,25394,37021,37022,37023,15426,37024,37025,25388,13631,37026,37027,37028,
+37029,37030,37031,37032,37033,18281,25392,37034,37035,37036,15914,19823,37037,
+37038,37039,37040,37041,15219,37042,37043,37044,19560,37045,37046,25391,37047,
+25393,37048,20263,25390,37049,20009,15197,37050,37051,37052,37053,37054,13675,
+15973,12882,13133,37055,12601,25387,12881,13612,14687,13928,37056,37057,20331,
+25399,37058,15180,37059,37060,18503,20554,37061,37062,37063,37064,37065,25400,
+13166,37066,37067,37068,37069,27945,37070,21370,21348,37071,37072,37073,27946,
+25401,21090,37074,37075,37076,37077,37078,25397,37079,37080,37081,37082,21342,
+37083,37084,37085,37086,14416,25395,37087,37088,25398,14175,37089,25396,16418,
+37090,37091,37092,25402,37093,37094,37095,37096,37097,37098,37099,37100,37101,
+37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,21560,37112,37113,
+37114,37115,37116,37117,37118,37184,13384,37185,25403,37186,15173,37187,18807,
+37188,37189,18789,37190,37191,37192,17469,37193,37194,37195,37196,37197,37198,
+37199,27947,37200,37201,37202,37203,17021,37204,37205,37206,37207,15195,16174,
+37208,37209,37210,37211,37212,37213,37214,20031,37215,37216,37217,37218,25404,
+37219,16182,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230,
+37231,37232,37233,37234,37235,37236,37237,37238,12655,37239,37240,21623,37241,
+37242,37243,37244,37245,25406,37246,37248,37249,37250,37251,37252,37253,37254,
+27949,37255,37256,37257,37258,37259,37260,37261,37262,37263,25407,14889,27948,
+37264,37265,25405,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275,
+25408,37276,37277,37278,37279,37280,37281,14902,37282,37283,37284,13870,37285,
+37286,37287,37288,37289,20536,37290,12355,27950,37291,37292,37293,37294,37295,
+27951,16449,37296,25409,37297,37298,37299,37300,37301,37302,37303,37304,37305,
+37306,37307,37308,37309,37310,37311,37312,37313,17715,37314,37315,37316,37317,
+37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,25410,37328,37329,
+37330,37331,37332,37333,37334,37335,37336,23602,37337,37338,37339,37340,37341,
+37342,27952,37343,14442,37344,20076,27175,20583,19065,18518,20279,13129,20050,
+15716,37345,37346,25438,15218,27176,21821,37347,18013,27177,37348,37349,37350,
+27178,37351,27180,27179,37352,27182,27181,37353,37354,37355,37356,15704,37357,
+27183,37358,16958,37359,37360,37361,37362,13377,13431,37363,37364,15143,37365,
+37366,37367,37368,37369,27750,27749,14143,19321,12642,37370,27751,37371,37372,
+37373,18760,27752,27753,37374,19030,24144,12869,21626,37440,37441,17995,12359,
+13426,18515,37442,37443,37444,19792,37445,37446,16184,37447,37448,37449,37450,
+37451,37452,37453,16219,37454,37455,18212,22068,37456,16425,24145,18728,20847,
+17700,12391,13110,18501,37457,37458,12386,37459,37460,14198,37461,37462,17786,
+37463,37464,13939,37465,21842,13136,15420,37466,37467,37468,13101,37469,37470,
+37471,37472,15985,12369,37473,37474,37475,37476,37477,37478,21078,19043,22309,
+37479,19766,13878,16185,21851,37480,14375,17751,37481,37482,37483,24146,16217,
+16981,18240,37484,15140,12584,37485,37486,17770,37487,37488,17787,19495,37489,
+37490,37491,37492,12583,37493,37494,37495,13654,37496,37497,37498,17448,37499,
+24147,20794,13161,37500,17266,37501,37502,14199,37504,22132,13603,12912,17460,
+17513,16429,24148,37505,12392,17732,16736,37506,14677,37507,15964,19800,12366,
+37508,19791,24150,15952,22334,24149,21840,12381,37509,37510,17506,37511,37512,
+16931,15472,37513,21301,16441,17697,12838,21617,37514,37515,16424,19011,24151,
+21884,37516,14640,37517,18477,19241,37518,24153,16189,37519,37520,37521,37522,
+17972,22311,18992,17475,37523,13142,14674,37524,37525,37526,37527,22072,27260,
+12340,37528,37529,37530,37531,16230,37532,37533,19572,37534,37535,37536,37537,
+19802,37538,37539,37540,22079,16974,37541,20046,19490,20526,17491,13618,24152,
+21877,15415,15187,37542,37543,12324,37544,17714,13420,37545,37546,37547,21873,
+37548,37549,27261,37550,37551,37552,37553,37554,37555,24154,19750,37556,37557,
+19820,37558,37559,37560,37561,20070,24156,37562,19761,16422,37563,37564,22333,
+37565,24155,12358,14900,18771,17523,15976,37566,37567,37568,37569,12854,37570,
+37571,37572,37573,37574,37575,37576,37577,16460,19312,37578,15473,15163,13623,
+37579,37580,37581,17781,37582,24166,37583,37584,37585,24163,15965,37586,37587,
+24159,37588,37589,37590,37591,13367,15709,37592,37593,24160,17517,37594,37595,
+37596,37597,20294,37598,13664,37599,37600,37601,37602,13918,19034,13684,24165,
+37603,21830,37604,24161,19533,18046,37605,17733,37606,37607,37608,21044,37609,
+15986,37610,37611,37612,37613,37614,37615,37616,16979,37617,19517,13112,37618,
+15699,37619,16216,19782,20826,13419,37620,24164,24157,24167,37621,27262,37622,
+37623,16944,24162,37624,37625,22080,13607,37626,12916,37627,24168,37628,24178,
+37629,37630,37696,37697,37698,24173,37699,24177,37700,37701,18528,37702,37703,
+37704,22369,24175,17256,19553,37705,12901,37706,37707,37708,21054,37709,37710,
+37711,37712,37713,37714,37715,24174,37716,24171,20053,37717,13351,37718,37719,
+37720,37721,37722,16171,15934,37723,37724,15698,37725,37726,37727,37728,24169,
+37729,21550,37730,24158,37731,24170,37732,37733,37734,37735,16447,37736,24172,
+12915,14441,16935,37737,37738,15681,37739,37740,37741,37742,37743,24181,24184,
+37744,37745,12843,13348,37746,37747,13418,18726,37748,37749,37750,37751,37752,
+37753,24182,19281,37754,14435,37755,24183,24186,37756,37757,37758,37760,24185,
+37761,37762,37763,19522,37764,12385,13422,37765,37766,37767,37768,37769,37770,
+25914,37771,37772,37773,37774,37775,20527,37776,37777,12907,37778,27425,37779,
+24180,37780,37781,18787,24179,12378,21025,12663,37782,19503,37783,37784,37785,
+37786,37787,37788,37789,24176,37790,19236,37791,37792,37793,21802,37794,37795,
+37796,37797,37798,24187,37799,37800,37801,37802,37803,37804,37805,37806,13405,
+37807,17446,37808,37809,37810,24189,37811,37812,37813,37814,37815,37816,37817,
+37818,37819,37820,17278,17441,24353,37821,37822,37823,37824,37825,37826,37827,
+16716,37828,24188,15983,37829,17970,37830,37831,37832,37833,37834,37835,37836,
+37837,37838,13125,18550,37839,37840,19258,24190,37841,37842,24356,37843,37844,
+37845,37846,22322,37847,37848,37849,37850,37851,13111,37852,37853,37854,37855,
+16707,37856,37857,18251,12837,13417,37858,22315,37859,37860,37861,37862,17516,
+37863,24354,24355,37864,24357,37865,14899,37866,37867,37868,24358,37869,16478,
+37870,37871,18755,37872,37873,37874,37875,37876,37877,37878,12889,18278,37879,
+24359,37880,18268,37881,37882,37883,37884,24360,27426,37885,37886,37952,37953,
+37954,19283,37955,37956,37957,24362,37958,24361,37959,12865,37960,37961,37962,
+37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,
+37976,37977,37978,37979,37980,37981,37982,37983,37984,17738,37985,37986,37987,
+37988,37989,37990,37991,37992,24363,37993,37994,37995,37996,37997,37998,37999,
+38000,21596,38001,38002,38003,38004,38005,18497,38006,38007,38008,38009,38010,
+38011,38012,38013,38014,38016,38017,38018,24364,38019,38020,38021,38022,38023,
+15984,38024,38025,24365,22055,38026,38027,38028,38029,27191,27446,19029,38030,
+22652,14404,38031,14629,38032,38033,14149,21886,38034,38035,38036,38037,38038,
+14666,38039,38040,20519,29773,38041,38042,13648,38043,38044,17268,38045,15944,
+38046,38047,38048,27447,12349,38049,38050,15692,38051,16690,38052,12630,13096,
+38053,38054,38055,14418,18722,38056,38057,13912,38058,38059,38060,38061,27448,
+15924,38062,38063,38064,19069,38065,18243,38066,21883,38067,38068,14195,38069,
+38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082,
+38083,20036,38084,38085,38086,21803,12659,38087,38088,38089,27699,12383,38090,
+27701,38091,38092,38093,13879,38094,16719,38095,30074,20529,38096,38097,21861,
+38098,20051,38099,38100,15727,13154,38101,14379,38102,21814,38103,27965,38104,
+13903,38105,19257,20546,38106,38107,38108,38109,38110,38111,38112,38113,14141,
+38114,38115,27702,18985,38116,38117,38118,17748,38119,27705,27704,16963,27703,
+38120,38121,38122,38123,20605,27706,38124,27707,22373,38125,38126,27708,38127,
+38128,38129,27709,18028,38130,38131,38132,38133,38134,38135,38136,38137,20062,
+38138,15432,38139,38140,18517,13609,15945,22076,21607,38141,38142,20782,20593,
+27192,27193,27194,14901,38208,38209,38210,38211,18993,16245,38212,38213,19834,
+38214,38215,38216,38217,38218,27200,38219,12346,27198,38220,38221,16421,38222,
+38223,38224,27195,38225,12925,38226,17271,15208,38227,38228,38229,21079,20084,
+27199,38230,38231,38232,27196,38233,38234,38235,27203,38236,20551,21299,38237,
+38238,38239,38240,13370,38241,17217,22386,38242,38243,38244,38245,21841,38246,
+19015,38247,27205,38248,38249,27204,27207,27206,38250,38251,38252,38253,38254,
+22119,38255,20308,38256,38257,27211,38258,15182,38259,38260,38261,38262,38263,
+38264,38265,15738,18766,38266,38267,27212,38268,38269,18745,20350,27210,21582,
+27213,27215,38270,38272,19821,38273,38274,38275,38276,27209,38277,27214,38278,
+38279,20078,38280,15198,38281,13119,38282,38283,38284,38285,38286,18005,15920,
+20090,38287,38288,38289,18279,38290,15911,27216,38291,38292,22087,38293,38294,
+38295,16704,38296,38297,38298,21597,38299,27217,38300,38301,20286,38302,38303,
+38304,38305,27218,38306,38307,38308,38309,19054,38310,38311,38312,38313,17711,
+12341,38314,38315,38316,38317,38318,27220,38319,38320,38321,38322,38323,38324,
+38325,38326,38327,27219,29791,38328,38329,38330,38331,38332,17466,38333,38334,
+38335,38336,38337,12585,38338,38339,38340,38341,25951,38342,38343,38344,38345,
+27221,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357,
+38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370,
+38371,19055,38372,27222,27223,18008,38373,38374,38375,38376,38377,38378,38379,
+38380,27224,38381,38382,27225,38383,38384,38385,38386,38387,38388,21563,38389,
+18298,21047,14460,38390,38391,27202,38392,12892,38393,38394,17020,38395,21624,
+19558,22382,38396,38397,38398,38464,38465,38466,38467,21570,21328,27459,17779,
+38468,14206,38469,38470,27476,38471,38472,38473,19255,27486,38474,16458,38475,
+38476,38477,19835,38478,13103,38479,18010,38480,38481,38482,38483,38484,38485,
+27516,38486,17470,38487,20020,17449,12606,21629,38488,19061,38489,22124,38490,
+38491,18003,13924,38492,38493,38494,38495,15226,38496,38497,20576,38498,38499,
+18737,38500,21587,18472,38501,38502,14411,38503,26686,18748,38504,38505,26683,
+38506,16494,20563,12868,13413,38507,26684,38508,38509,21832,38510,38511,38512,
+38513,38514,13893,38515,26685,19064,14428,19573,38516,38517,38518,16436,38519,
+38520,20846,26687,26690,38521,38522,14908,38523,12589,15708,38524,27197,26691,
+38525,26694,38526,26699,38528,38529,38530,38531,26700,38532,19273,12389,38533,
+15403,38534,38535,14649,38536,38537,26689,38538,19831,38539,26698,38540,38541,
+38542,38543,20086,38544,38545,38546,38547,21869,38548,16726,26692,38549,17206,
+38550,14715,22054,26696,38551,38552,38553,19040,21606,38554,26688,38555,26693,
+26695,38556,18233,14179,38557,26697,38558,16221,26706,38559,38560,26711,38561,
+26709,15452,15439,26715,38562,38563,38564,38565,38566,38567,38568,38569,26718,
+38570,26714,12666,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580,
+12376,17459,14412,18018,18494,18529,38581,38582,38583,26703,26708,26710,38584,
+14705,26712,22389,38585,17531,38586,26716,38587,38588,12905,38589,38590,38591,
+26705,38592,38593,15469,38594,38595,16194,26701,22137,38596,16760,12913,38597,
+38598,38599,38600,38601,38602,38603,38604,26719,38605,19009,26713,38606,38607,
+38608,38609,21796,38610,12650,21819,26702,26704,13872,26707,38611,26717,16440,
+38612,19063,38613,19240,38614,38615,18012,16501,38616,38617,38618,38619,38620,
+26729,38621,38622,38623,20515,38624,38625,38626,38627,38628,38629,38630,26738,
+22122,38631,38632,38633,38634,38635,38636,38637,26720,26721,38638,38639,38640,
+20857,14923,14457,38641,38642,14449,21588,26735,38643,26734,26732,14704,19538,
+26726,20006,16242,38644,12344,26737,26736,38645,22336,38646,26724,38647,19753,
+18723,38648,15160,15707,26730,38649,38650,38651,38652,38653,38654,38720,38721,
+38722,38723,26722,26723,26725,13621,26727,18245,26731,26733,15664,22318,38724,
+26744,38725,38726,38727,38728,38729,38730,38731,38732,26741,38733,19760,26742,
+38734,38735,38736,38737,38738,38739,38740,38741,38742,16698,38743,26728,38744,
+17207,12400,38745,38746,38747,38748,38749,38750,38751,38752,26740,38753,38754,
+38755,26743,38756,38757,38758,14627,38759,38760,38761,38762,38763,38764,38765,
+38766,38767,38768,18770,38769,38770,38771,17230,20064,16486,38772,38773,38774,
+38775,19315,38776,19549,20533,38777,38778,19041,38779,26739,38780,38781,38782,
+38784,38785,38786,38787,38788,38789,38790,15468,38791,26745,38792,38793,38794,
+38795,38796,38797,17246,38798,18021,38799,14711,38800,38801,38802,38803,12404,
+38804,38805,22360,38806,38807,15404,38808,17775,38809,38810,38811,38812,38813,
+19524,38814,38815,26918,38816,38817,38818,38819,38820,38821,38822,38823,38824,
+38825,18733,38826,26914,16482,38827,38828,38829,16195,38830,38831,38832,26750,
+14679,38833,26747,38834,38835,38836,38837,26916,38838,38839,38840,21070,38841,
+38842,38843,38844,38845,26915,38846,22066,22325,38847,26919,38848,15671,38849,
+38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,26748,26749,
+38861,38862,38863,26913,38864,38865,38866,38867,38868,38869,38870,38871,19798,
+38872,38873,21036,38874,38875,38876,26930,38877,38878,38879,38880,26921,38881,
+38882,38883,13354,38884,13371,38885,38886,26923,38887,38888,38889,38890,38891,
+38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,20520,
+38904,38905,26917,38906,38907,13182,38908,38909,26924,16483,38910,26922,38976,
+38977,26937,38978,38979,26936,38980,38981,38982,38983,26926,38984,38985,26746,
+38986,38987,26920,38988,38989,38990,38991,38992,16172,26929,26938,38993,38994,
+16933,38995,38996,38997,26927,38998,14405,38999,26925,39000,21340,26932,26933,
+26935,39001,39002,39003,26951,39004,39005,39006,39007,39008,39009,16454,26949,
+39010,39011,26928,39012,39013,26939,12401,39014,39015,39016,39017,39018,39019,
+39020,39021,39022,39023,26940,21797,39024,39025,26942,39026,26943,39027,39028,
+39029,26945,39030,39031,16753,39032,39033,18486,39034,39035,39036,26941,39037,
+39038,39040,39041,39042,26946,39043,39044,39045,39046,39047,39048,39049,39050,
+26947,39051,26931,39052,26934,39053,15153,39054,39055,39056,26944,39057,39058,
+39059,39060,39061,39062,15479,39063,39064,39065,26948,26950,39066,39067,39068,
+39069,39070,39071,39072,39073,39074,39075,39076,39077,26954,39078,39079,39080,
+39081,26958,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,12891,
+39092,26952,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,14126,
+39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,26955,
+26956,39115,39116,39117,39118,39119,39120,21825,39121,17443,39122,39123,39124,
+39125,39126,39127,26968,39128,14945,39129,39130,39131,39132,26953,39133,21283,
+39134,39135,39136,26964,39137,39138,39139,39140,39141,39142,39143,26967,26960,
+39144,39145,39146,39147,39148,26959,39149,39150,18241,39151,39152,39153,39154,
+39155,39156,39157,39158,26962,39159,39160,39161,39162,39163,39164,39165,26969,
+13128,39166,26963,39232,39233,39234,39235,39236,20336,39237,39238,39239,26957,
+39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,13175,39251,
+39252,39253,39254,39255,39256,39257,26966,39258,39259,26970,39260,39261,39262,
+19508,39263,39264,39265,20269,39266,39267,39268,39269,39270,39271,39272,39273,
+39274,26965,39275,26972,26971,39276,39277,39278,39279,39280,26974,39281,39282,
+39283,39284,39285,39286,39287,39288,26961,39289,39290,39291,39292,39293,39294,
+39296,39297,26973,39298,26975,17226,39299,39300,39301,39302,39303,39304,39305,
+39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318,
+39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,
+39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344,
+39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,
+39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,
+39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,
+39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,
+39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,
+39410,39411,39412,39413,18231,13390,15158,20544,27683,39414,39415,17719,39416,
+39417,39418,39419,39420,39421,39422,39488,39489,39490,21371,39491,39492,39493,
+39494,27684,39495,27685,18011,39496,39497,39498,16238,39499,39500,39501,39502,
+27686,39503,39504,27687,20522,39505,18232,39506,39507,14440,39508,39509,39510,
+39511,39512,39513,39514,39515,39516,39517,39518,39519,27688,39520,39521,39522,
+39523,39524,39525,39526,39527,22073,21885,13387,12861,20068,18023,39528,39529,
+19809,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541,
+39542,39543,13429,39544,19264,15455,39545,39546,39547,39548,26978,26979,20842,
+26981,39549,13433,26980,39550,20787,19042,12880,39552,26984,39553,39554,39555,
+39556,26982,26983,39557,39558,22067,39559,39560,39561,26985,26986,39562,39563,
+39564,39565,39566,26987,39567,39568,39569,39570,39571,39572,39573,39574,26988,
+39575,39576,39577,39578,39579,39580,39581,39582,27695,17721,13902,39583,21107,
+39584,39585,39586,39587,39588,39589,39590,13678,39591,15193,27697,39592,39593,
+21091,39594,39595,39596,39597,39598,20067,39599,17464,39600,17215,39601,39602,
+13886,22585,12616,12623,12625,17790,39603,12624,39604,17195,39605,39606,39607,
+39608,39609,21809,39610,39611,39612,39613,39614,39615,39616,39617,27428,14913,
+39618,39619,39620,19514,39621,39622,39623,27429,39624,27431,39625,39626,39627,
+27432,39628,39629,39630,27430,39631,39632,39633,39634,39635,39636,39637,27433,
+27435,27434,39638,39639,39640,39641,39642,27436,39643,19023,22581,17265,39644,
+17189,18040,27437,17482,39645,27438,27439,27440,14165,39646,39647,39648,14202,
+39649,27441,18274,39650,27443,39651,14884,20853,12337,27442,27444,39652,39653,
+39654,13610,16968,18280,39655,27445,39656,19246,25439,39657,39658,21312,39659,
+39660,39661,39662,22875,39663,39664,19745,22061,18291,39665,39666,39667,22880,
+15203,39668,14906,25442,39669,39670,39671,39672,39673,20267,39674,39675,39676,
+25440,18759,39677,14905,39678,39744,39745,20788,25441,18538,14639,15661,13144,
+20059,39746,39747,19520,39748,39749,39750,25448,25449,19828,39751,39752,39753,
+39754,39755,19501,39756,15411,39757,25450,39758,25451,39759,39760,20570,39761,
+39762,39763,18043,14170,39764,39765,18271,21066,20054,39766,25444,25452,39767,
+18802,13121,39768,39769,25447,39770,39771,18019,25445,39772,39773,27955,25446,
+39774,39775,39776,39777,18739,39778,17766,39779,39780,39781,14645,39782,17211,
+39783,25443,17725,16676,16985,12887,39784,25453,15142,17453,39785,25456,15962,
+39786,39787,25467,25461,14931,39788,39789,39790,39791,14160,21325,39792,22094,
+21843,14657,21812,20824,39793,39794,39795,39796,20537,18294,39797,39798,39799,
+18474,12852,39800,17242,39801,39802,39803,25454,39804,39805,25468,25455,14120,
+25463,25460,39806,39808,39809,14138,39810,39811,17698,39812,25462,17757,12840,
+18044,39813,17504,39814,39815,22306,39816,16481,25465,39817,39818,25466,25469,
+19497,25459,39819,21310,39820,12611,27956,25457,25458,39821,25464,20538,17987,
+21619,25470,39822,39823,15712,39824,39825,25639,39826,39827,25638,39828,39829,
+39830,20851,25635,39831,25641,39832,39833,39834,18551,39835,39836,39837,39838,
+20276,39839,25640,25646,16997,39840,39841,13876,39842,39843,39844,39845,39846,
+39847,15730,39848,25634,39849,39850,14953,25642,39851,39852,25644,39853,39854,
+13949,22110,25650,39855,25645,39856,39857,39858,25633,39859,15214,19805,18210,
+17737,39860,39861,16759,39862,25636,39863,18227,15660,15677,25637,39864,22343,
+12898,39865,25643,15427,25647,39866,15211,25648,17704,25649,39867,39868,39869,
+39870,21859,16163,39871,25658,39872,25655,39873,25659,39874,39875,25661,39876,
+39877,18006,39878,39879,14918,16459,39880,39881,39882,14369,25652,39883,39884,
+39885,39886,21537,39887,39888,14883,15742,39889,39890,39891,25660,39892,39893,
+39894,39895,39896,19775,39897,39898,17529,39899,39900,20347,18790,39901,39902,
+21311,39903,20305,39904,39905,25651,39906,25656,25657,19561,39907,39908,39909,
+39910,39911,19534,39912,16468,25653,16688,25654,20048,39913,15169,13651,39914,
+18547,15655,21831,18732,14370,25674,39915,39916,25676,20804,39917,39918,21050,
+39919,39920,14893,39921,39922,14932,39923,39924,39925,39926,39927,39928,25667,
+13677,39929,39930,39931,22349,25664,20349,25663,39932,39933,39934,16732,19530,
+40000,40001,40002,40003,19047,40004,40005,40006,40007,17495,40008,19540,25672,
+40009,40010,40011,25671,25665,40012,25668,13613,40013,40014,21337,40015,25670,
+40016,40017,40018,40019,21113,13411,40020,15156,40021,40022,18798,40023,13374,
+40024,40025,40026,15212,40027,20813,40028,19565,27957,40029,40030,40031,40032,
+40033,40034,40035,40036,18277,40037,40038,40039,40040,21544,40041,25675,22357,
+25666,40042,15653,25669,40043,40044,21350,40045,25673,18808,40046,40047,25662,
+40048,40049,21349,40050,40051,18302,13897,40052,21628,12851,25687,40053,40054,
+40055,20034,40056,25677,40057,20028,40058,14427,40059,40060,25686,40061,16202,
+40062,40064,40065,21326,40066,17260,40067,40068,40069,40070,40071,40072,40073,
+40074,17736,25688,40075,40076,40077,40078,40079,40080,40081,40082,19780,25679,
+40083,40084,40085,40086,25684,25685,40087,14974,40088,20326,40089,40090,21823,
+40091,40092,40093,25682,40094,40095,40096,40097,40098,40099,40100,40101,40102,
+40103,40104,25680,40105,40106,25678,40107,40108,40109,40110,40111,40112,40113,
+40114,40115,40116,40117,40118,40119,40120,40121,19813,18986,40122,40123,40124,
+16419,40125,15654,25683,40126,40127,14408,40128,40129,40130,40131,40132,25703,
+21556,40133,40134,40135,40136,40137,40138,40139,25691,40140,40141,40142,16751,
+40143,40144,25705,40145,40146,21095,40147,40148,25695,40149,25696,40150,40151,
+20266,40152,40153,40154,40155,19293,40156,25690,25681,40157,25701,40158,18524,
+25699,40159,40160,17511,25698,40161,25697,40162,40163,40164,13180,25704,40165,
+40166,40167,40168,13665,40169,40170,40171,22348,40172,40173,40174,25702,40175,
+15148,40176,22354,19535,27512,40177,25700,40178,40179,14710,40180,40181,40182,
+22093,25689,25692,17018,25694,40183,16971,16452,16976,40184,12661,19506,40185,
+40186,40187,40188,40189,40190,40256,40257,40258,40259,13646,40260,40261,40262,
+40263,25711,40264,40265,40266,40267,40268,40269,40270,40271,17967,40272,40273,
+40274,18017,40275,40276,25717,40277,40278,40279,40280,40281,16937,40282,40283,
+40284,16492,20829,25710,40285,40286,40287,40288,40289,40290,40291,40292,40293,
+40294,17454,40295,40296,40297,25709,40298,40299,40300,40301,25718,25716,17022,
+40302,25693,40303,25712,40304,19070,40305,21828,40306,40307,25713,40308,40309,
+40310,40311,40312,40313,40314,20858,40315,40316,40317,40318,40320,40321,40322,
+25707,25708,40323,40324,40325,25714,40326,20011,40327,40328,40329,40330,40331,
+40332,40333,40334,40335,40336,17739,40337,40338,40339,18225,40340,16954,40341,
+40342,40343,25706,40344,40345,40346,16714,40347,40348,40349,40350,40351,40352,
+19510,13105,40353,40354,40355,25723,40356,25715,40357,40358,40359,25722,40360,
+25725,40361,25724,40362,40363,40364,40365,40366,40367,40368,13134,40369,40370,
+40371,13114,25719,40372,40373,25721,25720,17772,40374,40375,40376,40377,40378,
+40379,40380,40381,40382,40383,40384,40385,40386,16445,40387,40388,40389,40390,
+21608,40391,40392,40393,40394,40395,25890,40396,40397,40398,40399,40400,40401,
+40402,40403,40404,40405,40406,12356,40407,40408,25892,40409,40410,25891,40411,
+40412,40413,40414,40415,40416,15396,40417,25893,40418,40419,40420,40421,40422,
+40423,25889,40424,40425,40426,40427,40428,40429,40430,25726,12660,40431,40432,
+40433,40434,40435,40436,40437,40438,40439,40440,40441,25896,40442,25897,25894,
+40443,40444,40445,40446,40512,40513,40514,40515,40516,40517,40518,40519,25895,
+25898,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531,
+40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544,
+40545,40546,40547,40548,40549,40550,40551,40552,18009,40553,40554,40555,40556,
+40557,40558,40559,40560,25899,25901,40561,40562,40563,40564,40565,40566,40567,
+25900,40568,40569,40570,40571,40572,40573,40574,40576,40577,40578,40579,40580,
+40581,40582,40583,40584,40585,25903,40586,40587,40588,25902,40589,40590,40591,
+40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604,
+40605,40606,14688,40607,40608,25904,40609,40610,40611,40612,40613,40614,40615,
+40616,40617,40618,40619,40620,40621,40622,25905,40623,40624,40625,40626,40627,
+40628,40629,40630,40631,40632,40633,40634,15216,27745,17264,40635,13638,15186,
+40636,40637,40638,40639,16745,21614,40640,15940,40641,40642,40643,22342,40644,
+21590,12883,27710,40645,40646,40647,40648,27201,40649,40650,40651,16943,13366,
+40652,40653,40654,20823,40655,40656,40657,13108,40658,18482,16187,27712,40659,
+40660,22091,40661,40662,27711,27713,40663,40664,40665,40666,40667,40668,40669,
+40670,40671,40672,40673,40674,40675,27717,15974,19519,17754,15932,40676,27718,
+40677,12670,40678,40679,40680,27716,21800,13667,40681,27714,16694,13155,40682,
+40683,27715,19256,16451,19582,40684,40685,40686,40687,16722,40688,27720,40689,
+40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,14950,
+16467,40702,22130,40768,40769,40770,20812,40771,40772,40773,40774,16190,40775,
+14131,18773,27719,15202,40776,19532,15741,18504,40777,20265,40778,40779,40780,
+40781,40782,40783,40784,19817,40785,17771,40786,40787,40788,14185,40789,40790,
+40791,40792,40793,40794,40795,40796,40797,40798,40799,20809,14904,40800,40801,
+40802,40803,40804,27721,40805,40806,27722,40807,15168,27723,40808,27746,12602,
+14169,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,15673,
+40820,40821,40822,40823,40824,40825,40826,40827,27724,20838,27725,40828,40829,
+40830,40832,18491,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842,
+40843,40844,40845,40846,27729,40847,40848,40849,40850,27731,40851,15181,40852,
+15461,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864,
+40865,27727,40866,18743,40867,40868,40869,40870,40871,17210,40872,27747,21845,
+27728,40873,40874,40875,40876,40877,22131,40878,40879,40880,27730,27726,40881,
+40882,40883,40884,27732,40885,27733,40886,40887,18751,40888,40889,40890,40891,
+40892,40893,20264,40894,40895,40896,40897,40898,20572,40899,40900,40901,40902,
+20780,40903,40904,40905,40906,18523,40907,40908,40909,27734,20085,40910,40911,
+40912,40913,40914,19052,27738,40915,40916,40917,40918,40919,40920,40921,27737,
+40922,40923,40924,12350,40925,40926,40927,40928,40929,40930,27735,40931,27736,
+40932,40933,40934,27748,40935,40936,40937,40938,40939,40940,40941,40942,40943,
+18492,40944,40945,40946,40947,40948,40949,40950,40951,40952,40953,16711,40954,
+40955,40956,40957,40958,27740,20832,41024,41025,41026,41027,41028,41029,41030,
+41031,41032,41033,27739,41034,41035,41036,41037,21615,41038,27741,41039,41040,
+41041,41042,41043,41044,23366,41045,41046,41047,41048,41049,41050,41051,41052,
+41053,41054,27742,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064,
+41065,41066,12588,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076,
+41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41088,41089,27743,
+41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,27744,41100,22310,
+41101,17728,41102,41103,41104,27452,12334,41105,41106,41107,15988,14392,21039,
+12374,13689,41108,22579,41109,19244,41110,25437,41111,41112,41113,41114,41115,
+41116,41117,17964,12390,41118,41119,41120,17734,27449,41121,41122,41123,41124,
+27450,41125,41126,41127,27451,41128,41129,20800,41130,17699,41131,27250,41132,
+17458,41133,17461,16462,41134,41135,41136,27251,17473,41137,20079,41138,41139,
+41140,41141,27248,27252,41142,41143,18812,41144,41145,18211,41146,41147,41148,
+19544,20094,41149,41150,41151,27253,27254,20268,16487,41152,41153,27255,41154,
+41155,41156,41157,41158,13887,27256,41159,27257,41160,27258,41161,41162,27259,
+41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,27249,
+41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,18478,
+24939,41187,14136,24940,41188,41189,41190,24941,41191,22324,24942,24943,21324,
+41192,41193,41194,41195,41196,41197,41198,24945,16241,24944,13650,41199,41200,
+41201,12599,41202,41203,41204,41205,24947,24946,41206,14972,41207,24948,41208,
+41209,41210,41211,14647,41212,15953,41213,41214,43584,43585,17532,43586,14941,
+15686,43587,43588,43589,43590,43591,43592,24949,24951,43593,43594,13888,20289,
+18984,24950,21880,21372,24952,24956,24953,43595,43596,24954,16490,43597,24958,
+25121,16455,43598,43599,43600,43601,24955,43602,24957,43603,43604,43605,43606,
+43607,43608,25125,43609,43610,43611,16724,43612,43613,43614,43615,25123,43616,
+25128,12926,25122,43617,43618,43619,17229,12866,25127,25126,43620,43621,25124,
+25129,43622,43623,25131,43624,43625,43626,20553,22125,17192,25132,43627,20311,
+43628,43629,25134,43630,43631,14959,43632,43633,26976,25133,25130,43634,43635,
+43636,43637,15147,21555,43638,43639,43640,43641,43642,43643,43644,43645,43646,
+43648,43649,43650,43651,25136,43652,43653,25135,43654,26977,43655,43656,43657,
+43658,25137,43659,43660,43661,43662,43663,43664,43665,43666,25138,43667,43668,
+43669,43670,43671,43672,43673,43674,43675,43676,43677,25139,19489,43678,25140,
+43679,43680,43840,43841,43842,43843,43844,43845,43846,43847,43848,43849,43850,
+43851,25141,43852,43853,43854,43855,43856,20606,43857,43858,16970,43859,21361,
+43860,19829,43861,43862,26464,43863,43864,26465,43865,43866,43867,43868,15937,
+43869,43870,43871,43872,17002,43873,43874,43875,26468,43876,43877,26467,43878,
+43879,43880,43881,43882,43883,19814,43884,17205,43885,43886,26466,15159,20310,
+43887,16737,26473,43888,43889,43890,26472,43891,43892,26484,12835,43893,43894,
+43895,43896,26474,43897,26470,43898,43899,43900,43901,43902,26476,26475,18746,
+43904,43905,21860,43906,26469,14121,26471,43907,43908,43909,43910,43911,43912,
+43913,26478,43914,43915,43916,43917,26483,43918,22121,43919,43920,43921,43922,
+26477,43923,26482,43924,26481,43925,43926,43927,12384,43928,43929,43930,43931,
+26485,43932,43933,43934,43935,43936,44096,44097,44098,44099,44100,44101,44102,
+44103,44104,44105,44106,18290,44107,16453,16493,44108,44109,16752,26480,44110,
+44111,44112,44113,26486,19318,44114,44115,44116,44117,44118,44119,44120,44121,
+44122,26658,26657,44123,44124,44125,44126,44127,44128,22337,44129,44130,26490,
+26489,44131,26491,44132,26487,44133,26494,44134,26493,44135,26492,44136,44137,
+16725,18265,17789,17731,44138,44139,44140,44141,44142,18285,44143,44144,44145,
+44146,26659,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157,
+44158,44160,44161,44162,44163,44164,44165,44166,26662,44167,26661,44168,26663,
+14967,26488,26660,44169,18544,18730,44170,44171,44172,44173,44174,44175,44176,
+44177,44178,44179,44180,44181,44182,26665,44183,44184,14693,44185,44186,44187,
+44188,44189,20862,26664,44190,44191,44192,44352,44353,44354,26666,44355,26669,
+26670,44356,16679,44357,44358,44359,26671,44360,44361,44362,26672,44363,44364,
+26668,44365,26676,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375,
+44376,26667,44377,26673,44378,44379,44380,44381,44382,44383,44384,44385,26677,
+26674,26675,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396,
+44397,44398,44399,44400,44401,26679,44402,44403,44404,44405,44406,44407,44408,
+44409,44410,44411,44412,44413,44414,44416,44417,44418,44419,44420,44421,44422,
+44423,44424,44425,26678,44426,44427,44428,44429,44430,44431,44432,44433,44434,
+14671,44435,28716,44436,28717,44437,17968,12394,18495,44438,19807,44439,44440,
+44441,44442,44443,44444,44445,20045,27185,44446,44447,44448,44608,27186,44609,
+17983,13385,44610,44611,44612,44613,44614,44615,44616,27187,44617,44618,44619,
+44620,21863,44621,44622,44623,44624,44625,44626,44627,44628,23929,44629,27188,
+44630,27189,44631,27190,44632,44633,44634,44635,14410,24368,18805,44636,19568,
+44637,44638,18810,44639,44640,44641,44642,44643,18811,44644,44645,21315,19238,
+44646,14374,28718,12610,44647,25912,19567,21321,15447,18794,44648,13671,44649,
+17488,13673,44650,28206,15149,44651,44652,26462,44653,28207,44654,44655,44656,
+44657,13097,44658,44659,28210,44660,44661,28209,15719,44662,28208,20023,44663,
+44664,44665,44666,17743,44667,44668,44669,44670,16756,23374,28211,20595,44672,
+44673,44674,44675,44676,44677,44678,44679,16980,18024,44680,44681,44682,14124,
+44683,44684,44685,44686,44687,44688,44689,28212,44690,13163,44691,44692,44693,
+15227,28213,44694,44695,44696,44697,44698,26460,44699,44700,44701,28214,44702,
+44703,15662,44704,44864,44865,44866,29026,44867,44868,44869,19048,44870,21065,
+28762,44871,28763,44872,28764,16710,44873,14445,15950,44874,44875,28766,44876,
+17713,28765,20849,44877,28768,12364,15722,44878,44879,44880,44881,44882,21087,
+28767,44883,13359,14184,28774,28773,17955,28769,28770,13379,44884,44885,28771,
+21870,44886,44887,19547,15954,15410,44888,44889,44890,28776,28775,28772,12833,
+44891,22050,21304,15927,18476,44892,44893,28778,44894,44895,44896,44897,20855,
+44898,22092,14939,28777,44899,13883,44900,44901,19764,44902,44903,17958,44904,
+44905,44906,16673,28779,28782,44907,28781,28784,28780,44908,15166,28783,44909,
+44910,44911,44912,19509,28786,44913,44914,13141,44915,44916,44917,44918,12628,
+44919,44920,28787,44921,44922,28788,28790,13409,44923,28785,44924,28791,44925,
+44926,44928,44929,28794,44930,28792,44931,44932,44933,28789,44934,44935,44936,
+44937,28797,44938,28793,28796,28798,44939,28961,44940,44941,44942,20033,28964,
+44943,28963,44944,16758,28795,19037,44945,44946,13425,12657,19505,44947,28966,
+44948,44949,28967,44950,44951,28972,21838,28969,44952,44953,18483,44954,44955,
+44956,28962,44957,28971,28968,28965,44958,44959,28970,44960,45120,45121,45122,
+45123,45124,45125,45126,12329,28973,45127,45128,45129,45130,45131,45132,28975,
+45133,28977,45134,45135,45136,45137,45138,28976,45139,28974,45140,45141,45142,
+45143,20770,45144,45145,45146,45147,45148,45149,45150,28978,45151,45152,45153,
+28979,45154,45155,45156,45157,45158,45159,45160,45161,14703,45162,45163,13639,
+45164,12375,12377,45165,45166,45167,21613,45168,13636,45169,15700,15178,28711,
+45170,45171,14430,45172,45173,28712,45174,45175,12328,45176,28713,45177,45178,
+19822,45179,45180,28714,45181,45182,45184,45185,45186,45187,45188,45189,45190,
+45191,28715,45192,45193,45194,45195,45196,45197,45198,45199,45200,17956,45201,
+45202,22117,29028,45203,29029,45204,45205,45206,45207,45208,45209,45210,45211,
+45212,45213,17267,45214,45215,21339,45216,45376,22097,17768,45377,21295,45378,
+21094,45379,45380,28225,12347,21813,20814,15456,14928,45381,16248,45382,14407,
+13633,17740,45383,45384,18978,45385,45386,45387,17227,45388,45389,45390,45391,
+45392,28226,45393,45394,45395,45396,45397,45398,45399,45400,17471,13858,45401,
+28012,17188,45402,22065,45403,45404,45405,20320,28015,45406,45407,17742,45408,
+13916,45409,45410,18977,45411,45412,28013,45413,45414,28016,28017,17212,45415,
+16180,45416,28014,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,
+45427,28020,28018,45428,45429,45430,45431,21862,17247,45432,28019,45433,45434,
+45435,28022,45436,21795,20771,45437,45438,45440,28021,45441,17232,45442,45443,
+45444,45445,45446,28023,16244,15980,28024,45447,19575,45448,20827,45449,45450,
+45451,22341,21878,45452,28028,45453,45454,45455,28027,45456,45457,45458,45459,
+45460,45461,45462,45463,28025,28026,45464,45465,45466,45467,45468,45469,45470,
+45471,28029,15910,45472,45632,45633,45634,45635,19247,28193,13885,45636,28194,
+17472,45637,28030,45638,45639,15710,12871,45640,45641,45642,45643,45644,45645,
+45646,45647,45648,45649,45650,45651,13891,45652,45653,45654,28197,22586,28195,
+28198,45655,45656,45657,17257,13170,45658,45659,45660,45661,45662,45663,28199,
+28196,20281,45664,45665,28200,17015,45666,45667,45668,45669,45670,45671,45672,
+45673,45674,45675,45676,45677,28201,28202,45678,24107,45679,45680,17971,45681,
+18246,45682,22133,13641,45683,19250,45684,45685,45686,28203,45687,45688,19755,
+45689,28204,45690,45691,45692,45693,45694,21808,45696,28205,45697,30276,45698,
+45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,23367,
+45711,45712,45713,45714,45715,45716,45717,45718,45719,13347,45720,45721,45722,
+17196,29030,45723,45724,45725,45726,45727,19000,21075,45728,22058,45888,28530,
+45889,15960,45890,15683,28531,13900,12331,45891,45892,45893,45894,18991,45895,
+45896,27958,45897,27959,45898,45899,45900,45901,20089,14127,16243,27960,17003,
+18736,45902,45903,45904,45905,45906,45907,27961,45908,45909,18038,16179,45910,
+45911,45912,27964,17784,45913,20816,45914,22313,27962,27963,45915,20834,45916,
+27967,27968,45917,27972,45918,45919,45920,27976,45921,27974,27982,21864,45922,
+27977,45923,45924,27975,27966,45925,45926,17769,45927,45928,45929,17990,45930,
+45931,18793,21586,27969,27970,27971,27973,45932,16505,45933,13345,45934,45935,
+45936,45937,14696,45938,27984,45939,45940,45941,45942,27985,45943,27978,45944,
+27983,45945,20088,45946,45947,19254,27980,27981,45948,45949,45950,45952,45953,
+20341,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965,
+27986,16754,21298,27979,18487,45966,45967,45968,45969,45970,45971,45972,45973,
+15471,45974,45975,45976,45977,17776,45978,45979,45980,45981,45982,45983,45984,
+46144,46145,46146,27990,46147,13679,46148,46149,16949,12333,19305,46150,46151,
+12590,46152,27988,46153,46154,46155,19819,13666,46156,27989,27987,27991,46157,
+46158,13690,46159,27992,46160,27993,46161,27996,46162,12620,46163,46164,46165,
+46166,46167,46168,46169,46170,17782,15470,27994,19516,12906,46171,46172,46173,
+46174,27995,46175,46176,46177,46178,17515,46179,46180,13381,46181,46182,46183,
+12405,46184,46185,46186,27999,16474,13416,46187,46188,46189,46190,17741,46191,
+46192,46193,27997,16196,46194,46195,46196,27998,46197,46198,46199,46200,46201,
+46202,46203,46204,46205,46206,46208,46209,46210,46211,17445,46212,46213,46214,
+28000,46215,46216,46217,46218,46219,28001,46220,28003,46221,46222,16727,46223,
+46224,15175,46225,46226,46227,46228,46229,46230,15672,46231,46232,46233,28002,
+46234,46235,46236,46237,46238,46239,46240,46400,46401,46402,46403,46404,46405,
+28004,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,28006,46416,
+46417,46418,46419,46420,28005,46421,46422,46423,46424,46425,46426,46427,46428,
+46429,46430,46431,46432,46433,46434,46435,28007,46436,46437,46438,46439,46440,
+19006,27754,16497,46441,18791,46442,27755,18030,46443,46444,46445,46446,27756,
+46447,18029,27757,46448,46449,46450,46451,46452,46453,46454,46455,46456,27760,
+46457,46458,22374,27763,46459,46460,27761,27758,27759,22307,18801,19310,27764,
+46461,27762,46462,46464,20329,46465,27766,17969,46466,46467,46468,46469,15424,
+46470,27765,46471,46472,46473,46474,46475,46476,46477,13627,15222,46478,27767,
+46479,46480,46481,46482,46483,22903,15739,46484,46485,16955,27768,46486,46487,
+46488,46489,27769,46490,46491,46492,46493,14371,46494,46495,46496,46656,46657,
+46658,46659,46660,46661,46662,27770,46663,46664,46665,46666,46667,46668,46669,
+46670,46671,46672,46673,46674,27771,46675,46676,46677,46678,46679,46680,46681,
+46682,46683,46684,46685,27772,46686,46687,46688,46689,46690,21357,22574,16491,
+46691,18269,14924,46692,20579,19261,46693,19770,46694,46695,14417,46696,46697,
+12668,46698,18287,46699,22102,46700,46701,46702,16198,17259,46703,46704,28533,
+46705,46706,17240,46707,46708,46709,46710,46711,46712,22370,46713,46714,46715,
+28535,13139,46716,18264,20845,46717,22088,46718,28536,46720,28534,46721,15229,
+13126,46722,46723,46724,46725,46726,46727,46728,15701,46729,46730,21062,46731,
+15200,46732,46733,20257,46734,28540,28539,46735,46736,28537,46737,46738,46739,
+46740,13132,46741,18772,19248,46742,46743,46744,46745,46746,28542,46747,46748,
+12382,46749,46750,22089,46751,46752,46912,28541,46913,13165,46914,46915,30293,
+46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928,
+46929,46930,20040,46931,46932,46933,28706,46934,28705,46935,13630,15450,15228,
+46936,14437,46937,46938,46939,46940,46941,46942,17474,46943,46944,46945,46946,
+46947,46948,46949,46950,46951,46952,28707,46953,46954,46955,46956,46957,19307,
+46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970,
+46971,46972,46973,46974,46976,46977,46978,46979,46980,46981,46982,28710,46983,
+46984,46985,20776,46986,15935,18286,28982,28983,16213,46987,46988,46989,46990,
+13353,28984,19771,46991,18260,21805,46992,28985,46993,28986,46994,46995,46996,
+46997,18255,46998,46999,47000,21028,22095,47001,47002,28987,15697,13360,15933,
+47003,47004,47005,13404,20049,47006,16223,28989,47007,47008,47168,47169,16250,
+28988,47170,28991,47171,47172,47173,28990,28992,47174,47175,47176,47177,47178,
+28993,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,16766,
+47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,16674,47201,
+47202,47203,47204,47205,47206,47207,47208,47209,47210,19066,47211,47212,21822,
+47213,47214,47215,47216,15930,15929,21826,47217,47218,16162,47219,19759,28981,
+47220,47221,47222,47223,47224,47225,15711,47226,13899,47227,47228,47229,47230,
+47232,47233,47234,47235,47236,22129,29507,47237,47238,29508,47239,14413,47240,
+47241,47242,29510,29511,47243,12362,47244,29509,47245,29513,19313,47246,47247,
+47248,29515,47249,20518,47250,47251,12618,29512,47252,47253,47254,29519,47255,
+13649,47256,47257,29527,47258,29522,47259,47260,47261,29524,29523,14203,47262,
+12607,47263,29518,29514,13658,47264,29520,47424,47425,29521,47426,29525,47427,
+47428,47429,47430,29517,47431,15459,47432,16765,47433,29526,47434,47435,47436,
+47437,47438,47439,29530,47440,29516,47441,13640,47442,15726,29532,47443,47444,
+14116,16240,22142,19762,47445,13424,47446,12895,47447,29528,47448,29529,18744,
+47449,29533,47450,47451,29534,47452,29537,47453,47454,47455,47456,47457,47458,
+47459,47460,47461,47462,47463,29535,47464,47465,29539,29538,47466,47467,29531,
+47468,16234,47469,13167,47470,29536,47471,47472,18217,47473,15474,47474,47475,
+47476,47477,29547,47478,47479,47480,47481,47482,47483,47484,14655,47485,47486,
+29540,47488,47489,47490,12845,15230,47491,19299,47492,47493,47494,47495,29549,
+29545,47496,47497,47498,14684,29550,47499,47500,47501,29541,29542,29546,16993,
+29548,29551,29544,15485,47502,47503,47504,20324,47505,47506,29552,47507,47508,
+47509,29543,47510,47511,47512,47513,47514,47515,47516,47517,29554,47518,47519,
+47520,47680,22317,17962,47681,47682,47683,47684,29555,47685,47686,47687,47688,
+29553,47689,16936,47690,47691,47692,47693,47694,14429,29557,47695,47696,29556,
+47697,47698,47699,13403,47700,47701,47702,29558,29559,47703,47704,47705,29560,
+47706,47707,47708,16442,47709,47710,16489,47711,47712,47713,47714,47715,17777,
+47716,47717,47718,47719,29563,47720,29562,47721,47722,47723,47724,47725,47726,
+47727,47728,13400,47729,47730,47731,29566,29561,47732,47733,29564,47734,47735,
+47736,47737,47738,47739,29565,47740,47741,47742,47744,47745,47746,47747,47748,
+29729,47749,47750,47751,47752,47753,47754,29731,15177,47755,47756,29730,47757,
+47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,29732,
+47770,47771,47772,47773,47774,47775,12862,29734,29733,47776,47936,47937,47938,
+47939,47940,47941,47942,47943,47944,47945,15406,47946,47947,47948,47949,47950,
+47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963,
+47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976,
+47977,47978,47979,47980,47981,47982,17239,22881,47983,47984,47985,47986,47987,
+47988,16480,29772,22353,47989,47990,47991,47992,47993,47994,47995,47996,47997,
+47998,48000,14171,48001,48002,48003,48004,48005,48006,48007,29774,16675,48008,
+48009,17993,48010,13398,21811,48011,48012,48013,29776,29775,29777,19290,48014,
+48015,29778,48016,21569,22112,48017,48018,48019,48020,14176,48021,48022,48023,
+16696,48024,48025,16699,29779,15916,48026,48027,48028,48029,48030,13410,48031,
+48032,29780,29781,15915,48192,48193,29782,48194,48195,48196,29787,48197,29783,
+29786,48198,14973,48199,29784,29785,48200,48201,48202,48203,48204,48205,48206,
+14434,19527,29788,48207,12890,48208,48209,17235,48210,48211,21603,16183,48212,
+48213,48214,48215,48216,48217,48218,29789,48219,48220,48221,48222,48223,48224,
+17716,48225,48226,48227,48228,48229,48230,48231,48232,29801,48233,48234,20277,
+48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247,
+48248,20041,48249,48250,48251,48252,48253,48254,48256,48257,48258,48259,48260,
+48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,19288,48271,19319,
+48272,48273,48274,48275,15732,48276,48277,48278,22351,48279,48280,48281,16475,
+48282,48283,48284,48285,48286,48287,48288,48448,48449,48450,48451,48452,48453,
+48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466,
+48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479,
+48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492,
+48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,20597,48503,48504,
+48505,48506,48507,48508,48509,48510,29802,48512,48513,48514,48515,48516,48517,
+48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530,
+48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543,
+48544,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715,
+48716,29803,48717,48718,48719,48720,48721,48722,48723,29804,48724,48725,48726,
+48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739,
+48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752,
+48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765,
+48766,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779,
+48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792,
+48793,48794,48795,48796,48797,48798,48799,48800,48960,48961,48962,48963,48964,
+48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977,
+48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990,
+48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003,
+49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016,
+49017,49018,49019,49020,49021,49022,49024,30563,49025,49026,49027,49028,49029,
+14129,49030,49031,49032,49033,49034,29805,49035,49036,49037,49038,49039,49040,
+49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053,
+49054,49055,49056,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,
+49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238,
+49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251,
+22379,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263,
+49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,29806,
+49276,49277,49278,26233,15936,26234,14956,26235,20299,26236,21564,15414,26237,
+26238,15437,18514,20019,26401,49280,13375,26402,18740,14425,17481,49281,22365,
+16986,14167,22077,20038,14148,49282,49283,17702,26403,20319,26404,26405,26406,
+16695,22377,18800,20280,22063,22101,26407,12397,26408,26409,18780,21103,15917,
+26410,12403,18526,15713,26411,18502,49284,26412,15206,14456,20772,26413,16999,
+15992,15690,19763,26414,26415,15982,20581,49285,19303,19536,15436,26416,15400,
+20599,26417,49286,20600,26418,26419,13378,26420,26421,18814,20012,17248,26423,
+12609,13169,49287,26424,26425,22363,21824,26426,16972,22330,26427,26428,26429,
+15466,17253,16450,26430,26431,15401,49288,26432,26433,26422,13904,26434,49289,
+26435,26436,15162,13662,16966,12640,26437,21557,26438,14399,26440,26439,14188,
+49290,26441,12920,26442,26443,26444,26445,26446,26447,26448,21287,19317,26449,
+26450,26451,26452,18761,26453,26454,26455,26456,26457,15689,26458,29502,49291,
+14423,49292,18481,49293,49294,49295,49296,49297,49298,49299,29503,49300,29504,
+29505,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,14686,19832,
+49311,49312,22632,14897,49472,16990,28215,49473,14115,49474,49475,49476,49477,
+28217,49478,28216,12373,49479,49480,49481,49482,49483,28219,21846,22383,49484,
+49485,49486,22083,49487,49488,28221,19056,49489,28220,49490,49491,49492,49493,
+28222,49494,49495,49496,49497,28224,49498,49499,28223,49500,49501,49502,49503,
+49504,49505,49506,49507,20850,49508,18236,49509,17216,49510,49511,49512,49513,
+49514,14433,49515,49516,49517,49518,49519,16743,49520,49521,29766,20575,29767,
+49522,20315,49523,49524,18490,49525,49526,29768,49527,49528,49529,49530,49531,
+49532,49533,29769,29770,49534,29771,49536,49537,49538,49539,49540,22906,14462,
+49541,49542,25969,21360,49543,29792,49544,20044,49545,49546,49547,13153,49548,
+49549,49550,49551,28980,49552,21102,49553,29793,49554,49555,49556,49557,49558,
+20328,29794,49559,49560,18252,49561,49562,49563,49564,49565,49566,13652,13412,
+29796,49567,49568,49728,29795,29797,49729,49730,29798,49731,49732,49733,49734,
+29799,49735,14898,12351,49736,29800,49737,49738,49739,49740,49741,49742,49743,
+14125,21101,49744,49745,49746,21035,16463,49747,16188,27427,21855,27208,49748,
+49749,49750,49751,29043,13944,19235,49752,49753,17485,49754,29031,49755,29032,
+14459,29033,14916,21573,12370,49756,49757,29034,49758,49759,49760,29035,49761,
+29036,49762,49763,29037,29038,29039,29041,29040,17749,49764,49765,49766,49767,
+49768,49769,29042,49770,13946,49771,29044,21038,24135,19274,49772,49773,13148,
+49774,13602,49775,14626,49776,49777,17524,29045,49778,49779,29046,49780,49781,
+49782,16708,16763,22064,29047,49783,49784,49785,49786,29048,49787,16682,49788,
+49789,49790,17976,49792,15963,49793,49794,49795,49796,49797,49798,49799,49800,
+49801,49802,49803,49804,49805,49806,29049,13391,49807,49808,49809,49810,49811,
+49812,29050,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823,
+49824,49984,27954,27953,49985,49986,19296,21086,49987,19265,21848,49988,18530,
+49989,16479,15393,49990,49991,49992,49993,49994,49995,27457,49996,49997,20516,
+49998,22114,49999,13895,14424,27456,14414,50000,27455,13094,14665,22059,50001,
+14196,14154,50002,50003,50004,15463,14142,27462,50005,27463,12345,16207,50006,
+27461,21373,50007,27464,50008,50009,27465,50010,50011,14158,50012,27458,27460,
+18806,22103,21837,20530,27471,20024,27472,50013,13608,50014,50015,50016,50017,
+50018,12595,27474,19493,50019,50020,50021,50022,50023,50024,50025,17750,27475,
+50026,27473,17759,27470,18980,27477,12411,50027,50028,14970,50029,50030,22583,
+29027,50031,27466,27467,27468,27469,27478,26176,27481,50032,16232,21064,27479,
+27484,14444,27480,50033,15674,50034,20568,50035,12343,50036,27485,17500,50037,
+50038,50039,50040,22060,50041,50042,50043,13408,50044,50045,17014,15417,50046,
+50048,27482,27483,21600,18026,17492,27487,17703,22901,50049,12849,50050,27492,
+50051,15685,50052,50053,50054,27490,50055,50056,50057,50058,50059,50060,50061,
+50062,50063,50064,50065,50066,50067,27491,50068,50069,14380,50070,19793,27493,
+50071,50072,50073,27489,50074,16691,50075,50076,50077,50078,50079,17954,50080,
+50240,50241,50242,50243,50244,50245,19571,50246,27494,50247,16432,21048,27495,
+50248,50249,50250,14383,14381,50251,27496,18235,19827,50252,50253,50254,27498,
+27499,50255,50256,50257,50258,50259,27501,50260,50261,50262,50263,20552,50264,
+27506,50265,27502,50266,50267,50268,27505,18553,50269,20860,27500,50270,50271,
+27497,50272,50273,50274,50275,14393,20313,17509,27503,27504,19546,19784,12402,
+50276,27510,50277,50278,50279,50280,50281,27509,50282,12850,50283,50284,50285,
+50286,14432,50287,27511,50288,50289,50290,50291,50292,50293,12652,50294,50295,
+19525,17444,20261,50296,50297,50298,50299,50300,27513,50301,50302,27682,50304,
+17778,50305,27514,50306,50307,50308,50309,50310,50311,50312,50313,18757,50314,
+50315,50316,50317,50318,50319,25183,27518,50320,50321,50322,50323,19790,27681,
+12635,21303,50324,50325,21084,50326,50327,50328,27517,50329,27515,50330,50331,
+50332,50333,50334,50335,50336,50496,50497,50498,50499,50500,50501,50502,50503,
+50504,50505,50506,50507,50508,50509,50510,13116,50511,50512,50513,27184,50514,
+50515,22356,50516,29739,13172,50517,50518,50519,50520,50521,22081,22082,50522,
+50523,50524,50525,50526,50527,21865,15946,50528,29735,50529,21032,29736,29737,
+50530,29738,15947,21343,50531,50532,50533,50534,50535,18784,18785,50536,50537,
+29506,50538,19046,50539,19570,50540,50541,50542,50543,50544,50545,25142,19252,
+50546,20072,22107,50547,29741,29742,29743,50548,50549,50550,50551,29746,50552,
+14909,29747,12387,29744,50553,29745,15650,12885,50554,29750,29751,13926,12848,
+20303,29748,13356,50555,29749,50556,50557,29752,50558,50560,50561,50562,50563,
+29753,50564,50565,19751,50566,29754,50567,29755,50568,50569,50570,29756,50571,
+50572,50573,50574,50575,50576,50577,50578,19282,50579,29757,50580,50581,50582,
+50583,29758,50584,50585,50586,50587,50588,50589,50590,50591,29759,50592,50752,
+50753,50754,50755,29790,16700,15464,50756,18731,20830,25973,50757,50758,50759,
+50760,23603,21077,50761,50762,23604,12332,23605,50763,50764,15706,50765,23609,
+50766,50767,50768,22594,50769,23607,21363,50770,18774,23610,23606,50771,23611,
+17186,50772,50773,50774,50775,23612,23621,23613,50776,50777,20063,22053,50778,
+23631,50779,23629,50780,50781,23634,15718,16939,50782,23608,23627,23630,23614,
+14162,12357,23623,20542,23617,15144,50783,14140,23628,50784,50785,23622,23615,
+18267,50786,50787,50788,20799,23616,50789,50790,23626,50791,50792,23632,50793,
+50794,20013,23618,50795,23619,23624,23625,12884,23633,19285,50796,21559,23643,
+23647,19494,23654,50797,17255,23644,50798,50799,16193,23641,50800,12410,14646,
+23653,23635,50801,23620,23638,18548,16224,50802,50803,50804,50805,18747,50806,
+50807,50808,12605,50809,21282,50810,50811,23642,50812,50813,23637,50814,17979,
+50816,23646,50817,50818,50819,50820,50821,22338,17199,14134,18257,17193,23650,
+23640,23659,23636,50822,50823,23645,50824,15909,23639,50825,23648,50826,50827,
+23651,23652,50828,23672,50829,50830,23649,23842,23655,50831,50832,50833,50834,
+50835,50836,50837,50838,50839,50840,15467,13380,50841,50842,17187,12903,23674,
+50843,23666,50844,23663,50845,23676,23662,21104,12904,50846,18519,18531,23675,
+50847,23661,50848,51008,51009,23671,51010,51011,23669,51012,51013,15907,23668,
+51014,12893,51015,51016,51017,51018,51019,23667,15478,23656,15172,51020,16499,
+51021,51022,51023,51024,51025,15444,23657,23658,51026,23665,23670,23673,13620,
+51027,18521,15207,23678,23677,21291,23841,23843,23845,21105,23844,23846,23847,
+21033,51028,51029,51030,51031,51032,51033,51034,14921,23849,51035,51036,23862,
+23857,23860,51037,51038,51039,51040,51041,51042,51043,23856,17998,51044,51045,
+16498,51046,51047,51048,51049,18735,51050,51051,51052,23660,23854,51053,51054,
+51055,51056,23863,51057,51058,23664,23855,51059,23864,51060,23852,51061,51062,
+51063,51064,51065,51066,51067,23865,23859,23853,17450,51068,51069,51070,51072,
+23848,16435,16683,23850,23851,51073,23858,15217,23861,21288,23866,51074,23867,
+17191,51075,51076,23890,23868,51077,51078,51079,23889,51080,14653,51081,51082,
+15957,51083,15994,51084,51085,14922,51086,51087,51088,51089,23882,51090,23877,
+51091,23871,51092,51093,51094,12875,23875,51095,23883,12836,23893,51096,51097,
+51098,23870,51099,51100,51101,18000,23888,51102,51103,51104,51264,51265,23892,
+16738,14150,51266,51267,51268,51269,51270,23886,23887,51271,51272,51273,23876,
+51274,51275,51276,23869,51277,23885,19537,51278,23881,51279,51280,51281,51282,
+23874,17224,17980,20014,23884,51283,23880,51284,51285,51286,51287,51288,51289,
+23873,51290,51291,51292,23878,16988,51293,51294,51295,51296,51297,51298,21289,
+21290,23891,20340,18552,51299,51300,51301,51302,51303,51304,51305,51306,23910,
+51307,51308,51309,51310,51311,51312,23879,51313,51314,51315,23904,16996,51316,
+51317,51318,51319,51320,51321,51322,51323,23905,51324,51325,51326,51328,51329,
+51330,51331,51332,51333,51334,23895,51335,51336,51337,51338,51339,22136,51340,
+23897,23896,14448,23894,51341,51342,51343,51344,17999,51345,13869,51346,51347,
+51348,51349,51350,23906,51351,14969,21601,23911,51352,51353,51354,13392,51355,
+23898,51356,16251,23907,51357,23903,51358,23901,51359,51360,51520,51521,51522,
+51523,51524,13657,51525,51526,51527,51528,23899,23900,23902,51529,15663,23908,
+51530,23909,51531,51532,51533,51534,51535,51536,51537,51538,23925,51539,17225,
+51540,51541,19298,51542,51543,51544,51545,23922,51546,51547,51548,51549,51550,
+51551,51552,51553,51554,51555,51556,51557,51558,22625,51559,51560,18001,51561,
+23924,51562,51563,51564,21876,23923,23920,51565,51566,23916,51567,23919,51568,
+23912,51569,51570,20590,51571,51572,51573,51574,18520,23918,51575,51576,23913,
+51577,51578,23914,19314,51579,23917,51580,51581,12621,51582,51584,51585,51586,
+51587,51588,16438,51589,15419,23921,51590,51591,23927,51592,23926,23915,51593,
+51594,51595,51596,51597,17774,51598,51599,51600,23931,51601,51602,51603,51604,
+51605,51606,51607,51608,51609,51610,51611,24100,51612,51613,24099,51614,51615,
+51616,51776,51777,51778,51779,51780,51781,51782,51783,51784,23928,51785,51786,
+51787,51788,17263,51789,17019,51790,51791,51792,21857,51793,51794,20021,51795,
+51796,51797,51798,23933,51799,12876,51800,51801,51802,51803,51804,51805,51806,
+51807,51808,17512,19039,51809,51810,51811,51812,51813,51814,51815,51816,51817,
+51818,18238,23930,23932,23934,24098,12330,12622,51819,51820,51821,51822,51823,
+24108,51824,51825,51826,51827,24102,15670,18543,51828,51829,51830,51831,51832,
+51833,51834,51835,51836,51837,51838,24097,51840,51841,24101,51842,51843,51844,
+51845,24105,51846,51847,51848,51849,51850,24104,51851,51852,51853,24103,51854,
+51855,51856,51857,51858,51859,51860,51861,51862,24109,51863,21580,51864,51865,
+51866,51867,24115,24106,24110,51868,51869,16473,51870,51871,51872,52032,52033,
+12577,24118,52034,24113,52035,52036,52037,52038,52039,52040,52041,24114,52042,
+52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,20774,24117,52053,
+52054,52055,52056,52057,52058,52059,24111,52060,52061,52062,24112,52063,20541,
+52064,52065,52066,24116,19053,24121,52067,52068,52069,52070,52071,52072,24120,
+52073,24119,52074,52075,52076,52077,52078,52079,52080,24123,52081,52082,52083,
+52084,52085,52086,52087,15717,52088,52089,52090,52091,52092,12888,17258,52093,
+52094,24122,52096,17722,52097,52098,52099,52100,52101,52102,24124,52103,52104,
+52105,52106,52107,52108,52109,19545,52110,52111,52112,52113,14122,52114,52115,
+52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128,
+52288,52289,21605,52290,52291,52292,24125,52293,52294,52295,52296,52297,24127,
+52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,17442,52309,
+52310,52311,52312,24129,52313,52314,52315,52316,52317,52318,52319,52320,52321,
+52322,52323,52324,52325,52326,52327,52328,24126,52329,24128,52330,52331,52332,
+52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,21818,52344,
+52345,52346,24130,52347,52348,52349,52350,52352,52353,52354,52355,52356,52357,
+52358,52359,52360,52361,52362,52363,29230,15138,16946,17712,16967,52364,52365,
+29231,52366,52367,52368,52369,52370,20585,52371,52372,52373,21341,52374,52375,
+52376,27453,52377,52378,52379,52380,52381,52382,52383,52384,13158,29232,52544,
+29233,52545,52546,18989,52547,52548,52549,52550,52551,52552,52553,14951,29235,
+29237,29236,19300,20282,29234,18996,21071,17004,52554,52555,52556,52557,52558,
+52559,52560,20035,29240,12406,29239,52561,52562,52563,52564,52565,29246,52566,
+12879,52567,52568,52569,52570,52571,52572,20801,29242,52573,52574,52575,52576,
+52577,29244,21609,52578,52579,29243,29238,29247,29245,52580,29241,52581,52582,
+29255,29252,29254,52583,52584,29258,29250,29248,52585,52586,52587,29253,52588,
+52589,52590,52591,52592,22139,52593,52594,52595,29249,52596,18297,18783,52597,
+29256,14662,13616,52598,52599,29251,29257,29264,29270,52600,52601,15191,52602,
+52603,52604,29269,19804,52605,22123,52606,52608,29266,29268,52609,52610,52611,
+52612,14450,52613,52614,52615,52616,29259,52617,52618,52619,29262,17017,52620,
+21853,29260,29261,29263,29267,52621,52622,52623,29273,21308,52624,52625,52626,
+52627,13930,52628,19057,52629,14180,29271,52630,52631,52632,29272,29274,29277,
+29275,52633,52634,29276,52635,52636,52637,52638,20817,29265,52639,19785,52640,
+20047,22057,52800,29283,52801,17243,52802,29280,52803,52804,16431,29292,29278,
+52805,29281,52806,52807,52808,29288,52809,52810,52811,52812,29282,52813,52814,
+29287,52815,52816,29286,52817,52818,29289,52819,52820,52821,29279,52822,52823,
+29284,29290,52824,52825,52826,52827,52828,52829,52830,21292,29285,12917,52831,
+52832,29298,52833,20523,52834,52835,52836,52837,29301,52838,52839,52840,15176,
+52841,29305,52842,52843,52844,52845,52846,52847,29296,52848,52849,29302,29304,
+29306,52850,52851,52852,52853,52854,52855,52856,52857,29299,52858,29297,52859,
+52860,52861,14971,52862,13691,52864,52865,52866,52867,29295,29303,29293,29294,
+52868,52869,52870,29291,29478,52871,29475,52872,52873,29474,52874,52875,29300,
+52876,18522,52877,52878,52879,52880,52881,29307,52882,52883,52884,29477,52885,
+52886,52887,52888,52889,52890,52891,17272,52892,52893,52894,52895,52896,53056,
+53057,53058,29309,53059,53060,29479,29481,29476,53061,29308,53062,53063,53064,
+29483,53065,29482,53066,53067,53068,53069,16989,53070,53071,29486,53072,53073,
+29488,53074,53075,53076,53077,53078,29473,53079,53080,53081,29489,29484,53082,
+53083,53084,53085,53086,29487,29310,29485,53087,53088,53089,53090,53091,53092,
+53093,29490,53094,53095,53096,53097,29492,53098,53099,53100,53101,29480,53102,
+53103,53104,53105,29491,53106,53107,53108,29493,53109,53110,53111,53112,53113,
+53114,53115,53116,53117,53118,20535,53120,53121,53122,53123,29496,53124,53125,
+53126,53127,22905,53128,53129,53130,53131,53132,53133,29497,53134,53135,53136,
+53137,53138,53139,53140,53141,29495,53142,18532,29494,53143,53144,53145,53146,
+29498,53147,53148,53149,53150,53151,29499,13376,53152,53312,53313,53314,53315,
+53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,28227,53326,53327,
+53328,53329,53330,53331,29500,53332,53333,29501,53334,53335,53336,20778,53337,
+53338,53339,29740,20550,53340,53341,53342,53343,53344,53345,20560,20828,53346,
+53347,53348,53349,53350,53351,20302,53352,53353,15702,53354,20803,53355,53356,
+53357,53358,53359,53360,53361,14946,24937,21058,28994,12857,53362,53363,12653,
+28995,53364,18752,13124,53365,22898,53366,19237,53367,28996,53368,53369,53370,
+53371,22100,53372,53373,53374,53376,53377,28997,29760,28998,53378,21548,28999,
+53379,12352,29761,53380,53381,29762,53382,53383,13436,53384,17755,53385,53386,
+53387,53388,19515,53389,53390,53391,20580,53392,53393,53394,53395,53396,19808,
+53397,53398,53399,53400,53401,29000,53402,22899,53403,53404,53405,53406,53407,
+53408,12603,53568,20270,53569,53570,53571,14372,53572,53573,53574,53575,53576,
+29002,53577,53578,53579,53580,29003,53581,53582,53583,53584,12867,16721,53585,
+53586,22320,29001,53587,53588,29004,53589,53590,53591,53592,29006,53593,53594,
+53595,22902,53596,21089,21539,53597,53598,29763,18489,53599,53600,53601,53602,
+53603,29764,53604,53605,29005,29007,16227,29008,53606,53607,29012,53608,53609,
+53610,53611,53612,53613,53614,29014,29009,53615,18769,17761,53616,53617,53618,
+16995,14716,53619,53620,29011,53621,29013,53622,53623,53624,14675,53625,53626,
+53627,53628,53629,53630,53632,29019,53633,53634,53635,53636,53637,14934,53638,
+12413,29017,53639,53640,53641,53642,53643,29016,29010,29018,53644,53645,53646,
+53647,53648,29015,53649,53650,53651,18540,53652,53653,53654,53655,19786,29021,
+53656,53657,53658,53659,25917,53660,53661,53662,29020,53663,29022,53664,53824,
+53825,53826,53827,53828,53829,53830,53831,53832,29023,53833,53834,20325,53835,
+53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848,
+53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,29765,15731,
+53860,53861,53862,53863,53864,53865,29024,53866,53867,53868,53869,53870,53871,
+53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884,
+53885,29025,53886,53888,53889,20087,53890,21034,53891,29051,53892,53893,14386,
+53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906,
+53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919,
+53920,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091,
+54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104,
+54105,54106,54107,54108,54109,54110,15483,14683,54111,14694,17241,19027,27240,
+16448,15989,27241,27242,27243,54112,27244,27245,27246,27247,15687,54113,54114,
+54115,30075,54116,54117,54118,30077,54119,30078,54120,30076,54121,54122,54123,
+54124,15714,54125,30241,13349,54126,54127,54128,54129,30242,54130,54131,54132,
+30243,54133,54134,54135,27698,54136,54137,54138,54139,54140,54141,54142,54144,
+54145,54146,54147,54148,20820,54149,54150,54151,54152,54153,54154,22890,54155,
+54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168,
+54169,54170,54171,54172,54173,54174,54175,54176,54336,54337,54338,54339,54340,
+54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353,
+54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366,
+54367,30244,54368,54369,54370,54371,54372,54373,54374,54375,54376,28218,54377,
+54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390,
+54391,54392,54393,54394,54395,54396,54397,54398,54400,54401,54402,54403,54404,
+54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417,
+54418,54419,54420,54421,54422,54423,54424,54425,21810,54426,54427,54428,54429,
+54430,54431,54432,54592,54593,54594,54595,54596,54597,54598,54599,21374,19548,
+54600,54601,54602,54603,54604,54605,54606,54607,19012,54608,54609,54610,54611,
+54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624,
+54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637,
+54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650,
+54651,54652,54653,54654,54656,54657,54658,54659,54660,54661,54662,54663,54664,
+54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677,
+54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54848,54849,
+54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862,
+54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875,
+54876,54877,54878,54879,54880,54881,54882,25920,54883,54884,54885,54886,54887,
+54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900,
+54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54912,54913,30245,
+54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926,
+54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939,
+54940,54941,54942,54943,54944,55104,55105,55106,55107,55108,55109,55110,55111,
+55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124,
+55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,15919,55136,
+55137,55138,55139,55140,17961,55141,55142,55143,55144,55145,55146,55147,55148,
+55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161,
+55162,55163,55164,55165,55166,55168,55169,55170,55171,55172,55173,55174,55175,
+55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188,
+55189,55190,55191,55192,23077,15430,13865,14396,18511,15397,23078,23079,19542,
+18499,23080,18045,55193,20789,21097,20790,15431,55194,15666,15204,23081,23082,
+20808,23083,20589,13935,16987,55195,19279,14189,18792,14147,15991,22052,23084,
+23085,17984,22375,18998,55196,21801,19295,21871,23086,22111,13386,23088,23087,
+55197,21099,23089,23090,23091,19028,23092,18987,23093,23094,13135,22127,23095,
+15152,13614,23096,23097,14702,20783,21096,23098,14403,20330,12911,23099,23100,
+55198,15723,20060,21359,23101,20083,23102,21333,15205,23103,19253,19280,23104,
+18283,22126,23105,17717,13889,23106,14156,16206,23107,23108,19245,23109,13687,
+23110,16706,22331,23111,19512,55199,21098,17457,23112,13693,15185,23113,20531,
+23114,23115,20029,23116,23117,23118,12919,23121,23119,20840,23120,17237,23122,
+55200,23123,23124,23125,20539,21029,12409,23126,18219,23127,15735,17185,23128,
+23129,17277,19511,23130,23131,16446,18007,23132,23133,18228,23134,23135,14664,
+55360,55361,55362,55363,55364,55365,55366,55367,55368,15213,55369,55370,55371,
+55372,13881,29816,55373,29817,55374,55375,19811,55376,55377,55378,55379,55380,
+55381,55382,55383,30009,55384,55385,55386,55387,27488,55388,55389,55390,55391,
+55392,55393,20339,15167,55394,55395,55396,55397,55398,55399,55400,14912,21541,
+55401,55402,55403,55404,55405,55406,55407,24921,55408,55409,55410,55411,30068,
+12586,12914,55412,55413,55414,55415,55416,55417,55418,30069,55419,55420,30071,
+55421,55422,55424,14929,30070,55425,17202,55426,55427,55428,55429,55430,55431,
+55432,30073,55433,55434,55435,30072,55436,55437,55438,55439,55440,55441,55442,
+55443,55444,55445,55446,55447,55448,55449,55450,55451,55452,55453,55454,55455,
+55456,55616,55617,55618,55619,55620,55621,55622,55623,55624,55625,55626,55627,
+55628,55629,55630,55631,55632,55633,55634,55635,55636,55637,55638,55639,55640,
+55641,55642,55643,55644,55645,55646,55647,55648,55649,55650,55651,55652,55653,
+55654,55655,55656,55657,55658,55659,55660,55661,55662,55663,55664,55665,55666,
+55667,55668,55669,55670,55671,55672,55673,55674,55675,55676,55677,55678,55680,
+55681,55682,55683,55684,55685,55686,55687,55688,55689,55690,55691,55692,55693,
+55694,55695,55696,55697,55698,55699,55700,55701,55702,55703,55704,55705,55706,
+55707,55708,55709,55710,55711,55712,55872,55873,55874,55875,55876,55877,55878,
+55879,55880,55881,55882,55883,55884,55885,55886,12596,21866,14394,55887,14641,
+12870,21616,20301,12380,21835,15221,22090,14135,19504,17974,12641,14650,22140,
+14689,14113,15482,27226,27227,19577,14707,27228,13435,17203,14161,14936,27229,
+21620,27230,15446,15199,27231,16734,16952,21599,22346,27232,27233,27236,27234,
+27235,18782,14387,13892,27237,19050,18765,13389,55888,55889,25177,17762,27238,
+16437,55890,22328,27239,22316,18556,22611,22605,21598,55891,21625,18756,21294,
+14419,13152,55892,18786,29814,55893,55894,55895,14933,55896,29815,55897,55898,
+22367,55899,55900,29809,14384,21844,14415,18032,55901,55902,55903,55904,55905,
+55906,55907,55908,55909,13123,55910,55911,29810,13100,55912,55913,55914,55915,
+21565,18295,55916,55917,55918,55919,55920,29812,55921,55922,29811,55923,55924,
+55925,55926,55927,55928,55929,55930,55931,55932,19531,55933,55934,55936,18468,
+55937,55938,55939,55940,55941,55942,55943,55944,55945,55946,55947,55948,55949,
+29813,55950,22371,17727,30016,55951,55952,30011,55953,30019,55954,30018,55955,
+22074,30017,55956,55957,55958,21566,30020,55959,30028,55960,55961,55962,55963,
+12367,13688,55964,30025,30026,55965,17756,55966,55967,55968,56128,30021,30022,
+56129,56130,30023,30027,56131,15968,30024,14458,56132,56133,56134,30032,30035,
+56135,56136,56137,16231,56138,14706,30012,30029,56139,56140,16951,56141,56142,
+56143,19576,56144,15481,56145,30030,30031,30033,13925,30034,56146,30037,56147,
+56148,56149,56150,56151,56152,56153,30013,56154,56155,56156,30036,21307,56157,
+13164,56158,56159,19492,56160,56161,56162,56163,30038,56164,56165,56166,56167,
+56168,56169,56170,56171,30039,15969,30040,56172,56173,19551,30043,56174,56175,
+56176,56177,56178,12872,22361,56179,30041,56180,30042,30044,56181,30050,56182,
+56183,56184,30048,56185,56186,56187,30047,30045,56188,56189,30049,56190,56192,
+30046,30052,30053,56193,19555,56194,56195,25919,13624,30051,30056,19491,56196,
+56197,56198,56199,56200,30054,30055,56201,56202,56203,56204,56205,56206,30014,
+56207,56208,56209,56210,56211,56212,56213,56214,56215,56216,56217,56218,12612,
+56219,56220,30015,56221,56222,13637,12900,56223,30060,30057,56224,13911,56384,
+30061,56385,30058,56386,56387,56388,56389,56390,30059,56391,56392,13402,56393,
+21610,56394,56395,56396,30062,56397,13177,56398,56399,56400,56401,56402,56403,
+56404,30063,30065,56405,56406,56407,30064,56408,56409,56410,56411,56412,56413,
+56414,30066,56415,30067,56416,56417,56418,56419,56420,56421,56422,56423,56424,
+56425,56426,56427,18797,14634,56428,56429,18299,56430,56431,13923,56432,56433,
+56434,56435,56436,56437,56438,19529,56439,56440,56441,56442,56443,56444,56445,
+56446,56448,56449,56450,56451,56452,56453,56454,56455,56456,56457,56458,27174,
+56459,56460,56461,56462,56463,56464,56465,56466,56467,56468,56469,56470,56471,
+56472,56473,56474,56475,56476,56477,56478,56479,56480,56640,56641,56642,56643,
+56644,56645,56646,56647,56648,56649,56650,56651,56652,56653,56654,56655,56656,
+56657,56658,56659,56660,56661,56662,56663,56664,56665,56666,56667,56668,56669,
+56670,56671,56672,56673,56674,56675,56676,56677,56678,56679,56680,56681,56682,
+56683,56684,56685,56686,56687,56688,56689,56690,56691,56692,56693,56694,56695,
+56696,56697,56698,56699,56700,56701,56702,56704,56705,56706,56707,56708,56709,
+56710,56711,56712,56713,56714,56715,56716,56717,56718,56719,56720,56721,56722,
+56723,56724,56725,56726,56727,56728,56729,56730,56731,56732,56733,56734,56735,
+56736,56896,56897,56898,56899,56900,56901,56902,56903,56904,56905,56906,56907,
+56908,56909,56910,56911,56912,56913,56914,56915,56916,56917,56918,56919,56920,
+56921,56922,56923,56924,56925,56926,56927,56928,13109,21630,14700,20601,56929,
+26989,22314,26990,16982,18541,14948,26991,26992,26993,22113,26994,26995,26997,
+26996,26998,26999,18273,27000,21592,27001,15694,56930,27002,27003,15695,27004,
+14376,16702,27005,12594,15188,14709,27006,56931,27169,27170,27171,14200,15405,
+56932,19044,24654,21551,20285,21815,27172,21854,27173,20545,14652,56933,13383,
+12633,56934,56935,56936,16433,56937,56938,56939,56940,12646,12647,56941,12648,
+56942,56943,56944,56945,13117,18536,56946,56947,56948,56949,25921,56950,56951,
+12639,56952,56953,56954,16713,13423,56955,56956,18216,21336,56957,18041,20792,
+56958,14717,17013,56960,56961,56962,56963,56964,21293,56965,21579,15740,56966,
+25922,14133,25923,56967,56968,15161,21858,56969,15736,21558,20005,16684,13145,
+56970,56971,19574,56972,25926,25924,25928,56973,25930,25927,13647,17992,56974,
+13692,25925,56975,19062,56976,56977,25929,56978,56979,56980,17236,12613,15395,
+56981,56982,56983,22327,56984,56985,19787,19277,19018,19539,25932,25931,17510,
+56986,56987,20769,20791,25933,56988,25936,56989,19768,22128,25935,13661,56990,
+19774,56991,25937,13882,56992,57152,19752,14692,57153,19013,13137,19289,21612,
+25938,14186,57154,57155,57156,25934,57157,57158,57159,57160,57161,57162,25941,
+13438,25942,57163,57164,57165,57166,57167,25939,25940,57168,21085,57169,57170,
+16991,12614,57171,21346,57172,57173,13917,19308,57174,25943,57175,57176,21366,
+57177,57178,57179,57180,57181,12649,57182,13940,25946,25944,25945,13632,57183,
+57184,57185,21061,25948,57186,57187,25950,57188,57189,57190,57191,57192,57193,
+25949,18226,57194,21027,57195,57196,25947,57197,57198,57199,57200,21602,21850,
+57201,57202,57203,57204,57205,25952,22385,57206,57207,57208,57209,57210,57211,
+57212,25953,57213,12636,20859,57214,25954,25956,57216,57217,57218,57219,25955,
+57220,57221,25957,57222,57223,57224,57225,57226,21080,57227,13643,57228,26463,
+57229,23157,57230,23160,57231,23158,57232,23159,57233,57234,57235,23162,20559,
+17479,57236,57237,12398,57238,57239,57240,20528,57241,23161,57242,21322,14890,
+23330,18289,57243,23164,23163,18779,23165,57244,23329,22366,23166,16730,57245,
+57246,23333,57247,57248,21364,57408,57409,23335,23332,57410,23336,57411,57412,
+15676,57413,57414,57415,16457,23331,23334,22051,57416,23337,57417,57418,57419,
+23341,57420,57421,57422,23342,23340,14914,57423,57424,57425,16164,23339,57426,
+57427,57428,23338,21575,12863,57429,57430,23343,57431,14713,57432,23344,57433,
+57434,57435,57436,13115,57437,57438,57439,13606,57440,57441,57442,57443,13884,
+23345,57444,57445,57446,13941,57447,23346,57448,57449,57450,57451,57452,57453,
+57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,57466,
+57467,12617,57468,57469,57470,57472,23348,57473,57474,57475,23347,23349,57476,
+57477,57478,57479,57480,57481,57482,57483,57484,57485,57486,23351,57487,23350,
+57488,57489,57490,57491,57492,57493,57494,23352,57495,57496,57497,57498,57499,
+57500,57501,57502,57503,23353,57504,57664,23354,57665,57666,21327,29818,18293,
+22339,17764,29820,29821,29819,57667,15942,57668,57669,57670,57671,20591,57672,
+57673,14163,57674,57675,21581,19498,57676,57677,29986,29985,14888,29822,19286,
+57678,57679,57680,29988,16466,57681,13162,57682,19754,29989,29987,15668,29992,
+57683,29993,15693,17208,16225,19297,29994,57684,57685,57686,29990,29991,17520,
+57687,57688,57689,57690,57691,29996,57692,13372,57693,22381,57694,13399,29995,
+29998,57695,57696,29997,29999,20561,57697,57698,57699,57700,57701,57702,57703,
+17233,18473,57704,57705,57706,57707,57708,57709,30000,30001,57710,57711,57712,
+57713,57714,57715,30002,57716,57717,30003,30004,30005,57718,57719,57720,57721,
+30007,30006,57722,57723,57724,57725,30008,57726,57728,57729,57730,57731,57732,
+57733,57734,57735,57736,57737,57738,12873,57739,21332,19021,57740,16495,22104,
+21040,16703,57741,15728,57742,57743,57744,57745,57746,57747,57748,57749,57750,
+57751,14378,57752,57753,57754,57755,57756,57757,57758,57759,57760,57920,57921,
+57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,
+57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,
+57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,
+57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,
+57974,57975,57976,57977,57978,57979,57980,57981,57982,57984,57985,57986,57987,
+57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,57999,58000,
+58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,58012,58013,
+58014,58015,58016,58176,58177,58178,58179,58180,58181,58182,58183,58184,58185,
+58186,58187,58188,58189,58190,58191,58192,58193,58194,58195,58196,58197,58198,
+58199,58200,58201,58202,58203,58204,58205,58206,58207,58208,58209,58210,58211,
+58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,15480,58222,58223,
+58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,58235,58236,
+58237,58238,58240,58241,58242,58243,58244,58245,58246,58247,30278,58248,58249,
+58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,58261,58262,
+58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58432,58433,58434,
+58435,58436,58437,30279,58438,58439,58440,58441,58442,58443,58444,58445,58446,
+58447,58448,58449,58450,58451,58452,58453,58454,58455,58456,58457,58458,58459,
+58460,58461,58462,30280,58463,58464,58465,58466,58467,58468,58469,58470,58471,
+58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484,
+58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58496,58497,58498,
+58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,58511,
+58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,58524,
+58525,58526,58527,58528,58688,58689,58690,58691,58692,58693,58694,58695,58696,
+58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,58708,58709,
+58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,58721,58722,
+58723,58724,58725,58726,58727,58728,58729,58730,58731,58732,58733,58734,58735,
+58736,58737,58738,58739,30281,58740,58741,58742,58743,58744,58745,58746,58747,
+58748,58749,58750,58752,58753,58754,58755,58756,58757,58758,58759,58760,58761,
+58762,58763,58764,58765,58766,58767,58768,58769,58770,58771,58772,58773,58774,
+58775,58776,58777,58778,58779,58780,58781,58782,58783,30282,58784,58944,58945,
+58946,58947,58948,58949,58950,58951,58952,58953,58954,58955,58956,58957,58958,
+58959,58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971,
+58972,58973,58974,58975,58976,58977,58978,30284,58979,58980,58981,58982,58983,
+58984,58985,58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996,
+58997,58998,58999,59000,59001,59002,59003,59004,59005,59006,59008,59009,59010,
+59011,59012,59013,59014,59015,59016,59017,59018,59019,59020,59021,59022,59023,
+59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,59034,59035,59036,
+59037,30283,59038,59039,59040,59200,59201,59202,59203,59204,59205,59206,59207,
+30569,59208,59209,59210,59211,59212,59213,59214,59215,59216,59217,59218,59219,
+59220,59221,59222,59223,59224,59225,59226,59227,59228,59229,59230,59231,59232,
+59233,59234,59235,59236,59237,59238,59239,59240,59241,59242,59243,59244,59245,
+59246,59247,59248,59249,59250,59251,59252,59253,59254,59255,59256,59257,59258,
+59259,59260,59261,59262,59264,59265,59266,59267,59268,59269,59270,59271,59272,
+59273,59274,59275,59276,59277,59278,59279,59280,59281,59282,59283,59284,59285,
+59286,59287,59288,59289,59290,59291,59292,59293,59294,59295,59296,59456,59457,
+59458,59459,59460,59461,59462,59463,59464,59465,59466,59467,59468,59469,59470,
+30285,59471,59472,59473,59474,59475,59476,59477,59478,59479,59480,59481,59482,
+59483,59484,59485,59486,59487,59488,59489,59490,59491,59492,59493,59494,59495,
+59496,59497,59498,59499,59500,59501,59502,59503,59504,59505,59506,59507,59508,
+59509,59510,59511,59512,59513,59514,30286,59515,59516,59517,59518,59520,59521,
+59522,59523,59524,59525,59526,59527,59528,59529,59530,59531,59532,59533,59534,
+59535,59536,59537,59538,59539,59540,28228,28229,28230,21867,13860,28232,28231,
+28233,28234,18213,28235,28236,59541,14128,13686,28237,28239,59542,28238,59543,
+14406,28240,28241,28242,13915,13102,22099,17478,12597,14422,28243,28244,21567,
+18261,15995,20057,14643,28246,28245,28248,28247,17701,28249,28250,18222,28251,
+18223,28252,12839,28253,28254,28255,28256,28257,22378,28258,28259,15448,28260,
+21323,19578,12844,16741,28261,18214,17197,59544,28262,28263,28264,28265,28266,
+28267,28268,59545,28269,28270,28271,59546,59547,28272,28273,28274,28276,28275,
+59548,28277,19757,16961,28278,28279,28280,21793,28281,20275,28282,28283,59549,
+28284,28285,28449,28286,28450,14453,17274,28451,28452,15682,21055,12921,28453,
+28454,28455,21112,28456,22141,28457,17996,59550,28458,28459,16692,28460,20346,
+19320,28462,28461,13178,14712,28463,28464,20578,28465,28466,14182,20543,28467,
+28468,28469,18545,19552,28470,28471,28472,28473,28474,21856,28475,13421,17194,
+28476,59551,28477,28478,28479,59552,20093,28480,16992,13368,22326,15733,59712,
+20295,28483,28481,28482,28484,13863,15484,15970,17228,28485,28486,59713,28487,
+28495,28488,28489,28490,18242,28529,13901,28491,59714,28492,28493,13894,17214,
+28494,59715,28496,28497,28498,21874,59716,28499,17527,59717,28500,17528,28501,
+28502,14436,12407,28503,28504,28505,59718,28506,28507,28508,28509,59719,28510,
+15925,28513,28511,28512,59720,28514,28515,16717,28516,28517,28518,28519,28520,
+28521,28522,28523,28524,16472,59721,28525,16685,28526,28527,28528,59722,59723,
+20322,59724,59725,59726,59727,59728,59729,59730,59731,13092,59732,59733,59734,
+59735,59736,59737,59738,59739,59740,59741,59742,59743,59744,59745,59746,59747,
+59748,59749,59750,59751,59752,59753,59754,59755,59756,59757,59758,59759,59760,
+59761,59762,59763,59764,59765,59766,59767,59768,59769,59770,59771,59772,59773,
+59774,59776,59777,59778,59779,59780,59781,59782,59783,59784,59785,59786,59787,
+59788,59789,59790,59791,59792,59793,59794,59795,59796,59797,59798,59799,59800,
+59801,59802,59803,59804,59805,59806,59807,59808,59968,59969,59970,59971,59972,
+59973,59974,59975,59976,59977,59978,59979,59980,59981,59982,59983,59984,59985,
+59986,59987,59988,59989,59990,59991,59992,59993,59994,59995,17221,25413,18753,
+25414,59996,12629,20042,13363,18546,25415,20304,25416,15460,25417,25418,17222,
+21794,17494,14699,20037,25419,17270,25420,59997,14119,14451,14930,25421,25422,
+21572,25423,59998,25424,20811,25425,25426,25427,25428,20822,25429,12923,16443,
+25430,59999,16427,25431,25432,25433,60000,25434,25435,60001,14391,23138,60002,
+13907,60003,23140,23139,60004,60005,60006,60007,60008,60009,60010,23142,60011,
+60012,60013,18542,60014,60015,23141,14144,20852,21109,21875,15703,60016,60017,
+60018,60019,22376,23144,23143,60020,12322,19795,60021,23145,60022,14397,15434,
+16957,16932,13122,23146,60023,16938,17456,15669,60024,60025,20318,60026,60027,
+60028,23147,18754,60029,60030,60032,60033,60034,12637,60035,60036,60037,23148,
+60038,13880,21562,60039,13181,60040,60041,23149,21577,20309,17763,60042,23150,
+60043,60044,60045,60046,60047,23151,60048,23152,16746,19541,20317,60049,60050,
+60051,60052,60053,60054,60055,60056,60057,60058,60059,60060,60061,21351,16929,
+60062,23153,60063,60064,19301,60224,23154,60225,19302,21118,60226,60227,60228,
+14452,60229,60230,23155,12335,20278,60231,60232,21839,60233,60234,60235,60236,
+60237,60238,60239,60240,60241,60242,19309,60243,60244,60245,60246,60247,60248,
+60249,60250,23156,60251,60252,25412,60253,60254,16677,60255,60256,30271,60257,
+60258,30272,30273,17489,60259,18488,20835,60260,60261,20571,20805,15407,14669,
+60262,28532,60263,60264,13382,21306,30274,13179,60265,60266,30275,60267,60268,
+13681,60269,60270,60271,60272,60273,60274,60275,60276,60277,60278,30277,60279,
+60280,60281,60282,60283,60284,60285,21354,30247,20777,60286,60288,60289,60290,
+30249,60291,60292,60293,30248,60294,60295,16739,16471,60296,12578,60297,60298,
+60299,60300,20077,60301,20584,30251,60302,60303,20342,60304,30250,21872,30252,
+17209,60305,60306,60307,15220,30254,30253,60308,60309,60310,17502,60311,60312,
+16728,60313,60314,60315,60316,60317,19242,60318,20284,60319,60320,60480,60481,
+60482,60483,60484,60485,60486,60487,60488,30255,60489,60490,30256,60491,60492,
+30257,60493,16950,60494,60495,60496,60497,60498,12372,17785,60499,60500,60501,
+60502,30258,60503,60504,60505,60506,60507,60508,60509,60510,60511,60512,60513,
+60514,60515,60516,60517,60518,60519,60520,60521,18272,30246,60522,60523,15928,
+60524,60525,15922,60526,13669,60527,60528,14151,60529,16191,17234,17254,60530,
+60531,22604,60532,60533,60534,14447,60535,60536,60537,60538,60539,60540,60541,
+60542,60544,15737,20773,60545,12368,60546,60547,60548,60549,60550,30512,60551,
+60552,60553,60554,60555,60556,60557,60558,30513,60559,60560,60561,60562,60563,
+20524,60564,12336,60565,60566,60567,30514,30515,60568,30516,60569,60570,60571,
+18250,60572,60573,60574,60575,60576,60736,60737,15951,60738,60739,30519,60740,
+60741,60742,60743,60744,60745,60746,30518,60747,12638,60748,30517,60749,60750,
+30520,60751,30521,60752,60753,60754,60755,60756,60757,60758,60759,60760,60761,
+60762,60763,60764,60765,60766,60767,60768,60769,60770,60771,60772,60773,60774,
+60775,60776,60777,60778,60779,60780,60781,60782,60783,60784,60785,60786,60787,
+60788,60789,60790,60791,60792,60793,60794,60795,60796,60797,60798,60800,60801,
+20004,18509,60802,14891,26680,26681,26682,15938,60803,60804,60805,60806,60807,
+21108,60808,21583,18776,60809,60810,60811,60812,60813,60814,60815,60816,60817,
+60818,60819,60820,60821,60822,60823,60824,60825,60826,60827,60828,60829,60830,
+60831,60832,60992,60993,60994,60995,60996,60997,60998,60999,61000,61001,61002,
+61003,61004,61005,61006,61007,61008,61009,61010,61011,61012,61013,61014,61015,
+61016,61017,61018,61019,61020,61021,61022,61023,61024,61025,61026,61027,61028,
+61029,61030,61031,61032,61033,61034,61035,61036,61037,61038,61039,61040,61041,
+61042,61043,61044,61045,61046,61047,61048,61049,61050,61051,61052,61053,61054,
+61056,61057,61058,61059,61060,61061,61062,61063,61064,61065,61066,61067,61068,
+61069,61070,61071,61072,61073,61074,61075,61076,61077,61078,61079,61080,61081,
+61082,61083,61084,61085,61086,61087,61088,61248,61249,61250,61251,61252,61253,
+21043,13861,18282,29052,20334,19251,20587,26479,19815,14667,13913,29053,12388,
+19276,29054,21540,16941,16748,17988,15921,29217,15445,61254,29218,29219,61255,
+29220,21059,17973,61256,19783,29221,61257,21297,16197,19554,61258,29222,29223,
+20821,13934,29224,29225,13663,29226,29227,61259,12924,29228,29229,18471,61260,
+61261,61262,61263,61264,61265,61266,61267,61268,61269,61270,61271,61272,61273,
+61274,61275,61276,61277,61278,61279,61280,61281,61282,61283,61284,61285,61286,
+61287,61288,61289,61290,61291,61292,61293,61294,61295,61296,61297,14183,61298,
+61299,27689,27690,27691,61300,27692,61301,61302,17966,27693,27694,61303,61304,
+61305,14153,18995,61306,61307,61308,61309,61310,61312,61313,25144,30543,61314,
+61315,61316,61317,61318,61319,61320,61321,61322,61323,61324,61325,61326,61327,
+61328,61329,61330,61331,61332,61333,61334,61335,61336,61337,61338,61339,61340,
+61341,61342,61343,61344,61504,61505,61506,61507,61508,30544,61509,61510,12877,
+61511,61512,61513,61514,61515,61516,61517,61518,61519,61520,61521,61522,61523,
+61524,61525,61526,61527,61528,61529,61530,61531,61532,61533,61534,61535,61536,
+61537,61538,61539,30545,61540,61541,61542,61543,61544,61545,61546,61547,61548,
+61549,61550,61551,61552,61553,61554,61555,61556,61557,61558,61559,61560,61561,
+61562,61563,61564,61565,61566,61568,61569,61570,61571,61572,61573,61574,61575,
+61576,61577,30547,30546,61578,61579,61580,61581,61582,61583,61584,61585,61586,
+61587,61588,61589,61590,25147,61591,15394,61592,25148,25149,25150,25151,25152,
+25153,14137,21115,15652,19022,12581,19271,61593,25154,13948,18500,25155,61594,
+61595,15688,61596,12669,25156,61597,13942,25157,17497,61598,61599,25158,20314,
+14685,25159,16417,61600,25160,12918,61760,25161,61761,16755,25162,25163,17016,
+25164,25165,25166,19031,22584,22885,20323,61762,61763,61764,61765,61766,61767,
+61768,61769,61770,61771,61772,28709,61773,61774,23600,61775,61776,61777,61778,
+61779,61780,61781,61782,61783,61784,61785,61786,61787,61788,61789,61790,61791,
+61792,61793,61794,61795,61796,61797,61798,61799,61800,61801,61802,61803,61804,
+61805,61806,61807,61808,61809,61810,61811,61812,61813,61814,61815,61816,61817,
+61818,61819,61820,61821,61822,61824,61825,61826,61827,61828,61829,61830,61831,
+61832,61833,61834,61835,61836,61837,61838,61839,61840,61841,61842,61843,61844,
+61845,61846,61847,61848,61849,61850,61851,61852,61853,61854,61855,61856,62016,
+62017,62018,62019,62020,62021,62022,62023,62024,62025,62026,62027,62028,62029,
+62030,62031,62032,62033,62034,62035,62036,62037,62038,62039,62040,62041,62042,
+62043,62044,62045,62046,62047,62048,62049,62050,62051,62052,62053,62054,62055,
+62056,62057,62058,62059,62060,62061,62062,62063,62064,62065,62066,62067,62068,
+62069,62070,62071,62072,62073,62074,62075,62076,62077,62078,62080,62081,62082,
+62083,62084,62085,62086,62087,62088,62089,62090,62091,62092,62093,62094,62095,
+62096,62097,62098,62099,62100,62101,62102,62103,62104,62105,62106,62107,62108,
+62109,62110,62111,62112,62272,62273,62274,62275,62276,62277,62278,62279,62280,
+62281,62282,62283,62284,62285,62286,62287,62288,62289,17005,21542,19796,20785,
+13147,18301,62290,12853,16959,26208,19003,26209,26210,15956,26211,22308,19797,
+26213,15453,26212,26214,26215,17006,62291,15678,26216,16998,14887,26217,62292,
+26218,13138,20841,62293,62294,16165,26219,18031,26220,26221,62295,62296,26222,
+17965,26223,62297,18727,26224,26225,26226,25913,26227,26228,16994,26229,26230,
+22120,26231,62298,26232,14663,62299,62300,62301,62302,62303,62304,62305,30523,
+30522,62306,62307,62308,62309,30526,30524,14881,62310,30527,62311,30528,62312,
+62313,62314,30530,30529,30532,62315,62316,30531,62317,62318,62319,62320,62321,
+30533,30534,62322,62323,62324,62325,30535,62326,19304,62327,62328,62329,62330,
+14431,62331,62332,62333,62334,62336,62337,30548,62338,30549,62339,62340,62341,
+62342,30550,62343,62344,62345,62346,30552,62347,30554,62348,30551,62349,62350,
+62351,62352,62353,62354,62355,62356,62357,30555,62358,30553,62359,62360,62361,
+62362,62363,62364,62365,22359,62366,62367,62368,62528,30556,62529,62530,62531,
+62532,62533,62534,30557,62535,62536,62537,30558,62538,62539,62540,62541,62542,
+62543,62544,62545,62546,62547,62548,30559,62549,62550,62551,30560,62552,62553,
+62554,62555,62556,62557,62558,62559,62560,62561,62562,23371,62563,62564,22570,
+62565,62566,62567,62568,62569,62570,62571,62572,25975,14701,62573,62574,62575,
+62576,16253,15210,30537,17991,30536,62577,30538,30540,30539,62578,62579,62580,
+30541,62581,20026,62582,30542,62583,62584,17447,62585,62586,62587,62588,62589,
+62590,62592,62593,62594,62595,62596,62597,62598,62599,62600,62601,62602,62603,
+62604,62605,62606,62607,62608,62609,62610,62611,62612,62613,62614,62615,62616,
+62617,62618,62619,62620,62621,62622,62623,62624,62784,62785,62786,62787,62788,
+62789,62790,62791,62792,62793,62794,62795,62796,62797,62798,62799,62800,62801,
+62802,62803,62804,62805,62806,62807,62808,62809,62810,62811,62812,62813,62814,
+62815,62816,62817,62818,62819,62820,62821,62822,62823,62824,62825,62826,62827,
+62828,62829,62830,62831,62832,62833,62834,62835,62836,62837,62838,62839,62840,
+62841,62842,62843,62844,62845,62846,62848,62849,62850,62851,62852,62853,62854,
+62855,62856,62857,62858,62859,62860,62861,62862,62863,62864,62865,62866,62867,
+62868,62869,62870,62871,62872,62873,62874,62875,62876,62877,62878,62879,62880,
+63040,63041,63042,63043,63044,63045,63046,63047,63048,63049,63050,63051,63052,
+63053,63054,63055,63056,63057,63058,63059,63060,63061,63062,63063,63064,63065,
+63066,63067,63068,63069,63070,63071,63072,63073,63074,63075,63076,63077,63078,
+63079,63080,63081,63082,63083,63084,63085,63086,63087,63088,63089,63090,63091,
+63092,63093,63094,63095,63096,63097,63098,63099,63100,63101,63102,63104,63105,
+63106,63107,63108,63109,63110,63111,63112,63113,63114,63115,63116,63117,63118,
+63119,63120,63121,63122,63123,63124,63125,63126,63127,63128,63129,63130,63131,
+63132,63133,63134,63135,63136,63296,63297,63298,63299,63300,63301,63302,63303,
+63304,63305,63306,63307,63308,63309,63310,63311,63312,63313,63314,63315,63316,
+63317,63318,63319,63320,63321,63322,63323,63324,63325,63326,63327,63328,63329,
+63330,63331,63332,63333,63334,63335,63336,63337,63338,63339,63340,63341,63342,
+63343,63344,63345,63346,63347,63348,63349,63350,63351,63352,63353,63354,63355,
+63356,63357,63358,63360,21347,63361,63362,30287,63363,16947,30288,63364,63365,
+30289,30290,30291,30292,63366,63367,30294,63368,12587,30295,63369,30296,30297,
+30298,63370,30299,30300,63371,63372,63373,63374,30301,30302,20298,63375,30303,
+30304,30305,30306,30307,30308,16496,30309,30310,30311,30312,30313,63376,30314,
+63377,30315,30316,63378,30317,30318,30319,30320,30321,30322,30323,30324,15912,
+63379,30325,30326,30327,30328,63380,63381,63382,63383,63384,18554,30329,30330,
+30331,30332,63385,63386,30333,30334,30497,30498,30499,30500,30501,63387,63388,
+30502,30503,30504,12654,30505,30506,30507,63389,63390,30508,30509,16731,30510,
+63391,63392,30511,63552,63553,63554,63555,63556,63557,63558,63559,63560,63561,
+63562,63563,63564,63565,63566,63567,63568,63569,63570,63571,63572,63573,63574,
+63575,63576,63577,63578,63579,63580,63581,63582,63583,63584,63585,63586,63587,
+63588,63589,63590,63591,63592,63593,63594,63595,63596,63597,63598,63599,63600,
+63601,63602,63603,63604,63605,63606,63607,63608,63609,63610,63611,63612,63613,
+63614,63616,63617,63618,63619,63620,63621,63622,63623,63624,63625,63626,63627,
+63628,63629,63630,63631,63632,63633,63634,63635,63636,63637,63638,63639,63640,
+63641,63642,63643,63644,63645,63646,63647,63648,63808,63809,63810,63811,63812,
+63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825,
+63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838,
+63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851,
+63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864,
+63865,63866,63867,63868,63869,63870,63872,63873,63874,63875,63876,63877,63878,
+63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891,
+63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904,
+64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076,
+64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089,
+64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102,
+64103,64104,64105,64106,64107,64108,64109,64110,64111,64112,64113,64114,64115,
+64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64128,64129,
+64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142,
+64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155,
+64156,64157,64158,64159,64160,64320,64321,64322,64323,64324,64325,64326,64327,
+64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340,
+64341,64342,64343,64344,64345,64346,64347,17521,28719,15398,28720,17273,64348,
+17720,20795,64349,28721,28722,28723,28724,28725,20796,64350,20844,64351,28727,
+28726,21543,64352,19794,28728,28730,28729,28731,28732,64353,64354,14443,28733,
+14952,64355,28734,28735,15977,28736,13932,28737,28738,28739,28740,18485,28741,
+28742,64356,28743,17780,64357,28744,64358,64359,64360,28745,64361,28746,30525,
+64362,28747,28748,28749,64363,28750,64364,64365,64366,64367,28751,14935,64368,
+28752,28753,28754,28755,28756,28757,28758,28760,64369,64370,21285,28759,64371,
+28761,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,30010,16953,
+64382,64384,30564,64385,64386,64387,64388,30565,30566,64389,64390,30567,64391,
+64392,64393,64394,64395,64396,30568,16948,64397,64398,64399,64400,64401,64402,
+64403,64404,64405,30570,64406,30571,64407,64408,64409,64410,64411,64412,17011,
+64413,64414,64415,64416,64576,64577,64578,64579,64580,64581,64582,64583,64584,
+29808,64585,64586,64587,29807,64588,64589,17001,64590,30561,30562,64591,64592,
+64593,64594,64595,15174,64596,64597,64598,64599,22884,64600,64601,64602,19058,
+16488,28708,64603,14938,64604,64605,18221,64606,64607,64608,17452,64609,64610,
+30572,30573,30574,64611,30576,30575,64612,30577,64613,64614,30580,64615,30579,
+64616,30578,30581,64617,64618,64619,64620,30582,64621,64622,64623,64624,64625,
+64626,64627,64628,64629,28009,64630,28010,28011,64631,30268,64632,64633,64634,
+64635,64636,64637,64638,64640,64641,64642,64643,64644,30269,64645,30270,13862,
+64646,22590,64647,64648,14660,64649,64650,64651,22587,64652,23601,64653,64654,
+64655,64656,64657,64658,19059,64659,30583,64660,64661,64662,64663,64664,64665,
+64666,64667,64668,30584,64669,64670,30585,64671,64672,64832,64833,64834,64835,
+64836,30587,64837,30586,64838,12615,64839,30588,30589,64840,64841,64842,64843,
+64844,30590,64845,64846,64847,64848,64849,64850,64851,64852,64853,64854,64855,
+18027,27700,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866,
+64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879,
+64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892,
+64893,64894,64896,64897,64898,64899,64900,64901,13149,30259,64902,64903,30260,
+16740,30261,30262,30263,30264,30265,30266,18467,30267,64904,64905,64906,64907,
+64908,64909,64910,64911,64912,64913,64914,64915,16762,14632,28008,64916,64917,
+64918,14698,22879,64919,64920,64921,64922,64923,64924,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64925,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64927,N,N,N,N,N,N,N,N,N,64928,
+65088,65089,65090,65091,N,65092,N,65093,65094,N,N,N,65095,N,N,N,N,N,N,65096,
+65097,65098,N,65099,65100,N,N,65101,65102,65103,43349,42738,N,42740,42741,
+42720,42721,42736,42737,42722,42723,42734,42735,42726,42727,42724,42725,42728,
+42729,42730,42731,N,N,N,N,43368,43369,43370,43371,43372,43373,43374,43375,
+43376,43377,N,43378,43379,43380,43381,N,43382,43383,43384,43385,43386,43387,
+43388,43389,43390,43392,43393,43394,43395,43396,N,43397,43398,43399,43400,
+8993,8994,8995,8551,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,
+9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022,
+9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,
+9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,
+9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,9065,9066,9067,
+9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,
+9083,9084,9085,8491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8553,8554,43350,9086,43351,8996,
+};
+
+static const struct unim_index gbcommon_encmap[256] = {
+{__gbcommon_encmap+0,164,252},{__gbcommon_encmap+89,1,220},{__gbcommon_encmap+
+309,81,217},{__gbcommon_encmap+446,145,201},{__gbcommon_encmap+503,1,81},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+584,
+16,59},{__gbcommon_encmap+628,3,153},{__gbcommon_encmap+779,8,191},{
+__gbcommon_encmap+963,18,18},{__gbcommon_encmap+964,96,155},{__gbcommon_encmap
++1024,0,229},{__gbcommon_encmap+1254,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+1316,0,254},{
+__gbcommon_encmap+1571,5,41},{__gbcommon_encmap+1608,32,163},{
+__gbcommon_encmap+1740,142,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__gbcommon_encmap+1812,0,255},{__gbcommon_encmap+2068,0,255},{
+__gbcommon_encmap+2324,0,255},{__gbcommon_encmap+2580,0,255},{
+__gbcommon_encmap+2836,0,255},{__gbcommon_encmap+3092,0,255},{
+__gbcommon_encmap+3348,0,255},{__gbcommon_encmap+3604,0,255},{
+__gbcommon_encmap+3860,0,255},{__gbcommon_encmap+4116,0,255},{
+__gbcommon_encmap+4372,0,255},{__gbcommon_encmap+4628,0,255},{
+__gbcommon_encmap+4884,0,255},{__gbcommon_encmap+5140,0,255},{
+__gbcommon_encmap+5396,0,255},{__gbcommon_encmap+5652,0,255},{
+__gbcommon_encmap+5908,0,255},{__gbcommon_encmap+6164,0,255},{
+__gbcommon_encmap+6420,0,255},{__gbcommon_encmap+6676,0,255},{
+__gbcommon_encmap+6932,0,255},{__gbcommon_encmap+7188,0,255},{
+__gbcommon_encmap+7444,0,255},{__gbcommon_encmap+7700,0,255},{
+__gbcommon_encmap+7956,0,255},{__gbcommon_encmap+8212,0,255},{
+__gbcommon_encmap+8468,0,255},{__gbcommon_encmap+8724,0,255},{
+__gbcommon_encmap+8980,0,255},{__gbcommon_encmap+9236,0,255},{
+__gbcommon_encmap+9492,0,255},{__gbcommon_encmap+9748,0,255},{
+__gbcommon_encmap+10004,0,255},{__gbcommon_encmap+10260,0,255},{
+__gbcommon_encmap+10516,0,255},{__gbcommon_encmap+10772,0,255},{
+__gbcommon_encmap+11028,0,255},{__gbcommon_encmap+11284,0,255},{
+__gbcommon_encmap+11540,0,255},{__gbcommon_encmap+11796,0,255},{
+__gbcommon_encmap+12052,0,255},{__gbcommon_encmap+12308,0,255},{
+__gbcommon_encmap+12564,0,255},{__gbcommon_encmap+12820,0,255},{
+__gbcommon_encmap+13076,0,255},{__gbcommon_encmap+13332,0,255},{
+__gbcommon_encmap+13588,0,255},{__gbcommon_encmap+13844,0,255},{
+__gbcommon_encmap+14100,0,255},{__gbcommon_encmap+14356,0,255},{
+__gbcommon_encmap+14612,0,255},{__gbcommon_encmap+14868,0,255},{
+__gbcommon_encmap+15124,0,255},{__gbcommon_encmap+15380,0,255},{
+__gbcommon_encmap+15636,0,255},{__gbcommon_encmap+15892,0,255},{
+__gbcommon_encmap+16148,0,255},{__gbcommon_encmap+16404,0,255},{
+__gbcommon_encmap+16660,0,255},{__gbcommon_encmap+16916,0,255},{
+__gbcommon_encmap+17172,0,255},{__gbcommon_encmap+17428,0,255},{
+__gbcommon_encmap+17684,0,255},{__gbcommon_encmap+17940,0,255},{
+__gbcommon_encmap+18196,0,255},{__gbcommon_encmap+18452,0,255},{
+__gbcommon_encmap+18708,0,255},{__gbcommon_encmap+18964,0,255},{
+__gbcommon_encmap+19220,0,255},{__gbcommon_encmap+19476,0,255},{
+__gbcommon_encmap+19732,0,255},{__gbcommon_encmap+19988,0,255},{
+__gbcommon_encmap+20244,0,255},{__gbcommon_encmap+20500,0,255},{
+__gbcommon_encmap+20756,0,255},{__gbcommon_encmap+21012,0,255},{
+__gbcommon_encmap+21268,0,255},{__gbcommon_encmap+21524,0,255},{
+__gbcommon_encmap+21780,0,255},{__gbcommon_encmap+22036,0,255},{
+__gbcommon_encmap+22292,0,255},{__gbcommon_encmap+22548,0,165},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{__gbcommon_encmap+22714,44,241},{__gbcommon_encmap+22912,12,41},{0,0,0},{0,
+0,0},{0,0,0},{__gbcommon_encmap+22942,48,107},{__gbcommon_encmap+23002,1,229},
+};
+
+static const ucs2_t __gb18030ext_decmap[2729] = {
+58566,58567,58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578,
+58579,58580,58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591,
+58592,58593,58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604,
+58605,58606,58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617,
+58618,58619,58620,58621,58622,58623,58624,58625,58626,58627,58628,U,58629,
+58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,58642,
+58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,58655,
+58656,58657,58658,58659,58660,58661,58662,58663,58664,58665,58666,58667,58668,
+58669,58670,58671,58672,58673,58674,58675,58676,58677,58678,58679,58680,58681,
+58682,58683,58684,58685,58686,58687,58688,58689,58690,58691,58692,58693,58694,
+58695,58696,58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,
+58708,58709,58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,
+58721,58722,58723,58724,U,58725,58726,58727,58728,58729,58730,58731,58732,
+58733,58734,58735,58736,58737,58738,58739,58740,58741,58742,58743,58744,58745,
+58746,58747,58748,58749,58750,58751,58752,58753,58754,58755,58756,58757,U,U,U,
+U,U,U,U,U,U,U,59238,59239,59240,59241,59242,59243,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8364,
+59245,U,U,U,U,U,U,U,U,U,U,59246,59247,U,U,U,U,U,U,U,U,U,U,U,U,59248,59249,
+58758,58759,58760,58761,58762,58763,58764,58765,58766,58767,58768,58769,58770,
+58771,58772,58773,58774,58775,58776,58777,58778,58779,58780,58781,58782,58783,
+58784,58785,58786,58787,58788,58789,58790,58791,58792,58793,58794,58795,58796,
+58797,58798,58799,58800,58801,58802,58803,58804,58805,58806,58807,58808,58809,
+58810,58811,58812,58813,58814,58815,58816,58817,58818,58819,58820,U,58821,
+58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,58832,58833,58834,
+58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,58845,58846,58847,
+58848,58849,58850,58851,58852,58853,58854,58855,58856,58857,58858,58859,58860,
+58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,58872,58873,
+58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,58885,58886,
+58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,58898,58899,
+58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,58911,58912,
+58913,58914,58915,58916,U,58917,58918,58919,58920,58921,58922,58923,58924,
+58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,58937,
+58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,59250,59251,59252,59253,59254,59255,59256,59257,59258,59259,59260,58950,
+58951,58952,58953,58954,58955,58956,58957,58958,58959,58960,58961,58962,58963,
+58964,58965,58966,58967,58968,58969,58970,58971,58972,58973,58974,58975,58976,
+58977,58978,58979,58980,58981,58982,58983,58984,58985,58986,58987,58988,58989,
+58990,58991,58992,58993,58994,58995,58996,58997,58998,58999,59000,59001,59002,
+59003,59004,59005,59006,59007,59008,59009,59010,59011,59012,U,59013,59014,
+59015,59016,59017,59018,59019,59020,59021,59022,59023,59024,59025,59026,59027,
+59028,59029,59030,59031,59032,59033,59034,59035,59036,59037,59038,59039,59040,
+59041,59042,59043,59044,59045,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59261,59262,59263,59264,59265,
+59266,59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,
+59056,59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,
+59069,59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,
+59082,59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,
+59095,59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,
+59108,U,59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,
+59120,59121,59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,
+59133,59134,59135,59136,59137,59138,59139,59140,59141,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,59269,59270,59271,59272,59273,59274,59275,59276,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59277,59278,59279,59280,59281,59282,
+59283,U,U,U,U,U,U,U,U,U,U,U,U,59284,59285,U,U,U,U,U,59286,U,U,59287,59288,
+59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,59146,59147,
+59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,59159,59160,
+59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,59172,59173,
+59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,59185,59186,
+59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,59198,59199,
+59200,59201,59202,59203,59204,U,59205,59206,59207,59208,59209,59210,59211,
+59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,59224,
+59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,59237,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59296,59297,
+59298,59299,59300,59301,59302,59303,59304,59305,59306,59307,59308,59309,59310,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59311,59312,
+59313,59314,59315,59316,59317,59318,59319,59320,59321,59322,59323,59324,59325,
+59326,59327,59328,59329,59330,59331,59332,59333,59334,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59335,U,U,505,U,59337,59338,59339,59340,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59341,59342,
+59343,59344,59345,59346,59347,59348,59349,59350,59351,59352,59353,59354,59355,
+59356,59357,59358,59359,59360,59361,59362,U,U,59363,U,59364,59365,59366,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+12350,12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283,
+U,59380,59381,59382,59383,59384,59385,59386,59387,59388,59389,59390,59391,
+59392,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,59393,59394,59395,59396,59397,59398,59399,59400,59401,59402,59403,59404,
+59405,59406,59407,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353,
+57354,57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366,
+57367,57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379,
+57380,57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392,
+57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405,
+57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418,
+57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431,
+57432,57433,57434,57435,57436,57437,57438,57439,57440,57441,57442,57443,57444,
+57445,57446,57447,57448,57449,57450,57451,57452,57453,57454,57455,57456,57457,
+57458,57459,57460,57461,57462,57463,57464,57465,57466,57467,57468,57469,57470,
+57471,57472,57473,57474,57475,57476,57477,57478,57479,57480,57481,57482,57483,
+57484,57485,57486,57487,57488,57489,57490,57491,57492,57493,57494,57495,57496,
+57497,57498,57499,57500,57501,57502,57503,57504,57505,57506,57507,57508,57509,
+57510,57511,57512,57513,57514,57515,57516,57517,57518,57519,57520,57521,57522,
+57523,57524,57525,57526,57527,57528,57529,57530,57531,57532,57533,57534,57535,
+57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,57548,
+57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,57561,
+57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,57574,
+57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,57587,
+57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,57600,
+57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,57613,
+57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,57626,
+57627,57628,57629,57630,57631,57632,57633,57634,57635,57636,57637,57638,57639,
+57640,57641,57642,57643,57644,57645,57646,57647,57648,57649,57650,57651,57652,
+57653,57654,57655,57656,57657,57658,57659,57660,57661,57662,57663,57664,57665,
+57666,57667,57668,57669,57670,57671,57672,57673,57674,57675,57676,57677,57678,
+57679,57680,57681,57682,57683,57684,57685,57686,57687,57688,57689,57690,57691,
+57692,57693,57694,57695,57696,57697,57698,57699,57700,57701,57702,57703,57704,
+57705,57706,57707,57708,57709,57710,57711,57712,57713,57714,57715,57716,57717,
+57718,57719,57720,57721,57722,57723,57724,57725,57726,57727,57728,57729,57730,
+57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,57742,57743,
+57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,57755,57756,
+57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,57768,57769,
+57770,57771,57772,57773,57774,57775,57776,57777,57778,57779,57780,57781,57782,
+57783,57784,57785,57786,57787,57788,57789,57790,57791,57792,57793,57794,57795,
+57796,57797,57798,57799,57800,57801,57802,57803,57804,57805,57806,57807,57808,
+57809,57810,57811,57812,57813,57814,57815,57816,57817,57818,57819,57820,57821,
+57822,57823,57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834,
+57835,57836,57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847,
+57848,57849,57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860,
+57861,57862,57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873,
+57874,57875,57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886,
+57887,57888,57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899,
+57900,57901,57902,57903,57904,57905,57906,57907,59408,59409,59410,59411,59412,
+57908,57909,57910,57911,57912,57913,57914,57915,57916,57917,57918,57919,57920,
+57921,57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,
+57934,57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,
+57947,57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,
+57960,57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,
+57973,57974,57975,57976,57977,57978,57979,57980,57981,57982,57983,57984,57985,
+57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,
+57999,58000,58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,
+58012,58013,58014,58015,58016,58017,58018,58019,58020,58021,58022,58023,58024,
+58025,58026,58027,58028,58029,58030,58031,58032,58033,58034,58035,58036,58037,
+58038,58039,58040,58041,58042,58043,58044,58045,58046,58047,58048,58049,58050,
+58051,58052,58053,58054,58055,58056,58057,58058,58059,58060,58061,58062,58063,
+58064,58065,58066,58067,58068,58069,58070,58071,58072,58073,58074,58075,58076,
+58077,58078,58079,58080,58081,58082,58083,58084,58085,58086,58087,58088,58089,
+58090,58091,58092,58093,58094,58095,58096,58097,58098,58099,58100,58101,58102,
+58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,58114,58115,
+58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,58127,58128,
+58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,58140,58141,
+58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,58153,58154,
+58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,58166,58167,
+58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,58179,58180,
+58181,58182,58183,58184,58185,58186,58187,58188,58189,58190,58191,58192,58193,
+58194,58195,58196,58197,58198,58199,58200,58201,58202,58203,58204,58205,58206,
+58207,58208,58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219,
+58220,58221,58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232,
+58233,58234,58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245,
+58246,58247,58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258,
+58259,58260,58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271,
+58272,58273,58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,58284,
+58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,58295,58296,58297,
+58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,58308,58309,58310,
+58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,58321,58322,58323,
+58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,58334,58335,58336,
+58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,58347,58348,58349,
+58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,58360,58361,58362,
+58363,58364,58365,58366,58367,58368,58369,58370,58371,58372,58373,58374,58375,
+58376,58377,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,
+58389,58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,
+58402,58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,
+58415,58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,
+58428,58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,
+58441,58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,
+58454,58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,
+58467,58468,58469,58470,58471,11905,59414,59415,59416,11908,13427,13383,11912,
+11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,14815,14963,
+14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,16735,11950,
+17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017,17996,59459,
+U,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821,18822,
+18847,18843,18871,18870,59476,59477,19619,19615,19616,19617,19575,19618,19731,
+19732,19733,19734,19735,19736,19737,19886,59492,58472,58473,58474,58475,58476,
+58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488,58489,
+58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501,58502,
+58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514,58515,
+58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527,58528,
+58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540,58541,
+58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553,58554,
+58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565,
+};
+
+static const struct dbcs_index gb18030ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap+0,64,
+160},{__gb18030ext_decmap+97,64,254},{__gb18030ext_decmap+288,64,160},{
+__gb18030ext_decmap+385,64,254},{__gb18030ext_decmap+576,64,254},{
+__gb18030ext_decmap+767,64,254},{__gb18030ext_decmap+958,64,254},{
+__gb18030ext_decmap+1149,150,254},{__gb18030ext_decmap+1254,88,254},{
+__gb18030ext_decmap+1421,161,254},{__gb18030ext_decmap+1515,161,254},{
+__gb18030ext_decmap+1609,161,254},{__gb18030ext_decmap+1703,161,254},{
+__gb18030ext_decmap+1797,161,254},{__gb18030ext_decmap+1891,161,254},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__gb18030ext_decmap+1985,250,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap
++1990,161,254},{__gb18030ext_decmap+2084,161,254},{__gb18030ext_decmap+2178,
+161,254},{__gb18030ext_decmap+2272,161,254},{__gb18030ext_decmap+2366,161,254
+},{__gb18030ext_decmap+2460,161,254},{__gb18030ext_decmap+2554,80,254},{0,0,0
+},
+};
+
+static const DBCHAR __gb18030ext_encmap[3227] = {
+43199,41699,65104,N,N,65108,N,N,N,65111,N,N,65112,65117,N,N,N,N,N,N,N,N,N,N,
+65118,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,N,65134,N,N,N,65137,N,N,N,N,65139,
+N,N,65140,65141,N,N,N,65145,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65156,43402,43403,
+43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43401,65110,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65109,65114,65116,N,N,N,N,N,N,N,N,N,N,N,65115,65120,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65119,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65122,65125,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65123,
+65124,65128,65129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65130,65135,65136,65138,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65144,N,N,N,N,65143,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65146,65147,65149,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65148,65152,N,N,N,N,N,65153,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65155,65157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65158,
+N,N,65159,N,N,N,N,65160,65161,N,65162,65163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,65165,N,N,N,65164,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65167,
+65166,65174,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65171,65172,65173,65175,65170,65176,65177,65178,65179,65180,65181,
+65182,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65183,
+43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693,
+43694,43695,43696,43697,43698,43699,43700,43701,43702,43703,43704,43705,43706,
+43707,43708,43709,43710,43711,43712,43713,43714,43715,43716,43717,43718,43719,
+43720,43721,43722,43723,43724,43725,43726,43727,43728,43729,43730,43731,43732,
+43733,43734,43735,43736,43737,43738,43739,43740,43741,43742,43743,43744,43745,
+43746,43747,43748,43749,43750,43751,43752,43753,43754,43755,43756,43757,43758,
+43759,43760,43761,43762,43763,43764,43765,43766,43767,43768,43769,43770,43771,
+43772,43773,43774,43937,43938,43939,43940,43941,43942,43943,43944,43945,43946,
+43947,43948,43949,43950,43951,43952,43953,43954,43955,43956,43957,43958,43959,
+43960,43961,43962,43963,43964,43965,43966,43967,43968,43969,43970,43971,43972,
+43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985,
+43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998,
+43999,44000,44001,44002,44003,44004,44005,44006,44007,44008,44009,44010,44011,
+44012,44013,44014,44015,44016,44017,44018,44019,44020,44021,44022,44023,44024,
+44025,44026,44027,44028,44029,44030,44193,44194,44195,44196,44197,44198,44199,
+44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212,
+44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225,
+44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238,
+44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251,
+44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264,
+44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277,
+44278,44279,44280,44281,44282,44283,44284,44285,44286,44449,44450,44451,44452,
+44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465,
+44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478,
+44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491,
+44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504,
+44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517,
+44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530,
+44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44705,
+44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,
+44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,
+44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744,
+44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757,
+44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770,
+44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783,
+44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796,
+44797,44798,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,
+44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984,
+44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997,
+44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010,
+45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023,
+45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036,
+45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049,
+45050,45051,45052,45053,45054,63649,63650,63651,63652,63653,63654,63655,63656,
+63657,63658,63659,63660,63661,63662,63663,63664,63665,63666,63667,63668,63669,
+63670,63671,63672,63673,63674,63675,63676,63677,63678,63679,63680,63681,63682,
+63683,63684,63685,63686,63687,63688,63689,63690,63691,63692,63693,63694,63695,
+63696,63697,63698,63699,63700,63701,63702,63703,63704,63705,63706,63707,63708,
+63709,63710,63711,63712,63713,63714,63715,63716,63717,63718,63719,63720,63721,
+63722,63723,63724,63725,63726,63727,63728,63729,63730,63731,63732,63733,63734,
+63735,63736,63737,63738,63739,63740,63741,63742,63905,63906,63907,63908,63909,
+63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922,
+63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935,
+63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948,
+63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961,
+63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974,
+63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987,
+63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,64161,64162,
+64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175,
+64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188,
+64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201,
+64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214,
+64215,64216,64217,64218,64219,64220,64221,64222,64223,64224,64225,64226,64227,
+64228,64229,64230,64231,64232,64233,64234,64235,64236,64237,64238,64239,64240,
+64241,64242,64243,64244,64245,64246,64247,64248,64249,64250,64251,64252,64253,
+64254,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428,
+64429,64430,64431,64432,64433,64434,64435,64436,64437,64438,64439,64440,64441,
+64442,64443,64444,64445,64446,64447,64448,64449,64450,64451,64452,64453,64454,
+64455,64456,64457,64458,64459,64460,64461,64462,64463,64464,64465,64466,64467,
+64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480,
+64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493,
+64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506,
+64507,64508,64509,64510,64673,64674,64675,64676,64677,64678,64679,64680,64681,
+64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694,
+64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707,
+64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720,
+64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733,
+64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746,
+64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759,
+64760,64761,64762,64763,64764,64765,64766,64929,64930,64931,64932,64933,64934,
+64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947,
+64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960,
+64961,64962,64963,64964,64965,64966,64967,64968,64969,64970,64971,64972,64973,
+64974,64975,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,
+64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,
+65000,65001,65002,65003,65004,65005,65006,65007,65008,65009,65010,65011,65012,
+65013,65014,65015,65016,65017,65018,65019,65020,65021,65022,65185,65186,65187,
+65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200,
+65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213,
+65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226,
+65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239,
+65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252,
+65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265,
+65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65277,65278,
+41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292,
+41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305,
+41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318,
+41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331,
+41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41344,41345,
+41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358,
+41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371,
+41372,41373,41374,41375,41376,41536,41537,41538,41539,41540,41541,41542,41543,
+41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556,
+41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569,
+41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582,
+41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595,
+41596,41597,41598,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609,
+41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622,
+41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41792,41793,41794,
+41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807,
+41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820,
+41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833,
+41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846,
+41847,41848,41849,41850,41851,41852,41853,41854,41856,41857,41858,41859,41860,
+41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873,
+41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886,
+41887,41888,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058,
+42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071,
+42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084,
+42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097,
+42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110,
+42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124,
+42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135,42136,42137,
+42138,42139,42140,42141,42142,42143,42144,42304,42305,42306,42307,42308,42309,
+42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322,
+42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335,
+42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348,
+42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361,
+42362,42363,42364,42365,42366,42368,42369,42370,42371,42372,42373,42374,42375,
+42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388,
+42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42560,
+42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573,
+42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586,
+42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599,
+42600,42601,42602,42603,42604,42605,42606,42607,42608,42609,42610,42611,42612,
+42613,42614,42615,42616,42617,42618,42619,42620,42621,42622,42624,42625,42626,
+42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639,
+42640,42641,42642,42643,42644,42645,42646,42647,42648,42649,42650,42651,42652,
+42653,42654,42655,42656,42816,42817,42818,42819,42820,42821,42822,42823,42824,
+42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837,
+42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850,
+42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863,
+42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,
+42877,42878,42880,42881,42882,42883,42884,42885,42886,42887,42888,42889,42890,
+42891,42892,42893,42894,42895,42896,42897,42898,42899,42900,42901,42902,42903,
+42904,42905,42906,42907,42908,42909,42910,42911,42912,41643,41644,41645,41646,
+41647,41648,N,41700,41711,41712,41725,41726,42228,42229,42230,42231,42232,
+42233,42234,42235,42236,42237,42238,42487,42488,42489,42490,42491,42492,42493,
+42494,42681,42682,42683,42684,42685,42686,42687,42688,42713,42714,42715,42716,
+42717,42718,42719,42732,42733,42739,42742,42743,42744,42745,42746,42747,42748,
+42749,42750,42946,42947,42948,42949,42950,42951,42952,42953,42954,42955,42956,
+42957,42958,42959,42960,42994,42995,42996,42997,42998,42999,43000,43001,43002,
+43003,43004,43005,43006,43158,43159,43160,43161,43162,43163,43164,43165,43166,
+43167,43168,43196,N,43201,43202,43203,43204,43242,43243,43244,43245,43246,
+43247,43248,43249,43250,43251,43252,43253,43254,43255,43256,43257,43258,43259,
+43260,43261,43262,43352,43355,43357,43358,43359,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427,
+43504,43505,43506,43507,43508,43509,43510,43511,43512,43513,43514,43515,43516,
+43517,43518,55290,55291,55292,55293,55294,N,65105,65106,65107,N,N,N,N,N,65113,
+N,N,N,N,N,N,N,65121,N,N,N,N,65126,65127,N,N,N,N,65132,65133,N,N,N,N,N,N,N,N,
+65142,N,N,N,N,N,N,N,65150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65168,65169,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,65184,
+};
+
+static const struct unim_index gb18030ext_encmap[256] = {
+{0,0,0},{__gb18030ext_encmap+0,249,249},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+1,172,172
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+2,129,202},{
+__gb18030ext_encmap+76,240,251},{__gb18030ext_encmap+88,62,62},{0,0,0},{0,0,0
+},{0,0,0},{__gb18030ext_encmap+89,71,115},{__gb18030ext_encmap+134,158,158},{
+__gb18030ext_encmap+135,14,26},{0,0,0},{0,0,0},{__gb18030ext_encmap+148,24,223
+},{__gb18030ext_encmap+348,115,115},{__gb18030ext_encmap+349,78,78},{
+__gb18030ext_encmap+350,110,224},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+
+465,86,86},{__gb18030ext_encmap+466,95,95},{0,0,0},{__gb18030ext_encmap+467,
+55,221},{__gb18030ext_encmap+634,214,214},{0,0,0},{__gb18030ext_encmap+635,76,
+97},{__gb18030ext_encmap+657,35,141},{0,0,0},{__gb18030ext_encmap+764,71,183},
+{0,0,0},{0,0,0},{__gb18030ext_encmap+877,119,163},{__gb18030ext_encmap+922,19,
+174},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{__gb18030ext_encmap+1078,0,255},{__gb18030ext_encmap+1334,0,255
+},{__gb18030ext_encmap+1590,0,255},{__gb18030ext_encmap+1846,0,255},{
+__gb18030ext_encmap+2102,0,255},{__gb18030ext_encmap+2358,0,255},{
+__gb18030ext_encmap+2614,0,255},{__gb18030ext_encmap+2870,0,255},{
+__gb18030ext_encmap+3126,0,100},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+
+static const struct _gb18030_to_unibmp_ranges {
+ Py_UNICODE first, last;
+ DBCHAR base;
+} gb18030_to_unibmp_ranges[] = {
+{128,163,0},{165,166,36},{169,175,38},{178,182,45},{184,214,50},{216,223,81},{
+226,231,89},{235,235,95},{238,241,96},{244,246,100},{248,248,103},{251,251,104
+},{253,256,105},{258,274,109},{276,282,126},{284,298,133},{300,323,148},{325,
+327,172},{329,332,175},{334,362,179},{364,461,208},{463,463,306},{465,465,307
+},{467,467,308},{469,469,309},{471,471,310},{473,473,311},{475,475,312},{477,
+504,313},{506,592,341},{594,608,428},{610,710,443},{712,712,544},{716,728,545
+},{730,912,558},{930,930,741},{938,944,742},{962,962,749},{970,1024,750},{1026
+,1039,805},{1104,1104,819},{1106,8207,820},{8209,8210,7922},{8215,8215,7924},{
+8218,8219,7925},{8222,8228,7927},{8231,8239,7934},{8241,8241,7943},{8244,8244,
+7944},{8246,8250,7945},{8252,8363,7950},{8365,8450,8062},{8452,8452,8148},{
+8454,8456,8149},{8458,8469,8152},{8471,8480,8164},{8482,8543,8174},{8556,8559,
+8236},{8570,8591,8240},{8596,8597,8262},{8602,8711,8264},{8713,8718,8374},{
+8720,8720,8380},{8722,8724,8381},{8726,8729,8384},{8731,8732,8388},{8737,8738,
+8390},{8740,8740,8392},{8742,8742,8393},{8748,8749,8394},{8751,8755,8396},{
+8760,8764,8401},{8766,8775,8406},{8777,8779,8416},{8781,8785,8419},{8787,8799,
+8424},{8802,8803,8437},{8808,8813,8439},{8816,8852,8445},{8854,8856,8482},{
+8858,8868,8485},{8870,8894,8496},{8896,8977,8521},{8979,9311,8603},{9322,9331,
+8936},{9372,9471,8946},{9548,9551,9046},{9588,9600,9050},{9616,9618,9063},{
+9622,9631,9066},{9634,9649,9076},{9652,9659,9092},{9662,9669,9100},{9672,9674,
+9108},{9676,9677,9111},{9680,9697,9113},{9702,9732,9131},{9735,9736,9162},{
+9738,9791,9164},{9793,9793,9218},{9795,11904,9219},{11906,11907,11329},{11909,
+11911,11331},{11913,11914,11334},{11917,11926,11336},{11928,11942,11346},{
+11944,11945,11361},{11947,11949,11363},{11951,11954,11366},{11956,11957,11370
+},{11960,11962,11372},{11964,11977,11375},{11979,12271,11389},{12284,12287,
+11682},{12292,12292,11686},{12312,12316,11687},{12319,12320,11692},{12330,
+12349,11694},{12351,12352,11714},{12436,12442,11716},{12447,12448,11723},{
+12535,12539,11725},{12543,12548,11730},{12586,12831,11736},{12842,12848,11982
+},{12850,12962,11989},{12964,13197,12102},{13200,13211,12336},{13215,13216,
+12348},{13218,13251,12350},{13253,13261,12384},{13263,13264,12393},{13267,
+13268,12395},{13270,13382,12397},{13384,13426,12510},{13428,13725,12553},{
+13727,13837,12851},{13839,13849,12962},{13851,14615,12973},{14617,14701,13738
+},{14703,14798,13823},{14801,14814,13919},{14816,14962,13933},{14964,15181,
+14080},{15183,15469,14298},{15471,15583,14585},{15585,16469,14698},{16471,
+16734,15583},{16736,17206,15847},{17208,17323,16318},{17325,17328,16434},{
+17330,17372,16438},{17374,17621,16481},{17623,17995,16729},{17997,18016,17102
+},{18018,18210,17122},{18212,18216,17315},{18218,18299,17320},{18301,18316,
+17402},{18318,18758,17418},{18760,18809,17859},{18811,18812,17909},{18814,
+18817,17911},{18820,18820,17915},{18823,18842,17916},{18844,18846,17936},{
+18848,18869,17939},{18872,19574,17961},{19576,19614,18664},{19620,19730,18703
+},{19738,19885,18814},{19887,19967,18962},{40870,55295,19043},{59244,59244,
+33469},{59336,59336,33470},{59367,59379,33471},{59413,59413,33484},{59417,
+59421,33485},{59423,59429,33490},{59431,59434,33497},{59437,59440,33501},{
+59443,59450,33505},{59452,59458,33513},{59460,59475,33520},{59478,59491,33536
+},{59493,63787,33550},{63789,63864,37845},{63866,63892,37921},{63894,63974,
+37948},{63976,63984,38029},{63986,64011,38038},{64016,64016,38064},{64018,
+64018,38065},{64021,64023,38066},{64025,64030,38069},{64034,64034,38075},{
+64037,64038,38076},{64042,65071,38078},{65074,65074,39108},{65093,65096,39109
+},{65107,65107,39113},{65112,65112,39114},{65127,65127,39115},{65132,65280,
+39116},{65375,65503,39265},{65510,65535,39394},{0,0,39420}};
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/mappings_hk.h b/sys/src/cmd/python/Modules/cjkcodecs/mappings_hk.h
new file mode 100644
index 000000000..a526e90d5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/mappings_hk.h
@@ -0,0 +1,2340 @@
+static const ucs2_t __big5hkscs_decmap[6095] = {
+62211,62212,62213,62214,62215,268,62217,209,205,62220,62221,203,8168,62224,
+202,62226,62227,62228,62229,270,62231,62232,256,193,461,192,274,201,282,200,
+332,211,465,210,62245,7870,62247,7872,202,257,225,462,224,593,275,233,283,232,
+299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,476,252,62276,7871,62278,
+7873,234,609,62282,62283,41897,4421,U,25866,U,U,20029,28381,40270,37343,U,U,
+30517,25745,20250,20264,20392,20822,20852,20892,20964,21153,21160,21307,21326,
+21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,23455,23706,24198,
+24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,32442,32455,32463,
+32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,36711,36718,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29713,31996,
+32205,26950,31433,21031,U,U,U,U,37260,30904,37214,32956,U,36107,33014,2535,U,
+U,32927,40647,19661,40393,40460,19518,40438,28686,40458,41267,13761,U,28314,
+33342,29977,U,18705,39532,39567,40857,31111,33900,7626,1488,10982,20004,20097,
+20096,20103,20159,20203,20279,13388,20413,15944,20483,20616,13437,13459,13477,
+20870,22789,20955,20988,20997,20105,21113,21136,21287,13767,21417,13649,21424,
+13651,21442,21539,13677,13682,13953,21651,21667,21684,21689,21712,21743,21784,
+21795,21800,13720,21823,13733,13759,21975,13765,32132,21797,U,3138,3349,20779,
+21904,11462,14828,833,36422,19896,38117,16467,32958,30586,11320,14900,18389,
+33117,27122,19946,25821,3452,4020,3285,4340,25741,36478,3734,3083,3940,11433,
+33366,17619,U,3398,39501,33001,18420,20135,11458,39602,14951,38388,16365,
+13574,21191,38868,30920,11588,40302,38933,U,17369,24741,25780,21731,11596,
+11210,4215,14843,4207,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,26330,26390,31136,25834,20562,3139,36456,8609,35660,1841,U,18443,
+425,16378,22643,11661,U,17864,1276,24727,3916,3478,21881,16571,17338,U,19124,
+10854,4253,33194,39157,3484,25465,14846,10101,36288,22177,25724,15939,U,42497,
+3593,10959,11465,U,4296,14786,14738,14854,33435,13688,24137,8391,22098,3889,
+11442,38688,13500,27709,20027,U,U,30068,11915,8712,42587,36045,3706,3124,
+26652,32659,4303,10243,10553,13819,20963,3724,3981,3754,16275,3888,3399,4431,
+3660,U,3755,2985,3400,4288,4413,16377,9878,25650,4013,13300,30265,11214,3454,
+3455,11345,11349,14872,3736,4295,3886,42546,27472,36050,36249,36042,38314,
+21708,33476,21945,U,40643,39974,39606,30558,11758,28992,33133,33004,23580,
+25970,33076,14231,21343,32957,37302,3834,3599,3703,3835,13789,19947,13833,
+3286,22191,10165,4297,3600,3704,4216,4424,33287,5205,3705,20048,11684,23124,
+4125,4126,4341,4342,22428,3601,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,30356,33485,4021,3707,20862,14083,4022,4480,21208,41661,
+18906,6202,16759,33404,22681,21096,13850,22333,31666,23400,18432,19244,40743,
+18919,39967,39821,23412,12605,22011,13810,22153,20008,22786,7105,63608,38737,
+134,20059,20155,13630,23587,24401,24516,14586,25164,25909,27514,27701,27706,
+28780,29227,20012,29357,18665,32594,31035,31993,32595,25194,13505,U,25419,
+32770,32896,26130,26961,21341,34916,35265,30898,35744,36125,38021,38264,38271,
+38376,36367,38886,39029,39118,39134,39267,38928,40060,40479,40644,27503,63751,
+20023,135,38429,25143,38050,20539,28158,40051,62842,15817,34959,16718,28791,
+23797,19232,20941,13657,23856,24866,35378,36775,37366,29073,26393,29626,12929,
+41223,15499,6528,19216,30948,29698,20910,34575,16393,27235,41658,16931,34319,
+U,31274,39239,35562,38741,28749,21284,8318,37876,30425,35299,62884,30685,
+20131,20464,20668,20015,20247,62891,21556,32139,22674,22736,7606,24210,24217,
+24514,10002,25995,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,13305,26905,27203,15459,27903,U,29184,17669,29580,16091,18963,23317,
+29881,35715,23716,22165,31379,31724,31939,32364,33528,34199,62924,34960,62926,
+36537,62928,36815,34143,39392,37409,62933,36281,5183,16497,17058,23066,U,U,U,
+39016,26475,17014,22333,U,34262,18811,33471,28941,19585,28020,23931,27413,
+28606,62956,62957,23446,62959,U,32347,23870,23880,23894,15868,14351,23972,
+23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,24893,
+23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,14851,25570,
+25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,26111,26195,
+15090,26258,15138,26390,15170,26532,26624,15192,26698,26756,15218,15217,15227,
+26889,26947,29276,26980,27039,27013,15292,27094,15325,27237,27252,27249,27266,
+15340,27289,15346,27307,27317,27348,27382,27521,27585,27626,27765,27818,15563,
+27906,27910,27942,28033,15599,28068,28081,28181,28184,28201,28294,35264,28347,
+28386,28378,40831,28392,28393,28452,28468,15686,16193,28545,28606,15722,15733,
+29111,23705,15754,28716,15761,28752,28756,28783,28799,28809,805,17345,13809,
+3800,16087,22462,28371,28990,22496,13902,27042,35817,23412,31305,22753,38105,
+31333,31357,22956,31419,31408,31426,31427,29137,25741,16842,31450,31453,31466,
+16879,21682,23553,31499,31573,31529,21262,23806,31650,31599,33692,23476,27775,
+31696,33825,31634,U,23840,15789,23653,33938,31738,U,31797,23745,31812,31875,
+18562,31910,26237,17784,31945,31943,31974,31860,31987,31989,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32359,17693,28228,32093,
+28374,29837,32137,32171,28981,32179,U,16471,24617,32228,15635,32245,6137,
+32229,33645,U,24865,24922,32366,32402,17195,37996,32295,32576,32577,32583,
+31030,25296,39393,32663,25425,32675,5729,104,17756,14182,17667,33594,32762,
+25737,U,32776,32797,U,32815,41095,27843,32827,32828,32865,10004,18825,26150,
+15843,26344,26405,32935,35400,33031,33050,22704,9974,27775,25752,20408,25831,
+5258,33304,6238,27219,19045,19093,17530,33321,2829,27218,15742,20473,5373,
+34018,33634,27402,18855,13616,6003,15864,33450,26907,63892,16859,34123,33488,
+33562,3606,6068,14017,12669,13658,33403,33506,33560,16011,28067,27397,27543,
+13774,15807,33565,21996,33669,17675,28069,33708,U,33747,13438,28372,27223,
+34138,13462,28226,12015,33880,23524,33905,15827,17636,27303,33866,15541,31064,
+U,27542,28279,28227,34014,U,33681,17568,33939,34020,23697,16960,23744,17731,
+34100,23282,28313,17703,34163,17686,26559,34326,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34341,34363,34241,28808,34306,5506,
+28877,63922,17770,34344,13896,6306,21495,29594,34430,34673,41208,34798,11303,
+34737,34778,34831,22113,34412,26710,17935,34885,34886,30176,15801,30180,34910,
+34972,18011,34996,34997,25537,35013,30583,30479,35207,35210,U,U,35239,35260,
+35365,35303,31012,31421,35484,30611,37374,35472,31321,31465,31546,16271,18195,
+31544,29052,35596,35615,21552,21861,35647,35660,35661,35497,19066,35728,35739,
+35503,5855,17941,34895,35995,32084,32143,63956,14117,32083,36054,32152,32189,
+36114,36099,6416,36059,28764,36113,19657,16080,36265,32770,4116,18826,15228,
+33212,28940,31463,36525,36534,36547,37588,36633,36653,33637,33810,36773,37635,
+41631,2640,36787,18730,35294,34109,15803,24312,12898,36857,40980,34492,34049,
+8997,14720,28375,36919,34108,31422,36961,34156,34315,37032,34579,37060,34534,
+37038,U,37223,15088,37289,37316,31916,35123,7817,37390,27807,37441,37474,
+21945,U,35526,15515,35596,21979,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,3377,37676,37739,35553,35819,28815,23235,35554,35557,
+18789,37444,35820,35897,35839,37747,37979,36540,38277,38310,37926,38304,28662,
+17081,9850,34520,4732,15918,18911,27676,38523,38550,16748,38563,28373,25050,
+38582,30965,35552,38589,21452,18849,27832,628,25616,37039,37093,19153,6421,
+13066,38705,34370,38710,18959,17725,17797,19177,28789,23361,38683,U,37333,
+38743,23370,37355,38751,37925,20688,12471,12476,38793,38815,38833,38846,38848,
+38866,38880,21612,38894,29724,37939,U,38901,37917,31098,19153,38964,38963,
+38987,39014,15118,29045,15697,1584,16732,22278,39114,39095,39112,39111,19199,
+27943,5843,21936,39137,39142,39148,37752,39225,18985,19314,38999,39173,39413,
+39436,39483,39440,39512,22309,14020,37041,39893,39648,39650,39685,39668,19470,
+39700,39725,34304,20532,39732,27048,14531,12413,39760,39744,40254,23109,6243,
+39822,16971,39938,39935,39948,40552,40404,40887,41362,41387,41185,41251,41439,
+40318,40323,41268,40462,26760,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,40388,8539,41363,41504,6459,41523,40249,41145,41652,40592,
+40597,40606,40610,19764,40618,40623,17252,40641,15200,14821,15645,20274,14270,
+35883,40706,40712,19350,37924,28066,40727,U,40761,22175,22154,40773,39352,
+37003,38898,33919,40802,40809,31452,40846,29206,19390,18805,18875,29047,18936,
+17224,19025,29598,35802,6394,31135,35198,36406,37737,37875,35396,37612,37761,
+37835,35180,17593,29207,16107,30578,31299,28880,17523,17400,29054,6127,28835,
+6334,13721,16071,6277,21551,6136,14114,5883,6201,14049,6004,6353,24395,14115,
+5824,22363,18981,5118,4776,5062,5302,34051,13990,U,33877,18836,29029,15921,
+21852,16123,28754,17652,14062,39325,28454,26617,14131,15381,15847,22636,6434,
+26640,16471,14143,16609,16523,16655,27681,21707,22174,26289,22162,4063,2984,
+3597,37830,35603,37788,20216,20779,14361,17462,20156,1125,895,20299,20362,
+22097,23144,427,971,14745,778,1044,13365,20265,704,36531,629,35546,524,20120,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,20685,
+20749,20386,20227,18958,16010,20290,20526,20588,20609,20428,20453,20568,20732,
+U,U,U,U,28278,13717,15929,16063,28018,6276,16009,20904,20931,1504,17629,1187,
+1170,1169,36218,35484,1806,21081,21156,2163,21217,U,18042,29068,17292,3104,
+18860,4324,27089,3613,U,16094,29849,29716,29782,29592,19342,19132,16525,21456,
+13700,29199,16585,21940,837,21709,3014,22301,37469,38644,37734,22493,22413,
+22399,13886,22731,23193,35398,5882,5999,5904,23084,22968,37519,23166,23247,
+23058,22854,6643,6241,17045,14069,27909,29763,23073,24195,23169,35799,1043,
+37856,29836,4867,28933,18802,37896,35323,37821,14240,23582,23710,24158,24136,
+6550,6524,15086,24269,23375,6403,6404,14081,6304,14045,5886,14035,33066,35399,
+7610,13426,35240,24332,24334,6439,6059,23147,5947,23364,34324,30205,34912,
+24702,10336,9771,24539,16056,9647,9662,37000,28531,25024,62,70,9755,24985,
+24984,24693,11419,11527,18132,37197,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,25713,18021,11114,14889,11042,13392,39146,11896,
+25399,42075,25782,25393,25553,18915,11623,25252,11425,25659,25963,26994,15348,
+12430,12973,18825,12971,21773,13024,6361,37951,26318,12937,12723,15072,16784,
+21892,35618,21903,5884,21851,21541,30958,12547,6186,12852,13412,12815,12674,
+17097,26254,27940,26219,19347,26160,30832,7659,26211,13010,13025,26142,22642,
+14545,14394,14268,15257,14242,13310,29904,15254,26511,17962,26806,26654,15300,
+27326,14435,14293,17543,27187,27218,27337,27397,6418,25873,26776,27212,15319,
+27258,27479,16320,15514,37792,37618,35818,35531,37513,32798,35292,37991,28069,
+28427,18924,U,16255,15759,28164,16444,23101,28170,22599,27940,30786,28987,
+17178,17014,28913,29264,29319,29332,18319,18213,20857,19108,1515,29818,16120,
+13919,19018,18711,24545,16134,16049,19167,35875,16181,24743,16115,29900,29756,
+37767,29751,17567,28138,17745,30083,16227,19673,19718,16216,30037,30323,42438,
+15129,29800,35532,18859,18830,15099,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,15821,19022,16127,18885,18675,37370,22322,37698,
+35555,6244,20703,21025,20967,30584,12850,30478,30479,30587,18071,14209,14942,
+18672,29752,29851,16063,19130,19143,16584,19094,25006,37639,21889,30750,30861,
+30856,30930,29648,31065,30529,22243,16654,U,33942,31141,27181,16122,31290,
+31220,16750,5862,16690,37429,31217,3404,18828,665,15802,5998,13719,21867,
+13680,13994,468,3085,31458,23129,9973,23215,23196,23053,603,30960,23082,23494,
+31486,16889,31837,31853,16913,23475,24252,24230,31949,18937,6064,31886,31868,
+31918,27314,32220,32263,32211,32590,25185,24924,31560,32151,24194,17002,27509,
+2326,26582,78,13775,22468,25618,25592,18786,32733,31527,2092,23273,23875,
+31500,24078,39398,34373,39523,27164,13375,14818,18935,26029,39455,26016,33920,
+28967,27857,17642,33079,17410,32966,33033,33090,26548,39107,27202,33378,33381,
+27217,33875,28071,34320,29211,23174,16767,6208,23339,6305,23268,6360,34464,
+63932,15759,34861,29730,23042,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,34926,20293,34951,35007,35046,35173,35149,22147,35156,
+30597,30596,35829,35801,35740,35321,16045,33955,18165,18127,14322,35389,35356,
+37960,24397,37419,17028,26068,28969,28868,6213,40301,35999,36073,32220,22938,
+30659,23024,17262,14036,36394,36519,19465,36656,36682,17140,27736,28603,8993,
+18587,28537,28299,6106,39913,14005,18735,37051,U,21873,18694,37307,37892,
+35403,16482,35580,37927,35869,35899,34021,35371,38297,38311,38295,38294,36148,
+29765,16066,18687,19010,17386,16103,12837,38543,36583,36454,36453,16076,18925,
+19064,16366,29714,29803,16124,38721,37040,26695,18973,37011,22495,U,37736,
+35209,35878,35631,25534,37562,23313,35689,18748,29689,16923,38811,38769,39224,
+3878,24001,35781,19122,38943,38106,37622,38359,37349,17600,35664,19047,35684,
+39132,35397,16128,37418,18725,33812,39227,39245,31494,15869,39323,19311,39338,
+39516,35685,22728,27279,39457,23294,39471,39153,19344,39240,39356,19389,19351,
+37757,22642,4866,22562,18872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,5352,30788,10015,15800,26821,15741,37976,14631,24912,
+10113,10603,24839,40015,40019,40059,39989,39952,39807,39887,40493,39839,41461,
+41214,40225,19630,16644,40472,19632,40204,41396,41197,41203,39215,40357,33981,
+28178,28639,27522,34300,17715,28068,28292,28144,33824,34286,28160,14295,24676,
+31202,13724,13888,18733,18910,15714,37851,37566,37704,703,30905,37495,37965,
+20452,13376,36964,21853,30781,30804,30902,30795,5975,12745,18753,13978,20338,
+28634,28633,U,28702,21524,16821,22459,22771,22410,40214,22487,28980,13487,
+16812,29163,27712,20375,U,6069,35401,24844,23246,23051,17084,17544,14124,
+19323,35324,37819,37816,6358,3869,33906,27840,5139,17146,11302,17345,22932,
+15799,26433,32168,24923,24740,18873,18827,35322,37605,29666,16105,29876,35683,
+6303,16097,19123,27352,29683,29691,16086,19006,19092,6105,19046,935,5156,
+18917,29768,18710,28837,18806,37508,29670,37727,1278,37681,35534,35350,37766,
+35815,21973,18741,35458,29035,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,18755,3327,22180,1562,3051,3256,21762,31172,6138,32254,
+5826,19024,6226,17710,37889,14090,35520,18861,22960,6335,6275,29828,23201,
+14050,15707,14000,37471,23161,35457,6242,37748,15565,2740,19094,14730,20724,
+15721,15692,5020,29045,17147,33304,28175,37092,17643,27991,32335,28775,27823,
+15574,16365,15917,28162,28428,15727,1013,30033,14012,13512,18048,16090,18545,
+22980,37486,18750,36673,35868,27584,22546,22472,14038,5202,28926,17250,19057,
+12259,4784,9149,26809,26983,5016,13541,31732,14047,35459,14294,13306,19615,
+27162,13997,27831,33854,17631,17614,27942,27985,27778,28638,28439,28937,33597,
+5946,33773,27776,28755,6107,22921,23170,6067,23137,23153,6405,16892,14125,
+23023,5948,14023,29070,37776,26266,17061,23150,23083,17043,27179,16121,30518,
+17499,17098,28957,16985,35297,20400,27944,23746,17614,32333,17341,27148,16982,
+4868,28838,28979,17385,15781,27871,63525,19023,32357,23019,23855,15859,24412,
+19037,6111,32164,33830,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,21637,15098,13056,532,22398,2261,1561,16357,8094,41654,28675,
+37211,23920,29583,31955,35417,37920,20424,32743,29389,29456,31476,29496,29497,
+22262,29505,29512,16041,31512,36972,29173,18674,29665,33270,16074,30476,16081,
+27810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,
+30061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,20316,
+29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,
+23646,30654,30667,22770,30744,28857,30748,16552,30777,30791,30801,30822,33864,
+21813,31027,26627,31026,16643,16649,31121,31129,36795,31238,36796,16743,31377,
+16818,31420,33401,16836,31439,31451,16847,20001,31586,31596,31611,31762,31771,
+16992,17018,31867,31900,17036,31928,17044,31981,36755,28864,3279,32207,32212,
+32208,32253,32686,32692,29343,17303,32800,32805,31545,32814,32817,32852,15820,
+22452,28832,32951,33001,17389,33036,29482,33038,33042,30048,33044,17409,15161,
+33110,33113,33114,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,17427,22586,33148,33156,17445,33171,17453,33189,22511,33217,33252,
+33364,17551,33446,33398,33482,33496,33535,17584,33623,38505,27018,33797,28917,
+33892,24803,33928,17668,33982,34017,34040,34064,34104,34130,17723,34159,34160,
+34272,17783,34418,34450,34482,34543,38469,34699,17926,17943,34990,35071,35108,
+35143,35217,31079,35369,35384,35476,35508,35921,36052,36082,36124,18328,22623,
+36291,18413,20206,36410,21976,22356,36465,22005,36528,18487,36558,36578,36580,
+36589,36594,36791,36801,36810,36812,36915,39364,18605,39136,37395,18718,37416,
+37464,37483,37553,37550,37567,37603,37611,37619,37620,37629,37699,37764,37805,
+18757,18769,40639,37911,21249,37917,37933,37950,18794,37972,38009,38189,38306,
+18855,38388,38451,18917,26528,18980,38720,18997,38834,38850,22100,19172,24808,
+39097,19225,39153,22596,39182,39193,20916,39196,39223,39234,39261,39266,19312,
+39365,19357,39484,39695,31363,39785,39809,39901,39921,39924,19565,39968,14191,
+7106,40265,39994,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,40702,22096,40339,40381,40384,40444,38134,36790,40571,40620,40625,
+40637,40646,38108,40674,40689,40696,31432,40772,148,695,928,26906,38083,22956,
+1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754,2765,3007,21610,
+63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138,3253,3293,3309,
+3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699,23584,4028,
+24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399,4411,21348,
+33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189,6506,6701,
+6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113,14024,8828,
+9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984,36768,11022,
+38840,11071,38983,39613,11340,U,11400,11447,23528,11528,11538,11703,11669,
+11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353,13671,13811,
+U,18874,U,13850,14102,U,838,22709,26382,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26904,15015,30295,24546,15889,16057,30206,8346,
+18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482,20946,1553,
+22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280,39369,14178,
+8643,35678,35662,U,18450,18683,18965,29193,19136,3192,22885,20133,20358,1913,
+36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574,21614,27474,
+U,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621,20582,13563,
+13260,U,22787,18300,35144,23214,23433,23558,7568,22433,29009,U,24834,31762,
+36950,25010,20378,35682,25602,25674,23899,27639,U,25732,6428,35562,18934,
+25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079,63693,U,
+22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,26521,26734,25617,
+26718,U,26823,31554,37056,2577,26918,U,26937,31301,U,27130,39462,27181,13919,
+25705,33,31107,27188,27483,23852,13593,U,27549,18128,27812,30011,34917,28078,
+22710,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+14108,9613,28747,29133,15444,29312,29317,37505,8570,29323,37680,29414,18896,
+27705,38047,29776,3832,34855,35061,10534,33907,6065,28344,18986,6176,14756,
+14009,U,U,17727,26294,40109,39076,35139,30668,30808,22230,16607,5642,14753,
+14127,33000,5061,29101,33638,31197,37288,U,19639,28847,35243,31229,31242,
+31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,21410,28167,37823,
+26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,32899,22293,38947,
+35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,32912,33012,33070,
+8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,34474,18682,25574,
+35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,23032,35849,U,
+36805,37100,U,37136,37180,15863,37214,19146,36816,29327,22155,38119,38377,
+38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,32415,40696,
+40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,36798,21953,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36794,
+9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,30877,14138,36480,
+6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,22870,20122,24193,
+25176,22207,3693,36366,23405,16008,19614,25566,U,6134,6267,25904,22061,23626,
+21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,15680,34672,19996,
+4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,37701,21554,33096,
+33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,22001,
+26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,3702,
+11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,25596,
+25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,21779,
+30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,29444,
+18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,4569,
+37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40029,25887,11680,
+18675,18400,40316,4076,3594,U,30115,4077,U,24648,4487,29091,32398,40272,19994,
+19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,22682,19310,33325,
+21579,22442,23189,2425,U,14930,9317,29556,40620,19721,39917,15614,40752,19547,
+20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,16119,15916,14890,
+36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,18358,22695,16575,
+22140,39819,23924,30292,42036,40581,19681,U,14331,24857,12506,17394,U,22109,
+4777,22439,18787,40454,21044,28846,13741,U,40316,31830,39737,22494,5996,23635,
+25811,38096,25397,29028,34477,3368,27938,19170,3441,U,20990,7951,23950,38659,
+7633,40577,36940,31519,39682,23761,31651,25192,25397,39679,31695,39722,31870,
+U,31810,31878,39957,31740,39689,U,39963,18750,40794,21875,23491,20477,40600,
+20466,21088,15878,21201,22375,20566,22967,24082,38856,40363,36700,21609,38836,
+39232,38842,21292,24880,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,26924,21466,39946,40194,19515,38465,27008,20646,30022,5997,
+39386,21107,U,37209,38529,37212,U,37201,36503,25471,27939,27338,22033,37262,
+30074,25221,1020,29519,31856,23585,15613,U,18713,30422,39837,20010,3284,33726,
+34882,U,23626,27072,U,22394,21023,24053,20174,27697,498,20281,21660,21722,
+21146,36226,13822,U,13811,U,27474,37244,40869,39831,38958,39092,39610,40616,
+40580,29050,31508,U,27642,34840,32632,U,22048,42570,36471,40787,U,36308,36431,
+40476,36353,25218,33661,36392,36469,31443,19063,31294,30936,27882,35431,30215,
+35418,40742,27854,34774,30147,41650,30803,63552,36108,29410,29553,35629,29442,
+29937,36075,19131,34351,24506,34976,17591,U,6203,28165,U,35454,9499,U,24829,
+30311,39639,40260,37742,39823,34805,U,U,36087,29484,38689,39856,13782,29362,
+19463,31825,39242,24921,24921,19460,40598,24957,U,22367,24943,25254,25145,U,
+14940,25058,21418,13301,25444,26626,13778,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23895,35778,36826,36409,U,20697,7494,30982,
+21298,38456,3899,16485,U,30718,U,31938,24346,31962,31277,32870,32867,32077,
+29957,29938,35220,33306,26380,32866,29830,32859,29936,33027,30500,35209,26572,
+30035,28369,34729,34766,33224,34700,35401,36013,35651,30507,29944,34010,13877,
+27058,36262,U,35241,U,28089,34753,16401,29927,15835,29046,24740,24988,15569,U,
+24695,U,32625,35629,U,24809,19326,21024,15384,15559,24279,30294,21809,6468,
+4862,39171,28124,28845,23745,25005,35343,13943,238,26694,20238,17762,23327,
+25420,40784,40614,25195,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,
+9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,
+8565,8566,8567,8568,8569,20022,20031,20101,20128,20866,20886,20907,21241,
+21304,21353,21430,22794,23424,24027,12083,24191,U,24400,24417,25908,U,30098,U,
+36789,U,168,710,12541,12542,12445,12446,U,U,12293,12294,12295,12540,65339,
+65341,10045,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,
+12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,
+12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,
+12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,
+12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,
+12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,
+12429,12430,12431,12432,12433,12434,12435,12449,12450,12451,12452,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12453,12454,12455,
+12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,
+12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,
+12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,
+12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,
+12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,
+12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,
+12534,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,
+1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
+1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
+1097,1098,1099,1100,1101,1102,1103,8679,8632,8633,63461,204,20058,138,20994,
+63466,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+63467,20872,63469,30215,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,65506,65508,65287,65282,12849,8470,8481,12443,12444,
+11904,11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,
+11946,11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,
+11998,12003,U,U,U,643,592,603,596,629,339,248,331,650,618,30849,37561,35023,
+22715,24658,31911,23290,9556,9574,9559,9568,9580,9571,9562,9577,9565,9554,
+9572,9557,9566,9578,9569,9560,9575,9563,9555,9573,9558,9567,9579,9570,9561,
+9576,9564,9553,9552,9581,9582,9584,9583,65517,1351,37595,1503,16325,34124,
+17077,29679,20917,13897,18754,35300,37700,6619,33518,15560,30780,26436,25311,
+18739,35242,672,27571,4869,20395,9453,20488,27945,31364,13824,19121,9491,U,
+894,24484,896,839,28379,1055,U,20737,13434,20750,39020,14147,33814,18852,1159,
+20832,13236,20842,3071,8444,741,9520,1422,12851,6531,23426,34685,1459,15513,
+20914,20920,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,40244,20937,20943,20945,15580,20947,19110,20915,20962,21314,20973,33741,
+26942,14125,24443,21003,21030,21052,21173,21079,21140,21177,21189,31765,34114,
+21216,34317,27411,U,35550,21833,28377,16256,2388,16364,21299,U,3042,27851,
+5926,26651,29653,24650,16042,14540,5864,29149,17570,21357,21364,34475,21374,U,
+5526,5651,30694,21395,35483,21408,21419,21422,29607,22386,16217,29596,21441,
+21445,27721,20041,22526,21465,15019,2959,21472,16363,11683,21494,3191,21523,
+28793,21803,26199,27995,21613,27475,3444,21853,21647,21668,18342,5901,3805,
+15796,3405,35260,9880,21831,19693,21551,29719,21894,21929,U,6359,16442,17746,
+17461,26291,4276,22071,26317,12938,26276,26285,22093,22095,30961,22257,38791,
+21502,22272,22255,22253,35686,13859,4687,22342,16805,27758,28811,22338,14001,
+27774,22502,5142,22531,5204,17251,22566,19445,22620,22698,13665,22752,22748,
+4668,22779,23551,22339,41296,17016,37843,13729,22815,26790,14019,28249,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5694,23076,
+21843,5778,34053,22985,3406,27777,27946,6108,23001,6139,6066,28070,28017,6184,
+5845,23033,28229,23211,23139,14054,18857,U,14088,23190,29797,23251,28577,9556,
+15749,6417,14130,5816,24195,21200,23414,25992,23420,31246,16388,18525,516,
+23509,24928,6708,22988,1445,23539,23453,19728,23557,6980,23571,29646,23572,
+7333,27432,23625,18653,23685,23785,23791,23947,7673,7735,23824,23832,23878,
+7844,23738,24023,33532,14381,18689,8265,8563,33415,14390,15298,24110,27274,U,
+24186,17596,3283,21414,20151,U,21416,6001,24073,24308,33922,24313,24315,14496,
+24316,26686,37915,24333,449,63636,15070,18606,4922,24378,26760,9168,U,9329,
+24419,38845,28270,24434,37696,35382,24487,23990,15711,21072,8042,28920,9832,
+37334,670,35369,24625,26245,6263,14691,15815,13881,22416,10164,31089,15936,
+24734,U,24755,18818,18831,31315,29860,20705,23200,24932,33828,24898,63654,
+28370,24961,20980,1622,24967,23466,16311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10335,25043,35741,39261,25040,14642,10624,
+10433,24611,24924,25886,25483,280,25285,6000,25301,11789,25452,18911,14871,
+25656,25592,5006,6140,U,28554,11830,38932,16524,22301,25825,25829,38011,14950,
+25658,14935,25933,28438,18984,18979,25989,25965,25951,12414,26037,18752,19255,
+26065,16600,6185,26080,26083,24543,13312,26136,12791,12792,26180,12708,12709,
+26187,3701,26215,20966,26227,U,7741,12849,34292,12744,21267,30661,10487,39332,
+26370,17308,18977,15147,27130,14274,U,26471,26466,16845,37101,26583,17641,
+26658,28240,37436,26625,13286,28064,26717,13423,27105,27147,35551,26995,26819,
+13773,26881,26880,15666,14849,13884,15232,26540,26977,35402,17148,26934,27032,
+15265,969,33635,20624,27129,13913,8490,27205,14083,27293,15347,26545,27336,
+37276,15373,27421,2339,24798,27445,27508,10189,28341,15067,949,6488,14144,
+21537,15194,27617,16124,27612,27703,9355,18673,27473,27738,33318,27769,15804,
+17605,15805,16804,18700,18688,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,15561,14053,15595,3378,39811,12793,9361,32655,26679,27941,
+28065,28139,28054,27996,28284,28420,18815,16517,28274,34099,28532,20935,U,U,
+33838,35617,U,15919,29779,16258,31180,28239,23185,12363,28664,14093,28573,
+15920,28410,5271,16445,17749,37872,28484,28508,15694,28532,37232,15675,28575,
+16708,28627,16529,16725,16441,16368,16308,16703,20959,16726,16727,16704,25053,
+28747,28798,28839,28801,28876,28885,28886,28895,16644,15848,29108,29078,17015,
+28971,28997,23176,29002,U,23708,17253,29007,37730,17089,28972,17498,18983,
+18978,29114,35816,28861,29198,37954,29205,22801,37955,29220,37697,22021,29230,
+29248,18804,26813,29269,29271,15957,12356,26637,28477,29314,U,29483,18467,
+34859,18669,34820,29480,29486,29647,29610,3130,27182,29641,29769,16866,5863,
+18980,26147,14021,18871,18829,18939,29687,29717,26883,18982,29753,1475,16087,
+U,10413,29792,36530,29767,29668,29814,33721,29804,14128,29812,37873,27180,
+29826,18771,19084,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,16735,19065,35727,23366,35843,6302,29896,6536,29966,U,29982,36569,
+6731,23511,36524,37765,30029,30026,30055,30062,20354,16132,19731,30094,29789,
+30110,30132,30210,30252,30289,30287,30319,30326,25589,30352,33263,14328,26897,
+26894,30369,30373,30391,30412,28575,33890,20637,20861,7708,30494,30502,30528,
+25775,21024,30552,12972,30639,35172,35176,5825,30708,U,4982,18962,26826,30895,
+30919,30931,38565,31022,21984,30935,31028,30897,30220,36792,34948,35627,24707,
+9756,31110,35072,26882,31104,22615,31133,31545,31036,31145,28202,28966,16040,
+31174,37133,31188,
+};
+
+static const struct dbcs_index big5hkscs_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{__big5hkscs_decmap+0,64,170},{__big5hkscs_decmap+107,64,254},{
+__big5hkscs_decmap+298,64,254},{__big5hkscs_decmap+489,64,253},{
+__big5hkscs_decmap+679,64,220},{__big5hkscs_decmap+836,96,254},{
+__big5hkscs_decmap+995,64,254},{__big5hkscs_decmap+1186,64,253},{
+__big5hkscs_decmap+1376,64,254},{__big5hkscs_decmap+1567,64,254},{
+__big5hkscs_decmap+1758,64,254},{__big5hkscs_decmap+1949,64,254},{
+__big5hkscs_decmap+2140,64,254},{__big5hkscs_decmap+2331,64,254},{
+__big5hkscs_decmap+2522,64,254},{__big5hkscs_decmap+2713,64,254},{
+__big5hkscs_decmap+2904,64,254},{__big5hkscs_decmap+3095,64,254},{
+__big5hkscs_decmap+3286,64,254},{__big5hkscs_decmap+3477,64,254},{
+__big5hkscs_decmap+3668,64,254},{__big5hkscs_decmap+3859,64,254},{
+__big5hkscs_decmap+4050,64,254},{__big5hkscs_decmap+4241,64,254},{
+__big5hkscs_decmap+4432,64,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__big5hkscs_decmap+4623,161,254},{__big5hkscs_decmap+4717,
+64,254},{__big5hkscs_decmap+4908,64,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_decmap+5099,214,254},{
+__big5hkscs_decmap+5140,64,254},{__big5hkscs_decmap+5331,64,254},{
+__big5hkscs_decmap+5522,64,254},{__big5hkscs_decmap+5713,64,254},{
+__big5hkscs_decmap+5904,64,254},{0,0,0},
+};
+
+static const unsigned char big5hkscs_phint_0[] = {
+160,89,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,1,8,0,0,0,0,0,0,0,0,0,0,
+0,0,2,44,0,30,0,0,0,0,0,64,174,86,238,249,221,228,33,23,0,0,0,128,219,73,31,
+76,130,55,237,228,223,189,247,245,239,31,100,136,94,253,223,11,0,0,0,192,247,
+143,0,131,5,0,8,201,8,4,129,64,68,5,11,9,35,1,32,2,0,0,0,32,145,24,0,96,0,168,
+6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,128,0,64,86,50,65,32,198,
+80,72,2,0,0,0,0,160,192,168,1,164,85,48,58,209,106,46,159,176,241,65,136,5,57,
+80,4,0,0,0,0,172,163,20,192,1,2,13,45,134,136,107,34,110,192,204,245,218,10,
+24,122,0,0,0,0,50,115,0,15,68,252,3,33,49,32,25,232,96,160,65,19,82,42,250,9,
+0,0,0,0,190,1,129,16,16,96,183,137,193,218,237,250,242,59,200,167,11,77,155,
+11,0,0,0,0,24,0,220,116,19,94,192,168,0,60,240,208,68,224,172,60,75,230,29,15,
+0,0,0,128,189,88,120,55,191,187,216,218,8,134,192,108,148,192,176,125,14,136,
+145,3,0,0,0,64,99,139,197,22,24,68,124,152,75,112,3,92,219,185,208,26,40,149,
+106,1,0,0,0,0,232,7,36,34,32,136,4,106,32,215,29,50,15,162,149,11,4,67,65,1,0,
+0,0,104,48,64,19,207,57,183,16,8,7,4,180,33,217,183,15,11,127,69,91,0,0,0,0,
+236,116,236,196,4,41,49,2,48,250,252,27,175,78,38,164,183,110,50,24,0,0,0,0,
+220,22,67,34,1,0,0,128,0,0,0,4,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,
+0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,28,241,220,190,126,252,186,123,238,249,55,249,
+93,165,255,31,215,2,0,0,0,128,63,255,213,117,117,187,120,231,62,245,177,173,
+189,75,150,188,46,181,85,2,0,0,0,192,109,51,55,176,233,204,159,42,126,83,204,
+255,77,234,218,198,255,55,165,0,0,0,0,160,192,252,222,50,83,161,28,0,0,33,176,
+71,0,74,32,32,233,215,235,0,0,0,0,160,183,1,64,49,101,247,12,36,64,48,45,144,
+123,18,0,0,2,0,0,0,0,0,0,0,8,80,144,69,0,4,0,0,32,64,4,161,128,96,2,0,32,0,8,
+0,0,0,0,148,8,2,32,40,0,0,1,8,254,251,73,
+};
+
+static const unsigned char big5hkscs_phint_11939[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,128,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static const unsigned char big5hkscs_phint_21733[] = {
+0,0,0,0,0,26,172,248,250,90,192,250,51,0,0,0,0,0,129,0,160,156,130,144,9,1,
+180,192,176,3,86,2,160,66,45,136,1,0,0,0,0,146,119,139,96,5,201,33,6,70,56,96,
+72,192,180,36,222,132,224,192,36,0,0,0,0,205,80,197,52,192,40,162,173,124,153,
+24,88,18,34,196,66,162,83,142,30,0,0,0,128,52,135,11,21,209,64,250,61,0,4,210,
+5,72,8,22,230,28,165,0,8,0,0,0,192,45,22,20,128,24,58,212,25,136,28,138,4,
+};
+
+static const DBCHAR __big5hkscs_bmp_encmap[26537] = {
+50904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34905,34903,N,N,N,N,N,N,
+34909,34907,34918,N,N,N,N,N,N,N,34913,34911,N,N,N,N,N,N,N,N,N,N,N,N,34922,
+34920,N,N,N,N,N,N,34927,34925,34983,N,34931,34929,N,N,N,N,34935,34933,N,N,N,N,
+51451,34939,34937,N,34978,34902,34919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34906,
+34924,N,N,N,N,N,N,34908,34926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34928,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51452,34910,34932,N,N,N,N,N,
+51450,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34936,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,34904,34921,N,34930,34912,34934,N,34938,N,34940,N,34941,N,
+34942,N,34977,51446,34923,N,N,51448,N,N,N,N,N,N,51447,N,N,N,N,N,34984,N,N,N,N,
+N,N,N,N,51454,N,N,N,N,N,N,N,N,N,N,51449,N,N,N,N,N,N,N,N,N,N,N,N,N,51445,N,N,N,
+N,N,N,51453,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50905,51193,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,51187,51188,51189,51190,51191,51192,51194,51195,51196,51197,
+51198,51264,51265,51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,
+51276,51277,51278,51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,
+51289,51290,51292,51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,
+51303,51304,51305,51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,
+51316,51317,N,51291,34915,34980,34917,34982,51410,N,N,N,N,N,N,N,N,N,N,51411,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+50869,50870,50871,50872,50873,50874,50875,50876,50877,50878,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,51319,51320,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51318,50849,50850,50851,
+50852,50853,50854,50855,50856,50857,50858,N,N,N,N,N,N,N,N,N,N,50859,50860,
+50861,50862,50863,50864,50865,50866,50867,50868,63993,63992,63974,63983,63965,
+63976,63985,63967,63980,63989,63971,63982,63991,63973,63977,63986,63968,63979,
+63988,63970,63975,63984,63966,63981,63990,63972,63978,63987,63969,63994,63995,
+63997,63996,50918,51414,N,N,N,51415,N,51416,51417,51418,N,51419,N,51420,51421,
+N,N,N,N,N,N,N,51422,N,N,N,N,N,N,51423,51424,N,N,N,N,N,N,N,51425,N,51426,N,N,
+51427,N,51428,N,51429,N,N,N,N,N,N,N,51430,N,N,N,N,N,51431,N,51432,N,N,N,N,N,N,
+N,51433,N,N,N,51434,N,51435,51436,N,51437,N,N,N,N,N,N,51438,51439,N,N,N,N,N,N,
+51440,N,N,N,N,51441,50893,50912,50913,50914,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930,
+50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,51008,
+51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,
+51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,
+51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,
+51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,
+51061,51062,51063,51064,51065,51066,N,N,N,N,N,N,N,51412,51413,50908,50909,N,N,
+51067,51068,51069,51070,51105,51106,51107,51108,51109,51110,51111,51112,51113,
+51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126,
+51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139,
+51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152,
+51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165,
+51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178,
+51179,51180,51181,51182,51183,51184,51185,51186,N,N,N,N,N,50915,50906,50907,
+51409,37495,N,N,N,N,N,N,N,N,N,N,38623,N,N,N,N,N,N,N,N,N,N,N,35285,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37837,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39903,N,N,
+N,N,N,N,64104,N,N,35290,36697,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35291,N,
+N,36701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35292,N,N,N,N,N,N,N,N,N,38647,N,N,N,N,N,N,
+N,N,N,N,N,N,35546,N,N,N,N,35804,N,N,N,N,N,N,38875,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40531,N,N,N,N,40362,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39914,35438,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35784,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35304,N,35306,N,N,N,N,N,35915,N,N,N,N,N,N,N,64368,N,N,N,N,N,N,N,N,N,
+N,N,35309,N,N,38109,N,35310,N,N,N,N,40628,35539,N,N,N,N,N,N,N,N,N,N,N,37595,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38107,35321,N,N,N,N,N,N,N,N,64378,N,N,N,
+35323,N,N,N,N,N,N,N,40700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35324,N,35263,N,N,
+N,35326,N,35302,N,N,40262,N,N,N,40430,N,N,N,41086,N,N,N,41064,N,N,N,N,39145,N,
+35688,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36349,35774,40921,N,N,N,N,N,N,N,
+35563,N,N,40919,35690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40028,N,35761,N,N,N,N,N,N,N,
+N,64350,N,N,N,N,N,N,N,N,N,40435,N,N,N,N,N,N,N,41168,N,N,N,64614,N,N,N,N,37609,
+N,N,N,N,N,N,N,N,39660,36779,64072,N,N,N,N,36421,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40047,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40670,N,N,N,N,N,N,
+35311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38633,N,N,N,N,N,N,N,N,N,
+N,40635,N,N,N,N,38110,N,40632,N,N,N,38842,64357,N,N,N,38358,N,N,N,40123,N,N,
+38874,N,N,N,N,36677,N,64381,37208,65124,N,38998,39757,N,N,N,N,N,N,N,N,N,N,
+37723,38343,N,38887,N,N,N,N,N,N,37721,N,N,N,37365,38840,N,N,64930,64438,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37626,37719,N,35750,N,N,N,N,64441,N,38832,N,N,64964,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40097,N,N,N,N,N,37362,37369,N,36849,N,N,N,N,N,N,38725,
+38995,N,N,65144,N,64449,37457,N,N,N,N,N,N,40365,N,N,N,N,N,64876,N,N,64107,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39874,N,N,N,N,N,N,N,N,
+N,N,N,N,39547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,35680,N,N,N,N,N,N,N,N,37707,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39613,N,N,N,N,37303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38324,N,N,N,N,N,65221,
+N,N,40688,36196,N,N,N,N,N,N,N,N,N,37481,N,N,N,N,N,N,36199,N,N,N,N,N,N,N,N,N,N,
+N,N,64490,N,N,N,N,N,N,N,N,64495,N,36200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37867,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64578,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,37222,N,N,N,N,N,N,N,N,64205,N,N,N,N,37853,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35788,36205,N,N,N,N,N,
+N,N,N,N,N,N,36206,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38568,N,N,N,N,N,N,N,N,N,
+N,64678,N,N,N,N,N,N,N,N,N,N,N,N,36207,N,N,N,N,N,N,N,N,N,N,N,N,N,36208,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64612,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,36960,N,N,N,N,N,N,N,N,36212,38851,N,N,N,N,N,N,N,35536,N,N,N,
+N,N,N,37492,N,39870,N,N,N,N,N,40136,N,N,40122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40633,N,N,N,N,N,38234,N,N,37300,N,N,N,N,N,N,35400,N,N,N,N,N,N,N,N,N,N,N,
+36221,N,N,35453,N,N,35522,64842,N,36257,N,N,35537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64692,35655,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37796,40666,N,N,N,N,N,N,N,N,N,
+35409,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36262,N,N,N,N,N,N,40645,N,N,
+N,N,64708,N,N,N,N,41080,N,38069,N,N,N,N,N,N,N,64706,35435,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36267,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64585,N,37825,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36975,N,36272,N,N,N,N,N,N,N,N,
+38014,37114,N,N,N,N,N,N,N,N,N,N,38009,N,N,N,N,N,N,N,N,36274,N,N,N,N,N,N,N,N,
+64750,N,N,N,N,N,N,N,N,N,N,N,N,N,39291,N,N,N,N,N,N,N,N,36276,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36279,N,N,N,N,N,N,N,37299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36283,36282,N,N,N,N,N,N,N,N,36284,36932,N,N,N,64844,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37860,N,N,37856,N,N,N,N,N,N,N,64851,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36291,N,39864,N,N,N,64496,N,37865,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37878,N,N,N,N,N,36293,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36298,
+N,N,N,N,N,36300,64861,37813,64865,N,N,N,40184,N,N,N,37458,N,N,41192,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35926,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36310,N,38848,N,N,N,41182,N,N,N,N,
+38866,N,N,N,N,N,64165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64931,N,N,N,36315,36527,N,N,
+N,N,N,N,N,N,N,37301,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64841,N,N,N,N,N,N,
+N,N,64977,N,N,N,N,N,N,N,N,N,N,36331,N,N,N,N,N,38854,N,64974,N,N,37116,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64601,N,N,38614,N,N,N,N,N,N,38853,36335,N,N,N,N,38871,N,N,N,
+N,N,36336,N,N,N,N,N,N,N,38566,N,N,N,N,N,N,N,64447,N,N,N,N,36339,N,N,N,N,37961,
+N,36341,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39026,N,N,N,N,N,N,N,36459,N,N,N,
+N,N,N,64253,N,N,N,N,N,N,N,N,N,N,36688,N,N,N,N,N,N,40396,64613,N,35908,N,N,
+39278,38049,N,N,N,N,N,36707,N,N,N,N,N,N,N,41178,N,N,N,N,N,N,N,N,N,N,N,37459,
+65001,N,N,40373,N,N,N,N,N,N,N,39033,N,N,N,40285,N,N,N,N,36195,38505,40816,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64618,N,N,35527,N,N,N,N,35287,N,N,N,N,N,N,N,N,
+N,N,N,N,65101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40669,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65275,39100,64204,N,N,38320,N,N,N,37988,N,N,N,N,
+N,N,37743,N,N,N,N,N,N,38073,N,N,38380,N,N,N,N,37358,N,N,39107,N,38390,N,N,N,
+36861,39109,N,N,N,N,38758,65134,N,N,38877,36010,N,N,37586,N,N,38753,39115,N,N,
+N,N,38384,N,38749,N,37347,N,N,N,N,39116,N,N,37993,39117,N,N,N,N,N,39118,N,
+38396,N,N,38051,38498,N,N,N,65206,N,37987,N,N,N,N,N,N,N,39120,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39121,N,N,N,N,38005,64224,N,N,N,N,N,
+N,N,N,N,38002,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39126,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39129,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39131,N,N,N,N,39133,N,N,N,N,N,N,N,N,39080,N,N,N,N,N,N,N,
+35437,N,N,N,N,N,N,N,N,N,N,N,35579,35502,64457,N,N,N,N,35933,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39142,N,N,N,N,N,N,N,N,N,N,N,39144,N,N,N,N,N,N,N,N,N,N,N,N,N,35405,N,N,N,
+37463,N,N,N,N,N,N,N,N,N,N,38367,N,N,41132,N,N,N,N,39147,N,N,N,N,39148,N,36035,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35512,
+N,N,N,40679,N,N,N,N,N,N,N,N,38076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64721,N,N,N,N,
+N,N,40134,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40574,39166,
+65000,N,N,N,N,39232,N,N,N,N,38089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39238,N,N,N,N,37056,
+N,38097,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39240,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39243,N,N,N,N,N,36437,N,N,N,N,39246,N,N,N,N,
+N,N,N,N,N,N,N,36606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36441,N,N,N,N,N,N,N,
+N,N,38124,38127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35936,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39253,N,N,N,N,N,N,N,N,N,38212,N,N,N,N,N,N,N,N,N,N,N,
+36043,N,N,N,39254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39257,N,N,N,N,N,N,N,39259,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36036,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64069,N,N,
+N,37047,N,N,38723,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38349,N,N,N,N,N,N,38857,
+64848,36537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38342,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35513,N,N,N,N,N,N,36348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35446,N,
+N,N,N,N,40273,N,N,N,N,N,N,N,N,N,N,N,N,N,39283,N,N,N,N,40271,39290,38244,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39329,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39333,N,N,N,
+N,N,N,N,39335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36589,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39341,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37998,36720,N,64208,N,N,N,N,N,N,N,N,N,N,N,N,N,39347,N,N,N,N,N,N,
+41043,N,N,N,N,N,N,N,N,38492,N,N,N,N,64890,N,N,N,N,N,N,N,N,38910,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37565,N,38909,N,N,N,N,36708,N,N,N,N,64759,38242,38861,40548,N,N,
+N,N,N,N,N,37452,36553,39356,N,N,N,N,40357,N,36692,N,N,N,N,N,N,N,N,N,N,36732,N,
+N,N,N,N,N,36514,N,N,N,N,N,N,N,N,N,36730,N,N,N,N,N,N,38830,N,N,N,N,38600,N,N,N,
+N,N,N,N,39363,N,37078,N,40126,N,N,N,36726,N,N,N,N,N,N,N,N,N,N,N,N,N,38000,
+64331,N,N,64970,N,N,N,N,N,N,36551,N,N,N,N,N,41209,N,N,N,N,N,N,N,36777,N,N,N,N,
+N,N,N,N,N,N,N,N,39367,N,N,N,N,N,N,N,N,N,N,N,N,N,37079,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40671,39374,N,N,N,N,N,N,N,N,36794,N,N,N,N,N,36843,N,39375,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36802,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37577,N,N,N,N,N,38876,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38323,40057,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38322,
+36827,N,N,N,N,39907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40570,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39918,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39390,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,35410,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39393,N,N,N,N,N,N,35431,35765,N,N,N,N,N,N,N,N,N,N,35500,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39401,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64458,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39413,64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39849,N,N,N,N,N,N,N,N,N,N,N,N,64476,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65110,N,
+N,N,N,N,40612,N,N,N,N,N,N,40265,38363,N,N,N,N,N,N,N,N,N,N,35269,N,N,N,N,N,N,N,
+N,N,N,N,N,39416,N,N,N,N,N,N,38500,N,N,N,N,36949,N,N,38612,N,N,N,N,N,N,N,38780,
+N,N,N,N,N,N,38477,N,38881,N,N,N,N,N,N,39496,N,N,N,N,N,N,N,N,N,N,N,39497,N,
+65149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37034,N,N,N,N,39504,N,N,N,N,N,N,N,
+37703,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36568,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37065,N,N,N,N,N,39509,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37052,N,N,N,N,N,39512,N,35768,37077,N,N,N,N,N,N,N,N,N,N,N,N,N,38465,N,N,N,N,N,
+N,39514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39516,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,38850,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35515,N,N,
+N,39850,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37109,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37189,35928,N,N,N,N,N,N,N,N,39523,N,N,N,N,N,N,35913,N,N,N,N,N,N,N,N,N,N,N,
+35766,N,N,N,N,N,N,N,N,N,N,64719,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38507,39534,N,
+37199,N,N,N,N,N,N,N,N,38726,N,N,41190,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37591,N,
+38517,N,N,37844,N,N,37307,38521,N,N,N,N,N,39536,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38520,37325,N,40010,41071,N,N,41066,N,N,N,N,N,
+N,37215,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40869,N,N,35258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40653,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39545,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40398,N,N,N,36050,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40307,N,N,N,N,N,N,N,N,N,38585,N,38588,N,N,N,N,N,N,40145,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40686,N,N,N,N,N,N,N,N,N,N,N,64323,40649,N,N,N,N,N,N,64467,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37294,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40312,N,N,N,N,N,N,N,N,N,N,40315,40627,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40626,N,40406,N,N,N,N,39247,N,N,35278,N,N,N,35776,N,40900,N,35796,
+N,N,35954,N,N,N,N,N,N,50879,35833,N,N,N,N,N,35142,N,50880,N,N,N,N,N,N,N,N,N,
+64229,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51323,35782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40023,N,N,N,N,N,N,N,N,N,N,N,N,N,39675,N,N,N,N,N,N,N,35280,35279,N,N,N,50881,N,
+35281,N,35298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37502,N,40378,N,N,N,N,N,50882,N,N,
+35951,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64504,N,N,N,35783,37483,N,N,35282,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40911,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40361,35283,N,N,39394,N,N,N,N,N,N,N,N,N,37479,37540,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35955,N,N,35150,N,N,N,N,N,N,N,N,N,N,N,N,N,35151,37496,N,
+N,N,N,N,N,N,N,37302,N,N,N,N,35284,N,40914,N,N,N,N,N,N,N,N,37543,N,N,38306,N,N,
+N,N,N,37486,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38634,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37487,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37539,N,N,N,N,N,35152,N,N,64087,N,N,N,N,
+39014,N,N,N,N,N,N,N,N,N,N,N,N,35286,N,N,N,N,N,N,N,N,N,N,39090,N,N,N,37547,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38622,37548,N,N,N,N,N,N,N,N,N,N,
+35952,N,40814,N,N,N,N,N,N,36594,N,N,N,40812,35288,N,N,N,N,64089,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37544,N,N,N,N,N,
+37219,N,N,N,N,N,N,35904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40819,N,37549,N,N,N,N,N,N,N,N,N,N,N,N,N,39913,N,N,N,N,N,37545,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37546,N,N,N,N,N,N,35289,N,N,N,N,N,N,N,64854,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,35953,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37537,N,N,37091,N,N,N,N,N,N,N,N,41126,
+N,N,N,N,N,38059,N,64626,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38852,N,N,N,N,N,N,
+N,37550,64103,N,N,N,N,N,N,N,N,N,N,N,37538,64105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37480,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35153,N,N,N,N,N,N,N,N,N,64111,N,N,N,N,N,
+N,N,N,N,64113,N,N,N,N,N,N,N,N,N,35154,N,N,N,N,37978,N,N,N,N,N,N,N,N,50883,N,N,
+N,35293,N,51362,N,N,N,N,N,N,N,N,N,N,N,N,N,50884,N,N,N,40530,N,35155,N,N,N,N,N,
+N,N,N,N,N,40533,37562,N,N,50885,N,N,35931,N,N,N,64125,64168,39528,64071,N,N,
+64126,N,N,N,N,N,N,N,N,N,N,37563,N,N,N,64950,N,64162,N,N,N,N,N,64163,N,64164,
+39860,64166,N,N,N,N,N,N,N,35295,N,N,N,64987,N,N,64169,N,35156,N,N,N,N,N,N,N,N,
+64171,N,N,N,N,N,N,64634,N,N,N,N,N,N,N,35296,N,40783,51325,N,N,35297,N,N,N,N,N,
+64176,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40909,41191,N,N,N,N,N,64177,35238,
+N,N,N,N,N,N,N,N,N,N,N,N,40698,N,N,N,N,N,N,N,64178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64180,N,37572,N,N,N,N,N,N,40815,N,N,N,N,N,N,N,35760,N,
+N,N,N,N,N,N,N,N,N,40876,N,N,N,N,N,35299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39891,35300,N,N,N,64181,N,N,N,N,N,40917,N,N,N,N,N,N,35157,N,N,37573,N,N,N,
+35158,N,N,N,N,N,N,N,N,N,N,N,N,64179,N,N,N,64182,N,N,N,N,N,N,N,N,N,N,N,64183,N,
+N,N,N,N,N,40668,N,N,N,64452,40817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64186,37575,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50886,39500,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35944,N,N,35301,N,N,N,N,40829,N,N,
+N,N,N,41129,64196,N,N,N,N,50887,N,N,35159,N,N,N,N,N,N,64170,N,N,N,N,N,N,N,N,N,
+N,N,35160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35811,N,35681,N,N,N,N,39665,N,N,40631,N,
+50888,N,N,N,64209,N,N,N,N,N,N,64210,N,N,N,N,N,N,N,N,40634,64212,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64217,N,N,N,N,N,N,N,N,N,N,N,N,64219,N,40160,N,N,N,
+64503,N,64506,35303,41082,64220,N,N,64221,N,35305,N,N,N,N,N,50889,N,N,N,N,N,N,
+N,N,N,N,64226,35307,N,N,64227,N,N,N,N,N,N,37064,N,N,N,37594,35161,40181,N,N,N,
+N,N,35162,64231,40866,N,N,N,N,N,64234,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64237,36781,N,N,N,N,N,N,64345,64239,38639,N,40428,N,N,N,40394,N,N,N,N,N,N,
+64877,N,35308,N,N,N,N,N,N,N,N,N,N,N,64324,N,N,40418,N,35957,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40640,N,40534,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40825,39623,N,N,64244,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39073,N,N,N,N,N,N,N,N,N,64248,N,N,N,35312,40519,N,N,40439,N,N,N,N,40915,
+N,39626,N,N,N,N,35313,64249,N,N,N,N,N,N,N,N,N,N,N,N,N,36442,N,35314,N,N,N,N,
+35315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37469,35665,37600,N,N,35316,N,N,N,N,N,
+N,N,N,N,40916,N,N,N,N,N,N,N,N,35449,N,N,N,N,N,N,N,N,N,N,N,35317,38823,N,N,N,N,
+N,N,N,N,N,N,37818,N,N,N,N,N,40536,N,N,N,N,35318,N,N,N,N,N,40535,N,N,N,N,35319,
+N,35393,N,N,35320,N,N,64241,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35322,N,N,N,
+N,N,N,N,64322,N,64191,N,N,N,N,N,N,N,N,N,64419,N,N,N,N,N,N,N,N,N,64247,N,N,N,N,
+N,N,N,N,N,N,N,40526,N,38108,N,N,N,N,N,38362,40440,40810,N,N,N,N,N,35511,N,N,N,
+N,N,N,N,N,N,N,N,N,64326,N,N,N,N,N,N,N,N,N,35398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64327,N,N,N,N,N,N,37192,N,N,N,37598,N,N,N,N,35667,40438,N,
+39898,N,N,N,N,40318,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35325,39396,N,N,
+N,N,N,40515,N,N,N,N,N,N,N,N,N,N,N,40425,N,36690,N,N,N,40437,40432,N,N,N,39399,
+N,N,N,N,N,35773,40431,N,N,N,N,N,N,N,N,N,N,N,40887,N,N,N,N,N,N,N,N,N,N,N,N,
+40400,N,40939,36265,40399,39137,N,40421,N,N,N,N,N,N,N,40392,N,N,N,N,N,N,N,N,N,
+64335,N,N,N,N,N,N,N,N,N,N,N,40427,N,N,N,N,N,N,N,N,N,64340,N,64341,39586,N,
+35542,N,39519,N,N,N,N,N,N,N,N,40693,N,N,N,36791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,39634,40554,40680,N,N,N,N,N,N,N,N,N,N,N,N,35775,37314,40290,
+N,N,N,N,N,N,37472,N,N,N,N,N,N,N,N,N,N,N,37470,37313,N,35525,N,N,38819,N,N,N,N,
+N,N,N,N,N,N,35692,N,36222,N,N,N,N,N,N,N,40020,N,N,N,N,N,40381,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40133,N,N,N,N,N,N,N,N,N,N,N,35163,N,N,N,N,N,N,N,N,
+N,N,64348,N,64347,N,64343,N,N,N,N,N,N,N,N,N,N,N,39111,64346,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40174,N,N,N,N,N,N,N,37602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38055,N,N,N,N,N,N,N,N,N,N,36044,N,39892,N,N,64356,64374,N,N,64352,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39397,N,N,39618,N,N,N,37371,N,N,N,41075,N,N,N,N,N,N,N,
+40818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40908,N,N,N,39077,37608,N,N,N,N,N,N,
+N,N,39868,N,38643,N,N,37607,N,N,64615,N,N,N,N,N,N,N,N,N,N,N,35709,N,N,N,N,
+39924,N,N,N,N,N,40695,N,N,40641,N,N,N,N,N,N,N,N,N,39279,N,N,N,N,N,N,38641,N,N,
+36417,N,N,N,N,N,38218,N,N,N,38886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38645,N,N,N,N,N,
+37606,40770,N,N,N,N,N,N,N,64359,N,N,N,N,N,N,N,N,39337,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64230,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,38525,N,N,N,64364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39330,N,N,N,N,N,
+39611,N,N,N,39525,N,N,37966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64366,N,N,
+39391,N,N,N,N,N,N,N,N,N,39139,N,N,37460,N,N,N,N,N,38523,35503,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35959,N,N,N,N,N,N,35759,40637,N,N,
+N,N,N,N,N,N,N,N,N,N,40678,N,N,64367,N,N,N,N,N,36577,N,N,N,N,39805,40062,N,N,N,
+N,63961,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37610,N,N,N,N,35960,N,N,N,N,N,N,N,N,N,N,
+N,64370,N,N,N,64369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35164,N,39152,38642,N,N,N,N,
+N,N,N,64372,35777,N,35165,35294,N,35166,N,N,50890,N,N,N,N,N,N,65090,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64379,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35167,N,35168,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40403,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38988,N,N,N,N,N,N,N,N,N,N,38738,N,N,N,N,N,38339,N,N,N,N,39862,N,
+N,N,N,N,N,N,N,N,N,N,N,39609,N,N,N,38835,N,N,N,N,N,N,40820,37617,N,N,N,N,N,N,N,
+N,N,N,N,38879,N,N,N,N,64422,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64427,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39031,N,N,N,38996,38341,N,N,N,N,N,N,N,40277,64434,38270,N,
+N,N,N,N,N,N,N,38722,N,38118,N,N,N,N,37621,N,N,N,N,N,N,N,36037,N,N,N,N,N,N,
+37629,N,N,64418,N,N,40017,N,N,38121,39004,37616,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,37964,N,N,N,N,N,N,N,37227,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35704,N,N,N,N,38114,N,
+N,N,N,N,N,N,38991,N,64437,N,N,N,N,37489,N,N,37733,N,N,39003,N,N,38992,N,N,N,N,
+N,N,N,38844,N,N,N,N,37619,N,N,37696,38989,N,N,N,38258,N,65007,N,N,N,N,N,N,N,N,
+64961,N,N,N,N,64442,N,N,37611,N,N,N,N,N,N,64627,38839,N,N,N,N,N,N,N,N,N,64436,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37031,N,N,N,N,N,N,N,N,N,N,38721,
+37620,N,N,N,64444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38263,N,N,N,N,N,N,N,N,N,N,N,
+40674,N,36728,N,N,N,N,N,N,N,63964,N,N,N,38514,40629,N,N,N,38475,N,N,N,36012,N,
+N,N,N,N,N,N,N,N,41210,N,N,N,N,N,N,N,N,N,N,N,38261,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37082,N,N,37735,N,65188,N,N,N,37087,N,N,N,N,37716,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35169,N,35764,N,N,N,N,40384,N,N,N,N,N,N,36424,N,
+64453,N,N,N,N,N,64455,N,N,N,50891,N,64121,N,N,N,N,N,N,N,N,N,N,N,N,N,40551,N,N,
+N,N,N,36057,N,N,N,N,N,N,64466,35170,35171,N,N,N,N,N,N,N,N,N,N,64637,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40811,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64460,N,65198,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64465,N,N,
+N,N,N,N,N,N,N,N,N,64373,64468,N,N,N,N,N,N,N,N,N,N,N,N,N,64470,64472,N,N,N,N,N,
+N,N,35677,N,37708,N,39650,N,N,35785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64475,40905,N,N,N,N,N,N,N,N,40772,N,N,N,N,N,N,
+N,N,N,N,39149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64477,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36338,35172,N,65010,N,
+37709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64487,N,N,N,N,N,N,
+41202,39016,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40792,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36211,N,N,N,64478,N,N,N,N,N,64479,N,N,N,N,N,35912,64483,N,N,N,N,36264,N,
+N,64484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40053,N,N,39032,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36192,N,N,N,N,N,N,N,64485,N,36193,N,N,N,N,N,N,N,N,N,N,N,N,N,36194,
+41121,N,N,N,40000,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39085,N,N,N,40682,N,
+N,N,N,N,N,36052,N,N,N,N,N,N,N,N,N,40171,N,N,N,N,N,64480,N,N,40785,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36197,N,N,N,N,N,N,40177,N,N,N,N,N,N,N,N,N,N,
+64600,N,N,36198,N,N,N,N,N,N,N,38484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64488,N,N,N,50892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40910,
+64508,N,39652,N,N,N,N,N,N,40821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36201,N,N,N,N,N,37711,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37710,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,64500,N,N,N,N,50894,N,N,N,64451,N,N,35173,N,N,N,N,N,N,N,N,
+N,N,N,35962,N,N,N,N,N,N,35963,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,36202,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37715,N,N,40443,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64509,N,N,N,
+36953,64576,N,64577,64579,37729,64582,37730,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36203,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64588,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38328,N,N,50896,35786,N,N,N,N,N,N,N,N,N,N,39034,N,N,N,N,
+50897,N,64593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64596,N,N,N,N,N,N,N,N,64175,N,N,N,N,
+N,N,N,36204,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64097,N,N,64599,N,N,N,N,N,N,N,N,N,39792,N,N,N,N,N,N,N,N,41041,N,N,N,N,N,N,N,
+35964,N,35787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37742,N,N,N,64725,
+64681,N,N,N,N,N,N,N,N,N,N,N,N,N,64609,N,N,N,N,N,N,N,N,N,35174,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64203,N,N,N,N,N,N,N,63962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37754,N,41184,N,N,N,N,N,N,37739,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64619,N,N,N,N,N,41180,N,N,37992,N,
+N,N,N,N,N,N,N,N,N,N,64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,36209,N,N,N,N,N,N,64868,N,N,N,N,39354,N,N,N,39632,39521,
+41189,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41051,38572,N,N,N,N,38720,N,N,N,N,
+N,N,N,N,N,N,N,N,40689,N,N,N,N,N,N,N,N,35917,N,N,N,N,N,N,N,N,N,N,N,N,N,40830,N,
+N,N,N,N,N,N,N,N,N,N,N,36210,N,N,N,N,64630,N,N,N,N,N,N,N,N,N,N,N,N,N,38569,N,N,
+N,N,N,N,N,N,41070,N,N,64682,N,N,N,64461,N,N,N,64628,N,N,N,N,N,N,N,N,N,N,41076,
+N,N,N,N,N,N,N,N,N,N,N,N,N,41073,N,N,N,64633,N,N,N,N,N,64636,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40016,N,N,37753,37752,N,N,41181,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36213,N,36214,N,N,N,N,N,N,37748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36215,64677,N,N,64674,N,N,N,N,N,N,37059,N,N,N,N,N,N,N,41081,36217,N,N,N,N,N,N,
+N,N,N,N,35836,N,41078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35789,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40794,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40948,N,N,40890,N,N,N,N,N,N,N,N,N,N,36218,N,N,N,N,N,N,N,N,N,
+N,N,N,40517,N,N,N,N,N,N,37808,N,41077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39750,N,64686,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64688,N,N,N,N,N,N,
+N,N,N,64081,N,N,N,N,N,36219,36220,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40662,N,N,37804,N,N,N,40795,N,37801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41084,N,N,N,N,N,N,N,64690,N,N,N,
+N,N,N,N,N,N,N,N,N,35521,N,N,N,N,N,40884,N,N,N,N,N,N,N,N,N,N,N,64684,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40524,N,N,N,N,N,N,N,36805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37805,N,N,N,N,N,N,N,
+N,N,N,N,N,40387,N,N,N,36258,N,N,N,40266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64694,N,N,36259,40523,N,40525,36260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35581,N,N,N,N,N,64693,N,64707,37810,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36261,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37793,N,N,N,N,N,N,N,N,N,N,35526,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,35419,N,N,N,35149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,65236,N,N,N,N,35448,N,37803,N,N,N,N,N,N,N,N,N,36263,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40773,N,N,N,N,N,N,N,N,N,35414,N,N,N,64703,N,N,N,
+64704,N,36582,N,N,35492,35139,N,N,N,N,N,N,37875,N,N,N,N,N,N,N,N,N,N,N,N,64683,
+40610,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40391,N,N,N,50898,35790,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64715,N,
+N,N,N,N,N,N,N,N,N,N,37811,N,64714,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64713,36268,N,64454,35175,N,35966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64717,N,N,N,N,N,N,N,N,40179,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64720,N,N,38331,N,N,N,N,N,N,N,N,N,N,N,64723,N,N,
+64724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36270,64727,N,N,N,
+N,N,37851,N,N,N,N,65123,N,N,N,N,N,N,N,N,N,N,N,N,37845,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64730,N,N,N,39793,N,N,64733,N,N,N,N,N,N,N,36271,N,N,N,64242,N,N,
+N,N,N,N,N,N,N,N,N,37848,N,N,N,64735,N,N,N,37843,N,N,N,N,N,N,N,64737,N,N,N,N,N,
+N,N,N,N,36470,N,N,N,N,N,N,N,64610,N,N,N,N,N,N,N,N,37841,N,N,N,36273,N,N,N,N,N,
+N,N,39001,N,N,N,N,N,N,N,N,N,64338,N,N,N,N,N,N,N,N,64339,N,N,N,N,N,64333,N,N,
+40127,N,N,N,N,N,N,N,N,39794,N,N,N,N,N,N,N,N,N,N,N,N,N,64336,37822,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40433,64747,N,N,N,N,N,
+N,N,N,N,41147,N,39806,N,N,N,N,N,N,N,36275,N,N,35922,N,N,N,N,39656,N,N,N,N,N,N,
+36572,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40185,N,N,N,N,N,N,N,N,N,N,N,N,N,64080,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39143,64755,N,N,N,N,
+64754,N,N,N,36042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,37861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39513,N,N,N,36277,N,N,N,N,N,N,
+N,64845,N,N,N,N,64862,N,N,N,N,N,N,N,N,N,N,N,N,N,36733,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38215,64758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37456,N,N,N,N,35176,36278,64763,41085,39164,35177,N,N,N,N,
+N,N,N,N,65103,N,N,37462,N,N,N,N,N,N,N,N,N,N,64201,N,N,37864,N,N,N,64760,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40163,64937,N,N,N,N,N,N,64580,N,N,N,N,N,N,N,N,
+38464,N,N,36280,N,N,N,N,N,N,N,N,N,N,39754,36793,N,N,N,N,N,N,64766,N,N,N,N,N,N,
+N,35178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36281,N,N,
+N,37246,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37876,N,N,N,N,N,N,N,N,N,N,N,N,N,64380,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37863,N,N,38895,N,N,N,65098,N,N,N,N,N,64837,N,
+38565,N,N,N,N,65248,64840,64839,65266,65130,N,N,N,N,N,36285,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39841,36002,39607,36604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40865,N,N,N,
+N,N,N,N,N,N,64849,N,N,N,N,N,N,N,64173,N,N,N,N,36286,N,N,35236,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39641,N,N,N,N,N,N,N,N,N,N,N,64846,N,N,36288,N,N,38896,N,N,N,N,N,N,
+N,N,N,N,37812,64836,N,N,N,N,N,N,N,N,N,N,N,N,40871,N,N,N,N,36290,N,N,N,N,39350,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,N,N,36289,N,N,36422,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,41169,N,N,N,N,N,N,N,N,N,N,N,N,N,40906,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37583,N,N,N,40180,36292,N,N,N,N,N,N,N,N,N,N,64833,N,N,N,N,N,N,N,39756,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64855,64751,40158,N,N,N,N,N,N,N,64834,39020,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38905,N,38232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39006,65147,38093,
+N,N,N,N,N,37870,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36003,N,64858,N,N,N,N,N,N,37877,
+N,N,N,N,N,37871,36586,N,N,N,36699,N,N,N,N,N,N,N,N,N,N,N,35934,N,36294,N,N,N,N,
+N,N,N,N,N,N,N,36296,N,N,36295,N,N,N,N,N,37879,N,N,N,N,N,N,N,36297,N,N,N,N,N,N,
+N,64498,N,N,N,N,38512,N,N,N,N,N,N,N,N,N,36299,N,N,N,64860,N,N,N,N,N,N,N,N,N,
+36709,N,N,N,36301,N,N,N,N,N,40360,38137,N,N,36302,N,N,N,N,N,N,N,N,37866,N,N,N,
+N,N,N,N,N,N,64863,37872,40886,N,N,N,N,N,N,N,N,N,36303,N,N,N,38755,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36304,37873,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40923,N,N,N,N,
+37880,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35831,N,N,N,N,64870,N,N,N,
+N,N,35791,N,N,N,N,N,N,36305,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64881,N,N,N,N,64879,
+N,N,N,N,N,N,N,N,36307,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40935,37053,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40912,N,N,N,35792,N,64882,N,40110,35793,N,N,35547,N,
+N,N,N,N,N,N,N,N,N,N,64228,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38350,N,64886,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64354,N,N,N,N,N,N,36308,N,N,N,64888,N,N,N,N,N,
+36579,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36982,N,N,
+39110,N,N,N,N,N,N,N,36309,N,N,N,N,38865,N,N,40630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,64199,N,N,41026,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39027,N,N,
+N,N,N,N,N,N,N,N,40956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36005,36311,N,N,
+37627,36312,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37967,N,
+36313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,35179,N,N,N,N,N,N,N,N,38862,N,N,N,64243,64942,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64431,37559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36314,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40026,N,N,N,N,N,N,64941,N,N,N,N,N,N,N,N,N,N,N,N,N,36316,37956,N,N,N,N,
+N,N,N,N,N,N,N,36317,N,N,N,N,N,N,N,41174,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35905,38869,N,37962,N,N,N,N,N,37965,N,N,N,N,38859,N,N,N,N,
+N,36318,N,N,36319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36320,65273,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64960,64761,N,N,N,N,N,
+N,N,N,64382,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37555,N,N,
+N,N,N,64943,N,N,N,N,N,N,N,N,N,36321,N,N,N,N,38355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64872,N,N,40119,N,N,
+36323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64192,36325,
+64100,N,35143,N,N,N,N,36324,N,N,N,N,N,36327,36328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64967,64944,N,N,N,N,N,N,37957,38870,N,N,N,N,N,N,N,N,N,64710,38980,N,N,N,N,
+N,N,N,N,N,N,N,N,36329,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36330,N,N,N,N,N,N,N,N,
+65104,N,N,N,N,N,N,64972,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40359,N,N,N,N,N,
+64973,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64975,N,N,N,N,38354,N,N,N,
+N,N,N,N,36333,N,N,N,N,N,N,N,N,64698,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64965,
+N,64978,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40156,N,N,N,N,N,38351,N,N,
+36334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64980,N,N,N,N,N,38636,38635,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37046,N,64963,39083,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38638,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36340,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64992,N,
+35943,N,N,36342,N,N,N,36343,N,N,N,N,N,N,N,36858,N,N,N,N,N,N,N,N,N,N,38864,N,N,
+N,N,35794,N,N,36344,N,N,N,N,N,37081,N,35911,N,64240,N,N,N,N,64993,36345,N,
+64995,N,N,N,N,N,N,N,36346,N,64355,N,N,N,37030,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39280,N,N,37355,N,38768,39023,64994,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39154,N,
+39676,35180,65021,N,N,39262,N,N,N,38333,N,N,N,N,N,N,N,64996,N,N,N,37350,N,N,N,
+N,64997,64998,N,N,N,N,N,N,N,N,64999,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37972,N,
+N,N,39352,N,N,N,N,N,N,N,N,38889,37702,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39011,N,N,N,N,N,N,N,N,N,N,N,38332,N,65005,65015,N,N,N,N,N,N,39024,38646,
+36521,N,N,N,N,N,37969,N,N,36419,N,35674,N,N,N,N,65006,N,N,N,N,65008,N,N,N,N,
+65012,N,39925,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38782,N,N,N,N,
+N,39893,N,39619,N,38856,41179,37328,N,N,40932,N,36829,N,37353,N,N,N,N,N,N,N,N,
+N,39136,N,N,N,37578,N,38999,N,N,35921,N,N,N,N,65003,N,39753,N,N,N,N,N,N,N,N,N,
+40310,40623,N,N,N,N,N,N,N,N,N,40140,N,N,N,N,N,N,65002,N,N,36337,N,N,65019,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36435,N,N,N,N,N,N,N,N,N,N,N,64207,N,N,
+N,N,N,N,N,N,N,N,N,N,N,38649,N,N,N,N,N,N,N,N,N,39103,40521,36007,N,N,N,N,N,N,N,
+N,39882,N,N,N,N,65022,37596,N,N,N,N,N,65089,37324,37346,N,N,N,N,N,N,N,N,N,N,N,
+N,65092,N,N,N,N,N,N,35795,N,N,65095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65096,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37973,N,N,N,N,65099,N,65100,N,N,N,N,36287,N,N,N,N,
+N,N,N,N,N,40568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65105,N,
+N,N,N,37974,N,N,N,N,N,N,N,40289,N,N,N,N,37975,N,N,N,N,N,N,N,N,N,N,39270,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35797,N,N,N,N,41065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,39092,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41033,41036,N,
+40549,N,N,N,N,N,N,N,N,N,N,N,39093,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65112,N,39285,65107,41061,N,65113,N,N,N,N,N,N,N,N,N,39095,39096,N,N,N,N,N,N,
+N,39098,N,N,N,N,N,N,39099,N,N,N,N,N,N,40892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41034,N,N,40647,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,36009,N,N,39086,N,N,N,N,N,N,N,N,37590,N,N,N,64225,N,37332,N,N,
+N,N,N,N,N,N,64222,N,N,65115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35923,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,65118,N,N,N,N,64471,65114,38085,N,N,N,N,64202,N,N,N,N,N,N,N,N,N,
+N,N,39105,38748,N,65140,N,38771,N,N,N,N,N,N,N,N,64070,N,N,N,38756,N,N,N,65128,
+N,38478,N,38757,35930,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35233,38394,N,37588,65129,N,
+64325,N,39112,N,N,37103,N,39113,39114,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37997,38071,65132,N,N,37995,N,N,N,N,N,N,37628,N,38379,N,65139,38766,
+65119,N,N,N,N,N,N,N,N,N,64957,N,N,37589,N,N,N,N,N,N,65209,N,N,65137,N,N,N,N,
+64443,N,N,38010,N,N,38395,65143,N,N,N,N,N,N,N,65145,N,65141,N,N,N,37981,N,N,N,
+N,N,N,N,65148,N,N,N,N,N,N,N,N,N,37700,36518,N,N,N,N,N,N,N,N,N,N,N,37587,N,
+38072,N,N,N,N,N,N,N,N,64625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38750,N,N,N,N,36013,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,65191,N,N,N,37994,N,N,N,37859,N,N,39119,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,41177,N,N,N,N,N,N,N,N,41151,41037,41144,N,N,N,N,N,
+41166,41143,N,N,N,N,N,N,N,N,65193,N,N,N,N,N,N,N,N,N,N,35267,N,N,N,N,65195,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40436,35181,N,N,N,N,N,40059,N,N,N,N,N,N,
+39122,N,N,N,40873,N,N,N,65202,N,N,65201,N,N,N,38873,N,41156,N,38006,N,N,N,N,N,
+N,N,N,N,N,39288,N,N,N,N,N,N,65203,N,N,N,N,N,39123,65204,N,N,N,39124,N,N,N,N,N,
+N,N,40889,N,N,N,N,N,N,N,N,38001,N,N,N,N,N,N,N,N,N,39125,65208,N,N,N,50900,N,N,
+N,N,N,N,N,N,N,N,N,65210,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40540,N,N,65211,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,41028,N,N,N,N,39127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39128,65212,N,N,N,N,40958,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65213,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40413,N,N,N,N,
+40673,N,N,N,N,N,N,N,N,N,N,N,N,39130,40415,65215,N,65214,N,N,40683,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40537,41052,N,N,N,N,N,N,N,65216,N,N,N,38007,39132,N,
+65217,N,N,N,39134,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65219,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,65224,N,N,N,65225,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65226,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65227,N,N,N,N,N,N,N,N,N,40898,N,N,
+35947,39108,N,38064,38065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65233,N,N,N,N,N,41153,N,
+65234,N,N,N,N,41165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65235,N,N,39141,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65238,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37348,N,N,N,N,36807,38062,N,35407,38066,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36820,N,N,N,N,39146,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65240,N,N,N,N,N,N,N,N,N,40416,N,N,N,N,39150,N,N,N,N,38340,N,64744,N,
+N,N,N,N,39151,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35950,N,N,N,N,N,N,N,N,64216,N,
+N,N,N,N,N,N,N,N,N,N,N,N,65244,N,N,N,N,N,N,N,N,N,41134,40268,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39153,N,N,N,39155,N,38081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39157,N,N,64079,38626,N,N,N,N,37968,N,38562,N,N,39158,N,N,N,38629,
+N,N,N,N,N,39159,N,41030,38627,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39160,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40676,N,N,N,N,N,N,63958,N,N,N,N,N,N,38083,N,N,N,
+N,38082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65249,N,65257,N,N,N,N,38628,N,35244,38619,N,N,N,N,N,N,N,N,N,N,N,N,N,65250,N,N,
+N,N,N,N,N,N,N,N,38084,65251,N,N,N,65255,40955,N,N,N,N,N,N,N,N,N,N,N,35929,N,N,
+N,N,N,N,N,N,N,37833,N,38120,64342,N,N,N,37061,41128,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65253,N,N,N,39165,39163,
+65256,N,36543,N,N,N,N,35800,65271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36712,38086,N,N,N,N,N,N,N,N,40426,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64617,
+N,N,N,N,N,N,N,N,N,N,N,N,40154,N,65267,N,N,40050,N,N,65264,35273,N,N,N,N,N,N,N,
+N,N,39233,N,N,N,N,N,N,N,39234,N,N,N,65269,N,37335,N,N,N,N,N,38092,N,N,N,65272,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38824,N,65276,N,N,N,N,N,
+64959,N,N,N,N,N,N,N,65278,N,N,N,N,N,N,N,N,N,N,N,N,N,38609,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,38101,N,N,38096,39236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35939,N,N,41139,N,N,N,N,N,N,N,N,N,N,N,N,38095,N,N,N,
+40954,N,N,N,N,37349,N,40042,N,N,N,36425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,36428,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36429,N,N,
+N,N,N,39539,N,N,N,N,N,N,N,N,N,N,N,N,N,39239,N,36017,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36432,N,N,N,N,N,N,N,N,N,N,36431,39241,N,N,N,N,N,
+36433,36434,N,N,N,N,39602,35237,N,N,N,N,N,39244,N,N,N,40952,N,N,N,N,N,N,36438,
+39245,37322,36439,N,N,N,N,38113,N,N,N,N,36935,N,36824,36440,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38123,36444,38227,N,N,N,N,N,N,N,40933,N,N,N,N,N,N,N,N,N,N,
+40790,N,N,N,N,N,N,N,38223,N,36446,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39274,N,N,N,N,
+N,N,N,N,40036,40153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36445,N,N,N,N,N,N,N,N,N,
+N,N,N,39248,N,N,N,N,N,N,N,N,N,39249,N,N,36450,N,N,N,N,N,N,N,N,N,N,N,39250,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36456,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36449,40793,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40797,36454,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36018,N,N,N,N,N,N,N,N,N,N,N,N,N,36462,N,40804,39251,N,N,64184,N,N,
+N,N,N,39252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36464,N,N,N,N,N,
+N,N,N,N,N,N,N,40801,N,36466,N,N,N,N,N,N,N,N,N,N,N,N,41067,N,N,N,N,40768,N,N,N,
+N,N,N,38125,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38126,N,N,40893,N,N,N,36475,N,N,N,N,
+N,N,39255,38135,N,40799,N,N,N,N,36467,N,N,40802,N,N,N,N,N,N,N,38134,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39256,N,N,N,N,N,N,N,N,N,36469,63963,N,N,N,N,36978,N,38136,N,N,
+N,N,N,N,N,N,N,39258,N,N,N,N,N,N,N,N,N,41136,36019,N,N,N,36473,N,36472,N,N,N,
+38131,N,N,N,N,N,39087,N,N,N,N,N,N,41138,N,N,N,N,N,N,N,N,N,N,N,36474,N,N,N,N,N,
+N,39260,N,N,N,N,N,36476,N,36477,N,N,N,35801,N,N,35234,40663,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41142,N,N,N,N,N,N,
+N,N,N,N,N,N,40514,N,N,36516,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36519,N,35958,N,N,N,N,N,N,N,N,N,N,N,38210,
+N,N,N,N,N,N,N,N,N,N,N,N,39037,N,N,N,38741,N,N,36520,N,N,N,N,N,N,N,36522,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35235,N,39264,39266,N,N,38140,
+39265,N,N,N,N,N,N,N,38138,N,N,N,N,N,N,N,36526,36530,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36528,N,N,N,N,N,N,N,39267,38826,38139,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36060,N,N,N,N,N,N,N,N,
+N,39030,N,36513,N,N,N,N,36020,N,36535,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40358,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40624,N,N,N,36536,N,N,N,N,N,N,N,N,N,N,N,N,40304,N,N,
+N,N,35182,N,N,N,N,N,N,N,35183,N,N,N,N,N,N,N,N,N,N,N,N,N,35184,N,N,N,N,N,N,N,N,
+N,N,N,N,35185,N,N,N,N,N,N,N,35186,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35187,35188,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35189,N,N,N,N,N,N,N,N,36540,36541,N,N,N,N,N,36542,N,40401,N,N,
+N,N,38141,N,N,N,35799,35802,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,41186,N,N,N,N,N,N,40937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64936,N,N,N,35559,N,N,N,36546,N,N,N,N,N,N,N,N,N,N,N,36548,N,N,N,N,N,N,N,N,N,N,
+39268,N,N,N,N,N,39269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,38222,N,N,N,N,N,N,N,N,N,39091,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36555,35807,N,N,N,N,N,36558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,36559,N,N,39272,N,N,N,N,39273,N,N,N,N,N,N,N,N,39275,36561,N,39276,N,N,N,N,N,
+N,N,N,N,36564,36565,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39277,N,N,N,
+N,N,N,41150,N,N,N,N,N,36566,41148,41141,N,N,41140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35253,N,N,N,N,N,N,N,36573,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40541,39281,N,
+N,N,N,35246,40424,N,N,N,N,N,N,N,N,38245,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39282,N,N,35676,N,N,N,N,N,N,N,N,N,35249,41152,N,
+N,N,36575,N,38246,N,N,39284,N,39286,N,N,N,39287,N,39289,N,N,40410,N,N,36576,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37724,N,N,N,N,N,N,N,40422,N,35679,N,N,38243,N,N,N,
+N,N,N,N,N,N,N,38247,N,N,N,N,N,40419,N,N,N,N,N,N,N,N,N,N,N,N,N,39292,N,N,39293,
+39294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39331,N,N,N,N,N,N,N,39332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39334,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39336,N,N,N,N,35518,N,N,N,N,N,N,N,N,N,N,N,40545,N,N,N,N,N,N,N,
+N,N,N,39338,N,N,N,N,N,N,41160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39339,N,N,N,N,N,N,N,N,N,N,65220,N,N,N,N,N,N,39106,36584,N,41146,N,N,N,N,
+N,N,N,N,N,N,N,64887,N,N,36590,N,N,N,40639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39340,N,N,N,N,N,N,N,N,N,N,N,N,
+N,38251,N,N,38252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39343,N,N,39242,35190,36680,
+N,N,N,N,N,N,N,N,N,N,N,64494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39342,N,N,N,36603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36048,N,N,
+N,N,35666,N,N,N,N,N,39344,N,N,N,N,35191,36673,N,N,N,N,N,N,N,39345,N,N,N,N,N,N,
+N,N,N,36681,N,N,N,N,N,N,N,N,N,N,N,64077,N,N,N,N,N,N,N,N,40420,36021,N,N,N,
+64489,39764,N,39346,40552,N,N,N,N,N,N,N,N,N,N,N,N,36682,N,36674,N,N,36689,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38982,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39348,N,N,N,N,N,N,N,N,N,N,36597,64853,N,N,
+40141,N,N,N,N,N,N,N,N,35192,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36691,N,
+N,N,N,N,N,N,N,N,N,N,36719,N,N,N,N,N,N,N,N,N,N,36451,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36694,N,N,N,N,N,N,N,N,N,N,N,N,65142,N,N,N,N,40902,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64172,N,N,N,N,N,36696,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38984,39351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38501,N,64108,N,40423,N,N,N,40546,N,N,
+N,38604,36455,N,N,64629,N,39038,N,N,N,N,N,N,N,64953,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,38908,N,N,N,N,N,N,N,N,N,39161,N,36710,N,N,N,N,N,N,N,N,38254,N,37445,N,N,
+36704,N,N,N,40657,N,N,N,N,N,65229,N,39353,N,N,N,N,N,N,N,N,N,N,N,N,36706,38732,
+N,N,N,N,N,N,N,N,N,N,N,N,37319,38239,N,N,N,N,N,N,N,39355,N,N,N,N,N,N,N,N,N,
+36461,36721,N,N,38091,N,N,N,N,N,N,N,N,N,N,N,N,38321,N,N,N,N,N,N,N,N,N,39666,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,38595,39357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,41167,N,N,N,36717,N,N,39358,36596,N,36722,38372,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39359,37442,N,64421,N,N,N,N,N,N,N,N,N,N,39360,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64948,36727,N,N,N,
+39361,N,N,N,N,N,N,N,N,N,64185,N,N,N,N,N,N,N,N,36672,64068,N,N,N,N,N,39362,N,N,
+N,N,N,N,N,36700,N,N,N,N,36029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39364,39365,N,N,
+36731,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36022,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36046,N,N,N,N,N,N,N,N,
+N,39366,N,N,N,N,N,N,N,N,N,N,N,N,N,38605,N,N,N,N,N,N,N,N,N,N,N,N,N,38599,36773,
+N,N,N,N,N,N,N,N,N,N,64187,N,35937,38256,N,N,N,37736,N,36734,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,36778,N,N,N,N,N,N,41040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37075,N,N,38230,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36792,N,N,N,N,N,39368,N,N,N,N,N,N,N,N,N,N,N,36783,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39369,N,N,N,N,N,N,N,N,N,N,N,N,N,38265,N,N,N,N,N,N,N,N,
+N,N,N,N,40777,N,N,N,N,39370,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39371,
+40405,36784,N,N,N,N,N,N,N,N,N,N,N,64122,N,N,N,N,N,N,N,N,40543,N,N,N,N,39373,
+41161,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39643,N,N,N,41158,N,N,N,
+N,N,N,N,36788,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41175,N,N,N,N,N,N,N,N,N,N,N,N,
+41159,N,N,N,N,N,N,N,41027,N,N,N,36789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36786,N,N,N,N,N,N,41057,40542,N,N,N,N,N,N,N,N,N,N,36790,N,N,N,N,N,N,N,N,40936,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40114,N,N,N,N,N,38268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40903,N,N,36795,36796,N,N,N,N,N,N,N,N,36844,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36800,N,37738,N,N,N,35812,40060,N,N,N,N,N,N,N,N,38305,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,65260,N,N,38307,N,N,N,N,N,N,N,35909,36024,N,N,N,N,N,N,
+N,N,N,N,N,36801,N,N,N,41042,N,N,N,N,N,N,N,N,N,N,N,N,N,39376,N,N,N,N,N,36803,
+36804,N,N,N,N,N,N,N,N,N,38308,N,N,N,N,N,36806,N,40544,N,N,N,N,N,N,N,63960,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38309,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40115,N,N,N,N,N,N,N,N,N,39377,65265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,39378,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40130,N,N,N,39379,N,N,N,N,N,38311,N,N,N,N,N,N,38313,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,38310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40029,N,N,N,N,N,
+N,N,N,39138,N,N,N,N,N,N,36809,N,41154,36810,N,N,N,N,N,N,39380,N,N,41145,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39768,N,36813,N,41172,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36814,N,N,N,N,35813,N,N,N,N,35193,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36816,38326,N,N,N,N,N,N,N,N,N,N,N,N,39382,N,38373,N,
+N,N,N,N,N,N,N,N,N,N,N,39383,N,N,N,N,38325,N,N,N,N,N,N,N,N,N,N,N,41162,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40957,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,41048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36822,N,N,N,
+39384,N,N,N,N,N,N,N,36819,N,N,N,N,N,N,N,N,N,N,N,N,36837,N,N,N,N,N,36841,N,N,N,
+N,39385,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37500,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40005,36830,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36831,N,N,N,N,N,N,N,N,N,N,N,N,N,41035,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36834,N,N,N,41164,N,N,N,N,N,N,N,N,36835,36836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39876,N,N,N,39932,N,N,N,N,N,N,38476,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,39670,N,36014,N,N,N,N,N,N,N,N,N,N,N,N,36839,N,N,N,N,N,N,N,N,N,N,36840,
+N,N,N,N,35815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35194,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35195,
+39386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36845,N,N,N,38336,N,N,N,N,N,N,N,N,N,N,N,N,N,41163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40520,N,N,N,N,N,N,39387,N,36851,N,N,N,N,
+36857,N,N,N,N,N,N,N,N,N,N,N,N,N,38337,N,41038,N,N,N,N,N,N,39388,N,N,N,N,41060,
+36855,N,N,N,N,N,N,N,35248,41032,N,N,N,N,36859,36854,N,N,N,N,N,40412,N,N,N,
+39389,35816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37569,N,N,N,N,N,N,N,40918,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41170,N,N,36928,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35524,N,N,39392,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40944,40947,N,N,N,N,N,N,N,N,N,N,N,N,40383,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40950,N,38344,N,N,40538,N,N,N,N,N,N,N,N,N,N,N,N,39395,
+N,N,N,N,N,N,N,N,N,N,N,35402,N,N,N,N,N,N,N,N,40945,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35495,N,N,N,N,N,N,N,N,39398,N,N,N,40951,N,40941,N,N,N,N,N,
+N,35420,N,40366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38345,N,N,N,N,N,36936,N,N,39400,N,N,N,N,N,36937,N,N,36026,N,N,
+37041,N,N,N,N,N,N,36938,N,N,N,N,N,N,N,N,N,N,39402,N,N,N,N,N,N,N,N,N,N,N,39889,
+N,N,N,N,N,N,N,39403,N,39404,N,N,N,N,N,N,N,N,39405,N,N,N,N,39406,36940,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36941,N,N,38347,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38882,N,N,N,N,N,N,N,N,38348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40824,N,N,N,N,N,
+N,N,N,N,35196,35197,N,N,N,N,N,N,35198,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39261,N,N,N,N,N,N,N,N,N,N,N,N,39770,N,N,N,N,
+36944,N,35919,N,N,N,N,N,N,N,N,N,N,N,36948,N,50902,39592,39407,65259,40355,
+40353,39235,39237,N,40317,N,N,39408,N,N,N,N,N,N,N,N,39409,N,39410,N,N,36028,
+40288,N,N,N,N,N,N,N,N,N,41123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36955,40667,N,N,N,N,N,N,N,N,N,40313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39411,N,N,N,36962,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40789,N,N,N,N,N,N,N,N,N,39929,N,N,N,N,N,N,N,N,N,N,36965,N,N,
+38624,N,N,N,N,N,N,N,39102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36968,N,N,N,
+N,N,36972,N,N,N,N,N,N,N,N,N,N,N,N,38360,N,N,N,N,N,N,N,N,36970,40882,N,N,N,N,N,
+N,N,40878,N,N,40880,N,35245,N,N,N,N,N,N,N,N,36974,N,N,N,N,N,N,N,N,40561,N,N,N,
+N,N,40522,N,N,N,N,N,40924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35243,N,40888,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36976,N,N,N,N,N,N,N,N,N,N,N,N,
+35683,N,N,N,N,38364,N,N,N,N,N,N,N,N,36977,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64606,N,N,N,N,N,N,N,N,35145,N,N,N,N,N,38491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35920,N,N,N,38054,N,N,N,36821,40563,N,N,N,N,N,36981,N,N,N,N,39415,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36031,N,N,N,N,N,N,39417,N,38499,38329,N,N,N,N,N,N,N,N,N,38100,N,
+N,N,N,N,N,64762,N,N,N,N,36983,N,N,37035,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40269,
+N,N,39418,N,N,N,N,37603,N,38843,N,N,36984,N,N,N,N,N,N,N,N,39419,N,N,38880,N,N,
+N,N,N,N,N,N,38620,N,N,N,N,N,N,N,N,N,40104,N,N,38770,N,N,N,N,37952,N,N,N,N,N,
+37618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39421,N,N,
+39420,N,N,N,N,N,N,N,63959,38474,N,N,N,38616,39422,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36939,N,N,N,N,N,N,64065,N,N,N,N,N,N,N,39488,N,38747,N,N,N,N,N,
+39489,37341,N,N,N,N,N,37884,39490,39491,N,38489,N,N,N,N,N,N,39492,36945,N,N,N,
+38079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37026,N,N,N,40107,38774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64597,65093,38056,39493,
+64075,40417,N,N,38617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38772,N,N,
+65013,N,N,N,37605,N,38469,37338,N,37027,N,N,41055,N,N,N,N,37039,38847,N,N,N,
+37196,N,N,N,N,38522,N,N,N,37342,N,N,39494,65200,38777,37996,N,N,N,N,N,N,N,N,
+39000,N,N,N,N,N,N,N,N,N,N,N,37478,N,N,N,37883,N,N,N,N,N,N,N,N,N,N,N,N,39495,N,
+N,N,N,N,N,N,N,N,N,38729,N,N,38728,N,37706,N,40162,N,N,N,N,N,N,37476,N,N,N,N,
+37343,N,N,N,N,N,N,N,64377,N,N,N,N,N,N,N,38615,N,N,N,N,37699,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64971,65146,N,37339,35946,38831,N,N,38365,N,N,N,37704,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39499,N,N,N,64581,N,39501,N,N,N,N,N,N,37308,37090,37044,38369,
+N,N,N,N,N,39502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39503,N,N,N,65088,65091,N,N,N,
+N,N,N,N,N,N,38621,N,N,N,N,N,N,39505,N,N,N,38567,N,N,37040,N,N,N,N,N,N,N,N,N,
+40014,N,37955,N,N,N,N,36538,N,N,N,N,N,N,N,N,N,N,N,N,39506,N,64705,N,N,N,N,N,N,
+N,N,N,35817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40111,N,N,35837,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39612,N,39608,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39591,39507,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35818,N,N,N,N,N,N,35819,N,N,N,N,N,37042,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,38377,38376,N,38374,N,N,N,N,N,N,37045,N,39508,N,N,N,
+37043,38375,N,N,35664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35820,N,N,N,
+N,N,N,N,N,N,N,N,39510,35835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39511,N,
+N,N,N,41130,N,N,N,N,N,N,N,N,40870,N,N,N,39372,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39349,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37054,N,N,N,N,N,40879,N,N,N,N,N,N,N,N,N,N,N,N,N,38386,N,N,N,N,N,N,37055,N,
+N,N,N,N,N,N,N,N,N,N,N,37057,N,65252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37060,N,N,
+N,N,N,N,37063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37604,40786,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37083,N,N,N,N,N,41062,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37074,N,N,N,N,37076,N,N,N,N,N,N,N,N,N,39515,38397,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,35780,N,N,N,35942,N,37086,N,N,N,N,N,40164,N,37089,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40518,N,N,N,38481,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64344,N,37094,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38480,N,N,N,37095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37096,39517,N,40826,N,N,N,39772,N,40828,N,N,64594,37097,N,37098,N,39518,N,
+N,N,N,N,40822,N,N,N,N,N,N,N,N,N,37099,N,N,N,N,N,N,N,N,N,N,N,N,N,37100,N,N,N,N,
+N,35822,N,N,N,N,N,N,N,37102,N,N,N,37318,N,N,37106,64700,35444,N,N,N,N,N,N,N,N,
+N,38487,N,N,N,40175,N,N,N,N,N,N,N,N,N,N,40927,N,N,N,N,37111,37110,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39774,N,N,N,37112,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37113,N,36041,N,N,N,64106,N,N,N,N,N,N,N,N,35823,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40928,N,N,37186,N,39522,N,N,N,N,N,N,N,N,N,
+38249,N,N,N,37188,37187,N,37185,N,N,N,35824,N,N,N,N,N,N,N,N,N,N,N,N,N,38496,N,
+35825,N,39414,37193,N,N,N,N,37194,N,N,N,N,N,37195,N,N,N,N,39524,N,N,N,35519,
+39526,N,N,N,N,N,N,N,N,N,N,39527,N,N,39529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39530,38482,37197,N,38502,N,N,N,N,40827,N,39531,N,N,N,N,N,N,N,
+41068,N,N,38503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39532,N,N,N,N,39533,35826,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38506,N,N,N,N,N,N,N,N,64746,N,N,N,N,N,38508,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37316,N,N,N,38519,N,N,N,N,N,N,N,39412,39535,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40875,N,N,N,N,N,36030,36545,N,N,N,N,38229,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37202,37203,N,N,N,37205,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38237,N,
+38513,N,N,N,N,40045,N,N,N,N,N,N,N,N,38515,N,N,N,N,N,N,N,N,N,N,N,37204,39537,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37206,N,N,N,38509,N,N,N,N,
+N,N,38231,N,N,N,N,N,N,N,N,35270,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,35434,N,N,N,35671,N,N,N,40929,N,N,39775,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41053,N,N,N,N,N,N,N,N,37211,N,37212,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37214,N,N,N,N,N,N,N,N,N,N,40796,40791,N,N,N,N,N,N,40805,
+N,N,N,N,N,39538,N,N,N,N,37216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40798,
+N,N,37217,N,N,N,N,N,N,37220,N,N,N,N,40769,N,N,N,N,N,N,37225,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,37224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39540,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38578,N,39541,N,64933,N,N,N,N,N,N,N,40681,
+N,35770,37229,41056,N,N,N,N,N,N,N,40926,N,N,N,N,N,40899,N,38581,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,41063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,38579,N,N,N,N,N,N,N,N,N,N,N,N,N,39542,N,N,N,N,N,N,N,N,N,N,N,38357,N,N,N,
+40650,N,N,N,39543,N,N,39544,N,N,N,N,N,N,N,N,N,N,37232,37231,N,N,N,N,N,N,N,
+40867,N,37233,N,N,N,38577,N,N,N,N,40803,N,N,N,N,N,40807,N,N,N,35769,39546,N,N,
+N,N,N,35670,N,N,N,N,N,N,N,N,39642,N,N,N,N,N,38576,N,N,N,N,39550,N,N,N,N,N,N,N,
+N,N,N,40414,N,N,N,N,N,N,N,N,N,38573,N,N,N,38574,N,N,N,N,N,N,N,N,N,40609,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40528,N,N,N,N,N,N,N,N,38575,35828,40868,N,N,
+N,N,N,N,N,N,N,38589,N,N,N,N,N,N,N,N,N,38644,N,N,N,N,N,N,N,N,N,N,38584,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64161,N,N,N,N,37287,N,N,N,N,N,N,N,N,N,N,41054,N,N,
+N,N,39549,N,N,N,N,35144,N,40625,N,N,N,N,N,N,N,N,N,N,N,N,N,40411,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38335,35443,N,N,N,N,N,N,N,N,N,N,N,N,N,40702,N,37242,N,N,N,N,
+37243,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39587,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38594,N,N,N,N,N,40823,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39588,N,N,39589,N,N,N,
+37281,N,N,N,N,35256,N,N,N,N,N,N,N,N,N,N,37235,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39590,35261,N,35257,N,37245,N,N,
+N,N,N,N,N,N,N,38587,N,N,N,40946,N,N,35829,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39593,N,N,
+N,N,N,40788,N,N,40931,40685,N,N,N,N,N,N,N,N,N,N,37290,N,N,N,N,37291,41072,N,
+40813,N,N,N,N,N,37292,N,N,N,37293,N,N,N,41213,N,40930,N,37295,40513,39594,N,N,
+37296,N,39595,N,N,N,N,N,N,N,N,N,N,N,39596,N,39498,N,37298,N,N,35830,N,39597,
+35254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39599,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,39600,N,N,N,N,N,N,39601,N,N,N,N,N,39585,37305,N,N,N,N,N,37306,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41025,35767,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37312,N,N,N,N,N,N,N,N,N,N,39603,37315,N,N,N,N,N,N,
+N,N,N,N,41212,N,N,40942,N,N,N,N,N,N,40809,N,N,N,N,N,N,N,37320,N,N,N,N,N,N,
+37321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36326,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37323,N,N,N,N,N,N,N,N,N,N,35272,N,N,N,N,N,36266,N,N,N,N,N,40925,34880,
+34881,34882,34883,34884,N,34886,N,N,34889,34890,N,N,34893,N,34895,34896,34897,
+34898,N,34900,34901,N,N,N,N,N,N,N,N,N,N,N,N,34914,N,34916,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34979,N,34981,N,N,N,34985,34986,35907,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35949,N,N,N,N,N,N,35956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36023,N,36025,N,36027,N,N,N,N,36032,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36055,36056,N,36058,51321,N,N,N,N,51326,51361,N,51363,35832,51408,
+N,N,N,N,51407,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50916,N,50917,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51405,N,
+51406,N,N,N,N,N,N,N,N,63998,
+};
+
+static const struct unim_index big5hkscs_bmp_encmap[256] = {
+{__big5hkscs_bmp_encmap+0,168,252},{__big5hkscs_bmp_encmap+85,0,220},{
+__big5hkscs_bmp_encmap+306,80,198},{0,0,0},{__big5hkscs_bmp_encmap+425,1,81},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+506,190,
+193},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+510,22,231},{0,0,0},{0,0,0},{
+__big5hkscs_bmp_encmap+720,96,125},{__big5hkscs_bmp_encmap+750,80,112},{0,0,0
+},{__big5hkscs_bmp_encmap+783,61,61},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__big5hkscs_bmp_encmap+784,128,227},{__big5hkscs_bmp_encmap+884,51,51
+},{__big5hkscs_bmp_encmap+885,5,254},{0,0,0},{__big5hkscs_bmp_encmap+1135,49,
+49},{0,0,0},{__big5hkscs_bmp_encmap+1136,53,251},{__big5hkscs_bmp_encmap+1335,
+6,254},{__big5hkscs_bmp_encmap+1584,9,245},{__big5hkscs_bmp_encmap+1821,1,251
+},{__big5hkscs_bmp_encmap+2072,15,250},{__big5hkscs_bmp_encmap+2308,8,254},{
+__big5hkscs_bmp_encmap+2555,1,251},{__big5hkscs_bmp_encmap+2806,14,244},{
+__big5hkscs_bmp_encmap+3037,13,239},{__big5hkscs_bmp_encmap+3264,19,253},{
+__big5hkscs_bmp_encmap+3499,6,255},{__big5hkscs_bmp_encmap+3749,0,250},{
+__big5hkscs_bmp_encmap+4000,4,250},{__big5hkscs_bmp_encmap+4247,3,249},{
+__big5hkscs_bmp_encmap+4494,17,252},{__big5hkscs_bmp_encmap+4730,43,242},{
+__big5hkscs_bmp_encmap+4930,1,244},{__big5hkscs_bmp_encmap+5174,3,233},{
+__big5hkscs_bmp_encmap+5405,6,245},{__big5hkscs_bmp_encmap+5645,19,244},{
+__big5hkscs_bmp_encmap+5871,0,250},{__big5hkscs_bmp_encmap+6122,6,231},{
+__big5hkscs_bmp_encmap+6348,15,255},{__big5hkscs_bmp_encmap+6589,16,192},{
+__big5hkscs_bmp_encmap+6766,4,237},{__big5hkscs_bmp_encmap+7000,9,156},{
+__big5hkscs_bmp_encmap+7148,4,248},{__big5hkscs_bmp_encmap+7393,3,253},{
+__big5hkscs_bmp_encmap+7644,3,252},{__big5hkscs_bmp_encmap+7894,1,254},{
+__big5hkscs_bmp_encmap+8148,2,249},{__big5hkscs_bmp_encmap+8396,1,254},{
+__big5hkscs_bmp_encmap+8650,19,239},{__big5hkscs_bmp_encmap+8871,2,251},{
+__big5hkscs_bmp_encmap+9121,5,253},{__big5hkscs_bmp_encmap+9370,0,254},{
+__big5hkscs_bmp_encmap+9625,3,251},{__big5hkscs_bmp_encmap+9874,2,249},{
+__big5hkscs_bmp_encmap+10122,2,254},{__big5hkscs_bmp_encmap+10375,13,255},{
+__big5hkscs_bmp_encmap+10618,5,245},{__big5hkscs_bmp_encmap+10859,16,245},{
+__big5hkscs_bmp_encmap+11089,9,252},{__big5hkscs_bmp_encmap+11333,12,223},{
+__big5hkscs_bmp_encmap+11545,35,253},{__big5hkscs_bmp_encmap+11764,7,226},{
+__big5hkscs_bmp_encmap+11984,44,229},{__big5hkscs_bmp_encmap+12170,24,254},{
+__big5hkscs_bmp_encmap+12401,7,234},{__big5hkscs_bmp_encmap+12629,10,255},{
+__big5hkscs_bmp_encmap+12875,24,241},{__big5hkscs_bmp_encmap+13093,2,254},{
+__big5hkscs_bmp_encmap+13346,0,202},{__big5hkscs_bmp_encmap+13549,0,250},{
+__big5hkscs_bmp_encmap+13800,3,246},{__big5hkscs_bmp_encmap+14044,5,250},{
+__big5hkscs_bmp_encmap+14290,28,255},{__big5hkscs_bmp_encmap+14518,2,254},{
+__big5hkscs_bmp_encmap+14771,2,250},{__big5hkscs_bmp_encmap+15020,4,248},{
+__big5hkscs_bmp_encmap+15265,3,254},{__big5hkscs_bmp_encmap+15517,5,246},{
+__big5hkscs_bmp_encmap+15759,0,226},{__big5hkscs_bmp_encmap+15986,2,251},{
+__big5hkscs_bmp_encmap+16236,2,248},{__big5hkscs_bmp_encmap+16483,5,220},{
+__big5hkscs_bmp_encmap+16699,2,217},{__big5hkscs_bmp_encmap+16915,12,254},{
+__big5hkscs_bmp_encmap+17158,8,245},{__big5hkscs_bmp_encmap+17396,6,244},{
+__big5hkscs_bmp_encmap+17635,6,254},{__big5hkscs_bmp_encmap+17884,11,252},{
+__big5hkscs_bmp_encmap+18126,18,252},{__big5hkscs_bmp_encmap+18361,37,254},{
+__big5hkscs_bmp_encmap+18579,7,223},{__big5hkscs_bmp_encmap+18796,6,250},{
+__big5hkscs_bmp_encmap+19041,2,246},{__big5hkscs_bmp_encmap+19286,3,246},{
+__big5hkscs_bmp_encmap+19530,24,255},{__big5hkscs_bmp_encmap+19762,11,237},{
+__big5hkscs_bmp_encmap+19989,5,248},{__big5hkscs_bmp_encmap+20233,3,252},{
+__big5hkscs_bmp_encmap+20483,2,239},{__big5hkscs_bmp_encmap+20721,112,245},{
+__big5hkscs_bmp_encmap+20855,4,255},{__big5hkscs_bmp_encmap+21107,0,231},{
+__big5hkscs_bmp_encmap+21339,28,234},{__big5hkscs_bmp_encmap+21546,12,226},{
+__big5hkscs_bmp_encmap+21761,81,247},{__big5hkscs_bmp_encmap+21928,3,212},{
+__big5hkscs_bmp_encmap+22138,1,242},{__big5hkscs_bmp_encmap+22380,25,249},{
+__big5hkscs_bmp_encmap+22605,8,196},{__big5hkscs_bmp_encmap+22794,81,254},{
+__big5hkscs_bmp_encmap+22968,8,253},{__big5hkscs_bmp_encmap+23214,3,244},{
+__big5hkscs_bmp_encmap+23456,1,246},{__big5hkscs_bmp_encmap+23702,45,244},{
+__big5hkscs_bmp_encmap+23902,29,244},{__big5hkscs_bmp_encmap+24118,3,245},{
+__big5hkscs_bmp_encmap+24361,20,245},{__big5hkscs_bmp_encmap+24587,14,245},{
+__big5hkscs_bmp_encmap+24819,12,255},{__big5hkscs_bmp_encmap+25063,2,255},{
+__big5hkscs_bmp_encmap+25317,2,124},{__big5hkscs_bmp_encmap+25440,2,252},{
+__big5hkscs_bmp_encmap+25691,10,254},{__big5hkscs_bmp_encmap+25936,2,165},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+26100,3,75},
+{0,0,0},{__big5hkscs_bmp_encmap+26173,122,239},{0,0,0},{__big5hkscs_bmp_encmap
++26291,229,237},{0,0,0},{__big5hkscs_bmp_encmap+26300,7,7},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+26301,2,237},
+};
+
+static const DBCHAR __big5hkscs_nonbmp_encmap[28325] = {
+40049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37749,N,N,N,N,N,
+N,N,37750,N,N,N,N,N,N,N,38216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,36550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35781,35834,
+N,N,51324,N,N,N,N,N,N,N,N,N,39604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34894,34891,
+51322,34888,N,N,N,34887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,41206,34885,N,34899,N,N,N,N,N,N,N,N,N,64685,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35501,N,37490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64583,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40913,64459,N,N,N,N,N,N,N,37501,N,N,N,N,N,N,N,
+39076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38119,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37067,37499,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38104,N,N,N,N,64607,N,64084,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39605,N,N,N,N,N,N,N,38618,37497,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64116,
+37493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36347,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35401,N,N,N,37599,39804,64099,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64096,37485,64098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39606,N,N,N,N,N,N,38763,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64874,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64852,N,37491,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38872,N,N,N,N,N,
+N,40891,37698,37494,N,N,N,N,N,N,N,N,N,N,64101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64110,N,N,N,N,N,N,40672,N,N,37568,37567,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,37566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39610,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35507,N,38773,64064,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64118,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64464,N,N,N,N,N,N,N,N,N,N,N,N,N,64123,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65133,N,N,N,N,N,N,39859,N,N,N,N,N,35276,N,N,N,N,39614,N,N,N,N,N,N,
+N,N,N,64066,37564,N,N,N,N,N,N,N,N,N,N,37980,39861,N,N,N,39615,N,N,N,39079,
+38820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37117,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64635,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39616,37571,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39888,38224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37574,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39078,38214,N,N,N,N,N,N,N,N,N,N,N,N,64867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64194,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40643,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35250,40038,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36947,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38849,N,N,N,N,N,N,N,N,N,N,N,N,N,39620,N,N,N,N,N,N,N,N,N,N,39621,36591,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64233,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37474,
+35575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39622,N,N,N,N,N,N,37601,N,N,N,
+N,39625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64198,N,N,N,N,N,N,N,N,
+38821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39627,N,N,N,64114,35422,N,38112,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37580,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35557,N,
+N,N,N,N,65116,39628,N,N,N,N,N,40441,35395,35494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64238,39884,N,N,N,39631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39633,N,N,N,N,N,N,N,
+N,40442,N,N,N,N,N,40316,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39635,
+N,N,38822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39263,N,N,N,64502,40901,
+35417,35691,N,N,N,N,N,N,39636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39637,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,38818,35396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40778,N,
+N,N,N,N,N,N,N,37025,64932,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35428,35570,
+35576,40408,N,N,38102,64254,64423,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39638,N,40781,N,N,64246,N,N,N,N,N,N,N,35415,N,35651,35652,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35510,N,N,N,N,N,35520,N,N,N,N,N,N,
+N,N,N,N,40532,N,N,N,N,N,N,N,N,N,N,39639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39640,39644,N,N,N,N,35530,40616,N,N,37475,39645,35685,35695,35710,N,N,N,N,
+36675,N,N,N,N,N,N,37584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35572,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40382,N,N,N,N,N,39649,N,64734,40445,35686,35696,
+35701,35556,35748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35565,N,N,N,N,N,N,N,N,N,
+35421,N,35656,N,N,N,N,40429,N,N,N,N,40512,N,N,N,N,N,N,N,35567,35574,40566,N,N,
+N,N,N,N,N,N,N,40675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39646,36350,N,N,N,N,64252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40113,40567,35684,35687,38731,N,N,N,N,N,N,N,N,38483,N,N,N,N,N,N,39648,
+35658,N,35569,35543,N,N,N,N,N,N,N,N,N,41131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35509,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35423,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35566,N,N,39647,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35582,N,N,N,N,N,N,35416,
+35747,35751,N,N,N,N,N,39651,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37473,N,N,N,N,N,N,N,N,N,N,40407,40573,40615,40619,36930,N,N,
+N,N,N,N,N,N,35705,35706,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39654,N,N,N,N,N,N,N,N,N,N,N,N,39653,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35454,N,N,N,N,N,40516,39655,35452,35697,N,
+N,39657,N,N,N,N,N,N,N,N,N,N,N,N,39658,N,N,N,N,N,N,N,N,N,N,N,N,N,39659,N,N,N,N,
+N,N,35517,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64334,N,N,N,N,N,N,N,N,N,
+N,39661,35577,40547,N,N,N,N,N,35657,35534,35694,N,N,N,N,N,35560,N,N,N,39662,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35418,35707,
+35708,39663,N,N,N,N,N,N,N,N,N,N,N,39664,N,35578,N,N,N,N,N,N,N,35137,N,N,35698,
+N,N,N,N,N,N,35571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35752,N,N,N,N,N,N,40622,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40562,64371,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37050,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37374,40694,
+N,N,N,N,N,N,38893,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39667,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,41198,38524,37701,39022,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39669,N,N,
+N,64587,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39668,65246,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64695,N,N,N,N,N,N,N,N,N,38897,N,N,N,38855,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40139,
+37440,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40168,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37373,38734,N,N,64360,N,N,N,N,N,N,N,
+N,N,N,N,N,N,38764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36034,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38888,N,64362,35700,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,36583,N,N,N,N,N,N,N,N,N,N,N,N,64968,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37441,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38561,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36595,39671,N,N,N,N,N,N,N,N,N,N,36774,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64214,40135,N,N,N,N,N,N,N,N,64215,N,N,N,N,N,39672,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64417,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36549,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64420,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64450,N,39617,N,N,N,N,N,37370,65243,38827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37191,N,64433,N,N,N,N,N,N,N,N,N,36842,N,N,N,N,N,N,38098,65121,64206,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37613,37363,37830,N,37722,64251,N,N,37615,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38983,37734,38997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38630,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40771,40874,38106,37614,64687,64507,N,
+36601,37366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37732,N,N,N,N,38133,40118,64429,
+38990,36676,38653,N,N,N,N,N,N,N,N,N,N,N,N,N,39673,N,N,N,39674,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38761,38356,38987,64426,N,N,39036,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37354,N,N,N,N,N,40367,40389,N,37361,36529,38825,64428,64696,40121,N,N,N,N,
+N,N,N,64432,64722,37835,N,N,39677,N,N,N,N,N,N,N,N,N,N,N,37364,35756,41045,N,N,
+N,N,38260,N,N,N,N,38334,N,N,N,N,N,N,N,N,N,N,N,N,38829,N,N,N,N,N,N,N,N,N,N,N,
+36585,N,N,37624,38846,37228,38058,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64611,N,
+N,N,40390,N,N,N,N,N,N,N,38837,37560,37359,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65190,38752,37720,38262,36780,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37356,38836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37367,N,N,N,N,
+38730,64329,38264,37820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,37334,37717,37718,38993,N,N,N,N,N,N,N,N,N,N,36856,64448,37874,N,N,
+37072,N,N,N,N,N,N,40004,N,N,N,N,N,37461,N,N,N,N,37731,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37285,N,N,N,N,N,N,N,N,41197,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64875,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37713,N,N,N,35927,N,N,64120,N,N,N,N,65192,N,N,N,N,N,N,N,N,N,N,N,N,N,37712,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64076,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37623,39744,N,N,N,N,N,N,64462,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39745,N,N,N,N,N,65197,64469,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35778,39548,39746,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39747,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40569,N,N,64473,N,N,N,N,N,N,39748,41127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35961,N,N,N,37726,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,35275,N,N,N,N,N,N,40787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37847,N,N,N,N,N,N,N,N,N,N,N,N,N,64481,65232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,64482,N,N,N,N,N,64739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64486,N,N,N,39863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,39749,N,N,N,N,N,N,N,N,N,N,N,N,39751,40784,N,N,N,N,N,39752,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39081,N,N,40189,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34892,39755,N,N,N,64492,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,35945,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39848,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35541,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64115,64857,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37282,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64493,N,N,N,N,N,N,40105,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35496,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39875,
+35553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39758,38352,N,N,N,36959,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,38894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64590,N,N,N,N,N,N,
+39759,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39760,40646,N,N,N,N,N,N,N,N,N,N,N,64592,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64883,N,N,N,N,N,64935,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40354,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,64094,N,
+N,N,N,N,N,N,41049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64117,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64446,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,37744,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37745,37751,65263,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37741,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,35580,N,64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40555,38115,36578,35965,N,36567,
+N,N,N,N,N,N,40013,N,N,N,38563,N,N,N,N,N,N,N,N,N,N,39761,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35523,N,N,N,N,N,N,N,N,N,N,N,
+38570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64616,35693,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64871,35561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64673,37740,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65136,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64680,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64745,40116,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,35562,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39765,N,N,N,38571,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64679,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39766,35516,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35531,N,N,N,N,
+N,39767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35277,N,39769,39771,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39773,N,N,N,40527,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37795,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35451,N,N,N,35650,
+38736,36787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35408,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39776,N,N,N,N,35653,N,N,N,35654,N,N,N,N,N,N,N,N,N,N,N,N,40446,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39778,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37755,N,N,N,N,N,37809,N,N,N,N,N,N,N,35424,N,N,
+N,N,N,N,N,N,35544,N,N,N,N,39779,N,N,N,N,N,N,N,N,N,N,35433,N,N,N,35399,N,N,
+35532,37756,39781,N,N,N,N,N,N,N,N,N,39782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35442,N,N,N,N,N,
+N,N,35450,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37807,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35504,N,N,N,N,
+N,N,N,39784,N,N,N,N,N,N,N,N,N,N,40611,N,N,64236,35703,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,39783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35673,64689,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64699,N,N,N,N,N,
+N,N,N,N,N,N,39785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37800,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36703,39786,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,39787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38892,39788,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65102,N,N,N,N,N,N,64962,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,39789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37223,64716,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37092,N,N,N,N,37093,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40690,37834,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,35772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36678,N,N,N,N,37839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64731,64732,N,N,N,N,N,N,N,N,N,N,N,N,N,37824,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64742,38631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64728,64729,64934,37838,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38385,N,N,N,N,N,N,N,N,N,40169,N,64740,38063,64119,
+37836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,36954,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,35924,N,N,N,N,N,N,N,37823,64337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37817,65239,37815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37849,N,N,N,N,N,N,N,N,N,N,N,N,N,37819,
+37850,39075,N,N,N,N,N,N,N,N,N,37073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64112,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39915,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39791,N,N,N,N,N,N,N,64764,N,N,N,N,N,N,N,N,N,N,N,N,N,35648,41083,N,N,N,
+36001,38903,N,N,N,37858,64726,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38233,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64832,N,N,37727,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38898,40054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,36600,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36679,N,N,N,N,N,N,N,N,N,N,N,N,39796,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37556,
+N,N,N,37357,N,N,38610,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64838,36687,38217,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39797,64092,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64843,N,N,N,38611,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64856,N,N,N,N,N,37983,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,41205,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37443,N,N,N,N,N,N,38906,N,N,N,N,N,N,N,N,N,N,N,N,
+40409,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38900,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37453,64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,39802,N,N,N,N,N,N,N,N,N,40661,N,N,N,N,N,N,N,N,N,N,N,N,64174,N,40137,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37464,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,36552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,38068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37857,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37855,N,N,N,N,N,64752,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37868,38902,38607,37854,35535,39842,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37714,N,N,N,N,N,N,
+N,N,N,N,N,39074,64878,36004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64124,37882,36988,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36711,N,40375,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,41193,64078,64929,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40564,40895,40651,39865,
+40404,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38841,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36593,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38267,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40658,38739,38564,36798,38105,36952,64889,64891,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36570,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36602,39845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40665,38868,37051,64956,64966,37448,N,N,N,N,N,N,N,37557,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40385,
+37561,37542,36683,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39846,N,N,N,N,N,37558,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,36416,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40664,37982,39007,38094,37450,64880,37991,N,N,N,N,N,N,N,N,N,N,N,
+36332,N,N,N,N,N,N,N,N,39896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37960,64193,40183,64958,
+N,N,N,N,N,N,N,N,N,N,N,N,36826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64985,N,N,64638,N,N,N,N,N,N,N,N,37881,N,N,N,N,64067,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64235,
+64195,38867,38393,40008,64984,41176,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64983,64330,39855,37963,64969,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36524,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64946,N,N,N,N,N,37466,
+64701,37593,N,N,N,64981,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37597,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37465,38586,N,N,N,N,N,N,N,N,N,N,37467,N,N,N,N,N,
+N,N,N,N,39851,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,64986,64990,N,N,N,64979,N,N,N,N,N,N,N,N,N,35910,N,N,N,N,N,N,64982,
+64988,64989,N,N,N,N,37118,N,N,65185,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35757,N,N,40152,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40557,64892,64353,N,N,N,N,N,N,38648,N,N,N,N,N,N,N,N,
+38640,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64756,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,65120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38994,38479,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37230,N,N,N,N,N,N,N,N,N,N,39021,N,N,39012,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37971,65004,64376,N,N,N,N,N,N,
+N,N,N,N,N,38330,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39005,N,37625,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39002,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65014,N,
+N,N,N,N,N,N,37840,39010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39853,N,N,N,N,N,N,N,N,N,N,N,38735,39854,N,N,N,N,N,N,N,N,N,N,N,
+N,37970,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39856,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37330,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,38890,64363,37297,65011,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37579,N,N,N,N,N,N,N,N,N,39857,N,N,N,N,N,64748,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39019,N,N,N,38737,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+39025,38383,N,N,N,N,N,N,N,40691,N,N,N,N,N,37352,39866,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64332,
+37482,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65016,39009,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37351,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,37869,38724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37345,N,N,64501,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39017,N,N,N,N,35426,N,N,39867,36008,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36471,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35506,
+40636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37794,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37757,40550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37977,N,N,N,N,N,N,N,N,N,39871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37976,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40613,39879,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,36468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35798,N,N,N,N,N,N,
+38070,64884,39104,38053,N,N,N,N,N,N,N,39880,N,N,N,38381,64894,64491,N,N,N,N,N,
+N,N,N,N,N,64893,N,N,N,N,N,N,N,N,N,38767,37985,N,40897,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38359,N,N,N,64082,40024,N,N,N,N,N,N,N,N,N,40808,39911,64718,
+38632,64073,38817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38221,40696,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65097,37326,38769,N,N,N,N,36047,N,
+N,N,64945,N,N,64622,N,N,N,N,N,40178,37816,36931,38745,38103,65126,38013,64623,
+N,N,N,N,37446,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64109,N,N,36599,N,64439,N,38012,
+37581,38834,N,N,N,N,N,N,N,N,N,65125,38526,38744,39799,37327,N,N,N,N,N,N,N,N,N,
+38052,N,N,N,N,N,N,N,N,N,N,40109,N,N,N,N,N,N,N,N,N,35755,N,N,N,38613,64691,N,N,
+N,37806,N,38765,N,N,N,N,N,N,37958,38391,N,N,N,N,N,N,N,N,40006,38235,37329,
+38132,N,65127,37541,N,N,N,65247,36011,N,39881,N,N,N,N,N,N,N,N,N,N,N,64749,
+65018,64712,65122,37372,65131,65017,64711,37198,40120,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38759,N,N,N,38382,N,N,39858,N,N,N,N,37984,N,N,N,38050,39029,
+38828,37331,N,N,N,N,N,N,N,N,N,N,N,39035,N,N,N,N,N,N,N,36587,38762,38494,N,N,N,
+N,N,N,N,N,N,38891,N,N,N,N,N,40953,38392,65186,36838,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,65150,N,N,N,N,N,N,40356,38760,36588,38077,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37979,40182,64167,39897,N,N,N,N,N,N,N,N,N,64093,38486,38754,N,N,N,N,N,N,38074,
+41039,37592,N,N,N,39883,N,N,N,N,N,N,38075,N,N,40287,N,N,N,N,N,N,37071,N,N,N,N,
+N,N,N,N,N,N,N,N,N,37989,N,N,40780,N,N,N,N,N,N,37080,40638,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64365,38346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40386,38904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,36860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38003,38004,N,N,
+N,N,N,N,N,N,N,N,N,N,65207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35403,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35413,
+35689,35548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35702,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39886,N,
+35432,41208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,39135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65205,N,N,N,39887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38651,N,N,39931,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40654,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36581,N,N,N,N,N,
+N,N,N,N,40571,39890,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,65230,35397,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65231,35749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35914,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,35564,N,N,64736,38061,65237,38060,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64602,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39894,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35439,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35753,36447,N,N,40395,N,64743,39895,N,N,
+N,N,N,N,N,N,N,N,N,37832,N,N,N,N,N,N,N,N,N,37360,36832,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,39899,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37101,N,39900,41196,N,N,N,39162,N,N,N,N,N,N,N,N,N,39904,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37831,37449,38625,39906,N,
+N,N,39908,N,N,36833,39909,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38080,N,N,37827,N,N,N,N,N,N,N,N,N,N,37829,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36985,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,38779,N,N,N,N,N,36990,N,N,N,N,65254,65094,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37488,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,38312,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36016,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38088,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,39097,37184,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64702,N,N,N,N,N,N,N,37207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64223,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39910,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,38467,36420,40015,65268,N,N,N,N,N,39912,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38511,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,36426,39917,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,37622,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40377,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36430,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64463,40642,N,N,N,N,N,
+N,38117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39920,38116,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,38225,35771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39921,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38128,36452,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38122,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36705,N,N,N,39780,36443,N,N,N,N,39922,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40393,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36460,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36723,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36725,
+36465,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36448,36458,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,35916,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38226,38228,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,35540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40379,38211,
+37630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38129,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,41194,40402,41137,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37368,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37986,39844,36525,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40621,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38608,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65262,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35508,N,
+N,N,N,N,N,N,N,N,N,N,N,38743,35447,39927,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,36533,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41069,36534,38742,
+38208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,41203,38078,N,N,N,39930,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64991,40380,N,N,N,N,N,N,N,N,38142,N,N,
+N,N,N,N,N,N,35803,41214,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36544,
+40775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35806,41211,N,N,N,N,36547,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38473,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,65218,N,N,38220,39933,N,N,N,N,N,N,N,N,N,N,N,N,N,37068,40032,
+38219,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39934,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,40003,N,N,N,40007,36556,N,N,N,36436,N,N,N,N,N,N,N,N,N,N,36580,40009,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38238,N,N,N,N,N,N,N,N,N,N,N,N,
+38236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40011,35809,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,36569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40372,N,37471,N,N,N,
+40012,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35489,N,N,N,N,N,N,N,N,N,N,N,N,N,36571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40022,35490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,38740,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40030,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,40660,38248,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41155,35558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,41207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40033,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64589,N,40539,N,N,N,N,N,N,N,N,40553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40035,65223,N,
+N,65222,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40039,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35810,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,37221,N,N,N,N,N,N,N,N,N,N,N,N,40167,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,35412,N,N,N,N,N,N,N,40044,40046,65117,N,N,N,N,N,40051,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38253,36592,36685,N,N,N,N,36598,N,
+N,N,N,N,N,N,N,64188,N,36053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64474,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35660,
+64885,39901,64245,N,N,N,N,N,N,N,40052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,38213,N,N,N,N,N,N,N,N,N,N,N,N,38598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,36714,36686,N,N,N,N,N,40056,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64085,N,N,N,N,N,N,N,N,N,N,N,N,38884,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40001,37468,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38650,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,36453,38985,64424,38978,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40058,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,38907,37066,N,N,N,N,40027,N,N,38733,N,N,36563,N,N,N,N,N,N,N,N,N,
+N,N,N,N,38241,40779,40885,37842,64938,38976,37190,39015,64090,64425,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38977,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36051,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64765,64939,37309,36684,38601,36693,64430,38255,N,N,N,N,N,N,40061,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41200,N,N,N,N,N,N,N,N,N,N,N,N,N,37999,64940,N,N,N,N,38603,38606,N,N,N,N,41046,
+N,40161,N,N,N,N,N,N,N,N,N,N,38596,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36702,36716,36515,64435,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64595,N,N,N,64947,N,N,N,N,36715,N,N,N,N,N,N,N,N,N,N,N,N,38602,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,36729,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40559,41157,64632,
+36418,36698,37058,36517,36961,37455,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37747,64949,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65228,N,64445,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38979,38597,35260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40099,N,N,N,N,N,N,37451,38986,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36772,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41201,
+40699,40146,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36775,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,64604,38981,N,N,36934,36049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65274,38240,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40776,37447,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40100,38257,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40102,N,N,N,N,40103,N,N,N,N,N,40106,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40659,N,N,N,40560,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,40108,36782,38269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40112,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38838,
+N,41149,35551,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,40618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36797,N,N,N,36799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37737,39847,
+51364,N,N,N,N,65258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,39905,N,N,N,N,N,N,35649,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,40374,41195,39843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35745,36808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,35148,39008,N,N,N,N,N,N,N,N,N,N,38087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,35672,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38315,38314,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40131,40132,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,37846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35814,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35441,36817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,39381,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37108,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35491,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40142,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40148,40149,N,N,N,64456,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40371,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64624,N,N,N,N,N,36823,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39795,N,N,N,N,N,N,N,N,N,N,64091,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,36818,36964,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39094,
+38504,N,N,N,N,40150,N,N,N,N,N,N,N,N,N,N,N,N,39101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36828,65270,36825,N,N,N,N,N,N,N,N,N,N,N,N,N,
+38209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38899,39928,40556,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36850,36846,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40151,N,N,N,N,N,N,N,N,N,N,N,N,40558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35392,N,N,N,N,N,N,N,N,N,N,36847,N,N,N,N,N,N,N,N,36852,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36853,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38338,39018,N,38863,40572,36929,N,N,N,
+N,N,N,40155,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37953,N,N,N,N,40166,40368,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40170,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40173,N,N,N,N,N,N,N,N,N,N,N,N,40186,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35682,35406,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,40138,35430,N,N,N,N,N,N,N,N,N,N,40187,40188,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40190,N,N,N,N,N,N,N,N,N,N,N,
+N,N,35411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40256,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40257,N,N,N,N,N,N,N,N,N,N,N,N,36933,35699,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,38858,N,40258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,35758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35538,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40434,40259,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40260,N,N,N,N,N,N,N,N,N,N,36554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36942,N,N,N,N,N,N,N,36531,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40949,N,N,N,N,N,N,N,N,N,N,N,N,40261,36943,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40263,N,N,N,35274,N,N,N,N,N,N,40117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64510,36958,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36963,36951,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36966,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39872,N,N,N,N,N,N,N,N,N,N,N,64741,37218,N,N,N,N,N,N,N,N,N,N,36967,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36769,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,36770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,40264,64211,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36957,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,37049,N,N,N,N,N,N,N,N,N,N,N,N,N,36971,35932,N,N,N,
+36969,65111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65109,36979,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39919,40176,N,N,
+N,N,N,N,N,N,N,N,N,N,40267,N,N,N,N,N,N,N,N,N,N,N,N,N,65241,N,N,N,65242,N,N,N,
+37344,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37336,N,N,N,N,N,N,N,N,N,N,38470,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37728,N,64083,40147,N,N,
+N,N,N,N,N,N,N,N,N,N,40270,N,N,N,64320,N,N,N,36322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,37954,N,36950,N,N,39013,N,35948,64074,N,N,40272,
+40274,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38319,38746,37705,38727,41204,N,N,N,N,N,
+N,38776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36815,N,N,N,64608,N,N,N,N,N,N,N,N,35918,N,
+N,N,64598,N,N,N,N,N,N,N,N,N,N,N,N,N,37340,38497,37612,37725,36574,38654,64847,
+38366,N,N,N,N,N,N,N,N,N,N,N,N,N,39088,41024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38845,38781,38901,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,39852,64218,37570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38833,N,N,N,N,N,36987,N,N,N,N,37886,38011,
+N,38775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64190,64835,37062,37028,37032,38057,N,
+37033,N,N,N,N,35941,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38368,36989,N,N,N,N,N,N,
+37477,N,N,N,N,N,N,N,N,N,N,N,N,N,64954,37828,N,N,N,N,N,N,N,N,65261,40363,41187,
+N,38472,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40275,N,N,N,N,N,35497,N,
+39877,N,38493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38751,38495,38510,64349,N,N,
+N,N,N,40369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,65187,N,N,N,N,N,N,N,N,N,40370,N,N,38318,64675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41122,N,N,38485,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40276,N,N,37697,N,38317,37333,N,N,N,N,N,N,N,N,N,N,N,N,38778,65020,
+36423,37885,37029,37036,N,N,N,N,N,N,N,N,38316,N,N,N,N,N,N,N,N,N,37038,65189,N,
+N,N,N,N,40278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38883,38370,N,N,N,N,N,37990,
+N,N,38471,N,N,N,N,37304,N,N,N,N,40172,N,N,N,N,N,N,N,N,37037,N,38371,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35663,N,N,35555,N,N,N,N,35661,38378,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35662,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36033,35821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37337,N,N,41124,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38389,38388,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,40883,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65199,N,N,N,N,
+N,65138,37498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65196,N,N,N,N,N,N,N,N,N,N,N,N,N,38387,40280,37746,N,N,37317,N,N,N,N,
+N,N,N,38466,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37069,38398,
+37209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38860,37070,N,N,N,N,N,N,40281,64757,65277,N,N,
+40283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,40284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37758,N,N,N,N,N,N,N,N,N,N,
+N,N,N,39084,N,N,40286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64976,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64864,N,
+N,N,N,N,N,N,N,N,N,N,40143,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37088,37107,N,N,39089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37104,N,N,N,N,
+N,N,N,N,N,N,N,37821,N,N,N,N,N,N,N,N,38327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40774,N,N,N,N,N,N,N,N,36427,38488,N,N,N,N,N,N,N,N,N,N,35404,N,40291,40655,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40293,N,N,N,N,N,N,N,40294,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40292,N,N,N,N,N,N,N,N,N,N,35436,35545,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40295,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35440,35827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,37200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,40129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,40296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+37799,N,N,N,N,N,N,38516,41199,N,37201,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35940,38518,40297,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64676,
+N,N,N,N,N,N,N,N,N,N,N,N,40298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37454,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40299,N,N,N,N,N,39873,
+40300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+35429,37213,N,N,N,N,N,N,N,N,40301,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37210,35906,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,40128,37226,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+40302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40614,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40397,N,N,40303,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,35259,40697,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,38580,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37234,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40648,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,35669,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40305,40306,N,N,N,N,
+N,N,N,N,N,N,N,N,40652,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37236,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40656,36956,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36562,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,37288,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,37239,N,N,N,N,N,N,N,N,N,N,N,38591,N,N,N,N,N,38592,N,N,N,N,
+36785,N,N,N,N,N,38583,35925,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,37240,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35262,37244,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,37237,37283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37238,N,N,N,
+N,N,N,N,N,38590,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,37241,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38582,
+37284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40309,N,N,N,N,N,N,N,N,N,N,N,36946,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41029,N,37289,N,39082,N,N,N,35935,N,N,35754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,40311,35136,40684,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37802,38008,N,N,N,N,40314,35529,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,35659,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40940,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,35554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,40565,39028,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,39624,N,N,N,N,41031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35779,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,40018,36605,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36776,N,N,N,N,N,N,N,N,N,38266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+36848,
+};
+
+static const struct unim_index big5hkscs_nonbmp_encmap[256] = {
+{__big5hkscs_nonbmp_encmap+0,33,238},{__big5hkscs_nonbmp_encmap+206,12,242},{
+__big5hkscs_nonbmp_encmap+437,4,229},{__big5hkscs_nonbmp_encmap+663,10,252},{
+__big5hkscs_nonbmp_encmap+906,19,254},{__big5hkscs_nonbmp_encmap+1142,71,235},
+{__big5hkscs_nonbmp_encmap+1307,17,118},{__big5hkscs_nonbmp_encmap+1409,14,121
+},{__big5hkscs_nonbmp_encmap+1517,44,213},{__big5hkscs_nonbmp_encmap+1687,22,
+231},{__big5hkscs_nonbmp_encmap+1897,17,205},{__big5hkscs_nonbmp_encmap+2086,
+13,255},{__big5hkscs_nonbmp_encmap+2329,11,255},{__big5hkscs_nonbmp_encmap+
+2574,21,200},{__big5hkscs_nonbmp_encmap+2754,4,251},{__big5hkscs_nonbmp_encmap
++3002,29,237},{__big5hkscs_nonbmp_encmap+3211,20,246},{
+__big5hkscs_nonbmp_encmap+3438,47,217},{__big5hkscs_nonbmp_encmap+3609,60,254
+},{__big5hkscs_nonbmp_encmap+3804,2,254},{__big5hkscs_nonbmp_encmap+4057,19,
+253},{__big5hkscs_nonbmp_encmap+4292,119,150},{__big5hkscs_nonbmp_encmap+4324,
+10,254},{__big5hkscs_nonbmp_encmap+4569,13,252},{__big5hkscs_nonbmp_encmap+
+4809,32,250},{__big5hkscs_nonbmp_encmap+5028,3,243},{__big5hkscs_nonbmp_encmap
++5269,45,75},{__big5hkscs_nonbmp_encmap+5300,68,194},{
+__big5hkscs_nonbmp_encmap+5427,42,172},{__big5hkscs_nonbmp_encmap+5558,70,249
+},{__big5hkscs_nonbmp_encmap+5738,28,213},{__big5hkscs_nonbmp_encmap+5924,15,
+232},{__big5hkscs_nonbmp_encmap+6142,69,252},{__big5hkscs_nonbmp_encmap+6326,
+42,195},{__big5hkscs_nonbmp_encmap+6480,8,124},{__big5hkscs_nonbmp_encmap+6597
+,33,250},{__big5hkscs_nonbmp_encmap+6815,101,237},{__big5hkscs_nonbmp_encmap+
+6952,19,190},{__big5hkscs_nonbmp_encmap+7124,27,246},{
+__big5hkscs_nonbmp_encmap+7344,18,205},{__big5hkscs_nonbmp_encmap+7532,3,247},
+{__big5hkscs_nonbmp_encmap+7777,38,147},{__big5hkscs_nonbmp_encmap+7887,102,
+232},{__big5hkscs_nonbmp_encmap+8018,14,206},{__big5hkscs_nonbmp_encmap+8211,
+38,201},{__big5hkscs_nonbmp_encmap+8375,7,238},{__big5hkscs_nonbmp_encmap+8607
+,13,239},{__big5hkscs_nonbmp_encmap+8834,116,227},{__big5hkscs_nonbmp_encmap+
+8946,51,218},{__big5hkscs_nonbmp_encmap+9114,3,249},{__big5hkscs_nonbmp_encmap
++9361,15,225},{__big5hkscs_nonbmp_encmap+9572,0,254},{
+__big5hkscs_nonbmp_encmap+9827,0,229},{__big5hkscs_nonbmp_encmap+10057,25,243
+},{__big5hkscs_nonbmp_encmap+10276,0,238},{__big5hkscs_nonbmp_encmap+10515,3,
+215},{__big5hkscs_nonbmp_encmap+10728,58,58},{__big5hkscs_nonbmp_encmap+10729,
+194,194},{__big5hkscs_nonbmp_encmap+10730,167,250},{__big5hkscs_nonbmp_encmap+
+10814,90,90},{__big5hkscs_nonbmp_encmap+10815,99,255},{
+__big5hkscs_nonbmp_encmap+10972,64,248},{__big5hkscs_nonbmp_encmap+11157,17,
+252},{__big5hkscs_nonbmp_encmap+11393,53,240},{__big5hkscs_nonbmp_encmap+11581
+,17,225},{__big5hkscs_nonbmp_encmap+11790,4,252},{__big5hkscs_nonbmp_encmap+
+12039,27,250},{__big5hkscs_nonbmp_encmap+12263,13,248},{
+__big5hkscs_nonbmp_encmap+12499,4,214},{__big5hkscs_nonbmp_encmap+12710,5,200
+},{__big5hkscs_nonbmp_encmap+12906,24,212},{__big5hkscs_nonbmp_encmap+13095,6,
+224},{__big5hkscs_nonbmp_encmap+13314,18,255},{__big5hkscs_nonbmp_encmap+13552
+,0,251},{__big5hkscs_nonbmp_encmap+13804,14,233},{__big5hkscs_nonbmp_encmap+
+14024,110,245},{__big5hkscs_nonbmp_encmap+14160,9,217},{
+__big5hkscs_nonbmp_encmap+14369,6,235},{__big5hkscs_nonbmp_encmap+14599,59,167
+},{__big5hkscs_nonbmp_encmap+14708,14,194},{__big5hkscs_nonbmp_encmap+14889,
+44,157},{__big5hkscs_nonbmp_encmap+15003,43,231},{__big5hkscs_nonbmp_encmap+
+15192,32,216},{__big5hkscs_nonbmp_encmap+15377,14,19},{
+__big5hkscs_nonbmp_encmap+15383,25,110},{__big5hkscs_nonbmp_encmap+15469,49,
+224},{__big5hkscs_nonbmp_encmap+15645,5,246},{__big5hkscs_nonbmp_encmap+15887,
+6,225},{__big5hkscs_nonbmp_encmap+16107,87,225},{__big5hkscs_nonbmp_encmap+
+16246,3,204},{__big5hkscs_nonbmp_encmap+16448,149,233},{
+__big5hkscs_nonbmp_encmap+16533,116,232},{__big5hkscs_nonbmp_encmap+16650,1,
+254},{__big5hkscs_nonbmp_encmap+16904,32,67},{__big5hkscs_nonbmp_encmap+16940,
+14,216},{__big5hkscs_nonbmp_encmap+17143,26,226},{__big5hkscs_nonbmp_encmap+
+17344,41,165},{__big5hkscs_nonbmp_encmap+17469,2,221},{
+__big5hkscs_nonbmp_encmap+17689,88,208},{__big5hkscs_nonbmp_encmap+17810,53,
+248},{__big5hkscs_nonbmp_encmap+18006,2,152},{__big5hkscs_nonbmp_encmap+18157,
+18,191},{__big5hkscs_nonbmp_encmap+18331,18,252},{__big5hkscs_nonbmp_encmap+
+18566,22,204},{__big5hkscs_nonbmp_encmap+18749,28,199},{
+__big5hkscs_nonbmp_encmap+18921,14,250},{__big5hkscs_nonbmp_encmap+19158,45,82
+},{__big5hkscs_nonbmp_encmap+19196,5,247},{__big5hkscs_nonbmp_encmap+19439,33,
+209},{__big5hkscs_nonbmp_encmap+19616,34,240},{__big5hkscs_nonbmp_encmap+19823
+,0,215},{__big5hkscs_nonbmp_encmap+20039,38,223},{__big5hkscs_nonbmp_encmap+
+20225,14,248},{__big5hkscs_nonbmp_encmap+20460,9,205},{
+__big5hkscs_nonbmp_encmap+20657,27,230},{__big5hkscs_nonbmp_encmap+20861,154,
+154},{__big5hkscs_nonbmp_encmap+20862,34,134},{__big5hkscs_nonbmp_encmap+20963
+,116,254},{__big5hkscs_nonbmp_encmap+21102,7,148},{__big5hkscs_nonbmp_encmap+
+21244,15,204},{__big5hkscs_nonbmp_encmap+21434,88,200},{
+__big5hkscs_nonbmp_encmap+21547,36,253},{__big5hkscs_nonbmp_encmap+21765,10,
+244},{__big5hkscs_nonbmp_encmap+22000,6,244},{__big5hkscs_nonbmp_encmap+22239,
+18,18},{__big5hkscs_nonbmp_encmap+22240,47,220},{__big5hkscs_nonbmp_encmap+
+22414,77,79},{__big5hkscs_nonbmp_encmap+22417,249,249},{
+__big5hkscs_nonbmp_encmap+22418,2,244},{__big5hkscs_nonbmp_encmap+22661,46,188
+},{__big5hkscs_nonbmp_encmap+22804,7,226},{__big5hkscs_nonbmp_encmap+23024,6,
+138},{__big5hkscs_nonbmp_encmap+23157,18,130},{__big5hkscs_nonbmp_encmap+23270
+,1,244},{__big5hkscs_nonbmp_encmap+23514,0,230},{__big5hkscs_nonbmp_encmap+
+23745,15,19},{__big5hkscs_nonbmp_encmap+23750,4,43},{__big5hkscs_nonbmp_encmap
++23790,51,252},{__big5hkscs_nonbmp_encmap+23992,15,252},{
+__big5hkscs_nonbmp_encmap+24230,12,255},{__big5hkscs_nonbmp_encmap+24474,3,210
+},{__big5hkscs_nonbmp_encmap+24682,52,185},{__big5hkscs_nonbmp_encmap+24816,
+15,231},{__big5hkscs_nonbmp_encmap+25033,197,197},{__big5hkscs_nonbmp_encmap+
+25034,136,237},{__big5hkscs_nonbmp_encmap+25136,13,235},{0,0,0},{0,0,0},{
+__big5hkscs_nonbmp_encmap+25359,29,231},{__big5hkscs_nonbmp_encmap+25562,158,
+244},{0,0,0},{__big5hkscs_nonbmp_encmap+25649,32,212},{
+__big5hkscs_nonbmp_encmap+25830,16,241},{__big5hkscs_nonbmp_encmap+26056,3,201
+},{__big5hkscs_nonbmp_encmap+26255,40,77},{__big5hkscs_nonbmp_encmap+26293,5,
+213},{__big5hkscs_nonbmp_encmap+26502,115,173},{__big5hkscs_nonbmp_encmap+
+26561,62,246},{__big5hkscs_nonbmp_encmap+26746,6,248},{
+__big5hkscs_nonbmp_encmap+26989,35,222},{__big5hkscs_nonbmp_encmap+27177,20,
+254},{__big5hkscs_nonbmp_encmap+27412,7,245},{__big5hkscs_nonbmp_encmap+27651,
+32,255},{__big5hkscs_nonbmp_encmap+27875,169,169},{__big5hkscs_nonbmp_encmap+
+27876,52,91},{__big5hkscs_nonbmp_encmap+27916,198,203},{
+__big5hkscs_nonbmp_encmap+27922,1,169},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__big5hkscs_nonbmp_encmap+28091,37,205},{__big5hkscs_nonbmp_encmap+28260,148,
+212},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/mappings_jisx0213_pair.h b/sys/src/cmd/python/Modules/cjkcodecs/mappings_jisx0213_pair.h
new file mode 100644
index 000000000..eda8e9e81
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/mappings_jisx0213_pair.h
@@ -0,0 +1,59 @@
+#define JISX0213_ENCPAIRS 46
+#ifdef EXTERN_JISX0213_PAIR
+static const struct widedbcs_index *jisx0213_pair_decmap;
+static const struct pair_encodemap *jisx0213_pair_encmap;
+#else
+static const ucs4_t __jisx0213_pair_decmap[49] = {
+810234010,810365082,810496154,810627226,810758298,816525466,816656538,
+816787610,816918682,817049754,817574042,818163866,818426010,838283418,
+15074048,U,U,U,39060224,39060225,42730240,42730241,39387904,39387905,39453440,
+39453441,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,48825061,48562921,
+};
+
+static const struct widedbcs_index jisx0213_pair_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap
++0,119,123},{__jisx0213_pair_decmap+5,119,126},{__jisx0213_pair_decmap+13,120,
+120},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap+14,68,102},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const struct pair_encodemap jisx0213_pair_encmap[JISX0213_ENCPAIRS] = {
+{0x00e60000,0x295c},{0x00e60300,0x2b44},{0x02540000,0x2b38},{0x02540300,0x2b48
+},{0x02540301,0x2b49},{0x02590000,0x2b30},{0x02590300,0x2b4c},{0x02590301,
+0x2b4d},{0x025a0000,0x2b43},{0x025a0300,0x2b4e},{0x025a0301,0x2b4f},{
+0x028c0000,0x2b37},{0x028c0300,0x2b4a},{0x028c0301,0x2b4b},{0x02e50000,0x2b60
+},{0x02e502e9,0x2b66},{0x02e90000,0x2b64},{0x02e902e5,0x2b65},{0x304b0000,
+0x242b},{0x304b309a,0x2477},{0x304d0000,0x242d},{0x304d309a,0x2478},{
+0x304f0000,0x242f},{0x304f309a,0x2479},{0x30510000,0x2431},{0x3051309a,0x247a
+},{0x30530000,0x2433},{0x3053309a,0x247b},{0x30ab0000,0x252b},{0x30ab309a,
+0x2577},{0x30ad0000,0x252d},{0x30ad309a,0x2578},{0x30af0000,0x252f},{
+0x30af309a,0x2579},{0x30b10000,0x2531},{0x30b1309a,0x257a},{0x30b30000,0x2533
+},{0x30b3309a,0x257b},{0x30bb0000,0x253b},{0x30bb309a,0x257c},{0x30c40000,
+0x2544},{0x30c4309a,0x257d},{0x30c80000,0x2548},{0x30c8309a,0x257e},{
+0x31f70000,0x2675},{0x31f7309a,0x2678},
+};
+#endif
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/mappings_jp.h b/sys/src/cmd/python/Modules/cjkcodecs/mappings_jp.h
new file mode 100644
index 000000000..c6dae3daa
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/mappings_jp.h
@@ -0,0 +1,4765 @@
+static const ucs2_t __jisx0208_decmap[6956] = {
+12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
+65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,
+12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,
+65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,
+12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,
+8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,
+65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U,
+8712,8715,8838,8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,172,8658,
+8660,8704,8707,U,U,U,U,U,U,U,U,U,U,U,8736,8869,8978,8706,8711,8801,8786,8810,
+8811,8730,8765,8733,8757,8747,8748,U,U,U,U,U,U,U,8491,8240,9839,9837,9834,
+8224,8225,182,U,U,U,U,9711,65296,65297,65298,65299,65300,65301,65302,65303,
+65304,65305,U,U,U,U,U,U,U,65313,65314,65315,65316,65317,65318,65319,65320,
+65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,
+65334,65335,65336,65337,65338,U,U,U,U,U,U,65345,65346,65347,65348,65349,65350,
+65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,
+65364,65365,65366,65367,65368,65369,65370,12353,12354,12355,12356,12357,12358,
+12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,
+12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,
+12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,
+12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,
+12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,
+12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12449,
+12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,
+12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,
+12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,
+12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,
+12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,
+12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,
+12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918,919,920,921,
+922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U,U,U,U,U,U,
+945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,
+965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,
+1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,
+1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073,
+1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,
+1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,
+1103,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,
+9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,
+9509,9528,9538,20124,21782,23043,38463,21696,24859,25384,23030,36898,33909,
+33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,26017,25201,
+23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,24245,25353,
+26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,22839,22996,
+23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,32173,32239,
+32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,37057,30959,
+19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,21729,22240,
+23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,21491,23431,
+28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,22040,21764,
+27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,38642,33615,
+39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,29787,30408,
+31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,35585,36234,
+38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,25588,27839,
+28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,37467,40219,
+22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,27178,27431,
+27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,23627,25014,
+33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,21270,20206,
+20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,31185,26247,
+26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,33499,33540,
+33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,20420,23784,
+25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,20250,35299,
+22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,25913,39745,
+26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,35997,20977,
+21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,35442,37799,
+39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,24275,25313,
+25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,37101,38307,
+38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,26806,39949,
+28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,19988,39993,
+21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,40232,26658,
+33541,33841,31909,21000,33477,29926,20094,20355,20896,23506,21002,21208,21223,
+24059,21914,22570,23014,23436,23448,23515,24178,24185,24739,24863,24931,25022,
+25563,25954,26577,26707,26874,27454,27475,27735,28450,28567,28485,29872,29976,
+30435,30475,31487,31649,31777,32233,32566,32752,32925,33382,33694,35251,35532,
+36011,36996,37969,38291,38289,38306,38501,38867,39208,33304,20024,21547,23736,
+24012,29609,30284,30524,23721,32747,36107,38593,38929,38996,39000,20225,20238,
+21361,21916,22120,22522,22855,23305,23492,23696,24076,24190,24524,25582,26426,
+26071,26082,26399,26827,26820,27231,24112,27589,27671,27773,30079,31048,23395,
+31232,32000,24509,35215,35352,36020,36215,36556,36637,39138,39438,39740,20096,
+20605,20736,22931,23452,25135,25216,25836,27450,29344,30097,31047,32681,34811,
+35516,35696,25516,33738,38816,21513,21507,21931,26708,27224,35440,30759,26485,
+40653,21364,23458,33050,34384,36870,19992,20037,20167,20241,21450,21560,23470,
+24339,24613,25937,26429,27714,27762,27875,28792,29699,31350,31406,31496,32026,
+31998,32102,26087,29275,21435,23621,24040,25298,25312,25369,28192,34394,35377,
+36317,37624,28417,31142,39770,20136,20139,20140,20379,20384,20689,20807,31478,
+20849,20982,21332,21281,21375,21483,21932,22659,23777,24375,24394,24623,24656,
+24685,25375,25945,27211,27841,29378,29421,30703,33016,33029,33288,34126,37111,
+37857,38911,39255,39514,20208,20957,23597,26241,26989,23616,26354,26997,29577,
+26704,31873,20677,21220,22343,24062,37670,26020,27427,27453,29748,31105,31165,
+31563,32202,33465,33740,34943,35167,35641,36817,37329,21535,37504,20061,20534,
+21477,21306,29399,29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,
+21936,31354,20598,23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,
+27795,38772,36705,31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,
+34219,35347,32676,36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,
+22317,29674,22411,22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,
+26223,26690,28179,30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,
+35336,35427,35686,36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,
+38553,26689,20625,27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,
+20518,20581,20860,21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,
+25458,26908,27177,29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,
+36066,36562,36963,37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,
+28187,28304,29572,29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,
+22266,22993,23396,24049,24235,24359,25144,25925,26543,28246,29392,31946,34996,
+32929,32993,33776,34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,
+21320,21577,21566,23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,
+35703,37264,20062,39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,
+21246,21402,21475,21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,
+24039,24055,24184,24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,
+26114,26179,26356,26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,
+30343,30828,31295,31968,32005,32024,32094,32177,32789,32771,32943,32945,33108,
+33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,37628,
+38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,28640,
+35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,28425,
+33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,22718,
+23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,20123,
+20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,35039,
+22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,25165,
+25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,33756,
+35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,27018,
+32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,26613,
+31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,25774,
+25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,19977,
+20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,34453,
+35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,21496,
+21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,24605,
+25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,31169,
+31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,36039,
+36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,26178,
+27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,36766,
+27728,40575,24335,35672,40235,31482,36600,23437,38635,19971,21489,22519,22833,
+23241,23460,24713,28287,28422,30142,36074,23455,34048,31712,20594,26612,33437,
+23649,34122,32286,33294,20889,23556,25448,36198,26012,29038,31038,32023,32773,
+35613,36554,36974,34503,37034,20511,21242,23610,26451,28796,29237,37196,37320,
+37675,33509,23490,24369,24825,20027,21462,23432,25163,26417,27530,29417,29664,
+31278,33131,36259,37202,39318,20754,21463,21610,23551,25480,27193,32172,38656,
+22234,21454,21608,23447,23601,24030,20462,24833,25342,27954,31168,31179,32066,
+32333,32722,33261,33311,33936,34886,35186,35728,36468,36655,36913,37195,37228,
+38598,37276,20160,20303,20805,21313,24467,25102,26580,27713,28171,29539,32294,
+37325,37507,21460,22809,23487,28113,31069,32302,31899,22654,29087,20986,34899,
+36848,20426,23803,26149,30636,31459,33308,39423,20934,24490,26092,26991,27529,
+28147,28310,28516,30462,32020,24033,36981,37255,38918,20966,21021,25152,26257,
+26329,28186,24246,32210,32626,26360,34223,34295,35576,21161,21465,22899,24207,
+24464,24661,37604,38500,20663,20767,21213,21280,21319,21484,21736,21830,21809,
+22039,22888,22974,23100,23477,23558,23567,23569,23578,24196,24202,24288,24432,
+25215,25220,25307,25484,25463,26119,26124,26157,26230,26494,26786,27167,27189,
+27836,28040,28169,28248,28988,28966,29031,30151,30465,30813,30977,31077,31216,
+31456,31505,31911,32057,32918,33750,33931,34121,34909,35059,35359,35388,35412,
+35443,35937,36062,37284,37478,37758,37912,38556,38808,19978,19976,19998,20055,
+20887,21104,22478,22580,22732,23330,24120,24773,25854,26465,26454,27972,29366,
+30067,31331,33976,35698,37304,37664,22065,22516,39166,25325,26893,27542,29165,
+32340,32887,33394,35302,39135,34645,36785,23611,20280,20449,20405,21767,23072,
+23517,23529,24515,24910,25391,26032,26187,26862,27035,28024,28145,30003,30137,
+30495,31070,31206,32051,33251,33455,34218,35242,35386,36523,36763,36914,37341,
+38663,20154,20161,20995,22645,22764,23563,29978,23613,33102,35338,36805,38499,
+38765,31525,35535,38920,37218,22259,21416,36887,21561,22402,24101,25512,27700,
+28810,30561,31883,32736,34928,36930,37204,37648,37656,38543,29790,39620,23815,
+23913,25968,26530,36264,38619,25454,26441,26905,33733,38935,38592,35070,28548,
+25722,23544,19990,28716,30045,26159,20932,21046,21218,22995,24449,24615,25104,
+25919,25972,26143,26228,26866,26646,27491,28165,29298,29983,30427,31934,32854,
+22768,35069,35199,35488,35475,35531,36893,37266,38738,38745,25993,31246,33030,
+38587,24109,24796,25114,26021,26132,26512,30707,31309,31821,32318,33034,36012,
+36196,36321,36447,30889,20999,25305,25509,25666,25240,35373,31363,31680,35500,
+38634,32118,33292,34633,20185,20808,21315,21344,23459,23554,23574,24029,25126,
+25159,25776,26643,26676,27849,27973,27927,26579,28508,29006,29053,26059,31359,
+31661,32218,32330,32680,33146,33307,33337,34214,35438,36046,36341,36984,36983,
+37549,37521,38275,39854,21069,21892,28472,28982,20840,31109,32341,33203,31950,
+22092,22609,23720,25514,26366,26365,26970,29401,30095,30094,30990,31062,31199,
+31895,32032,32068,34311,35380,38459,36961,40736,20711,21109,21452,21474,20489,
+21930,22766,22863,29245,23435,23652,21277,24803,24819,25436,25475,25407,25531,
+25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,
+32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,
+38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,
+24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,
+20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,
+21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,
+23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,
+33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,
+38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,
+35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,
+33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,
+22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,
+32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,
+20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,
+39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,
+20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,
+27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,
+24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,
+32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,
+25431,30452,26389,27784,29645,36035,37806,38515,27941,22684,26894,27084,36861,
+37786,30171,36890,22618,26626,25524,27131,20291,28460,26584,36795,34086,32180,
+37716,26943,28528,22378,22775,23340,32044,29226,21514,37347,40372,20141,20302,
+20572,20597,21059,35998,21576,22564,23450,24093,24213,24237,24311,24351,24716,
+25269,25402,25552,26799,27712,30855,31118,31243,32224,33351,35330,35558,36420,
+36883,37048,37165,37336,40718,27877,25688,25826,25973,28404,30340,31515,36969,
+37841,28346,21746,24505,25764,36685,36845,37444,20856,22635,22825,23637,24215,
+28155,32399,29980,36028,36578,39003,28857,20253,27583,28593,30000,38651,20814,
+21520,22581,22615,22956,23648,24466,26007,26460,28193,30331,33759,36077,36884,
+37117,37709,30757,30778,21162,24230,22303,22900,24594,20498,20826,20908,20941,
+20992,21776,22612,22616,22871,23445,23798,23947,24764,25237,25645,26481,26691,
+26812,26847,30423,28120,28271,28059,28783,29128,24403,30168,31095,31561,31572,
+31570,31958,32113,21040,33891,34153,34276,35342,35588,35910,36367,36867,36879,
+37913,38518,38957,39472,38360,20685,21205,21516,22530,23566,24999,25758,27934,
+30643,31461,33012,33796,36947,37509,23776,40199,21311,24471,24499,28060,29305,
+30563,31167,31716,27602,29420,35501,26627,27233,20984,31361,26932,23626,40182,
+33515,23493,37193,28702,22136,23663,24775,25958,27788,35930,36929,38931,21585,
+26311,37389,22856,37027,20869,20045,20970,34201,35598,28760,25466,37707,26978,
+39348,32260,30071,21335,26976,36575,38627,27741,20108,23612,24336,36841,21250,
+36049,32905,34425,24319,26085,20083,20837,22914,23615,38894,20219,22922,24525,
+35469,28641,31152,31074,23527,33905,29483,29105,24180,24565,25467,25754,29123,
+31896,20035,24316,20043,22492,22178,24745,28611,32013,33021,33075,33215,36786,
+35223,34468,24052,25226,25773,35207,26487,27874,27966,29750,30772,23110,32629,
+33453,39340,20467,24259,25309,25490,25943,26479,30403,29260,32972,32954,36649,
+37197,20493,22521,23186,26757,26995,29028,29437,36023,22770,36064,38506,36889,
+34687,31204,30695,33833,20271,21093,21338,25293,26575,27850,30333,31636,31893,
+33334,34180,36843,26333,28448,29190,32283,33707,39361,40614,20989,31665,30834,
+31672,32903,31560,27368,24161,32908,30033,30048,20843,37474,28300,30330,37271,
+39658,20240,32624,25244,31567,38309,40169,22138,22617,34532,38588,20276,21028,
+21322,21453,21467,24070,25644,26001,26495,27710,27726,29256,29359,29677,30036,
+32321,33324,34281,36009,31684,37318,29033,38930,39151,25405,26217,30058,30436,
+30928,34115,34542,21290,21329,21542,22915,24199,24444,24754,25161,25209,25259,
+26000,27604,27852,30130,30382,30865,31192,32203,32631,32933,34987,35513,36027,
+36991,38750,39131,27147,31800,20633,23614,24494,26503,27608,29749,30473,32654,
+40763,26570,31255,21305,30091,39661,24422,33181,33777,32920,24380,24517,30050,
+31558,36924,26727,23019,23195,32016,30334,35628,20469,24426,27161,27703,28418,
+29922,31080,34920,35413,35961,24287,25551,30149,31186,33495,37672,37618,33948,
+34541,39981,21697,24428,25996,27996,28693,36007,36051,38971,25935,29942,19981,
+20184,22496,22827,23142,23500,20904,24067,24220,24598,25206,25975,26023,26222,
+28014,29238,31526,33104,33178,33433,35676,36000,36070,36212,38428,38468,20398,
+25771,27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,
+24489,24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,
+39826,20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,
+25991,32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,
+38491,31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,
+29255,31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,
+37610,22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,
+27597,31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,
+24214,25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,
+33804,34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,
+20621,21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,
+32033,32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,
+22696,25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,
+26412,32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,
+21737,27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,
+26411,27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,
+39749,24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,
+30496,21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,
+21629,26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,
+38754,40634,25720,27169,33538,22916,23391,27611,29467,30450,32178,32791,33945,
+20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,36016,21839,24758,
+32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,30690,21380,24441,
+32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,27833,30290,35565,
+36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,25558,26377,26586,
+28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,37109,38596,34701,
+22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,23481,24248,25562,
+25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,32650,32768,33865,
+33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,27779,28020,32716,
+32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,32097,33853,37226,
+20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,23653,26446,26792,
+29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,31435,33870,25504,
+30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,40845,20406,24942,
+26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,28092,29471,30274,
+30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,32209,20523,21400,
+26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,22593,28057,32047,
+39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,33491,37428,38583,
+38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,24265,24651,24976,
+28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,27347,28809,36034,
+36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,28431,29282,29436,
+31725,32769,32894,34635,37070,20845,40595,31108,32907,37682,35542,20525,21644,
+35441,27498,36036,33031,24785,26528,40434,20121,20120,39952,35435,34241,34152,
+26880,28286,30871,33109,24332,19984,19989,20010,20017,20022,20028,20031,20034,
+20054,20056,20098,20101,35947,20106,33298,24333,20110,20126,20127,20128,20130,
+20144,20147,20150,20174,20173,20164,20166,20162,20183,20190,20205,20191,20215,
+20233,20314,20272,20315,20317,20311,20295,20342,20360,20367,20376,20347,20329,
+20336,20369,20335,20358,20374,20760,20436,20447,20430,20440,20443,20433,20442,
+20432,20452,20453,20506,20520,20500,20522,20517,20485,20252,20470,20513,20521,
+20524,20478,20463,20497,20486,20547,20551,26371,20565,20560,20552,20570,20566,
+20588,20600,20608,20634,20613,20660,20658,20681,20682,20659,20674,20694,20702,
+20709,20717,20707,20718,20729,20725,20745,20737,20738,20758,20757,20756,20762,
+20769,20794,20791,20796,20795,20799,20800,20818,20812,20820,20834,31480,20841,
+20842,20846,20864,20866,22232,20876,20873,20879,20881,20883,20885,20886,20900,
+20902,20898,20905,20906,20907,20915,20913,20914,20912,20917,20925,20933,20937,
+20955,20960,34389,20969,20973,20976,20981,20990,20996,21003,21012,21006,21031,
+21034,21038,21043,21049,21071,21060,21067,21068,21086,21076,21098,21108,21097,
+21107,21119,21117,21133,21140,21138,21105,21128,21137,36776,36775,21164,21165,
+21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,21237,21240,
+21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,21297,21299,
+21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,22808,21371,
+21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,38617,21471,
+26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,21564,21550,
+21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,21650,21627,
+21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,21704,21672,
+21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,21742,21741,
+21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,21816,21811,
+21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,21884,21891,
+21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,22007,22038,
+22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,22123,22116,
+22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,22198,22196,
+22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,22265,22272,
+22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,22310,22327,
+22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,22419,22432,
+22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,22499,22539,
+22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,22661,22713,
+22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,22745,22744,
+22757,22748,22756,22751,22767,22778,22777,22779,22780,22781,22786,22794,22800,
+22811,26790,22821,22828,22829,22834,22840,22846,31442,22869,22864,22862,22874,
+22872,22882,22880,22887,22892,22889,22904,22913,22941,20318,20395,22947,22962,
+22982,23016,23004,22925,23001,23002,23077,23071,23057,23068,23049,23066,23104,
+23148,23113,23093,23094,23138,23146,23194,23228,23230,23243,23234,23229,23267,
+23255,23270,23273,23254,23290,23291,23308,23307,23318,23346,23248,23338,23350,
+23358,23363,23365,23360,23377,23381,23386,23387,23397,23401,23408,23411,23413,
+23416,25992,23418,23424,23427,23462,23480,23491,23495,23497,23508,23504,23524,
+23526,23522,23518,23525,23531,23536,23542,23539,23557,23559,23560,23565,23571,
+23584,23586,23592,23608,23609,23617,23622,23630,23635,23632,23631,23409,23660,
+23662,20066,23670,23673,23692,23697,23700,22939,23723,23739,23734,23740,23735,
+23749,23742,23751,23769,23785,23805,23802,23789,23948,23786,23819,23829,23831,
+23900,23839,23835,23825,23828,23842,23834,23833,23832,23884,23890,23886,23883,
+23916,23923,23926,23943,23940,23938,23970,23965,23980,23982,23997,23952,23991,
+23996,24009,24013,24019,24018,24022,24027,24043,24050,24053,24075,24090,24089,
+24081,24091,24118,24119,24132,24131,24128,24142,24151,24148,24159,24162,24164,
+24135,24181,24182,24186,40636,24191,24224,24257,24258,24264,24272,24271,24278,
+24291,24285,24282,24283,24290,24289,24296,24297,24300,24305,24307,24304,24308,
+24312,24318,24323,24329,24413,24412,24331,24337,24342,24361,24365,24376,24385,
+24392,24396,24398,24367,24401,24406,24407,24409,24417,24429,24435,24439,24451,
+24450,24447,24458,24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,
+24534,24571,24548,24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,
+24590,24625,24603,24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,
+24650,24646,24653,24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,
+24707,24730,24708,24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,
+24756,24560,24765,24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,
+24826,24835,24865,24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,
+24892,24876,24884,24893,24898,24900,24947,24951,24920,24921,24922,24939,24948,
+24943,24933,24945,24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,
+24970,24977,25003,25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,
+32633,25037,25062,25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,
+25097,25101,25100,25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,
+25166,25182,25187,25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,
+25300,25219,25236,25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,
+25290,25282,25287,25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,
+25424,25406,25421,25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,
+25503,25525,25451,25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,
+25622,25652,25606,25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,
+25678,25898,25749,25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,
+25816,25794,25841,25831,33289,25824,25825,25260,25827,25839,25900,25846,25844,
+25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,25911,
+25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,25986,
+25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,26075,
+26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,26140,
+26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,26243,
+26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,26296,
+26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,26406,
+26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,26467,
+26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,26607,
+26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,26566,
+26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,26723,
+26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,26805,
+26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,26892,
+26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,26863,
+26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,27006,
+26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,27054,
+27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,27182,
+27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,27122,
+27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,27204,
+27148,27250,27190,27256,27207,27234,27225,27238,27208,27192,27170,27280,27277,
+27296,27268,27298,27299,27287,34327,27323,27331,27330,27320,27315,27308,27358,
+27345,27359,27306,27354,27370,27387,27397,34326,27386,27410,27414,39729,27423,
+27448,27447,30428,27449,39150,27463,27459,27465,27472,27481,27476,27483,27487,
+27489,27512,27513,27519,27520,27524,27523,27533,27544,27541,27550,27556,27562,
+27563,27567,27570,27569,27571,27575,27580,27590,27595,27603,27615,27628,27627,
+27635,27631,40638,27656,27667,27668,27675,27684,27683,27742,27733,27746,27754,
+27778,27789,27802,27777,27803,27774,27752,27763,27794,27792,27844,27889,27859,
+27837,27863,27845,27869,27822,27825,27838,27834,27867,27887,27865,27882,27935,
+34893,27958,27947,27965,27960,27929,27957,27955,27922,27916,28003,28051,28004,
+27994,28025,27993,28046,28053,28644,28037,28153,28181,28170,28085,28103,28134,
+28088,28102,28140,28126,28108,28136,28114,28101,28154,28121,28132,28117,28138,
+28142,28205,28270,28206,28185,28274,28255,28222,28195,28267,28203,28278,28237,
+28191,28227,28218,28238,28196,28415,28189,28216,28290,28330,28312,28361,28343,
+28371,28349,28335,28356,28338,28372,28373,28303,28325,28354,28319,28481,28433,
+28748,28396,28408,28414,28479,28402,28465,28399,28466,28364,28478,28435,28407,
+28550,28538,28536,28545,28544,28527,28507,28659,28525,28546,28540,28504,28558,
+28561,28610,28518,28595,28579,28577,28580,28601,28614,28586,28639,28629,28652,
+28628,28632,28657,28654,28635,28681,28683,28666,28689,28673,28687,28670,28699,
+28698,28532,28701,28696,28703,28720,28734,28722,28753,28771,28825,28818,28847,
+28913,28844,28856,28851,28846,28895,28875,28893,28889,28937,28925,28956,28953,
+29029,29013,29064,29030,29026,29004,29014,29036,29071,29179,29060,29077,29096,
+29100,29143,29113,29118,29138,29129,29140,29134,29152,29164,29159,29173,29180,
+29177,29183,29197,29200,29211,29224,29229,29228,29232,29234,29243,29244,29247,
+29248,29254,29259,29272,29300,29310,29314,29313,29319,29330,29334,29346,29351,
+29369,29362,29379,29382,29380,29390,29394,29410,29408,29409,29433,29431,20495,
+29463,29450,29468,29462,29469,29492,29487,29481,29477,29502,29518,29519,40664,
+29527,29546,29544,29552,29560,29557,29563,29562,29640,29619,29646,29627,29632,
+29669,29678,29662,29858,29701,29807,29733,29688,29746,29754,29781,29759,29791,
+29785,29761,29788,29801,29808,29795,29802,29814,29822,29835,29854,29863,29898,
+29903,29908,29681,29920,29923,29927,29929,29934,29938,29936,29937,29944,29943,
+29956,29955,29957,29964,29966,29965,29973,29971,29982,29990,29996,30012,30020,
+30029,30026,30025,30043,30022,30042,30057,30052,30055,30059,30061,30072,30070,
+30086,30087,30068,30090,30089,30082,30100,30106,30109,30117,30115,30146,30131,
+30147,30133,30141,30136,30140,30129,30157,30154,30162,30169,30179,30174,30206,
+30207,30204,30209,30192,30202,30194,30195,30219,30221,30217,30239,30247,30240,
+30241,30242,30244,30260,30256,30267,30279,30280,30278,30300,30296,30305,30306,
+30312,30313,30314,30311,30316,30320,30322,30326,30328,30332,30336,30339,30344,
+30347,30350,30358,30355,30361,30362,30384,30388,30392,30393,30394,30402,30413,
+30422,30418,30430,30433,30437,30439,30442,34351,30459,30472,30471,30468,30505,
+30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,
+30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,
+30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,
+30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,
+30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,
+30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,
+31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,
+31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,
+31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,
+31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,
+31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,
+31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,
+31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,
+31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,
+31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,
+31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,
+31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,
+31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,
+31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,
+31994,32006,32002,32028,32021,32010,32069,32075,32046,32050,32063,32053,32070,
+32115,32086,32078,32114,32104,32110,32079,32099,32147,32137,32091,32143,32125,
+32155,32186,32174,32163,32181,32199,32189,32171,32317,32162,32175,32220,32184,
+32159,32176,32216,32221,32228,32222,32251,32242,32225,32261,32266,32291,32289,
+32274,32305,32287,32265,32267,32290,32326,32358,32315,32309,32313,32323,32311,
+32306,32314,32359,32349,32342,32350,32345,32346,32377,32362,32361,32380,32379,
+32387,32213,32381,36782,32383,32392,32393,32396,32402,32400,32403,32404,32406,
+32398,32411,32412,32568,32570,32581,32588,32589,32590,32592,32593,32597,32596,
+32600,32607,32608,32616,32617,32615,32632,32642,32646,32643,32648,32647,32652,
+32660,32670,32669,32666,32675,32687,32690,32697,32686,32694,32696,35697,32709,
+32710,32714,32725,32724,32737,32742,32745,32755,32761,39132,32774,32772,32779,
+32786,32792,32793,32796,32801,32808,32831,32827,32842,32838,32850,32856,32858,
+32863,32866,32872,32883,32882,32880,32886,32889,32893,32895,32900,32902,32901,
+32923,32915,32922,32941,20880,32940,32987,32997,32985,32989,32964,32986,32982,
+33033,33007,33009,33051,33065,33059,33071,33099,38539,33094,33086,33107,33105,
+33020,33137,33134,33125,33126,33140,33155,33160,33162,33152,33154,33184,33173,
+33188,33187,33119,33171,33193,33200,33205,33214,33208,33213,33216,33218,33210,
+33225,33229,33233,33241,33240,33224,33242,33247,33248,33255,33274,33275,33278,
+33281,33282,33285,33287,33290,33293,33296,33302,33321,33323,33336,33331,33344,
+33369,33368,33373,33370,33375,33380,33378,33384,33386,33387,33326,33393,33399,
+33400,33406,33421,33426,33451,33439,33467,33452,33505,33507,33503,33490,33524,
+33523,33530,33683,33539,33531,33529,33502,33542,33500,33545,33497,33589,33588,
+33558,33586,33585,33600,33593,33616,33605,33583,33579,33559,33560,33669,33690,
+33706,33695,33698,33686,33571,33678,33671,33674,33660,33717,33651,33653,33696,
+33673,33704,33780,33811,33771,33742,33789,33795,33752,33803,33729,33783,33799,
+33760,33778,33805,33826,33824,33725,33848,34054,33787,33901,33834,33852,34138,
+33924,33911,33899,33965,33902,33922,33897,33862,33836,33903,33913,33845,33994,
+33890,33977,33983,33951,34009,33997,33979,34010,34000,33985,33990,34006,33953,
+34081,34047,34036,34071,34072,34092,34079,34069,34068,34044,34112,34147,34136,
+34120,34113,34306,34123,34133,34176,34212,34184,34193,34186,34216,34157,34196,
+34203,34282,34183,34204,34167,34174,34192,34249,34234,34255,34233,34256,34261,
+34269,34277,34268,34297,34314,34323,34315,34302,34298,34310,34338,34330,34352,
+34367,34381,20053,34388,34399,34407,34417,34451,34467,34473,34474,34443,34444,
+34486,34479,34500,34502,34480,34505,34851,34475,34516,34526,34537,34540,34527,
+34523,34543,34578,34566,34568,34560,34563,34555,34577,34569,34573,34553,34570,
+34612,34623,34615,34619,34597,34601,34586,34656,34655,34680,34636,34638,34676,
+34647,34664,34670,34649,34643,34659,34666,34821,34722,34719,34690,34735,34763,
+34749,34752,34768,38614,34731,34756,34739,34759,34758,34747,34799,34802,34784,
+34831,34829,34814,34806,34807,34830,34770,34833,34838,34837,34850,34849,34865,
+34870,34873,34855,34875,34884,34882,34898,34905,34910,34914,34923,34945,34942,
+34974,34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,
+34992,35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,
+35048,35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,
+35131,35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,
+35191,35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,
+35258,35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,
+35340,35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,
+35426,35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,
+35522,35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,
+35596,35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,
+35624,35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,
+35700,35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,
+35912,35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,
+35981,35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,
+36040,36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,
+36109,36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,
+36290,36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,
+36348,36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,
+36423,36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,
+36476,36481,36487,36485,36484,36491,36490,36499,36497,36500,36505,36522,36513,
+36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,36604,36603,36587,
+36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,36620,36646,36659,
+36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,36700,36706,36707,
+36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,36842,36847,36999,
+36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,36875,36903,36918,
+36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,36950,36952,36958,
+36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,37001,37007,37032,
+37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,37170,37168,37194,
+37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,37282,37291,37295,
+37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,37343,37345,37339,
+37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,37463,37445,37449,
+37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,37466,37583,37561,
+37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,37690,37685,37691,
+37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,37846,37847,37864,
+37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,37891,37895,37904,
+37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,37986,37982,37994,
+37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,38274,38279,38282,
+38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,38329,38334,38346,
+28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,38370,38433,38440,
+38446,38447,38466,38476,38479,38475,38519,38492,38494,38493,38495,38502,38514,
+38508,38541,38552,38549,38551,38570,38567,38577,38578,38576,38580,38582,38584,
+38585,38606,38603,38601,38605,35149,38620,38669,38613,38649,38660,38662,38664,
+38675,38670,38673,38671,38678,38681,38692,38698,38704,38713,38717,38718,38724,
+38726,38728,38722,38729,38748,38752,38756,38758,38760,21202,38763,38769,38777,
+38789,38780,38785,38778,38790,38795,38799,38800,38812,38824,38822,38819,38835,
+38836,38851,38854,38856,38859,38876,38893,40783,38898,31455,38902,38901,38927,
+38924,38968,38948,38945,38967,38973,38982,38991,38987,39019,39023,39024,39025,
+39028,39027,39082,39087,39089,39094,39108,39107,39110,39145,39147,39171,39177,
+39186,39188,39192,39201,39197,39198,39204,39200,39212,39214,39229,39230,39234,
+39241,39237,39248,39243,39249,39250,39244,39253,39319,39320,39333,39341,39342,
+39356,39391,39387,39389,39384,39377,39405,39406,39409,39410,39419,39416,39425,
+39439,39429,39394,39449,39467,39479,39493,39490,39488,39491,39486,39509,39501,
+39515,39511,39519,39522,39525,39524,39529,39531,39530,39597,39600,39612,39616,
+39631,39633,39635,39636,39646,39647,39650,39651,39654,39663,39659,39662,39668,
+39665,39671,39675,39686,39704,39706,39711,39714,39715,39717,39719,39720,39721,
+39722,39726,39727,39730,39748,39747,39759,39757,39758,39761,39768,39796,39827,
+39811,39825,39830,39831,39839,39840,39848,39860,39872,39882,39865,39878,39887,
+39889,39890,39907,39906,39908,39892,39905,39994,39922,39921,39920,39957,39956,
+39945,39955,39948,39942,39944,39954,39946,39940,39982,39963,39973,39972,39969,
+39984,40007,39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,
+40201,40200,40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,
+40257,40255,40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,
+40327,40363,40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,
+40390,40399,40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,
+40565,40569,40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,
+40632,40618,40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,
+40677,40680,40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,
+40725,40737,40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,
+40812,40810,40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,
+29081,
+};
+
+static const struct dbcs_index jisx0208_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+0,33,126},{__jisx0208_decmap
++94,33,126},{__jisx0208_decmap+188,48,122},{__jisx0208_decmap+263,33,115},{
+__jisx0208_decmap+346,33,118},{__jisx0208_decmap+432,33,88},{__jisx0208_decmap
++488,33,113},{__jisx0208_decmap+569,33,64},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+601,33,126},{__jisx0208_decmap+695,33,
+126},{__jisx0208_decmap+789,33,126},{__jisx0208_decmap+883,33,126},{
+__jisx0208_decmap+977,33,126},{__jisx0208_decmap+1071,33,126},{
+__jisx0208_decmap+1165,33,126},{__jisx0208_decmap+1259,33,126},{
+__jisx0208_decmap+1353,33,126},{__jisx0208_decmap+1447,33,126},{
+__jisx0208_decmap+1541,33,126},{__jisx0208_decmap+1635,33,126},{
+__jisx0208_decmap+1729,33,126},{__jisx0208_decmap+1823,33,126},{
+__jisx0208_decmap+1917,33,126},{__jisx0208_decmap+2011,33,126},{
+__jisx0208_decmap+2105,33,126},{__jisx0208_decmap+2199,33,126},{
+__jisx0208_decmap+2293,33,126},{__jisx0208_decmap+2387,33,126},{
+__jisx0208_decmap+2481,33,126},{__jisx0208_decmap+2575,33,126},{
+__jisx0208_decmap+2669,33,126},{__jisx0208_decmap+2763,33,126},{
+__jisx0208_decmap+2857,33,126},{__jisx0208_decmap+2951,33,126},{
+__jisx0208_decmap+3045,33,126},{__jisx0208_decmap+3139,33,126},{
+__jisx0208_decmap+3233,33,126},{__jisx0208_decmap+3327,33,126},{
+__jisx0208_decmap+3421,33,126},{__jisx0208_decmap+3515,33,83},{
+__jisx0208_decmap+3566,33,126},{__jisx0208_decmap+3660,33,126},{
+__jisx0208_decmap+3754,33,126},{__jisx0208_decmap+3848,33,126},{
+__jisx0208_decmap+3942,33,126},{__jisx0208_decmap+4036,33,126},{
+__jisx0208_decmap+4130,33,126},{__jisx0208_decmap+4224,33,126},{
+__jisx0208_decmap+4318,33,126},{__jisx0208_decmap+4412,33,126},{
+__jisx0208_decmap+4506,33,126},{__jisx0208_decmap+4600,33,126},{
+__jisx0208_decmap+4694,33,126},{__jisx0208_decmap+4788,33,126},{
+__jisx0208_decmap+4882,33,126},{__jisx0208_decmap+4976,33,126},{
+__jisx0208_decmap+5070,33,126},{__jisx0208_decmap+5164,33,126},{
+__jisx0208_decmap+5258,33,126},{__jisx0208_decmap+5352,33,126},{
+__jisx0208_decmap+5446,33,126},{__jisx0208_decmap+5540,33,126},{
+__jisx0208_decmap+5634,33,126},{__jisx0208_decmap+5728,33,126},{
+__jisx0208_decmap+5822,33,126},{__jisx0208_decmap+5916,33,126},{
+__jisx0208_decmap+6010,33,126},{__jisx0208_decmap+6104,33,126},{
+__jisx0208_decmap+6198,33,126},{__jisx0208_decmap+6292,33,126},{
+__jisx0208_decmap+6386,33,126},{__jisx0208_decmap+6480,33,126},{
+__jisx0208_decmap+6574,33,126},{__jisx0208_decmap+6668,33,126},{
+__jisx0208_decmap+6762,33,126},{__jisx0208_decmap+6856,33,126},{
+__jisx0208_decmap+6950,33,38},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __jisx0212_decmap[6179] = {
+728,711,184,729,733,175,731,730,126,900,901,U,U,U,U,U,U,U,U,161,166,191,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,186,170,
+169,174,8482,164,8470,902,904,905,906,938,U,908,U,910,939,U,911,U,U,U,U,940,
+941,942,943,970,912,972,962,973,971,944,974,1026,1027,1028,1029,1030,1031,
+1032,1033,1034,1035,1036,1038,1039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,
+1116,1118,1119,198,272,U,294,U,306,U,321,319,U,330,216,338,U,358,222,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,230,273,240,295,305,307,312,322,320,329,331,248,339,
+223,359,254,193,192,196,194,258,461,256,260,197,195,262,264,268,199,266,270,
+201,200,203,202,282,278,274,280,U,284,286,290,288,292,205,204,207,206,463,304,
+298,302,296,308,310,313,317,315,323,327,325,209,211,210,214,212,465,336,332,
+213,340,344,342,346,348,352,350,356,354,218,217,220,219,364,467,368,362,370,
+366,360,471,475,473,469,372,221,376,374,377,381,379,225,224,228,226,259,462,
+257,261,229,227,263,265,269,231,267,271,233,232,235,234,283,279,275,281,501,
+285,287,U,289,293,237,236,239,238,464,U,299,303,297,309,311,314,318,316,324,
+328,326,241,243,242,246,244,466,337,333,245,341,345,343,347,349,353,351,357,
+355,250,249,252,251,365,468,369,363,371,367,361,472,476,474,470,373,253,255,
+375,378,382,380,19970,19972,19973,19980,19986,19999,20003,20004,20008,20011,
+20014,20015,20016,20021,20032,20033,20036,20039,20049,20058,20060,20067,20072,
+20073,20084,20085,20089,20095,20109,20118,20119,20125,20143,20153,20163,20176,
+20186,20187,20192,20193,20194,20200,20207,20209,20211,20213,20221,20222,20223,
+20224,20226,20227,20232,20235,20236,20242,20245,20246,20247,20249,20270,20273,
+20320,20275,20277,20279,20281,20283,20286,20288,20290,20296,20297,20299,20300,
+20306,20308,20310,20312,20319,20323,20330,20332,20334,20337,20343,20344,20345,
+20346,20349,20350,20353,20354,20356,20357,20361,20362,20364,20366,20368,20370,
+20371,20372,20375,20377,20378,20382,20383,20402,20407,20409,20411,20412,20413,
+20414,20416,20417,20421,20422,20424,20425,20427,20428,20429,20431,20434,20444,
+20448,20450,20464,20466,20476,20477,20479,20480,20481,20484,20487,20490,20492,
+20494,20496,20499,20503,20504,20507,20508,20509,20510,20514,20519,20526,20528,
+20530,20531,20533,20544,20545,20546,20549,20550,20554,20556,20558,20561,20562,
+20563,20567,20569,20575,20576,20578,20579,20582,20583,20586,20589,20592,20593,
+20539,20609,20611,20612,20614,20618,20622,20623,20624,20626,20627,20628,20630,
+20635,20636,20638,20639,20640,20641,20642,20650,20655,20656,20665,20666,20669,
+20672,20675,20676,20679,20684,20686,20688,20691,20692,20696,20700,20701,20703,
+20706,20708,20710,20712,20713,20719,20721,20726,20730,20734,20739,20742,20743,
+20744,20747,20748,20749,20750,20722,20752,20759,20761,20763,20764,20765,20766,
+20771,20775,20776,20780,20781,20783,20785,20787,20788,20789,20792,20793,20802,
+20810,20815,20819,20821,20823,20824,20831,20836,20838,20862,20867,20868,20875,
+20878,20888,20893,20897,20899,20909,20920,20922,20924,20926,20927,20930,20936,
+20943,20945,20946,20947,20949,20952,20958,20962,20965,20974,20978,20979,20980,
+20983,20993,20994,20997,21010,21011,21013,21014,21016,21026,21032,21041,21042,
+21045,21052,21061,21065,21077,21079,21080,21082,21084,21087,21088,21089,21094,
+21102,21111,21112,21113,21120,21122,21125,21130,21132,21139,21141,21142,21143,
+21144,21146,21148,21156,21157,21158,21159,21167,21168,21174,21175,21176,21178,
+21179,21181,21184,21188,21190,21192,21196,21199,21201,21204,21206,21211,21212,
+21217,21221,21224,21225,21226,21228,21232,21233,21236,21238,21239,21248,21251,
+21258,21259,21260,21265,21267,21272,21275,21276,21278,21279,21285,21287,21288,
+21289,21291,21292,21293,21296,21298,21301,21308,21309,21310,21314,21324,21323,
+21337,21339,21345,21347,21349,21356,21357,21362,21369,21374,21379,21383,21384,
+21390,21395,21396,21401,21405,21409,21412,21418,21419,21423,21426,21428,21429,
+21431,21432,21434,21437,21440,21445,21455,21458,21459,21461,21466,21469,21470,
+21472,21478,21479,21493,21506,21523,21530,21537,21543,21544,21546,21551,21553,
+21556,21557,21571,21572,21575,21581,21583,21598,21602,21604,21606,21607,21609,
+21611,21613,21614,21620,21631,21633,21635,21637,21640,21641,21645,21649,21653,
+21654,21660,21663,21665,21670,21671,21673,21674,21677,21678,21681,21687,21689,
+21690,21691,21695,21702,21706,21709,21710,21728,21738,21740,21743,21750,21756,
+21758,21759,21760,21761,21765,21768,21769,21772,21773,21774,21781,21802,21803,
+21810,21813,21814,21819,21820,21821,21825,21831,21833,21834,21837,21840,21841,
+21848,21850,21851,21854,21856,21857,21860,21862,21887,21889,21890,21894,21896,
+21902,21903,21905,21906,21907,21908,21911,21923,21924,21933,21938,21951,21953,
+21955,21958,21961,21963,21964,21966,21969,21970,21971,21975,21976,21979,21982,
+21986,21993,22006,22015,22021,22024,22026,22029,22030,22031,22032,22033,22034,
+22041,22060,22064,22067,22069,22071,22073,22075,22076,22077,22079,22080,22081,
+22083,22084,22086,22089,22091,22093,22095,22100,22110,22112,22113,22114,22115,
+22118,22121,22125,22127,22129,22130,22133,22148,22149,22152,22155,22156,22165,
+22169,22170,22173,22174,22175,22182,22183,22184,22185,22187,22188,22189,22193,
+22195,22199,22206,22213,22217,22218,22219,22223,22224,22220,22221,22233,22236,
+22237,22239,22241,22244,22245,22246,22247,22248,22257,22251,22253,22262,22263,
+22273,22274,22279,22282,22284,22289,22293,22298,22299,22301,22304,22306,22307,
+22308,22309,22313,22314,22316,22318,22319,22323,22324,22333,22334,22335,22341,
+22342,22348,22349,22354,22370,22373,22375,22376,22379,22381,22382,22383,22384,
+22385,22387,22388,22389,22391,22393,22394,22395,22396,22398,22401,22403,22412,
+22420,22423,22425,22426,22428,22429,22430,22431,22433,22421,22439,22440,22441,
+22444,22456,22461,22471,22472,22476,22479,22485,22493,22494,22500,22502,22503,
+22505,22509,22512,22517,22518,22520,22525,22526,22527,22531,22532,22536,22537,
+22497,22540,22541,22555,22558,22559,22560,22566,22567,22573,22578,22585,22591,
+22601,22604,22605,22607,22608,22613,22623,22625,22628,22631,22632,22648,22652,
+22655,22656,22657,22663,22664,22665,22666,22668,22669,22671,22672,22676,22678,
+22685,22688,22689,22690,22694,22697,22705,22706,22724,22716,22722,22728,22733,
+22734,22736,22738,22740,22742,22746,22749,22753,22754,22761,22771,22789,22790,
+22795,22796,22802,22803,22804,34369,22813,22817,22819,22820,22824,22831,22832,
+22835,22837,22838,22847,22851,22854,22866,22867,22873,22875,22877,22878,22879,
+22881,22883,22891,22893,22895,22898,22901,22902,22905,22907,22908,22923,22924,
+22926,22930,22933,22935,22943,22948,22951,22957,22958,22959,22960,22963,22967,
+22970,22972,22977,22979,22980,22984,22986,22989,22994,23005,23006,23007,23011,
+23012,23015,23022,23023,23025,23026,23028,23031,23040,23044,23052,23053,23054,
+23058,23059,23070,23075,23076,23079,23080,23082,23085,23088,23108,23109,23111,
+23112,23116,23120,23125,23134,23139,23141,23143,23149,23159,23162,23163,23166,
+23179,23184,23187,23190,23193,23196,23198,23199,23200,23202,23207,23212,23217,
+23218,23219,23221,23224,23226,23227,23231,23236,23238,23240,23247,23258,23260,
+23264,23269,23274,23278,23285,23286,23293,23296,23297,23304,23319,23348,23321,
+23323,23325,23329,23333,23341,23352,23361,23371,23372,23378,23382,23390,23400,
+23406,23407,23420,23421,23422,23423,23425,23428,23430,23434,23438,23440,23441,
+23443,23444,23446,23464,23465,23468,23469,23471,23473,23474,23479,23482,23484,
+23488,23489,23501,23503,23510,23511,23512,23513,23514,23520,23535,23537,23540,
+23549,23564,23575,23582,23583,23587,23590,23593,23595,23596,23598,23600,23602,
+23605,23606,23641,23642,23644,23650,23651,23655,23656,23657,23661,23664,23668,
+23669,23674,23675,23676,23677,23687,23688,23690,23695,23698,23709,23711,23712,
+23714,23715,23718,23722,23730,23732,23733,23738,23753,23755,23762,23773,23767,
+23790,23793,23794,23796,23809,23814,23821,23826,23851,23843,23844,23846,23847,
+23857,23860,23865,23869,23871,23874,23875,23878,23880,23893,23889,23897,23882,
+23903,23904,23905,23906,23908,23914,23917,23920,23929,23930,23934,23935,23937,
+23939,23944,23946,23954,23955,23956,23957,23961,23963,23967,23968,23975,23979,
+23984,23988,23992,23993,24003,24007,24011,24016,24014,24024,24025,24032,24036,
+24041,24056,24057,24064,24071,24077,24082,24084,24085,24088,24095,24096,24110,
+24104,24114,24117,24126,24139,24144,24137,24145,24150,24152,24155,24156,24158,
+24168,24170,24171,24172,24173,24174,24176,24192,24203,24206,24226,24228,24229,
+24232,24234,24236,24241,24243,24253,24254,24255,24262,24268,24267,24270,24273,
+24274,24276,24277,24284,24286,24293,24299,24322,24326,24327,24328,24334,24345,
+24348,24349,24353,24354,24355,24356,24360,24363,24364,24366,24368,24372,24374,
+24379,24381,24383,24384,24388,24389,24391,24397,24400,24404,24408,24411,24416,
+24419,24420,24423,24431,24434,24436,24437,24440,24442,24445,24446,24457,24461,
+24463,24470,24476,24477,24482,24487,24491,24484,24492,24495,24496,24497,24504,
+24516,24519,24520,24521,24523,24528,24529,24530,24531,24532,24542,24545,24546,
+24552,24553,24554,24556,24557,24558,24559,24562,24563,24566,24570,24572,24583,
+24586,24589,24595,24596,24599,24600,24602,24607,24612,24621,24627,24629,24640,
+24647,24648,24649,24652,24657,24660,24662,24663,24669,24673,24679,24689,24702,
+24703,24706,24710,24712,24714,24718,24721,24723,24725,24728,24733,24734,24738,
+24740,24741,24744,24752,24753,24759,24763,24766,24770,24772,24776,24777,24778,
+24779,24782,24783,24788,24789,24793,24795,24797,24798,24802,24805,24818,24821,
+24824,24828,24829,24834,24839,24842,24844,24848,24849,24850,24851,24852,24854,
+24855,24857,24860,24862,24866,24874,24875,24880,24881,24885,24886,24887,24889,
+24897,24901,24902,24905,24926,24928,24940,24946,24952,24955,24956,24959,24960,
+24961,24963,24964,24971,24973,24978,24979,24983,24984,24988,24989,24991,24992,
+24997,25000,25002,25005,25016,25017,25020,25024,25025,25026,25038,25039,25045,
+25052,25053,25054,25055,25057,25058,25063,25065,25061,25068,25069,25071,25089,
+25091,25092,25095,25107,25109,25116,25120,25122,25123,25127,25129,25131,25145,
+25149,25154,25155,25156,25158,25164,25168,25169,25170,25172,25174,25178,25180,
+25188,25197,25199,25203,25210,25213,25229,25230,25231,25232,25254,25256,25267,
+25270,25271,25274,25278,25279,25284,25294,25301,25302,25306,25322,25330,25332,
+25340,25341,25347,25348,25354,25355,25357,25360,25363,25366,25368,25385,25386,
+25389,25397,25398,25401,25404,25409,25410,25411,25412,25414,25418,25419,25422,
+25426,25427,25428,25432,25435,25445,25446,25452,25453,25457,25460,25461,25464,
+25468,25469,25471,25474,25476,25479,25482,25488,25492,25493,25497,25498,25502,
+25508,25510,25517,25518,25519,25533,25537,25541,25544,25550,25553,25555,25556,
+25557,25564,25568,25573,25578,25580,25586,25587,25589,25592,25593,25609,25610,
+25616,25618,25620,25624,25630,25632,25634,25636,25637,25641,25642,25647,25648,
+25653,25661,25663,25675,25679,25681,25682,25683,25684,25690,25691,25692,25693,
+25695,25696,25697,25699,25709,25715,25716,25723,25725,25733,25735,25743,25744,
+25745,25752,25753,25755,25757,25759,25761,25763,25766,25768,25772,25779,25789,
+25790,25791,25796,25801,25802,25803,25804,25806,25808,25809,25813,25815,25828,
+25829,25833,25834,25837,25840,25845,25847,25851,25855,25857,25860,25864,25865,
+25866,25871,25875,25876,25878,25881,25883,25886,25887,25890,25894,25897,25902,
+25905,25914,25916,25917,25923,25927,25929,25936,25938,25940,25951,25952,25959,
+25963,25978,25981,25985,25989,25994,26002,26005,26008,26013,26016,26019,26022,
+26030,26034,26035,26036,26047,26050,26056,26057,26062,26064,26068,26070,26072,
+26079,26096,26098,26100,26101,26105,26110,26111,26112,26116,26120,26121,26125,
+26129,26130,26133,26134,26141,26142,26145,26146,26147,26148,26150,26153,26154,
+26155,26156,26158,26160,26161,26163,26169,26167,26176,26181,26182,26186,26188,
+26193,26190,26199,26200,26201,26203,26204,26208,26209,26363,26218,26219,26220,
+26238,26227,26229,26239,26231,26232,26233,26235,26240,26236,26251,26252,26253,
+26256,26258,26265,26266,26267,26268,26271,26272,26276,26285,26289,26290,26293,
+26299,26303,26304,26306,26307,26312,26316,26318,26319,26324,26331,26335,26344,
+26347,26348,26350,26362,26373,26375,26382,26387,26393,26396,26400,26402,26419,
+26430,26437,26439,26440,26444,26452,26453,26461,26470,26476,26478,26484,26486,
+26491,26497,26500,26510,26511,26513,26515,26518,26520,26521,26523,26544,26545,
+26546,26549,26555,26556,26557,26617,26560,26562,26563,26565,26568,26569,26578,
+26583,26585,26588,26593,26598,26608,26610,26614,26615,26706,26644,26649,26653,
+26655,26664,26663,26668,26669,26671,26672,26673,26675,26683,26687,26692,26693,
+26698,26700,26709,26711,26712,26715,26731,26734,26735,26736,26737,26738,26741,
+26745,26746,26747,26748,26754,26756,26758,26760,26774,26776,26778,26780,26785,
+26787,26789,26793,26794,26798,26802,26811,26821,26824,26828,26831,26832,26833,
+26835,26838,26841,26844,26845,26853,26856,26858,26859,26860,26861,26864,26865,
+26869,26870,26875,26876,26877,26886,26889,26890,26896,26897,26899,26902,26903,
+26929,26931,26933,26936,26939,26946,26949,26953,26958,26967,26971,26979,26980,
+26981,26982,26984,26985,26988,26992,26993,26994,27002,27003,27007,27008,27021,
+27026,27030,27032,27041,27045,27046,27048,27051,27053,27055,27063,27064,27066,
+27068,27077,27080,27089,27094,27095,27106,27109,27118,27119,27121,27123,27125,
+27134,27136,27137,27139,27151,27153,27157,27162,27165,27168,27172,27176,27184,
+27186,27188,27191,27195,27198,27199,27205,27206,27209,27210,27214,27216,27217,
+27218,27221,27222,27227,27236,27239,27242,27249,27251,27262,27265,27267,27270,
+27271,27273,27275,27281,27291,27293,27294,27295,27301,27307,27311,27312,27313,
+27316,27325,27326,27327,27334,27337,27336,27340,27344,27348,27349,27350,27356,
+27357,27364,27367,27372,27376,27377,27378,27388,27389,27394,27395,27398,27399,
+27401,27407,27408,27409,27415,27419,27422,27428,27432,27435,27436,27439,27445,
+27446,27451,27455,27462,27466,27469,27474,27478,27480,27485,27488,27495,27499,
+27502,27504,27509,27517,27518,27522,27525,27543,27547,27551,27552,27554,27555,
+27560,27561,27564,27565,27566,27568,27576,27577,27581,27582,27587,27588,27593,
+27596,27606,27610,27617,27619,27622,27623,27630,27633,27639,27641,27647,27650,
+27652,27653,27657,27661,27662,27664,27666,27673,27679,27686,27687,27688,27692,
+27694,27699,27701,27702,27706,27707,27711,27722,27723,27725,27727,27730,27732,
+27737,27739,27740,27755,27757,27759,27764,27766,27768,27769,27771,27781,27782,
+27783,27785,27796,27797,27799,27800,27804,27807,27824,27826,27828,27842,27846,
+27853,27855,27856,27857,27858,27860,27862,27866,27868,27872,27879,27881,27883,
+27884,27886,27890,27892,27908,27911,27914,27918,27919,27921,27923,27930,27942,
+27943,27944,27751,27950,27951,27953,27961,27964,27967,27991,27998,27999,28001,
+28005,28007,28015,28016,28028,28034,28039,28049,28050,28052,28054,28055,28056,
+28074,28076,28084,28087,28089,28093,28095,28100,28104,28106,28110,28111,28118,
+28123,28125,28127,28128,28130,28133,28137,28143,28144,28148,28150,28156,28160,
+28164,28190,28194,28199,28210,28214,28217,28219,28220,28228,28229,28232,28233,
+28235,28239,28241,28242,28243,28244,28247,28252,28253,28254,28258,28259,28264,
+28275,28283,28285,28301,28307,28313,28320,28327,28333,28334,28337,28339,28347,
+28351,28352,28353,28355,28359,28360,28362,28365,28366,28367,28395,28397,28398,
+28409,28411,28413,28420,28424,28426,28428,28429,28438,28440,28442,28443,28454,
+28457,28458,28463,28464,28467,28470,28475,28476,28461,28495,28497,28498,28499,
+28503,28505,28506,28509,28510,28513,28514,28520,28524,28541,28542,28547,28551,
+28552,28555,28556,28557,28560,28562,28563,28564,28566,28570,28575,28576,28581,
+28582,28583,28584,28590,28591,28592,28597,28598,28604,28613,28615,28616,28618,
+28634,28638,28648,28649,28656,28661,28665,28668,28669,28672,28677,28678,28679,
+28685,28695,28704,28707,28719,28724,28727,28729,28732,28739,28740,28744,28745,
+28746,28747,28756,28757,28765,28766,28750,28772,28773,28780,28782,28789,28790,
+28798,28801,28805,28806,28820,28821,28822,28823,28824,28827,28836,28843,28848,
+28849,28852,28855,28874,28881,28883,28884,28885,28886,28888,28892,28900,28922,
+28931,28932,28933,28934,28935,28939,28940,28943,28958,28960,28971,28973,28975,
+28976,28977,28984,28993,28997,28998,28999,29002,29003,29008,29010,29015,29018,
+29020,29022,29024,29032,29049,29056,29061,29063,29068,29074,29082,29083,29088,
+29090,29103,29104,29106,29107,29114,29119,29120,29121,29124,29131,29132,29139,
+29142,29145,29146,29148,29176,29182,29184,29191,29192,29193,29203,29207,29210,
+29213,29215,29220,29227,29231,29236,29240,29241,29249,29250,29251,29253,29262,
+29263,29264,29267,29269,29270,29274,29276,29278,29280,29283,29288,29291,29294,
+29295,29297,29303,29304,29307,29308,29311,29316,29321,29325,29326,29331,29339,
+29352,29357,29358,29361,29364,29374,29377,29383,29385,29388,29397,29398,29400,
+29407,29413,29427,29428,29434,29435,29438,29442,29444,29445,29447,29451,29453,
+29458,29459,29464,29465,29470,29474,29476,29479,29480,29484,29489,29490,29493,
+29498,29499,29501,29507,29517,29520,29522,29526,29528,29533,29534,29535,29536,
+29542,29543,29545,29547,29548,29550,29551,29553,29559,29561,29564,29568,29569,
+29571,29573,29574,29582,29584,29587,29589,29591,29592,29596,29598,29599,29600,
+29602,29605,29606,29610,29611,29613,29621,29623,29625,29628,29629,29631,29637,
+29638,29641,29643,29644,29647,29650,29651,29654,29657,29661,29665,29667,29670,
+29671,29673,29684,29685,29687,29689,29690,29691,29693,29695,29696,29697,29700,
+29703,29706,29713,29722,29723,29732,29734,29736,29737,29738,29739,29740,29741,
+29742,29743,29744,29745,29753,29760,29763,29764,29766,29767,29771,29773,29777,
+29778,29783,29789,29794,29798,29799,29800,29803,29805,29806,29809,29810,29824,
+29825,29829,29830,29831,29833,29839,29840,29841,29842,29848,29849,29850,29852,
+29855,29856,29857,29859,29862,29864,29865,29866,29867,29870,29871,29873,29874,
+29877,29881,29883,29887,29896,29897,29900,29904,29907,29912,29914,29915,29918,
+29919,29924,29928,29930,29931,29935,29940,29946,29947,29948,29951,29958,29970,
+29974,29975,29984,29985,29988,29991,29993,29994,29999,30006,30009,30013,30014,
+30015,30016,30019,30023,30024,30030,30032,30034,30039,30046,30047,30049,30063,
+30065,30073,30074,30075,30076,30077,30078,30081,30085,30096,30098,30099,30101,
+30105,30108,30114,30116,30132,30138,30143,30144,30145,30148,30150,30156,30158,
+30159,30167,30172,30175,30176,30177,30180,30183,30188,30190,30191,30193,30201,
+30208,30210,30211,30212,30215,30216,30218,30220,30223,30226,30227,30229,30230,
+30233,30235,30236,30237,30238,30243,30245,30246,30249,30253,30258,30259,30261,
+30264,30265,30266,30268,30282,30272,30273,30275,30276,30277,30281,30283,30293,
+30297,30303,30308,30309,30317,30318,30319,30321,30324,30337,30341,30348,30349,
+30357,30363,30364,30365,30367,30368,30370,30371,30372,30373,30374,30375,30376,
+30378,30381,30397,30401,30405,30409,30411,30412,30414,30420,30425,30432,30438,
+30440,30444,30448,30449,30454,30457,30460,30464,30470,30474,30478,30482,30484,
+30485,30487,30489,30490,30492,30498,30504,30509,30510,30511,30516,30517,30518,
+30521,30525,30526,30530,30533,30534,30538,30541,30542,30543,30546,30550,30551,
+30556,30558,30559,30560,30562,30564,30567,30570,30572,30576,30578,30579,30580,
+30586,30589,30592,30596,30604,30605,30612,30613,30614,30618,30623,30626,30631,
+30634,30638,30639,30641,30645,30654,30659,30665,30673,30674,30677,30681,30686,
+30687,30688,30692,30694,30698,30700,30704,30705,30708,30712,30715,30725,30726,
+30729,30733,30734,30737,30749,30753,30754,30755,30765,30766,30768,30773,30775,
+30787,30788,30791,30792,30796,30798,30802,30812,30814,30816,30817,30819,30820,
+30824,30826,30830,30842,30846,30858,30863,30868,30872,30881,30877,30878,30879,
+30884,30888,30892,30893,30896,30897,30898,30899,30907,30909,30911,30919,30920,
+30921,30924,30926,30930,30931,30933,30934,30948,30939,30943,30944,30945,30950,
+30954,30962,30963,30976,30966,30967,30970,30971,30975,30982,30988,30992,31002,
+31004,31006,31007,31008,31013,31015,31017,31021,31025,31028,31029,31035,31037,
+31039,31044,31045,31046,31050,31051,31055,31057,31060,31064,31067,31068,31079,
+31081,31083,31090,31097,31099,31100,31102,31115,31116,31121,31123,31124,31125,
+31126,31128,31131,31132,31137,31144,31145,31147,31151,31153,31156,31160,31163,
+31170,31172,31175,31176,31178,31183,31188,31190,31194,31197,31198,31200,31202,
+31205,31210,31211,31213,31217,31224,31228,31234,31235,31239,31241,31242,31244,
+31249,31253,31259,31262,31265,31271,31275,31277,31279,31280,31284,31285,31288,
+31289,31290,31300,31301,31303,31304,31308,31317,31318,31321,31324,31325,31327,
+31328,31333,31335,31338,31341,31349,31352,31358,31360,31362,31365,31366,31370,
+31371,31376,31377,31380,31390,31392,31395,31404,31411,31413,31417,31419,31420,
+31430,31433,31436,31438,31441,31451,31464,31465,31467,31468,31473,31476,31483,
+31485,31486,31495,31508,31519,31523,31527,31529,31530,31531,31533,31534,31535,
+31536,31537,31540,31549,31551,31552,31553,31559,31566,31573,31584,31588,31590,
+31593,31594,31597,31599,31602,31603,31607,31620,31625,31630,31632,31633,31638,
+31643,31646,31648,31653,31660,31663,31664,31666,31669,31670,31674,31675,31676,
+31677,31682,31685,31688,31690,31700,31702,31703,31705,31706,31707,31720,31722,
+31730,31732,31733,31736,31737,31738,31740,31742,31745,31746,31747,31748,31750,
+31753,31755,31756,31758,31759,31769,31771,31776,31781,31782,31784,31788,31793,
+31795,31796,31798,31801,31802,31814,31818,31829,31825,31826,31827,31833,31834,
+31835,31836,31837,31838,31841,31843,31847,31849,31853,31854,31856,31858,31865,
+31868,31869,31878,31879,31887,31892,31902,31904,31910,31920,31926,31927,31930,
+31931,31932,31935,31940,31943,31944,31945,31949,31951,31955,31956,31957,31959,
+31961,31962,31965,31974,31977,31979,31989,32003,32007,32008,32009,32015,32017,
+32018,32019,32022,32029,32030,32035,32038,32042,32045,32049,32060,32061,32062,
+32064,32065,32071,32072,32077,32081,32083,32087,32089,32090,32092,32093,32101,
+32103,32106,32112,32120,32122,32123,32127,32129,32130,32131,32133,32134,32136,
+32139,32140,32141,32145,32150,32151,32157,32158,32166,32167,32170,32179,32182,
+32183,32185,32194,32195,32196,32197,32198,32204,32205,32206,32215,32217,32256,
+32226,32229,32230,32234,32235,32237,32241,32245,32246,32249,32250,32264,32272,
+32273,32277,32279,32284,32285,32288,32295,32296,32300,32301,32303,32307,32310,
+32319,32324,32325,32327,32334,32336,32338,32344,32351,32353,32354,32357,32363,
+32366,32367,32371,32376,32382,32385,32390,32391,32394,32397,32401,32405,32408,
+32410,32413,32414,32572,32571,32573,32574,32575,32579,32580,32583,32591,32594,
+32595,32603,32604,32605,32609,32611,32612,32613,32614,32621,32625,32637,32638,
+32639,32640,32651,32653,32655,32656,32657,32662,32663,32668,32673,32674,32678,
+32682,32685,32692,32700,32703,32704,32707,32712,32718,32719,32731,32735,32739,
+32741,32744,32748,32750,32751,32754,32762,32765,32766,32767,32775,32776,32778,
+32781,32782,32783,32785,32787,32788,32790,32797,32798,32799,32800,32804,32806,
+32812,32814,32816,32820,32821,32823,32825,32826,32828,32830,32832,32836,32864,
+32868,32870,32877,32881,32885,32897,32904,32910,32924,32926,32934,32935,32939,
+32952,32953,32968,32973,32975,32978,32980,32981,32983,32984,32992,33005,33006,
+33008,33010,33011,33014,33017,33018,33022,33027,33035,33046,33047,33048,33052,
+33054,33056,33060,33063,33068,33072,33077,33082,33084,33093,33095,33098,33100,
+33106,33111,33120,33121,33127,33128,33129,33133,33135,33143,33153,33168,33156,
+33157,33158,33163,33166,33174,33176,33179,33182,33186,33198,33202,33204,33211,
+33227,33219,33221,33226,33230,33231,33237,33239,33243,33245,33246,33249,33252,
+33259,33260,33264,33265,33266,33269,33270,33272,33273,33277,33279,33280,33283,
+33295,33299,33300,33305,33306,33309,33313,33314,33320,33330,33332,33338,33347,
+33348,33349,33350,33355,33358,33359,33361,33366,33372,33376,33379,33383,33389,
+33396,33403,33405,33407,33408,33409,33411,33412,33415,33417,33418,33422,33425,
+33428,33430,33432,33434,33435,33440,33441,33443,33444,33447,33448,33449,33450,
+33454,33456,33458,33460,33463,33466,33468,33470,33471,33478,33488,33493,33498,
+33504,33506,33508,33512,33514,33517,33519,33526,33527,33533,33534,33536,33537,
+33543,33544,33546,33547,33620,33563,33565,33566,33567,33569,33570,33580,33581,
+33582,33584,33587,33591,33594,33596,33597,33602,33603,33604,33607,33613,33614,
+33617,33621,33622,33623,33648,33656,33661,33663,33664,33666,33668,33670,33677,
+33682,33684,33685,33688,33689,33691,33692,33693,33702,33703,33705,33708,33726,
+33727,33728,33735,33737,33743,33744,33745,33748,33757,33619,33768,33770,33782,
+33784,33785,33788,33793,33798,33802,33807,33809,33813,33817,33709,33839,33849,
+33861,33863,33864,33866,33869,33871,33873,33874,33878,33880,33881,33882,33884,
+33888,33892,33893,33895,33898,33904,33907,33908,33910,33912,33916,33917,33921,
+33925,33938,33939,33941,33950,33958,33960,33961,33962,33967,33969,33972,33978,
+33981,33982,33984,33986,33991,33992,33996,33999,34003,34012,34023,34026,34031,
+34032,34033,34034,34039,34098,34042,34043,34045,34050,34051,34055,34060,34062,
+34064,34076,34078,34082,34083,34084,34085,34087,34090,34091,34095,34099,34100,
+34102,34111,34118,34127,34128,34129,34130,34131,34134,34137,34140,34141,34142,
+34143,34144,34145,34146,34148,34155,34159,34169,34170,34171,34173,34175,34177,
+34181,34182,34185,34187,34188,34191,34195,34200,34205,34207,34208,34210,34213,
+34215,34228,34230,34231,34232,34236,34237,34238,34239,34242,34247,34250,34251,
+34254,34221,34264,34266,34271,34272,34278,34280,34285,34291,34294,34300,34303,
+34304,34308,34309,34317,34318,34320,34321,34322,34328,34329,34331,34334,34337,
+34343,34345,34358,34360,34362,34364,34365,34368,34370,34374,34386,34387,34390,
+34391,34392,34393,34397,34400,34401,34402,34403,34404,34409,34412,34415,34421,
+34422,34423,34426,34445,34449,34454,34456,34458,34460,34465,34470,34471,34472,
+34477,34481,34483,34484,34485,34487,34488,34489,34495,34496,34497,34499,34501,
+34513,34514,34517,34519,34522,34524,34528,34531,34533,34535,34440,34554,34556,
+34557,34564,34565,34567,34571,34574,34575,34576,34579,34580,34585,34590,34591,
+34593,34595,34600,34606,34607,34609,34610,34617,34618,34620,34621,34622,34624,
+34627,34629,34637,34648,34653,34657,34660,34661,34671,34673,34674,34683,34691,
+34692,34693,34694,34695,34696,34697,34699,34700,34704,34707,34709,34711,34712,
+34713,34718,34720,34723,34727,34732,34733,34734,34737,34741,34750,34751,34753,
+34760,34761,34762,34766,34773,34774,34777,34778,34780,34783,34786,34787,34788,
+34794,34795,34797,34801,34803,34808,34810,34815,34817,34819,34822,34825,34826,
+34827,34832,34841,34834,34835,34836,34840,34842,34843,34844,34846,34847,34856,
+34861,34862,34864,34866,34869,34874,34876,34881,34883,34885,34888,34889,34890,
+34891,34894,34897,34901,34902,34904,34906,34908,34911,34912,34916,34921,34929,
+34937,34939,34944,34968,34970,34971,34972,34975,34976,34984,34986,35002,35005,
+35006,35008,35018,35019,35020,35021,35022,35025,35026,35027,35035,35038,35047,
+35055,35056,35057,35061,35063,35073,35078,35085,35086,35087,35093,35094,35096,
+35097,35098,35100,35104,35110,35111,35112,35120,35121,35122,35125,35129,35130,
+35134,35136,35138,35141,35142,35145,35151,35154,35159,35162,35163,35164,35169,
+35170,35171,35179,35182,35184,35187,35189,35194,35195,35196,35197,35209,35213,
+35216,35220,35221,35227,35228,35231,35232,35237,35248,35252,35253,35254,35255,
+35260,35284,35285,35286,35287,35288,35301,35305,35307,35309,35313,35315,35318,
+35321,35325,35327,35332,35333,35335,35343,35345,35346,35348,35349,35358,35360,
+35362,35364,35366,35371,35372,35375,35381,35383,35389,35390,35392,35395,35397,
+35399,35401,35405,35406,35411,35414,35415,35416,35420,35421,35425,35429,35431,
+35445,35446,35447,35449,35450,35451,35454,35455,35456,35459,35462,35467,35471,
+35472,35474,35478,35479,35481,35487,35495,35497,35502,35503,35507,35510,35511,
+35515,35518,35523,35526,35528,35529,35530,35537,35539,35540,35541,35543,35549,
+35551,35564,35568,35572,35573,35574,35580,35583,35589,35590,35595,35601,35612,
+35614,35615,35594,35629,35632,35639,35644,35650,35651,35652,35653,35654,35656,
+35666,35667,35668,35673,35661,35678,35683,35693,35702,35704,35705,35708,35710,
+35713,35716,35717,35723,35725,35727,35732,35733,35740,35742,35743,35896,35897,
+35901,35902,35909,35911,35913,35915,35919,35921,35923,35924,35927,35928,35931,
+35933,35929,35939,35940,35942,35944,35945,35949,35955,35957,35958,35963,35966,
+35974,35975,35979,35984,35986,35987,35993,35995,35996,36004,36025,36026,36037,
+36038,36041,36043,36047,36054,36053,36057,36061,36065,36072,36076,36079,36080,
+36082,36085,36087,36088,36094,36095,36097,36099,36105,36114,36119,36123,36197,
+36201,36204,36206,36223,36226,36228,36232,36237,36240,36241,36245,36254,36255,
+36256,36262,36267,36268,36271,36274,36277,36279,36281,36283,36288,36293,36294,
+36295,36296,36298,36302,36305,36308,36309,36311,36313,36324,36325,36327,36332,
+36336,36284,36337,36338,36340,36349,36353,36356,36357,36358,36363,36369,36372,
+36374,36384,36385,36386,36387,36390,36391,36401,36403,36406,36407,36408,36409,
+36413,36416,36417,36427,36429,36430,36431,36436,36443,36444,36445,36446,36449,
+36450,36457,36460,36461,36463,36464,36465,36473,36474,36475,36482,36483,36489,
+36496,36498,36501,36506,36507,36509,36510,36514,36519,36521,36525,36526,36531,
+36533,36538,36539,36544,36545,36547,36548,36551,36559,36561,36564,36572,36584,
+36590,36592,36593,36599,36601,36602,36589,36608,36610,36615,36616,36623,36624,
+36630,36631,36632,36638,36640,36641,36643,36645,36647,36648,36652,36653,36654,
+36660,36661,36662,36663,36666,36672,36673,36675,36679,36687,36689,36690,36691,
+36692,36693,36696,36701,36702,36709,36765,36768,36769,36772,36773,36774,36789,
+36790,36792,36798,36800,36801,36806,36810,36811,36813,36816,36818,36819,36821,
+36832,36835,36836,36840,36846,36849,36853,36854,36859,36862,36866,36868,36872,
+36876,36888,36891,36904,36905,36911,36906,36908,36909,36915,36916,36919,36927,
+36931,36932,36940,36955,36957,36962,36966,36967,36972,36976,36980,36985,36997,
+37000,37003,37004,37006,37008,37013,37015,37016,37017,37019,37024,37025,37026,
+37029,37040,37042,37043,37044,37046,37053,37068,37054,37059,37060,37061,37063,
+37064,37077,37079,37080,37081,37084,37085,37087,37093,37074,37110,37099,37103,
+37104,37108,37118,37119,37120,37124,37125,37126,37128,37133,37136,37140,37142,
+37143,37144,37146,37148,37150,37152,37157,37154,37155,37159,37161,37166,37167,
+37169,37172,37174,37175,37177,37178,37180,37181,37187,37191,37192,37199,37203,
+37207,37209,37210,37211,37217,37220,37223,37229,37236,37241,37242,37243,37249,
+37251,37253,37254,37258,37262,37265,37267,37268,37269,37272,37278,37281,37286,
+37288,37292,37293,37294,37296,37297,37298,37299,37302,37307,37308,37309,37311,
+37314,37315,37317,37331,37332,37335,37337,37338,37342,37348,37349,37353,37354,
+37356,37357,37358,37359,37360,37361,37367,37369,37371,37373,37376,37377,37380,
+37381,37382,37383,37385,37386,37388,37392,37394,37395,37398,37400,37404,37405,
+37411,37412,37413,37414,37416,37422,37423,37424,37427,37429,37430,37432,37433,
+37434,37436,37438,37440,37442,37443,37446,37447,37450,37453,37454,37455,37457,
+37464,37465,37468,37469,37472,37473,37477,37479,37480,37481,37486,37487,37488,
+37493,37494,37495,37496,37497,37499,37500,37501,37503,37512,37513,37514,37517,
+37518,37522,37527,37529,37535,37536,37540,37541,37543,37544,37547,37551,37554,
+37558,37560,37562,37563,37564,37565,37567,37568,37569,37570,37571,37573,37574,
+37575,37576,37579,37580,37581,37582,37584,37587,37589,37591,37592,37593,37596,
+37597,37599,37600,37601,37603,37605,37607,37608,37612,37614,37616,37625,37627,
+37631,37632,37634,37640,37645,37649,37652,37653,37660,37661,37662,37663,37665,
+37668,37669,37671,37673,37674,37683,37684,37686,37687,37703,37704,37705,37712,
+37713,37714,37717,37719,37720,37722,37726,37732,37733,37735,37737,37738,37741,
+37743,37744,37745,37747,37748,37750,37754,37757,37759,37760,37761,37762,37768,
+37770,37771,37773,37775,37778,37781,37784,37787,37790,37793,37795,37796,37798,
+37800,37803,37812,37813,37814,37818,37801,37825,37828,37829,37830,37831,37833,
+37834,37835,37836,37837,37843,37849,37852,37854,37855,37858,37862,37863,37881,
+37879,37880,37882,37883,37885,37889,37890,37892,37896,37897,37901,37902,37903,
+37909,37910,37911,37919,37934,37935,37937,37938,37939,37940,37947,37951,37949,
+37955,37957,37960,37962,37964,37973,37977,37980,37983,37985,37987,37992,37995,
+37997,37998,37999,38001,38002,38020,38019,38264,38265,38270,38276,38280,38284,
+38285,38286,38301,38302,38303,38305,38310,38313,38315,38316,38324,38326,38330,
+38333,38335,38342,38344,38345,38347,38352,38353,38354,38355,38361,38362,38365,
+38366,38367,38368,38372,38374,38429,38430,38434,38436,38437,38438,38444,38449,
+38451,38455,38456,38457,38458,38460,38461,38465,38482,38484,38486,38487,38488,
+38497,38510,38516,38523,38524,38526,38527,38529,38530,38531,38532,38537,38545,
+38550,38554,38557,38559,38564,38565,38566,38569,38574,38575,38579,38586,38602,
+38610,23986,38616,38618,38621,38622,38623,38633,38639,38641,38650,38658,38659,
+38661,38665,38682,38683,38685,38689,38690,38691,38696,38705,38707,38721,38723,
+38730,38734,38735,38741,38743,38744,38746,38747,38755,38759,38762,38766,38771,
+38774,38775,38776,38779,38781,38783,38784,38793,38805,38806,38807,38809,38810,
+38814,38815,38818,38828,38830,38833,38834,38837,38838,38840,38841,38842,38844,
+38846,38847,38849,38852,38853,38855,38857,38858,38860,38861,38862,38864,38865,
+38868,38871,38872,38873,38877,38878,38880,38875,38881,38884,38895,38897,38900,
+38903,38904,38906,38919,38922,38937,38925,38926,38932,38934,38940,38942,38944,
+38947,38950,38955,38958,38959,38960,38962,38963,38965,38949,38974,38980,38983,
+38986,38993,38994,38995,38998,38999,39001,39002,39010,39011,39013,39014,39018,
+39020,39083,39085,39086,39088,39092,39095,39096,39098,39099,39103,39106,39109,
+39112,39116,39137,39139,39141,39142,39143,39146,39155,39158,39170,39175,39176,
+39185,39189,39190,39191,39194,39195,39196,39199,39202,39206,39207,39211,39217,
+39218,39219,39220,39221,39225,39226,39227,39228,39232,39233,39238,39239,39240,
+39245,39246,39252,39256,39257,39259,39260,39262,39263,39264,39323,39325,39327,
+39334,39344,39345,39346,39349,39353,39354,39357,39359,39363,39369,39379,39380,
+39385,39386,39388,39390,39399,39402,39403,39404,39408,39412,39413,39417,39421,
+39422,39426,39427,39428,39435,39436,39440,39441,39446,39454,39456,39458,39459,
+39460,39463,39469,39470,39475,39477,39478,39480,39495,39489,39492,39498,39499,
+39500,39502,39505,39508,39510,39517,39594,39596,39598,39599,39602,39604,39605,
+39606,39609,39611,39614,39615,39617,39619,39622,39624,39630,39632,39634,39637,
+39638,39639,39643,39644,39648,39652,39653,39655,39657,39660,39666,39667,39669,
+39673,39674,39677,39679,39680,39681,39682,39683,39684,39685,39688,39689,39691,
+39692,39693,39694,39696,39698,39702,39705,39707,39708,39712,39718,39723,39725,
+39731,39732,39733,39735,39737,39738,39741,39752,39755,39756,39765,39766,39767,
+39771,39774,39777,39779,39781,39782,39784,39786,39787,39788,39789,39790,39795,
+39797,39799,39800,39801,39807,39808,39812,39813,39814,39815,39817,39818,39819,
+39821,39823,39824,39828,39834,39837,39838,39846,39847,39849,39852,39856,39857,
+39858,39863,39864,39867,39868,39870,39871,39873,39879,39880,39886,39888,39895,
+39896,39901,39903,39909,39911,39914,39915,39919,39923,39927,39928,39929,39930,
+39933,39935,39936,39938,39947,39951,39953,39958,39960,39961,39962,39964,39966,
+39970,39971,39974,39975,39976,39977,39978,39985,39989,39990,39991,39997,40001,
+40003,40004,40005,40009,40010,40014,40015,40016,40019,40020,40022,40024,40027,
+40029,40030,40031,40035,40041,40042,40028,40043,40040,40046,40048,40050,40053,
+40055,40059,40166,40178,40183,40185,40203,40194,40209,40215,40216,40220,40221,
+40222,40239,40240,40242,40243,40244,40250,40252,40261,40253,40258,40259,40263,
+40266,40275,40276,40287,40291,40290,40293,40297,40298,40299,40304,40310,40311,
+40315,40316,40318,40323,40324,40326,40330,40333,40334,40338,40339,40341,40342,
+40343,40344,40353,40362,40364,40366,40369,40373,40377,40380,40383,40387,40391,
+40393,40394,40404,40405,40406,40407,40410,40414,40415,40416,40421,40423,40425,
+40427,40430,40432,40435,40436,40446,40458,40450,40455,40462,40464,40465,40466,
+40469,40470,40473,40476,40477,40570,40571,40572,40576,40578,40579,40580,40581,
+40583,40590,40591,40598,40600,40603,40606,40612,40616,40620,40622,40623,40624,
+40627,40628,40629,40646,40648,40651,40661,40671,40676,40679,40684,40685,40686,
+40688,40689,40690,40693,40696,40703,40706,40707,40713,40719,40720,40721,40722,
+40724,40726,40727,40729,40730,40731,40735,40738,40742,40746,40747,40751,40753,
+40754,40756,40759,40761,40762,40764,40765,40767,40769,40771,40772,40773,40774,
+40775,40787,40789,40790,40791,40792,40794,40797,40798,40808,40809,40813,40814,
+40815,40816,40817,40819,40821,40826,40829,40847,40848,40849,40850,40852,40854,
+40855,40862,40865,40866,40867,40869,
+};
+
+static const struct dbcs_index jisx0212_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0212_decmap+0,47,113},{0,0,0},{
+0,0,0},{0,0,0},{__jisx0212_decmap+67,97,124},{__jisx0212_decmap+95,66,126},{0,
+0,0},{__jisx0212_decmap+156,33,80},{__jisx0212_decmap+204,33,119},{
+__jisx0212_decmap+291,33,119},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0212_decmap+378,33,126},{__jisx0212_decmap+472,33,126},{
+__jisx0212_decmap+566,33,126},{__jisx0212_decmap+660,33,126},{
+__jisx0212_decmap+754,33,126},{__jisx0212_decmap+848,33,126},{
+__jisx0212_decmap+942,33,126},{__jisx0212_decmap+1036,33,126},{
+__jisx0212_decmap+1130,33,126},{__jisx0212_decmap+1224,33,126},{
+__jisx0212_decmap+1318,33,126},{__jisx0212_decmap+1412,33,126},{
+__jisx0212_decmap+1506,33,126},{__jisx0212_decmap+1600,33,126},{
+__jisx0212_decmap+1694,33,126},{__jisx0212_decmap+1788,33,126},{
+__jisx0212_decmap+1882,33,126},{__jisx0212_decmap+1976,33,126},{
+__jisx0212_decmap+2070,33,126},{__jisx0212_decmap+2164,33,126},{
+__jisx0212_decmap+2258,33,126},{__jisx0212_decmap+2352,33,126},{
+__jisx0212_decmap+2446,33,126},{__jisx0212_decmap+2540,33,126},{
+__jisx0212_decmap+2634,33,126},{__jisx0212_decmap+2728,33,126},{
+__jisx0212_decmap+2822,33,126},{__jisx0212_decmap+2916,33,126},{
+__jisx0212_decmap+3010,33,126},{__jisx0212_decmap+3104,33,126},{
+__jisx0212_decmap+3198,33,126},{__jisx0212_decmap+3292,33,126},{
+__jisx0212_decmap+3386,33,126},{__jisx0212_decmap+3480,33,126},{
+__jisx0212_decmap+3574,33,126},{__jisx0212_decmap+3668,33,126},{
+__jisx0212_decmap+3762,33,126},{__jisx0212_decmap+3856,33,126},{
+__jisx0212_decmap+3950,33,126},{__jisx0212_decmap+4044,33,126},{
+__jisx0212_decmap+4138,33,126},{__jisx0212_decmap+4232,33,126},{
+__jisx0212_decmap+4326,33,126},{__jisx0212_decmap+4420,33,126},{
+__jisx0212_decmap+4514,33,126},{__jisx0212_decmap+4608,33,126},{
+__jisx0212_decmap+4702,33,126},{__jisx0212_decmap+4796,33,126},{
+__jisx0212_decmap+4890,33,126},{__jisx0212_decmap+4984,33,126},{
+__jisx0212_decmap+5078,33,126},{__jisx0212_decmap+5172,33,126},{
+__jisx0212_decmap+5266,33,126},{__jisx0212_decmap+5360,33,126},{
+__jisx0212_decmap+5454,33,126},{__jisx0212_decmap+5548,33,126},{
+__jisx0212_decmap+5642,33,126},{__jisx0212_decmap+5736,33,126},{
+__jisx0212_decmap+5830,33,126},{__jisx0212_decmap+5924,33,126},{
+__jisx0212_decmap+6018,33,126},{__jisx0212_decmap+6112,33,99},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __jisxcommon_encmap[22016] = {
+8512,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41527,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538,
+8561,8562,41584,N,41539,8568,8495,41581,41580,N,8780,N,41582,41524,8555,8542,
+N,N,8493,N,8825,N,41521,N,41579,N,N,N,N,41540,43554,43553,43556,43562,43555,
+43561,43297,43566,43570,43569,43572,43571,43584,43583,43586,43585,N,43600,
+43602,43601,43604,43608,43603,8543,43308,43619,43618,43621,43620,43634,43312,
+43342,43810,43809,43812,43818,43811,43817,43329,43822,43826,43825,43828,43827,
+43840,43839,43842,43841,43331,43856,43858,43857,43860,43864,43859,8544,43340,
+43875,43874,43877,43876,43890,43344,43891,43559,43815,43557,43813,43560,43816,
+43563,43819,43564,43820,43567,43823,43565,43821,43568,43824,43298,43330,43575,
+43831,N,N,43574,43830,43576,43832,43573,43829,43578,43834,43579,43835,43581,
+43837,43580,N,43582,43838,43300,43332,43591,43847,43589,43845,N,N,43590,43846,
+43588,43333,43302,43334,43592,43848,43593,43849,43335,43594,43850,43596,43852,
+43595,43851,43305,43337,43304,43336,43597,43853,43599,43855,43598,43854,43338,
+43307,43339,43607,43863,N,N,43606,43862,43309,43341,43609,43865,43611,43867,
+43610,43866,43612,43868,43613,43869,43615,43871,43614,43870,43617,43873,43616,
+43872,43311,43343,43628,43884,43625,43881,43622,43878,43627,43883,43624,43880,
+43626,43882,43633,43889,43636,43892,43635,43637,43893,43639,43895,43638,43894,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43558,43814,43587,43843,43605,43861,43623,43879,43632,43888,43629,43885,43631,
+43887,43630,43886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43833,41520,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41519,41522,41526,41525,N,41523,41528,41529,
+42593,N,42594,42595,42596,N,42599,N,42601,42604,42614,9761,9762,9763,9764,
+9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779,
+9780,9781,9782,9783,9784,42597,42602,42609,42610,42611,42612,42619,9793,9794,
+9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,
+42616,9810,9811,9812,9813,9814,9815,9816,42613,42618,42615,42617,42620,10023,
+42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,N,42829,
+42830,10017,10018,10019,10020,10021,10022,10024,10025,10026,10027,10028,10029,
+10030,10031,10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,
+10043,10044,10045,10046,10047,10048,10049,10065,10066,10067,10068,10069,10070,
+10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,10082,10083,10084,
+10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,
+N,10071,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,N,
+42877,42878,8510,N,N,N,N,8509,8514,N,8518,8519,N,N,8520,8521,N,N,8823,8824,N,
+N,N,8517,8516,N,N,N,N,N,N,N,N,N,8819,N,8556,8557,N,N,N,N,N,N,N,8744,8558,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,41583,N,N,N,N,N,N,
+N,N,8818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8747,8748,8746,8749,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8781,N,8782,8783,N,8799,8784,N,N,N,
+8800,8762,N,N,8763,N,N,N,N,N,N,8541,N,N,N,N,N,N,N,8805,N,N,8807,8551,N,8796,N,
+N,N,N,N,N,8778,8779,8769,8768,8809,8810,N,N,N,N,N,N,N,8552,8808,N,N,N,N,N,N,N,
+8806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8802,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8546,8801,N,N,N,N,8549,8550,N,N,8803,8804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,8766,8767,N,N,8764,8765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,8797,8798,10273,10284,10274,10285,N,N,N,N,N,N,N,N,10275,N,N,10286,
+10276,N,N,10287,10278,N,N,10289,10277,N,N,10288,10279,10300,N,N,10295,N,N,
+10290,10281,10302,N,N,10297,N,N,10292,10280,N,N,10296,10301,N,N,10291,10282,N,
+N,10298,10303,N,N,10293,10283,N,N,10299,N,N,10304,N,N,N,N,N,N,N,N,10294,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,8739,8738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8741,8740,N,N,N,N,N,N,N,N,
+8743,8742,N,N,N,N,N,N,N,N,8737,8574,N,N,N,8571,N,N,8573,8572,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8830,8570,8569,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,8554,N,8553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8822,N,N,8821,N,8820,8481,8482,8483,8503,N,
+8505,8506,8507,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8745,8750,
+8524,8525,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,
+9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,
+9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,
+9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,
+9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,
+9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N,N,
+8491,8492,8501,8502,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,
+9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,
+9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,
+9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,
+9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,
+9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,
+9590,N,N,N,N,8486,8508,8499,8500,12396,17274,45089,15415,45090,45091,N,19324,
+15974,15152,15973,12860,45092,18772,19775,N,20514,12591,45093,N,13166,20515,
+16420,21058,13654,19002,N,N,N,N,15975,45094,N,20030,N,45095,45096,N,19010,N,
+45097,N,20516,45098,N,17254,45099,45100,45101,20517,13946,N,N,45102,20518,N,
+13405,17200,N,15463,20519,N,N,20520,45103,45104,20521,18229,45105,13655,N,
+45106,N,N,N,18231,N,18019,14403,19251,N,45107,N,N,N,26953,20522,15976,20523,
+12853,45108,N,45109,13925,14448,19561,N,N,22054,45110,N,N,N,N,45111,45112,N,N,
+N,N,N,N,N,19824,N,18045,45113,45114,N,N,N,45115,N,N,N,N,13349,45116,13621,N,
+20524,N,N,20525,20027,N,19773,16744,20527,15222,18035,45117,20530,N,N,12606,
+14431,N,14430,12390,45118,45119,20299,20298,N,14899,12321,45120,20531,20532,
+20533,19252,20534,N,14450,12391,19314,N,13692,N,N,13693,13694,17506,20028,
+45121,20535,N,N,20536,N,N,20537,N,N,45122,16205,N,N,N,N,N,15674,16206,20542,
+45123,20540,N,20541,13656,N,N,14883,12912,N,20539,20538,18985,45124,N,N,N,
+15174,15173,16958,20543,18773,16487,45125,45126,N,8504,20544,20546,45127,
+45128,45129,16997,20065,12362,N,N,45130,N,N,N,N,20545,12862,45131,13892,45132,
+17255,45133,N,45134,14191,20547,N,N,N,18212,N,45135,45136,45137,45138,13419,
+45139,45140,N,N,N,N,45141,20548,12363,45142,45143,14432,13420,18810,18482,
+13657,45144,N,N,45145,45146,45147,N,45148,12913,N,20583,17729,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,45149,18284,20550,45150,N,45152,18492,45153,20066,45154,16173,
+45155,15175,45156,15223,12864,45157,N,45158,N,45159,17489,N,N,17186,20554,
+45160,45161,N,45162,45163,12364,17507,15675,14900,19748,45164,16974,45165,
+12863,45166,20553,45167,19774,20549,20551,14958,20552,21796,45168,45151,N,N,
+45169,N,N,N,N,N,20560,45170,N,45171,N,45172,20563,20561,45173,N,12866,N,19003,
+20555,45174,45175,45176,45177,20559,14451,45178,45179,15176,N,45180,45181,
+13350,45182,45345,20564,N,20556,45346,45347,20067,45348,15224,45349,20557,
+45350,20562,45351,45352,45353,N,20565,45354,20558,45355,45356,13857,N,12365,
+45357,45358,13858,12865,N,N,N,N,N,N,N,N,N,21797,N,19321,18798,14452,N,N,45359,
+N,N,16175,20023,45360,N,45361,N,45362,45363,45364,45365,19032,45366,45367,
+14136,16933,12900,45368,45369,N,45370,45371,15699,45372,45373,45374,20569,
+45375,20574,20572,45376,N,20567,N,N,16943,20570,N,20573,20571,45377,19037,N,
+20568,45378,16174,45379,19315,20575,20576,N,N,N,N,N,N,N,N,15652,20589,45380,N,
+45381,18256,N,18742,20584,N,19056,N,12854,N,45382,45383,20588,45384,45385,
+45386,N,N,45387,20582,20591,45388,N,16722,45389,14404,45390,18268,45391,24647,
+45392,20590,17757,45393,20579,N,14454,45394,45395,14453,20577,45396,45397,
+45398,45399,15450,N,20585,45400,19055,17229,20581,14193,45401,20578,20586,
+20580,20049,20587,20289,45402,N,45403,N,45404,45405,N,45406,13926,N,N,14192,N,
+45430,N,N,N,N,45407,45408,45409,20592,N,45410,45411,20593,20597,12366,45412,N,
+45413,N,45414,19024,20596,45415,45416,45417,N,20595,20599,45418,N,45419,20598,
+N,17508,N,N,45420,45421,N,45422,45423,N,14194,45424,45425,N,N,45426,N,20600,
+45427,N,N,45428,45429,15429,N,16934,17509,13942,N,20601,N,N,N,N,13622,N,N,
+20602,45431,N,45432,45433,20604,45434,N,N,N,45435,N,N,19253,45436,45437,45438,
+14182,45601,45602,45603,N,45604,N,15153,18551,20603,45605,45606,N,45607,45608,
+45609,45610,45611,N,N,N,N,N,N,N,45612,N,14917,19779,N,45613,45614,N,20606,
+20771,20605,14916,N,15741,N,45615,45616,N,N,45617,14137,N,45618,N,20772,45619,
+45620,13903,N,45621,N,20769,20770,N,45622,17967,45623,16764,45624,13859,N,
+45625,45626,19277,20773,N,45627,N,20029,N,45628,45629,20774,45630,N,N,45631,
+20777,45632,20775,45633,16718,45634,45635,N,N,N,20776,20778,45636,N,45637,
+45649,N,N,20780,45638,N,N,20779,45639,19016,N,N,45640,13623,20782,20783,45641,
+12847,N,45642,45643,45644,20781,N,45645,45646,45647,45648,N,45650,N,15476,N,
+20786,20785,20784,45651,20566,45652,20787,45653,45654,45655,45656,15742,N,
+20788,N,45657,N,N,N,45658,45659,N,19749,N,45660,45661,N,45662,N,45663,19545,
+45664,45665,45666,N,20790,45667,45668,20789,20792,20791,N,N,20793,20794,12404,
+45669,14389,14139,15676,17275,13860,16488,14455,45670,14702,20796,19528,17734,
+45671,15225,N,20795,45672,20797,45673,N,45674,45675,N,17758,N,13173,N,N,45676,
+N,N,20798,N,45677,18046,45678,N,16692,20800,20801,18476,14456,20283,20802,N,N,
+13862,N,N,N,19004,16950,13937,17717,N,N,N,14195,N,45679,N,20803,N,20804,45680,
+45681,18018,12639,N,N,20807,14973,45682,20806,14918,45683,20808,26222,20809,
+19265,20810,N,20811,20812,15977,45684,15436,N,N,N,45685,N,N,13351,45686,20815,
+45687,20813,19517,20814,N,18778,20816,20817,20818,17759,45688,N,N,20822,20820,
+20821,20819,14947,20823,19562,20068,45689,N,45690,N,45691,20824,45692,45693,N,
+N,45694,N,16424,20825,15706,N,45857,20826,N,17276,20031,17760,N,45858,N,45859,
+45860,45861,N,45862,21061,N,45863,N,N,20827,29733,13893,45864,N,20828,19294,
+45865,N,N,45866,15720,17020,N,20830,18020,N,N,20831,45867,N,20832,13102,45868,
+45869,45870,20833,13863,45871,17996,12666,15696,N,N,18465,20834,17761,45872,
+45873,16207,20835,45874,18988,16474,13346,N,13353,20836,N,N,20838,N,N,14138,
+45875,45876,20837,45877,45878,20083,45879,N,N,N,N,15721,N,N,N,N,45880,N,18493,
+19020,N,20839,45881,19832,20840,N,N,N,20841,N,17790,45882,45883,20842,N,45884,
+16425,14974,14196,20843,15177,14703,45885,N,N,N,N,N,N,17510,20845,45886,N,
+16935,N,45887,14959,20846,20847,16688,N,20844,N,N,N,N,20849,45888,19254,45889,
+45890,N,45891,14692,45892,N,20848,45893,45894,45895,N,14197,14942,18285,45896,
+N,N,20852,20850,N,N,N,45897,18811,15978,20859,13156,20853,20851,16719,N,45898,
+45899,45900,N,N,N,20855,N,20854,45901,N,45902,13124,N,45903,N,14176,20860,
+20013,45904,N,45905,20856,N,N,N,20861,20858,45906,20857,45907,45908,45909,
+45910,N,45911,20047,45912,N,N,14457,12867,N,N,20084,45913,45914,45915,45916,N,
+15733,17752,14693,21026,21027,N,45917,45918,20069,N,N,20267,21029,45919,45920,
+45921,14458,45922,45923,21028,45924,13103,N,45925,21030,N,19286,45926,17468,
+45927,19750,45928,19033,N,N,45929,21031,N,45930,N,45931,28757,N,45932,17968,
+45933,21032,13354,19507,N,45934,45935,15905,21033,19047,21037,45936,16426,
+21034,13904,45937,21035,13355,45938,45939,45940,N,45941,N,N,N,45942,45943,
+14126,21038,45944,21039,45945,45946,21040,21041,15451,N,N,N,14459,19550,45947,
+19560,18039,45948,N,19057,21042,N,21043,N,45949,45950,46113,21045,N,21047,
+21046,46114,N,46115,N,21048,12861,19276,46116,14972,21049,46117,46118,16729,
+46119,46120,15906,13865,N,21050,N,46121,N,46122,46123,46124,18523,46125,46126,
+46127,N,21051,46128,21052,46129,21053,N,46130,N,N,21054,18724,13928,12389,
+46131,46132,46133,17983,21055,15677,46134,16489,N,21057,21056,15907,14433,
+21059,18494,46136,46135,21060,N,N,N,18524,16948,17006,13864,N,N,18030,17201,
+46137,18286,46138,19278,N,21062,N,16490,46139,N,46140,N,46141,14133,N,N,21063,
+N,N,46142,46143,21064,12588,12405,13421,46144,16936,13649,19825,N,21067,12855,
+46145,N,21066,N,N,46146,13866,N,N,21068,46147,19569,N,N,46148,46149,N,N,N,N,N,
+46150,N,N,N,N,46151,46152,N,21069,N,20050,46153,14460,N,N,46154,N,14390,21070,
+46155,N,N,46156,21072,21071,N,16223,12601,46157,46158,N,12638,21073,46159,
+21074,N,46160,14391,46161,46162,21075,46163,46164,N,46165,13678,N,46166,N,N,
+46167,N,15154,21076,N,46168,N,N,19316,14901,13658,19751,16720,18495,15485,
+46169,N,N,46170,46171,15687,46172,15464,15477,N,15734,46173,18496,N,46174,
+46175,21079,46176,12611,16721,14461,14405,13927,46177,46178,21083,17185,17022,
+13867,15908,21084,21082,12868,16998,15416,15179,12582,N,46179,13168,14694,
+15178,N,21085,21086,46180,13641,13126,N,N,N,14695,13640,17503,12581,17969,
+19518,14625,19833,17735,14462,N,46181,N,N,N,N,N,N,46182,14127,N,21095,N,13923,
+19274,46183,N,N,N,N,18525,46184,46185,21094,46186,13406,21089,21090,21092,
+46187,N,46188,N,N,46189,46190,21093,N,13659,16225,N,18989,21091,21087,14435,N,
+21088,N,20260,46191,46192,N,19058,46193,17512,14434,14704,N,N,46194,21096,
+46195,N,18013,N,N,N,N,N,N,N,N,N,N,N,N,46196,21100,N,N,46197,N,46198,N,46199,
+46200,15486,46201,15478,46202,N,46203,46204,N,21103,21101,N,19491,46205,21098,
+21107,21102,N,N,N,21105,14406,19519,N,46206,21106,46369,N,46370,21108,46371,
+21110,N,46372,46373,N,14960,20290,46374,21099,21097,21109,46375,21104,N,N,
+46376,46377,N,N,N,N,N,46378,N,N,46379,N,46380,21112,N,21283,21114,46381,46382,
+21118,46383,46384,21281,21115,46385,46386,21310,N,46387,14953,13105,N,N,N,
+46388,21113,46389,46390,46391,21285,12406,21284,46392,12325,18762,21282,N,
+21116,N,46393,21111,21117,14920,46394,N,N,46395,46396,N,N,N,N,N,N,N,N,N,21286,
+N,N,N,N,N,N,N,46397,12407,21295,N,N,21287,21288,N,15909,19305,46398,N,46399,
+21293,21292,46400,N,N,17711,N,N,N,46401,N,N,N,21294,N,46402,21291,46403,46404,
+46405,46406,N,N,12596,46407,14902,16176,46408,46409,N,N,46410,46411,46412,
+21289,17762,N,N,N,21290,46413,12322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+46414,46415,N,N,21300,19747,N,15911,46416,21306,N,46417,46418,N,21305,21296,N,
+46419,46420,46421,16963,N,21297,46422,N,N,17007,21302,15910,46423,N,46424,
+46425,N,21299,46426,N,19556,46427,46428,N,14140,N,N,21303,21304,46429,N,46430,
+46431,21301,21307,46432,N,46433,46434,N,21298,46435,N,46436,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,21313,21318,N,21314,46437,21309,46438,46439,21319,16689,
+N,46440,21321,46441,14626,21311,17277,N,N,46442,46443,N,46444,46445,46446,
+46447,N,N,46448,21315,21308,13357,N,13422,13157,21316,21312,N,N,N,46449,46450,
+N,N,14198,21322,21320,16723,13642,13868,46451,21317,N,13940,N,46452,N,N,N,
+12612,N,N,N,N,N,N,N,N,46453,N,46454,N,46455,21326,21324,46456,21543,N,46457,N,
+46458,46459,N,46460,N,N,46461,46462,46625,21329,N,N,46626,46627,N,21323,46628,
+21327,N,46629,21325,N,N,46630,15180,21328,N,N,N,N,46631,N,N,N,N,N,N,N,N,N,N,N,
+N,46632,21331,N,21336,N,N,N,21334,21333,46633,46634,17202,N,46635,12869,46636,
+N,N,46637,46638,46639,46640,46641,46642,N,21330,N,21332,15912,12595,46643,N,
+21335,N,N,N,N,N,N,N,N,N,N,N,N,N,12894,N,N,46644,N,N,21346,46645,15996,21342,
+46646,21340,46647,21341,46648,21343,46649,N,46650,46651,46652,N,46653,46654,
+46655,12605,46656,46657,N,46658,N,N,46659,N,46660,16697,46661,21337,46662,
+21338,N,N,N,46663,N,N,N,N,N,N,13178,N,N,46664,N,46665,46666,46667,46668,21345,
+N,46669,N,13423,46670,21348,21344,21347,46671,N,46672,N,46673,46674,N,18990,
+46675,N,N,18005,N,18488,N,N,N,N,N,21350,N,N,N,46676,46677,21349,13125,46678,N,
+21351,46679,46680,N,N,21354,N,N,N,N,21353,46681,N,N,N,46682,46683,N,N,46684,
+46685,46686,21352,N,18233,N,N,21355,46687,46688,46689,46690,N,46691,46692,
+46693,21356,N,N,46694,N,46695,21358,N,21357,46696,N,N,N,N,21360,N,46697,N,
+21363,21361,21359,21362,N,46698,N,N,21364,46699,46700,46701,46704,46705,21365,
+46702,46703,21366,N,21367,N,N,N,21368,20805,46706,15484,15181,46707,46708,
+12915,46709,12408,46710,N,17220,46711,46712,46713,46714,46715,N,N,46717,N,
+46718,21369,N,14884,46716,12367,16222,N,N,46881,46882,N,21370,14407,N,N,14705,
+N,21372,21371,46883,46884,19040,21373,N,N,46885,21537,21374,46886,21538,46887,
+21539,N,14199,N,46888,12640,21540,N,46889,21542,N,21541,N,46890,46891,21544,
+46892,N,17754,46893,N,46894,46895,46896,46897,21545,12341,14943,46898,46899,N,
+46900,14141,46901,46902,17231,N,N,46903,46904,N,N,21546,21547,N,N,21549,N,
+46905,46906,46907,21550,N,14948,N,N,46908,46909,13905,N,N,19255,N,46910,46911,
+21548,21551,14913,14627,46912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21555,46913,N,14885,
+46914,17203,46915,46916,21552,17498,46917,N,46918,46919,46920,46921,46922,N,
+46923,46924,46925,N,46926,N,46927,46928,46929,46930,N,46931,21556,N,46932,
+16226,46933,N,N,N,N,21554,21557,N,14143,46934,N,N,N,N,N,N,21558,46935,46944,N,
+46936,N,46937,46938,N,46939,46940,46941,46942,21559,46943,14628,13120,21561,N,
+N,46945,46946,46947,21562,N,46948,N,N,N,21563,N,N,21560,N,N,N,N,46949,N,N,N,N,
+46950,N,N,21553,N,N,21564,N,N,21565,46951,46952,N,N,19300,46953,N,15979,46954,
+N,N,21567,21568,21566,46955,21570,N,N,N,N,N,18232,46956,46957,12392,18774,
+46974,N,21571,46958,N,46959,46960,N,46961,N,N,N,46962,N,N,46963,N,N,N,15997,
+46964,46965,15417,46966,18269,13424,N,14955,46967,46968,46969,19289,N,17970,
+46970,46971,14200,16975,N,46972,46973,21569,21572,47137,47138,N,N,N,N,N,N,N,
+16964,N,N,N,21573,N,47139,N,21574,47140,47141,47142,21576,N,N,17513,N,47143,
+47144,N,N,13358,N,N,47145,N,29729,12641,19059,47146,N,15980,17736,N,N,N,47147,
+14950,N,N,21582,N,47148,19005,20061,N,N,N,N,N,N,N,47149,12916,21578,47150,
+47151,N,47152,47153,16698,21581,N,17763,47154,N,17737,17764,18489,17485,N,N,N,
+14921,47155,N,47156,21577,N,47157,N,N,47158,47159,12662,N,17718,N,N,N,N,21579,
+N,21575,N,N,16208,N,N,47160,21583,N,N,47161,N,15694,47162,47163,47164,N,13869,
+N,21584,N,47165,47166,47167,47168,N,47169,47170,N,47171,47172,N,N,19048,47173,
+N,47174,16765,N,N,N,N,17478,47175,N,21586,47176,47177,47178,N,N,N,47179,N,
+19279,47180,N,21587,N,N,21592,N,N,47181,47182,18991,N,N,N,N,21591,21585,21588,
+21590,47184,N,14886,N,N,19017,47185,N,47183,21593,N,17221,47186,N,12917,N,
+15981,47187,47188,N,47189,21595,47190,21594,47191,14696,47192,21596,21598,
+21597,47193,N,21600,47194,21589,21602,N,47195,47196,N,21601,21599,N,N,N,47197,
+N,15182,16209,N,16724,21603,16444,12397,18276,47198,N,N,N,17499,N,21605,21604,
+21606,21607,21608,21609,N,N,47199,47200,N,N,19025,21610,47201,47202,N,N,12870,
+21611,N,47203,47204,47205,19772,13104,N,21065,15688,16959,21612,19563,47207,N,
+N,N,47208,19508,47209,47210,21614,N,16999,47211,17719,16960,18775,21615,21616,
+12667,47212,47213,15418,21617,47214,N,47215,47216,12368,21618,N,N,N,N,N,21619,
+47217,N,N,N,47218,12642,N,47219,13425,18016,19060,N,N,N,N,21623,16725,21622,
+14144,47220,47221,19291,21621,N,17765,21625,47222,21624,47223,N,47224,47225,
+47226,21627,47227,21626,47228,N,12668,N,21628,15913,21630,17189,47229,21629,
+47230,18995,47393,N,N,47394,15735,17755,47395,47396,N,21793,47397,N,47398,
+47399,14629,N,N,N,21794,18209,18526,19537,N,N,N,N,N,18213,47400,47401,21803,
+47402,N,N,N,47403,13624,N,47404,19781,47405,N,19503,N,22060,N,21795,N,47406,N,
+N,N,21798,47407,16965,N,47408,19256,N,N,N,17738,47409,47410,47411,47412,N,
+21799,47413,N,N,N,47414,N,19301,47415,14922,47416,N,15914,N,N,47417,N,47418,
+47419,N,21800,N,47420,15184,47421,15183,N,47422,N,N,12345,14408,47423,16427,
+12369,N,N,N,N,21804,21805,N,21802,47424,47425,47426,N,N,N,47427,47428,12600,
+13359,47429,21801,N,19525,18737,N,N,47430,47431,N,47432,47433,N,47434,N,12328,
+47435,N,N,N,12409,N,N,N,15185,47436,12370,N,12323,47437,N,N,N,N,21810,N,N,
+47438,47439,47440,N,N,21808,47441,47442,N,N,N,N,19516,N,21811,N,21809,N,47443,
+21807,16177,N,N,47444,47445,21806,N,47446,47447,19034,47448,N,N,47449,N,14436,
+47450,N,N,N,N,21815,21816,N,N,N,N,N,15915,N,N,N,21812,20268,N,N,47451,47452,
+18252,47453,47454,21814,N,N,47455,N,N,N,47456,N,N,N,N,47457,N,N,N,N,14887,N,N,
+N,47458,N,N,N,21817,47459,N,47460,18776,47461,N,N,21818,N,21813,47462,N,N,N,N,
+N,N,N,N,N,47463,N,N,47464,47465,N,N,47466,19515,N,N,N,N,N,N,N,N,N,N,N,47467,N,
+N,N,N,47468,N,18270,47469,N,N,47470,N,N,47471,21819,18738,47472,N,47473,47474,
+47475,N,47476,N,N,N,N,47477,N,N,N,N,47478,N,N,N,N,47479,47480,47481,N,47482,N,
+N,47483,N,47484,47485,21820,21824,21821,47486,N,12871,21823,N,47649,N,47650,N,
+47651,15419,N,21822,14201,N,N,47652,21836,N,N,N,N,N,21829,21826,N,N,47653,N,
+47654,N,N,N,47655,17252,N,21825,N,47656,21827,N,N,21828,47657,N,N,N,47658,N,N,
+N,N,N,N,47659,47660,N,N,N,21830,21831,N,47661,47662,47663,N,N,N,N,N,N,47664,
+13426,N,21833,21832,N,N,N,N,N,N,N,N,N,21834,47665,N,47667,N,47668,N,47669,N,N,
+N,47670,15982,N,N,47671,N,N,N,N,21837,N,17500,47672,N,N,12613,N,21835,N,47666,
+N,21838,N,47673,N,N,N,N,N,21839,N,21842,47674,N,21840,N,21841,N,N,N,N,N,47675,
+47676,N,N,N,15186,21843,47677,N,14630,21844,47678,15226,16952,N,21845,21846,
+15194,14631,47679,19538,N,N,N,13608,14409,21847,13144,N,47680,21848,N,16953,N,
+N,47681,47682,21849,22051,N,21850,N,21851,N,N,21852,N,21854,N,47683,47684,
+47685,47686,21855,47687,N,21856,47688,17008,47689,12583,15465,12354,47690,
+16727,13360,15413,47691,14632,47692,47693,N,47694,47695,17766,47696,15649,
+13361,17256,17514,12344,13625,19061,N,15426,N,N,13650,16491,15420,19752,21857,
+N,47697,47698,N,N,47699,47700,13660,47701,14923,47702,47703,13106,12643,15916,
+12872,47704,21858,19782,47705,N,47706,N,N,15689,47707,47708,15460,21859,13427,
+18002,19497,21860,N,21861,N,N,18777,47709,N,47710,21863,N,13352,13943,21862,N,
+47711,47712,47713,47714,47715,13362,N,16178,21867,15137,47716,12873,21866,N,
+21864,21868,21865,18219,23629,16179,N,21869,N,N,20032,47717,21870,47718,N,
+21872,47719,17278,21871,N,16419,N,15227,N,N,47720,16976,15479,18805,16492,N,
+15437,21873,15917,21874,21875,12371,16954,16210,47721,21876,17971,15918,N,
+15919,N,21877,N,N,16493,47722,N,N,15920,N,N,N,47723,47724,21878,N,21879,47725,
+19552,N,47726,N,21880,47727,N,47728,47729,13894,47730,N,47731,15650,47732,N,N,
+47733,47734,N,21881,21882,15452,16172,18036,16212,18552,18210,13897,21883,N,N,
+N,13679,21884,N,13950,N,17999,12848,N,15187,21885,22050,22049,13949,N,21886,N,
+17720,N,N,N,47735,47736,N,47737,N,16944,N,17739,15432,47738,47739,16728,19834,
+N,47740,47741,47742,N,N,22052,47905,22053,18006,47906,15155,N,N,47907,47908,
+22055,N,N,22056,47909,47910,47911,47912,N,N,N,N,N,N,N,N,N,47913,47914,N,47915,
+N,22057,N,N,47916,13428,22058,47917,N,22059,N,N,N,N,N,N,N,N,47918,N,47919,
+47920,12844,47921,47922,N,N,47923,N,16699,13412,47924,22061,19496,N,N,N,N,
+16978,47925,13145,47926,47927,22063,22065,13407,N,47928,22062,22064,N,22067,N,
+N,N,N,N,N,22066,N,22068,N,47929,N,47930,N,N,N,N,N,N,47931,N,N,N,N,47933,N,
+22069,N,N,N,47932,N,N,17981,13870,N,N,N,N,N,N,12901,22070,22075,N,N,22073,
+47934,19063,19062,47935,47936,N,47937,N,17767,N,N,N,22072,15700,N,22071,47938,
+N,N,N,N,47939,16242,N,N,N,22076,N,47940,14954,N,N,22082,47941,N,22083,22077,
+13107,22078,22087,22086,22085,22081,N,N,N,22080,N,N,22084,47943,47944,N,47945,
+47946,N,19064,N,47942,N,N,N,N,N,47947,N,N,47948,N,N,N,N,47949,N,N,N,47950,N,
+47951,N,N,47952,47953,N,N,47954,N,47955,N,47959,22091,22088,N,22090,N,19826,
+47957,22089,N,N,47956,N,N,N,47958,N,N,22079,N,N,47960,47961,47962,47963,N,
+47964,N,N,N,N,16243,47965,N,22092,47966,N,14903,47967,N,N,22093,N,N,22094,N,N,
+47968,47969,N,N,N,47970,47971,N,47972,22097,47973,22096,N,N,22095,47974,N,
+47975,17768,22074,N,N,N,22103,N,47976,47977,47978,47979,N,N,N,47980,N,47981,N,
+22099,N,47982,47983,N,22098,N,N,N,N,47984,N,N,N,47985,22100,N,22101,N,47986,N,
+58996,N,47987,N,N,22104,47988,47989,20070,N,22105,22102,N,N,N,N,N,47990,N,N,N,
+47991,N,22106,N,47992,13408,22107,47994,N,47993,N,22109,22108,N,N,22110,N,
+47995,47996,N,22111,N,16494,15651,N,47997,15716,N,16739,47998,14633,14904,
+14634,13680,48161,N,22112,N,N,14905,N,N,14410,22113,19494,18243,22114,N,14635,
+48162,48163,N,13356,N,17191,13906,48164,N,15188,18779,N,N,18497,48165,N,N,N,
+22115,13429,48166,N,N,N,22118,48167,N,48168,48169,17441,N,48170,22117,22116,
+22119,N,17515,N,48171,48172,N,N,N,N,16227,N,N,48174,N,N,15189,N,16458,48173,
+16979,13602,N,48175,17442,N,48176,22120,22121,15983,N,N,N,N,19257,48177,N,
+22124,N,N,22123,22122,18813,N,22131,N,48180,N,48178,19290,N,22125,N,48179,
+48181,N,N,22127,19307,48182,22126,48183,N,N,48184,48185,N,48186,22128,N,18472,
+22129,19006,22130,N,N,N,48187,N,48188,48189,48190,48191,48192,N,48193,N,13363,
+19007,18223,22132,22133,N,14636,13364,22134,14392,19780,19753,13430,22136,
+48194,17443,N,14637,15921,N,N,18527,N,N,15922,48195,N,N,48196,15736,N,N,N,N,N,
+17516,19065,17721,N,N,14638,N,18780,N,N,N,22137,N,48197,N,48198,48199,17753,
+14914,48200,N,48201,14411,48202,17517,N,N,N,48203,N,48204,N,12355,15726,14639,
+19783,N,N,N,N,48205,48206,48207,N,22138,22139,18257,N,N,48208,N,22140,20087,
+20269,48210,48209,N,48211,22142,22141,48212,48213,13127,48214,48215,22305,N,N,
+N,22308,22309,48216,22307,48217,18752,15923,22311,22310,22306,N,48218,N,N,
+22312,22313,N,48219,22314,N,N,N,22317,22315,N,22316,22318,N,12644,17518,22319,
+N,14202,12918,18230,N,22320,18043,19035,48220,22321,20270,N,48221,48222,48223,
+22322,19008,22325,20513,20529,48224,15408,18037,22326,N,13661,17444,12410,
+22327,18982,14640,48225,N,17232,48226,48227,N,17519,N,48228,48229,48230,48231,
+19567,14393,14412,48232,22328,N,48233,48234,22329,48235,22335,48236,15461,N,N,
+48237,17445,48238,13871,22330,N,N,48239,18731,48240,17222,48241,48242,22331,N,
+N,48243,48244,N,48245,22332,N,13872,N,22333,48246,22334,N,48247,22336,N,17782,
+48248,N,22337,22338,48249,22339,N,48250,22324,22323,N,N,48251,22340,14145,
+48252,48253,N,18727,48254,N,14924,18743,17446,18763,22341,N,48417,15924,12614,
+48418,22342,48419,48420,N,22343,48421,19570,48422,N,18528,48423,48424,22346,
+12669,16428,22345,22344,14146,16980,N,22350,22348,48425,22347,20007,14437,
+48426,N,48427,15737,22349,17740,15678,N,N,48428,17984,22353,22352,N,N,48429,
+48430,22351,N,22354,14438,48431,N,48434,N,N,48432,22355,18812,15707,48433,
+48435,22356,18553,48436,48437,48438,N,17985,17447,N,N,N,48439,17712,N,N,22357,
+13611,N,N,N,N,N,16180,48440,18732,N,48441,48442,48443,N,48444,13431,18214,N,N,
+48445,48446,48447,48448,48449,N,22358,15190,19258,19259,N,N,12670,22363,48450,
+N,17257,48451,48452,N,22360,N,N,N,48453,48454,48455,12919,48456,48457,48458,
+48459,22573,22362,48460,48461,N,18224,48462,N,22361,N,48463,22359,48464,14714,
+N,22365,48465,N,N,48466,N,N,48467,22371,22377,22369,N,17756,48468,48469,22374,
+18781,48470,48471,22368,48472,22373,20071,15191,N,48473,16981,22366,N,N,48474,
+13662,22376,16429,12645,22370,12920,22375,N,48475,N,13873,N,22372,N,48476,N,
+48477,N,N,N,N,22378,N,N,N,N,N,48478,22380,22390,22388,N,N,22385,48479,48480,
+48481,22384,20088,48482,22386,N,N,13874,48483,14641,N,48484,15738,48485,48486,
+N,22393,22379,N,N,48487,N,22383,22367,48488,12922,22387,22389,17233,N,48489,
+14888,12856,22381,22392,22391,13875,N,16937,13158,48490,N,N,N,14147,N,22382,N,
+N,N,N,N,N,48491,48492,N,22394,48493,22397,22561,N,48494,N,48495,15421,48496,
+22567,17520,22395,48497,N,N,48498,22565,48499,12921,48500,22563,22564,48501,N,
+22398,22562,N,48502,48503,14439,19754,N,48504,13365,48505,48506,12633,22566,
+48507,18234,12333,N,N,N,N,N,48508,48509,18529,22364,22572,22576,19557,48510,
+22569,N,N,48673,17769,22574,48674,N,N,N,48675,N,48676,15984,22575,18007,48677,
+48678,48679,48680,N,N,48681,48682,N,20295,N,22571,48683,48684,N,N,22577,48685,
+14715,48686,16459,48687,48688,12372,22570,22568,48689,16730,N,48690,N,22396,
+15156,N,N,N,N,N,N,N,16966,22589,48691,16731,22584,48692,22581,22582,48693,
+15462,22585,22588,48694,48695,22583,15653,48696,22586,N,N,22580,48697,19580,
+19579,48698,N,48699,22590,22591,12373,48700,48701,48702,48703,48704,22579,
+48705,48706,N,48707,13938,12326,48708,N,48709,13366,N,22587,48710,N,N,N,N,
+22595,22594,N,48711,48712,22599,N,N,N,48713,48714,N,N,22600,48715,48716,48717,
+N,48718,N,N,22598,22601,22593,22597,N,48719,22602,N,22603,48720,48721,22592,
+15228,48722,22596,16982,14642,22578,16181,N,N,N,N,22616,N,19049,N,N,22606,
+22607,22608,N,N,22615,48723,22614,48724,N,19325,13367,N,22612,N,14149,13108,N,
+N,22609,48725,N,20024,22611,12374,22613,48726,22604,22610,22617,14148,22605,
+48727,N,N,48728,48729,N,19805,48730,48731,48732,19755,48733,48734,N,N,22620,N,
+N,22624,48735,N,48736,16766,N,20089,22625,48737,48738,22622,N,22619,48739,
+48740,22618,22623,N,48741,48742,N,48743,48744,N,N,N,18992,48745,N,17972,48746,
+14150,48747,22626,22621,48748,22627,N,N,N,14203,N,N,N,12849,N,48749,48750,
+22635,N,48751,N,13368,N,48752,48753,48754,22633,N,N,22634,14889,22632,22630,
+22629,22636,22628,22638,48755,48756,12923,N,N,N,N,48757,N,N,N,N,N,N,48758,
+48759,48760,48761,N,48762,48763,22640,N,48766,22639,48764,N,48765,N,N,48929,
+48930,N,48931,N,N,17448,N,22643,N,22641,22631,14204,N,22642,N,22646,22645,
+22647,22644,22648,48932,N,48933,48934,N,N,48935,22649,22650,19050,N,22652,
+22651,15679,N,16430,12902,12924,48936,22653,48937,12351,N,N,N,16460,22654,
+48938,27715,22817,14177,48939,22818,48940,48941,N,N,16495,48942,N,48943,22819,
+48944,N,N,22820,13626,22821,N,22822,22823,16983,N,N,N,14413,48945,N,19553,N,
+48946,N,19260,15722,22824,48947,48948,48949,N,48950,16496,28221,18530,N,15466,
+48951,14925,22825,N,48952,48953,48954,16967,48955,18983,48956,N,17009,N,48957,
+22828,48958,N,22826,N,22829,N,N,22827,48959,N,N,N,22830,N,N,N,N,48960,18993,
+48961,N,12343,N,48962,N,N,18782,N,N,18531,48963,N,22831,48964,22834,15925,
+13627,N,22832,22839,15926,N,N,N,N,22833,18244,N,N,48965,48966,48967,48968,
+19806,22835,22836,22840,17770,22837,14643,16478,N,N,22854,18484,N,17010,N,N,N,
+N,N,N,N,48969,N,48970,N,N,18532,23085,N,N,N,N,19066,N,48971,N,17521,48972,
+48973,N,19317,48974,22843,12833,17258,48975,48976,N,N,22852,N,48977,17204,
+22846,22853,22848,22855,22851,N,22850,18287,48978,22844,12925,22842,13681,
+17011,22838,48979,48980,22841,14644,16475,48981,15927,22849,18258,N,N,13682,
+13128,N,N,N,N,N,N,N,N,48982,N,13159,16161,22857,22862,N,22858,48983,14205,
+48984,22863,15138,14697,N,N,N,N,48985,48986,15654,22845,15229,22860,48987,
+48988,N,N,15192,22861,12356,48989,48990,22856,48991,N,N,48992,17449,N,48993,N,
+N,48994,N,48995,13683,N,N,N,N,N,13876,N,N,N,N,N,N,N,22859,12327,48996,48997,
+14915,N,48998,N,16182,N,N,N,N,N,48999,49000,N,N,49001,17522,N,49002,18516,
+22865,16734,N,49003,49004,49005,49006,N,49007,N,N,16938,49008,49009,15147,
+22866,49010,22868,22864,N,49011,49012,49013,19041,N,17469,49014,N,N,49015,
+16732,N,N,N,N,N,N,N,N,49016,49017,19067,15438,22880,N,22879,49018,49019,16248,
+N,N,49020,14206,N,49021,49022,22873,15929,49185,N,18024,18225,49186,49187,N,
+49188,22871,N,49189,16733,49190,N,N,49191,15480,22876,49192,N,15928,N,22870,
+22875,49193,N,18259,N,49194,49195,22869,N,14113,49196,49197,13149,N,N,49198,
+22877,20011,14926,17205,22874,49199,16476,49200,14645,16228,12646,16700,22872,
+13637,49201,49202,49203,N,N,14151,N,17487,22878,N,N,N,N,N,16735,N,49204,22881,
+N,22883,49205,N,16951,22889,49206,22884,N,49207,22886,N,N,N,N,49208,18753,
+17523,49209,22887,49210,49211,49212,19756,N,N,N,19784,13369,49213,N,N,N,49214,
+12334,N,22885,N,49215,N,N,N,22882,49216,N,49217,N,13432,N,N,N,49218,49219,
+12647,49220,22888,N,49221,49222,19785,22892,N,N,49223,49224,N,N,16955,N,22899,
+49225,N,49226,22893,49227,N,22890,22897,49228,N,N,N,22867,N,49229,N,49230,N,
+49231,N,49232,49233,22894,N,22898,49234,49235,N,18498,17771,N,49236,49237,N,N,
+N,22891,49238,22895,N,N,N,14152,N,N,49239,14961,49240,N,N,16477,N,N,N,N,N,N,N,
+N,49241,N,N,22903,49242,N,49243,49244,49245,49246,N,N,N,17702,N,49247,49248,
+49249,49250,N,49251,49252,49253,N,49254,N,N,N,22900,N,19296,N,N,N,49255,N,
+22901,N,N,N,49256,49257,N,22902,N,19534,N,16418,49258,N,49259,N,N,N,N,N,14178,
+N,49260,N,49261,22909,N,N,N,N,N,N,49262,49263,49264,15157,22906,N,22905,N,N,
+49265,49266,18226,49267,N,49268,17973,49269,N,49270,N,49271,17713,22907,49272,
+N,49273,22908,N,18799,49274,18245,15139,N,16497,N,19280,49275,N,N,N,N,N,13129,
+N,23077,22910,49276,49277,49278,N,19786,23079,N,49441,23075,N,23076,N,49442,
+49443,49444,49445,16736,49446,N,49447,49448,23074,N,22847,49449,N,49450,23078,
+N,23073,N,N,N,N,N,23083,23084,17703,23086,49451,49452,15140,23081,N,49453,
+49454,N,13628,49455,N,23087,49456,23080,23091,N,23090,49457,23089,49458,N,N,
+23092,49459,N,23094,15985,49460,23093,49461,N,N,49462,23097,N,N,49463,49464,
+49465,N,N,N,N,49466,N,N,N,49467,49468,N,49469,N,23095,49470,N,49471,23096,
+22896,49472,49473,N,N,49474,23099,23098,N,49475,N,N,49476,22904,23100,23088,N,
+49477,15193,N,49478,N,N,23101,23102,23104,23103,23105,12926,49479,14646,49480,
+49481,19068,16431,N,N,N,49482,N,14414,N,49483,23107,49484,N,N,N,23110,N,18770,
+49485,13663,49486,N,49487,23109,23108,18260,23111,13877,N,N,N,23113,23112,
+49488,49489,N,13370,15158,N,N,18008,49490,N,N,N,49491,14153,N,N,N,16244,N,
+23114,N,16432,17704,N,18783,23115,N,49492,N,N,49493,N,N,N,49494,23116,23117,N,
+49495,N,19000,21853,16454,49496,N,18764,N,14936,N,18533,18499,49497,N,N,49498,
+N,17741,49499,20033,N,23119,15440,49500,N,23120,49501,12342,N,49502,13908,
+16461,49503,18784,N,N,N,23121,15170,17223,49504,15195,16183,N,49505,49506,
+49507,N,N,23122,N,19069,N,N,12663,15196,N,49508,N,23125,49509,23123,23126,
+20025,23124,N,49510,49511,N,16507,23127,N,49512,16946,49513,N,23128,N,49514,N,
+49515,13434,49516,23130,N,23129,N,N,N,49517,23131,23132,13435,N,N,18044,17206,
+13676,15197,16737,N,N,15708,12336,N,N,49518,23133,49519,N,49520,49521,N,N,N,
+49522,12834,23137,N,N,49523,49524,49525,N,14647,23136,49526,N,14891,15930,
+49527,49528,23135,N,15931,49529,19520,14890,N,49530,49531,12375,16462,49532,
+49533,N,N,N,N,N,23142,49534,49697,16433,12615,49698,49699,49700,49701,15701,
+49702,19302,14962,49703,49704,49705,49706,15932,49707,16423,49708,49709,N,
+49710,23141,23139,23140,49712,N,49711,N,N,17259,N,N,23334,49713,23146,15230,
+14648,23144,49714,49715,N,N,23145,49716,16184,49717,N,49719,23143,N,49718,
+15151,N,N,N,N,49720,49721,49722,N,49723,49724,23148,23147,23152,49725,49726,
+23153,N,23149,N,13090,23150,23151,18517,49728,49729,49730,N,18785,14154,23154,
+N,N,49732,16434,49733,15933,49735,49736,49737,17234,49738,49740,N,49731,49734,
+49739,13895,N,23155,23159,N,N,12875,23156,23158,N,49741,49742,49743,23157,N,
+49744,15723,49745,N,N,N,17224,12357,23160,49746,49747,49748,49749,23161,N,
+49750,49751,N,17450,N,49752,N,20081,N,N,N,N,15171,N,49753,19051,N,N,49754,
+49755,N,19261,49756,N,N,23330,23163,N,49757,23166,N,23165,49758,49759,23162,
+49760,49761,23329,N,N,18014,49762,23164,N,N,49763,N,49764,49765,N,N,N,N,49766,
+N,23331,N,N,15724,23332,49767,19787,18296,N,49768,23333,N,N,N,N,N,23335,N,
+49769,23336,N,49770,49771,N,49772,N,23337,N,13898,12616,14649,23338,N,23339,
+15729,16738,49773,49727,21080,16702,16701,16984,14919,N,N,20594,N,49774,N,
+49775,14190,19757,N,19070,N,18814,49776,23340,N,N,N,49777,14963,17471,23341,
+20271,N,49778,N,19262,49779,17451,23342,13436,49780,N,49781,N,N,N,23343,23344,
+19546,N,19492,19318,19292,15141,23346,N,N,15467,N,49782,19281,N,23348,23351,
+23350,N,13433,N,N,13664,49783,23347,N,23349,N,N,N,49784,23352,49785,49786,
+16249,N,N,49787,N,19835,12361,14944,16956,N,15453,49788,49789,15987,N,N,23355,
+N,N,17742,49790,23353,16939,23354,15986,19549,23356,23357,19816,49953,N,N,N,
+23362,N,49954,14650,49955,18261,23359,17772,23134,23138,49956,13647,49957,
+18247,N,N,N,49958,23361,N,15934,18500,N,49959,N,N,49960,23367,N,18554,N,23358,
+N,23364,23363,N,49961,49962,16463,49963,N,49964,N,19309,49965,20051,49966,
+49967,19303,49968,12876,15198,N,N,20296,23366,16245,N,N,N,23365,N,N,23360,N,N,
+N,N,N,14415,49969,49970,49971,23372,23370,49972,12877,23368,23374,23380,N,
+49973,49974,49975,N,N,49977,16968,49978,49979,19009,49980,23382,N,49981,49982,
+18722,N,N,N,23381,18288,19263,13371,49983,16503,15680,N,N,49984,17491,49985,
+19758,N,49986,23377,23376,N,N,49987,23378,N,23375,N,49988,23383,N,23373,N,N,
+23371,N,23379,23369,49989,17260,49990,19576,15430,14964,49991,49992,N,49976,N,
+14906,N,N,19311,13121,17486,17994,12617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,16498,
+49994,N,16436,14122,N,49995,N,N,N,49996,23385,49997,N,14651,13180,N,N,N,N,
+49999,49998,23387,13172,23393,50000,50001,N,50002,50003,50004,23390,50005,
+16499,N,N,N,13131,14892,N,50006,13130,14927,N,50007,23388,14181,14155,17773,
+50008,50009,23386,N,12358,N,50010,N,50011,23389,23391,N,13901,14124,49993,
+13372,13643,50012,N,50013,50014,23394,N,50015,14969,19313,N,15159,N,N,N,23395,
+N,N,N,18736,N,N,N,50016,N,N,50017,50018,50019,50020,50021,N,23407,50022,12851,
+23396,N,50023,50024,50025,50026,N,23413,23397,N,20034,50027,23404,50028,18271,
+50029,N,50030,N,N,N,N,23412,N,23399,N,N,N,12340,23401,N,50031,14652,50032,N,
+50033,23403,50034,23402,N,23398,23409,50035,15935,50036,N,50037,21613,14440,
+19836,50038,50039,N,N,23400,50040,17524,13091,14893,50041,23392,N,23408,13153,
+N,N,23406,23410,50042,17774,N,N,N,N,N,N,N,13438,50043,23602,N,50044,19529,
+23415,13437,50045,23422,N,50046,50209,50210,19264,50211,23585,23587,50212,
+23591,23417,50213,17194,N,50214,50215,N,17775,23595,23420,N,23592,N,50216,N,
+23586,50217,N,50218,50219,50220,50221,16185,23596,50222,50223,16435,N,N,50224,
+50225,N,N,23594,13373,50226,50227,50228,20304,23414,N,N,23590,12376,50229,N,
+23416,50230,50231,19514,23421,16162,17479,23411,50232,50233,23589,50234,N,N,
+50235,50236,N,16250,23599,13169,14369,N,N,N,N,23601,23418,23600,N,23593,23419,
+N,23597,N,23598,N,N,N,N,N,23615,50237,N,50238,17998,50239,23588,N,50240,23611,
+N,50241,N,23613,N,17496,N,N,50242,N,N,50243,N,N,N,50244,19788,N,N,N,50245,N,N,
+N,N,18806,23608,16970,N,50246,N,23614,16703,50247,23605,23618,23617,N,18031,
+23616,18026,50248,50249,50250,50251,N,50252,50253,23620,23607,50254,13896,
+23610,15709,50255,50256,50257,18272,23612,13899,N,23604,23606,23603,50258,
+50259,20272,13146,23609,50260,50261,23619,13109,N,N,N,N,N,N,N,14951,N,N,50262,
+12637,N,N,23636,50263,N,20273,23639,50264,N,50265,N,N,16186,23638,N,N,N,23637,
+50266,N,N,N,50267,50268,23634,50269,N,N,50270,N,50271,23622,50272,N,23651,
+23621,N,23640,N,N,50273,50274,N,50275,23632,50276,N,23627,23624,N,23625,N,
+23633,N,50277,N,29730,50278,N,23630,14653,17480,16740,23628,N,23623,50279,N,
+23626,N,N,50280,50281,19789,19306,N,N,N,23631,23641,N,N,N,50282,N,N,50283,N,
+23649,23642,N,N,23655,N,23653,50284,50285,N,50286,23648,50287,N,50288,N,N,N,
+23647,N,17488,N,16741,50289,23645,50290,50291,23643,50292,N,23650,N,N,N,N,
+23656,18549,23662,N,N,50293,N,50294,23657,23660,23654,50295,N,17268,N,18744,
+50296,23644,N,50297,23652,15936,50298,19535,23672,23659,50299,N,N,N,50300,
+14370,12835,13151,N,N,23635,N,50301,N,50302,N,50465,15937,23664,50466,23671,
+15481,13170,50467,N,17198,50468,50469,N,N,N,N,23661,50470,50471,23666,23670,
+50472,50473,13878,N,N,50474,N,50475,50476,50477,N,N,50478,50479,N,13644,23668,
+N,50480,N,N,N,13601,N,17995,23667,N,50481,N,23669,50482,N,N,50483,N,N,N,N,N,N,
+50484,23663,50485,N,N,N,N,23665,N,N,N,N,N,50486,13152,17225,50487,N,50488,
+23676,N,50489,50490,N,50491,N,50492,N,23674,14441,N,23673,50493,N,N,N,N,N,
+23841,N,N,N,50494,23384,50495,50496,50497,23675,N,23677,23678,N,50498,N,N,N,N,
+23852,50499,23848,N,23405,50500,50501,50502,N,23847,50503,N,N,N,23846,N,N,
+23843,N,50504,50505,50506,N,23658,23845,23844,N,N,50507,N,50509,50508,N,N,
+50510,N,N,N,50511,23850,N,20262,50512,50513,50514,N,N,N,23853,13947,50515,
+50516,23849,23851,N,N,N,N,50517,N,N,50518,18471,N,23854,N,50519,N,N,N,50520,
+50521,50522,N,N,N,N,N,N,N,23858,23855,50523,50524,50525,50526,19827,23856,
+50527,50528,N,50529,23646,N,N,N,N,50530,50531,50532,23859,N,N,N,23860,50533,N,
+N,N,50534,N,12597,50535,23862,14183,15393,N,13909,50536,N,N,12836,50537,N,N,
+50538,50539,N,N,50540,N,N,19807,N,N,50541,50542,23864,23863,23866,13629,50543,
+N,13910,13374,50544,N,N,N,23869,N,N,50545,23868,N,23870,50546,N,12878,50547,
+17207,N,23871,N,50548,13375,23873,N,50549,N,50550,23872,N,23874,N,50551,N,
+23875,50552,23876,15199,16437,14881,N,18800,50553,N,19042,20292,50554,N,N,
+50555,15221,50556,N,N,14928,20082,50557,N,N,23877,23878,N,15200,N,50558,50721,
+23879,23880,N,50722,23882,23881,50723,19288,N,N,15710,15468,15172,N,23883,N,N,
+N,N,N,N,N,23885,16163,50724,23884,N,N,50725,N,N,23886,50726,50727,N,50728,
+50729,23887,N,N,N,50730,50731,23888,23889,50732,50733,50734,23890,50735,23892,
+23891,23893,12837,17226,N,23894,50736,50737,15142,13132,23895,50738,50739,
+17730,21580,N,N,50740,50741,13603,23896,N,N,50742,N,23897,50743,19052,19304,N,
+N,N,17991,23898,18534,N,50744,N,18555,N,50745,19539,N,N,N,23899,N,50746,N,
+50747,N,N,50748,50749,N,N,N,23901,23900,N,50750,23903,N,50751,N,23902,N,N,N,
+50752,N,50753,N,N,N,N,N,50754,50755,N,50756,50757,N,N,23905,50758,N,N,N,50759,
+50760,15201,50761,19505,50762,23906,23907,N,N,13604,N,50763,N,23908,N,N,N,
+50764,N,N,N,23910,23909,N,50765,50766,50767,N,N,N,50768,N,50769,N,N,N,N,50770,
+16229,50771,50772,18745,12618,N,50773,50774,N,N,18501,50775,17525,15681,13665,
+N,N,N,N,N,N,N,50776,50777,N,50778,18502,50779,15406,N,50780,N,50781,23912,N,
+13376,N,50782,12664,50783,50784,18034,23911,14654,17235,N,23913,N,N,N,N,50998,
+23921,N,23914,50785,N,50786,N,50787,16961,N,13666,23922,50788,N,50789,N,50790,
+50791,14184,50792,N,13605,23920,N,N,23918,23915,19808,N,50793,50794,50795,
+17472,50796,N,N,18009,23916,N,N,23924,N,23923,14115,50797,50798,12845,50799,
+50800,14907,23917,23919,50801,N,N,50802,N,19287,17012,N,N,N,N,N,N,N,N,19319,N,
+N,23932,N,50803,23933,50804,12879,50805,N,N,N,18984,19581,24097,15395,15938,
+23928,23934,12648,N,13879,50806,N,23925,23930,50807,N,N,16500,18289,N,18535,
+50808,N,50809,50810,50811,50812,23927,50813,19233,50814,23929,N,24100,50977,
+24098,50978,23931,N,N,50979,19234,18248,13667,N,17701,N,50980,17261,50981,
+24101,50982,50983,N,50984,24099,16985,23926,50985,12619,50986,50987,N,N,50988,
+N,N,50989,19790,24112,N,50990,50991,N,50992,24111,50993,N,N,N,16502,N,24108,
+50994,19820,N,N,17974,24102,N,N,N,N,N,17477,50995,50996,50997,12620,14655,
+24105,N,N,50999,51000,N,51001,15655,24110,N,24109,24104,N,24107,51002,N,13160,
+51003,24106,18249,51004,N,20014,N,N,15988,16501,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,51005,N,24118,24116,N,18765,N,51006,51007,N,51008,N,24113,24115,51009,
+12602,51010,N,14656,20274,N,13117,N,18786,51011,51012,N,N,N,19809,N,N,13092,
+16187,24117,N,N,51013,N,N,N,N,N,51014,N,N,24122,N,51015,15939,N,N,N,19760,N,
+24119,N,N,51016,51017,24114,51018,24120,51019,51020,51021,20062,N,17779,17986,
+N,N,N,N,N,N,N,N,N,N,N,N,N,51022,N,51023,N,N,13110,N,N,12629,N,51024,24126,N,
+51025,24129,51026,N,N,20035,51027,N,51028,19812,N,N,N,51029,24136,24130,24127,
+51030,N,51031,20052,24133,N,51032,51033,N,15690,24135,N,N,24140,51034,N,17777,
+24138,N,51035,N,51036,24132,51037,51038,17208,51039,N,24139,51040,24128,N,
+24134,51041,24141,12412,24131,N,24142,51042,51043,16188,N,15711,51044,18981,
+51045,14894,N,24123,24137,17722,51046,51047,N,N,N,51048,16438,N,13161,14929,
+15940,24125,15682,N,N,N,N,N,N,N,14156,N,24124,N,N,N,24146,15725,14394,N,24161,
+51049,24155,13684,17743,51050,24150,24159,12335,12594,51051,N,12857,N,24152,
+16940,24143,24145,14657,N,N,51052,N,N,N,51053,N,24162,51054,24157,51055,51056,
+N,24149,N,N,N,N,24156,51057,51058,N,N,51059,51060,19499,51061,N,24154,24158,
+51062,N,51063,51064,51065,51066,N,14416,51067,15941,N,N,17209,51068,51069,
+51070,24148,N,N,51233,51234,N,N,N,19759,51235,N,N,24151,N,N,24144,17778,N,N,
+24147,51236,N,N,24153,N,N,N,N,51237,N,51238,20305,15422,19326,N,24163,N,N,N,N,
+N,N,N,N,N,18478,51239,N,24175,14395,N,N,51240,N,N,15712,N,24165,51241,N,N,
+20015,14658,N,24178,51242,N,12398,N,N,24176,N,51243,N,N,24164,N,N,51244,51245,
+24170,N,51246,24172,51247,N,N,19791,24167,N,N,17710,51248,N,24169,N,51249,
+51250,51251,24177,51252,24171,19527,N,51253,51254,24166,51255,15394,24190,
+51256,51257,51258,N,13162,N,24168,24173,24174,N,N,N,N,N,N,N,17004,16986,N,N,N,
+N,N,N,N,N,N,N,N,N,51259,24182,51260,51261,24188,N,N,24186,N,17705,N,N,24355,
+24183,51262,N,51263,N,51264,24184,24160,13689,18746,N,51265,N,15423,N,51266,
+14711,51267,N,51268,51269,N,20275,N,24180,N,24354,12649,16742,51270,N,51271,N,
+51272,51273,N,N,N,N,18297,N,13377,20090,N,N,51274,N,N,51275,51276,19489,17490,
+51283,N,51277,51278,24187,24189,51279,N,N,51280,N,16690,N,N,51281,51282,N,
+24353,24185,N,24179,N,N,N,13379,N,N,N,N,N,N,N,N,N,51284,N,51285,51286,51287,
+14185,N,N,51288,24367,51289,51290,24362,16504,51291,51292,13155,N,51293,51294,
+N,15713,N,24371,N,51295,N,N,N,51296,24364,17452,24361,17497,N,N,N,24396,N,N,N,
+24358,N,24357,N,24366,51297,51298,N,24360,24359,24365,51299,16417,N,24356,
+51300,51301,N,N,51302,51303,51304,24368,N,51305,24369,51306,51307,51308,N,
+51309,13378,N,N,51310,N,N,N,N,51311,51312,24374,N,24373,24375,51313,51314,
+51315,51316,N,24378,N,N,N,51317,51318,51319,17731,N,24372,N,51320,51321,N,N,
+24376,N,N,51322,N,N,N,14179,17017,24370,18235,N,51323,24377,51324,51325,N,
+51326,N,N,N,N,N,N,N,N,N,24382,24380,N,N,24383,N,51489,24386,N,N,51490,24379,
+14698,18216,N,N,24121,N,N,N,51491,51492,N,19828,24381,N,24385,17013,51493,
+24384,N,24363,N,51494,28521,N,N,51495,24389,N,51496,51497,24393,51498,24391,N,
+N,N,51499,51500,51501,N,24387,N,24388,N,51502,N,24392,N,24390,N,N,N,18766,N,
+51503,24398,N,24395,24394,N,24397,18004,24399,51504,N,N,51505,N,N,17269,17005,
+N,N,N,N,16421,N,N,51506,24400,N,24402,N,51507,N,N,51508,N,51509,N,N,51510,N,
+24401,N,N,N,N,51511,51512,N,N,N,51513,51514,51515,51516,24181,N,51521,N,N,
+24403,N,N,51517,51518,N,N,18023,N,N,N,N,51519,51520,N,N,N,N,24404,51522,51523,
+N,N,N,N,N,12880,51524,N,51525,17780,13093,N,N,N,N,51526,51527,N,13668,N,N,N,
+15454,14930,51528,N,N,51529,N,N,N,51530,51531,N,N,20263,16230,N,N,N,12650,N,N,
+N,24406,N,51532,51533,51534,51535,51536,24405,N,51537,N,N,N,N,N,N,N,N,51538,N,
+N,N,N,N,N,51539,24409,17210,24412,24407,51540,51541,N,24411,51542,N,N,51543,
+24410,17728,12377,N,N,N,N,N,N,N,N,N,N,N,N,N,20085,N,51544,24414,N,N,N,12584,N,
+51545,N,51546,51547,51548,51549,N,51550,24416,N,N,51551,24415,N,24413,N,N,N,N,
+51552,N,N,N,N,N,N,N,N,N,N,N,N,24408,N,N,N,N,N,N,N,19235,51553,N,N,24418,51554,
+51555,51556,51557,51558,N,24417,N,51559,51560,N,N,51561,N,N,N,N,12651,N,N,N,N,
+24420,18994,N,24419,N,51562,N,51563,19509,N,N,N,N,15943,N,N,N,N,51564,N,51565,
+N,51566,51567,51568,N,N,N,N,16691,N,51569,N,N,N,15942,N,N,N,N,51570,N,N,N,
+51571,51572,51573,N,20091,51574,51575,24426,N,16505,N,51576,N,51577,N,N,24422,
+24427,51578,N,12652,51579,N,51580,N,51581,N,51582,N,24425,N,18273,24421,24424,
+15944,51745,18513,N,N,24428,N,15441,N,N,N,N,N,N,N,N,N,N,51746,N,N,N,16506,N,N,
+51747,N,N,N,24431,51748,N,51749,24423,N,14119,N,51750,N,N,24429,N,N,51751,N,
+19792,24432,N,N,N,29734,51752,51753,N,N,N,15695,51754,N,51755,N,N,N,N,N,24433,
+N,N,N,24434,N,N,51756,51757,18222,51758,51759,N,N,N,N,N,24436,51760,N,N,N,
+24437,51761,51762,51763,N,18227,51764,N,N,N,17781,24439,N,51765,51766,N,24441,
+N,20053,N,24438,51767,24440,12653,51768,24435,N,51769,51770,N,51771,N,N,21339,
+24442,N,N,N,N,16743,15160,24444,N,N,N,N,24443,16164,21081,N,N,N,N,N,N,24445,N,
+N,51772,24609,N,24430,24446,N,51773,24610,51774,N,N,N,N,N,18298,51775,51776,
+51777,N,N,N,24611,N,N,24612,N,N,51778,N,N,N,51779,N,N,51780,24613,N,51781,N,
+51782,N,N,N,N,51783,N,N,N,24614,N,17502,51784,24616,24615,N,51785,24617,N,
+24618,N,51786,15455,18787,N,51787,51788,19564,24619,24620,16726,15396,24621,
+24622,51789,51790,51791,N,51792,24623,19026,18503,N,N,24624,18263,N,51793,
+51794,51795,N,17453,51796,N,51797,51798,N,24625,12903,51799,13677,51800,19526,
+51801,19510,51802,12852,20276,51803,N,N,N,19282,51804,18986,N,51805,N,N,51806,
+51807,N,51808,16439,N,24626,N,N,51809,51810,17987,N,51811,51812,14371,24627,
+51813,14932,24629,24628,N,51814,N,N,24630,N,51815,N,N,N,51816,51817,N,N,N,
+24631,51818,N,N,24632,N,N,N,N,51819,N,N,N,N,13630,N,24633,N,N,N,N,24634,51820,
+N,N,N,14372,51821,51822,18504,N,51823,24636,N,51824,N,15989,N,N,24635,N,N,N,N,
+51825,N,N,51826,13880,24637,24639,N,24638,51827,N,51828,N,N,51829,N,24640,N,
+14417,N,24641,N,N,51830,51831,13929,51832,16704,N,14717,N,N,N,51833,24643,
+24644,24642,N,N,51834,N,N,N,15469,N,N,17992,13881,N,N,N,N,N,51835,51836,N,N,
+24646,17196,24645,51837,51838,20277,18274,52001,52002,N,52003,52004,N,52005,N,
+N,24649,52006,N,52007,N,N,N,N,52008,52009,N,N,24651,24648,52010,52011,N,19540,
+24650,24652,52012,20036,N,N,52013,N,52014,24656,N,52015,52016,24655,17270,
+18221,52017,N,14373,24654,N,52018,52019,N,24653,52020,19761,19762,N,N,52021,
+52022,N,52023,24657,12654,N,N,N,52024,14710,15202,N,N,N,N,N,N,N,52025,24658,
+24659,52026,N,52027,N,N,N,52028,24661,52029,N,N,N,N,52030,52031,52032,52033,N,
+N,15683,N,N,52034,52035,24663,52036,24662,52037,52038,N,52039,52040,24664,
+52041,13133,N,N,24666,N,52042,24665,52043,24668,24667,52044,N,N,N,52045,52046,
+N,52047,14396,52048,52049,20008,N,13900,N,12838,N,N,52050,N,52051,N,N,52052,N,
+52053,13930,52054,52055,N,N,N,52056,N,52057,52058,52059,N,52060,N,N,52061,
+52062,N,N,13409,52063,52064,N,52065,N,N,N,N,20072,24670,N,52066,N,52067,N,
+52068,N,24672,52069,52070,N,52071,24673,N,12881,N,N,52072,52073,N,24669,52074,
+15161,52075,52076,17473,24671,52077,N,N,52078,52079,N,N,52080,N,N,52081,N,N,N,
+52082,24676,N,15470,52083,N,52084,N,24674,52085,52086,N,52087,14142,N,N,18505,
+24675,N,N,24702,N,N,52088,52089,N,52090,24681,52091,52092,52093,N,52094,14397,
+52257,52258,52259,N,13669,52260,24678,19837,52261,N,20016,52262,N,N,N,N,N,N,
+52263,N,N,N,N,N,N,N,N,52264,52265,N,N,N,N,N,N,17014,N,52266,24680,52267,N,
+52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,24682,20054,13911,
+18556,18250,N,N,52278,24683,N,N,N,N,24685,52279,24688,N,52280,52281,N,52282,
+52283,N,N,N,52284,N,52285,N,N,N,52286,52287,N,N,24684,N,52288,N,24687,14442,
+12621,24689,52289,16240,24686,20060,N,52290,24692,29732,N,52291,52292,52293,
+24690,24693,52294,N,52295,52296,24679,24691,52297,52298,14908,N,N,24694,N,N,N,
+N,N,N,N,24695,N,52299,52300,N,19838,N,52301,52302,52303,N,52304,N,24696,N,N,N,
+52305,52306,52307,52308,N,N,N,N,N,52309,52310,52311,N,52312,N,24697,52313,
+52314,52315,24677,52316,N,N,52317,24698,52318,52319,52320,52321,N,N,52322,
+52323,13380,52324,52325,N,N,52326,N,N,N,52327,N,52328,N,15397,N,52329,N,N,N,N,
+N,N,N,N,52330,52331,24699,N,52332,N,N,24700,52333,N,N,52334,24701,N,N,N,52335,
+N,52336,52337,12603,N,52338,52339,24865,N,18747,24866,52340,N,13348,24867,
+52341,24868,52342,52343,N,N,24869,52344,24871,24872,24870,N,52345,N,18771,
+24874,24873,N,52346,52347,52348,N,N,52349,24876,24875,24877,52350,N,N,N,N,N,
+24878,24880,24879,N,N,14713,52513,24882,N,24881,52514,52515,13381,N,16211,N,
+17724,N,24883,16440,52516,52517,N,15162,52518,12665,24884,52519,19793,52520,
+52521,19043,24885,N,N,52522,17732,19763,14659,16189,N,N,52523,17227,21044,
+52524,17454,12904,24886,52525,52526,52527,52528,N,N,52529,24887,N,24892,52530,
+52531,24890,24889,23106,13094,24888,52532,12378,52533,18474,52534,N,18506,N,N,
+52535,N,20017,24893,24891,17244,16422,52536,52537,18475,52538,18733,N,24895,
+20012,14157,24896,N,24894,18518,24897,N,24898,N,52539,12379,52540,N,15990,
+24903,N,24900,18029,24899,52541,52542,52543,52544,52545,52546,13606,N,52547,
+24906,N,N,52548,24901,24902,N,24905,24904,18725,N,N,16706,16705,52549,13631,
+52550,52551,24907,52552,N,N,N,52553,24908,N,52554,24909,N,N,N,N,52555,24911,
+52556,24910,N,N,N,N,N,12630,N,N,N,N,N,24919,18536,24913,52557,24915,N,N,24917,
+16190,52558,N,24918,24916,15424,52559,52560,52561,24912,24914,52562,18754,
+52563,15945,N,N,24921,N,52564,24920,52565,52566,N,N,24922,N,15398,14895,N,
+52567,17783,24923,N,17483,52568,N,24925,52569,52570,52571,20001,24924,52572,N,
+N,52573,N,16745,N,N,52574,N,52575,52576,24930,52577,24932,24933,17236,N,N,N,N,
+52578,24931,N,24928,N,24926,24927,52579,24929,52580,52581,52582,N,N,52583,
+52584,24936,52585,24934,52586,24935,N,52587,N,N,52588,52589,N,52590,52591,N,N,
+52592,N,52593,52594,52595,52596,24937,24939,24940,24941,52597,24942,52598,
+52599,24938,N,52600,N,N,N,52601,N,N,24944,N,52602,52603,24943,52604,N,N,52605,
+52606,52769,24945,52770,N,N,N,52772,52773,20037,52774,52775,52776,24948,24946,
+24947,52777,52771,52778,13410,N,N,N,N,N,19582,N,N,52779,19018,N,24950,52780,N,
+N,24949,N,N,52781,N,24951,24952,N,52782,52783,N,24956,24953,24954,24955,N,
+24957,52784,52785,52786,24958,52787,25121,N,52788,N,25122,N,25123,N,18479,
+17744,25124,18290,18740,N,25125,52789,N,25126,17706,52790,13095,14660,25127,N,
+N,25128,52791,52792,25129,N,15145,N,N,25131,N,52793,25130,N,N,25132,25133,
+52794,52795,52796,N,52797,52798,N,52799,52800,52801,52802,52803,52804,52805,N,
+52806,N,N,52807,18537,N,25134,N,N,N,25135,N,N,29545,25136,25137,25138,N,N,
+52808,N,15150,N,52809,25139,18262,N,52810,19295,N,12622,52811,12631,52812,
+52813,25140,52814,N,N,N,25142,N,52815,N,25141,17776,N,52816,N,16441,23865,N,
+25143,19521,52817,25144,N,13382,18519,25145,52818,25146,52819,N,25147,N,52820,
+N,19548,N,52821,52822,19541,N,17470,N,52823,N,16746,52824,N,25149,52825,N,
+15714,52826,15946,N,N,25152,N,52827,25151,25150,18557,52828,13383,14377,N,
+52829,N,N,N,52830,N,52831,52832,N,52833,N,52834,52835,25158,52836,N,25155,
+16191,19506,N,52837,N,25154,25156,25157,N,52838,25153,N,N,N,52839,52840,52841,
+N,N,N,N,52842,52843,52844,25159,25160,52845,17455,N,13411,52846,52847,N,17253,
+N,52848,N,N,52849,52850,25161,N,N,52851,N,N,52852,52853,52854,N,N,52855,N,N,N,
+52856,52857,N,N,25162,25165,52858,N,52859,52860,52861,16231,52862,17988,53025,
+25166,19283,53026,25163,N,53027,25164,53028,N,N,N,53029,N,53030,53031,53032,N,
+N,N,N,25169,53033,N,N,53034,25168,25167,53035,N,N,N,53036,N,N,N,N,N,N,25171,
+53037,53038,25170,N,N,25172,N,N,53039,53040,53041,N,N,N,53042,N,N,N,25174,
+53043,25173,N,53044,N,N,19021,N,53045,N,N,53046,N,15702,20038,53047,53048,
+25175,53049,N,17975,N,53050,25176,N,N,25177,N,25181,25179,25180,53051,25178,N,
+N,N,53052,N,N,N,25182,N,53053,N,N,N,25183,N,N,N,53054,53055,N,N,53056,N,25184,
+N,53057,25185,19511,25186,N,53058,53059,53060,N,19568,25187,53061,17230,53062,
+18282,N,13931,53063,N,53064,17211,25188,13882,53065,53066,N,16464,53067,N,N,N,
+53068,N,N,53069,25189,14909,N,N,53070,53071,N,N,53072,N,N,25190,53073,53074,N,
+N,53075,25191,N,14374,14933,N,N,N,N,N,N,N,53076,N,N,25193,53077,53078,53079,N,
+17750,14934,13646,N,N,N,N,N,53080,53081,N,53082,N,19236,N,18251,53083,N,53084,
+N,N,17751,N,N,N,N,14684,N,N,N,53085,53086,25195,N,53087,53088,N,N,N,53089,N,
+53090,N,N,N,53091,N,N,N,N,N,N,N,N,N,53092,15947,53093,N,53094,53095,N,53096,
+53097,N,N,N,53098,N,53099,20018,14661,N,53100,14375,N,N,18467,N,25197,N,N,N,N,
+N,53101,N,25199,N,53102,N,N,14443,N,N,N,N,25198,17526,N,N,53103,N,25201,13111,
+25196,53104,N,18538,N,12592,53105,14956,N,20306,53106,N,25200,N,N,53108,53109,
+53110,N,53107,N,25202,53111,N,N,19019,53112,16473,25204,N,53113,53114,N,25205,
+53115,53116,53117,53118,N,25203,N,N,N,N,13134,53281,25211,53282,25210,53283,N,
+15399,N,N,N,25212,25207,53284,53285,53286,25213,25208,53287,N,53288,N,18520,
+25206,53289,53290,25209,53291,53292,N,N,N,25378,53294,N,N,N,53295,53296,53297,
+N,N,53293,N,53298,25377,19297,N,53299,N,25214,N,N,12395,N,N,53300,53301,25380,
+N,53303,53304,N,N,53305,53306,N,25379,N,53307,53302,15948,N,N,N,N,53308,25381,
+N,N,N,N,53309,N,16707,N,53310,25383,25382,N,N,N,N,N,N,25384,53311,N,53312,N,
+53313,53314,53315,N,N,N,N,53316,25192,53317,N,53318,25194,25386,25385,53319,N,
+N,N,53320,N,N,53321,53322,N,N,N,N,15400,53323,20073,53324,15442,53325,25387,
+14135,N,N,53326,53327,53328,13632,13607,15203,53329,53330,N,N,N,53331,19764,
+53332,N,25393,53333,25392,16708,25389,53334,N,25391,53335,53336,15691,16192,
+25390,25388,N,18218,N,N,15949,N,53337,18748,53338,N,53339,N,14935,N,N,N,N,
+53340,N,N,N,N,17784,N,53341,25394,53342,53343,N,53344,25395,25417,13912,N,N,
+20285,16693,N,N,N,N,25396,53345,53346,12882,17527,18977,N,53347,N,53348,53349,
+53350,53351,N,53352,N,N,53353,53354,25397,N,N,N,53355,N,N,N,N,13690,25398,
+53356,53357,25400,53358,N,N,25401,53359,18217,53360,N,25402,53361,N,N,N,53362,
+25403,25404,53363,N,13913,12883,17989,15656,15204,53364,N,53365,N,N,53366,
+53367,25405,53368,15657,N,N,N,53369,N,12874,18755,N,53370,25406,53371,N,18539,
+N,53372,N,N,53373,53374,16709,53537,25409,53538,25410,18281,53539,16193,25407,
+N,17249,53540,53541,25408,53542,N,N,15950,53543,N,N,N,N,N,N,53544,N,N,12380,
+53545,13609,N,53546,53547,N,N,N,53548,25411,53549,53550,17528,53551,25412,
+16455,N,N,53552,N,N,19501,53553,N,18723,25413,25414,17237,53554,20039,N,53555,
+25416,25415,53556,N,N,N,N,N,53557,N,N,N,53558,N,53559,15471,53560,53561,25418,
+12400,N,53562,53563,N,25421,53564,53565,53566,25419,12884,14158,25420,14662,
+14706,N,19046,25422,53567,53568,19284,53569,53570,25424,N,N,53571,16465,12623,
+12858,12332,N,N,N,N,53572,53573,25423,N,53574,N,N,53575,53576,N,53577,53578,
+25425,25426,15991,N,53579,N,53580,N,25427,53581,13135,N,53582,N,N,25429,N,N,N,
+14186,53583,13670,N,53584,25430,13941,N,N,25431,53585,16508,53586,17997,53587,
+16480,14965,53588,53589,N,25432,N,53590,53591,N,N,N,N,53592,53593,17250,16747,
+53594,25434,25436,25433,25435,N,N,N,N,N,53595,14114,53596,N,N,53597,N,N,N,N,N,
+25437,14118,N,53598,N,13671,19794,25439,N,N,53599,N,53600,25440,N,N,53601,
+12590,53602,53603,N,N,25443,N,N,N,13174,25442,25441,53604,25445,25438,53605,
+25446,20009,53606,25447,53607,25448,N,53608,21620,25450,N,25449,N,N,N,25451,
+25452,53609,20021,25453,N,28783,15951,25454,25455,15703,N,17976,25456,N,53610,
+53611,17192,53612,53613,25457,N,17212,25458,53614,N,N,53615,N,13861,N,20799,
+17245,15411,53616,N,53617,53618,13384,25459,N,25634,N,25462,53619,13672,N,
+25461,25636,N,N,N,25460,N,15952,N,N,53620,N,N,N,25464,25465,N,17707,N,N,25466,
+53621,13150,N,N,53622,N,16218,18788,53623,25468,53624,53625,53626,17000,53627,
+53628,53629,53630,53793,N,25463,53794,25467,25469,N,N,14971,N,N,N,53795,N,
+53796,53797,53798,N,N,N,25638,18734,53799,18470,17785,N,13914,25637,25635,
+53800,18485,25470,17246,17787,N,17786,53801,14966,N,N,N,N,N,N,25656,N,N,53802,
+N,N,N,53803,25640,53804,25642,N,53805,53806,N,25645,53807,25646,53808,25643,
+25644,53809,53810,25641,25639,N,53811,N,N,25633,N,N,N,N,N,N,N,N,N,53812,N,
+19023,12885,N,53813,N,25653,N,25650,53814,25655,53815,53816,25654,N,18291,
+19495,53817,15163,25648,25657,25652,53818,25651,25647,53819,25649,53820,13385,
+N,N,N,53821,N,N,N,N,17213,N,53822,16509,N,53823,53824,18466,53825,N,25662,
+53826,53827,N,18468,N,53828,53829,53830,53831,N,N,16481,25659,53832,N,18511,
+53833,25663,19027,53834,17243,53835,25658,25660,N,N,25661,N,N,N,N,53836,N,
+53837,53838,N,53839,53840,53841,N,25664,N,N,15428,N,N,N,17990,25669,25668,N,
+53842,25665,53843,N,N,20278,N,N,N,N,53844,25674,53845,53846,25678,25675,53847,
+53848,53849,N,53850,N,53851,25671,53852,53853,53854,53855,N,53856,25672,N,
+53857,N,53858,53859,25677,53860,53861,N,25666,21077,25673,25667,N,N,25676,N,
+53862,N,53863,N,N,N,25682,53864,13386,N,25679,N,53865,53866,25680,53867,N,
+25681,25684,53868,N,N,N,N,53869,N,53870,53871,N,53872,25683,18550,53873,53874,
+N,N,25685,20092,19053,25690,N,N,25687,N,N,53875,N,N,N,53876,N,25686,16466,N,
+25689,25691,53878,53879,53880,25688,53877,25695,N,25692,53881,53882,53883,
+53884,53885,53886,25693,25670,54049,N,54050,25694,25696,N,54051,N,54052,N,N,
+25697,54053,54054,N,54055,N,54056,19014,N,25698,N,N,N,54057,N,N,54058,54059,
+19554,N,N,13902,14121,25699,N,N,54060,54061,N,18996,N,16232,N,19504,N,54062,
+25700,N,20019,N,54063,18292,N,16710,18228,N,N,15693,N,N,54064,12352,54065,
+25705,25703,N,25701,13345,54066,15953,25706,N,N,25704,N,25702,25710,N,54067,
+25709,25708,25707,N,N,54068,54069,N,25711,54070,54071,54072,25712,16442,54073,
+25713,N,25715,N,54074,25714,N,54075,54076,54077,14418,N,N,54078,16696,54079,N,
+N,25717,54080,54081,54082,17788,54083,25716,54084,54085,N,25718,54086,18997,
+16748,14663,N,25719,N,N,N,54087,20040,N,54088,N,54089,N,N,N,25721,N,N,25722,N,
+25723,54090,25724,N,15205,N,25725,14159,N,N,13674,13610,N,25889,54091,19571,
+14664,25726,54092,54093,54094,25892,19558,N,18236,N,54095,18739,54096,54097,
+54098,15715,25891,54099,15443,14665,15206,13673,18998,25890,54100,54101,N,
+16711,19266,14967,54102,N,N,54103,N,N,N,54104,15207,17501,54105,25895,20063,
+14937,54106,25896,16194,N,25898,N,N,N,15954,14896,N,54107,54108,54109,25897,
+54110,54111,15658,14398,16712,25893,25899,54112,54113,N,N,25894,14160,54114,
+25902,25906,14187,54115,N,54116,N,N,25901,54117,N,54118,54119,25910,54120,
+54121,14666,N,N,19821,12348,25907,N,54122,13675,54123,25904,N,54124,N,N,N,
+25905,N,54125,17789,25903,25900,N,13096,16484,N,54126,14376,54127,54128,N,
+25912,N,54129,N,54130,54131,54132,N,54133,54134,N,54135,25909,N,54136,54137,
+54138,N,25911,N,54139,N,25908,N,N,54140,54141,N,14161,16947,25913,16750,54142,
+54305,25926,N,N,25922,25916,N,N,54306,54307,N,N,54308,25920,15482,12381,25915,
+25923,25927,14667,19542,54309,17494,25917,54310,54311,25925,54312,25914,17214,
+N,25919,12349,19530,N,N,54313,54314,54315,54316,54317,25918,N,N,13915,18540,
+54318,54319,54320,16749,N,20048,15727,N,N,25966,N,54321,25928,54322,16510,N,
+25924,25929,25931,N,17529,25934,54324,N,25930,54325,54326,N,19028,13387,54327,
+54328,19531,54329,N,12382,N,54330,25933,N,20093,54331,54332,N,N,54333,54334,
+25932,54323,12655,N,N,18028,25935,N,N,54335,25942,25936,25943,N,N,N,N,54336,
+54337,25939,N,N,54338,N,54339,N,N,N,18299,54340,54341,15434,25941,54342,25938,
+25944,25937,N,N,15684,54343,54344,N,N,19237,54345,54346,15692,54347,N,25940,
+25952,54348,N,25948,54349,25951,N,25949,25953,25947,N,25921,16467,54350,N,
+18507,N,25950,54351,54352,25945,54353,N,N,16673,14162,N,15659,54354,N,54355,N,
+54356,N,16165,16694,25956,N,54357,25958,25959,N,N,25955,25957,54358,N,54359,
+54360,N,N,54361,25946,25954,N,25962,25961,54362,N,19322,54363,54364,14123,N,N,
+54365,N,N,N,N,54366,25960,N,25964,25963,25967,54367,25969,N,54368,15164,25965,
+N,N,54369,54370,25970,25971,54371,N,25972,54372,25978,17723,25974,54373,25973,
+25975,25976,54374,25977,N,54375,N,54376,25979,25980,54377,54378,13388,N,25981,
+N,25982,54380,54379,54381,54382,54383,N,N,N,54384,54385,26145,N,54386,N,N,N,N,
+26146,26147,26148,54387,26149,26150,54388,54389,26152,26151,N,N,26153,N,N,
+54390,54391,54392,N,26154,26155,54393,N,54394,54395,54396,54397,26158,26156,
+26157,14945,14163,N,54398,17238,N,18483,54561,15728,N,N,18253,N,18541,26159,
+22637,N,N,N,54562,54563,54564,54565,N,26160,26162,N,19813,26161,26164,26163,N,
+19795,54566,26165,54567,18558,54568,54569,54570,N,N,26166,N,54571,54572,N,N,
+26169,N,54573,26168,26167,N,N,54574,54575,26170,14130,N,54576,N,16674,13633,
+54577,N,N,54578,26174,26171,N,N,26172,N,54579,N,26175,N,26176,26173,N,N,54580,
+12585,N,54581,54582,12839,N,54583,N,26178,26179,N,54584,N,26180,N,19810,N,
+54585,54586,N,N,15660,N,26182,26181,N,N,N,N,N,54587,N,N,N,54588,16233,26183,N,
+54589,N,54590,26184,N,54591,26185,N,13413,54592,N,54593,54594,13389,N,54595,
+26186,N,N,N,N,N,26187,54596,19293,19811,54597,54598,54599,19796,20279,N,14669,
+26190,15444,26189,54600,54601,N,54602,26191,15401,54603,54604,54605,16977,
+54606,26192,54607,54608,14668,54609,19543,26193,26194,N,N,26195,54610,54611,
+54612,54613,26196,N,N,54614,N,54615,N,26197,N,N,N,54616,N,54617,N,54618,N,N,
+15402,54619,54620,19565,54621,N,54622,54623,26199,54624,17215,54625,26198,
+54626,N,N,N,54627,N,26201,N,N,N,26200,N,N,N,N,N,N,N,26202,N,N,N,16443,N,26203,
+N,26204,N,N,N,19001,26205,54628,16751,26206,N,54629,N,54630,N,26207,N,N,N,N,
+54631,N,20094,26210,54632,26209,26208,17456,54633,26211,16166,N,26212,N,N,N,
+26213,20280,26214,N,54634,N,N,26215,26217,26216,18469,54635,18041,N,20286,
+18473,N,54636,N,N,N,N,26219,N,N,15955,N,18730,N,26220,26218,54637,13390,54638,
+N,N,14420,15208,N,N,18542,54639,54640,N,14378,19267,54641,26223,26221,N,14670,
+N,14671,12393,N,14952,N,N,N,54642,54643,18265,N,N,N,N,N,N,N,N,12383,26228,N,
+17216,N,54644,N,N,N,18264,54645,16987,54646,N,N,54647,N,54648,54649,26230,
+54650,54651,26226,26229,26224,N,26227,19238,N,54652,14421,N,N,12413,26225,N,N,
+N,N,N,N,N,54653,54654,26232,54817,26233,54818,54819,17977,N,54820,N,13883,
+54821,54822,N,26406,18237,54823,15209,54824,N,13884,16456,20294,19502,26231,
+16468,54825,N,N,N,N,N,N,N,N,N,N,54826,54827,54828,N,13651,26234,54829,N,54830,
+N,54831,N,N,26236,54832,N,N,54833,N,26235,N,N,54834,N,N,26237,54835,17190,N,
+18238,N,54836,N,N,N,17457,54837,N,54838,N,26403,N,N,N,N,N,N,54839,26402,54840,
+N,N,54841,26238,54842,N,16213,N,18789,26405,54843,26404,14672,20307,N,54844,N,
+N,N,N,N,N,N,26421,54845,54846,N,N,N,26409,26410,54847,54848,54849,N,15472,N,
+54850,26408,54851,14712,26407,N,N,26411,N,N,54852,17458,18978,16675,N,N,N,N,
+16988,26415,54853,26416,26412,54855,54856,54857,N,26413,N,26414,54858,N,N,
+54859,14673,54854,N,N,26422,N,26418,54860,N,54861,N,18790,54862,19308,18728,
+54863,N,26417,N,54864,26420,26419,N,N,N,19268,26423,N,N,N,N,54865,N,26424,N,
+54866,16695,54867,26425,N,N,26427,N,26431,54868,N,26428,26426,18239,26429,N,
+26430,54870,N,54871,12850,N,26437,26432,54872,54869,N,26433,54873,54874,N,
+26434,N,16929,N,54875,N,54876,26436,26435,26438,54877,N,54878,54879,26439,
+26440,54880,N,16195,54881,12905,N,26441,20055,N,15403,54882,54883,15661,N,N,
+54884,54885,54886,15210,17239,54887,54888,N,54889,54890,26442,26443,12593,
+54891,26444,54892,54893,26445,26446,54894,N,26447,N,26448,13885,23082,26449,N,
+16485,26450,15435,54895,26451,N,20528,54896,54897,N,26452,19038,13404,54898,
+54899,16676,15704,54900,18801,15662,N,54901,54902,N,N,N,N,N,54903,26453,14674,
+26454,18508,N,26468,N,N,N,54904,26456,54905,16969,18293,14399,26455,16677,
+54906,N,N,N,N,N,26457,N,N,54907,54908,54909,54910,17530,N,N,N,55073,N,N,55074,
+55075,N,55076,N,N,N,N,55077,N,26459,26458,26461,N,55078,26460,N,26462,55079,N,
+26464,55080,26463,N,13391,55081,26465,N,26466,26467,N,55082,14897,20041,N,
+26469,16167,N,55083,N,12656,26470,26471,N,N,55084,N,55085,26472,55086,55087,
+55088,N,55089,55090,N,N,55091,N,55092,55093,12402,N,26473,55094,N,N,55095,
+26474,N,55096,N,55097,N,55098,18791,55099,55100,N,15431,N,26476,55101,55102,N,
+55103,55104,13097,12338,55105,55106,55107,55108,26475,26478,18254,55109,16196,
+55110,12886,55111,19239,55112,N,N,55113,14173,13916,55114,26477,55115,12906,
+55116,55117,N,N,N,N,N,13347,55118,N,N,N,N,N,N,N,N,N,55119,12657,26482,20074,
+16989,55120,N,18756,N,26494,55121,12887,26492,N,26490,26481,55122,26479,55123,
+26480,55124,15459,13932,17271,55125,N,55126,18001,N,55127,N,55128,N,12625,N,
+26484,26483,N,55129,55130,N,26489,26485,26488,N,55131,55132,55133,55134,19536,
+26487,12888,13181,26491,55135,55136,26493,55137,55138,N,N,14164,N,N,N,N,N,N,N,
+26659,26668,26669,N,N,55140,12331,55141,55142,55143,N,55144,55145,26676,N,N,N,
+N,12401,N,N,26667,55146,55147,55148,26666,55149,26661,26660,55150,26658,26657,
+17251,55151,17019,26663,55152,N,55153,55154,N,N,26662,N,55155,55156,55157,
+26665,N,55158,N,16752,14165,N,N,55159,55160,12609,26664,55161,14675,55358,
+55139,55162,55163,55164,16753,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+55165,N,N,26682,N,26683,N,12889,55166,N,N,12846,26680,55329,N,55330,55331,N,
+55332,N,55333,26670,55334,26678,N,26685,26679,N,N,55335,26677,N,N,N,55336,
+26486,55337,55338,26675,N,55339,55340,26671,55341,55342,55343,13392,26673,
+26684,N,26674,N,N,N,55344,55345,26686,55346,26672,18300,55347,55372,N,N,N,
+19817,N,N,N,26681,N,N,N,N,N,N,N,26703,55348,55349,55350,26695,N,N,N,16251,N,
+55351,N,55352,13638,N,13917,N,26690,55353,55354,55355,N,12891,55356,N,15956,N,
+26693,N,N,N,14938,55357,N,17745,26698,N,N,N,N,N,N,N,55359,19054,55360,26689,N,
+N,N,12890,14422,18729,26699,N,26687,N,55361,26696,55362,55363,N,26706,55364,
+26691,55365,N,26692,17978,N,55366,26697,N,N,55367,26694,19240,26700,12384,
+55368,N,55369,N,26688,N,55370,N,N,N,55371,N,N,N,N,N,N,26702,N,26701,N,N,N,N,N,
+N,18283,26708,N,26719,N,N,55373,N,13182,N,N,N,26722,N,N,26704,55374,N,N,26709,
+19822,N,N,N,N,N,N,N,55375,26718,55376,55377,19797,55378,N,N,55379,20010,55380,
+N,55381,55382,N,N,N,55383,17272,55384,55385,55386,13163,55387,N,N,N,55388,
+18802,26724,17953,55389,55390,12337,55391,N,26717,55392,26713,16754,26707,
+26715,26720,55393,18220,N,55394,55395,12330,55396,26712,55397,26721,18808,N,
+55398,55399,N,N,N,55400,26716,N,26711,55401,N,N,N,N,N,15957,N,N,N,N,15663,N,
+55402,55403,15404,55404,N,N,N,19544,N,N,18759,N,55405,26727,N,26736,N,N,N,N,
+55406,N,55407,55408,55409,N,N,26714,N,55410,N,55411,13175,N,55412,N,N,N,15992,
+26725,55413,26730,16755,55414,55415,26726,55416,26733,55417,N,17247,N,26734,
+55418,55419,19798,26723,13112,55420,26729,N,55421,26732,19500,N,55422,N,N,
+26735,N,N,26728,26731,N,55585,N,N,N,N,N,N,N,N,N,N,55586,N,N,55587,N,19241,N,
+20257,55588,55589,55590,55591,N,26739,N,N,55592,N,N,55594,55595,26746,55596,N,
+26738,15427,N,55597,55598,N,N,26705,55599,N,N,N,N,55600,N,55601,N,55602,19022,
+N,19490,26745,26744,N,26740,26741,N,12598,N,55603,N,55604,26743,N,26737,55605,
+55606,55607,55608,17493,55609,N,N,55610,55611,26742,12414,N,55612,N,N,55593,
+55613,55614,16930,55615,N,N,N,N,N,N,19011,N,55616,26747,26913,N,18521,N,N,
+55617,N,26750,15958,15433,26915,N,N,13886,55618,55619,55620,55621,55622,N,
+26916,55623,18809,26749,55624,26710,N,55625,55626,55627,55628,55629,55630,
+55631,26748,55632,N,N,N,20303,17954,18803,55633,N,26923,N,55634,N,N,N,N,N,N,N,
+26929,N,55635,55636,55637,N,55638,26930,55639,26917,55640,N,N,18294,55641,
+55642,26927,26919,55643,26921,55644,55645,N,N,55646,26931,26920,N,55647,26924,
+N,N,12658,55648,18021,N,26925,26928,55649,N,55650,55651,N,55652,N,26918,55653,
+16678,55654,26922,15143,16197,14128,19572,55668,19577,15730,N,N,N,N,55655,N,
+55656,55657,55658,26935,26933,N,55659,55660,55661,55662,N,20302,55663,N,N,N,N,
+55664,N,26932,55665,55666,N,19829,55667,26934,26936,N,N,N,N,26937,N,N,55669,N,
+55670,N,26940,26938,N,55671,55672,N,N,N,17955,26939,55673,N,55674,18509,26926,
+N,N,55675,N,N,N,N,N,55676,N,N,55677,15731,N,26941,26946,16756,55678,N,26945,
+55841,55842,N,26914,N,55843,55844,26947,16713,N,N,26942,26944,N,55845,55846,N,
+55847,55848,55849,26943,N,N,23857,23842,55850,55851,26949,55852,N,N,55853,N,N,
+55854,26948,N,N,N,N,55855,N,55856,N,N,N,19830,N,25148,26950,N,N,N,N,N,55857,N,
+55858,N,55859,N,55860,55861,N,26951,55862,47206,55863,N,N,N,55864,N,N,N,N,N,N,
+26952,14423,N,13652,N,55865,55866,26954,20829,55867,55868,55869,55870,13685,N,
+20026,55871,13939,26955,55872,55873,55874,55875,55876,N,N,26956,N,55877,N,
+17262,55878,N,N,55879,N,26957,N,N,N,55880,55881,55882,N,18042,55883,12346,N,N,
+N,N,N,N,N,N,N,N,N,N,55917,N,12899,26962,26963,55884,N,N,N,55885,N,26958,N,
+15165,55886,N,55887,N,55888,N,55889,N,N,N,N,55890,N,26959,18242,N,55891,55892,
+55893,26960,26961,26971,N,55894,N,26965,26968,55895,N,55896,55897,55898,26964,
+55899,55900,55901,N,N,N,N,N,55902,55903,55904,N,55905,26966,55906,26967,15448,
+N,26969,N,17217,N,14166,13122,N,N,55907,55908,N,26972,55909,N,55910,N,13119,
+55911,26977,55912,N,26973,26976,55913,N,N,55914,18490,55915,N,55916,N,26974,N,
+N,26975,18760,18522,26978,N,N,N,N,N,N,N,N,17021,26988,55918,26984,55919,55920,
+12907,26982,N,19242,26983,55921,55922,26980,55923,26981,26986,26989,55924,N,
+26987,55925,55926,55927,26985,26979,55928,55929,N,N,N,17240,55930,26996,N,
+19498,N,55931,55932,N,55933,N,55934,N,26994,N,N,56097,26995,N,N,N,N,56098,
+56099,N,56100,56101,N,26990,N,N,26992,N,56102,56103,26993,56104,56105,56106,
+26991,56107,N,N,56108,N,56109,N,N,N,16486,N,20281,27000,56110,27001,N,N,N,N,
+27169,N,16170,N,27003,56111,27006,N,N,N,56112,N,26998,26997,56113,N,27170,
+56114,56115,12892,N,27004,N,27171,N,N,N,27005,56116,N,56117,56118,N,27002,N,
+17459,N,26999,N,N,56119,N,N,N,18280,N,N,27175,56120,56121,56122,56123,56124,
+56125,56126,N,56127,56128,19771,N,N,56129,N,N,56130,N,56131,N,56132,56133,
+56134,N,N,N,N,56135,27174,56136,N,27173,56137,N,N,N,56138,N,N,N,27182,56139,
+56140,56141,27176,N,56142,N,27184,N,56143,N,N,N,N,19814,27187,N,27178,56144,
+56145,27179,56146,N,N,27183,N,27186,27185,56147,56148,56149,27177,N,N,56150,N,
+27180,N,27197,N,N,56151,56152,N,N,56153,56154,N,56155,N,N,56156,27190,N,56157,
+56158,56159,N,N,N,N,N,56160,56161,N,56162,N,27188,N,56163,27189,56164,N,N,
+27194,27195,56165,13098,56166,13634,N,N,27193,56167,56168,N,56169,N,27172,
+56170,N,N,56171,56172,56173,N,27192,27196,27191,56174,27198,56176,56177,56178,
+27200,27199,N,56179,56175,56180,56181,56182,N,56183,56184,N,27202,27201,26970,
+N,N,N,27206,56185,N,N,N,N,56186,56187,N,56188,27203,56189,N,N,56190,27204,N,N,
+27205,56353,27207,56354,N,N,N,14188,56355,27209,56356,27208,56357,15664,N,
+56358,56359,56360,56361,14676,24103,56362,N,N,56363,27210,15697,N,56364,56365,
+13113,56366,27211,56367,12626,56368,15959,27212,56369,56370,14677,27213,12385,
+56371,N,N,N,18749,56372,N,27214,N,N,N,N,16234,56373,27221,N,N,27218,N,17263,N,
+56374,N,56375,N,27219,27216,13918,56376,27215,27222,N,N,N,N,N,14134,N,N,16990,
+N,27228,N,N,N,N,27224,N,N,N,16949,27223,56377,27226,56378,56379,56380,N,27217,
+56381,56382,N,27227,N,27229,N,N,N,56383,N,56384,18543,N,N,27225,N,27230,27232,
+N,N,14419,27220,N,12353,N,N,56385,N,N,56386,56387,27231,56388,14939,20086,
+27233,27234,16757,N,N,N,N,56389,56390,56391,56392,56393,20002,N,56394,56395,
+56396,27235,19765,N,N,27236,27237,N,56397,19044,27238,56398,14912,N,20003,N,N,
+N,N,N,56399,27243,N,N,N,N,N,N,56400,56401,56402,27244,15960,27242,56403,N,
+56404,19815,27239,N,N,27241,16445,16254,56405,27240,N,27245,N,56406,18979,N,N,
+27247,N,27246,56407,56408,56409,13164,N,19243,27248,N,56410,56411,N,56412,
+56413,56414,N,56415,27260,27250,N,56416,N,N,N,N,27251,56417,56418,56419,N,
+27252,27253,N,N,N,N,56420,56421,56422,N,N,56423,27257,N,27258,56424,56425,
+27256,N,N,56426,N,56427,27254,56428,27249,27255,56429,56430,N,N,56431,N,N,
+27259,28727,N,56432,N,N,56433,N,N,N,12840,56434,N,N,56435,56436,56437,N,27262,
+13919,27261,56438,56439,56440,27426,N,27425,N,N,N,27428,56441,N,27427,56442,
+27429,56443,N,15665,56444,27430,56445,N,27431,N,N,56446,56609,56610,56611,
+27432,16446,N,19799,N,27433,N,N,18980,18246,27434,56612,27435,14379,N,56613,N,
+13612,56614,N,N,27436,56615,56616,15211,18241,27437,N,13136,56617,56618,N,N,
+56619,56620,27438,N,N,N,56621,27440,19831,N,27439,16198,N,27441,N,N,27442,
+56622,N,27443,13393,56623,56624,56625,56626,N,N,27444,N,56627,27445,N,27446,
+27447,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,13137,N,56628,56629,56630,56631,56632,
+N,27448,N,27449,27450,N,N,N,N,N,12914,N,56633,16168,27451,N,56634,N,56635,N,
+56636,N,N,N,56637,N,56638,27452,N,56639,N,27453,56640,N,N,N,56641,N,56642,
+14400,N,17531,27454,56643,56644,N,56645,14167,N,16214,N,27457,N,17956,56646,
+27456,56647,56648,14129,56649,56650,27455,17015,13613,N,N,27458,N,27459,56651,
+15961,56652,N,56653,14189,56654,27460,56655,N,N,N,19244,56656,56657,16479,N,
+56658,N,13686,N,19573,16714,56659,27461,56660,N,N,16199,17264,15962,56661,
+56662,N,56663,27462,N,56664,N,56665,27465,56666,27466,56667,N,N,N,56668,56669,
+N,14910,16962,27464,56670,15963,18750,56671,56672,56673,N,N,27463,56674,56675,
+15212,N,12627,56676,27470,14168,N,56677,15214,56678,N,15213,N,20301,27469,
+27468,16679,N,13645,20291,13114,15964,N,56679,56680,56681,N,56682,56683,56684,
+27467,N,56685,56686,56687,N,27472,56688,27473,27471,56689,14424,N,19776,N,
+56690,15215,18215,N,56691,56692,27476,56693,16448,N,17218,56694,56695,19766,
+56696,27479,N,N,N,14444,56697,16447,27475,N,27480,14445,27477,27478,56698,
+27474,56699,N,N,16482,17993,56700,56701,17199,N,12893,56702,N,N,56865,56866,N,
+18544,N,56867,13635,N,56868,17460,N,N,27483,56869,27481,N,56870,17228,56871,
+56872,56873,16449,13394,27482,N,16219,N,56874,20042,56875,56876,56877,20288,
+56878,N,N,27484,27495,17461,56879,27494,56880,27491,27499,27492,N,27488,N,
+17532,27487,N,N,N,27485,56881,19745,15216,N,56882,27489,N,27486,56883,56884,
+56885,27493,15732,N,14401,N,56886,N,17018,56887,19269,12634,12386,N,17957,
+56888,56889,27497,N,N,56895,56890,27496,N,18022,N,27501,56891,N,N,27490,N,
+27500,27502,N,14380,27498,14678,56892,15445,56893,56894,27503,19800,N,N,N,N,
+27506,N,27509,N,N,27507,18741,56896,N,N,56897,N,N,27504,N,N,N,56898,N,13920,N,
+N,56899,N,27508,N,N,27510,56900,56901,56902,56903,56904,N,56905,27514,N,N,
+27511,56910,27513,27512,N,N,56906,56907,56908,N,27515,N,15409,56909,27517,
+27516,18792,N,56911,27681,N,N,N,56912,N,N,14169,N,N,N,N,27518,27682,56913,N,
+27683,13636,26177,15993,N,27684,N,56914,14446,56915,56916,N,N,56917,27685,
+56918,N,27686,56919,N,15166,56920,56921,N,N,N,N,23118,56922,27687,56923,27688,
+56924,15666,N,27689,27690,56925,56926,27691,N,N,27692,27693,N,56927,N,56928,
+56929,17195,56930,56931,27694,N,N,56932,56933,27696,N,27695,N,N,N,56934,17958,
+56935,27697,56936,19245,56937,27698,N,27699,56938,27700,56939,N,56940,56941,
+27701,N,56942,56943,56946,18010,56944,N,56945,N,N,N,15965,27702,56947,56948,N,
+56949,N,56950,56951,14699,20526,27703,56952,N,N,N,N,N,56953,N,56954,56955,N,
+27704,18751,27705,56956,27713,N,56957,N,N,N,27706,N,N,27708,56958,57121,N,
+27707,27709,57122,19270,27710,27711,N,57123,N,57124,57125,27712,N,N,N,27714,
+57126,N,57127,57128,13101,17511,N,18793,14946,14679,N,57129,N,N,18767,12895,
+18510,27717,13395,16469,27716,27721,17273,19555,N,27719,27720,13614,N,27722,
+18275,16991,57130,57131,18545,17725,27718,N,19271,12908,27724,20264,17474,
+20293,57132,57133,15217,27723,57134,16945,57135,N,27740,16680,57136,N,18040,N,
+18768,N,57138,57137,N,N,57139,27727,15167,15218,57140,15966,N,18277,57141,
+14381,27726,27725,N,18794,N,57142,N,15425,N,57143,17746,N,57144,57145,N,57146,
+N,N,57147,N,57148,57149,N,27729,27730,14680,27728,57150,57151,57152,N,57153,
+27731,27732,N,27734,16931,57154,27733,13414,N,27736,N,27735,27737,N,57155,
+27739,27741,N,27742,57156,N,N,N,57157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,16470,57158,15439,27743,N,57159,N,13138,57160,27744,
+57161,N,16758,27745,N,27746,18795,N,N,13615,N,N,N,N,N,N,N,57162,N,27747,57163,
+N,57164,17462,N,N,57165,N,12635,N,N,57166,N,N,57167,57168,N,N,N,57169,N,N,N,
+27748,N,N,N,N,57170,57171,57172,N,N,15473,N,N,57173,N,16246,N,N,57174,57175,N,
+N,57176,N,N,57177,16941,N,57178,N,57179,N,57180,27751,57181,57199,N,27750,N,
+57182,N,27749,N,N,57183,57184,57185,57186,N,57187,27757,27755,N,57188,27752,N,
+57189,N,N,57190,57191,27754,57192,N,57193,27753,27756,N,13687,N,27760,N,16471,
+N,27761,57194,57195,N,57196,14425,N,27758,27759,57197,N,N,20265,57198,57200,
+57201,17463,57202,16681,N,N,N,N,N,N,27762,57203,N,27765,57204,N,N,57205,57206,
+57207,N,27763,27764,19801,57208,N,N,N,17959,27768,57209,N,N,57210,N,57211,N,N,
+N,N,N,N,27766,27767,27769,57212,57213,57214,57377,N,N,57378,57379,N,N,27945,N,
+N,N,N,N,27772,57380,N,57381,27773,27771,57382,57383,57384,57385,N,N,N,57386,N,
+N,57387,57388,27770,N,17533,N,N,27937,27941,27938,27774,57389,27939,57390,
+57391,57392,27940,N,N,N,57393,27947,N,N,N,27942,N,57394,57395,57396,57397,
+16472,27944,57398,57399,27946,27943,N,N,N,N,57400,N,N,57401,57402,N,57403,
+57404,57405,27949,N,15667,N,27948,N,N,57406,57407,57408,27950,N,N,N,N,27951,
+57409,57410,27954,27953,N,27952,N,57411,27956,27955,N,19574,N,N,57412,27958,
+57413,27957,27959,57414,N,N,N,27960,57415,57416,N,57417,57418,N,N,27962,57419,
+N,N,N,N,57420,N,57421,27961,16200,27963,57422,57423,13933,27964,27966,N,57424,
+N,57425,N,N,N,N,57426,57427,N,N,27967,N,57428,57429,N,57430,57431,27968,27965,
+57432,27969,N,15446,27970,13616,14131,N,57433,N,57434,14382,N,57435,N,N,N,N,N,
+N,27971,57436,N,N,18032,N,N,17726,27972,N,N,N,N,57437,N,N,27975,N,57444,57438,
+N,57439,57440,N,N,N,N,N,57441,15412,57442,57443,27974,27973,14170,27976,57445,
+N,57446,13139,N,27978,N,57447,57448,14940,27977,N,27986,N,N,57449,57450,N,
+27980,27982,19045,27979,57451,57452,57453,27981,N,27985,27983,13617,57454,
+27984,57455,57456,N,57457,N,57458,27987,57459,57460,18266,20056,N,57461,57462,
+57463,15668,N,N,N,27988,57464,57465,57466,57467,19746,27990,57468,27989,N,N,
+27993,19777,57469,57470,27992,57633,13165,27991,27996,57634,N,27995,N,N,27994,
+17714,27997,57635,N,57636,57637,57638,57639,57640,N,27998,57641,N,N,N,27999,
+57642,57643,14700,N,14117,28000,28001,28002,57644,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+16201,28003,57645,15405,28004,57646,57647,N,28005,57648,57649,57650,21025,
+20862,N,N,N,N,28006,25968,28007,17188,16171,18240,N,N,57651,57652,28008,57653,
+N,19029,17492,14718,N,57654,17193,57655,57656,12586,N,19320,16215,57657,N,N,N,
+57658,57659,N,57660,14174,N,57661,13921,57662,57663,19030,57664,N,N,N,N,28009,
+N,N,N,N,N,57665,N,28011,57666,57667,28010,12896,N,57668,18038,28012,18295,N,
+17715,57669,28013,15698,57670,N,N,28015,57671,57672,19522,28030,28017,28018,
+57673,N,17481,57674,16992,16759,57675,17960,57676,28016,13653,N,57677,N,N,
+28025,57678,28022,28197,17961,17248,28019,N,17534,17747,28020,28024,16224,
+57679,18279,17484,57680,N,16450,28023,16942,16932,28021,12329,20258,N,N,N,
+28026,57681,57682,57684,N,57685,57686,16993,57683,N,15669,16202,57687,57688,
+28028,28027,57689,12399,28029,N,N,18735,N,28199,57690,N,18011,16235,57691,
+57692,17241,N,13944,N,28198,19767,12607,57693,19031,12897,28193,28194,28195,
+28196,17979,17187,12387,28200,N,28201,29731,N,57694,16957,57695,28202,N,12659,
+16716,57696,14383,N,19802,57697,57698,28203,17708,N,N,57699,16760,15447,28204,
+57700,N,28207,N,57701,15717,28205,16683,16682,57702,12388,N,20043,28209,N,
+18546,28211,28210,28208,25444,13396,57703,N,28014,57704,28213,28212,57705,
+57706,N,57707,28214,57708,19768,N,N,N,57709,N,57710,57711,57712,N,57713,N,N,N,
+N,57714,57715,57716,18017,N,57717,19246,N,28215,N,15449,N,N,N,N,28216,57718,
+28217,57719,57720,57721,28218,57722,N,17697,N,N,N,N,57723,57725,N,N,12394,N,
+57726,57889,57890,N,57891,57892,N,14681,N,57724,N,20282,N,N,N,57901,N,N,57893,
+N,57894,57895,57896,N,28222,57897,57898,N,57899,N,14132,28219,N,28220,57900,N,
+N,18804,N,N,57903,N,13140,N,57904,57905,N,N,N,57906,19769,57902,13887,N,N,N,N,
+N,17748,57907,57908,57909,N,28223,N,57910,57911,57912,N,57913,N,N,N,N,57914,N,
+N,57915,N,28224,N,57916,N,57917,57918,57919,28225,57920,N,57921,N,57922,N,
+57923,N,57925,57926,N,57924,N,57927,N,57928,N,N,N,17698,57929,57930,28227,
+57931,28226,N,57932,N,57933,57934,N,57935,57936,N,57937,57938,N,N,N,N,N,57939,
+N,N,N,57940,57941,18003,28228,15670,15456,18267,17265,57942,N,N,15474,57943,
+16236,N,28229,57944,28230,57945,57946,57947,N,N,N,N,N,57948,16221,28231,57949,
+28232,N,57950,N,28233,19823,N,15671,57951,N,N,N,N,28235,28234,57952,14682,N,
+14707,15168,57953,57954,57955,N,N,N,N,N,57956,28238,57957,N,57958,57959,15718,
+N,28237,57960,28236,N,17001,57961,N,14447,57962,16451,57963,57964,57965,N,
+18480,57966,N,N,N,15673,N,57967,N,N,57968,28239,N,15967,N,57969,N,57970,N,
+28242,28240,57971,57972,57973,28241,57974,57975,57976,57977,28244,28243,57978,
+N,15994,N,28245,57979,57980,57981,N,57982,28246,28247,58145,58146,N,58147,
+18512,14931,15457,28248,N,28249,20004,15685,19566,20044,28250,13922,N,58148,
+58149,N,28251,58150,17699,58151,58152,28254,13176,16203,58153,28252,N,28253,N,
+17504,58154,58155,19285,13948,N,58156,58157,N,58158,58159,58160,58161,58162,
+58163,N,N,N,28256,28257,58164,N,58165,N,58166,28255,58167,N,28259,58168,58169,
+N,N,58170,58171,58172,58173,N,58174,58175,N,58176,18015,13123,N,58177,28263,
+58178,58179,28260,28262,58180,N,58181,N,N,N,58182,58183,28258,N,N,N,N,58184,
+58185,58186,58187,N,58188,28495,N,N,28261,N,58189,58190,58191,N,N,58192,20075,
+58193,58194,14426,58195,58196,58197,N,58198,N,58199,28271,58200,N,58201,58202,
+17716,28266,58203,58204,28269,28267,58205,28272,N,58206,58207,58208,28273,
+58209,N,N,N,N,N,28265,58210,58211,28278,12660,58212,58213,28264,N,58214,58215,
+18477,N,28268,58216,15968,58217,58218,58219,N,N,N,N,58220,58221,58222,14683,N,
+N,N,58223,58224,58225,58226,58227,N,58228,58229,58230,19272,58231,13924,N,N,
+15686,N,17980,N,N,58232,58233,58234,N,N,58235,58236,N,N,16685,58237,28276,N,
+28270,28275,58238,19523,58401,17464,28277,28274,N,N,58402,58403,N,N,N,58404,
+58405,N,58406,58407,N,N,58408,N,16684,N,58409,N,N,58410,N,N,N,58411,28281,
+58412,28280,58413,58414,58415,58416,N,58417,58418,58419,58420,58421,N,58422,
+58423,58424,58425,N,N,58426,58427,58428,58429,28279,58430,N,19247,58431,N,
+58432,N,58433,58434,58435,N,N,58436,58437,N,58438,58439,58440,N,58441,15739,
+58442,N,58443,58444,28282,19039,N,58445,12628,58446,N,58447,N,18758,17266,N,N,
+N,N,13688,58448,28284,58449,14685,N,N,58450,58451,N,58452,N,N,N,15148,N,58453,
+N,N,N,N,58454,N,28283,16237,58455,N,N,58456,58457,N,N,16238,28449,28451,N,
+58458,58459,58460,58461,15995,58462,28450,28452,58463,58464,13907,58465,18757,
+58466,58467,15458,20259,N,28286,14968,N,N,20287,58468,58469,28454,58470,58471,
+N,N,28453,28455,N,N,N,N,N,N,N,N,28285,N,N,58472,58473,58474,N,18025,N,17749,N,
+N,58475,58476,58477,N,17495,58478,28460,58479,58480,N,58481,17219,28456,N,
+58482,N,28457,N,N,N,58483,58484,N,58485,N,58486,58487,N,14125,58488,28459,
+58489,58490,58491,N,58492,58493,14384,58494,N,N,N,58657,N,28458,58658,15969,
+58659,58660,58661,58662,N,N,N,N,N,58663,N,58664,58665,13177,58666,N,58667,N,N,
+58668,N,28464,58669,14911,16761,58670,N,17482,58671,N,N,58672,N,N,58673,N,
+58674,58675,N,58676,13115,58677,58683,N,58678,28462,28463,17475,N,28461,N,N,N,
+58679,58680,58681,N,N,28465,58682,N,N,N,N,N,N,58684,N,28471,58685,58686,58687,
+58688,28474,58689,58690,58691,58692,58693,N,N,28473,17709,N,58694,N,N,28466,
+28467,28470,58695,N,N,58696,28472,58697,58698,N,13888,58699,N,28475,28469,
+58700,58701,28468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58703,58704,58702,58705,58706,N,
+58707,58708,58709,28479,58710,N,N,28480,58711,58712,N,N,N,58713,58714,58715,
+28481,N,N,28478,28477,58716,58717,58718,15970,17962,28476,N,N,N,N,58719,N,
+28485,N,N,N,N,N,N,N,N,N,28483,N,N,58720,58721,N,58722,58723,58724,58725,28484,
+28482,N,17016,N,28486,58726,N,58728,N,58727,N,28487,N,58729,28489,58730,N,N,
+58731,N,58732,N,58733,N,N,N,N,13397,28488,19578,N,58734,N,N,N,58735,28500,
+28490,58736,N,28493,58737,28491,58738,28492,58739,N,N,N,N,58740,N,28494,58741,
+N,58742,58743,58744,28496,58745,58746,N,N,28497,N,28498,N,N,N,N,28501,28499,
+28502,28504,N,28503,N,58748,58747,17465,58749,58750,N,N,N,N,58913,N,19559,N,
+28505,16686,58914,N,N,28506,58915,19012,28507,13099,58916,58917,58918,12604,N,
+13399,N,13398,28508,N,28509,N,28510,28511,N,N,N,58919,58920,58921,28512,58922,
+13400,13141,14686,18486,58923,28514,28513,58924,N,58925,58926,28515,N,N,N,N,
+12636,N,58927,N,58928,N,N,28518,58929,28517,28516,58930,28519,58931,N,N,N,
+28522,N,N,58932,12359,58933,58934,28520,58935,28524,28523,N,N,58936,58937,
+58938,58939,28526,28525,28527,N,17966,58940,58941,N,28528,58942,58943,58944,
+58945,28529,28531,N,58946,28530,58947,18796,58948,58949,N,N,28532,58950,N,
+58951,58952,58953,N,28533,N,14949,N,58954,N,28534,28535,N,58955,19273,58956,N,
+N,N,58957,58958,58959,58960,16715,58961,58962,N,12324,16971,58963,28536,N,
+18797,N,N,N,N,N,N,28539,28537,14687,N,28538,14402,N,58964,N,58965,N,58966,
+58967,58968,N,N,19013,28541,28705,28542,28706,N,58969,12577,16216,15740,13401,
+28707,N,N,N,18278,N,28709,N,58970,N,12578,N,28708,17476,58971,20045,17963,
+28540,20006,N,14385,58972,58973,19803,58974,58975,N,58976,58977,58978,58979,
+13945,20020,N,14120,58980,16994,26401,N,28710,13100,16239,N,58981,N,N,13142,
+28712,58982,28713,28711,14180,58983,14941,15971,58984,N,58985,12579,N,N,20057,
+58986,58987,58988,28715,28206,58989,28714,N,N,N,58990,58991,28718,28716,28717,
+58992,28719,N,28720,20076,28721,28722,58993,16457,18491,N,N,N,16253,13415,N,N,
+19770,12909,15672,14427,N,28725,58994,28724,15219,28726,28723,N,N,15144,58995,
+N,N,28730,27181,N,58997,21078,58998,16247,28728,58999,59000,59001,N,N,20005,
+18033,N,N,N,N,12587,59002,16483,15414,N,N,N,59003,18999,59004,12608,N,N,N,
+20077,19819,N,28731,59005,17733,15483,N,59006,59169,28732,59170,28733,16204,
+28734,59171,20078,N,N,28729,28736,28738,N,28737,N,28735,N,N,28739,N,N,28740,
+59172,59173,16762,59174,12898,N,N,59175,59176,59177,28741,N,N,19512,59178,N,
+28742,N,N,N,N,N,28743,59179,20266,59180,N,N,N,N,23345,28744,N,N,N,28745,28746,
+N,N,59181,28750,59182,28747,N,28748,N,28749,28751,59183,N,N,N,59184,59185,N,N,
+16452,N,N,59186,19575,59187,59188,16453,59189,59190,28752,N,18547,N,28753,
+29523,19532,59191,28754,N,28755,59192,28756,13143,59193,28758,N,16217,59194,N,
+N,28759,N,59195,14116,N,59196,59197,59198,28760,28764,59199,28762,59200,N,
+59201,59202,28763,N,N,13171,28761,28765,N,N,59203,N,28766,N,12360,N,28767,
+28768,N,N,N,N,59204,59205,59206,15972,59207,59208,N,28769,N,59209,59210,13639,
+N,59211,28772,N,N,28771,N,28770,N,N,27505,59212,19036,59213,N,N,59214,59215,
+28773,28774,59216,59217,N,59218,59219,59220,N,59221,N,59222,59223,N,59224,N,
+28775,59225,59226,28776,59227,28777,59228,59229,28778,59230,59231,59232,N,
+59233,59234,N,13402,59235,N,N,59236,59237,59238,N,59242,28779,59239,59240,N,
+59241,59243,N,N,59244,N,N,N,N,N,N,N,N,28780,18211,59245,N,59246,28782,12859,
+59247,28785,28784,59248,59249,N,59250,12580,N,N,N,13889,19015,17466,14882,N,
+14688,15719,59251,16220,N,59252,N,28787,59254,59255,28786,19778,13416,18514,
+18012,59256,N,59257,16252,20046,59253,14171,N,59258,N,59259,N,59260,28790,N,
+59261,28789,59432,59262,N,N,N,N,59425,19275,17964,59426,59427,59428,N,59429,
+59430,12624,59431,N,28791,28788,N,N,18769,19818,28792,59433,N,N,N,N,N,59434,N,
+28793,59435,N,N,59436,28795,17002,13147,13148,28794,N,59437,59438,59439,13417,
+14386,59440,59441,13418,59442,59443,17727,N,N,20064,N,N,N,59444,59445,N,59446,
+59447,14428,N,N,59448,28796,59449,N,N,28797,28798,28961,N,28963,28962,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,18807,N,28964,59450,N,59451,59452,28965,59453,28966,N,N,59454,
+N,28967,59455,59456,N,59457,59458,N,N,N,59459,N,N,59460,28969,28968,59461,
+28970,N,59462,N,N,N,59463,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18548,26188,N,N,16169,N,
+59464,13618,59465,N,59466,59467,59468,N,28971,59469,28972,N,21036,23867,18515,
+N,N,12411,59470,12347,N,59471,N,N,N,N,N,15220,19248,15998,59472,28973,N,19551,
+N,59473,59474,28974,19804,N,12610,N,N,N,15169,59475,28975,12910,28976,59476,
+59477,59478,28977,N,59479,59480,59481,28979,28980,59482,28982,28978,59483,N,
+28981,N,59484,59485,13403,N,N,59486,28983,N,28984,N,N,59487,59488,59489,59490,
+59491,N,N,N,59492,59493,59494,59495,28985,28986,N,59496,59497,28987,N,N,28989,
+59498,59499,59500,28988,N,28991,28994,59501,59502,N,28990,28992,28993,N,59503,
+28995,N,13890,59504,59505,N,59506,59507,N,59508,59509,59510,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,15475,28996,28997,14689,N,59511,N,59512,N,59513,N,N,N,N,N,28998,
+59514,N,13118,N,N,N,18255,28999,29000,N,59515,59516,59517,17242,18027,59518,N,
+N,N,59681,59682,N,29001,59683,N,59684,N,18301,N,59685,16972,12632,13934,N,
+13935,59686,N,N,N,N,N,N,17267,29006,13936,59687,59688,12911,N,N,29005,59689,
+59690,29003,59691,29004,59692,29002,N,N,29016,N,N,N,N,59693,N,N,59694,59695,
+59696,29007,29008,N,59697,29009,29010,N,59698,59699,N,N,29012,59700,N,29011,N,
+59701,59702,15705,29013,59703,59704,59705,29015,N,N,N,N,N,59706,59707,N,13619,
+29014,59708,59709,16763,14387,N,N,59710,N,N,29017,N,N,N,N,59711,N,59712,N,
+59713,59714,59715,N,N,59716,16973,N,N,29018,N,59717,59718,N,17965,N,N,59719,N,
+59720,59721,29019,59722,N,N,N,N,N,29024,N,29022,59724,29021,29023,59725,29020,
+N,59723,N,N,59726,59727,59728,29026,59729,N,N,59730,N,N,59731,29025,59732,
+29028,N,N,13891,29027,N,59733,N,29029,N,N,29030,N,29032,29031,N,N,N,29033,
+29035,29034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,14716,N,59734,N,59735,
+29036,59736,59737,29037,N,59738,N,59739,59740,59741,N,13116,59742,N,59743,
+29038,N,59744,59745,29039,59746,N,59747,16241,N,59748,N,59749,N,N,N,N,N,59750,
+29040,59751,29041,59752,29042,29043,59753,59754,59755,14690,N,N,59756,59757,N,
+29044,29045,59758,N,29046,29047,59759,59760,29048,59761,N,59762,18481,29050,
+59763,18726,29051,29049,N,29053,59764,59765,29052,59766,N,29054,N,59767,59768,
+29217,N,59769,N,59770,59771,59772,59773,59774,59937,59938,29218,N,59939,59940,
+N,59941,59942,59943,59944,N,59945,N,59946,N,N,N,59947,N,29219,59948,29220,
+59949,59950,N,N,29221,59951,N,29222,29223,N,29224,59952,29225,29226,29227,
+29228,59953,N,59954,29229,29230,N,23861,29231,59955,59956,59957,N,59958,N,
+59959,59960,25720,13620,59961,N,N,N,13089,14898,29233,29232,19493,N,N,59962,N,
+N,59963,59964,29235,29236,29234,N,29237,N,N,19298,59965,59966,59967,29238,N,
+13691,59968,N,N,59969,N,N,59970,N,59971,N,59972,59973,N,59974,N,59975,59976,
+59977,59978,59979,20261,N,N,N,59980,29239,59981,N,59982,59983,59984,N,N,N,N,N,
+59985,59986,N,N,29241,59987,59988,59989,59990,N,59991,59992,59993,N,59994,
+12350,59995,59996,29242,18987,29240,59997,N,29243,29244,N,N,59998,N,N,59999,
+60000,29245,29246,N,N,N,N,N,60001,60002,29247,60003,19310,15149,60004,14970,
+16687,N,60005,60006,60007,N,29248,N,N,60008,60009,29251,N,60010,60011,N,60012,
+60013,29249,60014,N,N,N,N,29252,60015,60016,14449,29250,N,N,N,60017,29253,
+60018,29254,29255,N,29259,N,15146,60019,60020,N,N,16996,N,60021,N,60022,N,
+29260,29257,29256,29258,60023,N,60024,14175,N,60025,60026,N,N,N,60027,29264,
+29263,29262,60028,N,12339,N,60029,60030,60193,60194,N,N,60195,N,60196,60197,N,
+60198,N,29274,N,29270,N,29271,29267,29273,60199,29269,13154,N,60200,20300,
+60201,29272,29268,29266,29265,60202,N,60203,60204,60205,29276,60206,N,60207,N,
+N,29279,60208,60209,29278,29277,60210,60211,60212,60213,60214,N,N,18761,29275,
+12403,29280,60215,29282,N,N,60216,60217,60218,N,13167,29261,12599,N,60219,
+29284,N,N,60220,N,60221,60222,60223,29283,29281,17197,60224,60225,N,N,N,60226,
+60227,60228,N,19312,60229,60230,N,60231,20058,60232,N,29285,60233,60240,60234,
+60235,60236,29286,N,N,60237,N,N,N,29287,60242,60238,60239,60241,N,N,60243,N,
+60244,N,60245,N,N,60246,29288,60247,29289,N,N,60248,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,17467,60249,29290,N,18487,N,29295,29291,N,N,N,
+29292,N,60250,19249,19524,N,18000,60251,N,60252,60254,29296,N,N,29297,17982,
+29294,29293,N,60253,N,N,12842,N,N,60255,29305,N,N,29304,N,60256,60257,N,N,
+12661,60258,60259,60260,29302,N,N,N,29301,N,N,29299,N,13179,N,29298,15410,
+12841,N,N,60261,60262,N,60263,60264,60265,N,N,N,N,N,60266,14691,60267,60269,
+29308,29307,N,29306,60270,60271,29303,60268,29309,60272,29310,N,60273,N,N,N,N,
+N,29477,29476,N,60274,60275,N,N,N,N,29478,N,N,12589,29473,29474,60276,14708,
+19513,60278,60277,29475,60279,N,N,N,60280,60281,60282,19250,N,N,29483,60283,N,
+29479,N,N,N,60284,60285,N,N,29484,60286,60449,N,60450,N,N,N,N,60451,60452,N,
+60453,29481,N,29480,60454,N,N,60455,60456,14172,N,N,60457,60458,N,60459,60460,
+60461,60462,N,29485,N,N,N,N,N,N,60463,N,N,29486,N,N,N,N,29487,60464,29482,
+60465,N,60466,29300,N,60467,29488,N,17505,60468,N,N,29492,60469,29493,29491,
+60470,N,N,60471,N,29490,29496,60472,29489,N,29494,60473,N,60474,60475,N,N,N,N,
+29495,N,N,N,29498,60476,60477,60478,60479,N,29497,60480,N,N,N,60481,60482,
+60483,N,N,N,N,60484,29500,60485,N,60486,N,60487,N,29501,60488,29502,60489,N,
+20297,60490,60491,N,N,N,29499,17003,14957,N,N,29503,60492,60494,N,N,N,N,60495,
+N,N,60493,N,N,N,60496,N,60497,60498,60499,N,N,60500,60501,N,N,60502,29504,
+29505,60503,60504,29506,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29507,N,N,14388,29508,60505,60506,
+60507,29509,N,15407,60508,29510,60509,60510,60511,60512,N,60513,29511,N,N,
+29512,29513,N,60514,60515,N,29516,29514,20284,N,29515,60516,20079,60517,N,N,
+60518,N,29517,60519,20059,N,N,N,N,60520,29518,18302,N,60521,29519,29521,N,
+60522,29522,60523,60524,60525,N,N,60526,60527,60528,N,N,29520,14701,19533,
+19299,22135,N,23904,19323,N,N,N,N,12843,N,60529,N,60530,N,N,60531,29524,13648,
+29525,29526,29527,N,14709,N,29528,60532,N,N,24660,19547,N,16995,29529,29531,
+29530,60533,29532,N,N,N,60534,29533,N,60535,29534,N,N,N,60536,60537,60538,
+29535,60539,60540,60541,N,29536,60542,29537,29538,60705,29539,N,29540,29541,
+29542,N,60706,60707,60708,N,N,N,29543,29544,60709,N,N,N,N,17700,60710,60711,
+60712,60713,14429,60714,29546,60715,60716,N,60717,60718,60719,N,N,N,60720,
+16717,29547,60721,N,N,N,60722,N,N,N,60723,60724,29548,N,N,60725,N,60726,60727,
+N,60728,N,N,60729,N,60730,60731,18721,60732,60733,29549,60734,N,60735,N,60736,
+60737,60738,60739,60740,N,N,29550,25399,N,N,27738,28781,N,N,29551,60741,29552,
+60742,60743,60744,60745,N,60746,N,N,60747,60748,29554,29555,29556,20080,29553,
+N,N,29557,29558,60749,60750,29560,N,29559,60751,60752,60753,60754,60755,29562,
+60756,N,60757,29563,29561,N,N,60758,N,N,60759,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+20022,N,60760,60761,60762,60763,N,60764,29564,60765,60766,N,N,N,N,29565,25428,
+60767,N,29566,60768,60769,60770,N,60771,8490,N,8564,8560,8563,8565,N,8522,
+8523,8566,8540,8484,N,8485,8511,9008,9009,9010,9011,9012,9013,9014,9015,9016,
+9017,8487,8488,8547,8545,8548,8489,8567,9025,9026,9027,9028,9029,9030,9031,
+9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046,
+9047,9048,9049,9050,8526,N,8527,8496,8498,8494,9057,9058,9059,9060,9061,9062,
+9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,
+9078,9079,9080,9081,9082,8528,8515,8529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8497,
+N,8559,
+};
+
+static const struct unim_index jisxcommon_encmap[256] = {
+{__jisxcommon_encmap+0,92,255},{__jisxcommon_encmap+164,0,245},{
+__jisxcommon_encmap+410,199,221},{__jisxcommon_encmap+433,132,206},{
+__jisxcommon_encmap+508,1,95},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{__jisxcommon_encmap+603,16,59},{__jisxcommon_encmap+647,3,212},{
+__jisxcommon_encmap+857,0,165},{__jisxcommon_encmap+1023,18,18},{0,0,0},{
+__jisxcommon_encmap+1024,0,239},{__jisxcommon_encmap+1264,5,111},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisxcommon_encmap+1371,0,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisxcommon_encmap+1626,0,255},{
+__jisxcommon_encmap+1882,0,255},{__jisxcommon_encmap+2138,0,254},{
+__jisxcommon_encmap+2393,0,254},{__jisxcommon_encmap+2648,0,255},{
+__jisxcommon_encmap+2904,0,250},{__jisxcommon_encmap+3155,1,255},{
+__jisxcommon_encmap+3410,0,255},{__jisxcommon_encmap+3666,5,255},{
+__jisxcommon_encmap+3917,0,255},{__jisxcommon_encmap+4173,0,253},{
+__jisxcommon_encmap+4427,2,255},{__jisxcommon_encmap+4681,0,253},{
+__jisxcommon_encmap+4935,0,255},{__jisxcommon_encmap+5191,1,253},{
+__jisxcommon_encmap+5444,1,254},{__jisxcommon_encmap+5698,0,255},{
+__jisxcommon_encmap+5954,1,255},{__jisxcommon_encmap+6209,7,253},{
+__jisxcommon_encmap+6456,0,255},{__jisxcommon_encmap+6712,0,255},{
+__jisxcommon_encmap+6968,1,250},{__jisxcommon_encmap+7218,6,255},{
+__jisxcommon_encmap+7468,0,255},{__jisxcommon_encmap+7724,0,255},{
+__jisxcommon_encmap+7980,0,255},{__jisxcommon_encmap+8236,2,253},{
+__jisxcommon_encmap+8488,0,255},{__jisxcommon_encmap+8744,0,253},{
+__jisxcommon_encmap+8998,2,255},{__jisxcommon_encmap+9252,2,244},{
+__jisxcommon_encmap+9495,4,252},{__jisxcommon_encmap+9744,0,255},{
+__jisxcommon_encmap+10000,1,254},{__jisxcommon_encmap+10254,0,253},{
+__jisxcommon_encmap+10508,3,255},{__jisxcommon_encmap+10761,0,254},{
+__jisxcommon_encmap+11016,2,255},{__jisxcommon_encmap+11270,0,255},{
+__jisxcommon_encmap+11526,3,255},{__jisxcommon_encmap+11779,0,254},{
+__jisxcommon_encmap+12034,0,252},{__jisxcommon_encmap+12287,2,255},{
+__jisxcommon_encmap+12541,0,252},{__jisxcommon_encmap+12794,0,255},{
+__jisxcommon_encmap+13050,2,254},{__jisxcommon_encmap+13303,0,254},{
+__jisxcommon_encmap+13558,0,251},{__jisxcommon_encmap+13810,0,158},{
+__jisxcommon_encmap+13969,54,255},{__jisxcommon_encmap+14171,0,254},{
+__jisxcommon_encmap+14426,2,255},{__jisxcommon_encmap+14680,0,254},{
+__jisxcommon_encmap+14935,0,253},{__jisxcommon_encmap+15189,1,255},{
+__jisxcommon_encmap+15444,0,255},{__jisxcommon_encmap+15700,0,254},{
+__jisxcommon_encmap+15955,0,255},{__jisxcommon_encmap+16211,1,254},{
+__jisxcommon_encmap+16465,1,255},{__jisxcommon_encmap+16720,0,255},{
+__jisxcommon_encmap+16976,0,159},{__jisxcommon_encmap+17136,55,255},{
+__jisxcommon_encmap+17337,1,255},{__jisxcommon_encmap+17592,1,254},{
+__jisxcommon_encmap+17846,0,254},{__jisxcommon_encmap+18101,0,255},{
+__jisxcommon_encmap+18357,0,255},{__jisxcommon_encmap+18613,0,255},{
+__jisxcommon_encmap+18869,0,253},{__jisxcommon_encmap+19123,1,132},{
+__jisxcommon_encmap+19255,119,230},{__jisxcommon_encmap+19367,28,251},{
+__jisxcommon_encmap+19591,0,255},{__jisxcommon_encmap+19847,1,254},{
+__jisxcommon_encmap+20101,2,255},{__jisxcommon_encmap+20355,1,255},{
+__jisxcommon_encmap+20610,0,255},{__jisxcommon_encmap+20866,0,249},{
+__jisxcommon_encmap+21116,2,254},{__jisxcommon_encmap+21369,2,255},{
+__jisxcommon_encmap+21623,2,165},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__jisxcommon_encmap+21787,1,229},
+};
+
+static const ucs2_t __cp932ext_decmap[969] = {
+65340,65374,8741,65372,8230,8229,8216,8217,8220,8221,65288,65289,12308,12309,
+65339,65341,65371,65373,12296,12297,12298,12299,12300,12301,12302,12303,12304,
+12305,65291,65293,177,215,U,247,65309,8800,65308,65310,8806,8807,8734,8756,
+9794,9792,176,8242,8243,8451,65509,65284,65504,65505,65285,65283,65286,65290,
+65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,
+8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U,8712,8715,8838,
+8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,65506,9312,9313,9314,9315,
+9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,
+9331,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,13129,13076,13090,
+13133,13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,
+13212,13213,13214,13198,13199,13252,13217,U,U,U,U,U,U,U,U,13179,U,12317,12319,
+8470,13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,
+13180,8786,8801,8747,8750,8721,8730,8869,8736,8735,8895,8757,8745,8746,32394,
+35100,37704,37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,
+20220,20224,20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,
+20510,20550,20592,20546,20628,20724,20696,20810,20836,20893,20926,20972,21013,
+21148,21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,
+21642,21673,21759,21894,22361,22373,22444,22472,22471,64015,U,64016,22686,
+22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,
+23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,
+24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,
+24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,
+26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,
+26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,
+27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,
+27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,
+28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,
+28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,
+29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,
+30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,
+64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,
+32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,
+33864,33972,34131,34137,U,34155,64031,34224,64032,64033,34823,35061,35346,
+35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,
+64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,
+37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,
+37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,
+37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,
+37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,
+38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,
+39794,39823,39857,39867,39936,40304,40299,64045,40473,40657,U,U,8560,8561,
+8562,8563,8564,8565,8566,8567,8568,8569,65506,65508,65287,65282,8560,8561,
+8562,8563,8564,8565,8566,8567,8568,8569,8544,8545,8546,8547,8548,8549,8550,
+8551,8552,8553,65506,65508,65287,65282,12849,8470,8481,8757,32394,35100,37704,
+37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224,
+20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550,
+20592,20546,20628,20724,20696,20810,U,20836,20893,20926,20972,21013,21148,
+21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,21642,
+21673,21759,21894,22361,22373,22444,22472,22471,64015,64016,22686,22706,22795,
+22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,23582,23718,
+23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,24372,24423,
+24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,24880,24984,
+25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,26158,26142,
+26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,26382,63785,
+26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,27106,27184,
+27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,27866,27908,
+28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,28220,28351,
+28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,28998,28999,
+64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,29667,29650,
+29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,30338,30364,
+30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,64024,64025,
+U,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,32092,
+32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,33864,
+33972,34131,34137,34155,64031,34224,64032,64033,34823,35061,35346,35383,35449,
+35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,64035,36559,
+64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,37358,37348,
+37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,37479,37543,
+37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,37665,37627,
+64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,37937,37957,
+37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,38737,38741,
+38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,39794,39823,
+39857,39867,39936,40304,40299,64045,40473,40657,
+};
+
+static const struct dbcs_index cp932ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_decmap+0,95,202},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__cp932ext_decmap+108,64,156},{0,0,0},{0,0,0},{0,0,0},{0,0,
+0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{__cp932ext_decmap+201,64,252},{__cp932ext_decmap+390,64,252},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__cp932ext_decmap+579,64,252},{__cp932ext_decmap+768,64,252},{
+__cp932ext_decmap+957,64,75},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __cp932ext_encmap[9686] = {
+34690,N,N,N,N,N,N,N,N,N,N,34692,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,N,N,N,N,N,N,61167,
+61168,61169,61170,61171,61172,61173,61174,61175,61176,34708,N,N,N,N,N,N,N,N,N,
+N,N,N,N,34712,N,N,N,N,N,33121,N,N,N,N,N,N,N,N,34707,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,34713,34624,34625,34626,34627,34628,34629,34630,
+34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643,
+34688,N,34689,34698,34699,N,N,N,N,N,N,34700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,34693,34694,34695,34696,34697,34661,N,N,N,N,N,N,N,N,N,
+34665,N,N,N,N,N,N,34656,N,N,N,34659,N,N,N,N,N,N,N,N,N,34657,34667,N,N,34666,
+34660,N,N,N,34668,N,N,N,N,N,N,N,N,N,N,34662,N,N,N,N,34670,N,N,N,N,N,N,N,N,N,N,
+N,N,N,34655,34669,N,N,34658,N,N,N,34663,N,N,N,N,N,34664,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34686,34703,34702,34701,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,34674,34675,N,N,N,N,N,N,N,N,N,N,N,N,34671,34672,34673,
+N,N,34677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+34676,N,N,N,N,N,N,N,N,34691,60748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,60749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60750,
+60751,N,N,60752,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60753,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,60754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60756,N,N,N,N,N,N,N,
+60755,N,60758,N,N,N,N,N,60757,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60741,N,N,N,60759,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,60762,60763,N,N,N,60761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,60760,N,60766,N,N,N,60764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60769,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60768,60770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60771,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,60773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60774,60775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,60776,N,N,N,N,N,N,N,N,N,60777,N,N,N,N,N,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,60778,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60779,
+60780,N,N,N,N,N,N,60781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60784,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60785,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60786,60789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60788,N,N,N,N,N,N,N,N,N,N,N,N,
+60790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60791,60792,60793,N,N,N,N,N,N,N,N,N,N,N,60794,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60795,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60797,60796,60801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,60802,60803,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60804,N,N,N,N,N,N,N,60805,N,60806,N,N,N,N,N,60807,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,60808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60809,60810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60811,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60814,60815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60816,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60818,60819,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60822,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,60820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60823,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60824,60825,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60826,60827,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,60828,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60747,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60829,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60830,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60831,60832,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60833,N,N,
+N,N,60834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60836,N,N,N,N,N,N,N,N,60835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60838,
+60839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60837,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60841,N,
+N,N,N,N,N,60840,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60842,60843,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60844,60845,60846,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60847,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60848,60849,60850,N,N,N,N,N,
+N,N,N,60853,N,N,N,N,N,N,N,N,N,N,N,60851,N,N,N,N,N,N,N,N,60855,N,N,N,N,N,60856,
+N,N,N,N,N,N,N,N,N,60854,N,N,60743,N,N,N,N,N,N,N,N,N,60852,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60858,N,60859,N,N,N,N,N,N,N,N,N,N,N,60857,N,
+N,N,N,N,N,N,N,N,N,N,N,N,60861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60862,N,N,N,N,N,N,60863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60864,N,N,N,N,N,N,N,N,N,N,N,N,60865,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,60866,60746,60867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60870,N,N,N,N,60872,
+60873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60874,N,N,N,N,N,N,
+N,N,N,N,N,N,N,60871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,60744,N,N,N,N,N,N,60875,60877,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60879,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60880,60881,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60883,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60882,N,N,N,N,N,N,N,60884,N,N,N,N,N,N,N,
+N,N,N,60885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60886,N,60887,60888,
+60889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60890,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,60892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60891,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,60893,60894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60895,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,60897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60898,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60899,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60901,N,N,N,N,N,60900,N,
+N,N,60902,60905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60903,N,N,60906,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60904,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,60907,60908,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60909,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,60910,60911,N,60912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,60913,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60914,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60915,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,60742,60917,N,N,N,N,N,N,N,N,N,N,60916,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,60919,60920,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60918,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60922,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60923,60924,N,N,N,N,N,N,N,N,N,N,N,N,60992,60993,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60995,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60996,N,N,N,N,N,N,N,N,N,N,N,60997,
+N,N,N,N,N,N,N,N,61000,N,N,N,60998,N,N,N,N,N,N,N,N,N,N,N,N,60999,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,61002,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61003,N,N,61005,61004,N,N,N,61006,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61007,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61008,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61009,61010,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60812,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61011,61012,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61015,61013,N,61014,N,N,N,N,N,N,N,61016,61018,
+61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61022,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61023,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61028,N,N,N,N,N,N,61030,61031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61032,N,N,N,61034,61035,61037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61038,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61040,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61039,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61041,61042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60736,61043,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61044,61046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61047,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61048,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61050,61051,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61052,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60740,61053,N,N,N,N,
+N,61054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61056,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61058,61061,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61062,60737,61063,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61064,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61066,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,61068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61070,
+61071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61072,61073,N,N,N,61074,61075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,61076,61078,61081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61082,61084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61087,N,N,61086,N,N,N,61088,N,N,N,
+N,N,61091,61092,N,N,N,N,N,N,N,61089,61090,61093,N,N,N,61095,N,N,N,N,N,61094,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61102,61096,N,61098,N,N,N,61097,N,N,N,N,N,N,N,N,N,N,N,N,N,61099,N,N,61101,N,N,
+N,N,N,N,N,61100,N,N,N,N,N,N,N,N,N,N,N,N,N,61103,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61105,61106,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61104,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61110,N,N,61114,N,61112,N,61108,N,61109,
+N,N,N,N,N,N,61113,N,N,N,N,N,N,61107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60745,N,
+61117,N,N,N,61120,61122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61121,61119,N,N,61116,N,N,N,61115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,60738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61124,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61125,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61126,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61128,61129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61130,N,N,61131,
+61132,61135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61136,61137,N,N,N,N,N,N,N,61138,
+N,N,N,N,N,N,N,61139,N,N,N,N,N,N,N,N,N,61140,N,61141,N,61142,N,N,N,61143,61144,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61145,61148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61150,61151,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61152,N,N,61153,61155,N,N,61154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,61156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61157,N,N,N,N,N,N,N,N,N,61158,61159,61161,N,N,N,N,61160,61163,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61164,60868,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61133,60787,60798,60800,60821,60860,60876,60878,
+60921,60994,61017,61025,61026,61027,61029,61033,61036,61045,61057,61059,61060,
+61069,61077,61079,61080,61083,61111,61118,61134,61146,61147,61149,61162,61180,
+N,N,N,N,61179,N,N,N,N,N,33148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33119,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33169,
+33170,33226,N,61178,
+};
+
+static const struct unim_index cp932ext_encmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+0,22,121},{__cp932ext_encmap
++100,17,191},{0,0,0},{__cp932ext_encmap+275,96,115},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__cp932ext_encmap+295,29,31},{0,0,0},{__cp932ext_encmap+298,49,168},{
+__cp932ext_encmap+418,3,205},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{__cp932ext_encmap+621,40,252},{__cp932ext_encmap+834,0,255},{
+__cp932ext_encmap+1090,30,244},{__cp932ext_encmap+1305,74,236},{
+__cp932ext_encmap+1468,21,219},{__cp932ext_encmap+1667,0,221},{
+__cp932ext_encmap+1889,138,255},{__cp932ext_encmap+2007,134,134},{0,0,0},{
+__cp932ext_encmap+2008,89,200},{__cp932ext_encmap+2120,158,178},{
+__cp932ext_encmap+2141,11,186},{0,0,0},{__cp932ext_encmap+2317,86,236},{
+__cp932ext_encmap+2468,30,245},{__cp932ext_encmap+2684,39,208},{0,0,0},{
+__cp932ext_encmap+2854,33,222},{__cp932ext_encmap+3044,93,242},{
+__cp932ext_encmap+3194,17,152},{__cp932ext_encmap+3330,19,166},{
+__cp932ext_encmap+3478,245,245},{__cp932ext_encmap+3479,96,206},{
+__cp932ext_encmap+3590,78,78},{__cp932ext_encmap+3591,0,251},{
+__cp932ext_encmap+3843,14,192},{__cp932ext_encmap+4022,1,207},{
+__cp932ext_encmap+4229,104,226},{__cp932ext_encmap+4352,48,228},{
+__cp932ext_encmap+4533,214,214},{__cp932ext_encmap+4534,63,218},{
+__cp932ext_encmap+4690,4,252},{__cp932ext_encmap+4939,39,191},{
+__cp932ext_encmap+5092,136,245},{__cp932ext_encmap+5202,5,187},{
+__cp932ext_encmap+5385,4,254},{__cp932ext_encmap+5636,177,190},{
+__cp932ext_encmap+5650,36,245},{__cp932ext_encmap+5860,7,159},{
+__cp932ext_encmap+6013,1,111},{__cp932ext_encmap+6124,130,166},{
+__cp932ext_encmap+6161,70,70},{__cp932ext_encmap+6162,33,122},{
+__cp932ext_encmap+6252,48,155},{__cp932ext_encmap+6360,209,235},{
+__cp932ext_encmap+6387,158,158},{0,0,0},{__cp932ext_encmap+6388,72,214},{
+__cp932ext_encmap+6531,82,138},{__cp932ext_encmap+6588,71,161},{0,0,0},{0,0,0
+},{0,0,0},{__cp932ext_encmap+6679,1,246},{__cp932ext_encmap+6925,72,220},{
+__cp932ext_encmap+7074,83,176},{0,0,0},{0,0,0},{__cp932ext_encmap+7168,7,245},
+{__cp932ext_encmap+7407,28,28},{__cp932ext_encmap+7408,18,246},{
+__cp932ext_encmap+7637,83,127},{__cp932ext_encmap+7682,240,244},{
+__cp932ext_encmap+7687,18,118},{__cp932ext_encmap+7788,207,207},{0,0,0},{
+__cp932ext_encmap+7789,103,222},{__cp932ext_encmap+7909,21,238},{
+__cp932ext_encmap+8127,6,255},{__cp932ext_encmap+8377,2,248},{
+__cp932ext_encmap+8624,49,72},{__cp932ext_encmap+8648,146,146},{
+__cp932ext_encmap+8649,157,175},{__cp932ext_encmap+8668,51,85},{
+__cp932ext_encmap+8703,87,101},{__cp932ext_encmap+8718,39,158},{
+__cp932ext_encmap+8838,78,220},{__cp932ext_encmap+8981,114,187},{
+__cp932ext_encmap+9055,0,0},{__cp932ext_encmap+9056,107,112},{
+__cp932ext_encmap+9062,25,209},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+9247
+,41,220},{__cp932ext_encmap+9427,14,45},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__cp932ext_encmap+9459,2,228},
+};
+
+static const ucs2_t __jisx0213_1_bmp_decmap[2197] = {
+65287,65282,65293,126,12339,12340,12341,12347,12348,12543,12447,U,U,U,U,U,U,U,
+U,8836,8837,8842,8843,8713,8709,8965,8966,U,U,U,U,U,U,U,8853,8854,8855,8741,
+8742,10629,10630,12312,12313,12310,12311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8802,
+8771,8773,8776,8822,8823,8596,U,U,U,U,U,U,U,U,9838,9835,9836,9833,9655,9654,
+9665,9664,8599,8600,8598,8601,8644,8680,8678,8679,8681,10548,10549,U,U,U,U,U,
+U,U,U,U,U,10687,9673,12349,65094,65093,9702,8226,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,8723,8501,8463,13259,8467,8487,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12448,8211,10746,10747,12363,U,12365,U,12367,U,
+12369,U,12371,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12436,12437,
+12438,12459,U,12461,U,12463,U,12465,U,12467,U,U,U,U,U,U,U,12475,U,U,U,U,U,U,U,
+U,12484,U,U,U,12488,9828,9824,9826,9830,9825,9829,9831,9827,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,962,9461,9462,9463,9464,9465,9466,9467,9468,
+9469,9470,9750,9751,12320,9742,9728,9729,9730,9731,9832,9649,12784,12785,
+12786,12787,12788,12789,12790,12791,12792,12793,U,12794,12795,12796,12797,
+12798,12799,9150,9151,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,
+9163,9164,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+12535,12536,12537,12538,8922,8923,8531,8532,8533,10003,8984,9251,9166,12881,
+12882,12883,12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,
+12895,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,
+12989,12990,12991,U,U,U,U,U,U,U,U,9680,9681,9682,9683,8252,8263,8264,8265,461,
+462,464,7742,7743,504,505,465,466,468,470,472,474,476,8364,160,161,164,166,
+169,170,171,173,174,175,178,179,183,184,185,186,187,188,189,190,191,192,193,
+194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,
+213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,
+233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252,
+253,254,255,256,298,362,274,332,257,299,363,275,333,260,728,321,317,346,352,
+350,356,377,381,379,261,731,322,318,347,711,353,351,357,378,733,382,380,340,
+258,313,262,268,280,282,270,323,327,336,344,366,368,354,341,259,314,263,269,
+281,283,271,273,324,328,337,345,367,369,355,729,264,284,292,308,348,364,265,
+285,293,309,349,365,625,651,638,643,658,620,622,633,648,598,627,637,642,656,
+635,621,607,626,669,654,609,331,624,641,295,661,660,614,664,450,595,599,644,
+608,403,339,338,616,649,600,629,601,604,606,592,623,650,612,652,596,593,594,
+653,613,674,673,597,657,634,615,602,U,509,8048,8049,U,U,U,U,U,U,U,U,8050,8051,
+865,712,716,720,721,774,8255,779,769,772,768,783,780,770,741,742,743,744,745,
+U,U,805,812,825,796,799,800,776,829,809,815,734,804,816,828,820,797,798,792,
+793,810,826,827,771,794,10102,10103,10104,10105,10106,10107,10108,10109,10110,
+10111,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,8560,8561,8562,8563,
+8564,8565,8566,8567,8568,8569,8570,8571,9424,9425,9426,9427,9428,9429,9430,
+9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,
+9446,9447,9448,9449,13008,13009,13010,13011,13012,13013,13014,13015,13016,
+13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13050,13033,
+13029,13037,13036,U,U,U,U,U,U,U,U,U,8273,8258,9312,9313,9314,9315,9316,9317,
+9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,8544,
+8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,13129,13076,13090,13133,
+13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,13212,
+13213,13214,13198,13199,13252,13217,8555,U,U,U,U,U,U,U,13179,12317,12319,8470,
+13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,13180,
+U,U,U,8750,U,U,U,U,8735,8895,U,U,U,10070,9758,20465,U,13314,20008,20015,20016,
+20109,20193,20221,20223,20227,20235,20320,20296,20297,20310,20319,20330,20332,
+20350,20362,20372,20375,64048,20425,20448,20481,20482,20494,20504,20519,20526,
+20544,20539,20545,20628,20684,20722,20688,20710,64049,20742,20739,20747,20766,
+20789,20810,64050,20821,20823,13493,20893,20931,20938,20958,20962,20974,20993,
+13531,21011,21013,21065,21079,21089,21139,21192,64051,21196,21200,21206,21211,
+64052,21232,21243,21248,21255,21276,64053,21345,21347,21373,21395,21405,21426,
+21522,21543,21581,21660,21611,21620,21631,21640,21654,21665,21673,21702,21759,
+21774,21803,21813,21840,21854,21889,21894,21902,64054,21933,21966,64055,22024,
+22030,22075,22089,22134,22118,64056,22127,22129,22130,22169,22174,22185,22188,
+22195,22217,22218,22282,U,22305,22319,22323,22324,22384,22391,22396,22428,
+64015,U,22456,22471,22472,22479,22500,22509,22517,22518,22527,22537,64016,
+22625,22628,64057,22652,22665,22686,64058,22697,U,22738,22734,22740,22746,
+22752,22761,22796,34369,22877,22893,22923,22930,22948,22979,22994,23005,23059,
+23075,23143,23149,23159,23166,23172,23198,23207,23236,U,23321,23333,21085,
+23361,23382,23421,23443,23512,23532,23570,23582,23587,23595,14221,23650,64059,
+64060,U,23674,23695,23711,23715,23722,23738,23755,23760,23762,23796,U,14306,
+23821,23847,64017,23878,23879,23891,23882,23917,23937,23968,23972,23975,23992,
+24011,21534,22099,24034,24084,24088,24152,24158,24254,63784,24267,24313,24320,
+24322,24327,24349,24355,24372,24374,24381,24384,24389,24404,24408,24420,24423,
+24445,24457,24476,24487,24495,24501,24503,24521,24542,24545,24553,24589,24596,
+24600,24627,24629,24647,64061,24733,24734,24779,24788,24789,24797,24824,24860,
+24875,24880,24887,64062,24973,64063,25020,25017,64064,25122,25150,25155,25174,
+25178,25199,25221,25284,25302,25340,25354,25368,25401,25411,25445,25468,25573,
+25581,25589,25616,25620,25634,25721,25681,25696,25709,25806,25790,25791,25796,
+25802,25808,25847,25851,25890,25897,64065,25959,26013,64066,26112,26121,26133,
+26142,26170,26146,26148,26155,26160,26161,26163,26363,26184,26188,U,26201,
+26202,26209,26213,26227,26231,26232,26253,64067,26272,26290,26299,26310,26312,
+15138,26331,26344,26362,26387,63785,26419,26470,26439,26440,26491,26497,26515,
+26520,26523,26555,26617,26560,26583,26620,26625,26706,26653,26668,26673,26715,
+26738,26741,64068,26787,26789,26802,26824,26832,26856,26861,26864,26865,26876,
+26890,26953,U,26933,26946,26967,26979,26980,26984,27008,64020,27045,27053,
+27087,15286,15299,27106,27113,27114,27125,27126,27151,27157,U,27195,27198,
+27205,27216,27222,27227,27243,27251,U,27273,27284,27293,27294,27301,27364,
+27367,15375,63773,27419,27422,27436,27445,27462,27478,27488,27493,27495,27511,
+27522,27561,27565,63856,27599,27606,27607,27647,27653,27664,27699,27737,27740,
+27818,27764,27766,27781,27782,27800,27804,27899,27846,27860,27872,27883,27886,
+U,27908,27918,27950,27953,27961,27967,27992,28005,64069,28034,28039,28041,
+28052,28074,28076,28095,28100,28118,28122,28123,28125,28156,64070,28212,28228,
+28252,28254,28331,28337,28353,28359,28366,28432,28442,64071,28458,28463,28467,
+28497,28505,28510,28513,28514,28542,28552,28556,28557,28564,28576,28583,28598,
+28604,28615,28618,28665,28656,28661,28677,28678,28712,28746,28765,28766,28750,
+28772,28789,28805,28836,28843,28855,28884,28888,28900,28943,28971,28958,28960,
+28974,28976,28998,28999,29009,64072,29010,29020,29024,29032,64021,29061,29063,
+29074,29121,29114,29124,29182,29184,29205,29269,29270,15935,29325,29339,29374,
+29376,29435,U,29479,29480,64022,29520,29542,29564,29589,29599,29600,29602,
+29606,29611,29641,29647,29654,29657,29667,29673,29703,29706,29722,29723,64074,
+29734,29736,29738,29739,29740,29742,29743,29744,29764,29766,29767,29771,29783,
+29794,29803,29805,29830,29831,29833,29848,29852,29855,29859,29840,29862,29864,
+29865,29877,29887,29896,29897,29914,29951,29953,29975,29999,30063,30073,30098,
+16242,30158,30180,30208,30210,30216,30229,30230,30233,30238,30253,30261,30275,
+30283,30308,30309,30317,30319,30321,30337,30363,30365,30366,30374,30378,30390,
+30405,30412,30414,30420,30438,30449,30460,30474,30489,30516,30518,30534,30541,
+30542,30556,30559,30562,30586,30592,30612,30634,30688,30765,30787,30798,30799,
+30801,30824,30830,64075,30896,U,30893,30948,30962,30976,30967,31004,31022,
+31025,31028,64076,64077,31045,31046,64078,64079,64080,31068,64081,64025,64026,
+31097,64082,64083,64027,31128,31153,31160,31176,31178,U,31188,31198,31211,
+31213,31235,64084,31289,31325,31341,64085,31365,31392,U,31411,31419,31438,
+31467,31485,31506,31533,31547,31559,31566,31584,31597,31599,31602,31646,64086,
+31703,31705,31745,31793,31774,31776,31795,31798,16996,U,31833,31853,31865,
+31887,31892,31904,31932,31957,31961,31965,32007,32008,32019,32029,32035,32049,
+32065,32072,32083,32092,32122,32131,32139,32160,32166,32194,32204,32214,32227,
+64087,32296,32264,32273,32277,64089,32327,32338,32353,32394,32397,32583,64090,
+32657,32663,32703,32718,32731,32735,32748,32750,32762,64091,32788,32806,32821,
+32823,32828,32970,32983,32992,33011,33048,33098,33120,33127,33128,33133,33211,
+33226,33231,33239,64092,17491,17499,33376,33396,U,33422,33441,33443,33444,
+33449,33454,33463,33470,33471,33478,33493,33533,33534,33536,33537,33634,33570,
+33581,33594,33603,33607,33617,33621,33661,33670,33682,33688,33703,33705,33727,
+33728,33735,33743,33745,33761,33770,33793,33798,33802,64095,33864,33887,33904,
+33907,33925,33950,33967,33972,33978,33984,33986,U,34098,34078,34083,34095,
+34137,34148,64031,34221,34170,34188,34191,34210,34224,34251,34254,34285,34322,
+34303,34308,34309,34320,U,34328,34345,34360,34391,34395,63798,34402,17821,
+34412,34421,34456,34488,34554,34556,34557,34571,34673,34695,34696,34732,34733,
+34741,17898,34774,34796,34822,34826,34832,34836,34847,34968,34986,35018,35022,
+U,35061,35100,64096,35096,35097,35098,35111,35120,35122,35129,35136,35220,
+64097,35284,35301,35318,35346,35349,35362,35383,35399,35406,35421,35425,35445,
+35449,35495,35536,35551,35572,35574,64034,64098,64099,35654,35668,35673,35689,
+35741,35913,35944,64100,36065,36084,36088,36094,64101,36114,36123,36271,36302,
+36305,36311,36384,36387,36413,36464,36475,U,36544,18500,36602,36638,36653,
+36662,36692,U,36774,36789,36836,36840,36846,36872,36909,64103,37000,37013,
+37015,37017,37019,37026,37043,37054,37060,37061,37063,37079,37085,37086,37103,
+37108,64038,37140,37141,37142,37154,37155,37159,37167,37169,37172,37181,37192,
+37211,37251,37278,37292,37297,37308,37335,37371,37348,37349,37357,37361,37383,
+37392,37432,37433,37434,37436,37440,37443,37455,37496,37512,37570,37579,37580,
+37587,37600,37631,37636,37663,37665,37669,37704,37705,37706,37732,37733,37738,
+37744,37787,37795,37818,37830,37854,37855,37892,37885,37939,37962,37987,37995,
+38001,38002,38286,38303,38310,38313,38316,38326,38333,38347,38352,38355,18864,
+38362,38366,38488,38532,63964,38557,38564,38565,38610,38622,64104,38633,38639,
+38707,38715,38733,38734,38735,38746,38766,38771,38805,38830,38842,38849,38857,
+38878,38875,38900,64105,38922,38942,38955,38960,64106,38994,38995,38998,38999,
+39001,39002,63952,39013,39020,39098,39112,39143,39256,39326,39426,39427,39460,
+39469,39470,39480,39498,39502,39506,39606,39617,39619,39630,39638,39673,39682,
+39688,39712,19479,39725,39774,39801,39782,39794,39797,39812,39818,39823,39838,
+39847,39873,39886,39909,39928,39933,39936,39971,40001,40015,40016,40019,40035,
+40037,40055,40221,40222,40259,40263,40274,40291,40304,40316,40330,40342,40384,
+40364,40380,40407,U,40423,40455,40469,40572,40606,40612,40620,40623,40628,
+40629,40643,40657,40720,40761,40791,40848,40852,40855,40866,23032,23643,24183,
+30246,32363,
+};
+
+static const struct dbcs_index jisx0213_1_bmp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+0,47,125},{
+__jisx0213_1_bmp_decmap+79,33,126},{__jisx0213_1_bmp_decmap+173,43,118},{
+__jisx0213_1_bmp_decmap+249,43,72},{__jisx0213_1_bmp_decmap+279,57,126},{
+__jisx0213_1_bmp_decmap+349,66,126},{__jisx0213_1_bmp_decmap+410,65,124},{
+__jisx0213_1_bmp_decmap+470,33,126},{__jisx0213_1_bmp_decmap+564,33,126},{
+__jisx0213_1_bmp_decmap+658,33,126},{__jisx0213_1_bmp_decmap+752,33,126},{
+__jisx0213_1_bmp_decmap+846,33,126},{__jisx0213_1_bmp_decmap+940,33,126},{
+__jisx0213_1_bmp_decmap+1034,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+
+1128,85,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_1_bmp_decmap+1170,39,126},{__jisx0213_1_bmp_decmap+1258,33,126},{
+__jisx0213_1_bmp_decmap+1352,33,126},{__jisx0213_1_bmp_decmap+1446,33,126},{
+__jisx0213_1_bmp_decmap+1540,33,125},{__jisx0213_1_bmp_decmap+1633,33,126},{
+__jisx0213_1_bmp_decmap+1727,33,126},{__jisx0213_1_bmp_decmap+1821,33,126},{
+__jisx0213_1_bmp_decmap+1915,33,126},{__jisx0213_1_bmp_decmap+2009,33,126},{
+__jisx0213_1_bmp_decmap+2103,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __jisx0213_2_bmp_decmap[2425] = {
+19970,19983,19986,20009,20011,20014,20032,20039,20040,U,20049,13318,U,20058,
+20073,20125,13356,13358,20153,20155,U,20156,20163,20168,20176,20203,20186,
+20209,20213,20224,20246,20324,20279,20286,20308,20312,U,20343,20344,20346,
+20349,20354,20357,20370,20378,20454,20402,20414,20421,20427,20431,20434,13418,
+20466,20480,20496,20499,20508,20510,20514,13416,20546,20550,20558,20563,20567,
+20579,20582,20586,20592,20643,20616,20626,20627,20629,20630,20636,20650,U,
+20657,20666,20667,20676,20679,20723,U,20686,U,20692,20697,20705,20713,13458,
+20744,U,20759,20763,U,20832,U,20851,20867,20875,13500,20888,20899,20909,13511,
+20924,U,U,20979,20980,20994,21010,21014,U,21077,21084,21100,21111,21124,21122,
+U,21144,U,21156,21158,21167,21178,21179,21194,13599,21201,U,21239,21258,21259,
+21284,21301,21310,21314,U,U,21351,21356,21370,21412,21428,U,21431,21440,U,
+13661,13662,21461,21466,13667,21492,21493,21589,21540,21544,13678,21571,21602,
+21606,21612,21642,21645,21653,21664,21670,21677,21678,21687,21690,21695,21699,
+U,21740,21743,21745,21747,21760,21761,21769,21820,21825,13734,21831,21834,
+13736,21856,21857,21860,U,21885,21890,21896,21905,13765,21970,U,U,21951,21961,
+21964,21969,21981,13786,21986,U,21993,22056,U,22023,22032,22064,22071,13812,
+22077,22079,22080,22087,22110,22112,22125,13829,22152,22156,22165,22170,22173,
+22184,22189,22194,22213,22221,22239,22248,22262,22263,U,22293,22307,U,22313,U,
+22341,22342,22348,22349,U,22376,22383,22387,22388,22389,22395,U,U,22444,22426,
+22429,22430,22440,22487,U,22476,U,U,22494,22502,22512,13898,22520,22523,22525,
+22532,22558,22560,22567,22578,22585,U,22601,22604,22631,22666,22667,22669,
+22671,22672,22676,22685,22698,22705,U,22723,22733,22754,22771,22772,22789,
+22790,22795,22797,22804,22820,U,13969,22845,13977,22854,13974,U,22875,22879,U,
+22901,22902,22908,22943,22958,22972,22984,22989,23006,23011,23012,23015,23022,
+U,U,14031,23052,23053,23063,23079,23085,23125,23141,23162,23179,23196,23199,
+23200,23202,23217,23219,23221,23226,23231,23258,23260,23264,23269,23280,23278,
+23285,23296,23304,23319,23348,23341,23372,23378,23400,23407,23420,23423,23425,
+23428,23446,23468,14177,23488,14178,23502,23510,14188,14187,23537,23549,14197,
+23555,23593,23600,U,23647,23651,23655,23656,23657,23664,U,U,23676,U,U,23688,
+23690,14273,U,U,23712,23714,23718,23719,U,23725,23733,U,23753,U,U,23814,23824,
+23851,23837,23840,23844,23846,23857,23865,23874,14312,23905,23914,14324,23920,
+U,14333,23944,14336,23954,23956,23959,23961,23984,23986,23988,U,23993,24017,
+24023,24024,24032,U,24036,24041,14383,24064,14390,24082,24085,14400,24095,
+24110,24126,24137,14428,24150,14433,24171,24172,24173,24174,U,24229,24234,
+24236,24249,24255,24262,24274,24281,U,24317,24328,24334,24348,U,24350,24391,
+24419,24434,24446,24463,24482,24484,24504,24516,14586,24519,24523,24530,24531,
+24532,24546,24558,24559,24563,24572,14615,24599,24610,24612,14618,24652,24703,
+24714,24725,24744,U,24752,24753,24766,24776,24793,24795,24814,24818,24821,
+24848,24850,24851,24857,24862,24890,14703,24897,24902,24928,24956,U,24978,
+24979,24983,24984,24997,25000,25005,U,25045,25053,25055,25077,U,25109,25123,
+25129,25158,25164,25169,25170,25185,25188,25211,25197,25203,25241,25254,25301,
+U,25341,25347,25357,25360,U,U,25394,25397,25403,25404,25409,25412,25422,U,
+25433,U,U,25452,25476,25497,U,25492,25533,25591,25556,25557,25564,25568,25579,
+25580,25586,25609,25630,25637,25641,25647,25690,25691,25693,25715,25725,25735,
+25745,25757,25759,25803,25804,25813,25815,U,25828,25829,25855,25860,14958,
+25871,25876,25878,14963,25886,25906,25924,25940,25963,25978,25985,25988,25989,
+25994,26034,26037,26040,26047,26050,26057,26068,15062,26098,26105,26108,26116,
+26120,26145,26154,26181,26193,26190,15082,U,26199,26203,26211,U,U,26218,26219,
+26220,26221,26235,26240,26256,26258,26265,15118,26285,26289,26293,15130,26303,
+15132,26348,15063,26369,26373,26386,U,26393,U,U,26444,26445,26452,26461,U,U,U,
+26484,26486,U,26514,U,33635,26640,26544,26546,26563,26568,26578,26585,26587,
+26608,26615,U,U,U,26648,26655,26669,U,26675,26683,26686,26692,26693,26697,
+26700,26709,26711,15223,26731,26734,26746,26748,26754,26768,26774,15213,26776,
+26777,26778,26780,26794,26795,26804,26811,26875,U,U,64019,26819,26821,26828,
+26831,26838,26841,26852,26853,26860,26871,26883,26887,15239,15240,U,26939,
+15245,26950,26985,26988,26994,27002,27007,27026,15268,27030,27032,27046,27056,
+27063,27066,27068,27072,27089,27094,U,U,27184,U,U,27107,27118,27119,27123,
+15309,27124,27134,27153,27162,27165,U,27186,27187,27188,27199,27206,27209,
+27258,27214,27218,27236,U,27262,27267,27275,15344,27281,27295,27297,U,27307,
+27325,27334,27348,27344,27356,27357,U,U,27372,27377,27378,27379,27389,U,27403,
+27407,27408,27409,U,27415,15398,27439,27466,27480,27500,27509,27514,27521,
+27547,27566,U,27581,27582,27591,27592,27593,27610,27622,27623,27630,27633,
+27650,27658,27662,27701,27702,27706,U,27711,27725,27739,27757,27780,27785,
+15555,27796,27797,27799,27821,27842,27856,15570,27862,27866,27868,27881,27884,
+27885,U,27904,27914,27940,27942,27943,27751,27951,27964,27995,27998,28000,
+28016,28032,28033,28042,28045,28049,28056,U,28183,U,U,U,28075,28078,28084,
+28098,27956,28104,28110,28111,28112,28127,28137,28150,28214,28190,28194,28199,
+15633,28210,28220,28232,28233,28235,28236,28239,28241,28243,28244,28247,28259,
+15646,28307,28327,28340,28351,28355,28362,28377,28469,28395,28409,28411,28426,
+28428,28440,28453,28470,28476,U,28498,28503,28506,28512,28520,28568,28541,
+28560,28566,28606,28575,28581,28591,15716,28597,28616,28617,28634,28638,28649,
+U,28668,28672,28679,28682,28707,U,28729,28730,28732,28739,28743,28747,15770,
+28756,28773,28777,28780,28782,28790,28798,28801,28806,28821,28823,28859,U,
+28831,28849,U,28908,28874,28881,28883,28892,28931,28932,28934,28935,28936,
+28940,15808,28975,28977,29008,29002,29011,29022,15828,29078,29056,29083,29088,
+29090,29102,29103,29107,U,29131,29139,29145,29148,29191,15877,64073,29227,
+29236,29240,29241,20012,29250,29267,29271,29283,U,29294,29295,29304,29311,
+29326,U,29357,29358,29360,29361,29377,15968,29388,15974,15976,29427,29434,
+29447,29458,29464,29465,16003,29497,29484,29489,29491,29501,29522,16020,29547,
+29548,U,29550,29551,29553,29559,29569,29573,29578,29588,29592,29596,29598,
+29605,29608,29621,29623,29625,29628,29631,29637,29643,29665,29671,29689,29715,
+29690,29697,29732,29745,29753,29779,29760,29763,29773,29778,29789,29809,29825,
+29829,29832,U,29842,29847,29849,29856,29857,29861,29866,29867,29881,29883,
+29882,29910,29912,29918,29935,29931,U,29946,U,29984,29988,29994,16215,U,30013,
+30014,30016,30024,30030,30032,30034,30060,30066,30065,30074,30077,30078,30081,
+U,30092,16245,30114,16247,30128,30135,30143,30144,30150,30159,30163,30173,
+30175,30176,30183,30188,30190,30193,30201,30211,30232,30215,30223,16302,U,
+30227,30235,30236,U,30245,30248,30268,30259,U,16329,30273,U,30281,30293,16343,
+30318,30357,30364,30369,30368,30375,30376,30383,U,30409,U,30440,30444,U,30487,
+30490,30509,30517,16441,U,U,30552,30560,30570,U,30578,30588,30589,U,16472,
+30618,30623,30626,30628,30633,30686,30687,30692,30694,30698,30700,16531,30704,
+30708,30715,U,30725,30726,30729,30733,30745,30753,30764,30791,30820,30826,U,
+30858,30868,30884,30877,30878,30879,30907,30920,30924,30926,30933,30944,30945,
+30950,30969,30970,30971,30974,U,30992,31003,31024,31013,31035,31050,31064,
+31067,16645,31079,31090,31124,31125,31126,31131,31137,31145,31156,31163,31170,
+31175,31180,31181,31190,16712,U,U,16719,31242,31249,31253,31259,31262,16739,
+31277,31288,31303,31308,31318,31321,31324,31327,31328,31335,31338,31349,31352,
+31362,31370,31376,31395,31404,U,16820,31417,31420,31422,16831,31436,31441,
+31463,31464,31476,U,U,31495,U,31549,31527,31530,31534,31535,31537,16870,16883,
+31615,31553,16878,31573,31609,31588,31590,31593,31603,U,16903,31632,31633,
+31643,16910,31663,31669,31676,31685,31690,U,U,31700,31702,31706,31722,31728,
+31747,31755,31758,31759,31782,31813,31818,31825,31831,31838,31841,31849,31854,
+31855,31856,U,U,U,31910,U,31926,31927,31935,U,31940,U,31944,31949,U,31959,U,
+31974,31979,U,31989,32003,32009,17094,32018,32030,U,U,32061,32062,32064,32071,
+U,U,17110,32089,32090,32106,32112,17117,32127,U,32134,32136,32140,32151,U,
+32157,32167,32170,32182,32183,32192,32215,32217,32230,32241,32249,17154,U,
+64088,32272,32279,32285,32288,32295,32300,32325,32371,32373,32382,32390,32391,
+17195,32401,32408,32410,17219,32572,32571,32574,32579,32580,32591,13505,U,
+32594,U,32609,32611,32612,32621,32637,32638,U,32656,20859,U,32662,32668,32685,
+U,32707,32719,32739,32741,32751,32754,32770,32778,32776,32782,32785,32790,
+32804,32812,32816,32835,32870,32881,32885,32891,32921,32924,32932,32935,32952,
+U,32965,32981,32984,32998,U,33037,33013,33019,17390,33077,33046,33054,17392,
+33060,33063,33068,U,33085,17416,33129,17431,33153,17436,33156,33157,17442,
+33176,33202,33217,33219,33238,33243,U,33252,U,33260,U,33277,33279,U,33284,U,
+33305,33313,33314,U,33330,33332,33340,33350,33353,33349,U,33355,17526,33359,
+17530,33367,U,33372,33379,U,64093,64094,33401,17553,33405,33407,33411,33418,
+33427,33447,33448,33458,33460,33466,33468,33506,33512,33527,33543,33544,33548,
+33620,33563,33565,33584,33596,33604,33623,17598,33663,17620,17587,33677,33684,
+33685,33691,33693,33737,33744,33748,33757,33765,33785,33807,33809,33813,U,
+33815,33849,33866,33871,33873,33874,33881,33882,33884,U,33893,33910,33912,
+33916,33921,17677,34012,33943,33958,33982,17672,33998,33999,34003,U,34023,
+34026,34031,34032,34033,34042,34045,34060,34075,34084,34085,34091,34100,34127,
+34159,17701,17731,34110,34129,34131,34142,34145,34146,U,34171,34173,34175,
+34177,34182,34195,34205,34207,34231,34236,34247,34250,34264,34265,34271,34273,
+34278,34294,34304,34321,34334,34337,34340,34343,U,34361,34364,U,34368,64032,
+34387,34390,34415,34423,34426,34439,34441,34445,34449,34460,34461,34472,64033,
+34481,34483,34497,34499,34513,34517,34519,34531,34534,17848,34565,34567,34574,
+34576,34579,34585,34591,34593,34595,34609,34618,34622,34624,34627,34641,34648,
+34660,34661,34674,34684,U,U,34727,34697,34699,34707,34720,U,17893,34750,U,
+34753,34766,34805,34783,U,34787,34789,34790,34794,34795,34797,34817,34819,
+34827,34835,34856,34862,34866,34876,17935,34890,34904,34911,34916,U,U,34921,U,
+34927,34976,35004,35005,35006,35008,35026,U,35025,35027,35035,35056,35057,
+17985,35073,U,35127,U,35138,35141,35145,U,18021,35170,35200,35209,35216,35231,
+35248,35255,35286,35288,35307,18081,35313,35315,35325,35327,18095,35345,35348,
+U,35361,35381,35390,35397,35405,35416,35502,35472,35511,35518,35543,35580,U,
+35594,35589,35597,35612,35615,35629,35651,18188,35665,35678,35702,35711,35713,
+35723,35732,35733,35740,35742,35897,U,35901,U,U,35909,35911,35919,35924,35927,
+35945,35949,35955,U,35987,35986,35993,18276,35995,36004,36054,36053,36057,U,
+36080,36081,U,36105,36110,36204,36228,36245,36262,U,36294,36296,36313,36332,
+36364,18429,36349,36358,U,36372,36374,36385,36386,36391,U,18454,36406,36409,
+36427,36436,36450,36460,36461,36463,36504,36510,36526,36531,36533,36534,36539,
+U,36561,36564,18510,36601,U,36608,36616,36631,36651,36672,36682,36696,U,36772,
+36788,64102,36790,U,36801,36806,64036,36810,36813,36819,36821,36832,36849,
+36853,36859,36866,36876,36919,U,36931,36932,36957,36997,37004,37008,38429,
+37025,18613,37040,37046,37059,37064,U,37084,37087,U,37110,37106,37120,37099,
+37118,37119,37124,37126,37144,37148,37150,37175,37177,37178,37190,37191,37207,
+37209,37217,37220,37236,37241,37253,37262,37288,37294,37299,37302,37315,37316,
+37338,U,U,37356,37358,37377,37386,37398,37399,U,37427,37442,37447,37450,37454,
+37457,37462,37465,37472,37473,37477,37479,37480,U,U,37500,37501,37503,37513,
+37517,37527,37529,37535,37543,37547,U,U,37554,37567,37568,37574,37582,37584,
+37591,37593,37605,37607,37649,37623,37625,37627,37634,37645,37653,37661,37662,
+37671,37673,U,U,37703,37713,37719,37722,37739,37745,37747,37793,U,U,37768,
+37771,37775,37790,37877,U,U,37873,37825,37831,37852,37858,37863,37897,37903,
+37910,37911,37883,37938,37940,37947,37957,U,U,37997,37999,38264,38265,38278,
+38284,38285,U,38315,38324,U,38344,U,U,38444,38451,38452,U,38460,38465,38497,U,
+38530,U,38554,U,18919,38569,38575,38579,38586,38589,18938,U,38616,38618,38621,
+18948,38676,38691,18985,38710,38721,38727,38741,38743,38747,38762,U,U,38806,
+38810,38814,38818,38833,38834,38846,38860,38865,38868,38872,38873,38881,38897,
+38916,38925,38926,38932,38934,19132,U,38947,38962,38963,38949,38983,39014,
+39083,39085,39088,U,39095,39096,39099,39100,39103,39106,39111,39115,39136,U,
+39137,39139,39141,39146,39152,39153,39155,39176,19259,U,39190,39191,U,39194,
+39195,39196,U,39217,39218,39219,39226,39227,39228,39232,39233,39238,39245,
+39246,39260,39263,39264,39331,39334,39353,39357,39359,39363,39369,39380,39385,
+39390,U,39408,39417,39420,39434,39441,39446,39450,39456,39473,39478,39492,
+39500,39512,19394,39599,19402,39607,19410,39609,U,39622,39632,39634,39637,
+19432,39644,39648,39653,39657,39683,39692,39696,39698,39702,39708,39723,39731,
+39741,19488,39755,39779,39781,39787,39788,39795,39798,39799,39846,39852,39857,
+U,U,39858,39864,39870,39879,39923,39896,39901,39911,39914,39915,39919,39918,U,
+39930,U,39927,U,39958,39960,39961,39962,39965,39970,39975,39977,39978,U,39985,
+39990,39991,40005,40028,U,40009,40010,U,40020,40024,40027,40029,40031,40041,
+40042,40043,40045,40046,40048,40050,40053,40058,40166,40178,40203,40194,U,
+40209,40215,40216,U,19652,U,40242,19665,40258,40266,40287,40290,U,40297,40299,
+U,40307,40310,40311,40318,40324,40333,40345,40353,40383,40373,40377,40381,
+40387,40391,40393,40406,40410,40415,40416,40419,40436,19719,40458,40450,40461,
+40473,40476,40477,40571,U,40576,40581,40603,40616,U,40637,U,40671,40679,40686,
+40703,40706,19831,40707,40727,40729,40751,40759,40762,40765,40769,40773,40774,
+40787,40789,40792,U,40797,U,40809,U,40813,40816,40821,
+};
+
+static const struct dbcs_index jisx0213_2_bmp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+0,34,126},{0,0,0},{
+__jisx0213_2_bmp_decmap+93,33,126},{__jisx0213_2_bmp_decmap+187,33,126},{
+__jisx0213_2_bmp_decmap+281,33,125},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+
+374,33,126},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+468,33,126},{
+__jisx0213_2_bmp_decmap+562,33,126},{__jisx0213_2_bmp_decmap+656,33,126},{
+__jisx0213_2_bmp_decmap+750,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_2_bmp_decmap+844,33,126},{__jisx0213_2_bmp_decmap+938,33,126},{
+__jisx0213_2_bmp_decmap+1032,33,126},{__jisx0213_2_bmp_decmap+1126,33,126},{
+__jisx0213_2_bmp_decmap+1220,34,126},{__jisx0213_2_bmp_decmap+1313,33,126},{
+__jisx0213_2_bmp_decmap+1407,33,126},{__jisx0213_2_bmp_decmap+1501,33,126},{
+__jisx0213_2_bmp_decmap+1595,33,125},{__jisx0213_2_bmp_decmap+1688,35,126},{
+__jisx0213_2_bmp_decmap+1780,33,126},{__jisx0213_2_bmp_decmap+1874,33,125},{
+__jisx0213_2_bmp_decmap+1967,34,125},{__jisx0213_2_bmp_decmap+2059,34,126},{
+__jisx0213_2_bmp_decmap+2152,33,126},{__jisx0213_2_bmp_decmap+2246,33,126},{
+__jisx0213_2_bmp_decmap+2340,33,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __jisx0213_bmp_encmap[27287] = {
+8754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10530,
+10531,N,N,10532,N,10533,N,N,10534,10535,10536,N,10537,10538,10539,N,N,10540,
+10541,N,N,N,10542,10543,10544,10545,10546,10547,10548,10549,10550,10551,10552,
+10553,10554,10555,10556,10557,10558,10559,10560,10561,10562,10563,10564,10565,
+10566,10567,10568,10569,10570,10571,10572,10573,N,10574,10575,10576,10577,
+10578,10579,10580,10581,10582,10583,10584,10585,10586,10587,M,10589,10590,
+10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602,10603,
+10604,N,10605,10606,10607,10608,10609,10610,10611,10612,10613,10618,10810,
+10825,10785,10796,10812,10827,10841,10847,N,N,10813,10828,10816,10831,N,10832,
+10616,10621,N,N,N,N,10814,10829,10815,10830,10842,10848,N,N,N,N,N,N,10843,
+10849,N,10877,N,N,10614,10619,N,N,N,N,N,N,N,N,10844,10850,N,N,N,10811,10826,N,
+N,10788,10799,N,N,10787,10798,10817,10833,N,N,10818,10834,N,N,10874,10617,
+10622,N,N,10819,10835,11051,11050,10809,10824,N,N,10820,10836,10789,10800,
+10845,10851,10791,10803,10790,10802,10823,10839,10792,10804,N,N,N,N,10615,
+10620,10846,10852,10821,10837,10822,10838,N,N,N,N,N,N,N,10793,10805,10795,
+10808,10794,10807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11049,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+11044,N,N,N,N,N,N,N,N,N,N,10351,10352,N,10353,10358,10359,N,10360,N,10361,N,
+10362,N,10363,N,10364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+10356,10357,N,N,N,11077,11059,11065,11066,11045,M,11071,10862,11046,11054,M,M,
+N,11057,N,11058,10869,11048,10873,N,N,11062,11068,11042,11074,11052,N,N,N,
+10858,10868,10859,11060,10875,10853,10870,10863,N,11055,N,N,N,10860,11073,
+10867,N,10864,10855,N,N,10876,10865,10856,11047,N,N,N,10861,11053,11061,10854,
+M,11067,10872,N,10866,11072,10857,N,11041,10878,N,N,11043,N,N,N,N,10871,N,N,N,
+11070,11069,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,10801,11091,N,N,N,11092,N,N,N,11093,11094,N,N,N,N,N,N,10786,10840,N,
+10797,N,10806,11121,N,N,N,N,N,N,M,11105,11106,11107,M,11100,11098,11103,11133,
+11099,N,11095,N,11117,N,N,11097,11102,N,N,11101,N,N,N,N,N,N,N,N,11128,11129,
+11134,N,11114,11126,11127,11115,11116,N,N,N,11122,11111,N,N,N,11119,11130,N,
+11112,N,N,11120,11123,N,N,N,11125,N,N,N,N,11113,11131,11132,11124,11118,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11090,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,9817,10354,10355,11078,11079,11088,11089,9084,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,9024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,10347,N,N,11096,N,N,11390,N,N,N,N,10348,10349,10350,N,N,N,N,N,N,N,11389,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,10529,9053,N,N,N,9055,N,N,11618,N,N,N,N,N,N,N,N,N,N,11620,
+N,N,N,N,N,9056,N,N,N,N,N,N,N,N,N,N,N,N,N,9052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,10104,10105,10106,N,N,N,N,N,N,N,N,N,N,11573,11574,
+11575,11576,11577,11578,11579,11580,11581,11582,11583,11607,N,N,N,N,11317,
+11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8817,N,8999,8997,8998,9000,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9001,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9003,9004,
+9002,9005,8775,N,N,N,8774,N,N,N,N,N,N,N,N,N,9051,N,N,N,N,N,N,N,N,N,N,N,11640,
+N,N,N,N,N,8788,8789,N,N,N,N,N,N,N,11635,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,8812,N,8813,N,N,8814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8811,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8815,8816,N,N,N,N,N,N,N,N,N,N,N,N,8770,
+8771,N,N,N,N,8772,8773,N,N,N,N,N,N,N,N,N,8785,8786,8787,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11641,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10102,10103,8776,8777,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,10108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10050,10051,10052,10053,10054,10055,
+10056,10057,10058,10059,10060,10061,10062,10063,10064,N,10110,10109,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11553,11554,11555,11556,11557,11558,11559,
+11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,11329,11330,11331,11332,11333,11334,11335,11336,
+11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,
+11350,11351,11352,11353,11354,N,11307,11308,11309,11310,11311,11312,11313,
+11314,11315,11316,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9837,N,N,
+N,N,8994,8993,N,N,N,N,N,N,N,N,8996,8995,N,N,N,N,N,N,N,9019,N,N,N,N,N,N,10343,
+10344,10345,10346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9023,9832,9833,9834,
+9835,N,N,N,N,N,N,N,N,N,N,9831,N,N,N,N,N,N,N,9828,9829,N,N,N,N,N,N,11646,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9786,9789,9787,9792,9785,9790,
+9788,9791,9836,8829,N,8827,8828,N,8826,10107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,11645,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,9006,
+9007,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,8790,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9018,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,9085,9086,8794,8795,8792,8793,N,N,N,11616,N,11617,9830,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8755,8756,8757,N,N,N,N,N,8758,8759,9020,N,N,N,
+N,N,N,N,N,N,N,N,N,N,M,N,M,N,M,N,M,N,M,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,9332,9333,9334,N,N,N,N,N,N,N,N,8761,9083,N,N,N,N,N,N,N,N,N,N,M,N,M,
+N,M,N,M,N,M,N,N,N,N,N,N,N,M,N,N,N,N,N,N,N,N,M,N,N,N,M,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10098,
+10099,10100,10101,N,N,N,N,8760,9838,9839,9840,9841,9842,9843,9844,M,9846,9847,
+9849,9850,9851,9852,9853,9854,11626,11627,N,N,N,N,N,N,11628,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,10305,10306,10307,10308,10309,10310,10311,10312,
+10313,10314,10315,10316,10317,10318,10319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,11621,11622,11623,11624,11625,N,N,N,N,N,N,N,N,10320,
+10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,
+10334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11355,11356,11357,11358,11359,11360,
+11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,
+11374,N,11377,N,N,N,11376,N,N,11379,11378,N,N,N,N,N,N,N,N,N,N,N,N,11375,11590,
+N,N,N,N,N,N,N,N,N,11594,N,N,N,N,N,N,11585,N,N,N,11588,N,N,N,N,N,N,N,N,N,11586,
+11596,N,N,11595,11589,N,N,N,11597,N,N,N,N,N,N,N,N,N,N,11591,N,N,N,N,11599,N,N,
+N,N,N,N,N,N,N,N,N,N,N,11584,11598,N,N,11587,N,N,N,11592,N,N,N,N,N,11593,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11615,11631,
+11630,11629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11603,11604,N,N,N,N,N,N,N,N,N,N,N,N,
+11600,11601,11602,N,N,11606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,11605,N,N,N,N,N,N,9054,N,11619,11811,N,N,N,41261,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41266,N,41267,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41310,N,41302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41342,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11859,N,N,N,N,N,N,41771,N,N,N,N,
+62568,N,N,N,N,N,41775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11867,41800,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41821,41822,N,N,N,N,41825,N,N,N,N,N,N,N,
+N,N,N,41831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42019,N,42022,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,42040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42050,42058,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42105,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42303,N,N,N,N,42307,N,N,42305,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,42327,43043,43045,N,N,N,N,N,N,N,N,43049,43048,N,N,N,N,N,
+N,N,N,43052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20319,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,43070,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,20335,N,N,N,N,N,43094,N,N,N,N,N,N,N,N,N,N,N,43097,N,N,N,N,N,N,N,N,43100,
+43102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,43119,N,N,N,N,N,N,43121,N,N,N,N,N,N,N,N,N,43124,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43129,N,N,N,N,43131,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44091,44102,N,N,44106,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44128,44379,N,N,N,N,44383,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44401,44598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44412,44590,N,N,N,N,N,N,N,N,N,
+N,N,44594,N,44596,N,N,N,N,N,30025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,44653,N,N,N,N,N,N,N,N,N,44645,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,44840,44841,N,N,N,N,44844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30078,N,N,N,N,N,N,N,N,N,N,N,N,30241,N,
+N,N,N,N,N,N,N,N,44872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44893,30266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44919,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+60987,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60994,61041,N,N,N,N,N,N,N,N,N,N,N,N,61054,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61248,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,61268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61303,61480,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,61503,N,N,N,N,N,61505,N,61506,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61520,61748,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30797,N,N,61766,N,61768,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61788,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,61799,N,N,N,N,N,N,N,N,N,N,N,N,N,61804,61986,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62009,62052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62068,N,N,N,
+N,N,N,62071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62077,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62259,N,N,N,N,N,N,
+N,N,N,N,62263,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,62279,N,N,N,N,N,N,N,62283,N,N,N,N,62280,62291,N,N,N,N,N,N,62295,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,31085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62507,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62518,N,N,N,N,N,N,62523,62542,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62557,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,62561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62782,N,62786,62792,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,62794,N,N,N,N,62796,N,N,N,N,N,62799,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31321,N,N,N,N,N,N,N,31322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62828,N,N,N,62830,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62839,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63029,N,N,N,N,N,N,N,N,
+N,N,63026,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63028,63065,N,N,N,N,63060,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63085,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31569,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63340,N,N,N,N,31584,
+63524,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,63546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,63555,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63566,N,
+N,N,N,N,N,N,N,N,N,N,N,N,63571,63595,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63785,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63807,63817,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31819,N,N,N,N,N,N,N,N,N,63836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64039,32088,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64362,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,64368,64373,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,64376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64567,64597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64806,N,N,N,N,N,N,N,64808,N,N,N,
+N,N,N,N,64810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64817,32318,N,N,N,N,N,
+N,N,N,64831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65066,N,N,N,N,N,N,N,N,N,N,N,N,65069,65099,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65120,41250,N,N,N,N,N,
+N,N,N,N,N,N,N,41251,N,N,41252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11812,
+41253,N,41254,61486,N,41255,11813,11814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41256,N,
+N,N,N,N,N,41257,41258,N,N,N,N,N,N,N,N,41260,N,N,N,N,N,N,N,N,41263,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,41264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,11815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41265,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41268,N,41269,41271,N,N,N,N,N,N,41272,N,N,N,N,
+41273,N,N,N,N,N,N,N,41274,N,N,N,N,N,N,N,N,N,41276,N,N,N,N,N,N,11816,N,N,N,N,N,
+N,N,N,N,41275,N,N,N,N,N,41277,N,N,N,41278,N,N,N,N,N,N,N,11817,N,11818,41279,N,
+N,11819,N,N,N,N,N,N,N,11820,N,N,N,N,N,N,N,N,N,N,41280,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41282,N,N,N,N,N,N,41283,N,N,N,N,N,N,N,
+N,N,11822,11823,N,N,N,N,N,N,N,N,N,N,41284,N,11824,N,41285,N,N,N,N,N,N,11825,
+11821,N,N,N,41281,N,N,N,N,N,11826,N,11827,N,N,N,N,N,N,N,N,N,N,41287,41288,N,
+41289,N,N,41290,11828,N,N,N,41291,N,N,41292,N,N,N,N,11829,N,N,N,N,N,N,N,41293,
+N,11830,N,N,11831,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41296,N,N,N,N,N,N,N,N,N,N,N,41297,N,N,N,N,N,N,41298,N,N,N,11833,N,41299,N,N,N,
+41300,N,N,41301,N,N,N,N,N,N,N,N,N,N,N,N,N,11834,N,N,N,N,N,41295,N,N,N,N,N,N,N,
+N,N,N,11809,41303,41304,11835,11836,N,N,N,N,N,N,N,N,N,N,N,11837,N,41305,N,N,
+41306,N,N,N,N,11838,N,N,N,41307,N,41308,N,N,N,41309,N,N,N,N,11839,N,N,N,N,N,N,
+11840,N,N,N,N,N,N,N,N,N,N,N,N,11842,N,N,N,N,11841,11843,41311,N,N,N,41312,N,N,
+N,N,N,N,N,41313,N,N,N,N,41314,N,N,N,41315,N,N,N,N,N,N,N,N,N,N,N,41316,N,N,
+41317,N,N,N,41318,N,N,N,N,N,41319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,41321,N,N,N,N,N,N,N,N,N,41322,41323,11844,41324,41325,N,N,N,N,N,41326,N,N,N,
+N,N,N,41320,N,N,N,N,N,N,41327,N,N,N,N,N,N,41329,N,N,N,N,N,N,N,N,41330,41331,N,
+N,N,N,N,N,N,N,41332,N,N,41333,N,N,N,N,11845,N,41336,N,11847,N,N,N,41338,N,N,N,
+N,41339,N,N,N,N,N,N,N,41340,N,N,N,N,11848,N,N,41341,N,N,N,N,N,N,N,N,11846,
+41334,11851,N,N,11850,N,41761,N,N,11852,N,N,N,N,N,N,N,N,N,N,N,41763,N,N,N,
+41764,N,N,11853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11854,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,11855,N,N,N,N,N,N,N,N,N,N,11857,N,11858,N,N,N,N,N,
+N,N,N,41766,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41768,N,N,N,N,N,N,N,62580,N,N,
+N,N,N,N,N,41769,N,N,N,N,N,N,N,41770,N,N,N,N,N,N,N,N,N,N,N,N,41772,N,N,N,N,
+11860,N,N,N,N,N,41773,N,N,N,N,N,N,N,N,N,41774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41776,N,N,N,N,N,N,11861,N,N,N,N,N,N,11862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,11863,N,N,N,11864,N,N,N,N,N,N,N,N,N,N,N,11865,N,N,N,N,41779,41780,11866,
+41781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41782,11868,N,11869,41783,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,11870,N,N,N,N,N,N,N,N,N,N,N,41785,N,11871,N,N,N,N,41786,12158,N,N,N,
+11872,N,N,N,N,N,N,N,N,N,N,41787,N,N,N,N,N,N,N,N,N,N,41788,N,N,N,N,N,N,N,N,N,N,
+41790,N,41789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11873,N,N,N,N,41792,N,N,N,N,N,N,N,N,
+N,N,N,41794,N,41795,N,N,N,N,N,N,N,N,41796,N,N,N,N,N,N,N,N,N,N,41797,41798,N,N,
+N,N,N,N,N,N,N,N,N,N,11874,N,41799,N,11876,N,N,N,11877,41801,N,N,N,N,11878,N,N,
+N,N,11879,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11881,N,N,N,N,N,N,41803,N,N,
+N,11882,11883,N,N,N,N,N,N,11884,N,N,41804,41805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,11885,N,N,N,N,N,N,N,41806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41807,N,N,N,N,N,N,
+N,N,41808,N,N,N,41809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,11887,N,11888,N,N,N,41812,N,N,N,N,41813,N,N,N,N,N,N,N,N,N,N,N,N,N,41814,N,
+N,11889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11890,N,N,N,N,N,N,N,N,N,
+11891,N,N,N,N,N,N,41815,N,N,N,N,N,N,N,N,N,N,N,N,N,11892,N,41816,N,N,41818,N,N,
+N,N,N,N,N,N,41819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41823,N,N,N,N,41824,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41826,41827,11893,N,N,N,N,N,
+N,N,N,N,N,N,20350,N,N,N,N,N,41829,N,N,11894,41830,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,41832,N,N,N,N,N,N,N,N,N,11895,N,N,N,N,N,N,N,41828,N,N,
+N,N,N,N,N,N,N,N,N,N,41833,N,N,N,41834,N,N,N,N,11897,41835,N,N,N,N,N,N,N,11898,
+N,N,N,N,N,N,N,N,N,N,11899,N,N,N,N,N,N,N,N,11900,N,41836,N,N,41837,N,N,N,N,N,N,
+N,41838,11901,N,N,N,N,N,11896,N,N,N,41839,11902,N,N,N,N,41840,N,N,12065,N,N,N,
+41841,41842,N,N,N,N,N,N,N,N,41843,N,N,41844,N,N,N,N,41845,N,N,N,41846,N,N,
+12066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,41848,N,N,41849,N,41850,N,41851,N,N,N,N,N,N,N,N,N,N,N,12067,41852,41853,N,N,
+N,N,N,N,N,41854,N,N,N,N,12068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,12069,N,N,N,N,N,N,N,N,N,12070,N,N,N,N,N,N,42017,N,N,N,N,42018,N,N,N,N,
+N,42020,N,N,42021,N,N,N,N,N,12071,N,N,N,N,N,N,N,N,N,N,N,N,N,12072,N,42023,
+42024,N,N,42025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42027,N,N,N,
+12073,42028,N,N,N,12074,N,42029,N,N,N,N,N,12075,N,N,42030,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+42035,N,N,N,N,N,N,N,N,N,42036,N,N,42037,N,12078,N,N,42038,42032,N,N,N,N,N,N,N,
+N,N,N,42039,N,N,N,N,42041,N,N,N,N,N,N,42043,42046,12080,N,N,N,N,N,12081,N,
+42047,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42044,N,N,N,N,N,N,N,42048,
+N,N,N,N,N,N,42049,N,N,N,12082,N,42051,N,42052,42053,N,N,N,N,N,N,42054,N,12083,
+N,N,N,N,N,N,N,N,N,29735,N,N,N,N,N,N,N,N,N,N,42055,N,42056,N,N,N,N,N,12085,N,N,
+N,N,N,N,42057,N,12087,N,12088,12089,N,N,N,12084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,42059,N,N,N,42060,N,N,N,N,N,N,N,N,42061,N,N,N,12090,42062,N,N,42063,12091,
+N,N,N,N,N,N,N,N,N,42064,12092,N,N,12093,42065,N,N,N,N,42066,12094,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,42067,N,N,N,12095,12096,N,N,42068,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,42069,N,N,N,N,N,N,N,N,42070,N,N,N,N,N,N,N,N,N,N,N,N,N,42071,42072,
+12097,N,N,N,N,N,N,N,N,N,N,42074,N,N,N,N,N,N,N,N,N,N,N,12099,N,42075,N,N,N,N,N,
+42077,N,N,N,N,N,12100,N,N,N,12101,12102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42079,
+42080,N,N,N,N,N,42081,42082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,42084,N,N,N,N,N,N,42085,12103,N,N,42086,42087,42088,N,12104,N,N,N,42089,
+12105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42093,N,12106,
+42094,42095,N,N,N,N,N,N,N,N,N,42096,N,N,N,42092,N,N,N,N,N,N,N,N,N,N,N,12109,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,12110,12111,N,N,N,42099,N,N,12112,N,N,N,N,N,N,N,
+42097,N,N,N,N,N,N,42102,N,N,N,N,N,12113,N,42103,N,N,N,N,N,N,12114,N,N,42104,N,
+N,N,N,12115,12116,N,42106,N,N,42107,N,42108,N,12117,42109,N,N,N,N,12118,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42110,N,42273,N,N,N,N,N,N,42274,N,N,N,N,N,N,
+N,N,N,N,42275,N,N,N,N,N,N,42276,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42278,N,N,42279,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12120,N,N,12121,N,N,42280,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,12123,N,N,N,N,N,N,N,N,N,N,N,N,12124,42281,42282,N,
+42283,N,42284,42285,N,N,N,42286,N,N,N,N,N,N,N,N,42287,12125,N,N,N,N,N,N,N,N,N,
+N,12127,42288,N,N,N,N,N,N,42289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42291,N,N,N,
+N,N,N,N,N,N,42292,12130,N,N,N,12129,N,12131,N,N,N,N,N,12132,N,N,N,N,N,12133,N,
+42293,N,N,N,N,N,N,12134,N,N,N,N,N,N,N,N,N,42294,42295,42296,42297,N,N,N,N,
+42298,12135,42299,N,N,N,N,N,N,42300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42301,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42304,N,N,N,N,N,N,N,N,42306,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42309,N,12137,N,42310,N,N,N,N,N,N,N,N,N,N,N,N,
+N,12138,N,N,N,N,N,N,N,42312,42313,N,N,N,N,N,42314,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+12139,N,N,N,N,N,N,12140,N,N,N,N,N,N,N,N,N,N,N,N,42315,N,N,N,N,12141,N,N,N,N,N,
+N,N,N,N,42316,N,N,N,N,N,N,N,N,N,N,N,N,N,42317,N,N,N,N,N,N,12142,N,N,N,N,42318,
+N,N,N,N,42319,N,N,N,N,12143,N,N,N,N,N,N,N,N,N,N,12144,42320,N,N,N,N,42321,
+42322,N,N,42323,N,N,N,N,N,N,42324,N,N,N,N,N,N,N,N,N,32378,42328,42329,N,N,N,N,
+N,12145,N,N,N,42330,N,N,N,N,N,N,N,N,N,N,N,12146,N,N,N,42331,N,N,N,N,N,42332,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+42333,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42334,N,12147,N,N,N,N,N,12148,N,N,N,N,N,N,
+N,N,N,12149,N,N,42335,N,N,N,12150,N,N,N,N,N,12151,N,N,N,N,N,N,42336,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,42337,N,12152,42338,42339,N,42340,N,N,N,N,12153,N,N,N,N,
+N,N,N,N,N,42341,N,42342,N,42343,N,N,N,N,42344,N,N,N,N,42345,N,N,N,N,12154,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42346,N,42347,N,N,N,42348,N,N,N,N,42349,
+N,N,N,N,N,N,N,N,42351,N,42350,N,N,N,N,42352,42353,N,N,N,N,N,N,N,42354,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,42355,N,12156,N,N,N,N,N,N,N,N,N,N,N,12157,N,N,N,N,N,N,N,
+42357,N,N,N,N,N,N,42356,N,N,N,N,N,N,N,N,N,N,N,N,20309,N,N,N,N,N,N,N,N,N,N,
+42358,N,N,N,N,N,42359,N,N,N,20310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42360,N,N,
+N,N,N,N,42361,N,N,N,N,N,N,N,N,N,N,N,N,42362,20311,N,42363,N,42364,N,N,42365,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,20312,N,N,43041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,43042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43044,N,N,N,N,N,N,N,N,N,N,N,
+N,N,43046,N,N,N,N,N,N,N,43047,N,20313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+20314,N,N,N,N,43050,N,N,N,N,N,N,N,N,N,N,N,43051,43053,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,20315,N,N,N,N,N,N,N,N,N,N,N,20316,N,N,N,N,20317,N,N,N,N,N,43054,N,20318,N,
+N,N,N,43055,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,32379,N,N,N,43057,N,N,20320,43058,N,N,N,43059,43060,43061,N,
+N,N,N,N,N,43062,N,N,N,N,N,N,N,N,N,20324,N,43065,N,N,N,N,N,N,N,N,N,N,N,43068,N,
+43069,N,N,N,N,20325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20326,43073,N,43074,20327,N,
+N,43075,43076,N,N,20328,N,N,43078,N,N,N,N,N,N,N,43079,N,N,N,N,20329,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,43081,N,20330,N,N,N,N,20331,N,20332,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20333,43084,N,N,N,N,N,N,20336,N,N,
+43085,N,N,N,N,N,N,N,N,N,N,N,N,43087,N,N,43088,N,N,N,43089,N,43090,20337,N,N,N,
+43086,N,N,N,N,N,43091,N,N,N,N,N,N,N,43092,N,N,N,N,N,N,N,N,43093,N,N,N,20339,
+20340,N,N,20342,N,N,N,N,N,N,N,N,20341,N,N,N,N,N,N,N,N,N,N,N,N,N,43095,N,N,N,N,
+N,N,N,N,43096,N,N,20343,N,N,43098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20344,N,N,N,
+N,N,N,43101,N,N,N,N,N,N,N,N,N,43103,N,43104,N,N,43105,N,43106,N,N,N,N,N,N,
+20345,N,N,N,20346,N,N,20347,N,N,N,N,N,N,N,N,43107,N,43108,N,43109,N,N,N,20348,
+43111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20349,N,N,N,N,N,43112,N,N,N,N,N,43113,
+43114,N,N,N,N,N,N,N,43115,N,29736,N,43117,N,N,N,N,43118,43120,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,43122,N,29737,43123,N,N,29738,N,N,N,N,N,N,43125,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,43126,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43127,N,N,N,N,N,N,N,N,N,N,
+43128,N,N,N,N,N,N,N,N,N,N,N,N,43130,N,29739,N,N,N,N,N,29740,N,N,N,N,N,N,N,N,N,
+N,N,N,43132,43133,43134,44065,N,N,N,N,N,N,N,N,32380,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44067,N,N,N,N,
+44068,N,44069,N,N,N,N,N,N,N,N,N,N,N,N,44070,N,N,N,N,29741,44071,N,N,N,N,N,N,
+44072,N,N,N,N,29743,N,N,N,N,N,N,44073,N,N,N,N,N,N,44074,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29744,N,N,N,44076,29745,N,29746,N,N,N,
+N,29747,44077,N,N,N,N,N,44078,N,N,N,N,N,N,N,N,N,N,N,N,N,44079,29748,44081,N,N,
+N,N,29749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29750,N,29751,N,N,N,N,N,N,29752,N,N,
+29753,N,N,N,N,29754,N,44082,N,N,N,N,N,N,N,N,N,N,N,N,29755,N,N,N,29756,N,N,N,N,
+N,N,N,N,N,N,44083,29757,N,N,29758,N,N,N,N,N,N,N,N,N,N,44084,N,N,N,N,N,N,N,N,N,
+N,29759,44085,N,N,N,N,N,N,N,N,N,N,29760,N,N,N,N,N,44086,N,N,N,N,N,N,N,N,N,N,N,
+N,29761,N,N,N,N,N,44087,N,44088,N,N,29762,N,N,N,N,N,N,N,29763,N,N,N,N,N,29764,
+N,29765,44089,N,N,N,N,N,N,N,N,N,N,N,44090,N,N,44092,N,29766,N,44093,N,N,N,N,N,
+N,44094,44095,44096,N,N,N,N,N,N,N,N,N,29767,N,N,29768,44097,N,N,N,N,N,N,29769,
+N,N,N,N,44098,44099,N,N,N,44100,N,N,N,N,N,N,N,N,44101,29770,N,N,N,N,N,N,29771,
+N,N,44103,29772,N,N,N,N,N,N,N,N,N,44104,N,44105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+29773,N,29774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29775,N,N,N,N,44107,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44108,N,N,N,N,N,N,N,N,N,N,44109,N,N,N,N,N,N,N,N,N,N,44110,N,N,N,N,
+N,N,N,29777,29778,N,N,N,N,N,N,N,N,N,44111,N,N,N,N,N,N,N,44113,44114,N,N,N,N,N,
+N,N,N,N,N,N,N,44115,N,N,N,N,N,N,N,N,N,44116,N,N,29779,N,N,N,N,N,N,N,N,29780,
+29781,N,N,N,44117,N,44118,N,29782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44119,N,N,N,
+44120,N,N,44121,N,N,29783,44122,N,44123,44124,N,N,N,N,N,44125,N,N,29784,N,
+44126,N,N,N,N,N,N,N,N,N,N,N,N,29785,N,N,N,N,29786,N,N,N,N,N,N,29787,N,N,44127,
+N,N,N,N,N,N,44129,N,N,N,N,44130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,44131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44132,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,29789,N,N,N,N,44134,44135,N,N,N,44136,44137,N,N,N,N,N,
+N,N,N,N,N,N,N,44138,N,N,44139,N,N,N,N,44140,N,N,N,N,N,N,N,N,N,N,N,29792,N,N,
+29791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44142,N,N,N,N,N,N,N,
+44143,N,44144,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44145,44147,N,N,N,N,N,
+N,N,N,N,N,N,N,29794,44148,N,N,N,N,N,44149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,29795,N,N,N,N,29796,N,N,44150,N,N,N,N,N,44151,N,N,N,N,44152,44153,N,N,N,
+29797,N,N,N,29798,N,N,N,N,N,N,44154,N,N,44155,N,N,N,N,N,N,N,N,44157,N,29799,N,
+N,N,44158,N,N,N,N,N,N,N,44156,N,N,N,N,N,N,N,N,N,29800,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,44321,N,N,N,N,N,N,N,N,N,N,N,N,44322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44323,
+29802,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,29803,44325,44326,N,N,N,N,N,N,29804,N,N,44327,N,N,44328,N,N,N,N,N,N,N,29805,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44331,N,N,44332,N,N,N,29806,
+N,44333,44334,N,N,N,N,44335,N,29807,44336,N,N,N,N,N,N,N,N,N,44337,N,N,N,N,N,N,
+N,N,N,N,44339,N,N,N,N,N,N,N,N,N,N,N,29808,N,N,N,N,N,N,44342,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,29809,N,N,N,N,N,N,N,44343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44346,N,N,
+N,N,44344,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,44347,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44349,44350,N,N,N,N,N,N,
+44351,N,N,N,44352,N,N,N,N,29810,N,N,N,N,N,44353,44354,29811,N,N,N,N,44355,N,N,
+29812,N,44348,44356,N,N,N,N,N,N,29813,N,N,N,29814,N,N,N,N,N,N,N,N,N,44357,N,N,
+N,29815,N,N,44358,N,N,N,44359,N,N,N,N,N,44360,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29817,N,N,N,N,N,N,N,N,44361,44362,N,44363,N,
+N,29818,N,N,N,N,N,N,N,N,N,N,N,N,29819,N,N,N,N,N,44364,N,N,N,N,N,29816,N,N,N,
+44365,N,N,N,N,N,N,N,N,N,44366,N,N,N,N,N,N,N,N,N,44367,N,N,N,N,N,N,N,N,N,N,N,
+44368,N,44369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+29821,29822,N,N,N,N,29985,N,N,N,N,N,29986,44370,44371,N,29820,N,29987,N,N,N,N,
+44372,N,44373,N,N,N,N,N,N,N,N,N,N,N,N,44375,44376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,29988,N,N,N,29989,N,N,N,44377,44378,N,N,N,N,N,N,N,N,N,N,44380,N,N,N,N,
+44381,N,44382,N,N,N,N,N,N,N,44384,N,N,N,29990,N,N,N,N,N,N,29991,N,N,N,N,N,N,N,
+N,44385,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44387,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29993,N,N,N,44388,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,44389,N,N,N,N,N,N,44390,N,N,44391,44392,N,N,N,N,44393,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,29994,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44394,N,N,
+44395,N,N,44396,N,N,N,N,N,N,44397,N,N,44398,N,N,N,N,N,N,44399,N,N,N,N,N,N,N,N,
+N,N,44400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44402,N,N,
+N,N,N,N,44403,N,N,44404,29996,N,N,N,44405,N,N,N,44406,29997,N,N,N,N,N,N,N,N,N,
+N,N,29998,N,N,N,N,N,N,N,N,29999,N,N,44407,30001,N,30002,N,N,N,N,N,44408,30003,
+N,N,N,N,30004,30005,N,30006,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,N,N,N,44409,N,N,
+30008,N,N,N,30009,N,44411,N,N,44410,N,N,N,N,N,44414,N,30011,30012,44577,N,N,N,
+N,N,30013,N,44578,N,30014,N,N,N,N,44581,44582,44583,44584,N,N,N,N,N,30015,N,N,
+N,30016,30017,N,N,44585,N,N,N,N,44586,N,N,N,N,N,N,N,N,N,N,N,N,30018,N,N,44587,
+N,44588,N,N,N,N,N,N,44589,N,N,N,N,N,N,30020,N,N,N,N,N,N,N,N,N,N,N,N,44591,N,N,
+N,44592,30021,N,N,44593,N,N,N,N,N,30022,N,N,N,44595,N,N,N,N,N,N,30023,N,30024,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30026,N,N,N,N,N,N,N,N,N,N,N,N,30027,N,N,N,
+44597,N,N,N,N,N,N,N,N,N,N,N,N,N,30028,30007,44599,N,N,N,44600,N,N,N,N,N,N,N,N,
+N,N,N,N,44601,30029,N,N,N,N,N,44603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,30031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30033,30034,N,N,N,44606,
+44607,N,N,N,N,N,N,44608,N,N,N,N,N,N,N,N,44609,N,N,N,N,N,N,N,N,30032,N,N,N,N,N,
+N,N,N,N,N,N,N,N,44613,N,44614,N,N,N,N,30035,N,N,N,N,N,30036,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,44616,30037,N,N,N,N,30038,N,N,30039,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44620,N,44621,N,N,N,N,N,N,N,N,30040,N,N,N,N,30042,N,N,44622,N,N,N,
+N,44623,N,N,N,N,N,N,N,N,N,44624,N,N,N,N,30043,N,44625,N,44626,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,44627,N,N,N,N,N,N,44628,N,30041,N,N,30044,30045,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,44619,N,N,N,N,N,N,N,44632,N,N,N,N,30047,N,44633,N,N,N,N,
+N,N,N,N,N,N,N,N,30048,44634,N,N,N,30049,N,44636,N,N,N,N,N,N,N,44637,N,N,44638,
+N,N,N,N,N,44639,44640,N,N,N,44641,N,N,44642,N,N,N,N,N,30046,N,N,44643,N,44644,
+N,N,N,30050,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44646,N,N,44647,N,N,N,30051,N,N,
+30052,N,N,N,N,44648,N,44649,N,N,N,N,N,44650,N,N,N,N,N,N,N,N,N,N,N,N,N,44651,N,
+N,N,N,N,44652,N,44654,44655,44656,N,44657,N,N,N,N,N,N,30054,N,30055,N,N,N,N,
+44658,44659,N,N,N,N,N,N,30056,N,44660,N,N,N,N,N,N,44661,N,N,N,N,N,N,N,44666,N,
+44667,N,N,30057,N,N,N,44668,N,N,44669,30058,N,N,N,N,N,44670,N,N,44833,N,N,N,N,
+N,N,N,N,N,N,44834,44835,N,N,30059,N,N,N,44836,30060,N,N,30061,30062,N,N,N,N,N,
+44837,N,N,N,44662,30063,44838,N,N,N,44839,N,N,30064,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30067,N,N,N,N,N,
+44843,N,N,N,N,N,N,30068,N,N,N,44845,N,N,30065,N,N,N,N,N,N,N,N,N,N,N,N,N,30069,
+N,N,N,N,N,N,N,N,N,N,N,30070,30071,N,N,N,30072,44846,N,N,44847,N,N,N,N,N,44848,
+N,N,N,N,N,N,N,44849,N,N,N,N,44850,30073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44851,N,N,N,44853,N,44854,N,N,N,N,N,N,N,N,N,N,N,N,30075,44855,N,N,N,N,N,N,
+30076,N,N,44856,N,N,N,N,N,N,44857,N,N,44858,N,44859,N,N,N,44860,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,30077,N,44861,N,N,N,N,44862,N,N,N,N,N,N,N,N,N,N,N,30242,44868,N,
+N,N,N,N,30243,30244,N,N,N,44869,44870,N,N,N,44871,44873,30245,30246,N,N,N,N,N,
+N,N,44874,30247,N,44875,N,N,N,30248,N,N,N,N,44876,N,N,44877,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,44865,N,44879,44880,44881,N,N,N,N,N,N,30250,N,N,30251,44882,
+N,N,N,N,N,30252,44883,N,N,44884,N,N,N,N,44886,N,30253,N,44887,N,N,N,30254,N,N,
+N,N,30255,N,N,N,N,N,N,N,N,44888,N,N,N,N,N,N,30256,N,N,N,N,N,N,N,30257,N,N,N,N,
+N,N,44885,N,N,N,44890,N,N,N,N,44891,N,N,N,N,N,30259,N,44892,N,N,N,N,N,44894,N,
+N,30260,N,N,N,N,N,N,N,N,30261,30262,44895,N,44896,N,N,N,30263,N,N,N,N,N,44898,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44899,N,N,N,N,N,N,N,N,44900,N,N,N,N,N,N,N,N,
+N,44902,N,N,N,44901,N,N,N,N,N,N,N,44903,44904,N,N,N,N,N,N,30264,N,N,30265,N,N,
+N,N,44907,N,N,N,N,44908,44909,44910,N,N,N,N,N,N,N,N,N,44911,44913,N,N,N,44914,
+44915,44916,N,N,N,N,N,44918,N,N,N,30268,N,N,30269,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30270,N,N,44920,N,N,N,N,N,30271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30272,N,N,N,
+44921,N,N,N,N,N,N,N,N,N,N,N,30273,N,44922,N,N,N,N,N,N,N,30274,N,N,N,N,30275,N,
+30276,N,N,N,N,44923,N,N,N,N,N,N,N,N,44924,N,30277,N,N,44925,N,N,N,N,N,N,44926,
+30278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60961,N,N,N,N,N,N,N,N,N,
+N,N,N,N,30279,N,N,N,30280,60962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60964,60965,N,N,N,
+N,N,N,N,N,60966,60967,60968,N,N,N,N,N,30282,N,N,N,N,N,N,30283,30284,N,N,60969,
+N,N,N,N,N,N,N,N,N,N,N,60970,60971,N,N,N,N,N,N,60972,N,N,60973,N,N,N,N,N,N,N,N,
+N,N,N,N,N,30285,60974,N,N,30286,N,N,N,N,60975,N,N,N,60976,N,30287,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30288,N,60977,60978,N,
+N,N,60979,N,N,N,N,60981,N,N,N,N,N,N,N,N,N,N,N,N,N,60982,N,N,N,N,N,N,N,N,N,N,N,
+30289,N,60983,30290,N,N,N,N,N,N,N,N,N,N,61007,N,N,N,N,N,60984,N,N,N,N,N,N,
+30292,N,30293,N,N,N,N,N,N,N,N,N,N,N,N,N,60985,30294,30295,N,N,60986,N,N,N,N,N,
+N,N,N,N,N,60988,60989,N,60990,30296,N,N,N,30297,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30291,N,N,60991,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60992,N,N,N,30299,N,N,
+N,N,N,N,N,N,N,60993,N,N,N,30300,N,60995,N,N,N,60996,N,60997,N,N,N,30301,N,N,N,
+N,N,N,N,N,60998,N,30302,60999,61000,30303,N,N,N,N,N,N,N,N,N,N,N,N,30298,61002,
+N,N,N,30305,N,N,N,N,N,61003,N,N,N,30306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61004,N,61005,61006,N,N,N,N,N,N,30307,61008,N,30308,N,N,61029,N,N,N,N,
+30309,N,N,61009,N,N,30310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30311,N,N,61010,N,N,61011,N,61012,N,N,N,N,30312,N,N,N,N,N,N,N,N,N,N,61013,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,61014,61015,30314,N,N,N,N,30315,N,30316,61016,N,N,
+61017,N,N,N,61018,N,N,30317,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30318,61025,30319,N,61026,N,N,N,N,N,61027,N,N,N,N,N,N,N,N,N,N,30320,N,N,61028,
+N,30321,N,N,N,61030,N,N,N,N,N,61031,61032,61033,N,N,N,N,N,30322,N,N,N,30323,
+30324,N,30325,N,61034,N,N,N,N,N,N,N,N,N,61035,N,N,N,N,N,N,N,N,N,N,N,N,61036,N,
+N,N,N,N,30326,61021,N,N,N,N,N,N,61038,N,N,N,61039,N,N,N,N,61040,N,N,N,N,N,N,N,
+N,N,N,61042,N,30328,N,61037,N,N,N,N,N,61043,N,N,N,N,N,N,N,30329,N,N,N,61044,
+61045,N,61046,61047,N,N,61048,N,61049,N,61050,61051,N,N,61052,N,N,N,N,30330,N,
+30331,N,N,N,N,61053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61217,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61218,N,N,N,30332,N,N,N,N,N,30333,N,N,61219,N,N,N,N,N,N,N,N,N,N,61220,N,
+30334,N,61221,N,N,N,30497,N,N,61222,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,61223,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61225,N,N,N,N,N,N,N,N,N,N,N,N,N,61226,N,61227,
+61228,N,61229,N,N,N,30499,N,N,N,N,N,N,N,61230,N,30500,N,N,N,N,N,N,N,N,N,N,
+61231,N,N,N,N,30502,N,N,N,N,30503,N,N,N,30504,N,61224,61232,N,N,N,N,N,61233,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30505,61235,N,N,N,N,61236,N,30506,61237,
+N,N,N,30507,N,61238,30508,30509,N,N,N,N,N,61239,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61241,30510,N,N,N,N,N,N,N,N,N,30511,N,N,N,30512,30513,N,N,61242,N,N,
+N,30514,N,61243,N,61240,N,N,N,N,N,N,61245,30515,N,N,N,N,61246,N,30516,N,N,N,N,
+N,N,N,61247,N,N,N,N,N,61249,30517,N,N,N,N,N,30518,N,61244,N,N,N,N,N,N,N,N,
+30519,61250,61251,30520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61252,N,N,N,61253,N,N,N,
+N,N,N,N,N,N,N,61254,N,N,N,N,N,N,30522,N,N,N,N,30523,N,N,N,30521,N,N,61256,
+61257,N,N,N,N,30524,30525,61258,N,N,61259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,61260,N,N,N,N,30526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61262,61263,N,
+61264,N,N,N,N,N,N,61265,N,N,N,61266,N,N,30527,61267,N,N,30530,N,N,N,N,N,61269,
+N,N,N,N,N,N,N,N,30528,30529,N,N,N,N,N,30531,61270,N,N,N,61271,N,N,61272,N,
+61273,N,N,N,N,N,N,30532,61274,N,N,N,N,N,N,N,61275,N,N,61276,N,N,N,30533,61277,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,61278,N,61279,N,N,N,N,N,N,N,61282,N,N,N,N,30534,N,
+N,N,N,N,N,30535,N,N,N,N,N,61283,N,N,N,N,N,30536,N,N,N,61280,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,61286,N,N,N,N,N,N,61287,N,61288,30537,N,N,N,30538,N,N,N,61289,N,N,N,
+N,N,N,N,30539,N,N,N,N,N,N,N,61285,61290,61291,N,61292,61293,61294,N,N,N,61295,
+N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30542,N,30543,N,N,N,N,N,N,N,N,N,N,30541,
+N,N,30544,61297,30545,61298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30546,
+30547,N,N,61300,N,N,N,N,N,61299,30548,30550,61301,N,N,N,N,N,N,N,N,30551,N,
+61302,N,30552,N,N,N,N,N,N,N,30553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61305,N,N,N,N,30555,N,30556,N,N,N,N,N,N,N,N,N,N,30557,N,N,N,61304,N,N,N,N,
+61306,N,N,N,N,61307,N,61308,N,N,N,N,N,N,N,N,N,N,N,61309,61310,N,N,N,61473,N,N,
+N,N,N,N,30559,N,N,N,N,N,N,30558,N,N,30560,N,N,N,N,N,N,61475,N,N,N,N,N,N,N,
+61476,N,N,N,N,N,61477,N,N,61478,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,30561,30562,N,N,N,N,N,N,61479,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30563,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61482,N,N,N,N,N,N,N,N,61483,N,
+N,N,61484,61485,N,N,N,N,N,N,N,N,61487,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61488,N,
+30564,30565,61489,N,N,N,N,N,N,N,N,N,N,N,61490,N,N,N,N,N,N,N,N,N,N,61492,61493,
+N,N,N,N,N,N,N,N,61494,N,N,N,N,N,N,61495,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,61496,
+N,N,N,N,N,N,N,N,N,N,N,N,30568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61498,61499,N,
+61500,61501,N,N,N,N,N,N,N,N,N,N,N,N,30569,N,30570,61502,N,N,N,N,N,N,N,N,N,N,
+61504,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61507,N,N,N,N,N,N,61508,30571,61509,N,N,N,N,N,N,N,N,N,N,61510,N,N,N,N,N,
+61511,61512,N,N,N,N,N,N,N,N,N,N,N,N,N,30573,30574,N,N,N,61515,N,N,N,N,61516,N,
+61517,N,N,N,N,N,61514,N,N,N,61518,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30576,N,
+61519,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30577,N,N,N,N,61521,61522,N,61524,
+61525,N,61526,N,N,N,N,N,61527,N,N,N,N,30578,N,N,N,N,61528,N,N,N,61529,N,N,N,N,
+61530,N,N,N,N,N,N,N,N,N,61531,30579,N,N,61532,N,N,N,61533,N,61534,30580,30581,
+N,30582,N,N,61535,30583,N,61536,N,N,30584,N,N,N,N,N,N,N,N,N,61537,N,61538,N,
+61539,N,N,61540,N,N,61541,N,N,N,N,N,61542,N,N,N,30585,N,61543,N,N,N,30586,N,N,
+N,N,N,N,30587,N,N,30588,N,N,N,N,N,N,N,61544,N,30589,N,N,N,61545,N,30590,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,61546,61548,61549,N,N,N,N,N,30753,N,N,30754,N,N,N,N,N,
+N,N,N,61547,N,N,N,N,N,N,30755,30756,N,N,N,N,N,N,N,N,61550,N,30758,N,30759,N,
+30760,30761,30762,N,30763,30764,30765,61551,N,N,N,N,N,N,N,61552,N,N,N,N,N,N,
+61554,N,N,61555,30766,N,30767,30768,N,N,N,30769,N,61556,N,N,N,N,61557,61553,N,
+N,N,30770,N,N,N,N,N,61558,N,N,N,N,30771,N,N,N,N,N,N,N,N,30772,N,30773,N,N,N,
+61559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61560,N,N,N,61561,30774,30775,61562,30776,
+N,N,N,N,N,N,30781,N,61564,N,N,N,N,61565,30777,61566,N,N,30778,N,N,30779,61729,
+61730,N,30780,N,61731,30782,N,30783,30784,61732,61733,N,N,N,N,N,N,N,N,N,30785,
+N,N,N,61734,61736,61735,N,N,N,30786,N,N,N,N,N,N,N,N,30787,30788,N,N,N,N,N,N,N,
+N,N,N,N,N,61737,N,61738,N,30789,N,N,N,61739,N,N,N,N,N,N,N,N,N,N,N,N,61741,N,N,
+N,61740,N,N,N,N,N,N,N,N,N,N,61743,N,N,N,N,30790,30791,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,30792,N,N,N,N,N,N,N,N,61745,N,N,N,61746,N,N,N,N,N,61747,N,N,
+N,N,30793,N,N,N,N,N,N,N,N,N,N,N,N,N,61750,61751,N,61752,N,N,N,N,N,N,N,61753,N,
+N,N,N,N,61754,N,61755,N,61756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61757,N,N,30794,N,61759,61758,N,N,N,N,N,N,30795,61760,N,N,61761,61762,N,N,
+61763,N,N,N,N,N,N,N,N,N,N,61765,N,N,N,N,N,30796,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61767,N,N,N,N,N,N,N,N,N,N,N,N,N,61769,N,N,N,N,N,N,61770,N,N,N,N,N,N,N,61771,
+61772,N,N,N,N,N,61773,N,N,N,N,N,N,N,30798,61774,N,N,N,61775,N,N,N,N,N,N,N,N,N,
+61776,N,61777,61778,N,N,N,30799,N,N,61779,N,N,N,N,61780,N,61781,N,N,61782,N,N,
+N,N,N,N,N,61783,30800,N,30801,61784,N,N,N,61786,30802,N,N,N,N,N,N,61787,N,N,N,
+61790,N,30803,30804,N,61785,30805,N,61791,61792,N,30806,N,N,N,N,N,N,61794,
+32381,N,61795,N,N,N,N,30807,N,N,N,N,N,61797,N,30808,N,N,N,N,N,N,61796,N,N,N,N,
+61800,N,30809,N,N,N,N,N,61802,N,30810,N,N,N,N,N,N,N,N,N,61803,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,30811,30812,N,N,N,N,N,N,N,30813,61805,30814,N,30815,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,30816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61806,N,N,N,N,N,
+30817,61807,30818,30819,N,61809,61808,N,N,N,N,30820,61810,61811,N,30821,N,N,N,
+N,61812,N,N,N,N,N,N,30822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30823,N,N,N,61814,N,N,
+30824,N,30825,N,N,N,N,N,30826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30827,N,61816,
+N,N,N,61817,N,N,N,N,30828,N,N,N,N,N,N,N,N,N,N,30829,30830,N,N,N,N,N,N,N,N,N,N,
+N,N,61819,N,30831,61820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61821,N,N,N,N,N,N,
+30832,61822,30833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30834,N,N,N,N,N,N,30835,30836,
+N,N,N,N,N,N,N,N,N,61989,N,N,N,30837,N,N,30838,61990,N,30839,N,N,N,N,N,N,N,
+61991,N,N,N,N,N,N,N,61993,N,N,N,N,N,N,N,30840,N,61994,61995,N,N,30841,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30842,N,N,N,N,N,61998,N,N,N,N,61999,N,N,62000,N,
+62001,N,N,N,N,62002,30843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62003,62004,30844,N,N,N,
+62005,N,62006,N,N,N,62007,N,62008,N,N,N,62010,N,N,N,62011,N,N,N,N,N,N,62012,
+62014,62015,N,N,62016,N,N,N,62017,N,N,N,N,N,N,N,N,N,N,N,62018,N,N,N,N,N,N,N,
+62019,N,N,N,N,N,N,N,N,N,N,62020,30845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,31009,N,N,N,62021,N,N,N,N,N,N,31010,31011,N,31012,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,62022,N,N,N,31013,N,62023,N,N,N,31014,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,62025,N,N,N,N,N,N,N,N,N,62026,N,N,N,N,N,N,N,N,62028,
+62029,62030,N,N,N,N,62027,N,N,N,N,N,N,N,N,31018,N,N,31016,N,N,N,N,N,N,N,N,N,N,
+62031,N,N,N,N,N,N,N,N,N,N,N,N,62032,N,N,N,62033,N,62034,N,N,N,N,N,N,62035,N,N,
+N,N,N,N,N,N,N,N,62036,62037,N,N,31019,N,62038,N,N,N,N,N,N,N,N,N,N,N,31020,N,N,
+N,N,31022,N,62039,62040,62041,N,N,62042,31021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62044,N,N,N,N,N,N,N,N,N,N,62045,31023,N,N,N,N,N,N,N,N,62047,N,N,N,N,N,N,N,N,
+31024,N,62046,31025,N,N,31026,N,N,N,N,N,N,62048,N,N,N,N,N,N,N,N,N,31029,31030,
+N,N,N,62049,N,N,N,N,N,N,N,N,N,N,N,N,N,62050,N,N,62051,31034,N,N,N,N,N,N,N,N,N,
+N,62053,N,N,N,N,N,N,N,N,N,N,62054,N,N,N,N,N,N,31038,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,62055,62056,62057,N,31042,N,N,62058,N,N,N,N,N,62059,
+N,N,N,N,N,N,N,62060,N,N,N,N,N,N,N,31043,N,N,62061,N,N,N,31044,N,N,62062,N,N,N,
+N,N,N,62063,N,N,N,N,62064,31045,N,31046,N,62065,62066,N,N,N,N,N,N,31048,N,
+62067,N,N,N,N,N,N,N,31049,N,N,N,N,N,N,N,N,N,N,N,N,31050,N,31051,31052,N,N,N,N,
+N,N,62072,N,N,N,N,N,N,62073,N,N,N,62074,N,N,N,N,N,62075,N,N,62076,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,62078,N,N,N,N,N,N,N,N,N,N,62241,31054,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62242,N,N,N,N,62243,N,N,N,N,N,N,N,N,N,62244,N,N,62245,N,N,62246,31055,N,
+62247,62248,N,N,N,N,N,N,62249,N,N,62250,N,N,31056,N,N,N,N,N,N,N,62251,N,N,
+62252,N,N,N,N,N,N,N,N,N,62253,N,N,31058,N,N,N,N,62254,N,N,N,N,N,62255,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,31059,N,N,62256,N,N,N,N,N,N,N,N,62257,N,N,N,N,N,N,31061,
+N,N,N,N,N,62260,N,31062,62261,N,62262,N,N,N,N,N,N,N,N,N,N,N,N,N,62264,N,31063,
+N,N,62265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62266,62267,N,N,31064,N,N,
+N,N,N,N,N,N,62268,N,N,N,N,N,N,N,N,31065,62271,N,N,N,N,N,N,N,N,N,N,31066,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62274,N,N,62275,N,N,31067,62276,62277,N,
+62278,N,N,N,N,N,N,N,N,N,31068,N,62273,N,N,N,62282,N,N,N,N,N,31069,N,N,N,N,N,N,
+31070,N,N,N,N,N,N,62284,N,N,N,N,N,N,N,N,N,N,31071,N,N,N,62286,N,62287,N,N,
+62288,N,N,N,31072,N,31073,N,N,31074,62289,N,N,N,N,N,62285,N,N,N,N,N,62281,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,62292,62293,N,N,N,N,N,N,N,N,N,62294,N,N,31075,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,62296,N,N,N,N,N,62297,N,N,N,N,N,N,62298,N,N,N,N,N,
+N,N,N,62299,N,N,N,N,62300,N,N,N,N,N,N,N,N,N,62303,N,62304,31077,N,31078,62305,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62306,N,N,N,N,N,62307,31079,N,62308,N,N,N,N,N,N,
+N,62309,N,N,62310,62311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31081,N,31082,N,N,N,N,N,
+62312,N,N,N,N,N,N,N,N,N,N,31080,N,31083,N,N,31084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62313,N,N,N,N,62314,N,N,N,N,N,N,62315,N,N,N,N,N,62316,N,31087,N,N,N,N,62317,N,
+N,62318,N,N,N,N,N,N,N,62319,N,N,N,31088,62320,62321,62322,N,N,N,N,N,N,N,N,
+31089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31090,N,N,N,N,31091,N,N,N,N,N,
+N,N,N,N,N,N,31092,N,N,N,N,N,62326,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62328,62329,N,
+N,N,N,31093,N,N,62330,N,N,N,N,62332,N,N,N,62334,N,N,N,N,62497,N,N,N,N,N,N,N,
+31094,N,62499,N,31095,N,N,N,31096,N,N,N,N,N,N,N,N,62501,N,N,N,N,62502,N,N,N,N,
+N,N,N,N,N,62504,62505,N,N,N,31097,31098,62506,N,N,N,N,N,N,N,N,62508,31099,N,N,
+N,N,N,N,N,N,N,31100,62509,N,N,N,N,31101,N,N,N,N,N,N,N,N,N,N,N,N,N,31102,N,N,N,
+N,N,N,N,N,N,N,N,62512,62513,N,62514,31265,N,N,N,N,N,62515,31266,N,N,N,N,N,N,N,
+N,N,N,31267,N,N,N,N,N,62519,62520,N,31268,N,N,N,N,N,N,N,N,N,N,N,N,N,62521,N,N,
+N,N,N,62522,N,N,N,N,N,N,N,N,N,31269,N,N,N,N,62524,N,N,N,31270,N,N,62526,N,
+62527,N,N,31271,62528,N,N,N,N,N,N,N,N,N,N,62529,N,N,N,N,N,62531,N,N,31272,N,N,
+N,N,N,31273,62532,N,N,62533,N,N,N,N,N,N,N,N,N,N,N,62534,62535,N,N,N,N,N,N,N,N,
+62536,N,31274,N,N,N,N,N,N,N,N,N,31275,N,N,N,N,N,N,N,N,N,31276,62537,N,62538,N,
+N,N,N,N,N,N,N,N,31277,N,N,62539,N,N,N,N,N,N,N,N,N,N,62540,N,N,N,N,N,N,N,62541,
+31280,N,N,N,N,N,N,N,62545,31281,N,N,N,31282,N,62546,N,N,N,N,N,62547,N,N,62548,
+N,N,N,N,N,N,62549,31279,N,N,N,62550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,62551,N,31284,N,N,N,N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31286,N,N,N,N,N,N,N,N,N,32382,N,N,N,N,N,N,N,62552,N,62553,N,N,N,N,N,N,N,N,
+62554,N,N,N,N,N,N,N,62555,62556,N,N,31287,N,N,31288,N,N,N,62558,N,N,N,N,N,N,
+62559,N,62560,62563,62562,N,62564,N,N,N,N,62565,62566,N,N,31289,N,N,N,N,N,N,N,
+62567,N,N,62570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62572,N,62573,62574,N,N,N,N,N,N,N,
+N,62575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62576,62577,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,62579,31291,N,N,N,N,62582,31292,N,N,N,N,62583,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,62584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31293,N,N,N,62586,N,N,N,N,N,N,N,
+N,N,N,31294,62587,N,N,N,N,N,N,N,N,N,N,N,31295,N,N,N,31296,N,N,N,62588,N,62589,
+N,N,N,N,N,N,31297,N,31298,62590,N,N,62753,N,N,N,N,N,N,N,31299,62754,N,N,N,N,N,
+62756,N,62755,N,N,N,62757,N,N,62758,N,N,31301,N,62759,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62760,N,31302,N,N,N,N,N,62761,N,N,N,62762,N,N,N,N,31303,N,31304,N,N,N,N,
+31305,N,N,N,N,N,N,62763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62764,N,N,N,N,N,N,N,N,N,N,62765,N,N,N,62766,N,N,N,N,N,62767,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62768,N,N,62769,N,N,N,N,
+N,N,N,62770,N,N,62771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62772,N,N,N,N,N,N,N,N,N,
+N,N,N,62774,N,N,N,N,31306,N,N,N,N,N,N,N,N,N,N,62775,N,31307,62776,N,N,N,N,N,N,
+N,31308,N,N,N,N,N,62777,N,N,N,N,N,N,N,N,N,N,N,N,31309,N,62780,N,N,N,N,N,62781,
+62779,N,N,N,N,N,N,N,N,62784,N,31310,N,N,N,N,N,62785,N,N,N,N,N,62787,N,N,62788,
+N,N,N,N,62789,N,N,N,N,N,N,N,N,62783,N,N,N,N,N,N,N,62791,N,N,N,N,N,N,N,N,N,N,N,
+N,31311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31312,N,N,N,N,N,N,31313,
+31314,62793,N,N,N,31315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62795,N,N,62797,
+62798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62800,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,62801,N,N,N,N,N,N,N,N,31316,N,N,N,N,N,62802,N,62803,N,N,N,
+N,N,N,31317,N,N,N,N,31318,N,N,N,N,N,N,62804,31319,N,N,N,62805,N,N,N,N,N,N,N,N,
+62807,N,N,N,N,N,N,N,62809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62811,N,62812,62814,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62816,N,N,N,N,N,N,N,62817,62818,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,62820,N,62821,N,N,N,N,N,N,N,62822,N,N,N,N,N,N,N,N,
+62825,62823,N,N,62824,N,62827,N,N,N,62829,N,N,N,N,N,N,N,62831,N,N,N,N,62833,N,
+N,N,31323,N,N,62834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31324,N,N,N,N,62838,N,N,N,
+62840,N,62841,N,N,N,62842,N,N,N,N,N,N,62843,N,N,N,31326,N,N,N,N,62844,N,N,N,N,
+N,N,N,N,N,N,N,N,N,31327,N,31328,31329,N,N,62845,62846,31330,N,N,N,N,31331,N,N,
+N,63009,N,63010,N,N,31332,N,N,63011,N,63012,N,31333,31334,N,N,N,N,N,N,31335,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,63013,N,N,N,N,N,63014,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63015,N,N,N,N,N,31337,31338,31339,31340,N,N,N,N,N,
+63016,63017,N,N,N,63018,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63020,N,63021,N,N,N,N,
+31342,N,N,N,N,N,N,N,N,N,N,31343,N,N,63022,N,N,N,N,N,N,N,N,N,31344,N,63023,N,N,
+N,N,N,N,31345,63024,N,N,31346,N,N,N,N,N,N,N,N,N,31347,N,N,63019,31348,N,63025,
+N,N,N,N,N,N,N,N,N,N,31341,44618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,31349,N,63027,N,N,N,N,N,N,31350,N,N,N,N,N,N,63030,N,N,N,N,31351,N,63031,
+63032,N,N,31352,N,N,63033,N,63034,N,N,N,N,N,N,N,N,N,31353,N,31354,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31355,31356,N,N,N,N,N,N,31357,N,63035,N,N,N,N,N,
+31358,63036,31521,N,N,63037,N,N,N,N,N,N,N,N,63038,N,N,N,31522,N,N,N,63039,N,N,
+N,N,31523,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63040,31524,N,N,N,N,31525,N,N,N,31526,N,
+N,N,N,63041,N,63042,N,N,N,63043,N,63045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31528,N,63047,N,
+N,N,N,63048,N,63049,63050,N,N,N,N,N,N,63051,63052,N,63053,N,N,31529,N,N,N,N,N,
+63055,N,N,N,N,N,N,N,N,N,N,31530,N,N,31531,N,N,63056,N,63057,N,N,N,63058,N,N,N,
+N,63059,N,N,N,31532,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63062,N,N,N,N,N,N,31533,
+N,N,N,N,N,N,N,63063,N,N,N,N,N,N,N,N,31534,N,N,N,N,31535,N,N,N,N,N,31536,N,N,N,
+63064,N,31537,N,31538,N,N,N,N,N,N,N,N,N,N,N,63066,63067,N,N,N,63068,N,N,N,N,N,
+N,N,N,63061,N,N,N,N,N,N,N,N,N,N,63070,N,N,63071,N,N,N,N,63072,63073,63074,N,N,
+N,N,N,N,N,N,63075,N,N,63076,63077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63078,N,N,31541,
+N,N,N,N,31542,63079,63080,N,N,N,N,N,63081,N,N,N,31543,N,N,31540,N,63082,N,N,N,
+N,N,N,N,N,N,63087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63083,N,63088,N,63089,N,N,N,
+N,N,31544,N,N,N,N,63090,N,N,63091,63092,N,31545,N,N,N,N,N,N,N,N,N,N,63084,N,N,
+N,N,N,N,N,N,N,N,31548,63094,N,63095,N,63096,N,63097,N,N,N,N,63098,N,N,N,N,N,
+31549,N,N,31550,N,N,N,63099,N,N,N,N,N,N,N,N,N,63100,N,63101,N,N,31551,N,N,N,N,
+N,N,N,N,N,N,31547,N,N,31552,N,N,N,N,N,N,63267,N,N,N,N,63268,N,N,N,N,N,N,N,N,N,
+N,63269,N,N,63270,31553,N,N,31554,N,N,N,N,N,N,N,N,N,63271,63272,N,N,N,N,N,
+63273,N,63274,N,N,N,N,63275,N,N,N,N,N,N,31555,N,N,N,N,N,N,N,N,63276,N,N,N,N,N,
+N,N,N,31557,63277,N,N,N,31558,31559,N,N,N,N,N,N,N,N,N,N,31560,63278,31556,N,N,
+N,N,N,31562,N,N,N,N,N,63279,N,N,63280,N,N,63281,N,N,63282,N,31563,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,31564,63284,N,N,63285,N,N,N,63287,12136,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,63289,N,N,63290,31565,N,N,N,31566,N,N,N,N,N,N,31568,N,N,N,N,N,N,N,
+N,N,31570,N,N,63291,N,N,N,N,N,31571,N,63292,N,N,63293,N,N,N,N,N,N,N,N,N,N,N,N,
+63294,N,63295,N,N,N,63296,N,N,N,63297,N,N,N,N,N,N,31572,N,N,N,63298,63299,N,N,
+N,N,N,N,N,N,N,N,63300,N,N,N,N,N,N,N,N,63302,N,63303,N,N,N,N,31573,N,N,N,N,N,N,
+N,N,63304,N,63305,N,N,N,N,N,N,N,N,N,N,N,N,N,63306,N,N,N,63307,N,63308,N,N,N,N,
+N,N,N,N,N,N,N,63309,N,N,63310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31574,N,
+31575,31576,63312,N,63313,N,N,N,31577,N,N,63314,N,63315,N,N,63316,N,N,N,N,N,
+63317,N,N,N,N,N,63318,N,63319,N,63320,N,N,N,N,N,N,N,N,N,N,N,N,N,63321,N,N,N,N,
+N,N,N,N,63322,N,N,N,63323,N,63324,N,N,63325,N,N,N,N,N,N,N,N,N,N,N,N,N,63326,N,
+N,N,N,N,N,63327,N,N,N,N,N,N,N,N,N,N,N,63328,63329,N,N,N,N,N,N,N,N,N,N,N,31578,
+63330,N,N,N,N,N,N,N,N,N,63331,N,N,N,N,N,N,N,N,N,N,31579,31580,63335,N,63336,N,
+N,N,N,N,N,N,63337,N,N,N,N,N,N,N,N,N,N,N,N,63338,N,N,N,N,N,N,63334,N,N,N,N,
+31581,31582,N,N,N,N,N,N,N,31583,N,N,N,N,N,N,N,N,63341,N,N,63343,N,N,N,N,N,N,N,
+N,N,N,N,N,63344,N,N,N,N,N,N,N,31585,N,N,N,N,N,N,N,N,63346,N,N,N,63348,N,63349,
+63350,N,N,N,63351,63352,31586,63353,N,N,N,N,N,N,N,63345,63354,N,63355,N,N,
+31587,N,N,N,31588,63356,N,N,N,N,31589,N,N,63357,31590,N,N,N,N,N,N,N,N,N,N,
+31591,N,N,N,N,N,N,N,N,63358,N,N,N,N,N,63521,N,N,N,63522,N,N,N,N,N,N,N,N,N,
+63523,N,N,N,N,N,N,N,N,N,N,N,N,N,63525,N,N,N,N,N,N,N,N,N,N,N,N,N,63526,N,N,N,N,
+N,N,63527,N,N,N,N,63528,N,N,N,N,63531,N,N,N,N,N,63533,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31592,N,N,N,N,N,N,N,
+63534,N,N,N,N,N,N,N,N,N,31593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63535,63536,
+63537,N,63538,N,N,N,N,N,N,N,N,N,31594,N,N,N,31595,N,N,63541,63539,63542,N,N,N,
+N,N,N,N,63543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63544,63545,N,N,N,31597,
+63547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31600,31601,31602,N,31598,N,
+N,N,N,N,N,N,N,N,N,31603,N,N,N,N,N,N,N,N,31604,N,31605,N,N,N,N,63549,N,31606,N,
+N,N,N,N,N,31607,N,63551,N,N,63552,N,N,N,63553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,63556,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,63557,N,N,N,N,N,N,N,N,63558,N,N,N,N,N,N,63559,N,N,N,31608,N,N,N,N,N,N,N,N,N,
+N,63560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63561,N,N,N,N,N,N,63562,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31610,N,63563,N,63564,N,N,N,N,N,N,N,
+N,N,N,N,N,31611,N,N,N,N,N,63565,N,N,N,N,N,63567,N,63568,N,N,31612,N,N,N,N,N,N,
+63569,N,63570,63572,31613,N,63573,31614,N,N,N,N,N,N,N,N,N,N,N,63575,31777,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63576,N,31778,N,N,N,N,N,N,63577,N,N,N,N,N,N,
+63578,N,31779,N,N,N,N,N,63579,31780,N,N,N,N,N,N,N,N,N,63580,N,N,N,N,31781,N,N,
+N,31782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31783,N,N,N,31784,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,31785,N,N,N,N,N,N,63581,N,N,N,N,N,N,N,N,63583,N,N,N,N,N,N,63584,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,31786,N,N,N,N,N,N,63585,N,N,N,N,N,N,N,31787,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,31788,N,31789,N,N,N,N,N,63586,63589,N,N,N,N,63588,
+N,N,63590,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63591,N,N,63592,N,N,N,N,N,N,N,N,N,N,N,N,
+N,63593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63594,N,N,31793,N,N,N,N,N,N,
+N,N,N,N,63596,N,N,31794,N,N,N,N,31795,N,N,N,N,63597,N,N,N,N,N,N,N,N,N,N,31796,
+N,N,N,N,N,N,N,N,N,N,N,N,63598,N,N,N,N,N,N,N,N,63599,N,63600,N,N,N,N,N,N,N,N,N,
+63601,N,N,N,N,N,N,N,N,63602,63603,N,N,N,N,N,N,63604,31797,63605,63606,N,N,N,
+63608,N,N,N,N,N,N,N,63611,N,63612,N,31798,N,N,N,N,N,63613,N,N,N,N,63614,N,N,
+63777,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31799,63778,N,N,N,63779,N,N,N,N,N,63780,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63783,63782,N,N,N,
+N,N,63784,N,63786,N,N,N,N,N,N,N,N,63787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63789,63788,N,N,
+63790,N,N,N,N,N,N,N,31801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63792,63793,N,N,31802,N,
+N,N,31803,N,N,N,N,N,31804,63795,N,N,N,N,63796,N,N,N,31806,N,N,N,N,N,N,N,N,
+31807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,63797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63798,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,63799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63800,N,N,N,N,N,N,
+N,N,31808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63802,N,63803,N,N,N,N,N,
+31809,N,N,31810,N,N,N,N,N,31811,N,63804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63808,63809,N,N,N,N,N,63806,N,N,N,N,N,N,
+N,63811,N,63812,N,N,N,N,N,N,N,N,N,31812,63813,63814,31813,N,N,N,63815,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,63818,N,N,63819,N,N,N,31814,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63820,N,N,N,N,N,N,N,N,63821,N,N,N,N,N,N,N,N,N,N,N,N,N,63822,N,N,N,N,N,N,N,N,N,
+63823,63824,N,63825,31815,N,N,N,N,N,N,N,N,N,N,31816,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63826,N,N,N,N,N,63827,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,63828,N,N,N,N,63829,N,63830,63831,N,N,N,N,63832,N,N,N,N,31818,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,63834,N,N,63835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63837,31820,63839,N,N,N,N,N,N,N,63840,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,63841,N,N,N,N,N,N,31821,N,N,N,N,N,N,N,N,N,N,N,N,63842,N,
+31822,N,N,N,N,N,N,N,N,31823,N,N,N,N,N,N,N,N,N,63843,N,N,N,N,N,N,N,N,N,63844,N,
+N,N,N,N,N,N,N,N,31824,N,N,N,63845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63847,N,31826,N,N,N,N,N,N,N,N,N,N,N,N,N,63848,
+31827,63850,N,N,N,N,N,N,N,N,N,N,63852,N,N,N,N,63853,N,N,N,63855,N,N,63856,N,N,
+N,N,N,63857,N,63858,N,N,N,N,N,N,N,N,N,N,63859,N,N,N,31828,N,N,N,31829,N,N,N,N,
+N,31830,N,N,63860,N,N,N,63861,N,N,N,N,N,63862,63863,N,N,N,N,N,31831,N,N,N,
+63864,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31832,N,
+N,N,N,N,N,N,N,N,63865,N,N,N,N,N,N,N,N,N,N,N,63867,63868,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,63869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64034,N,N,31834,N,N,N,64035,N,N,N,64036,N,N,N,
+N,31835,N,31836,N,31837,N,31838,N,N,N,N,N,64038,31839,N,N,N,N,N,N,N,N,N,N,N,N,
+N,64040,N,N,31840,N,N,64041,N,N,N,N,N,N,N,31841,N,N,N,N,64042,31842,31843,N,
+31844,64043,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31845,N,N,N,N,64045,31846,31847,64046,
+N,N,N,N,N,N,N,N,N,N,N,64051,N,N,N,31848,N,N,64049,N,31849,N,64048,N,N,N,N,N,N,
+N,64052,64053,64050,N,N,N,64054,N,64055,N,N,N,N,N,N,N,N,N,N,N,N,N,31851,31852,
+31853,N,64056,N,N,N,64057,N,64058,N,N,N,31854,31855,N,N,N,31856,N,N,N,N,N,N,N,
+31857,N,31858,N,N,31859,N,N,64059,N,64060,64061,N,N,31860,N,N,N,N,N,N,N,N,
+64062,64063,31861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64064,N,64065,N,31862,N,N,N,N,N,
+64066,N,N,64067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64068,N,N,N,N,64069,N,N,N,N,N,N,
+N,N,N,31863,N,64070,N,N,N,N,N,N,N,N,64071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31864,
+N,N,N,N,N,N,N,N,N,64072,N,N,N,31865,N,64073,N,N,31866,N,64074,N,N,64075,N,N,N,
+N,N,31867,N,N,N,N,N,N,64076,64077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31868,N,
+N,64078,N,N,N,N,N,N,N,N,N,31870,32033,N,N,N,N,N,N,64081,32034,64082,N,N,32035,
+N,N,N,N,N,N,N,N,N,31869,64083,N,N,N,N,N,32036,N,N,64084,N,N,N,N,N,32037,N,N,N,
+N,N,64085,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,N,
+N,N,N,32038,32039,32040,N,32041,N,N,N,32042,N,64089,32043,N,N,N,64090,N,N,
+64091,N,N,N,64092,32044,N,64093,N,N,N,N,64094,N,N,64095,N,N,N,N,N,N,64096,
+64097,N,N,N,64098,N,64099,64100,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32045,N,N,N,
+64103,64104,N,64105,N,N,N,N,N,N,N,N,32046,64106,N,N,N,64107,N,N,N,N,N,N,N,N,N,
+64108,N,64109,N,N,N,N,N,64110,N,N,N,N,N,N,N,64111,N,N,N,64112,N,N,N,N,N,N,
+64115,N,N,N,N,N,N,N,N,N,N,N,N,64116,64117,N,32047,N,N,N,64118,N,N,N,N,32048,
+32049,N,64119,N,64120,N,N,32050,N,N,N,64121,N,64122,N,N,N,N,N,N,32051,N,N,N,N,
+64123,N,64124,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64290,N,64291,N,64292,N,N,N,32052,
+64293,N,32053,N,N,N,N,N,N,N,N,64294,N,N,N,64125,N,N,N,64295,N,N,N,N,N,N,N,
+64296,64297,32054,N,32055,N,N,N,32056,N,64298,N,64299,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64302,32057,32058,32059,N,N,N,N,N,N,64303,N,
+N,N,N,N,64304,N,N,64305,N,N,N,N,N,N,N,N,N,32060,32061,N,N,N,N,32062,64306,N,N,
+N,N,32063,64307,N,64308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64312,N,N,
+64313,N,N,N,64314,N,N,N,N,N,N,N,N,N,N,N,32064,N,N,64315,N,N,64309,N,32065,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32066,N,N,N,N,N,N,64320,N,N,N,N,32067,
+64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64322,N,32068,32069,N,N,64323,N,
+N,N,N,64324,N,N,N,N,N,N,N,N,N,64319,N,N,N,64316,N,N,N,N,N,64329,N,32071,32070,
+N,N,N,N,64325,N,N,N,N,N,64326,N,N,N,N,N,N,64327,64328,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64330,32072,64331,N,N,N,N,N,N,64332,N,N,N,N,N,N,N,
+N,N,64333,N,N,N,N,32073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32074,
+N,N,N,N,N,N,N,32075,N,64336,N,64337,N,32076,32077,64338,64339,N,N,N,N,N,N,N,N,
+N,N,N,N,64340,N,N,N,N,N,64341,64342,32078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32079,N,N,N,N,N,N,32080,N,N,32081,N,64344,32082,N,N,N,N,N,N,N,64345,N,32083,N,
+N,N,N,N,N,32084,N,N,N,N,N,N,N,N,N,N,64347,N,N,32085,N,N,N,N,32086,N,N,32087,N,
+N,N,N,N,N,32089,N,N,N,32090,64037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64350,N,N,N,N,N,
+N,64351,64352,N,N,N,N,N,N,N,64354,N,N,N,N,64355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,32091,N,N,N,N,N,N,N,N,64356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,N,32092,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,64360,N,N,32094,N,N,N,N,N,N,32095,32096,N,N,N,64363,N,N,N,N,N,64364,N,N,
+N,64365,N,N,N,N,N,N,64366,N,N,64367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32097,N,N,N,N,N,64370,N,64371,N,N,64372,32098,N,N,N,N,N,N,N,N,N,N,32100,N,N,N,
+N,N,32101,64374,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,32102,N,N,64377,N,N,N,N,32103,N,N,N,N,N,64378,N,N,N,N,N,64379,N,N,N,N,N,
+32104,32105,32106,N,N,N,N,N,64380,N,64381,N,N,32107,64382,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64545,N,N,N,32108,N,N,N,N,32109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,32110,64548,N,N,N,64549,N,N,N,64550,N,N,N,64551,N,
+N,N,N,N,N,N,N,N,N,N,32111,N,N,64552,64553,N,N,N,N,N,N,N,32112,N,N,N,64554,N,N,
+32113,N,N,N,N,N,N,N,32114,N,N,64555,N,N,N,N,64556,N,N,64557,N,N,N,64558,64559,
+N,32116,N,N,32115,N,N,64560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64561,N,N,32117,
+64562,N,N,N,N,N,32119,N,N,64563,64564,N,N,N,N,N,64565,N,64566,N,N,N,N,N,N,N,
+32120,N,N,N,N,64569,N,64572,N,N,N,N,N,32121,N,N,N,N,32122,N,64570,64571,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64573,N,N,N,N,N,N,N,N,N,N,32124,32125,N,N,
+32126,32289,N,32290,32291,N,N,N,N,N,N,N,N,N,N,32293,64574,N,N,N,N,N,32294,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64575,N,64576,N,N,64577,N,N,N,N,N,N,
+64579,64580,N,32295,64581,64582,N,N,64583,N,N,64584,N,N,N,N,64585,32296,N,N,
+64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64587,64589,N,64590,N,64591,N,
+32297,N,N,64592,N,N,N,N,N,64593,64594,N,64595,64596,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64599,64600,N,N,64602,64603,64604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64606,64607,64608,N,N,N,N,N,N,64609,64610,64611,N,N,N,64612,64613,N,N,N,N,
+64614,N,N,N,N,N,N,64615,64616,N,N,N,N,N,N,N,N,N,32298,N,N,N,64617,N,N,64618,
+64619,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32299,N,N,N,N,64620,N,N,
+64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64622,N,N,N,64623,N,64624,N,N,N,
+64625,N,N,N,N,N,64626,N,N,N,N,N,N,N,N,N,N,64627,N,N,N,N,64628,N,N,N,N,64629,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64631,N,N,N,N,N,N,N,N,64632,N,N,64633,32300,
+32301,N,N,N,N,N,N,64634,N,N,N,N,N,N,64635,N,N,N,N,64636,N,N,N,64637,N,N,N,N,N,
+64638,N,N,N,32302,N,N,N,N,N,N,N,N,32303,32304,N,N,64801,N,N,N,N,64802,N,32305,
+N,N,N,N,N,N,N,N,N,N,N,64803,N,N,N,N,N,32306,N,64804,N,32307,N,N,N,32308,N,N,N,
+N,N,64805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,64807,N,N,N,N,N,N,32309,64809,N,64811,N,N,N,N,N,N,N,
+32310,N,32311,N,N,64813,N,N,N,N,N,N,N,32312,N,64814,N,64815,N,N,64816,32313,N,
+N,N,N,N,64818,N,N,N,64819,N,N,N,N,64820,N,N,N,64821,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,32314,32315,64822,N,N,N,N,32316,N,N,N,64823,N,N,N,64824,N,64825,N,N,N,
+64826,N,N,N,N,N,64827,N,N,N,32317,N,N,N,N,N,N,N,N,N,N,64828,N,32319,N,N,N,N,N,
+64829,N,N,N,N,N,N,N,N,N,64830,N,N,N,N,N,N,N,N,N,N,N,N,N,64832,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,32320,N,N,N,N,64833,N,64834,32322,N,N,N,N,64835,64836,N,N,
+N,N,N,32323,64837,N,32324,64838,64839,N,32321,N,N,N,N,N,N,N,N,N,N,32325,N,N,N,
+N,N,32326,N,N,N,N,32327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32328,N,N,N,N,N,N,N,64840,
+32329,N,N,N,N,64841,N,N,N,N,64842,64845,N,N,N,N,N,64846,N,N,N,N,N,64847,N,N,
+32330,N,N,N,N,N,64848,N,N,N,N,N,N,32331,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,64851,
+N,N,N,N,N,N,N,32332,N,64852,N,N,64853,64854,N,N,64856,64855,N,N,N,64849,N,N,N,
+64860,32333,N,64858,N,N,32334,32335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64862,N,64863,64864,64865,N,N,64866,N,N,N,N,64867,32336,N,N,N,64868,N,64869,
+64870,N,N,N,N,N,N,64872,N,N,N,N,64873,64874,N,N,N,N,N,N,N,N,N,32337,N,N,N,
+64875,N,N,N,64878,64879,N,N,N,N,32338,32339,N,N,32340,64881,N,N,N,64882,N,N,
+64883,64876,64884,N,64885,N,N,N,32341,N,32342,N,N,N,64886,64887,64888,N,64889,
+64890,N,64891,N,64892,N,N,64893,N,32343,N,N,64894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65057,N,N,N,N,N,N,N,N,N,N,N,65058,65060,N,N,N,N,
+N,N,N,N,65059,N,N,N,N,N,65062,N,N,N,N,N,65063,65064,N,N,N,N,32344,32345,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65070,
+32346,N,N,N,32347,N,N,65071,N,N,N,N,N,N,N,32348,N,N,N,N,N,N,N,N,N,N,N,N,65072,
+N,N,65073,32349,N,N,N,N,N,65075,N,65076,N,N,N,N,32350,N,N,65078,N,N,65079,
+65080,N,N,N,N,32351,N,65081,N,N,N,N,N,65082,N,N,N,N,N,32352,N,N,65083,N,N,N,N,
+N,N,N,N,32353,N,N,65084,N,N,N,N,N,N,N,65085,N,N,N,N,N,N,N,N,N,N,32355,N,N,N,N,
+N,N,N,N,65087,N,N,N,65088,N,N,32356,65089,N,65086,32354,N,N,65090,N,N,N,65091,
+N,65092,N,N,N,N,N,N,N,N,N,N,N,N,65093,32357,N,N,65094,N,N,N,N,65095,65096,N,N,
+65097,N,N,N,32359,N,N,N,N,N,N,N,N,N,N,N,N,65098,65101,N,N,N,N,32360,N,N,65100,
+N,N,65102,N,N,N,N,N,N,N,32361,N,N,N,65103,N,N,65104,65105,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,65106,32362,N,N,N,65108,N,N,N,N,65109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,65110,N,N,32363,N,N,N,N,N,32364,N,N,N,65111,N,N,N,32365,N,N,32366,
+N,N,N,N,32367,32368,N,N,N,N,N,N,N,65113,N,N,N,N,N,32369,N,N,N,N,N,N,N,N,N,N,N,
+N,N,32370,N,N,N,N,N,N,N,N,N,N,N,N,N,65115,N,N,N,N,N,N,N,65116,N,N,N,N,N,N,
+65117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65118,65119,65121,N,N,N,N,N,N,N,N,N,N,N,
+N,32371,N,N,N,N,N,N,65122,N,65123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+65124,N,N,N,N,N,N,N,65125,N,32372,65126,N,N,65127,N,N,N,65128,N,N,N,65129,
+65130,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,65132,N,32373,65133,N,N,N,N,65135,N,N,N,
+N,N,N,N,N,N,N,N,65137,N,N,N,65139,N,N,65140,N,N,N,N,65141,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32374,N,N,N,32375,N,N,32376,N,N,N,N,N,N,N,N,N,
+N,32377,30267,N,N,N,N,N,N,N,N,N,N,29742,30030,N,N,N,N,N,N,N,N,N,N,N,N,31567,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32292,N,N,N,N,N,N,N,N,N,N,N,32093,12107,12119,20338,N,44665,30074,30554,30575,
+N,N,31036,31037,31041,N,N,N,31546,63288,63301,31790,N,63854,N,31850,N,N,N,N,N,
+N,N,N,N,11832,11849,11856,11875,11880,11886,12076,12079,12086,12122,12126,
+20321,20322,29776,29788,29790,29793,29992,29995,30019,30053,30313,30327,30501,
+30549,61481,30757,31015,31027,31028,31031,31032,31033,31035,31039,31040,31053,
+31057,31076,31278,62544,31283,31290,31300,31320,62836,62837,31527,31599,31609,
+31791,31792,31800,31805,63849,31833,32099,32118,32123,9022,9021,8752,N,N,N,N,
+8751,N,N,N,N,N,8753,
+};
+
+static const struct unim_index jisx0213_bmp_encmap[256] = {
+{__jisx0213_bmp_encmap+0,126,255},{__jisx0213_bmp_encmap+130,0,253},{
+__jisx0213_bmp_encmap+384,80,233},{__jisx0213_bmp_encmap+538,0,194},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+733,62,63
+},{__jisx0213_bmp_encmap+735,112,115},{__jisx0213_bmp_encmap+739,19,172},{
+__jisx0213_bmp_encmap+893,15,233},{__jisx0213_bmp_encmap+1112,5,219},{
+__jisx0213_bmp_encmap+1327,5,206},{__jisx0213_bmp_encmap+1529,35,254},{
+__jisx0213_bmp_encmap+1749,177,230},{__jisx0213_bmp_encmap+1803,0,110},{
+__jisx0213_bmp_encmap+1914,19,127},{0,0,0},{__jisx0213_bmp_encmap+2023,52,251
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+2223,
+22,255},{__jisx0213_bmp_encmap+2457,240,255},{__jisx0213_bmp_encmap+2473,49,
+250},{__jisx0213_bmp_encmap+2675,3,205},{__jisx0213_bmp_encmap+2878,2,219},{
+__jisx0213_bmp_encmap+3096,31,244},{__jisx0213_bmp_encmap+3310,5,207},{
+__jisx0213_bmp_encmap+3513,97,253},{__jisx0213_bmp_encmap+3670,0,250},{
+__jisx0213_bmp_encmap+3921,23,111},{__jisx0213_bmp_encmap+4010,110,234},{
+__jisx0213_bmp_encmap+4135,14,240},{__jisx0213_bmp_encmap+4362,15,210},{
+__jisx0213_bmp_encmap+4558,17,212},{__jisx0213_bmp_encmap+4754,5,148},{
+__jisx0213_bmp_encmap+4898,87,215},{__jisx0213_bmp_encmap+5027,57,147},{
+__jisx0213_bmp_encmap+5118,5,243},{__jisx0213_bmp_encmap+5357,7,221},{
+__jisx0213_bmp_encmap+5572,2,240},{__jisx0213_bmp_encmap+5811,8,212},{
+__jisx0213_bmp_encmap+6016,8,234},{__jisx0213_bmp_encmap+6243,15,175},{
+__jisx0213_bmp_encmap+6404,12,253},{__jisx0213_bmp_encmap+6646,22,181},{
+__jisx0213_bmp_encmap+6806,176,250},{__jisx0213_bmp_encmap+6881,4,188},{
+__jisx0213_bmp_encmap+7066,59,232},{__jisx0213_bmp_encmap+7240,23,209},{
+__jisx0213_bmp_encmap+7427,7,119},{__jisx0213_bmp_encmap+7540,2,255},{
+__jisx0213_bmp_encmap+7794,0,242},{__jisx0213_bmp_encmap+8037,0,243},{
+__jisx0213_bmp_encmap+8281,3,244},{__jisx0213_bmp_encmap+8523,1,251},{
+__jisx0213_bmp_encmap+8774,0,245},{__jisx0213_bmp_encmap+9020,18,255},{
+__jisx0213_bmp_encmap+9258,0,233},{__jisx0213_bmp_encmap+9492,7,247},{
+__jisx0213_bmp_encmap+9733,10,255},{__jisx0213_bmp_encmap+9979,4,244},{
+__jisx0213_bmp_encmap+10220,5,248},{__jisx0213_bmp_encmap+10464,12,245},{
+__jisx0213_bmp_encmap+10698,0,253},{__jisx0213_bmp_encmap+10952,3,244},{
+__jisx0213_bmp_encmap+11194,6,233},{__jisx0213_bmp_encmap+11422,0,253},{
+__jisx0213_bmp_encmap+11676,0,252},{__jisx0213_bmp_encmap+11929,13,248},{
+__jisx0213_bmp_encmap+12165,16,245},{__jisx0213_bmp_encmap+12395,21,253},{
+__jisx0213_bmp_encmap+12628,3,247},{__jisx0213_bmp_encmap+12873,9,255},{
+__jisx0213_bmp_encmap+13120,4,252},{__jisx0213_bmp_encmap+13369,0,251},{
+__jisx0213_bmp_encmap+13621,1,252},{__jisx0213_bmp_encmap+13873,1,252},{
+__jisx0213_bmp_encmap+14125,3,254},{__jisx0213_bmp_encmap+14377,15,253},{
+__jisx0213_bmp_encmap+14616,11,255},{__jisx0213_bmp_encmap+14861,2,251},{
+__jisx0213_bmp_encmap+15111,0,252},{__jisx0213_bmp_encmap+15364,23,251},{
+__jisx0213_bmp_encmap+15593,10,252},{__jisx0213_bmp_encmap+15836,0,236},{
+__jisx0213_bmp_encmap+16073,3,254},{__jisx0213_bmp_encmap+16325,0,251},{
+__jisx0213_bmp_encmap+16577,7,250},{__jisx0213_bmp_encmap+16821,1,255},{
+__jisx0213_bmp_encmap+17076,1,249},{__jisx0213_bmp_encmap+17325,0,252},{
+__jisx0213_bmp_encmap+17578,10,251},{__jisx0213_bmp_encmap+17820,5,254},{
+__jisx0213_bmp_encmap+18070,0,237},{__jisx0213_bmp_encmap+18308,3,253},{
+__jisx0213_bmp_encmap+18559,7,240},{__jisx0213_bmp_encmap+18793,1,245},{
+__jisx0213_bmp_encmap+19038,3,249},{__jisx0213_bmp_encmap+19285,8,154},{
+__jisx0213_bmp_encmap+19432,59,250},{__jisx0213_bmp_encmap+19624,2,251},{
+__jisx0213_bmp_encmap+19874,13,255},{__jisx0213_bmp_encmap+20117,4,254},{
+__jisx0213_bmp_encmap+20368,0,249},{__jisx0213_bmp_encmap+20618,1,253},{
+__jisx0213_bmp_encmap+20871,12,255},{__jisx0213_bmp_encmap+21115,0,253},{
+__jisx0213_bmp_encmap+21369,5,245},{__jisx0213_bmp_encmap+21610,1,245},{
+__jisx0213_bmp_encmap+21855,1,255},{__jisx0213_bmp_encmap+22110,17,252},{
+__jisx0213_bmp_encmap+22346,5,158},{__jisx0213_bmp_encmap+22500,57,254},{
+__jisx0213_bmp_encmap+22698,9,253},{__jisx0213_bmp_encmap+22943,6,250},{
+__jisx0213_bmp_encmap+23188,0,251},{__jisx0213_bmp_encmap+23440,2,255},{
+__jisx0213_bmp_encmap+23694,0,251},{__jisx0213_bmp_encmap+23946,1,255},{
+__jisx0213_bmp_encmap+24201,2,253},{__jisx0213_bmp_encmap+24453,4,114},{
+__jisx0213_bmp_encmap+24564,120,222},{__jisx0213_bmp_encmap+24667,29,239},{
+__jisx0213_bmp_encmap+24878,20,244},{__jisx0213_bmp_encmap+25103,4,243},{
+__jisx0213_bmp_encmap+25343,8,252},{__jisx0213_bmp_encmap+25588,2,249},{
+__jisx0213_bmp_encmap+25836,2,253},{__jisx0213_bmp_encmap+26088,0,242},{
+__jisx0213_bmp_encmap+26331,2,244},{__jisx0213_bmp_encmap+26574,2,255},{
+__jisx0213_bmp_encmap+26828,2,162},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+26989
+,29,220},{__jisx0213_bmp_encmap+27181,15,106},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_bmp_encmap+27273,69,70},{__jisx0213_bmp_encmap+27275,2,13},
+};
+
+static const ucs2_t __jisx0213_1_emp_decmap[340] = {
+11,4669,U,U,U,U,U,U,U,U,U,4891,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5230,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,6333,2975,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,5812,U,U,U,U,U,U,U,U,U,U,7732,12740,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+13764,14143,U,U,U,U,U,U,U,U,14179,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15614,18417,21646,21774,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22385,U,U,U,U,U,U,U,U,U,U,U,
+U,22980,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23969,27391,28224,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28916,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30340,33399,U,U,U,U,U,U,U,33741,41360,
+};
+
+static const struct dbcs_index jisx0213_1_emp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_1_emp_decmap+0,34,34},{__jisx0213_1_emp_decmap+1,66,123},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__jisx0213_1_emp_decmap+59,84,110},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_emp_decmap+86,58,114},{
+__jisx0213_1_emp_decmap+143,41,96},{__jisx0213_1_emp_decmap+199,108,108},{
+__jisx0213_1_emp_decmap+200,126,126},{__jisx0213_1_emp_decmap+201,41,110},{
+__jisx0213_1_emp_decmap+271,93,93},{__jisx0213_1_emp_decmap+272,51,108},{
+__jisx0213_1_emp_decmap+330,73,81},{0,0,0},{__jisx0213_1_emp_decmap+339,102,
+102},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const ucs2_t __jisx0213_2_emp_decmap[2053] = {
+137,U,U,U,U,U,U,U,U,U,162,U,U,164,U,U,U,U,U,U,U,418,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,531,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,811,U,U,U,U,U,U,897,U,881,1017,U,U,1098,U,1289,U,U,U,U,U,U,U,U,U,
+1494,1576,U,U,U,U,U,1871,U,U,U,U,U,U,2055,U,2106,U,U,U,U,U,U,U,U,2233,U,U,U,U,
+U,U,U,2428,2461,U,U,U,U,U,2771,U,U,2845,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,3397,3553,U,U,U,U,U,U,3733,3693,U,U,U,U,U,U,U,3684,U,U,3935,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,4609,U,U,4693,U,4731,U,U,U,
+U,4724,U,U,U,U,U,U,4836,4823,U,U,U,U,U,U,4861,U,4918,4932,5060,U,U,U,U,U,U,U,
+U,U,U,U,U,5229,U,U,U,U,U,U,U,U,U,U,U,5591,U,U,U,U,U,27689,U,U,5703,U,U,U,U,U,
+U,U,U,U,U,U,U,U,5894,5954,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,6595,7254,U,U,U,U,U,U,7469,7493,U,7544,7522,U,U,U,
+7585,7580,U,U,U,U,7570,U,U,7607,U,7648,7731,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+7966,U,U,U,U,U,U,U,U,U,U,8054,U,U,U,U,U,8186,8571,U,U,U,U,U,U,U,U,8990,U,U,U,
+U,9133,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9971,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10331,U,U,U,U,U,U,U,10411,U,U,U,U,10639,
+10936,U,U,U,U,11087,11088,U,U,U,U,U,U,U,11078,U,11293,11174,U,U,U,11300,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,11745,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12739,12789,12726,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13170,U,13267,13266,U,U,U,U,13264,13284,
+13269,U,U,13274,U,13279,U,U,U,U,U,U,U,U,U,U,U,13386,13393,13387,U,U,U,13413,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13540,13658,13716,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13881,13895,U,13880,13882,U,U,U,U,U,U,U,U,U,U,
+14108,U,U,U,U,U,U,U,U,U,U,14092,U,U,U,U,U,U,U,14180,U,U,U,U,U,U,U,14335,14311,
+U,U,U,U,U,14372,U,U,U,U,14397,15000,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15487,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15616,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+15680,U,15866,15865,15827,16254,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16534,
+U,U,U,U,U,16643,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16838,U,U,16894,17340,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,17961,U,U,U,U,U,18085,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,18582,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19021,19286,U,19311,U,U,U,U,19478,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,19732,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19982,U,U,
+U,20023,U,U,U,U,20074,U,U,20107,U,U,U,U,U,U,U,U,U,U,U,20554,U,20565,U,U,20770,
+20905,U,20965,20941,U,U,U,21022,U,U,U,21068,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+21550,U,U,U,U,U,U,U,U,U,U,21721,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21927,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22441,22452,22996,U,U,U,U,U,U,U,
+U,U,U,23268,23267,U,23281,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23474,U,U,U,U,U,U,
+U,U,U,U,23627,23652,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24110,24150,24165,
+U,24162,U,U,U,24280,U,24258,24296,U,24355,U,U,24412,U,U,U,U,U,U,24544,24532,U,
+U,U,U,24588,24571,U,U,U,U,U,U,U,24599,U,U,U,U,24672,U,U,U,U,U,U,U,U,U,U,U,U,
+24813,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25200,U,25222,U,U,U,U,
+U,U,25420,U,U,15630,U,U,U,25602,26238,U,U,U,U,26288,U,U,U,U,U,U,U,U,U,U,U,
+26397,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26845,U,26858,U,26961,U,U,26991,U,27101,U,
+U,U,27166,U,U,U,U,U,U,27224,U,U,U,U,U,27276,U,U,27319,27763,U,U,U,U,U,U,U,U,U,
+27869,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28261,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,28564,U,U,U,U,U,U,U,U,28664,28662,28663,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,28941,U,U,28985,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29659,29658,U,U,U,U,U,29694,U,U,29712,U,U,U,U,
+29769,30229,30228,U,30257,U,U,U,U,U,U,U,30355,U,U,U,U,U,U,U,30478,U,30499,U,U,
+U,30546,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31109,U,U,U,U,U,U,U,U,U,U,U,U,
+31364,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31667,U,31678,31687,31928,U,U,U,U,
+U,U,U,U,U,32160,U,U,32272,U,U,U,U,U,U,32695,U,U,U,U,U,U,U,U,32906,U,U,U,U,U,
+32955,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33410,U,U,U,U,33523,U,U,U,U,U,U,U,33804,
+U,U,U,U,33877,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34155,U,U,U,34248,34249,U,U,U,U,U,U,
+U,U,U,U,34519,U,U,34554,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,35145,35142,U,U,U,U,U,U,35179,U,U,U,U,U,U,U,U,U,U,U,U,U,35207,35208,U,
+U,U,U,U,U,U,U,U,U,35258,35259,U,U,U,U,U,U,U,U,U,U,U,35358,35369,U,U,U,U,U,U,U,
+U,U,U,35441,35395,U,U,U,U,U,U,U,U,35481,35533,U,U,U,U,U,35556,35549,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,35777,35823,U,U,U,U,U,U,U,36112,U,U,36209,U,36347,36383,U,
+U,U,36406,U,U,U,36489,U,36587,U,36658,U,U,U,U,U,U,U,36856,37536,37553,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38032,U,U,U,U,U,U,U,U,U,38351,U,U,U,U,U,U,U,U,
+U,38527,U,U,U,U,U,U,U,U,U,38640,U,U,38681,U,U,U,38736,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,39110,39538,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,40411,40509,U,U,U,U,U,U,U,U,U,U,U,U,40469,U,40586,U,40521,U,
+U,U,U,U,U,U,U,U,40644,U,U,U,U,U,40681,U,U,40667,40910,U,U,U,41007,U,40986,U,U,
+U,U,U,U,41209,U,U,41090,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,8728,U,U,U,U,41868,U,42039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,42481,U,
+42498,U,42522,U,U,U,42674,
+};
+
+static const struct dbcs_index jisx0213_2_emp_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+0,33,121},{0,0,0},{
+__jisx0213_2_emp_decmap+89,34,119},{__jisx0213_2_emp_decmap+175,42,117},{
+__jisx0213_2_emp_decmap+251,37,126},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+
+341,48,108},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+402,34,114},{
+__jisx0213_2_emp_decmap+483,36,125},{__jisx0213_2_emp_decmap+573,35,120},{
+__jisx0213_2_emp_decmap+659,42,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+__jisx0213_2_emp_decmap+735,35,96},{__jisx0213_2_emp_decmap+797,50,100},{
+__jisx0213_2_emp_decmap+848,34,123},{__jisx0213_2_emp_decmap+938,46,122},{
+__jisx0213_2_emp_decmap+1015,33,118},{__jisx0213_2_emp_decmap+1101,50,125},{
+__jisx0213_2_emp_decmap+1177,34,121},{__jisx0213_2_emp_decmap+1265,53,115},{
+__jisx0213_2_emp_decmap+1328,68,126},{__jisx0213_2_emp_decmap+1387,33,115},{
+__jisx0213_2_emp_decmap+1470,41,122},{__jisx0213_2_emp_decmap+1552,37,126},{
+__jisx0213_2_emp_decmap+1642,33,126},{__jisx0213_2_emp_decmap+1736,33,113},{
+__jisx0213_2_emp_decmap+1817,34,118},{__jisx0213_2_emp_decmap+1902,44,112},{
+__jisx0213_2_emp_decmap+1971,37,118},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __jisx0213_emp_encmap[8787] = {
+11810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,41249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41259,N,41262,41270,41286,41328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,41337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41335,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41762,41765,41767,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,41777,41778,41784,41791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41793,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,41802,41810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,41811,41817,41820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20308,41847,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42026,42042,N,N,N,
+N,N,N,N,N,42034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,42033,42045,42073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+12098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42076,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42083,N,N,N,N,N,N,42078,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,42091,N,N,N,N,N,N,N,N,N,N,N,N,42090,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,42098,12108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,42100,N,N,N,N,N,N,N,N,N,N,N,N,N,42101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42277,42290,
+12128,42302,42311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+20323,42325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42326,12155,42366,43056,
+43063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43064,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,43066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43077,N,N,N,N,N,
+N,N,N,N,43072,N,N,N,N,43071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43080,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43082,43083,20334,43099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+43116,44066,65107,44075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44080,44112,44133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,44141,44146,44324,44338,N,N,N,N,N,N,N,N,44329,44330,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,44341,44340,N,N,N,N,N,N,44345,44374,44580,N,N,N,N,N,N,N,N,N,N,N,N,
+44413,30010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44579,44602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44610,
+N,44605,44604,N,44612,N,N,N,N,44615,N,N,N,N,44617,N,N,N,N,44611,44629,44631,N,
+N,N,N,N,44630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44635,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+44663,44664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44842,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30066,
+44866,44863,44867,N,N,N,N,N,N,N,N,N,N,N,N,44864,44889,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,44878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,30249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30258,44897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44906,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44905,44912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44917,
+60963,60980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30304,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,62581,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,61023,61022,61234,61255,61261,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61284,
+61474,61491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,61497,30572,61523,61563,61742,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,61744,61749,61764,61789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61793,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+61798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61801,
+61813,N,N,N,N,N,N,N,N,N,N,61815,61818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61985,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61988,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61987,61992,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61996,
+62013,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62024,31017,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62043,31047,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,62069,N,N,N,N,N,N,N,N,N,N,62070,31060,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+62258,62270,62269,N,N,N,N,N,N,N,N,N,N,N,N,62272,62290,62301,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62302,31086,62323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62324,N,N,N,N,N,N,N,N,N,N,N,
+62327,N,N,62325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62333,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62331,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62498,62500,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,62503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,62511,N,N,N,N,N,N,N,N,N,N,N,62510,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62517,62516,N,N,N,N,N,N,N,N,N,N,62525,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62530,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62543,62569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,62571,62578,62585,62773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62778,62790,62806,N,N,
+N,N,N,N,N,N,N,N,N,N,62808,62810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,62813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62815,62819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62826,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,62832,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,62835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,31325,42308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,63044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63054,
+31539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63069,63093,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63265,63266,63102,31561,
+63283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,63286,63333,63332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,63339,63342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63347,
+63530,63529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63532,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,31596,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63540,63548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,63550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63554,63574,63587,63607,N,N,N,N,N,N,N,N,N,N,
+63609,N,N,N,N,N,N,N,N,63610,63781,63791,63794,63801,63810,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63816,31817,N,N,N,N,N,N,N,N,N,N,63833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,63838,31825,63846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63851,63866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+63870,64033,64044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,64047,64080,N,N,64079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64101,64102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64113,64114,64126,N,N,N,N,N,N,N,N,N,N,64289,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64301,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64300,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64310,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64318,N,N,N,N,N,N,
+64317,64334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,64335,64343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64346,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64348,64349,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,64353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64359,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,64369,64546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64547,64568,64578,
+64588,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64598,64601,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,64630,64812,64843,64857,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64844,
+N,N,N,N,N,N,N,N,N,N,N,64861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,64880,N,N,N,N,N,N,N,N,N,N,N,N,N,64877,65061,65067,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,65065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65074,32358,65112,65114,65134,
+65136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65138,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65142,
+};
+
+static const struct unim_index jisx0213_emp_encmap[256] = {
+{__jisx0213_emp_encmap+0,11,164},{__jisx0213_emp_encmap+154,162,162},{
+__jisx0213_emp_encmap+155,19,19},{__jisx0213_emp_encmap+156,43,249},{
+__jisx0213_emp_encmap+363,74,74},{__jisx0213_emp_encmap+364,9,214},{
+__jisx0213_emp_encmap+570,40,40},{__jisx0213_emp_encmap+571,79,79},{
+__jisx0213_emp_encmap+572,7,185},{__jisx0213_emp_encmap+751,124,157},{
+__jisx0213_emp_encmap+785,211,211},{__jisx0213_emp_encmap+786,29,159},{0,0,0},
+{__jisx0213_emp_encmap+917,69,225},{__jisx0213_emp_encmap+1074,100,149},{
+__jisx0213_emp_encmap+1124,95,95},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+1125,
+1,253},{__jisx0213_emp_encmap+1378,27,196},{__jisx0213_emp_encmap+1548,109,110
+},{__jisx0213_emp_encmap+1550,215,215},{__jisx0213_emp_encmap+1551,71,180},{
+__jisx0213_emp_encmap+1661,6,66},{__jisx0213_emp_encmap+1722,189,189},{
+__jisx0213_emp_encmap+1723,195,195},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+
+1724,86,86},{__jisx0213_emp_encmap+1725,45,224},{__jisx0213_emp_encmap+1905,
+51,52},{__jisx0213_emp_encmap+1907,30,250},{0,0,0},{__jisx0213_emp_encmap+2128
+,123,123},{__jisx0213_emp_encmap+2129,24,24},{__jisx0213_emp_encmap+2130,30,
+173},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2274,243,243},{0,0,0},{
+__jisx0213_emp_encmap+2275,91,171},{__jisx0213_emp_encmap+2356,143,143},{
+__jisx0213_emp_encmap+2357,184,184},{__jisx0213_emp_encmap+2358,70,166},{
+__jisx0213_emp_encmap+2455,29,36},{__jisx0213_emp_encmap+2463,225,225},{0,0,0
+},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2464,182,245},{0,0,0},{
+__jisx0213_emp_encmap+2528,114,228},{__jisx0213_emp_encmap+2643,74,228},{
+__jisx0213_emp_encmap+2798,90,196},{__jisx0213_emp_encmap+2905,56,71},{
+__jisx0213_emp_encmap+2921,12,255},{__jisx0213_emp_encmap+3165,36,61},{0,0,0},
+{__jisx0213_emp_encmap+3191,152,152},{0,0,0},{__jisx0213_emp_encmap+3192,127,
+254},{__jisx0213_emp_encmap+3320,0,250},{0,0,0},{__jisx0213_emp_encmap+3571,
+126,126},{__jisx0213_emp_encmap+3572,150,150},{__jisx0213_emp_encmap+3573,3,
+254},{0,0,0},{__jisx0213_emp_encmap+3825,188,188},{0,0,0},{0,0,0},{
+__jisx0213_emp_encmap+3826,41,165},{__jisx0213_emp_encmap+3951,241,241},{
+__jisx0213_emp_encmap+3952,150,150},{0,0,0},{__jisx0213_emp_encmap+3953,77,77
+},{__jisx0213_emp_encmap+3954,86,111},{__jisx0213_emp_encmap+3980,22,22},{
+__jisx0213_emp_encmap+3981,20,20},{__jisx0213_emp_encmap+3982,14,139},{0,0,0},
+{__jisx0213_emp_encmap+4108,74,85},{__jisx0213_emp_encmap+4120,34,229},{
+__jisx0213_emp_encmap+4316,30,76},{0,0,0},{__jisx0213_emp_encmap+4363,46,217},
+{__jisx0213_emp_encmap+4535,14,167},{0,0,0},{__jisx0213_emp_encmap+4689,113,
+180},{0,0,0},{__jisx0213_emp_encmap+4757,196,212},{__jisx0213_emp_encmap+4774,
+227,241},{__jisx0213_emp_encmap+4789,178,178},{__jisx0213_emp_encmap+4790,75,
+100},{__jisx0213_emp_encmap+4816,161,161},{__jisx0213_emp_encmap+4817,46,232},
+{__jisx0213_emp_encmap+5004,35,251},{__jisx0213_emp_encmap+5221,12,237},{0,0,0
+},{__jisx0213_emp_encmap+5447,112,134},{__jisx0213_emp_encmap+5470,76,76},{
+__jisx0213_emp_encmap+5471,2,2},{0,0,0},{__jisx0213_emp_encmap+5472,126,176},{
+__jisx0213_emp_encmap+5523,29,29},{__jisx0213_emp_encmap+5524,221,234},{
+__jisx0213_emp_encmap+5538,81,221},{__jisx0213_emp_encmap+5679,30,255},{0,0,0
+},{__jisx0213_emp_encmap+5905,41,221},{0,0,0},{__jisx0213_emp_encmap+6086,64,
+101},{__jisx0213_emp_encmap+6124,148,248},{__jisx0213_emp_encmap+6225,244,244
+},{__jisx0213_emp_encmap+6226,13,57},{0,0,0},{__jisx0213_emp_encmap+6271,218,
+254},{__jisx0213_emp_encmap+6308,16,73},{0,0,0},{__jisx0213_emp_encmap+6366,
+20,147},{__jisx0213_emp_encmap+6494,14,82},{0,0,0},{__jisx0213_emp_encmap+6563
+,133,133},{__jisx0213_emp_encmap+6564,132,132},{__jisx0213_emp_encmap+6565,
+179,199},{__jisx0213_emp_encmap+6586,184,184},{__jisx0213_emp_encmap+6587,160,
+160},{__jisx0213_emp_encmap+6588,16,16},{__jisx0213_emp_encmap+6589,183,183},{
+__jisx0213_emp_encmap+6590,138,187},{0,0,0},{__jisx0213_emp_encmap+6640,119,
+243},{__jisx0213_emp_encmap+6765,205,205},{__jisx0213_emp_encmap+6766,12,85},{
+__jisx0213_emp_encmap+6840,107,201},{__jisx0213_emp_encmap+6935,215,250},{0,0,
+0},{0,0,0},{__jisx0213_emp_encmap+6971,70,187},{__jisx0213_emp_encmap+7089,30,
+228},{__jisx0213_emp_encmap+7288,193,239},{0,0,0},{__jisx0213_emp_encmap+7335,
+16,251},{__jisx0213_emp_encmap+7571,31,235},{__jisx0213_emp_encmap+7776,50,248
+},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+7975,160,177},{0,0,0},{
+__jisx0213_emp_encmap+7993,144,144},{__jisx0213_emp_encmap+7994,207,207},{
+__jisx0213_emp_encmap+7995,127,240},{__jisx0213_emp_encmap+8109,25,80},{
+__jisx0213_emp_encmap+8165,198,198},{0,0,0},{__jisx0213_emp_encmap+8166,114,
+114},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+8167,219,219},{
+__jisx0213_emp_encmap+8168,21,233},{__jisx0213_emp_encmap+8381,206,206},{
+__jisx0213_emp_encmap+8382,26,249},{__jisx0213_emp_encmap+8606,144,144},{0,0,0
+},{__jisx0213_emp_encmap+8607,140,140},{__jisx0213_emp_encmap+8608,55,55},{
+__jisx0213_emp_encmap+8609,241,241},{__jisx0213_emp_encmap+8610,2,178},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},
+};
+
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/mappings_kr.h b/sys/src/cmd/python/Modules/cjkcodecs/mappings_kr.h
new file mode 100644
index 000000000..7e6fdd270
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/mappings_kr.h
@@ -0,0 +1,3251 @@
+static const ucs2_t __ksx1001_decmap[8264] = {
+12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,
+8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,
+12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,
+65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,
+9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,
+8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,
+8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,
+729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,
+9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,
+9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,
+9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,
+65281,65282,65283,65284,65285,65286,65287,65288,65289,65290,65291,65292,65293,
+65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65306,
+65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317,65318,65319,
+65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,
+65333,65334,65335,65336,65337,65338,65339,65510,65341,65342,65343,65344,65345,
+65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,
+65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,
+65372,65373,65507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,
+12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,
+12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,
+12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,
+12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,
+12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,
+12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,
+12681,12682,12683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567,
+8568,8569,U,U,U,U,U,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,U,U,U,
+U,U,U,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,
+932,933,934,935,936,937,U,U,U,U,U,U,U,U,945,946,947,948,949,950,951,952,953,
+954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,9472,9474,9484,
+9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
+9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,
+9489,9498,9497,9494,9493,9486,9485,9502,9503,9505,9506,9510,9511,9513,9514,
+9517,9518,9521,9522,9525,9526,9529,9530,9533,9534,9536,9537,9539,9540,9541,
+9542,9543,9544,9545,9546,13205,13206,13207,8467,13208,13252,13219,13220,13221,
+13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13258,13197,
+13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,13235,13236,
+13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,13243,13244,
+13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,13194,13195,
+13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,13277,13264,
+13267,13251,13257,13276,13254,198,208,170,294,U,306,U,319,321,216,338,186,222,
+358,330,U,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,
+12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,
+12920,12921,12922,12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433,
+9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448,
+9449,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,
+9326,189,8531,8532,188,190,8539,8540,8541,8542,230,273,240,295,305,307,312,
+320,322,248,339,223,254,359,331,329,12800,12801,12802,12803,12804,12805,12806,
+12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819,
+12820,12821,12822,12823,12824,12825,12826,12827,9372,9373,9374,9375,9376,9377,
+9378,9379,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,
+9393,9394,9395,9396,9397,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,
+9342,9343,9344,9345,9346,185,178,179,8308,8319,8321,8322,8323,8324,12353,
+12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,
+12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,
+12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,
+12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,
+12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,
+12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,
+12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,
+12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,
+12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,
+12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,
+12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,
+12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,
+12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,1040,
+1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,
+1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,
+1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073,1074,1075,1076,1077,1105,
+1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,
+1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,44032,44033,44036,
+44039,44040,44041,44042,44048,44049,44050,44051,44052,44053,44054,44055,44057,
+44058,44059,44060,44061,44064,44068,44076,44077,44079,44080,44081,44088,44089,
+44092,44096,44107,44109,44116,44120,44124,44144,44145,44148,44151,44152,44154,
+44160,44161,44163,44164,44165,44166,44169,44170,44171,44172,44176,44180,44188,
+44189,44191,44192,44193,44200,44201,44202,44204,44207,44208,44216,44217,44219,
+44220,44221,44225,44228,44232,44236,44245,44247,44256,44257,44260,44263,44264,
+44266,44268,44271,44272,44273,44275,44277,44278,44284,44285,44288,44292,44294,
+44300,44301,44303,44305,44312,44316,44320,44329,44332,44333,44340,44341,44344,
+44348,44356,44357,44359,44361,44368,44372,44376,44385,44387,44396,44397,44400,
+44403,44404,44405,44406,44411,44412,44413,44415,44417,44418,44424,44425,44428,
+44432,44444,44445,44452,44471,44480,44481,44484,44488,44496,44497,44499,44508,
+44512,44516,44536,44537,44540,44543,44544,44545,44552,44553,44555,44557,44564,
+44592,44593,44596,44599,44600,44602,44608,44609,44611,44613,44614,44618,44620,
+44621,44622,44624,44628,44630,44636,44637,44639,44640,44641,44645,44648,44649,
+44652,44656,44664,44665,44667,44668,44669,44676,44677,44684,44732,44733,44734,
+44736,44740,44748,44749,44751,44752,44753,44760,44761,44764,44776,44779,44781,
+44788,44792,44796,44807,44808,44813,44816,44844,44845,44848,44850,44852,44860,
+44861,44863,44865,44866,44867,44872,44873,44880,44892,44893,44900,44901,44921,
+44928,44932,44936,44944,44945,44949,44956,44984,44985,44988,44992,44999,45000,
+45001,45003,45005,45006,45012,45020,45032,45033,45040,45041,45044,45048,45056,
+45057,45060,45068,45072,45076,45084,45085,45096,45124,45125,45128,45130,45132,
+45134,45139,45140,45141,45143,45145,45149,45180,45181,45184,45188,45196,45197,
+45199,45201,45208,45209,45210,45212,45215,45216,45217,45218,45224,45225,45227,
+45228,45229,45230,45231,45233,45235,45236,45237,45240,45244,45252,45253,45255,
+45256,45257,45264,45265,45268,45272,45280,45285,45320,45321,45323,45324,45328,
+45330,45331,45336,45337,45339,45340,45341,45347,45348,45349,45352,45356,45364,
+45365,45367,45368,45369,45376,45377,45380,45384,45392,45393,45396,45397,45400,
+45404,45408,45432,45433,45436,45440,45442,45448,45449,45451,45453,45458,45459,
+45460,45464,45468,45480,45516,45520,45524,45532,45533,45535,45544,45545,45548,
+45552,45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593,
+45600,45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701,
+45705,45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738,
+45740,45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794,
+45796,45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815,
+45816,45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844,
+45845,45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927,
+45929,45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964,
+45968,45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032,
+46036,46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108,
+46112,46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181,
+46188,46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280,
+46288,46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328,
+46356,46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385,
+46388,46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428,
+46429,46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515,
+46516,46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552,
+46572,46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749,
+46752,46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888,
+46889,46892,46895,46896,46904,46905,46907,46916,46920,46924,46932,46933,46944,
+46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,46988,46989,46991,
+46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,47017,47019,47020,
+47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,47100,47101,47103,
+47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,47133,47140,47141,
+47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,47187,47196,47197,
+47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,47280,47284,47288,
+47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,47336,47337,47340,
+47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,47424,47428,47436,
+47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,47476,47477,47480,
+47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,47536,47540,47548,
+47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,47570,47576,47577,
+47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,47605,47607,47608,
+47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,47682,47688,47689,
+47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,47719,47720,47721,
+47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,47785,47787,47788,
+47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,47868,47872,47876,
+47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,47926,47928,47931,
+47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,47956,47960,47969,
+47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,48064,48068,48072,
+48080,48083,48120,48121,48124,48127,48128,48130,48136,48137,48139,48140,48141,
+48143,48145,48148,48149,48150,48151,48152,48155,48156,48157,48158,48159,48164,
+48165,48167,48169,48173,48176,48177,48180,48184,48192,48193,48195,48196,48197,
+48201,48204,48205,48208,48221,48260,48261,48264,48267,48268,48270,48276,48277,
+48279,48281,48282,48288,48289,48292,48295,48296,48304,48305,48307,48308,48309,
+48316,48317,48320,48324,48333,48335,48336,48337,48341,48344,48348,48372,48373,
+48374,48376,48380,48388,48389,48391,48393,48400,48404,48420,48428,48448,48456,
+48457,48460,48464,48472,48473,48484,48488,48512,48513,48516,48519,48520,48521,
+48522,48528,48529,48531,48533,48537,48538,48540,48548,48560,48568,48596,48597,
+48600,48604,48617,48624,48628,48632,48640,48643,48645,48652,48653,48656,48660,
+48668,48669,48671,48708,48709,48712,48716,48718,48724,48725,48727,48729,48730,
+48731,48736,48737,48740,48744,48746,48752,48753,48755,48756,48757,48763,48764,
+48765,48768,48772,48780,48781,48783,48784,48785,48792,48793,48808,48848,48849,
+48852,48855,48856,48864,48867,48868,48869,48876,48897,48904,48905,48920,48921,
+48923,48924,48925,48960,48961,48964,48968,48976,48977,48981,49044,49072,49093,
+49100,49101,49104,49108,49116,49119,49121,49212,49233,49240,49244,49248,49256,
+49257,49296,49297,49300,49304,49312,49313,49315,49317,49324,49325,49327,49328,
+49331,49332,49333,49334,49340,49341,49343,49344,49345,49349,49352,49353,49356,
+49360,49368,49369,49371,49372,49373,49380,49381,49384,49388,49396,49397,49399,
+49401,49408,49412,49416,49424,49429,49436,49437,49438,49439,49440,49443,49444,
+49446,49447,49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480,
+49481,49483,49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513,
+49520,49524,49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567,
+49569,49573,49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624,
+49632,49636,49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679,
+49681,49688,49689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714,
+49716,49736,49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788,
+49789,49791,49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836,
+49837,49844,49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901,
+49903,49905,49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939,
+49940,49941,49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032,
+50034,50040,50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143,
+50144,50146,50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224,
+50228,50236,50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324,
+50332,50360,50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444,
+50448,50452,50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501,
+50504,50505,50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525,
+50526,50528,50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560,
+50564,50567,50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612,
+50613,50616,50617,50619,50620,50621,50622,50628,50629,50630,50631,50632,50633,
+50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,50668,50669,
+50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,50693,50694,
+50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,50732,50733,
+50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,50760,50768,
+50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,50809,50812,
+50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,50855,50857,
+50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,50893,50896,
+50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,50941,50948,
+50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,50992,50993,
+50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,51025,51026,
+51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,51061,51064,
+51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,51088,51089,
+51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,51116,51117,
+51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,51152,51160,
+51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,51219,51221,
+51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,51264,51272,
+51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,51331,51333,
+51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,51389,51396,
+51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,51453,51456,
+51460,51461,51462,51468,51469,51471,51473,51480,51500,51508,51536,51537,51540,
+51544,51552,51553,51555,51564,51568,51572,51580,51592,51593,51596,51600,51608,
+51609,51611,51613,51648,51649,51652,51655,51656,51658,51664,51665,51667,51669,
+51670,51673,51674,51676,51677,51680,51682,51684,51687,51692,51693,51695,51696,
+51697,51704,51705,51708,51712,51720,51721,51723,51724,51725,51732,51736,51753,
+51788,51789,51792,51796,51804,51805,51807,51808,51809,51816,51837,51844,51864,
+51900,51901,51904,51908,51916,51917,51919,51921,51923,51928,51929,51936,51948,
+51956,51976,51984,51988,51992,52000,52001,52033,52040,52041,52044,52048,52056,
+52057,52061,52068,52088,52089,52124,52152,52180,52196,52199,52201,52236,52237,
+52240,52244,52252,52253,52257,52258,52263,52264,52265,52268,52270,52272,52280,
+52281,52283,52284,52285,52286,52292,52293,52296,52300,52308,52309,52311,52312,
+52313,52320,52324,52326,52328,52336,52341,52376,52377,52380,52384,52392,52393,
+52395,52396,52397,52404,52405,52408,52412,52420,52421,52423,52425,52432,52436,
+52452,52460,52464,52481,52488,52489,52492,52496,52504,52505,52507,52509,52516,
+52520,52524,52537,52572,52576,52580,52588,52589,52591,52593,52600,52616,52628,
+52629,52632,52636,52644,52645,52647,52649,52656,52676,52684,52688,52712,52716,
+52720,52728,52729,52731,52733,52740,52744,52748,52756,52761,52768,52769,52772,
+52776,52784,52785,52787,52789,52824,52825,52828,52831,52832,52833,52840,52841,
+52843,52845,52852,52853,52856,52860,52868,52869,52871,52873,52880,52881,52884,
+52888,52896,52897,52899,52900,52901,52908,52909,52929,52964,52965,52968,52971,
+52972,52980,52981,52983,52984,52985,52992,52993,52996,53000,53008,53009,53011,
+53013,53020,53024,53028,53036,53037,53039,53040,53041,53048,53076,53077,53080,
+53084,53092,53093,53095,53097,53104,53105,53108,53112,53120,53125,53132,53153,
+53160,53168,53188,53216,53217,53220,53224,53232,53233,53235,53237,53244,53248,
+53252,53265,53272,53293,53300,53301,53304,53308,53316,53317,53319,53321,53328,
+53332,53336,53344,53356,53357,53360,53364,53372,53373,53377,53412,53413,53416,
+53420,53428,53429,53431,53433,53440,53441,53444,53448,53449,53456,53457,53459,
+53460,53461,53468,53469,53472,53476,53484,53485,53487,53488,53489,53496,53517,
+53552,53553,53556,53560,53562,53568,53569,53571,53572,53573,53580,53581,53584,
+53588,53596,53597,53599,53601,53608,53612,53628,53636,53640,53664,53665,53668,
+53672,53680,53681,53683,53685,53690,53692,53696,53720,53748,53752,53767,53769,
+53776,53804,53805,53808,53812,53820,53821,53823,53825,53832,53852,53860,53888,
+53889,53892,53896,53904,53905,53909,53916,53920,53924,53932,53937,53944,53945,
+53948,53951,53952,53954,53960,53961,53963,53972,53976,53980,53988,53989,54000,
+54001,54004,54008,54016,54017,54019,54021,54028,54029,54030,54032,54036,54038,
+54044,54045,54047,54048,54049,54053,54056,54057,54060,54064,54072,54073,54075,
+54076,54077,54084,54085,54140,54141,54144,54148,54156,54157,54159,54160,54161,
+54168,54169,54172,54176,54184,54185,54187,54189,54196,54200,54204,54212,54213,
+54216,54217,54224,54232,54241,54243,54252,54253,54256,54260,54268,54269,54271,
+54273,54280,54301,54336,54340,54364,54368,54372,54381,54383,54392,54393,54396,
+54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,54492,
+54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,54551,
+54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,54629,
+54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,54665,
+54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,54757,
+54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,54803,
+54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,54857,
+54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,54915,
+54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,54971,
+54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,55029,
+55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,55085,
+55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,55128,
+55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,55176,
+55177,55180,55184,55192,55193,55195,55197,20285,20339,20551,20729,21152,21487,
+21621,21733,22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292,
+33499,33540,34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508,
+24682,24932,27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014,
+24178,24185,25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487,
+31777,32925,33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883,
+35088,34638,38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204,
+28187,29976,30131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002,
+32987,37440,38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743,
+30074,30086,31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477,
+40007,20171,20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117,
+30342,30422,31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923,
+32697,37301,20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067,
+36317,36382,63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967,
+33137,34388,36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298,
+30652,37392,40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608,
+33160,35233,38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963,
+40273,25225,27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772,
+20140,20435,20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950,
+25004,25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898,
+30169,30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629,
+36885,37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760,
+25106,26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336,
+35489,35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235,
+25335,25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660,
+32771,32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678,
+38599,39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372,
+23825,26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844,
+20849,21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002,
+38799,20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707,
+38982,24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748,
+29743,29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866,
+20362,20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979,
+21350,25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439,
+32024,32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657,
+27211,29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171,
+39509,39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646,
+22036,22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472,
+27590,27628,27714,28317,28792,29399,29590,29699,30655,30697,31350,32127,32777,
+33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,37476,37558,39378,
+39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,21531,31384,32676,
+35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,31406,33422,36524,
+20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,21413,29527,34152,
+36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,27512,36020,39740,
+63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,31998,33909,35215,
+36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,27224,20811,21067,
+21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,26681,27135,29822,
+31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,25810,26129,27278,
+29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,21450,24613,25201,
+27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,20864,21980,22120,
+22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,24190,24524,25216,
+26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,27773,27778,28103,
+29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,31047,31048,31098,
+31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,36215,37665,37668,
+39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,26708,37329,21931,
+20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,63760,63761,63762,
+63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,63771,63772,26262,
+63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,26511,26976,28275,
+63778,30007,63779,63780,63781,32013,63782,63783,34930,22218,23064,63784,63785,
+63786,63787,63788,20035,63789,20839,22856,26608,32784,63790,22899,24180,25754,
+31178,24565,24684,25288,25467,23527,23511,21162,63791,22900,24361,24594,63792,
+63793,63794,29785,63795,63796,63797,63798,63799,63800,39377,63801,63802,63803,
+63804,63805,63806,63807,63808,63809,63810,63811,28611,63812,63813,33215,36786,
+24817,63814,63815,33126,63816,63817,23615,63818,63819,63820,63821,63822,63823,
+63824,63825,23273,35365,26491,32016,63826,63827,63828,63829,63830,63831,33021,
+63832,63833,23612,27877,21311,28346,22810,33590,20025,20150,20294,21934,22296,
+22727,24406,26039,26086,27264,27573,28237,30701,31471,31774,32222,34507,34962,
+37170,37723,25787,28606,29562,30136,36948,21846,22349,25018,25812,26311,28129,
+28251,28525,28601,30192,32835,33213,34113,35203,35527,35674,37663,27795,30035,
+31572,36367,36957,21776,22530,22616,24162,25095,25758,26848,30070,31958,34739,
+40680,20195,22408,22382,22823,23565,23729,24118,24453,25140,25825,29619,33274,
+34955,36024,38538,40667,23429,24503,24755,20498,20992,21040,22294,22581,22615,
+23566,23648,23798,23947,24230,24466,24764,25361,25481,25623,26691,26873,27330,
+28120,28193,28372,28644,29182,30428,30585,31153,31291,33796,35241,36077,36339,
+36424,36867,36884,36947,37117,37709,38518,38876,27602,28678,29272,29346,29544,
+30563,31167,31716,32411,35712,22697,24775,25958,26109,26302,27788,28958,29129,
+35930,38931,20077,31361,20189,20908,20941,21205,21516,24999,26481,26704,26847,
+27934,28540,30140,30643,31461,33012,33891,37509,20828,26007,26460,26515,30168,
+31431,33651,63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471,
+23965,27225,29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313,
+32645,34367,34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226,
+39409,63838,20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888,
+25829,25900,27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266,
+26391,28010,29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504,
+30053,20142,20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635,
+37327,20406,20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268,
+34851,38317,39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722,
+24976,25088,25891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925,
+21015,21155,27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278,
+22265,63839,23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646,
+38728,38936,40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347,
+28510,28696,29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565,
+30860,31103,32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903,
+31840,32894,20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534,
+24278,26009,29134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650,
+27155,28122,28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611,
+27060,27969,28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134,
+38520,20374,20523,23833,28138,32184,36650,24459,24900,26647,63841,38534,21202,
+32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,21519,21774,
+23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,31852,32633,
+32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,29848,34298,
+36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,31520,31890,
+25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,33180,33707,
+37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,28459,28771,
+30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,33545,35178,
+38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,36638,37017,
+22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,36067,36993,
+39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,33804,20906,
+35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,40629,28357,
+34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,33986,34719,
+37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,25721,26286,
+26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,33541,35584,
+35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,22818,26406,
+33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,33495,37672,
+21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,28961,29687,
+30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,20497,21006,
+21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,27797,29289,
+21619,23194,23614,23883,24396,24494,26410,26806,26979,28220,28228,30473,31859,
+32654,34183,35598,36855,38753,40692,23735,24758,24845,25003,25935,26107,26108,
+27665,27887,29599,29641,32225,38292,23494,34588,35600,21085,21338,25293,25615,
+25778,26420,27192,27850,29632,29854,31636,31893,32283,33162,33334,34180,36843,
+38649,39361,20276,21322,21453,21467,25292,25644,25856,26001,27075,27886,28504,
+29677,30036,30242,30436,30460,30928,30971,31020,32070,33324,34784,36820,38930,
+39151,21187,25300,25765,28196,28497,30332,36299,37297,37474,39662,39747,20515,
+20621,22346,22952,23592,24135,24439,25151,25918,26041,26049,26121,26507,27036,
+28354,30917,32033,32938,33152,33323,33459,33953,34444,35370,35607,37030,38450,
+40848,20493,20467,63843,22521,24472,25308,25490,26479,28227,28953,30403,32972,
+32986,35060,35061,35097,36064,36649,37197,38506,20271,20336,24091,26575,26658,
+30333,30334,39748,24161,27146,29033,29140,30058,63844,32321,34115,34281,39132,
+20240,31567,32624,38309,20961,24070,26805,27710,27726,27867,29359,31684,33539,
+27861,29754,20731,21128,22721,25816,27287,29863,30294,30887,34327,38370,38713,
+63845,21342,24321,35722,36776,36783,37002,21029,30629,40009,40712,19993,20482,
+20853,23643,24183,26142,26170,26564,26821,28851,29953,30149,31177,31453,36647,
+39200,39432,20445,22561,22577,23542,26222,27493,27921,28282,28541,29668,29995,
+33769,35036,35091,35676,36628,20239,20693,21264,21340,23443,24489,26381,31119,
+33145,33583,34068,35079,35206,36665,36667,39333,39954,26412,20086,20472,22857,
+23553,23791,23792,25447,26834,28925,29090,29739,32299,34028,34562,36898,37586,
+40179,19981,20184,20463,20613,21078,21103,21542,21648,22496,22827,23142,23386,
+23413,23500,24220,63846,25206,25975,26023,28014,28325,29238,31526,31807,32566,
+33104,33105,33178,33344,33433,33705,35331,36000,36070,36091,36212,36282,37096,
+37340,38428,38468,39385,40167,21271,20998,21545,22132,22707,22868,22894,24575,
+24996,25198,26128,27774,28954,30406,31881,31966,32027,33452,36033,38640,63847,
+20315,24343,24447,25282,23849,26379,26842,30844,32323,40300,19989,20633,21269,
+21290,21329,22915,23138,24199,24754,24970,25161,25209,26000,26503,27047,27604,
+27606,27607,27608,27832,63848,29749,30202,30738,30865,31189,31192,31875,32203,
+32737,32933,33086,33218,33778,34586,35048,35513,35692,36027,37145,38750,39131,
+40763,22188,23338,24428,25996,27315,27567,27996,28657,28693,29277,29613,36007,
+36051,38971,24977,27703,32856,39425,20045,20107,20123,20181,20282,20284,20351,
+20447,20735,21490,21496,21766,21987,22235,22763,22882,23057,23531,23546,23556,
+24051,24107,24473,24605,25448,26012,26031,26614,26619,26797,27515,27801,27863,
+28195,28681,29509,30722,31038,31040,31072,31169,31721,32023,32114,32902,33293,
+33678,34001,34503,35039,35408,35422,35613,36060,36198,36781,37034,39164,39391,
+40605,21066,63849,26388,63850,20632,21034,23665,25955,27733,29642,29987,30109,
+31639,33948,37240,38704,20087,25746,27578,29022,34217,19977,63851,26441,26862,
+28183,33439,34072,34923,25591,28545,37394,39087,19978,20663,20687,20767,21830,
+21930,22039,23360,23577,23776,24120,24202,24224,24258,24819,26705,27233,28248,
+29245,29248,29376,30456,31077,31665,32724,35059,35316,35443,35937,36062,38684,
+22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,31513,
+22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,26360,
+26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,35475,
+36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,28101,
+28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,25159,
+25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,32680,
+33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,21352,
+23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,21089,
+26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,22995,
+23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,32882,
+33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,21484,
+22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,28040,
+28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,32057,
+34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,26463,
+28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,29575,
+23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,37782,
+34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,24101,
+24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,29159,
+29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,32353,
+32670,33065,33585,33936,34010,34282,34966,35504,35728,36664,36930,36995,37228,
+37526,37561,38539,38567,38568,38614,38656,38920,39318,39635,39706,21460,22654,
+22809,23408,23487,28113,28506,29087,29729,29881,32901,33789,24033,24455,24490,
+24642,26092,26642,26991,27219,27529,27957,28147,29667,30462,30636,31565,32020,
+33059,33308,33600,34036,34147,35426,35524,37255,37662,38918,39348,25100,34899,
+36848,37477,23815,23847,23913,29791,33181,34664,28629,25342,32722,35126,35186,
+19998,20056,20711,21213,21319,25215,26119,32361,34821,38494,20365,21273,22070,
+22987,23204,23608,23630,23629,24066,24337,24643,26045,26159,26178,26558,26612,
+29468,30690,31034,32709,33940,33997,35222,35430,35433,35553,35925,35962,22516,
+23508,24335,24687,25325,26893,27542,28252,29060,31698,34645,35672,36606,39135,
+39166,20280,20353,20449,21627,23072,23480,24892,26032,26216,29180,30003,31070,
+32051,33102,33251,33688,34218,34254,34563,35338,36523,36763,63857,36805,22833,
+23460,23526,24713,23529,23563,24515,27777,63858,28145,28683,29978,33455,35574,
+20160,21313,63859,38617,27663,20126,20420,20818,21854,23077,23784,25105,29273,
+33469,33706,34558,34905,35357,38463,38597,39187,40201,40285,22538,23731,23997,
+24132,24801,24853,25569,27138,28197,37122,37716,38990,39952,40823,23433,23736,
+25353,26191,26696,30524,38593,38797,38996,39839,26017,35585,36555,38332,21813,
+23721,24022,24245,26263,30284,33780,38343,22739,25276,29390,40232,20208,22830,
+24591,26171,27523,31207,40230,21395,21696,22467,23830,24859,26326,28079,30861,
+33406,38552,38724,21380,25212,25494,28082,32266,33099,38989,27387,32588,40367,
+40474,20063,20539,20918,22812,24825,25590,26928,29242,32822,63860,37326,24369,
+63861,63862,32004,33509,33903,33979,34277,36493,63863,20335,63864,63865,22756,
+23363,24665,25562,25880,25965,26264,63866,26954,27171,27915,28673,29036,30162,
+30221,31155,31344,63867,32650,63868,35140,63869,35731,37312,38525,63870,39178,
+22276,24481,26044,28417,30208,31142,35486,39341,39770,40812,20740,25014,25233,
+27277,33222,20547,22576,24422,28937,35328,35578,23420,34326,20474,20796,22196,
+22852,25513,28153,23978,26989,20870,20104,20313,63871,63872,63873,22914,63874,
+63875,27487,27741,63876,29877,30998,63877,33287,33349,33593,36671,36701,63878,
+39192,63879,63880,63881,20134,63882,22495,24441,26131,63883,63884,30123,32377,
+35695,63885,36870,39515,22181,22567,23032,23071,23476,63886,24310,63887,63888,
+25424,25403,63889,26941,27783,27839,28046,28051,28149,28436,63890,28895,28982,
+29017,63891,29123,29141,63892,30799,30831,63893,31605,32227,63894,32303,63895,
+34893,36575,63896,63897,63898,37467,63899,40182,63900,63901,63902,24709,28037,
+63903,29105,63904,63905,38321,21421,63906,63907,63908,26579,63909,28814,28976,
+29744,33398,33490,63910,38331,39653,40573,26308,63911,29121,33865,63912,63913,
+22603,63914,63915,23992,24433,63916,26144,26254,27001,27054,27704,27891,28214,
+28481,28634,28699,28719,29008,29151,29552,63917,29787,63918,29908,30408,31310,
+32403,63919,63920,33521,35424,36814,63921,37704,63922,38681,63923,63924,20034,
+20522,63925,21000,21473,26355,27757,28618,29450,30591,31330,33454,34269,34306,
+63926,35028,35427,35709,35947,63927,37555,63928,38675,38928,20116,20237,20425,
+20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034,
+25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986,
+40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800,
+22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402,
+33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740,
+30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505,
+27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931,
+20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747,
+25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350,
+32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020,
+32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029,
+28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854,
+63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962,
+26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398,
+36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020,
+31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939,
+38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290,
+22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503,
+29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301,
+20553,20702,21361,22285,22996,23041,23561,24944,26256,28205,29234,29771,32239,
+32963,33806,33894,34111,34655,34907,35096,35586,36949,38859,39759,20083,20369,
+20754,20842,63943,21807,21929,23418,23461,24188,24189,24254,24736,24799,24840,
+24841,25540,25912,26377,63944,26580,26586,63945,26977,26978,27833,27943,63946,
+28216,63947,28641,29494,29495,63948,29788,30001,63949,30290,63950,63951,32173,
+33278,33848,35029,35480,35547,35565,36400,36418,36938,36926,36986,37193,37321,
+37742,63952,63953,22537,63954,27603,32905,32946,63955,63956,20801,22891,23609,
+63957,63958,28516,29607,32996,36103,63959,37399,38287,63960,63961,63962,63963,
+32895,25102,28700,32104,34701,63964,22432,24681,24903,27575,35518,37504,38577,
+20057,21535,28139,34093,38512,38899,39150,25558,27875,37009,20957,25033,33210,
+40441,20381,20506,20736,23452,24847,25087,25836,26885,27589,30097,30691,32681,
+33380,34191,34811,34915,35516,35696,37291,20108,20197,20234,63965,63966,22839,
+23016,63967,24050,24347,24411,24609,63968,63969,63970,63971,29246,29669,63972,
+30064,30157,63973,31227,63974,32780,32819,32900,33505,33617,63975,63976,36029,
+36019,36999,63977,63978,39156,39180,63979,63980,28727,30410,32714,32716,32764,
+35610,20154,20161,20995,21360,63981,21693,22240,23035,23493,24341,24525,28270,
+63982,63983,32106,33589,63984,34451,35469,63985,38765,38775,63986,63987,19968,
+20314,20350,22777,26085,28322,36920,37808,39353,20219,22764,22922,23001,24641,
+63988,63989,31252,63990,33615,36035,20837,21316,63991,63992,63993,20173,21097,
+23381,33471,20180,21050,21672,22985,23039,23376,23383,23388,24675,24904,28363,
+28825,29038,29574,29943,30133,30913,32043,32773,33258,33576,34071,34249,35566,
+36039,38604,20316,21242,22204,26027,26152,28796,28856,29237,32189,33421,37196,
+38592,40306,23409,26855,27544,28538,30430,23697,26283,28507,31668,31786,34870,
+38620,19976,20183,21280,22580,22715,22767,22892,23559,24115,24196,24373,25484,
+26290,26454,27167,27299,27404,28479,29254,63994,29520,29835,31456,31911,33144,
+33247,33255,33674,33900,34083,34196,34255,35037,36115,37292,38263,38556,20877,
+21705,22312,23472,25165,26448,26685,26771,28221,28371,28797,32289,35009,36001,
+36617,40779,40782,29229,31631,35533,37658,20295,20302,20786,21632,22992,24213,
+25269,26485,26990,27159,27822,28186,29401,29482,30141,31672,32053,33511,33785,
+33879,34295,35419,36015,36487,36889,37048,38606,40799,21219,21514,23265,23490,
+25688,25973,28404,29380,63995,30340,31309,31515,31821,32318,32735,33659,35627,
+36042,36196,36321,36447,36842,36857,36969,37841,20291,20346,20659,20840,20856,
+21069,21098,22625,22652,22880,23560,23637,24283,24731,25136,26643,27583,27656,
+28593,29006,29728,30000,30008,30033,30322,31564,31627,31661,31686,32399,35438,
+36670,36681,37439,37523,37666,37931,38651,39002,39019,39198,20999,25130,25240,
+27993,30308,31434,31680,32118,21344,23742,24215,28472,28857,31896,38673,39822,
+40670,25509,25722,34678,19969,20117,20141,20572,20597,21576,22979,23450,24128,
+24237,24311,24449,24773,25402,25919,25972,26060,26230,26232,26622,26984,27273,
+27491,27712,28096,28136,28191,28254,28702,28833,29582,29693,30010,30555,30855,
+31118,31243,31357,31934,32142,33351,35330,35562,35998,37165,37194,37336,37478,
+37580,37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351,
+24716,25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500,
+38555,38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805,
+26089,26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226,
+29866,30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299,
+34468,35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751,
+36275,37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837,
+28121,29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352,
+24038,24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014,
+22863,23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855,
+29664,30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659,
+36913,37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803,
+26201,27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423,
+33537,20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366,
+25327,28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336,
+24535,25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460,
+30693,30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996,
+36100,36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634,
+26185,26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433,
+30494,30603,31206,32265,32285,33275,34095,34967,35386,36049,36587,36784,36914,
+37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,29894,30142,31209,
+31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,28503,32221,36655,
+37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,23919,24046,27425,
+27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,31364,37679,38015,
+40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,32408,35738,36106,
+38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,22649,24920,24921,
+25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,24288,24432,24884,
+25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,33081,33369,33750,
+33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,34081,37319,37365,
+20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,21076,23610,24957,
+25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,20191,21315,21912,
+22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,36368,36983,37351,
+38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,36639,36685,37941,
+20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,22558,22974,24086,
+25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,32893,33729,35531,
+38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,36958,39636,21021,
+21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,28966,30813,30977,
+30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,37218,37259,37294,
+20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,21474,22618,23541,
+24740,24961,25696,32317,32880,34085,37507,25774,20652,23828,26368,22684,25277,
+25512,26894,27000,27166,28267,30394,31179,33467,33833,35535,36264,36861,37138,
+37195,37276,37648,37656,37786,38619,39478,39949,19985,30044,31069,31482,31569,
+31689,32302,33988,36441,36468,36600,36880,26149,26943,29763,20986,26414,40668,
+20805,24544,27798,34802,34909,34935,24756,33205,33795,36101,21462,21561,22068,
+23094,23601,28810,32736,32858,33030,33261,36259,37257,39519,40434,20596,20164,
+21408,24827,28204,23652,20360,20516,21988,23769,24159,24677,26772,27835,28100,
+29118,30164,30196,30305,31258,31305,32199,32251,32622,33268,34473,36636,38601,
+39347,40786,21063,21189,39149,35242,19971,26578,28422,20405,23522,26517,27784,
+28024,29723,30759,37341,37756,34756,31204,31281,24555,20182,21668,21822,22702,
+22949,24816,25171,25302,26422,26965,33333,38464,39345,39389,20524,21331,21828,
+22396,64001,25176,64002,25826,26219,26589,28609,28655,29730,29752,35351,37944,
+21585,22022,22374,24392,24986,27470,28760,28845,32187,35477,22890,33067,25506,
+30472,32829,36010,22612,25645,27067,23445,24081,28271,64003,34153,20812,21488,
+22826,24608,24907,27526,27760,27888,31518,32974,33492,36294,37040,39089,64004,
+25799,28580,25745,25860,20814,21520,22303,35342,24927,26742,64005,30171,31570,
+32113,36890,22534,27084,33151,35114,36864,38969,20600,22871,22956,25237,36879,
+39722,24925,29305,38358,22369,23110,24052,25226,25773,25850,26487,27874,27966,
+29228,29750,30772,32631,33453,36315,38935,21028,22338,26495,29256,29923,36009,
+36774,37393,38442,20843,21485,25420,20329,21764,24726,25943,27803,28031,29260,
+29437,31255,35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255,
+31687,32232,32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536,
+23318,24163,24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263,
+21638,21754,22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770,
+32990,33071,33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292,
+26333,28689,29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080,
+34920,35961,39111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444,
+25259,30130,30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091,
+31558,33534,39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781,
+33655,34662,36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680,
+24717,26097,27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106,
+36676,20989,21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569,
+21512,21704,30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658,
+25239,26477,26689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565,
+21683,22419,22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559,
+36994,39405,39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190,
+29670,37141,38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563,
+36562,27463,38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203,
+27883,28843,29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010,
+36066,37449,39023,23377,31348,34880,38913,23244,20448,21332,22846,23805,25406,
+28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,24418,27842,
+28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,37026,37795,
+39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,20114,21628,
+22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,28111,28246,
+28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,31946,32286,
+32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,39013,24785,
+25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,21700,24344,
+27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,27194,28779,
+30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,25899,30906,
+30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,26707,28185,
+29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,20976,24140,
+24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,28514,29004,
+29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,24315,24458,
+24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,33214,33588,
+34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,25928,25989,
+26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,21518,21564,
+21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,22734,28932,
+29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,21913,27585,
+24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,30054,34407,
+24676,35662,40440,20807,20982,21256,27958,33016,40657,26133,27427,28824,30165,
+21507,23673,32007,35350,27424,27453,27462,21560,24688,27965,32725,33288,20694,
+20958,21916,22123,22221,23020,23305,24076,24985,24984,25137,26206,26342,29081,
+29113,29114,29351,31143,31232,32690,35440,
+};
+
+static const struct dbcs_index ksx1001_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+0,33,126},{__ksx1001_decmap+
+94,33,103},{__ksx1001_decmap+165,33,126},{__ksx1001_decmap+259,33,126},{
+__ksx1001_decmap+353,33,120},{__ksx1001_decmap+441,33,100},{__ksx1001_decmap+
+509,33,111},{__ksx1001_decmap+588,33,126},{__ksx1001_decmap+682,33,126},{
+__ksx1001_decmap+776,33,115},{__ksx1001_decmap+859,33,118},{__ksx1001_decmap+
+945,33,113},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+1026,33,126},{
+__ksx1001_decmap+1120,33,126},{__ksx1001_decmap+1214,33,126},{__ksx1001_decmap
++1308,33,126},{__ksx1001_decmap+1402,33,126},{__ksx1001_decmap+1496,33,126},{
+__ksx1001_decmap+1590,33,126},{__ksx1001_decmap+1684,33,126},{__ksx1001_decmap
++1778,33,126},{__ksx1001_decmap+1872,33,126},{__ksx1001_decmap+1966,33,126},{
+__ksx1001_decmap+2060,33,126},{__ksx1001_decmap+2154,33,126},{__ksx1001_decmap
++2248,33,126},{__ksx1001_decmap+2342,33,126},{__ksx1001_decmap+2436,33,126},{
+__ksx1001_decmap+2530,33,126},{__ksx1001_decmap+2624,33,126},{__ksx1001_decmap
++2718,33,126},{__ksx1001_decmap+2812,33,126},{__ksx1001_decmap+2906,33,126},{
+__ksx1001_decmap+3000,33,126},{__ksx1001_decmap+3094,33,126},{__ksx1001_decmap
++3188,33,126},{__ksx1001_decmap+3282,33,126},{0,0,0},{__ksx1001_decmap+3376,
+33,126},{__ksx1001_decmap+3470,33,126},{__ksx1001_decmap+3564,33,126},{
+__ksx1001_decmap+3658,33,126},{__ksx1001_decmap+3752,33,126},{__ksx1001_decmap
++3846,33,126},{__ksx1001_decmap+3940,33,126},{__ksx1001_decmap+4034,33,126},{
+__ksx1001_decmap+4128,33,126},{__ksx1001_decmap+4222,33,126},{__ksx1001_decmap
++4316,33,126},{__ksx1001_decmap+4410,33,126},{__ksx1001_decmap+4504,33,126},{
+__ksx1001_decmap+4598,33,126},{__ksx1001_decmap+4692,33,126},{__ksx1001_decmap
++4786,33,126},{__ksx1001_decmap+4880,33,126},{__ksx1001_decmap+4974,33,126},{
+__ksx1001_decmap+5068,33,126},{__ksx1001_decmap+5162,33,126},{__ksx1001_decmap
++5256,33,126},{__ksx1001_decmap+5350,33,126},{__ksx1001_decmap+5444,33,126},{
+__ksx1001_decmap+5538,33,126},{__ksx1001_decmap+5632,33,126},{__ksx1001_decmap
++5726,33,126},{__ksx1001_decmap+5820,33,126},{__ksx1001_decmap+5914,33,126},{
+__ksx1001_decmap+6008,33,126},{__ksx1001_decmap+6102,33,126},{__ksx1001_decmap
++6196,33,126},{__ksx1001_decmap+6290,33,126},{__ksx1001_decmap+6384,33,126},{
+__ksx1001_decmap+6478,33,126},{__ksx1001_decmap+6572,33,126},{__ksx1001_decmap
++6666,33,126},{__ksx1001_decmap+6760,33,126},{__ksx1001_decmap+6854,33,126},{
+__ksx1001_decmap+6948,33,126},{__ksx1001_decmap+7042,33,126},{__ksx1001_decmap
++7136,33,126},{__ksx1001_decmap+7230,33,126},{__ksx1001_decmap+7324,33,126},{
+__ksx1001_decmap+7418,33,126},{__ksx1001_decmap+7512,33,126},{__ksx1001_decmap
++7606,33,126},{__ksx1001_decmap+7700,33,126},{__ksx1001_decmap+7794,33,126},{
+__ksx1001_decmap+7888,33,126},{__ksx1001_decmap+7982,33,126},{__ksx1001_decmap
++8076,33,126},{__ksx1001_decmap+8170,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},
+};
+
+static const ucs2_t __cp949ext_decmap[9650] = {
+44034,44035,44037,44038,44043,44044,44045,44046,44047,44056,44062,44063,44065,
+44066,44067,44069,44070,44071,44072,44073,44074,44075,44078,44082,44083,44084,
+U,U,U,U,U,U,44085,44086,44087,44090,44091,44093,44094,44095,44097,44098,44099,
+44100,44101,44102,44103,44104,44105,44106,44108,44110,44111,44112,44113,44114,
+44115,44117,U,U,U,U,U,U,44118,44119,44121,44122,44123,44125,44126,44127,44128,
+44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141,
+44142,44143,44146,44147,44149,44150,44153,44155,44156,44157,44158,44159,44162,
+44167,44168,44173,44174,44175,44177,44178,44179,44181,44182,44183,44184,44185,
+44186,44187,44190,44194,44195,44196,44197,44198,44199,44203,44205,44206,44209,
+44210,44211,44212,44213,44214,44215,44218,44222,44223,44224,44226,44227,44229,
+44230,44231,44233,44234,44235,44237,44238,44239,44240,44241,44242,44243,44244,
+44246,44248,44249,44250,44251,44252,44253,44254,44255,44258,44259,44261,44262,
+44265,44267,44269,44270,44274,44276,44279,44280,44281,44282,44283,44286,44287,
+44289,44290,44291,44293,44295,44296,44297,44298,44299,44302,44304,44306,44307,
+44308,44309,44310,44311,44313,44314,44315,44317,44318,44319,44321,44322,44323,
+44324,44325,44326,44327,44328,44330,44331,44334,44335,44336,44337,44338,44339,
+U,U,U,U,U,U,44342,44343,44345,44346,44347,44349,44350,44351,44352,44353,44354,
+44355,44358,44360,44362,44363,44364,44365,44366,44367,44369,44370,44371,44373,
+44374,44375,U,U,U,U,U,U,44377,44378,44379,44380,44381,44382,44383,44384,44386,
+44388,44389,44390,44391,44392,44393,44394,44395,44398,44399,44401,44402,44407,
+44408,44409,44410,44414,44416,44419,44420,44421,44422,44423,44426,44427,44429,
+44430,44431,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443,
+44446,44447,44448,44449,44450,44451,44453,44454,44455,44456,44457,44458,44459,
+44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44472,44473,
+44474,44475,44476,44477,44478,44479,44482,44483,44485,44486,44487,44489,44490,
+44491,44492,44493,44494,44495,44498,44500,44501,44502,44503,44504,44505,44506,
+44507,44509,44510,44511,44513,44514,44515,44517,44518,44519,44520,44521,44522,
+44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535,
+44538,44539,44541,44542,44546,44547,44548,44549,44550,44551,44554,44556,44558,
+44559,44560,44561,44562,44563,44565,44566,44567,44568,44569,44570,44571,44572,
+U,U,U,U,U,U,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583,
+44584,44585,44586,44587,44588,44589,44590,44591,44594,44595,44597,44598,44601,
+44603,44604,U,U,U,U,U,U,44605,44606,44607,44610,44612,44615,44616,44617,44619,
+44623,44625,44626,44627,44629,44631,44632,44633,44634,44635,44638,44642,44643,
+44644,44646,44647,44650,44651,44653,44654,44655,44657,44658,44659,44660,44661,
+44662,44663,44666,44670,44671,44672,44673,44674,44675,44678,44679,44680,44681,
+44682,44683,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695,
+44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708,
+44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721,
+44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44735,44737,44738,
+44739,44741,44742,44743,44744,44745,44746,44747,44750,44754,44755,44756,44757,
+44758,44759,44762,44763,44765,44766,44767,44768,44769,44770,44771,44772,44773,
+44774,44775,44777,44778,44780,44782,44783,44784,44785,44786,44787,44789,44790,
+44791,44793,44794,44795,44797,44798,44799,44800,44801,44802,44803,44804,44805,
+U,U,U,U,U,U,44806,44809,44810,44811,44812,44814,44815,44817,44818,44819,44820,
+44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833,
+44834,44835,U,U,U,U,U,U,44836,44837,44838,44839,44840,44841,44842,44843,44846,
+44847,44849,44851,44853,44854,44855,44856,44857,44858,44859,44862,44864,44868,
+44869,44870,44871,44874,44875,44876,44877,44878,44879,44881,44882,44883,44884,
+44885,44886,44887,44888,44889,44890,44891,44894,44895,44896,44897,44898,44899,
+44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914,
+44915,44916,44917,44918,44919,44920,44922,44923,44924,44925,44926,44927,44929,
+44930,44931,44933,44934,44935,44937,44938,44939,44940,44941,44942,44943,44946,
+44947,44948,44950,44951,44952,44953,44954,44955,44957,44958,44959,44960,44961,
+44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974,
+44975,44976,44977,44978,44979,44980,44981,44982,44983,44986,44987,44989,44990,
+44991,44993,44994,44995,44996,44997,44998,45002,45004,45007,45008,45009,45010,
+45011,45013,45014,45015,45016,45017,45018,45019,45021,45022,45023,45024,45025,
+U,U,U,U,U,U,45026,45027,45028,45029,45030,45031,45034,45035,45036,45037,45038,
+45039,45042,45043,45045,45046,45047,45049,45050,45051,45052,45053,45054,45055,
+45058,45059,U,U,U,U,U,U,45061,45062,45063,45064,45065,45066,45067,45069,45070,
+45071,45073,45074,45075,45077,45078,45079,45080,45081,45082,45083,45086,45087,
+45088,45089,45090,45091,45092,45093,45094,45095,45097,45098,45099,45100,45101,
+45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114,
+45115,45116,45117,45118,45119,45120,45121,45122,45123,45126,45127,45129,45131,
+45133,45135,45136,45137,45138,45142,45144,45146,45147,45148,45150,45151,45152,
+45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165,
+45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178,
+45179,45182,45183,45185,45186,45187,45189,45190,45191,45192,45193,45194,45195,
+45198,45200,45202,45203,45204,45205,45206,45207,45211,45213,45214,45219,45220,
+45221,45222,45223,45226,45232,45234,45238,45239,45241,45242,45243,45245,45246,
+45247,45248,45249,45250,45251,45254,45258,45259,45260,45261,45262,45263,45266,
+U,U,U,U,U,U,45267,45269,45270,45271,45273,45274,45275,45276,45277,45278,45279,
+45281,45282,45283,45284,45286,45287,45288,45289,45290,45291,45292,45293,45294,
+45295,45296,U,U,U,U,U,U,45297,45298,45299,45300,45301,45302,45303,45304,45305,
+45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318,
+45319,45322,45325,45326,45327,45329,45332,45333,45334,45335,45338,45342,45343,
+45344,45345,45346,45350,45351,45353,45354,45355,45357,45358,45359,45360,45361,
+45362,45363,45366,45370,45371,45372,45373,45374,45375,45378,45379,45381,45382,
+45383,45385,45386,45387,45388,45389,45390,45391,45394,45395,45398,45399,45401,
+45402,45403,45405,45406,45407,45409,45410,45411,45412,45413,45414,45415,45416,
+45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429,
+45430,45431,45434,45435,45437,45438,45439,45441,45443,45444,45445,45446,45447,
+45450,45452,45454,45455,45456,45457,45461,45462,45463,45465,45466,45467,45469,
+45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45481,45482,45483,
+45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496,
+U,U,U,U,U,U,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507,
+45508,45509,45510,45511,45512,45513,45514,45515,45517,45518,45519,45521,45522,
+45523,45525,U,U,U,U,U,U,45526,45527,45528,45529,45530,45531,45534,45536,45537,
+45538,45539,45540,45541,45542,45543,45546,45547,45549,45550,45551,45553,45554,
+45555,45556,45557,45558,45559,45560,45562,45564,45566,45567,45568,45569,45570,
+45571,45574,45575,45577,45578,45581,45582,45583,45584,45585,45586,45587,45590,
+45592,45594,45595,45596,45597,45598,45599,45601,45602,45603,45604,45605,45606,
+45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619,
+45621,45622,45623,45624,45625,45626,45627,45629,45630,45631,45632,45633,45634,
+45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647,
+45648,45649,45650,45651,45652,45653,45654,45655,45657,45658,45659,45661,45662,
+45663,45665,45666,45667,45668,45669,45670,45671,45674,45675,45676,45677,45678,
+45679,45680,45681,45682,45683,45686,45687,45688,45689,45690,45691,45693,45694,
+45695,45696,45697,45698,45699,45702,45703,45704,45706,45707,45708,45709,45710,
+U,U,U,U,U,U,45711,45714,45715,45717,45718,45719,45723,45724,45725,45726,45727,
+45730,45732,45735,45736,45737,45739,45741,45742,45743,45745,45746,45747,45749,
+45750,45751,U,U,U,U,U,U,45752,45753,45754,45755,45756,45757,45758,45759,45760,
+45761,45762,45763,45764,45765,45766,45767,45770,45771,45773,45774,45775,45777,
+45779,45780,45781,45782,45783,45786,45788,45790,45791,45792,45793,45795,45799,
+45801,45802,45808,45809,45810,45814,45820,45821,45822,45826,45827,45829,45830,
+45831,45833,45834,45835,45836,45837,45838,45839,45842,45846,45847,45848,45849,
+45850,45851,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863,
+45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876,
+45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889,
+45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902,
+45903,45904,45905,45906,45907,45911,45913,45914,45917,45920,45921,45922,45923,
+45926,45928,45930,45932,45933,45935,45938,45939,45941,45942,45943,45945,45946,
+45947,45948,45949,45950,45951,45954,45958,45959,45960,45961,45962,45963,45965,
+U,U,U,U,U,U,45966,45967,45969,45970,45971,45973,45974,45975,45976,45977,45978,
+45979,45980,45981,45982,45983,45986,45987,45988,45989,45990,45991,45993,45994,
+45995,45997,U,U,U,U,U,U,45998,45999,46000,46001,46002,46003,46004,46005,46006,
+46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019,
+46022,46023,46025,46026,46029,46031,46033,46034,46035,46038,46040,46042,46044,
+46046,46047,46049,46050,46051,46053,46054,46055,46057,46058,46059,46060,46061,
+46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074,
+46075,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088,
+46089,46090,46091,46092,46093,46094,46095,46097,46098,46099,46100,46101,46102,
+46103,46105,46106,46107,46109,46110,46111,46113,46114,46115,46116,46117,46118,
+46119,46122,46124,46125,46126,46127,46128,46129,46130,46131,46133,46134,46135,
+46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148,
+46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46162,46163,
+46165,46166,46167,46169,46170,46171,46172,46173,46174,46175,46178,46180,46182,
+U,U,U,U,U,U,46183,46184,46185,46186,46187,46189,46190,46191,46192,46193,46194,
+46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207,
+46209,46210,U,U,U,U,U,U,46211,46212,46213,46214,46215,46217,46218,46219,46220,
+46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233,
+46234,46235,46236,46238,46239,46240,46241,46242,46243,46245,46246,46247,46249,
+46250,46251,46253,46254,46255,46256,46257,46258,46259,46260,46262,46264,46266,
+46267,46268,46269,46270,46271,46273,46274,46275,46277,46278,46279,46281,46282,
+46283,46284,46285,46286,46287,46289,46290,46291,46292,46294,46295,46296,46297,
+46298,46299,46302,46303,46305,46306,46309,46311,46312,46313,46314,46315,46318,
+46320,46322,46323,46324,46325,46326,46327,46329,46330,46331,46332,46333,46334,
+46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347,
+46348,46349,46350,46351,46352,46353,46354,46355,46358,46359,46361,46362,46365,
+46366,46367,46368,46369,46370,46371,46374,46379,46380,46381,46382,46383,46386,
+46387,46389,46390,46391,46393,46394,46395,46396,46397,46398,46399,46402,46406,
+U,U,U,U,U,U,46407,46408,46409,46410,46414,46415,46417,46418,46419,46421,46422,
+46423,46424,46425,46426,46427,46430,46434,46435,46436,46437,46438,46439,46440,
+46441,46442,U,U,U,U,U,U,46443,46444,46445,46446,46447,46448,46449,46450,46451,
+46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464,
+46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477,
+46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490,
+46491,46492,46493,46494,46495,46498,46499,46501,46502,46503,46505,46508,46509,
+46510,46511,46514,46518,46519,46520,46521,46522,46526,46527,46529,46530,46531,
+46533,46534,46535,46536,46537,46538,46539,46542,46546,46547,46548,46549,46550,
+46551,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564,
+46565,46566,46567,46568,46569,46570,46571,46573,46574,46575,46576,46577,46578,
+46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591,
+46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604,
+46605,46606,46607,46610,46611,46613,46614,46615,46617,46618,46619,46620,46621,
+U,U,U,U,U,U,46622,46623,46624,46625,46626,46627,46628,46630,46631,46632,46633,
+46634,46635,46637,46638,46639,46640,46641,46642,46643,46645,46646,46647,46648,
+46649,46650,U,U,U,U,U,U,46651,46652,46653,46654,46655,46656,46657,46658,46659,
+46660,46661,46662,46663,46665,46666,46667,46668,46669,46670,46671,46672,46673,
+46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686,
+46687,46688,46689,46690,46691,46693,46694,46695,46697,46698,46699,46700,46701,
+46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714,
+46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727,
+46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740,
+46741,46742,46743,46744,46745,46746,46747,46750,46751,46753,46754,46755,46757,
+46758,46759,46760,46761,46762,46765,46766,46767,46768,46770,46771,46772,46773,
+46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786,
+46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799,
+46800,46801,46802,46803,46805,46806,46807,46808,46809,46810,46811,46812,46813,
+U,U,U,U,U,U,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824,
+46825,46826,46827,46828,46829,46830,46831,46833,46834,46835,46837,46838,46839,
+46841,46842,U,U,U,U,U,U,46843,46844,46845,46846,46847,46850,46851,46852,46854,
+46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867,
+46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,
+46881,46882,46883,46884,46885,46886,46887,46890,46891,46893,46894,46897,46898,
+46899,46900,46901,46902,46903,46906,46908,46909,46910,46911,46912,46913,46914,
+46915,46917,46918,46919,46921,46922,46923,46925,46926,46927,46928,46929,46930,
+46931,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46945,46946,
+46947,46949,46950,46951,46953,46954,46955,46956,46957,46958,46959,46962,46964,
+46966,46967,46968,46969,46970,46971,46974,46975,46977,46978,46979,46981,46982,
+46983,46984,46985,46986,46987,46990,46995,46996,46997,47002,47003,47005,47006,
+47007,47009,47010,47011,47012,47013,47014,47015,47018,47022,47023,47024,47025,
+47026,47027,47030,47031,47033,47034,47035,47036,47037,47038,47039,47040,47041,
+U,U,U,U,U,U,47042,47043,47044,47045,47046,47048,47050,47051,47052,47053,47054,
+47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067,
+47068,47069,U,U,U,U,U,U,47070,47071,47072,47073,47074,47075,47076,47077,47078,
+47079,47080,47081,47082,47083,47086,47087,47089,47090,47091,47093,47094,47095,
+47096,47097,47098,47099,47102,47106,47107,47108,47109,47110,47114,47115,47117,
+47118,47119,47121,47122,47123,47124,47125,47126,47127,47130,47132,47134,47135,
+47136,47137,47138,47139,47142,47143,47145,47146,47147,47149,47150,47151,47152,
+47153,47154,47155,47158,47162,47163,47164,47165,47166,47167,47169,47170,47171,
+47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47186,
+47188,47189,47190,47191,47192,47193,47194,47195,47198,47199,47201,47202,47203,
+47205,47206,47207,47208,47209,47210,47211,47214,47216,47218,47219,47220,47221,
+47222,47223,47225,47226,47227,47229,47230,47231,47232,47233,47234,47235,47236,
+47237,47238,47239,47240,47241,47242,47243,47244,47246,47247,47248,47249,47250,
+47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,
+U,U,U,U,U,U,47264,47265,47266,47267,47268,47269,47270,47271,47273,47274,47275,
+47276,47277,47278,47279,47281,47282,47283,47285,47286,47287,47289,47290,47291,
+47292,47293,U,U,U,U,U,U,47294,47295,47298,47300,47302,47303,47304,47305,47306,
+47307,47309,47310,47311,47313,47314,47315,47317,47318,47319,47320,47321,47322,
+47323,47324,47326,47328,47330,47331,47332,47333,47334,47335,47338,47339,47341,
+47342,47343,47345,47346,47347,47348,47349,47350,47351,47354,47356,47358,47359,
+47360,47361,47362,47363,47365,47366,47367,47368,47369,47370,47371,47372,47373,
+47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47385,47386,47387,
+47388,47389,47390,47391,47393,47394,47395,47396,47397,47398,47399,47400,47401,
+47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414,
+47415,47416,47417,47418,47419,47422,47423,47425,47426,47427,47429,47430,47431,
+47432,47433,47434,47435,47437,47438,47440,47442,47443,47444,47445,47446,47447,
+47450,47451,47453,47454,47455,47457,47458,47459,47460,47461,47462,47463,47466,
+47468,47470,47471,47472,47473,47474,47475,47478,47479,47481,47482,47483,47485,
+U,U,U,U,U,U,47486,47487,47488,47489,47490,47491,47494,47496,47499,47500,47503,
+47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516,
+47517,47518,U,U,U,U,U,U,47519,47520,47521,47522,47523,47524,47525,47526,47527,
+47528,47529,47530,47531,47534,47535,47537,47538,47539,47541,47542,47543,47544,
+47545,47546,47547,47550,47552,47554,47555,47556,47557,47558,47559,47562,47563,
+47565,47571,47572,47573,47574,47575,47578,47580,47583,47584,47586,47590,47591,
+47593,47594,47595,47597,47598,47599,47600,47601,47602,47603,47606,47611,47612,
+47613,47614,47615,47618,47619,47620,47621,47622,47623,47625,47626,47627,47628,
+47629,47630,47631,47632,47633,47634,47635,47636,47638,47639,47640,47641,47642,
+47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655,
+47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668,
+47669,47670,47671,47674,47675,47677,47678,47679,47681,47683,47684,47685,47686,
+47687,47690,47692,47695,47696,47697,47698,47702,47703,47705,47706,47707,47709,
+47710,47711,47712,47713,47714,47715,47718,47722,47723,47724,47725,47726,47727,
+U,U,U,U,U,U,47730,47731,47733,47734,47735,47737,47738,47739,47740,47741,47742,
+47743,47744,47745,47746,47750,47752,47753,47754,47755,47757,47758,47759,47760,
+47761,47762,U,U,U,U,U,U,47763,47764,47765,47766,47767,47768,47769,47770,47771,
+47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47786,
+47789,47790,47791,47793,47795,47796,47797,47798,47799,47802,47804,47806,47807,
+47808,47809,47810,47811,47813,47814,47815,47817,47818,47819,47820,47821,47822,
+47823,47824,47825,47826,47827,47828,47829,47830,47831,47834,47835,47836,47837,
+47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850,
+47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863,
+47864,47865,47866,47867,47869,47870,47871,47873,47874,47875,47877,47878,47879,
+47880,47881,47882,47883,47884,47886,47888,47890,47891,47892,47893,47894,47895,
+47897,47898,47899,47901,47902,47903,47905,47906,47907,47908,47909,47910,47911,
+47912,47914,47916,47917,47918,47919,47920,47921,47922,47923,47927,47929,47930,
+47935,47936,47937,47938,47939,47942,47944,47946,47947,47948,47950,47953,47954,
+U,U,U,U,U,U,47955,47957,47958,47959,47961,47962,47963,47964,47965,47966,47967,
+47968,47970,47972,47973,47974,47975,47976,47977,47978,47979,47981,47982,47983,
+47984,47985,U,U,U,U,U,U,47986,47987,47988,47989,47990,47991,47992,47993,47994,
+47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007,
+48009,48010,48011,48013,48014,48015,48017,48018,48019,48020,48021,48022,48023,
+48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48037,
+48038,48039,48041,48042,48043,48045,48046,48047,48048,48049,48050,48051,48053,
+48054,48056,48057,48058,48059,48060,48061,48062,48063,48065,48066,48067,48069,
+48070,48071,48073,48074,48075,48076,48077,48078,48079,48081,48082,48084,48085,
+48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098,
+48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111,
+48112,48113,48114,48115,48116,48117,48118,48119,48122,48123,48125,48126,48129,
+48131,48132,48133,48134,48135,48138,48142,48144,48146,48147,48153,48154,48160,
+48161,48162,48163,48166,48168,48170,48171,48172,48174,48175,48178,48179,48181,
+U,U,U,U,U,U,48182,48183,48185,48186,48187,48188,48189,48190,48191,48194,48198,
+48199,48200,48202,48203,48206,48207,48209,48210,48211,48212,48213,48214,48215,
+48216,48217,U,U,U,U,U,U,48218,48219,48220,48222,48223,48224,48225,48226,48227,
+48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240,
+48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253,
+48254,48255,48256,48257,48258,48259,48262,48263,48265,48266,48269,48271,48272,
+48273,48274,48275,48278,48280,48283,48284,48285,48286,48287,48290,48291,48293,
+48294,48297,48298,48299,48300,48301,48302,48303,48306,48310,48311,48312,48313,
+48314,48315,48318,48319,48321,48322,48323,48325,48326,48327,48328,48329,48330,
+48331,48332,48334,48338,48339,48340,48342,48343,48345,48346,48347,48349,48350,
+48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363,
+48364,48365,48366,48367,48368,48369,48370,48371,48375,48377,48378,48379,48381,
+48382,48383,48384,48385,48386,48387,48390,48392,48394,48395,48396,48397,48398,
+48399,48401,48402,48403,48405,48406,48407,48408,48409,48410,48411,48412,48413,
+U,U,U,U,U,U,48414,48415,48416,48417,48418,48419,48421,48422,48423,48424,48425,
+48426,48427,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439,
+48440,48441,U,U,U,U,U,U,48442,48443,48444,48445,48446,48447,48449,48450,48451,
+48452,48453,48454,48455,48458,48459,48461,48462,48463,48465,48466,48467,48468,
+48469,48470,48471,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483,
+48485,48486,48487,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498,
+48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511,
+48514,48515,48517,48518,48523,48524,48525,48526,48527,48530,48532,48534,48535,
+48536,48539,48541,48542,48543,48544,48545,48546,48547,48549,48550,48551,48552,
+48553,48554,48555,48556,48557,48558,48559,48561,48562,48563,48564,48565,48566,
+48567,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580,
+48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593,
+48594,48595,48598,48599,48601,48602,48603,48605,48606,48607,48608,48609,48610,
+48611,48612,48613,48614,48615,48616,48618,48619,48620,48621,48622,48623,48625,
+U,U,U,U,U,U,48626,48627,48629,48630,48631,48633,48634,48635,48636,48637,48638,
+48639,48641,48642,48644,48646,48647,48648,48649,48650,48651,48654,48655,48657,
+48658,48659,U,U,U,U,U,U,48661,48662,48663,48664,48665,48666,48667,48670,48672,
+48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685,
+48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698,
+48699,48700,48701,48702,48703,48704,48705,48706,48707,48710,48711,48713,48714,
+48715,48717,48719,48720,48721,48722,48723,48726,48728,48732,48733,48734,48735,
+48738,48739,48741,48742,48743,48745,48747,48748,48749,48750,48751,48754,48758,
+48759,48760,48761,48762,48766,48767,48769,48770,48771,48773,48774,48775,48776,
+48777,48778,48779,48782,48786,48787,48788,48789,48790,48791,48794,48795,48796,
+48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48809,48810,
+48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823,
+48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836,
+48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48850,48851,
+U,U,U,U,U,U,48853,48854,48857,48858,48859,48860,48861,48862,48863,48865,48866,
+48870,48871,48872,48873,48874,48875,48877,48878,48879,48880,48881,48882,48883,
+48884,48885,U,U,U,U,U,U,48886,48887,48888,48889,48890,48891,48892,48893,48894,
+48895,48896,48898,48899,48900,48901,48902,48903,48906,48907,48908,48909,48910,
+48911,48912,48913,48914,48915,48916,48917,48918,48919,48922,48926,48927,48928,
+48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941,
+48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954,
+48955,48956,48957,48958,48959,48962,48963,48965,48966,48967,48969,48970,48971,
+48972,48973,48974,48975,48978,48979,48980,48982,48983,48984,48985,48986,48987,
+48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,
+49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,
+49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026,
+49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039,
+49040,49041,49042,49043,49045,49046,49047,49048,49049,49050,49051,49052,49053,
+U,U,U,U,U,U,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064,
+49065,49066,49067,49068,49069,49070,49071,49073,49074,49075,49076,49077,49078,
+49079,49080,U,U,U,U,U,U,49081,49082,49083,49084,49085,49086,49087,49088,49089,
+49090,49091,49092,49094,49095,49096,49097,49098,49099,49102,49103,49105,49106,
+49107,49109,49110,49111,49112,49113,49114,49115,49117,49118,49120,49122,49123,
+49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136,
+49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149,
+49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162,
+49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175,
+49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188,
+49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201,
+49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49213,49214,49215,
+49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228,
+49229,49230,49231,49232,49234,49235,49236,49237,49238,49239,49241,49242,49243,
+U,U,U,U,U,U,49245,49246,49247,49249,49250,49251,49252,49253,49254,49255,49258,
+49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,
+49272,49273,U,U,U,U,U,U,49274,49275,49276,49277,49278,49279,49280,49281,49282,
+49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295,
+49298,49299,49301,49302,49303,49305,49306,49307,49308,49309,49310,49311,49314,
+49316,49318,49319,49320,49321,49322,49323,49326,49329,49330,49335,49336,49337,
+49338,49339,49342,49346,49347,49348,49350,49351,49354,49355,49357,49358,49359,
+49361,49362,49363,49364,49365,49366,49367,49370,49374,49375,49376,49377,49378,
+49379,49382,49383,49385,49386,49387,49389,49390,49391,49392,49393,49394,49395,
+49398,49400,49402,49403,49404,49405,49406,49407,49409,49410,49411,49413,49414,
+49415,49417,49418,49419,49420,49421,49422,49423,49425,49426,49427,49428,49430,
+49431,49432,49433,49434,49435,49441,49442,49445,49448,49449,49450,49451,49454,
+49458,49459,49460,49461,49463,49466,49467,49469,49470,49471,49473,49474,49475,
+49476,49477,49478,49479,49482,49486,49487,49488,49489,49490,49491,49494,49495,
+U,U,U,U,U,U,49497,49498,49499,49501,49502,49503,49504,49505,49506,49507,49510,
+49514,49515,49516,49517,49518,49519,49521,49522,49523,49525,49526,49527,49529,
+49530,49531,U,U,U,U,U,U,49532,49533,49534,49535,49536,49537,49538,49539,49540,
+49542,49543,49544,49545,49546,49547,49551,49553,49554,49555,49557,49559,49560,
+49561,49562,49563,49566,49568,49570,49571,49572,49574,49575,49578,49579,49581,
+49582,49583,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595,
+49596,49598,49599,49600,49601,49602,49603,49605,49606,49607,49609,49610,49611,
+49613,49614,49615,49616,49617,49618,49619,49621,49622,49625,49626,49627,49628,
+49629,49630,49631,49633,49634,49635,49637,49638,49639,49641,49642,49643,49644,
+49645,49646,49647,49650,49652,49653,49654,49655,49656,49657,49658,49659,49662,
+49663,49665,49666,49667,49669,49670,49671,49672,49673,49674,49675,49678,49680,
+49682,49683,49684,49685,49686,49687,49690,49691,49693,49694,49697,49698,49699,
+49700,49701,49702,49703,49706,49708,49710,49712,49715,49717,49718,49719,49720,
+49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733,
+U,U,U,U,U,U,49734,49735,49737,49738,49739,49740,49741,49742,49743,49746,49747,
+49749,49750,49751,49753,49754,49755,49756,49757,49758,49759,49761,49762,49763,
+49764,49766,U,U,U,U,U,U,49767,49768,49769,49770,49771,49774,49775,49777,49778,
+49779,49781,49782,49783,49784,49785,49786,49787,49790,49792,49794,49795,49796,
+49797,49798,49799,49802,49803,49804,49805,49806,49807,49809,49810,49811,49812,
+49813,49814,49815,49817,49818,49820,49822,49823,49824,49825,49826,49827,49830,
+49831,49833,49834,49835,49838,49839,49840,49841,49842,49843,49846,49848,49850,
+49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863,
+49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876,
+49877,49878,49879,49880,49881,49882,49883,49886,49887,49889,49890,49893,49894,
+49895,49896,49897,49898,49902,49904,49906,49907,49908,49909,49911,49914,49917,
+49918,49919,49921,49922,49923,49924,49925,49926,49927,49930,49931,49934,49935,
+49936,49937,49938,49942,49943,49945,49946,49947,49949,49950,49951,49952,49953,
+49954,49955,49958,49959,49962,49963,49964,49965,49966,49967,49968,49969,49970,
+U,U,U,U,U,U,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981,
+49982,49983,49984,49985,49986,49987,49988,49990,49991,49992,49993,49994,49995,
+49996,49997,U,U,U,U,U,U,49998,49999,50000,50001,50002,50003,50004,50005,50006,
+50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019,
+50020,50021,50022,50023,50026,50027,50029,50030,50031,50033,50035,50036,50037,
+50038,50039,50042,50043,50046,50047,50048,50049,50050,50051,50053,50054,50055,
+50057,50058,50059,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070,
+50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083,
+50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096,
+50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109,
+50110,50111,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123,
+50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50138,
+50139,50141,50142,50145,50147,50148,50149,50150,50151,50154,50155,50156,50158,
+50159,50160,50161,50162,50163,50166,50167,50169,50170,50171,50172,50173,50174,
+U,U,U,U,U,U,50175,50176,50177,50178,50179,50180,50181,50182,50183,50185,50186,
+50187,50188,50189,50190,50191,50193,50194,50195,50196,50197,50198,50199,50200,
+50201,50202,U,U,U,U,U,U,50203,50204,50205,50206,50207,50208,50209,50210,50211,
+50213,50214,50215,50216,50217,50218,50219,50221,50222,50223,50225,50226,50227,
+50229,50230,50231,50232,50233,50234,50235,50238,50239,50240,50241,50242,50243,
+50244,50245,50246,50247,50249,50250,50251,50252,50253,50254,50255,50256,50257,
+50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270,
+50271,50272,50273,50274,50275,50278,50279,50281,50282,50283,50285,50286,50287,
+50288,50289,50290,50291,50294,50295,50296,50298,50299,50300,50301,50302,50303,
+50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317,
+50318,50319,50320,50321,50322,50323,50325,50326,50327,50328,50329,50330,50331,
+50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345,
+50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358,
+50359,50361,50362,50363,50365,50366,50367,50368,50369,50370,50371,50372,50373,
+U,U,U,U,U,U,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384,
+50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397,
+50398,50399,U,U,U,U,U,U,50400,50401,50402,50403,50404,50405,50406,50407,50408,
+50410,50411,50412,50413,50414,50415,50418,50419,50421,50422,50423,50425,50427,
+50428,50429,50430,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443,
+50445,50446,50447,50449,50450,50451,50453,50454,50455,50456,50457,50458,50459,
+50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50474,50475,
+50477,50478,50479,50481,50482,50483,50484,50485,50486,50487,50490,50492,50494,
+50495,50496,50497,50498,50499,50502,50503,50507,50511,50512,50513,50514,50518,
+50522,50523,50524,50527,50530,50531,50533,50534,50535,50537,50538,50539,50540,
+50541,50542,50543,50546,50550,50551,50552,50553,50554,50555,50558,50559,50561,
+50562,50563,50565,50566,50568,50569,50570,50571,50574,50576,50578,50579,50580,
+50582,50585,50586,50587,50589,50590,50591,50593,50594,50595,50596,50597,50598,
+50599,50600,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50614,
+U,U,U,U,U,U,50615,50618,50623,50624,50625,50626,50627,50635,50637,50639,50642,
+50643,50645,50646,50647,50649,50650,50651,50652,50653,50654,50655,50658,50660,
+50662,50663,U,U,U,U,U,U,50664,50665,50666,50667,50671,50673,50674,50675,50677,
+50680,50681,50682,50683,50690,50691,50692,50697,50698,50699,50701,50702,50703,
+50705,50706,50707,50708,50709,50710,50711,50714,50717,50718,50719,50720,50721,
+50722,50723,50726,50727,50729,50730,50731,50735,50737,50738,50742,50744,50746,
+50748,50749,50750,50751,50754,50755,50757,50758,50759,50761,50762,50763,50764,
+50765,50766,50767,50770,50774,50775,50776,50777,50778,50779,50782,50783,50785,
+50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50797,50798,50800,
+50802,50803,50804,50805,50806,50807,50810,50811,50813,50814,50815,50817,50818,
+50819,50820,50821,50822,50823,50826,50828,50830,50831,50832,50833,50834,50835,
+50838,50839,50841,50842,50843,50845,50846,50847,50848,50849,50850,50851,50854,
+50856,50858,50859,50860,50861,50862,50863,50866,50867,50869,50870,50871,50875,
+50876,50877,50878,50879,50882,50884,50886,50887,50888,50889,50890,50891,50894,
+U,U,U,U,U,U,50895,50897,50898,50899,50901,50902,50903,50904,50905,50906,50907,
+50910,50911,50914,50915,50916,50917,50918,50919,50922,50923,50925,50926,50927,
+50929,50930,U,U,U,U,U,U,50931,50932,50933,50934,50935,50938,50939,50940,50942,
+50943,50944,50945,50946,50947,50950,50951,50953,50954,50955,50957,50958,50959,
+50960,50961,50962,50963,50966,50968,50970,50971,50972,50973,50974,50975,50978,
+50979,50981,50982,50983,50985,50986,50987,50988,50989,50990,50991,50994,50996,
+50998,51000,51001,51002,51003,51006,51007,51009,51010,51011,51013,51014,51015,
+51016,51017,51019,51022,51024,51033,51034,51035,51037,51038,51039,51041,51042,
+51043,51044,51045,51046,51047,51049,51050,51052,51053,51054,51055,51056,51057,
+51058,51059,51062,51063,51065,51066,51067,51071,51072,51073,51074,51078,51083,
+51084,51085,51087,51090,51091,51093,51097,51099,51100,51101,51102,51103,51106,
+51111,51112,51113,51114,51115,51118,51119,51121,51122,51123,51125,51126,51127,
+51128,51129,51130,51131,51134,51138,51139,51140,51141,51142,51143,51146,51147,
+51149,51151,51153,51154,51155,51156,51157,51158,51159,51161,51162,51163,51164,
+U,U,U,U,U,U,51166,51167,51168,51169,51170,51171,51173,51174,51175,51177,51178,
+51179,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192,
+51193,51194,U,U,U,U,U,U,51195,51196,51197,51198,51199,51202,51203,51205,51206,
+51207,51209,51211,51212,51213,51214,51215,51218,51220,51223,51224,51225,51226,
+51227,51230,51231,51233,51234,51235,51237,51238,51239,51240,51241,51242,51243,
+51246,51248,51250,51251,51252,51253,51254,51255,51257,51258,51259,51261,51262,
+51263,51265,51266,51267,51268,51269,51270,51271,51274,51275,51278,51279,51280,
+51281,51282,51283,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294,
+51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307,
+51308,51309,51310,51311,51314,51315,51317,51318,51319,51321,51323,51324,51325,
+51326,51327,51330,51332,51336,51337,51338,51342,51343,51344,51345,51346,51347,
+51349,51350,51351,51352,51353,51354,51355,51356,51358,51360,51362,51363,51364,
+51365,51366,51367,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378,
+51379,51380,51381,51382,51383,51384,51385,51386,51387,51390,51391,51392,51393,
+U,U,U,U,U,U,51394,51395,51397,51398,51399,51401,51402,51403,51405,51406,51407,
+51408,51409,51410,51411,51414,51416,51418,51419,51420,51421,51422,51423,51426,
+51427,51429,U,U,U,U,U,U,51430,51431,51432,51433,51434,51435,51436,51437,51438,
+51439,51440,51441,51442,51443,51444,51446,51447,51448,51449,51450,51451,51454,
+51455,51457,51458,51459,51463,51464,51465,51466,51467,51470,51472,51474,51475,
+51476,51477,51478,51479,51481,51482,51483,51484,51485,51486,51487,51488,51489,
+51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,U,U,U,U,U,U,51501,
+51502,51503,51504,51505,51506,51507,51509,51510,51511,51512,51513,51514,51515,
+51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,U,U,U,
+U,U,U,51528,51529,51530,51531,51532,51533,51534,51535,51538,51539,51541,51542,
+51543,51545,51546,51547,51548,51549,51550,51551,51554,51556,51557,51558,51559,
+51560,51561,51562,51563,51565,51566,51567,51569,51570,51571,51573,51574,51575,
+51576,51577,51578,51579,51581,51582,51583,51584,51585,51586,51587,51588,51589,
+51590,51591,51594,51595,51597,51598,51599,U,U,U,U,U,U,51601,51602,51603,51604,
+51605,51606,51607,51610,51612,51614,51615,51616,51617,51618,51619,51620,51621,
+51622,51623,51624,51625,51626,51627,51628,51629,51630,U,U,U,U,U,U,51631,51632,
+51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645,
+51646,51647,51650,51651,51653,51654,51657,51659,51660,51661,51662,51663,51666,
+51668,51671,51672,51675,51678,51679,51681,51683,51685,51686,51688,51689,51690,
+51691,51694,51698,51699,51700,51701,51702,51703,51706,51707,51709,51710,51711,
+51713,51714,51715,51716,U,U,U,U,U,U,51717,51718,51719,51722,51726,51727,51728,
+51729,51730,51731,51733,51734,51735,51737,51738,51739,51740,51741,51742,51743,
+51744,51745,51746,51747,51748,51749,U,U,U,U,U,U,51750,51751,51752,51754,51755,
+51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768,
+51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781,
+51782,51783,51784,51785,51786,51787,51790,51791,51793,51794,51795,51797,51798,
+51799,51800,51801,51802,51803,51806,51810,51811,51812,51813,51814,51815,51817,
+51818,U,U,U,U,U,U,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828,
+51829,51830,51831,51832,51833,51834,51835,51836,51838,51839,51840,51841,51842,
+51843,51845,51846,U,U,U,U,U,U,51847,51848,51849,51850,51851,51852,51853,51854,
+51855,51856,51857,51858,51859,51860,51861,51862,51863,51865,51866,51867,51868,
+51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881,
+51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894,
+51895,51896,51897,51898,51899,51902,51903,51905,51906,51907,51909,U,U,U,U,U,U,
+51910,51911,51912,51913,51914,51915,51918,51920,51922,51924,51925,51926,51927,
+51930,51931,51932,51933,51934,51935,51937,51938,51939,51940,51941,51942,51943,
+U,U,U,U,U,U,51944,51945,51946,51947,51949,51950,51951,51952,51953,51954,51955,
+51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969,
+51970,51971,51972,51973,51974,51975,51977,51978,51979,51980,51981,51982,51983,
+51985,51986,51987,51989,51990,51991,51993,51994,51995,51996,51997,51998,51999,
+52002,52003,52004,52005,52006,52007,52008,52009,U,U,U,U,U,U,52010,52011,52012,
+52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025,
+52026,52027,52028,52029,52030,52031,52032,52034,52035,52036,U,U,U,U,U,U,52037,
+52038,52039,52042,52043,52045,52046,52047,52049,52050,52051,52052,52053,52054,
+52055,52058,52059,52060,52062,52063,52064,52065,52066,52067,52069,52070,52071,
+52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084,
+52085,52086,52087,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099,
+52100,52101,52102,52103,52104,U,U,U,U,U,U,52105,52106,52107,52108,52109,52110,
+52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123,
+52125,52126,52127,52128,52129,52130,52131,U,U,U,U,U,U,52132,52133,52134,52135,
+52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148,
+52149,52150,52151,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162,
+52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175,
+52176,52177,52178,52179,52181,52182,52183,52184,52185,52186,52187,52188,52189,
+52190,52191,U,U,U,U,U,U,52192,52193,52194,52195,52197,52198,52200,52202,52203,
+52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216,
+52217,52218,52219,52220,U,U,U,U,U,U,52221,52222,52223,52224,52225,52226,52227,
+52228,52229,52230,52231,52232,52233,52234,52235,52238,52239,52241,52242,52243,
+52245,52246,52247,52248,52249,52250,52251,52254,52255,52256,52259,52260,52261,
+52262,52266,52267,52269,52271,52273,52274,52275,52276,52277,52278,52279,52282,
+52287,52288,52289,52290,52291,52294,52295,52297,52298,52299,52301,52302,U,U,U,
+U,U,U,52303,52304,52305,52306,52307,52310,52314,52315,52316,52317,52318,52319,
+52321,52322,52323,52325,52327,52329,52330,52331,52332,52333,52334,52335,52337,
+52338,U,U,U,U,U,U,52339,52340,52342,52343,52344,52345,52346,52347,52348,52349,
+52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362,
+52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375,
+52378,52379,52381,52382,52383,52385,52386,52387,52388,52389,52390,52391,52394,
+52398,52399,52400,52401,52402,52403,52406,52407,52409,U,U,U,U,U,U,52410,52411,
+52413,52414,52415,52416,52417,52418,52419,52422,52424,52426,52427,52428,52429,
+52430,52431,52433,52434,52435,52437,52438,52439,52440,52441,52442,U,U,U,U,U,U,
+52443,52444,52445,52446,52447,52448,52449,52450,52451,52453,52454,52455,52456,
+52457,52458,52459,52461,52462,52463,52465,52466,52467,52468,52469,52470,52471,
+52472,52473,52474,52475,52476,52477,52478,52479,52480,52482,52483,52484,52485,
+52486,52487,52490,52491,52493,52494,52495,52497,52498,52499,52500,52501,52502,
+52503,52506,52508,52510,52511,52512,U,U,U,U,U,U,52513,52514,52515,52517,52518,
+52519,52521,52522,52523,52525,52526,52527,52528,52529,52530,52531,52532,52533,
+52534,52535,52536,52538,52539,52540,52541,52542,U,U,U,U,U,U,52543,52544,52545,
+52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558,
+52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571,
+52573,52574,52575,52577,52578,52579,52581,52582,52583,52584,52585,52586,52587,
+52590,52592,52594,52595,52596,52597,52598,52599,52601,52602,52603,52604,52605,
+52606,52607,52608,U,U,U,U,U,U,52609,52610,52611,52612,52613,52614,52615,52617,
+52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52630,52631,52633,
+52634,52635,52637,52638,52639,U,U,U,U,U,U,52640,52641,52642,52643,52646,52648,
+52650,52651,52652,52653,52654,52655,52657,52658,52659,52660,52661,52662,52663,
+52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52677,
+52678,52679,52680,52681,52682,52683,52685,52686,52687,52689,52690,52691,52692,
+52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705,
+U,U,U,U,U,U,52706,52707,52708,52709,52710,52711,52713,52714,52715,52717,52718,
+52719,52721,52722,52723,52724,52725,52726,52727,52730,52732,52734,52735,52736,
+52737,52738,U,U,U,U,U,U,52739,52741,52742,52743,52745,52746,52747,52749,52750,
+52751,52752,52753,52754,52755,52757,52758,52759,52760,52762,52763,52764,52765,
+52766,52767,52770,52771,52773,52774,52775,52777,52778,52779,52780,52781,52782,
+52783,52786,52788,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799,
+52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,U,U,U,U,U,U,52810,
+52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823,
+52826,52827,52829,52830,52834,52835,52836,52837,52838,52839,52842,52844,U,U,U,
+U,U,U,52846,52847,52848,52849,52850,52851,52854,52855,52857,52858,52859,52861,
+52862,52863,52864,52865,52866,52867,52870,52872,52874,52875,52876,52877,52878,
+52879,52882,52883,52885,52886,52887,52889,52890,52891,52892,52893,52894,52895,
+52898,52902,52903,52904,52905,52906,52907,52910,52911,52912,52913,52914,52915,
+52916,52917,52918,52919,52920,52921,52922,U,U,U,U,U,U,52923,52924,52925,52926,
+52927,52928,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940,
+52941,52942,52943,52944,52945,52946,52947,52948,52949,U,U,U,U,U,U,52950,52951,
+52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52966,
+52967,52969,52970,52973,52974,52975,52976,52977,52978,52979,52982,52986,52987,
+52988,52989,52990,52991,52994,52995,52997,52998,52999,53001,53002,53003,53004,
+53005,53006,53007,53010,53012,53014,53015,53016,53017,53018,53019,53021,53022,
+53023,53025,53026,53027,U,U,U,U,U,U,53029,53030,53031,53032,53033,53034,53035,
+53038,53042,53043,53044,53045,53046,53047,53049,53050,53051,53052,53053,53054,
+53055,53056,53057,53058,53059,53060,U,U,U,U,U,U,53061,53062,53063,53064,53065,
+53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53078,53079,53081,
+53082,53083,53085,53086,53087,53088,53089,53090,53091,53094,53096,53098,53099,
+53100,53101,53102,53103,53106,53107,53109,53110,53111,53113,53114,53115,53116,
+53117,53118,53119,53121,53122,53123,53124,53126,53127,53128,53129,53130,53131,
+53133,U,U,U,U,U,U,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143,
+53144,53145,53146,53147,53148,53149,53150,53151,53152,53154,53155,53156,53157,
+53158,53159,53161,U,U,U,U,U,U,53162,53163,53164,53165,53166,53167,53169,53170,
+53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183,
+53184,53185,53186,53187,53189,53190,53191,53192,53193,53194,53195,53196,53197,
+53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210,
+53211,53212,53213,53214,53215,53218,53219,53221,53222,53223,53225,U,U,U,U,U,U,
+53226,53227,53228,53229,53230,53231,53234,53236,53238,53239,53240,53241,53242,
+53243,53245,53246,53247,53249,53250,53251,53253,53254,53255,53256,53257,53258,
+U,U,U,U,U,U,53259,53260,53261,53262,53263,53264,53266,53267,53268,53269,53270,
+53271,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284,
+53285,53286,53287,53288,53289,53290,53291,53292,53294,53295,53296,53297,53298,
+53299,53302,53303,53305,53306,53307,53309,53310,53311,53312,53313,53314,53315,
+53318,53320,53322,53323,53324,53325,53326,53327,U,U,U,U,U,U,53329,53330,53331,
+53333,53334,53335,53337,53338,53339,53340,53341,53342,53343,53345,53346,53347,
+53348,53349,53350,53351,53352,53353,53354,53355,53358,53359,U,U,U,U,U,U,53361,
+53362,53363,53365,53366,53367,53368,53369,53370,53371,53374,53375,53376,53378,
+53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391,
+53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404,
+53405,53406,53407,53408,53409,53410,53411,53414,53415,53417,53418,53419,53421,
+53422,53423,53424,53425,53426,U,U,U,U,U,U,53427,53430,53432,53434,53435,53436,
+53437,53438,53439,53442,53443,53445,53446,53447,53450,53451,53452,53453,53454,
+53455,53458,53462,53463,53464,53465,53466,U,U,U,U,U,U,53467,53470,53471,53473,
+53474,53475,53477,53478,53479,53480,53481,53482,53483,53486,53490,53491,53492,
+53493,53494,53495,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506,
+53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53518,53519,53520,
+53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533,
+53534,53535,U,U,U,U,U,U,53536,53537,53538,53539,53540,53541,53542,53543,53544,
+53545,53546,53547,53548,53549,53550,53551,53554,53555,53557,53558,53559,53561,
+53563,53564,53565,53566,U,U,U,U,U,U,53567,53570,53574,53575,53576,53577,53578,
+53579,53582,53583,53585,53586,53587,53589,53590,53591,53592,53593,53594,53595,
+53598,53600,53602,53603,53604,53605,53606,53607,53609,53610,53611,53613,53614,
+53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627,
+53629,53630,53631,53632,53633,53634,53635,53637,53638,53639,53641,53642,U,U,U,
+U,U,U,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654,
+53655,53656,53657,53658,53659,53660,53661,53662,53663,53666,53667,53669,53670,
+53671,U,U,U,U,U,U,53673,53674,53675,53676,53677,53678,53679,53682,53684,53686,
+53687,53688,53689,53691,53693,53694,53695,53697,53698,53699,53700,53701,53702,
+53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715,
+53716,53717,53718,53719,53721,53722,53723,53724,53725,53726,53727,53728,53729,
+53730,53731,53732,53733,53734,53735,53736,53737,53738,U,U,U,U,U,U,53739,53740,
+53741,53742,53743,53744,53745,53746,53747,53749,53750,53751,53753,53754,53755,
+53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,U,U,U,U,U,U,
+53768,53770,53771,53772,53773,53774,53775,53777,53778,53779,53780,53781,53782,
+53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795,
+53796,53797,53798,53799,53800,53801,53802,53803,53806,53807,53809,53810,53811,
+53813,53814,53815,53816,53817,53818,53819,53822,53824,53826,53827,53828,53829,
+53830,53831,53833,53834,53835,53836,U,U,U,U,U,U,53837,53838,53839,53840,53841,
+53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53853,53854,53855,
+53856,53857,53858,53859,53861,53862,53863,53864,U,U,U,U,U,U,53865,53866,53867,
+53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880,
+53881,53882,53883,53884,53885,53886,53887,53890,53891,53893,53894,53895,53897,
+53898,53899,53900,53901,53902,53903,53906,53907,53908,53910,53911,53912,53913,
+53914,53915,53917,53918,53919,53921,53922,53923,53925,53926,53927,53928,53929,
+53930,53931,53933,U,U,U,U,U,U,53934,53935,53936,53938,53939,53940,53941,53942,
+53943,53946,53947,53949,53950,53953,53955,53956,53957,53958,53959,53962,53964,
+53965,53966,53967,53968,53969,U,U,U,U,U,U,53970,53971,53973,53974,53975,53977,
+53978,53979,53981,53982,53983,53984,53985,53986,53987,53990,53991,53992,53993,
+53994,53995,53996,53997,53998,53999,54002,54003,54005,54006,54007,54009,54010,
+54011,54012,54013,54014,54015,54018,54020,54022,54023,54024,54025,54026,54027,
+54031,54033,54034,54035,54037,54039,54040,54041,54042,54043,54046,54050,54051,
+U,U,U,U,U,U,54052,54054,54055,54058,54059,54061,54062,54063,54065,54066,54067,
+54068,54069,54070,54071,54074,54078,54079,54080,54081,54082,54083,54086,54087,
+54088,54089,U,U,U,U,U,U,54090,54091,54092,54093,54094,54095,54096,54097,54098,
+54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111,
+54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124,
+54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137,
+54138,54139,54142,54143,54145,54146,54147,54149,54150,54151,U,U,U,U,U,U,54152,
+54153,54154,54155,54158,54162,54163,54164,54165,54166,54167,54170,54171,54173,
+54174,54175,54177,54178,54179,54180,54181,54182,54183,54186,54188,54190,U,U,U,
+U,U,U,54191,54192,54193,54194,54195,54197,54198,54199,54201,54202,54203,54205,
+54206,54207,54208,54209,54210,54211,54214,54215,54218,54219,54220,54221,54222,
+54223,54225,54226,54227,54228,54229,54230,54231,54233,54234,54235,54236,54237,
+54238,54239,54240,54242,54244,54245,54246,54247,54248,54249,54250,54251,54254,
+54255,54257,54258,54259,54261,54262,54263,U,U,U,U,U,U,54264,54265,54266,54267,
+54270,54272,54274,54275,54276,54277,54278,54279,54281,54282,54283,54284,54285,
+54286,54287,54288,54289,54290,54291,54292,54293,54294,U,U,U,U,U,U,54295,54296,
+54297,54298,54299,54300,54302,54303,54304,54305,54306,54307,54308,54309,54310,
+54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323,
+54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54337,
+54338,54339,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,
+54352,54353,54354,54355,U,U,U,U,U,U,54356,54357,54358,54359,54360,54361,54362,
+54363,54365,54366,54367,54369,54370,54371,54373,54374,54375,54376,54377,54378,
+54379,54380,54382,54384,54385,54386,U,U,U,U,U,U,54387,54388,54389,54390,54391,
+54394,54395,54397,54398,54401,54403,54404,54405,54406,54407,54410,54412,54414,
+54415,54416,54417,54418,54419,54421,54422,54423,54424,54425,54426,54427,54428,
+54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54442,
+54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455,
+54456,U,U,U,U,U,U,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466,
+54467,54468,54469,54470,54471,54472,54473,54474,54475,54477,54478,54479,54481,
+54482,54483,54485,U,U,U,U,U,U,54486,54487,54488,54489,54490,54491,54493,54494,
+54496,54497,54498,54499,54500,54501,54502,54503,54505,54506,54507,54509,54510,
+54511,54513,54514,54515,54516,54517,54518,54519,54521,54522,54524,54526,54527,
+54528,54529,54530,54531,54533,54534,54535,54537,54538,54539,54541,54542,54543,
+54544,54545,54546,54547,54550,54552,54553,54554,54555,54556,54557,U,U,U,U,U,U,
+54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570,
+54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583,
+U,U,U,U,U,U,54584,54585,54586,54587,54590,54591,54593,54594,54595,54597,54598,
+54599,54600,54601,54602,54603,54606,54608,54610,54611,54612,54613,54614,54615,
+54618,54619,54621,54622,54623,54625,54626,54627,54628,54630,54631,54634,54636,
+54638,54639,54640,54641,54642,54643,54646,54647,54649,54650,54651,54653,54654,
+54655,54656,54657,54658,54659,54662,54666,54667,U,U,U,U,U,U,54668,54669,54670,
+54671,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684,
+54685,54686,54687,54688,54689,54690,54691,54692,54694,54695,U,U,U,U,U,U,54696,
+54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709,
+54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722,
+54723,54724,54725,54726,54727,54730,54731,54733,54734,54735,54737,54739,54740,
+54741,54742,54743,54746,54748,54750,54751,54752,54753,54754,54755,54758,54759,
+54761,54762,54763,54765,54766,U,U,U,U,U,U,54767,54768,54769,54770,54771,54774,
+54776,54778,54779,54780,54781,54782,54783,54786,54787,54789,54790,54791,54793,
+54794,54795,54796,54797,54798,54799,54802,U,U,U,U,U,U,54806,54807,54808,54809,
+54810,54811,54813,54814,54815,54817,54818,54819,54821,54822,54823,54824,54825,
+54826,54827,54828,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839,
+54842,54843,54845,54846,54847,54849,54850,54851,54852,54854,54855,54858,54860,
+54862,54863,54864,54866,54867,54870,54871,54873,54874,54875,54877,54878,54879,
+54880,54881,U,U,U,U,U,U,54882,54883,54884,54885,54886,54888,54890,54891,54892,
+54893,54894,54895,54898,54899,54901,54902,54903,54904,54905,54906,54907,54908,
+54909,54910,54911,54912,U,U,U,U,U,U,54913,54914,54916,54918,54919,54920,54921,
+54922,54923,54926,54927,54929,54930,54931,54933,54934,54935,54936,54937,54938,
+54939,54940,54942,54944,54946,54947,54948,54949,54950,54951,54953,54954,54955,
+54957,54958,54959,54961,54962,54963,54964,54965,54966,54967,54968,54970,54972,
+54973,54974,54975,54976,54977,54978,54979,54982,54983,54985,54986,54987,U,U,U,
+U,U,U,54989,54990,54991,54992,54994,54995,54997,54998,55000,55002,55003,55004,
+55005,55006,55007,55009,55010,55011,55013,55014,55015,55017,55018,55019,55020,
+55021,U,U,U,U,U,U,55022,55023,55025,55026,55027,55028,55030,55031,55032,55033,
+55034,55035,55038,55039,55041,55042,55043,55045,55046,55047,55048,55049,55050,
+55051,55052,55053,55054,55055,55056,55058,55059,55060,55061,55062,55063,55066,
+55067,55069,55070,55071,55073,55074,55075,55076,55077,55078,55079,55082,55084,
+55086,55087,55088,55089,55090,55091,55094,55095,55097,U,U,U,U,U,U,55098,55099,
+55101,55102,55103,55104,55105,55106,55107,55109,55110,55112,55114,55115,55116,
+55117,55118,55119,55122,55123,55125,55130,55131,55132,55133,55134,U,U,U,U,U,U,
+55135,55138,55140,55142,55143,55144,55146,55147,55149,55150,55151,55153,55154,
+55155,55157,55158,55159,55160,55161,55162,55163,55166,55167,55168,55170,55171,
+55172,55173,55174,55175,55178,55179,55181,55182,55183,55185,55186,55187,55188,
+55189,55190,55191,55194,55196,55198,55199,55200,55201,55202,55203,
+};
+
+static const struct dbcs_index cp949ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{__cp949ext_decmap+0,65,254},{__cp949ext_decmap+190,
+65,254},{__cp949ext_decmap+380,65,254},{__cp949ext_decmap+570,65,254},{
+__cp949ext_decmap+760,65,254},{__cp949ext_decmap+950,65,254},{
+__cp949ext_decmap+1140,65,254},{__cp949ext_decmap+1330,65,254},{
+__cp949ext_decmap+1520,65,254},{__cp949ext_decmap+1710,65,254},{
+__cp949ext_decmap+1900,65,254},{__cp949ext_decmap+2090,65,254},{
+__cp949ext_decmap+2280,65,254},{__cp949ext_decmap+2470,65,254},{
+__cp949ext_decmap+2660,65,254},{__cp949ext_decmap+2850,65,254},{
+__cp949ext_decmap+3040,65,254},{__cp949ext_decmap+3230,65,254},{
+__cp949ext_decmap+3420,65,254},{__cp949ext_decmap+3610,65,254},{
+__cp949ext_decmap+3800,65,254},{__cp949ext_decmap+3990,65,254},{
+__cp949ext_decmap+4180,65,254},{__cp949ext_decmap+4370,65,254},{
+__cp949ext_decmap+4560,65,254},{__cp949ext_decmap+4750,65,254},{
+__cp949ext_decmap+4940,65,254},{__cp949ext_decmap+5130,65,254},{
+__cp949ext_decmap+5320,65,254},{__cp949ext_decmap+5510,65,254},{
+__cp949ext_decmap+5700,65,254},{__cp949ext_decmap+5890,65,254},{
+__cp949ext_decmap+6080,65,160},{__cp949ext_decmap+6176,65,160},{
+__cp949ext_decmap+6272,65,160},{__cp949ext_decmap+6368,65,160},{
+__cp949ext_decmap+6464,65,160},{__cp949ext_decmap+6560,65,160},{
+__cp949ext_decmap+6656,65,160},{__cp949ext_decmap+6752,65,160},{
+__cp949ext_decmap+6848,65,160},{__cp949ext_decmap+6944,65,160},{
+__cp949ext_decmap+7040,65,160},{__cp949ext_decmap+7136,65,160},{
+__cp949ext_decmap+7232,65,160},{__cp949ext_decmap+7328,65,160},{
+__cp949ext_decmap+7424,65,160},{__cp949ext_decmap+7520,65,160},{
+__cp949ext_decmap+7616,65,160},{__cp949ext_decmap+7712,65,160},{
+__cp949ext_decmap+7808,65,160},{__cp949ext_decmap+7904,65,160},{
+__cp949ext_decmap+8000,65,160},{__cp949ext_decmap+8096,65,160},{
+__cp949ext_decmap+8192,65,160},{__cp949ext_decmap+8288,65,160},{
+__cp949ext_decmap+8384,65,160},{__cp949ext_decmap+8480,65,160},{
+__cp949ext_decmap+8576,65,160},{__cp949ext_decmap+8672,65,160},{
+__cp949ext_decmap+8768,65,160},{__cp949ext_decmap+8864,65,160},{
+__cp949ext_decmap+8960,65,160},{__cp949ext_decmap+9056,65,160},{
+__cp949ext_decmap+9152,65,160},{__cp949ext_decmap+9248,65,160},{
+__cp949ext_decmap+9344,65,160},{__cp949ext_decmap+9440,65,160},{
+__cp949ext_decmap+9536,65,160},{__cp949ext_decmap+9632,65,82},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __cp949_encmap[33133] = {
+8750,N,N,8756,N,N,8535,8487,N,10275,N,N,8489,8807,N,8518,8510,10615,10616,
+8741,N,8786,8484,8748,10614,10284,N,10361,10358,10362,8751,N,N,N,N,N,N,10273,
+N,N,N,N,N,N,N,N,N,10274,N,N,N,N,N,N,8511,10282,N,N,N,N,N,10285,10540,N,N,N,N,
+N,N,10529,N,N,N,N,N,N,N,N,N,10531,N,N,N,N,N,N,8512,10538,N,N,N,N,N,10541,
+10530,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10276,10532,N,N,N,N,N,N,N,N,N,
+10533,10278,10534,N,N,N,N,10535,N,N,N,N,N,N,10280,10536,10281,10537,N,N,N,N,N,
+N,10544,10287,10543,N,N,N,N,N,N,10283,10539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,10286,10542,8743,N,N,N,N,N,N,N,N,8752,N,N,N,N,N,N,N,8744,8747,8746,8749,N,
+8745,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,
+9551,9552,9553,N,9554,9555,9556,9557,9558,9559,9560,N,N,N,N,N,N,N,9569,9570,
+9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,N,
+9586,9587,9588,9589,9590,9591,9592,11303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11297,
+11298,11299,11300,11301,11302,11304,11305,11306,11307,11308,11309,11310,11311,
+11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324,
+11325,11326,11327,11328,11329,11345,11346,11347,11348,11349,11350,11352,11353,
+11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365,11366,
+11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,N,11351,
+8490,N,N,8494,8495,N,N,8496,8497,N,N,8787,8788,N,N,N,8485,8486,N,N,N,N,N,N,N,
+N,N,8758,N,8519,8520,N,N,N,N,N,N,N,8536,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+10617,N,N,N,N,N,N,N,N,N,N,10618,N,10619,10620,10621,10622,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8806,8521,N,N,N,N,N,
+8757,N,N,N,N,N,N,N,N,N,10020,N,N,8800,N,N,N,N,N,N,N,N,N,N,8805,8802,N,N,N,
+10073,N,N,N,N,8522,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,10359,10360,N,N,N,N,N,N,10363,10364,10365,10366,N,9520,
+9521,9522,9523,9524,9525,9526,9527,9528,9529,N,N,N,N,N,N,9505,9506,9507,9508,
+9509,9510,9511,9512,9513,9514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+8551,8552,8550,8553,8554,8789,8792,8790,8793,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,8737,N,8738,8739,N,8531,8740,N,N,N,8532,8564,N,N,8565,N,N,N,8755,N,8754,
+N,N,N,N,N,N,N,N,8558,N,N,8560,8516,N,8528,N,N,N,N,8491,N,8572,8573,8571,8570,
+8562,8563,N,8753,N,N,N,N,N,8517,8561,N,N,N,N,N,N,8493,8559,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,8533,N,N,8514,8515,
+N,N,N,N,8556,8557,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8569,N,N,
+8566,8567,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8769,N,N,N,N,N,N,N,N,N,N,N,8529,
+8530,10343,10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354,
+10355,10356,10357,N,N,N,N,N,10599,10600,10601,10602,10603,10604,10605,10606,
+10607,10608,10609,10610,10611,10612,10613,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,
+10583,10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,
+10596,10597,10598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10317,
+10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,
+10331,10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,9761,
+9772,9762,9773,N,N,N,N,N,N,N,N,9763,9800,9799,9774,9764,9794,9793,9775,9766,
+9798,9797,9777,9765,9796,9795,9776,9767,9788,9801,9802,9783,9803,9804,9778,
+9769,9790,9805,9806,9785,9807,9808,9780,9768,9809,9810,9784,9789,9811,9812,
+9779,9770,9813,9814,9786,9791,9815,9816,9781,9771,9817,9818,9787,9819,9820,
+9792,9821,9822,9823,9824,9825,9826,9827,9828,9782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8774,N,N,N,N,N,N,N,N,N,N,N,N,N,8545,8544,N,
+8771,8775,8776,8779,8778,8777,8780,N,N,N,N,N,N,N,N,8547,8546,N,N,8762,8761,N,
+N,N,N,8549,8548,N,N,8760,8759,N,N,N,N,8543,8542,8770,N,N,8539,N,N,8541,8540,
+8772,8773,8538,8537,N,N,N,N,N,N,N,8783,8782,N,N,N,N,N,N,N,N,N,N,N,N,8784,N,
+8785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8527,N,
+8526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8764,8765,N,
+8768,8763,8766,N,8767,8781,8795,8796,N,8797,8794,8481,8482,8483,8488,N,N,N,N,
+8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,N,8555,8498,8499,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,
+10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,
+10811,10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,
+10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,10836,
+10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,10848,10849,
+10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860,10861,10862,
+10863,10864,10865,10866,10867,N,N,N,N,N,N,N,N,N,N,N,N,N,11041,11042,11043,
+11044,11045,11046,11047,11048,11049,11050,11051,11052,11053,11054,11055,11056,
+11057,11058,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,
+11070,11071,11072,11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,
+11083,11084,11085,11086,11087,11088,11089,11090,11091,11092,11093,11094,11095,
+11096,11097,11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108,
+11109,11110,11111,11112,11113,11114,11115,11116,11117,11118,11119,11120,11121,
+11122,11123,11124,11125,11126,9249,9250,9251,9252,9253,9254,9255,9256,9257,
+9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,
+9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,
+9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,
+9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,
+9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,
+9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,10545,10546,10547,10548,
+10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,10560,10561,
+10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,10572,8799,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10289,10290,10291,10292,
+10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,
+10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,N,N,N,8798,
+10057,10058,10059,10060,10061,N,N,N,10042,10043,10076,10077,10078,10038,10039,
+10040,10068,10069,10070,10071,10072,10017,10018,10019,10021,10027,10028,10029,
+10030,10031,10032,10033,10034,10035,10036,10023,10024,10025,10026,10045,10046,
+10085,10086,10087,10088,10081,10082,10083,10047,10048,10049,10050,10051,10052,
+10053,10054,10055,10056,10062,10063,10064,10065,10066,10067,10074,10075,8803,
+10092,10022,10080,10095,8801,10044,10093,10037,N,N,N,N,10041,10090,N,N,10091,
+N,N,10079,N,8804,N,N,10084,10094,10089,27753,28491,N,30290,N,N,N,22578,27995,
+24370,24382,31035,N,23668,N,N,N,30052,N,N,29478,23904,24870,N,20088,23600,N,N,
+N,N,25386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29033,N,N,N,N,19834,N,N,N,N,N,31791,
+21281,N,28971,N,N,N,N,N,N,26449,21036,N,20089,N,N,N,N,N,29053,N,24127,31546,
+31033,N,N,N,N,N,N,20050,N,25387,27488,N,N,N,20090,19319,25893,N,N,N,N,N,N,N,N,
+N,N,N,19041,N,21580,N,N,N,N,N,27233,N,N,23651,24365,N,N,N,N,N,N,19307,N,N,N,
+21807,N,N,N,22133,N,25976,N,N,24128,27683,N,26957,N,27175,26998,31547,N,26473,
+28492,N,N,20582,N,N,24129,N,N,25644,N,N,22604,31089,N,20063,31268,26162,N,
+31355,N,N,31293,19528,28493,21845,N,N,N,N,N,N,N,21282,N,N,N,27729,N,N,N,N,N,
+25639,27730,N,N,30257,N,N,20091,N,N,20561,19263,N,27940,N,N,N,N,N,N,27944,
+24130,30306,27996,23669,24633,N,N,N,21582,N,29749,N,N,N,21339,22069,27684,N,N,
+N,N,N,N,N,N,N,N,25702,N,29034,N,N,N,19308,19264,N,N,N,27762,20586,N,N,N,N,N,N,
+N,31090,27685,20575,N,26474,20587,23633,23401,32076,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23383,N,N,N,N,23137,N,22070,N,25439,N,24131,N,
+24132,18977,N,N,N,N,N,28268,N,N,21283,28215,30799,N,N,N,N,27208,28216,28972,
+28965,26958,N,N,N,31036,N,N,N,25977,27754,23894,27970,N,N,N,N,N,N,N,N,N,N,N,N,
+30757,N,N,N,N,N,25914,23384,N,N,18978,N,N,20813,N,N,N,28269,N,N,N,27755,24133,
+N,25440,N,19017,29289,N,21838,N,30262,N,20034,22087,N,25396,N,28973,N,27234,N,
+N,N,N,22338,N,29479,N,N,19818,N,27502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22834,
+32037,N,N,N,N,N,30293,21858,N,N,N,N,N,N,N,N,30773,N,N,19573,30005,25645,N,N,N,
+N,26475,29013,N,N,N,28731,N,N,26933,N,19529,31317,N,N,24916,N,N,22358,N,N,
+23617,N,24134,31343,25441,N,N,N,N,N,N,N,N,N,N,N,N,24947,23670,N,20092,N,23364,
+N,30833,N,N,23652,N,25967,23601,N,N,N,21846,N,N,29530,N,19265,N,23363,N,N,N,
+22906,21358,N,N,N,31288,N,N,32038,27503,N,29734,N,19530,29480,N,29531,N,23335,
+30263,N,20326,28786,19290,N,26450,22339,30320,26718,N,N,N,N,N,N,N,N,N,N,N,N,N,
+25894,N,N,N,N,N,N,N,25959,N,N,N,18979,19495,27209,N,N,N,N,N,30774,N,N,N,N,N,
+31269,N,N,N,N,28974,N,28494,N,N,N,N,N,N,N,N,19309,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30256,28495,26959,N,30558,N,N,N,N,N,N,N,20051,N,N,N,N,23671,N,N,N,N,N,N,N,
+23336,N,N,N,19320,N,N,N,N,N,N,24353,23905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+30026,26934,N,N,N,N,26476,28270,N,29552,N,24383,N,N,N,N,N,N,19531,N,N,N,N,N,N,
+20545,N,N,N,29778,24634,N,N,N,N,24384,N,20064,N,N,N,23634,32106,N,N,N,22134,N,
+N,N,27210,N,N,N,N,N,N,26729,N,25388,N,N,N,N,N,29520,N,N,N,N,N,N,N,N,N,N,N,
+18980,N,23416,N,N,N,24135,27504,29014,N,N,25954,N,19532,N,N,19323,N,N,N,N,N,N,
+N,N,27235,N,N,N,N,N,N,N,N,N,N,N,N,24385,N,22125,N,N,N,N,N,N,N,N,26960,N,N,N,N,
+N,N,N,28217,N,N,N,N,21859,N,N,20819,N,25968,N,N,N,26676,27459,N,27178,31356,
+30070,28732,32084,24635,20035,N,20538,30522,22643,30541,N,N,N,25646,N,N,N,N,N,
+N,N,N,N,21599,N,N,N,N,N,20583,N,N,27773,N,21038,28271,21847,27236,30754,19819,
+22335,31537,N,N,19820,N,N,N,23602,20588,20093,28272,N,N,N,19522,N,N,N,20589,N,
+N,N,N,N,25975,N,N,N,29564,N,N,28194,N,N,N,N,22835,N,N,22644,N,26935,N,N,N,N,N,
+N,N,N,20014,N,N,N,N,22818,N,N,N,N,22641,N,21583,N,N,N,N,N,N,N,N,N,25895,21842,
+N,N,N,N,N,22057,N,N,N,N,N,N,29730,N,29015,N,N,21848,N,28733,22352,21584,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,22351,27498,32107,N,N,23405,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+31813,19266,N,N,N,N,32085,N,29768,26730,30067,N,N,31070,21359,N,N,27731,N,N,
+23874,28471,26452,N,19018,N,N,N,22907,N,N,31357,N,N,N,N,N,22058,N,N,N,N,N,
+29816,N,N,N,N,N,N,30583,23596,N,N,N,22359,24354,N,N,N,20030,N,21360,N,N,N,N,N,
+28708,24940,20327,29515,27945,19006,N,N,N,N,N,N,N,29807,N,N,N,30286,N,N,24187,
+20539,21815,28273,N,N,N,N,N,N,29736,N,23672,N,N,N,N,19239,N,23118,N,N,N,24678,
+N,N,N,N,N,N,N,27941,28274,N,N,N,N,23673,N,N,31068,N,N,29532,N,N,N,N,N,N,N,
+30834,N,29817,N,N,N,31857,N,N,N,20540,23417,22321,N,N,N,19324,N,N,N,28709,
+19325,N,N,N,N,N,N,N,N,21876,N,N,N,19821,18981,N,N,22059,20546,N,N,N,N,28734,
+21053,19492,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31286,N,N,19533,N,23162,N,
+30287,N,26936,N,22645,N,N,N,19534,N,N,N,N,22349,N,N,21585,26989,N,19051,22882,
+N,32050,N,25389,22092,22836,N,N,24871,28243,20547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+32051,N,21860,N,N,20328,N,27971,20530,N,N,20094,23080,30800,N,N,32086,N,N,N,N,
+30801,N,30802,23635,N,N,N,N,23906,31609,23873,N,25397,N,N,N,N,N,N,27997,20036,
+N,19233,N,N,N,N,N,N,23907,N,N,N,N,31837,N,N,N,N,N,N,N,N,N,31023,N,N,N,N,N,
+21115,20257,25640,N,29750,27774,N,N,25390,26477,32065,23138,N,N,22579,N,N,N,
+23908,28783,30321,31344,N,N,20853,N,N,23119,N,23636,N,23590,N,28479,N,N,N,N,N,
+20047,N,24665,N,N,N,N,N,N,22870,27732,27211,N,N,19007,21808,N,20329,N,N,N,N,N,
+29037,N,19535,N,N,N,N,25720,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25709,N,N,N,N,22360,N,
+32039,N,N,N,N,27179,30258,N,N,N,N,20336,31037,N,N,N,N,N,N,26228,N,N,N,N,N,N,N,
+N,N,N,N,N,N,19291,N,N,N,N,N,N,N,29521,N,N,N,N,26961,29481,20576,26962,N,23139,
+N,N,N,N,N,N,25170,N,30242,24948,N,N,N,23140,N,N,N,N,N,26453,30015,20258,19759,
+20259,N,N,N,19760,29054,20515,24879,30755,N,18982,30523,29290,24136,26963,N,N,
+N,N,24137,32094,19008,N,N,N,31082,20814,28244,N,21586,22819,32040,22361,30542,
+31294,N,N,N,N,N,N,N,N,N,20310,N,22384,N,27489,30789,N,N,N,N,N,23674,N,N,23875,
+N,31071,N,N,N,N,N,N,N,26479,N,N,N,N,32101,30243,N,22908,32041,N,26478,N,N,N,
+21861,N,N,N,N,N,28496,N,19761,N,N,N,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,28978,N,28977,N,N,N,N,N,N,19762,N,23083,N,18983,N,N,N,N,N,25442,
+31548,22820,N,N,28218,N,N,N,N,N,30803,N,N,N,N,N,31610,N,20260,N,23675,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30307,N,N,N,27946,N,N,29217,20065,N,N,N,N,N,N,
+31270,N,N,N,N,31072,N,N,N,N,27734,N,N,25710,31009,N,N,31599,N,N,N,31083,28195,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27180,N,N,N,18984,N,N,29818,N,N,
+N,N,19798,31862,N,N,N,29769,N,N,N,N,N,N,N,30804,30758,N,24138,29254,N,N,N,N,N,
+N,22362,N,21328,N,N,N,N,N,N,N,N,N,N,N,22597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,27238,N,29533,N,N,N,25690,N,N,N,N,N,N,N,N,30308,N,N,N,N,N,30322,N,24386,N,N,
+N,N,N,N,N,N,22909,N,N,N,19574,N,N,21306,N,N,N,N,N,N,N,25647,N,N,N,N,31073,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28710,N,N,N,19283,N,N,N,24636,N,
+29770,21626,N,32042,31074,N,N,N,N,N,N,N,N,N,N,N,N,N,29751,32066,31792,N,32108,
+19042,N,N,N,N,N,N,N,N,N,32061,N,27239,24387,20818,20066,N,21284,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32043,N,24416,N,N,N,N,N,N,N,N,N,N,N,N,29255,N,N,
+N,N,N,26480,N,20590,N,N,29482,N,N,N,24139,30264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,24949,28979,30499,N,N,18985,N,N,N,N,N,N,N,N,N,N,20261,N,N,
+24388,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24880,N,N,28735,N,30244,N,
+25398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31302,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20591,N,N,32109,N,N,N,N,N,N,N,N,23876,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,31863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,26175,N,N,N,N,N,N,24109,N,31295,N,N,N,N,N,25969,N,N,N,N,N,N,N,
+27972,N,N,N,N,N,N,N,N,N,N,N,N,N,21029,N,N,32110,N,N,N,30006,N,N,N,N,N,N,N,N,
+24950,24140,N,N,31838,N,27735,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19805,N,N,N,N,N,N,
+N,N,22071,19763,30805,25944,N,N,N,20330,N,N,20304,N,27212,N,N,N,N,27182,27181,
+N,N,21361,N,21285,N,N,N,N,N,N,30543,N,N,N,N,N,N,N,N,28196,N,N,N,N,20516,N,N,
+29218,N,N,N,N,N,N,N,N,N,N,20592,N,N,N,N,29219,N,30584,N,N,N,N,20531,N,N,23337,
+N,N,21307,19052,N,28966,19285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,N,N,19806,N,
+30500,N,N,N,30784,N,N,N,21341,N,19536,N,N,N,N,20262,N,N,N,N,N,N,30323,N,N,N,N,
+N,24951,N,N,N,N,N,21340,N,N,31358,N,N,N,N,N,N,N,31271,N,N,N,N,N,N,N,N,N,N,N,N,
+27481,N,20263,27183,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,25711,N,N,N,26937,29016,N,N,22616,N,N,24690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,26164,23676,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29553,N,N,N,25424,N,N,29307,N,
+23366,20593,N,20594,20316,N,21329,N,N,19505,30552,N,19240,27452,25662,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29788,N,N,23618,N,N,28711,N,N,26176,N,N,19053,N,
+N,N,N,26731,25960,23619,N,N,27998,21362,N,N,N,N,19575,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,20052,26411,N,N,N,19267,N,24881,N,N,30514,N,N,21363,21330,N,30016,N,N,N,
+24413,N,N,28275,26481,N,32052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29256,N,N,N,
+29522,N,N,28276,N,25171,N,N,N,N,19537,N,24426,N,N,N,26938,N,N,N,N,N,N,N,N,N,
+22871,N,N,N,N,N,N,N,N,30029,N,29042,31303,N,N,N,N,N,N,N,N,22904,21570,N,N,N,N,
+30309,N,N,N,N,23877,N,N,N,N,N,N,26482,27999,N,N,19019,N,N,23418,N,N,N,26677,N,
+21286,N,N,N,N,N,N,32053,N,N,31049,N,25698,N,31549,N,N,22308,20037,N,N,N,N,
+20053,22118,N,N,N,N,25917,N,N,N,N,N,N,24141,27763,N,N,28000,N,N,N,N,N,N,N,N,N,
+27756,31550,24427,N,24952,31038,N,N,N,N,20595,24618,26722,N,N,25172,21117,N,
+25896,N,N,N,N,N,22867,N,N,N,N,21342,N,29752,30524,23677,N,26732,25703,N,N,
+25463,N,N,N,N,N,27688,N,N,N,N,N,N,31345,N,N,N,N,N,25970,N,N,20596,21039,23653,
+N,N,N,N,20517,28980,31793,19576,N,N,23878,31313,N,30559,N,N,31272,N,N,N,N,N,
+28277,N,24142,N,N,N,N,26483,N,N,30508,27460,28001,24619,23879,N,N,N,N,21043,
+21055,N,N,N,19020,N,N,N,N,31551,N,N,N,N,25981,23909,22605,N,N,N,N,N,27764,N,N,
+N,N,N,N,N,N,20597,N,N,26733,20562,N,22872,N,N,N,N,N,N,N,N,N,N,N,30310,N,N,
+23338,N,N,N,30560,N,N,N,N,N,N,N,N,N,N,N,N,22617,N,29731,N,N,29789,N,N,N,N,
+28497,N,N,22837,N,N,27947,N,25399,N,N,N,N,28219,19764,N,24691,27213,N,N,N,N,
+27765,26734,N,19241,28975,N,N,N,N,N,N,N,N,19021,N,27689,N,29291,N,32111,N,
+31091,N,N,N,N,N,N,N,N,N,26177,N,N,27736,N,N,N,27948,27214,N,26719,N,N,N,N,N,N,
+N,N,N,N,N,N,N,24143,N,N,N,N,N,N,21030,N,N,26484,20822,N,N,26178,25443,N,N,N,N,
+25648,N,N,N,22580,N,N,N,N,N,N,N,N,N,N,N,N,30245,N,N,N,N,N,29534,N,N,N,N,22309,
+N,N,N,N,30568,N,N,26694,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31590,N,N,N,N,N,N,N,
+23910,N,N,N,23678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,22618,N,N,N,N,N,N,N,23084,27184,N,N,N,N,N,N,N,N,
+25400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18986,24953,N,
+27185,N,N,N,N,29292,N,N,31342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28245,N,
+N,N,N,31092,N,N,21100,31611,N,N,N,32112,N,24637,20067,N,N,N,N,N,N,N,N,N,30790,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,24389,N,N,25918,N,N,N,N,N,N,N,N,N,N,N,N,27949,31338,N,N,19822,27942,N,
+27950,28781,N,23841,N,27951,31864,N,22635,N,N,N,19577,19765,N,N,N,N,31273,N,
+24925,N,N,N,N,25173,27983,N,N,N,23842,N,N,31050,N,27240,N,25965,N,N,N,N,N,N,N,
+N,21355,N,26964,24954,25676,N,24932,26695,N,N,20059,N,N,N,23637,N,30517,31859,
+28787,20015,28981,28498,26696,27505,N,N,N,N,N,19284,24638,25464,27241,31794,N,
+N,N,N,N,24692,N,20320,N,28197,N,N,31274,26179,24882,18987,N,25444,26939,N,N,N,
+N,N,25174,29554,N,28246,27186,20598,27737,23115,20264,N,N,N,N,23843,N,N,N,
+22619,N,31054,26965,25425,N,N,21052,N,N,N,N,N,N,22572,29516,N,19835,30294,N,
+26485,26735,25465,21051,29555,25467,N,24144,20016,N,22135,29017,N,N,N,N,N,
+30017,23620,N,30011,N,24145,23654,N,N,24146,N,N,28002,28278,27215,28782,25468,
+N,21343,21364,24883,N,24884,N,N,N,N,29779,N,N,24390,N,N,N,N,N,N,N,N,N,N,26966,
+N,N,N,23339,N,N,N,N,N,N,N,N,30246,N,N,N,N,N,N,25401,27461,29737,19766,21113,N,
+23085,21091,20305,N,N,N,N,19292,19578,N,20317,N,N,26665,N,25403,25402,N,N,
+24666,N,N,N,28279,N,N,N,N,N,23603,N,N,N,N,21365,N,22310,N,30261,22363,N,N,N,N,
+N,N,24917,N,N,21610,N,24355,N,N,N,N,N,N,N,32095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,20599,27988,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19242,N,N,N,N,N,N,N,
+25691,N,24955,19234,N,N,N,N,21344,N,25663,N,31552,N,23102,25677,N,22073,N,N,N,
+28480,N,24956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30265,N,N,N,N,N,
+N,24391,N,N,N,N,N,N,N,25649,N,N,N,N,N,N,23655,23656,N,N,N,31318,N,21366,N,N,N,
+N,29018,N,31346,25213,N,N,N,N,N,21839,20600,N,N,19807,N,N,30027,N,25712,19243,
+N,22340,N,N,N,N,N,N,N,N,N,N,N,N,N,25214,N,23898,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23086,19054,N,N,N,21817,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25377,N,N,26723,N,N,29483,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,20265,N,N,N,21367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+21617,N,N,20068,N,26738,N,N,N,N,N,N,N,25973,N,N,N,N,N,N,N,N,N,N,N,N,N,26414,N,
+22074,N,24428,25664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26724,N,N,N,N,22581,N,N,N,
+25692,N,N,N,N,N,N,29753,28982,N,N,25182,24885,N,N,19823,28967,20069,19293,N,N,
+22883,N,N,29484,N,N,20601,27691,24147,30569,N,N,31093,N,N,N,N,N,24926,19310,
+25404,30806,N,N,23406,N,N,N,N,N,32113,N,N,N,N,30518,N,N,N,N,29790,N,N,29293,N,
+23385,N,28712,N,N,N,N,N,N,N,24957,N,N,N,N,N,24148,N,24620,N,N,N,N,N,28003,N,N,
+21345,N,24392,N,N,N,N,22838,N,32044,28499,N,N,N,25665,30827,N,23340,N,N,N,N,
+31814,N,N,N,N,N,N,N,N,22573,N,N,N,N,N,N,N,N,N,30266,N,23391,21331,30791,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,19022,30785,21044,N,N,23604,31289,19023,N,31795,27242,
+27243,20602,N,N,N,N,N,28004,N,N,23911,N,N,24393,N,N,N,N,24429,N,N,N,N,N,28220,
+N,28481,N,N,19538,N,23844,N,N,N,24394,N,N,N,N,N,21368,28968,N,N,N,19767,N,
+28500,N,N,N,N,N,N,N,25693,24430,19244,26940,N,N,N,N,N,27244,N,N,N,24395,N,N,N,
+N,N,31039,22063,21830,N,N,N,N,N,20266,N,N,20009,N,N,22136,N,N,N,28983,28280,N,
+N,N,22873,29535,N,30792,20038,N,N,N,N,N,N,N,N,21862,N,N,N,N,N,N,29798,N,N,
+26181,28501,N,N,19311,31839,23591,N,N,22119,N,N,N,N,N,30793,N,N,N,N,25426,N,
+25405,N,20321,28736,27738,N,23895,31600,N,N,27692,N,N,N,28713,N,N,N,N,N,N,
+31319,31553,N,21056,N,N,N,N,N,N,N,25904,N,N,N,28005,N,N,N,N,19245,N,31024,N,N,
+N,N,N,N,N,N,N,N,N,30501,N,19246,N,23087,N,22582,N,N,N,N,N,N,N,21287,31538,N,
+32068,N,27693,N,N,N,N,N,N,31521,N,N,N,25961,26990,N,29556,30835,28737,24111,
+30768,N,N,29536,26415,N,N,N,N,N,23341,N,26165,N,N,31016,N,N,23896,26713,28502,
+N,N,N,21346,N,25183,N,N,31840,22344,32045,N,N,N,24431,19539,21369,N,N,N,N,
+21616,23367,24149,N,N,N,N,28788,N,21840,25945,N,N,N,N,N,N,31815,23638,25184,N,
+N,N,23088,N,N,N,N,N,N,29475,N,21356,N,29771,N,N,N,32069,N,N,N,N,N,25469,N,
+31025,N,N,N,N,N,N,20603,27739,N,N,N,N,N,N,N,N,30012,29220,22606,22607,N,N,N,N,
+N,N,30071,N,N,N,N,N,N,N,N,N,N,30305,N,N,N,N,N,N,N,N,N,21047,N,N,N,N,N,N,N,
+31596,N,23880,25704,N,N,21057,N,N,N,30807,N,N,N,N,N,22075,24150,N,N,30525,
+27694,N,N,N,20577,N,24693,27187,N,20054,N,N,N,N,19493,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,27766,25185,25406,N,N,N,N,N,N,N,N,N,31816,N,N,19824,N,31094,N,N,
+24432,N,N,N,25919,N,N,N,20031,N,N,N,N,31841,27952,32081,30267,N,N,31055,27482,
+19009,N,21048,19825,N,25427,32102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+26221,N,N,N,25466,N,N,28714,31056,N,N,N,N,N,N,31842,N,30759,N,N,N,24933,28281,
+N,N,N,26486,27245,N,N,31796,30018,N,N,22364,N,N,N,N,N,N,N,N,28789,N,23912,
+21357,30076,N,23103,N,19579,N,N,N,21370,29732,N,N,N,N,N,N,N,28503,N,21571,N,N,
+N,N,N,N,N,N,N,31587,N,N,N,N,N,N,N,N,31597,N,24621,N,N,27246,31539,25666,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,30311,21085,N,24396,N,N,31817,N,N,25897,24694,30259,
+24958,N,N,N,N,19312,N,27247,27248,N,N,N,23104,30772,27506,N,N,N,N,N,25667,N,N,
+N,N,26967,25713,N,N,N,19055,N,N,N,N,N,N,N,20055,N,N,N,N,N,N,N,N,31818,N,N,N,
+29537,N,N,19268,N,N,N,N,25445,N,19269,27188,N,N,26941,N,22345,N,N,27483,27953,
+N,19523,30526,31819,N,N,N,N,N,N,30836,N,22839,N,N,29523,29524,N,N,N,30564,N,
+30545,N,N,22583,20017,19010,N,N,31540,19270,N,N,28790,N,N,21863,N,27216,N,N,N,
+N,N,19540,19247,N,N,N,N,N,29738,26927,N,N,30019,26968,N,N,N,N,N,N,N,23913,N,N,
+N,29043,N,21883,24123,N,N,29819,N,N,N,32115,32114,30502,N,N,N,N,N,N,N,N,N,
+23881,N,N,21587,N,19496,N,23105,19541,N,22884,N,N,N,31306,N,N,N,25955,N,N,N,
+21308,N,N,N,19056,N,N,N,N,20548,N,N,N,19024,31275,27499,26488,22885,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20823,N,N,N,N,N,N,N,N,N,N,N,29476,N,
+N,N,21627,31843,31320,N,29525,N,20267,N,N,27507,21884,N,N,N,N,N,N,21332,19836,
+N,22886,N,25209,25121,27476,N,24695,25650,19580,N,N,N,31588,N,N,N,29739,N,N,N,
+N,20541,N,19057,N,N,N,N,N,N,N,N,28472,N,N,N,22336,N,28282,32116,N,N,21347,N,
+31554,N,N,N,N,N,N,N,21864,23342,24886,30775,N,N,N,N,N,24639,31555,23914,N,
+25122,N,28198,N,N,N,N,N,30312,N,N,N,N,30325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,23882,N,N,20578,N,N,N,N,23846,N,N,23915,N,N,25721,N,N,25391,20604,N,N,
+N,29820,N,N,N,N,19516,30570,N,N,N,N,N,N,25956,24433,N,N,30561,N,31095,28473,N,
+N,30808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31017,N,N,N,N,N,30809,N,N,N,28221,N,N,N,
+22598,N,N,25699,30030,N,N,N,N,23897,N,N,N,N,22887,21049,21827,N,N,23141,23120,
+N,20825,20056,N,19294,29740,23163,N,30313,26739,20268,28784,N,29821,23368,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,20032,25428,20815,29045,N,19826,N,20331,N,N,N,19768,
+N,N,N,N,N,N,25382,20826,29221,N,N,N,N,N,29222,N,25678,N,N,N,N,N,N,N,21371,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28969,N,N,N,29257,N,N,N,N,N,N,N,
+N,N,N,28504,26185,N,22584,31347,N,N,N,N,N,N,N,N,N,N,29493,N,N,30756,N,N,20851,
+26184,N,N,N,N,30810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23657,24151,N,N,N,N,N,
+19295,N,N,N,20332,N,N,N,N,29791,N,N,20852,21050,N,N,N,24434,N,N,N,24887,N,N,N,
+N,25123,21372,N,N,28006,N,N,N,N,N,23369,N,N,N,25722,N,20318,N,N,20048,N,N,N,N,
+21843,29557,30510,N,N,28488,N,19827,30031,25971,28738,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,19025,N,N,N,27249,N,20518,N,N,N,N,N,N,N,N,22874,28715,N,N,N,
+N,N,27495,N,N,N,25920,31797,N,N,N,N,N,25668,N,N,N,N,N,N,N,N,N,N,N,19497,32070,
+N,N,N,N,N,27189,N,25898,24378,24927,N,23121,N,N,N,N,24888,N,26740,21373,N,N,N,
+N,25124,N,N,N,N,N,29258,N,N,N,N,N,N,N,N,N,23142,30515,N,N,N,N,N,N,N,N,N,N,N,N,
+32077,N,N,N,29494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28247,N,N,
+N,N,N,N,N,30020,N,N,N,N,N,N,N,N,22564,N,N,N,N,N,29223,N,N,N,N,N,N,N,N,22840,
+22841,28489,N,N,N,N,N,N,N,N,N,N,N,N,N,22094,N,N,N,N,N,N,N,N,30539,24366,26741,
+N,N,N,N,N,N,21045,N,N,N,21333,N,N,N,N,N,29772,23164,N,N,N,N,N,22888,N,30571,
+30025,N,29500,N,23122,N,N,N,N,N,N,N,N,21301,N,N,N,N,N,26678,N,N,22095,29754,N,
+30537,N,N,19498,N,N,28739,19542,N,N,N,20563,N,21309,N,N,N,23419,N,19296,N,N,N,
+N,N,N,21348,30327,N,N,21818,29517,19297,N,N,N,N,27508,N,N,N,N,N,29741,N,31786,
+N,N,N,N,N,30572,N,N,N,26742,23143,N,N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,25921,N,N,N,N,24686,N,N,N,N,N,21885,N,N,N,N,N,N,20070,31787,21819,N,N,
+29224,N,N,N,N,N,N,25125,19769,27250,19271,N,19828,N,N,23343,28505,N,N,N,N,N,
+19770,N,N,31865,N,N,N,N,24435,20071,23106,N,20269,N,N,N,N,26489,30760,N,N,N,N,
+N,N,29538,N,N,N,19058,24356,N,N,21572,N,N,N,N,N,19543,25922,N,N,N,N,19771,N,
+28506,28248,N,23847,25126,N,N,N,N,N,24640,N,N,N,22064,30794,N,31866,N,22910,N,
+N,N,N,24112,N,N,N,23916,23144,N,N,N,N,N,21600,N,22137,N,19799,24152,N,N,29304,
+N,25686,N,N,20549,29742,N,23848,N,N,N,27973,29526,N,N,24153,25446,N,N,N,N,N,N,
+21288,N,23344,N,N,25946,25407,N,N,N,23345,N,N,N,21865,N,N,N,N,N,24641,28507,N,
+N,28777,N,N,22322,N,N,N,N,20605,N,N,N,N,N,N,N,N,22889,N,N,20606,N,27757,21289,
+N,29225,28740,N,N,25186,26991,N,N,N,31057,N,N,26969,N,N,N,N,N,26714,23107,
+23108,21573,N,26490,19808,25392,N,23346,31556,N,29539,N,22821,31591,23883,
+20564,N,26166,24622,32090,N,N,N,N,N,N,N,N,23605,24696,26417,N,N,N,N,30064,N,
+22620,27974,N,N,N,N,24889,N,25408,31040,26992,N,N,22875,N,29540,N,N,N,23606,
+25705,N,N,N,N,N,28741,25409,31820,31821,N,N,N,N,29259,N,29260,N,N,N,25679,N,N,
+N,N,N,N,N,N,N,29019,N,31321,N,28984,32117,24697,N,N,N,N,26491,31799,31844,
+31557,25447,22585,N,30328,N,N,23621,19544,N,N,N,24623,29799,N,28508,20348,
+28509,N,29226,N,N,N,N,N,N,N,N,N,32062,N,N,18988,32059,32071,N,N,N,N,26418,N,
+27217,24436,N,N,N,N,20844,25694,25923,N,N,N,N,22822,N,N,19772,N,29541,N,N,N,N,
+N,N,N,N,27989,N,N,22842,N,N,N,28007,31541,30828,N,N,N,N,24679,N,19545,N,N,
+21574,N,N,N,N,N,26405,N,21877,21310,N,31867,N,N,N,N,N,N,N,N,N,N,N,N,25714,N,N,
+24437,N,N,26744,30829,N,N,20039,N,N,N,N,N,32118,N,N,N,N,N,N,N,N,N,26712,N,
+19800,26454,19546,N,N,19043,24438,28743,28742,N,22586,N,29044,29808,30028,N,N,
+31845,N,N,N,N,27205,27251,N,23899,N,23639,N,N,N,N,N,N,24189,29305,N,21831,N,N,
+N,22608,N,28744,20769,20770,N,N,N,N,N,N,22868,22120,22858,N,23089,22599,23650,
+29518,30068,N,N,28985,N,N,23123,N,30314,N,N,N,20341,N,N,32046,N,N,N,N,N,N,N,N,
+19026,N,N,24372,N,N,N,N,22365,31290,28199,30013,N,30837,N,N,28008,N,N,N,N,N,
+21601,N,20771,24918,N,N,N,N,N,N,N,N,N,N,N,N,N,31096,N,23370,19321,21588,N,
+22876,N,28222,N,30573,N,N,N,21102,N,N,24934,30585,N,N,N,N,N,N,N,23917,N,26715,
+N,23347,N,N,N,20855,24624,N,N,21602,N,30295,N,22393,N,N,22621,N,19837,29227,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19773,30786,N,N,29228,N,N,18989,18990,20270,N,
+N,N,N,N,25410,N,N,N,N,N,23607,N,N,N,N,N,N,N,N,N,N,23386,22843,19059,30291,
+26232,27253,N,N,N,N,N,27254,N,N,30329,N,N,N,N,N,N,N,N,N,N,N,20271,N,N,19027,N,
+N,18991,21040,28986,N,22323,25411,29565,24154,N,N,N,N,24155,N,N,28510,25187,
+28283,N,N,24439,22346,N,N,N,N,N,N,N,N,N,20072,23387,N,N,N,N,N,N,N,28987,N,N,N,
+N,26993,N,N,N,N,N,N,N,N,31287,20550,N,N,19499,28200,N,N,19322,31097,19581,
+21374,N,N,N,N,25680,N,N,N,N,N,29294,N,21589,24397,N,31800,20816,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29261,N,N,N,N,N,N,N,N,30546,N,N,N,N,N,N,N,N,
+19028,N,21849,N,N,N,22622,N,N,N,N,N,N,N,N,N,19801,N,N,N,28201,30268,N,N,19547,
+N,N,N,N,N,28745,N,31868,N,26697,29822,N,N,N,N,26492,22366,N,N,N,N,24156,N,
+28716,19582,19809,N,24890,N,23407,23090,N,N,N,N,N,N,N,N,N,N,N,N,N,20773,23608,
+N,N,N,22646,N,20772,N,19810,N,N,N,N,23658,N,N,28791,N,28746,20542,N,23900,N,N,
+N,N,21590,21334,N,N,N,N,N,N,27984,19745,N,N,N,N,N,24373,N,N,N,24440,N,N,N,N,N,
+N,21537,20018,26698,N,N,N,N,27509,N,N,N,N,N,N,N,25429,30032,N,N,N,29985,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22823,N,N,N,N,N,N,N,N,25899,N,N,N,N,N,N,N,N,
+N,N,N,N,26187,N,30065,N,N,N,N,N,N,N,N,N,N,25925,N,N,N,N,N,N,N,N,31011,24667,
+30315,N,19313,N,22890,29986,N,N,N,22353,N,20856,27256,27257,23091,N,N,N,N,
+28511,N,N,29039,N,25974,28223,25188,N,N,N,N,N,20543,N,31276,30033,26419,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26942,N,N,N,N,N,29262,23348,N,
+N,N,N,N,N,N,N,31822,N,23918,N,N,N,N,N,N,26420,N,N,N,N,N,22324,N,N,N,N,N,N,
+30516,N,N,N,N,N,19774,N,23145,N,N,N,N,N,N,N,20272,30553,29542,N,N,20057,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20010,N,19272,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,20519,N,28747,N,20551,25669,N,N,N,N,N,N,N,23392,N,N,N,N,N,N,21850,N,
+22311,N,N,N,28224,N,30838,N,N,N,N,30034,28009,N,22844,N,25926,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,29987,N,N,23124,25127,31612,N,N,29020,N,N,N,N,N,N,19060,N,N,
+N,26746,N,N,20073,N,N,N,N,N,N,27000,25189,N,N,N,N,20537,21618,N,N,N,N,N,20774,
+N,24398,N,N,N,N,N,N,N,N,N,31860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21290,
+N,N,N,19500,N,N,N,N,28512,N,N,N,25957,20565,N,N,N,N,N,N,N,N,23420,N,N,N,N,
+31846,N,N,N,N,N,19326,28010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24113,N,N,N,N,N,N,N,
+31075,N,N,N,N,N,N,21538,20342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22096,N,N,N,N,N,N,
+21866,29038,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31307,N,N,N,N,
+25889,21809,N,N,N,N,N,20333,N,28011,N,N,N,N,N,21810,N,N,N,21820,N,N,N,N,N,N,N,
+N,N,32098,29485,N,32091,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26928,N,N,N,N,N,N,N,20775,
+N,N,32099,20019,N,N,N,N,N,N,N,32100,31310,N,N,N,N,18992,N,30503,N,20273,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,26146,N,31798,29229,28513,29486,23622,22891,N,N,N,26720,
+N,N,N,N,N,N,N,24872,N,N,N,N,21878,20349,N,N,24157,N,N,N,22865,N,N,N,25706,
+29263,N,30527,N,N,25190,25128,N,N,N,N,N,N,N,N,N,N,N,25430,N,27985,N,N,N,N,N,
+27001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22065,24114,N,N,24680,N,N,21291,N,27484,N,
+N,24367,N,19011,N,N,28284,N,32067,N,N,N,27510,20274,N,N,N,N,22892,N,22845,N,
+22623,N,N,21560,27454,23919,N,23920,23921,23922,N,N,22846,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,31558,20275,28285,N,N,N,N,N,N,25643,N,23109,N,22636,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,20776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25129,N,N,24124,26421,N,N,
+N,N,N,23408,N,28514,29040,20276,N,N,N,N,N,N,N,N,N,N,N,23409,N,24625,N,N,N,N,
+24357,N,31058,N,N,26493,N,N,26147,31601,19248,29230,N,N,N,N,N,N,N,19815,N,
+26716,N,N,26455,N,N,30528,N,20579,N,N,N,23073,N,N,N,19517,N,N,20777,23884,N,N,
+25470,20778,26666,N,27190,31098,26188,30296,N,N,N,21575,N,N,N,22859,N,22866,
+21323,22647,23081,30072,N,N,24158,29231,30761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+22600,N,N,28225,N,N,N,N,31041,N,N,N,N,23923,27258,N,30269,24891,19775,29780,
+26189,N,31823,31522,N,24668,N,N,N,N,29755,23125,N,31026,N,N,N,N,N,N,31602,N,
+23414,N,24159,N,N,N,23410,N,N,N,N,N,30812,30574,27496,N,21114,N,N,28988,N,N,
+31322,N,N,23146,23110,30529,N,N,26422,25927,22060,N,N,N,N,23623,N,N,N,N,N,
+24873,N,25130,N,21798,N,N,21591,N,N,N,N,N,N,29264,N,27259,N,24669,31603,N,N,N,
+N,N,N,N,28989,N,N,25191,32087,N,20040,27191,N,31808,N,32103,30575,N,N,22325,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28474,29021,N,24115,N,N,N,N,N,N,
+26699,N,N,30813,N,N,31559,21832,N,22367,N,23849,N,N,N,N,N,26929,N,N,31277,
+30297,31348,N,N,N,N,N,30762,N,N,N,N,N,26222,N,19548,24892,24687,N,N,26943,
+31869,26190,N,N,24919,N,26191,N,29809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,25715,N,N,25723,N,N,31076,N,N,N,N,N,N,N,N,N,N,28515,N,N,20334,30270,
+24626,31870,20779,N,N,N,22394,N,N,N,31560,N,25175,N,N,N,N,N,N,21539,28792,
+22312,N,N,N,24935,N,N,21311,N,N,N,N,N,N,28516,N,22341,27490,N,N,31847,N,N,
+25634,N,25192,N,26192,N,31592,29800,25972,29756,29781,24374,N,31801,28226,
+19061,N,N,N,28517,19298,21540,N,24160,23165,25670,26686,N,N,N,N,24670,30260,
+27218,N,31099,N,N,24642,N,19044,N,26423,N,27261,N,22877,N,23092,28202,31593,N,
+N,N,N,23371,23093,N,N,N,N,N,28990,N,N,21292,N,N,N,N,N,N,N,N,31561,N,24399,N,N,
+21312,25431,N,28518,31824,N,N,N,N,N,N,N,26944,N,N,N,30035,N,N,27740,30519,N,N,
+27192,20857,N,N,N,N,N,N,23624,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27193,
+N,N,N,N,N,29022,N,N,N,N,N,22326,20277,N,22824,N,N,27758,N,N,23850,N,N,N,N,
+19746,26670,N,N,N,24893,N,29265,N,N,N,N,26945,N,N,N,21116,N,N,N,N,N,N,N,23349,
+N,29543,22654,N,N,N,31825,N,27954,29743,N,31523,N,N,31809,N,28203,21541,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29810,N,N,N,N,28249,N,N,N,31562,
+N,N,N,N,N,19811,22587,25947,30839,N,N,N,30292,N,N,N,N,N,N,N,N,22313,N,19273,N,
+N,26193,28748,N,N,N,N,N,N,N,N,N,N,22574,N,31059,21886,N,N,N,N,N,N,N,22588,
+29232,N,N,N,N,25131,29544,N,N,N,N,N,28482,N,N,N,N,N,N,28012,N,26424,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,23166,N,N,19518,N,N,29308,23147,N,25176,27990,N,N,22097,
+24627,N,N,31826,N,27464,N,N,N,N,N,N,N,N,21313,28749,N,20343,N,N,N,N,N,N,N,N,N,
+27986,N,21592,23625,22385,N,N,24379,N,N,29477,N,N,N,29773,N,N,N,N,28991,30769,
+N,27002,N,N,N,31563,N,N,19029,N,N,N,N,N,N,N,N,N,N,N,31060,30538,N,N,22088,N,N,
+N,N,N,N,31848,29501,N,28286,N,26494,N,N,N,N,N,21314,N,N,N,N,21302,N,19501,
+30330,22066,21080,N,N,N,N,N,N,26456,N,N,N,N,N,N,N,N,N,N,25381,N,N,N,N,26425,N,
+N,N,N,28717,31564,27425,N,N,21542,N,N,N,N,31565,N,21821,29023,N,N,30331,N,
+24116,N,N,N,N,N,N,N,N,N,N,N,N,21867,25928,N,N,N,31524,21561,N,N,24161,N,25635,
+N,N,N,22327,N,30830,N,N,N,24117,N,N,22098,N,31061,26426,27477,21879,28519,
+24894,N,N,N,31278,N,N,N,22121,22126,N,N,N,N,N,N,26427,N,N,N,N,N,N,N,27723,N,N,
+N,N,N,N,21811,N,N,N,N,N,N,N,N,N,N,N,N,N,20020,N,N,N,31525,24942,N,N,N,N,N,N,
+30504,N,N,N,N,31566,N,N,N,N,N,22589,N,N,N,N,N,N,N,31613,N,N,N,N,31849,N,N,N,N,
+N,N,N,20278,N,N,N,27975,28204,N,N,N,N,N,N,N,19549,N,N,N,N,30247,N,N,N,26234,N,
+N,N,29988,N,N,N,N,N,32092,27955,20041,N,N,N,N,N,N,28520,N,N,24895,N,N,N,N,N,N,
+31323,19299,30505,N,31526,N,N,N,23609,N,N,N,28992,27976,28483,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,22061,N,N,32078,N,N,N,26657,N,N,N,N,N,N,N,N,31604,21799,N,N,N,
+29046,N,26195,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19550,N,N,N,N,N,N,N,30770,N,N,
+N,23659,32054,N,N,N,N,25962,N,N,29024,N,N,N,N,N,N,N,N,N,N,N,N,23372,23885,N,N,
+N,21576,N,N,22893,N,N,N,N,29989,N,N,N,N,N,N,N,N,N,26235,N,N,N,N,N,26196,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,32072,N,22049,32063,N,31827,N,28449,N,26428,N,N,N,N,
+N,20846,N,N,26197,N,N,26994,N,24368,N,N,N,N,N,22624,31802,32047,28750,N,23393,
+N,N,25929,N,27956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24643,N,N,N,N,N,N,25432,N,N,N,N,
+27003,27176,N,N,N,N,32055,N,N,31527,N,26946,N,N,N,N,32119,N,N,N,N,N,25177,N,N,
+23660,N,N,N,N,N,N,N,N,N,26658,N,N,N,N,26224,N,N,N,N,N,N,N,32120,32121,N,N,N,
+30271,N,N,26407,N,26199,N,N,N,N,21619,21577,N,N,N,N,22138,N,22386,N,24896,N,
+23394,26200,N,N,N,N,N,N,N,N,N,26429,N,N,N,N,N,28751,29502,25132,N,N,N,N,N,
+30007,24688,N,N,N,N,N,N,N,N,N,N,N,N,32056,25448,N,21543,26748,31314,N,N,N,N,N,
+30831,N,N,N,N,N,N,N,N,N,22099,N,N,N,N,N,N,N,N,N,N,21812,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,28752,N,30576,28211,N,N,27194,N,27219,N,N,27977,23851,N,N,N,25900,32033,
+N,24400,27699,N,24401,N,N,N,N,N,28013,30776,30586,N,N,N,30763,N,N,N,N,N,29792,
+N,N,N,N,N,21562,25651,N,26970,N,24118,N,22847,N,22848,22127,N,N,N,N,22860,N,
+23082,N,N,N,N,N,N,N,N,24421,N,N,N,N,N,N,30565,N,N,N,19506,N,N,24441,22368,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21563,N,N,N,N,
+32122,N,N,N,N,19507,N,N,23411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24402,N,20042,N,
+28250,N,N,N,N,N,N,N,N,N,25700,N,31567,N,N,N,N,N,N,20279,N,28227,N,N,N,N,N,N,N,
+20074,N,N,N,N,N,N,N,25133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22369,31349,N,N,21833,
+30764,26457,N,N,N,N,N,N,N,N,N,N,N,29545,N,N,N,N,22637,25412,28785,N,N,N,N,N,N,
+N,26725,N,N,N,24698,28228,22878,N,N,N,N,N,N,N,N,N,N,27426,27427,N,N,N,N,N,N,
+31810,27195,N,N,N,N,26667,24162,N,N,N,N,N,N,N,N,N,N,28015,N,26659,N,N,N,N,
+20337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21564,N,31850,N,N,N,N,N,26430,N,31858,N,
+N,22068,N,N,25134,N,21303,31308,N,N,N,N,N,N,N,N,31324,N,27957,24931,N,26668,N,
+26717,N,N,28521,N,N,N,N,N,29757,N,20280,26971,20780,N,N,N,N,N,N,23111,N,N,N,N,
+N,N,N,27465,N,26700,N,N,N,24119,N,N,N,N,22076,21349,N,N,N,N,N,31325,N,N,N,N,N,
+N,23126,N,18993,N,N,N,N,N,N,23112,24358,N,31027,29266,N,19012,N,N,N,N,N,N,
+20043,N,N,19829,N,N,N,32048,21800,N,28993,N,N,25193,23626,27700,31296,N,N,
+31528,20520,N,N,23148,N,N,N,N,N,N,N,N,N,22894,N,24699,N,N,N,28522,31326,24644,
+N,20281,N,21834,22370,25135,N,22328,N,N,N,N,N,N,N,N,N,26701,N,N,N,N,N,N,N,
+30298,N,N,N,N,28450,25178,30332,N,N,31568,20781,N,19812,N,20782,23661,26702,N,
+28793,20021,26236,N,N,22395,20566,23925,30577,N,30333,N,23415,N,N,N,N,31594,
+26972,22849,N,30066,24645,N,N,N,N,N,N,27220,N,N,N,N,N,N,N,N,N,31042,N,27196,N,
+21061,31569,26432,27429,N,24442,25378,22329,N,26947,N,26749,26671,N,N,29267,
+31529,22565,N,N,N,N,21835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20552,N,N,N,20783,22371,
+N,N,N,24646,N,22050,N,28016,N,N,N,N,N,N,N,N,N,N,N,N,22387,N,N,N,31828,N,23127,
+19551,N,29268,N,20784,N,19552,N,23421,29503,N,28753,N,N,N,N,N,31803,N,25136,N,
+N,26149,N,N,N,25179,N,N,N,24414,N,24647,N,N,N,N,N,N,29295,N,N,N,19553,N,N,N,N,
+22122,N,N,N,N,26434,N,N,N,20022,N,29504,N,19838,N,N,N,31570,N,30840,30587,N,N,
+26687,N,N,N,N,N,N,N,26679,N,N,N,N,N,N,N,N,27958,23610,N,N,19508,N,N,N,N,N,N,N,
+N,N,N,N,N,29047,N,N,N,26680,N,N,19062,N,25636,29782,N,N,N,24422,N,N,N,24359,N,
+24423,24897,N,26948,N,N,23627,26949,N,N,N,28451,27430,19235,25449,N,N,N,20859,
+28452,N,28523,N,N,N,N,N,N,N,N,N,N,N,N,20532,N,N,N,N,19747,N,N,26726,N,28453,N,
+21324,23149,N,N,N,N,22330,N,29269,30053,22895,N,N,N,N,31028,N,N,21844,32079,N,
+N,N,23395,N,N,N,N,29025,27702,N,N,N,N,31614,21335,N,20785,N,19249,N,N,N,N,
+20786,N,N,N,N,N,N,19250,28994,N,N,29793,31029,N,N,24899,24898,N,27511,N,N,N,N,
+N,N,N,N,N,N,N,24360,N,N,N,N,N,N,N,19274,N,N,N,N,N,26169,N,N,N,N,N,30814,31018,
+19063,N,27959,N,N,21304,29270,N,N,21593,28229,29296,N,N,N,18994,N,N,23611,N,
+29048,N,N,N,N,N,27703,N,N,N,N,25930,N,30272,32093,N,N,21603,19554,N,30548,N,N,
+N,N,N,N,22373,N,N,N,N,N,N,N,N,N,N,N,N,N,21315,N,22566,N,30273,N,N,N,N,N,23926,
+N,19776,25948,N,N,N,N,N,N,N,N,N,N,N,N,25931,N,N,N,N,N,N,N,N,N,N,N,24900,N,N,N,
+N,N,26672,29744,29546,23150,N,22331,N,25137,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,22314,N,N,N,N,N,N,22139,N,N,N,N,N,N,N,N,N,25695,N,19030,N,N,N,27432,N,N,
+N,23422,N,N,N,N,N,N,N,N,N,N,30274,N,N,28475,N,N,N,N,21629,N,N,24648,N,N,N,
+26681,N,28454,N,N,N,N,N,19748,N,N,21620,23329,23388,23389,N,N,N,N,N,28252,N,
+19275,31829,N,N,N,N,N,N,20075,N,19777,N,N,31571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,31019,N,N,N,N,N,N,N,N,N,N,N,30036,N,N,N,N,22825,N,N,
+26973,23373,N,N,23886,N,26435,N,27724,N,N,N,N,N,N,N,31084,N,N,N,19276,N,N,N,N,
+24700,21544,N,27987,22639,N,29271,N,19064,23151,N,N,22100,N,N,N,N,N,N,22861,N,
+N,N,22638,N,29249,N,N,N,24403,N,N,N,23152,N,25194,24701,N,N,22648,N,N,N,30511,
+23094,N,19031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29272,N,22649,N,N,N,N,N,N,N,
+N,31327,N,N,N,N,N,N,N,N,N,N,N,N,N,20335,22850,N,28754,N,25681,N,N,N,29495,N,N,
+N,N,N,N,N,N,N,N,N,N,31328,N,N,N,N,N,N,N,N,N,N,N,N,N,28524,N,N,N,N,N,25138,N,
+21565,N,N,22862,N,N,N,N,29794,N,N,N,N,N,N,N,N,N,N,N,N,N,21545,N,N,N,N,19778,
+26458,N,N,N,N,N,N,N,N,N,N,N,29273,N,N,N,N,N,22826,N,N,N,N,N,N,N,N,N,N,N,N,
+22590,N,N,N,N,N,N,23597,N,N,N,N,N,N,25195,22140,N,N,19065,N,N,21594,N,N,N,N,N,
+N,N,29783,19489,N,N,20282,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30008,
+N,N,N,22851,20584,N,N,N,N,N,25413,27512,N,29233,N,N,N,20283,N,N,N,21293,26721,
+20076,N,N,N,24628,24163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23927,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,29234,29558,30299,N,N,N,N,22398,N,N,N,N,N,30815,N,30578,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,20521,N,N,N,N,N,N,N,N,N,26202,N,N,N,N,N,N,N,N,N,N,
+N,N,N,29990,N,N,N,N,N,N,N,N,N,N,N,N,N,22332,19555,N,N,26203,N,N,N,N,N,N,N,N,N,
+N,N,N,23901,N,N,N,N,20787,N,N,N,N,N,28525,N,N,N,N,22110,25716,24943,N,N,23928,
+N,N,N,N,N,26703,N,N,N,N,N,N,N,N,N,N,N,19045,N,N,N,23585,N,24629,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,31788,31789,22567,N,N,N,N,27960,N,N,N,23350,N,N,N,N,22128,
+29487,N,N,19749,N,23153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22568,N,
+N,N,19556,N,N,20788,N,N,N,N,N,19032,N,N,N,N,N,23154,29991,N,N,N,N,N,N,N,N,N,N,
+N,N,29992,N,N,N,N,N,N,N,26150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21868,
+21880,23155,N,N,N,N,N,N,N,N,N,N,N,N,N,25414,N,N,N,24164,N,24165,20789,N,N,N,N,
+N,20790,20791,29235,N,N,N,N,N,N,26974,N,N,N,N,N,28755,29236,N,N,28756,19300,
+31572,30054,25450,N,24166,N,N,N,N,24404,N,N,30841,N,N,N,N,28718,N,N,N,N,N,N,N,
+N,N,N,N,N,20792,N,N,N,N,22111,N,20567,N,N,N,N,N,N,N,N,N,N,N,31777,28526,23640,
+N,26975,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25949,32123,N,N,24649,N,N,N,
+22089,N,N,21546,N,25932,N,N,N,N,N,26976,N,N,N,20568,31778,21566,25139,24167,N,
+N,N,N,N,N,N,23612,21046,30037,N,N,N,N,N,20001,29993,N,N,23929,N,N,23930,N,N,N,
+N,N,N,28757,N,N,N,N,30303,N,29274,25707,N,29297,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,27705,32124,N,N,N,N,24874,N,N,19033,N,N,28527,N,29994,N,N,N,N,N,N,27769,N,
+N,30765,N,29250,30275,N,22354,N,N,31010,28758,N,N,N,N,N,N,N,N,N,N,N,N,N,28794,
+N,N,30304,N,N,N,N,26995,29251,N,N,N,21547,18995,19750,N,19779,19802,N,N,N,N,N,
+22863,N,N,30276,N,N,N,28253,26436,N,N,N,N,N,N,N,N,25140,N,N,N,N,N,N,N,N,N,
+24418,26459,N,N,N,N,N,N,26673,N,31790,N,N,N,N,25933,N,N,N,31339,N,20284,N,N,
+20322,19830,N,N,28528,N,29758,N,21581,N,N,29496,N,N,N,26913,N,N,N,N,N,N,N,N,N,
+29298,29547,N,28759,N,N,20311,N,N,N,N,N,N,20319,N,N,N,N,N,N,N,N,N,26688,26689,
+N,N,N,20323,26914,N,N,N,N,N,N,N,N,N,N,20522,N,N,N,N,N,N,N,N,N,29505,20523,N,
+21604,N,N,28476,22561,N,N,N,N,N,N,N,N,N,N,N,22879,N,29527,N,N,N,23613,N,19557,
+28017,N,N,29026,N,21595,N,N,N,N,25141,N,N,19046,N,21294,N,N,N,N,N,N,19558,N,N,
+29011,30055,N,N,N,N,19034,31598,N,24901,N,N,N,N,N,N,N,24425,N,28254,N,N,30530,
+N,22562,N,N,N,N,N,23852,N,N,N,N,N,28719,22077,N,N,N,N,N,N,N,N,N,N,N,24875,N,N,
+N,N,N,N,N,N,N,N,N,N,31030,N,N,21621,N,20553,28455,25196,N,23402,20044,30056,
+30549,N,21325,N,29566,N,N,N,N,N,N,N,N,N,20533,N,N,N,N,N,N,N,N,N,N,N,24702,N,
+24443,N,N,N,N,N,N,26205,N,N,N,N,N,N,N,26660,N,N,N,N,N,N,N,N,N,19277,N,N,N,
+28456,N,N,N,28212,N,N,N,N,23128,20793,N,24361,N,N,29488,N,N,19524,N,N,N,20023,
+N,N,N,N,N,N,N,N,N,N,N,28457,N,N,N,24405,N,N,27991,N,N,N,28230,N,N,N,N,N,N,N,
+28477,31830,N,N,23412,N,28458,30777,N,30057,N,N,N,N,N,N,N,N,25433,N,N,N,N,N,N,
+N,N,N,N,N,N,N,24902,N,N,N,21567,N,N,N,N,24168,28778,N,N,N,N,N,N,N,N,N,N,29506,
+N,N,N,N,N,N,N,N,N,N,N,21295,N,N,19035,N,N,N,N,N,31831,N,N,27992,24903,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,29784,22067,23853,N,N,N,21822,N,N,N,N,N,N,N,N,28995,
+28255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22123,N,N,N,29785,N,N,N,N,N,N,N,
+22374,N,N,N,N,N,N,23095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23931,N,N,N,N,N,23887,N,
+N,N,N,N,N,N,N,22563,N,N,23129,N,28760,28484,N,N,N,N,N,N,24920,N,N,N,N,N,29012,
+N,28018,N,N,N,N,N,N,21851,N,N,21852,29508,19287,N,N,N,N,N,25142,N,N,N,N,28529,
+N,N,N,N,N,N,N,N,N,N,N,31573,N,N,N,N,N,N,N,N,N,N,N,21336,N,N,N,N,N,N,N,23888,
+28761,19251,N,N,N,N,N,N,21853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19751,N,N,
+20524,20794,N,28996,N,25907,31605,26977,32096,31804,N,23074,23075,N,21025,N,N,
+21103,N,N,N,25197,N,N,24169,20060,29237,20580,23889,N,N,N,N,24904,23351,24419,
+N,N,N,N,N,N,N,N,27961,28997,N,29519,22315,24876,N,N,25451,N,28231,N,N,N,24905,
+19066,N,N,N,N,N,N,N,28795,31329,28762,19559,23156,N,N,N,N,N,N,N,N,N,19519,N,N,
+N,N,N,N,N,N,N,N,N,N,N,20077,N,N,21801,31330,N,N,N,20581,N,27478,N,27743,N,N,N,
+24444,N,N,30550,24170,19252,N,N,28478,N,N,19509,N,N,N,N,N,20285,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,28530,25143,N,N,N,19560,N,N,N,N,N,N,N,N,28796,N,N,N,22112,N,
+28998,N,N,N,N,N,N,N,N,N,25144,27435,N,N,N,19253,22609,N,29774,29559,N,N,22342,
+N,20795,30506,N,27978,22355,22650,N,N,N,N,N,N,N,30277,N,N,20812,23932,N,N,N,N,
+N,N,N,N,N,N,24445,N,31077,N,24650,N,N,29309,21296,N,29811,23113,N,26206,N,N,N,
+N,30778,26704,N,N,22651,N,N,27221,N,N,N,N,22051,N,N,N,N,N,N,30278,29275,25724,
+N,N,N,N,N,N,N,N,N,N,26674,N,N,N,N,N,23130,N,29276,31574,26930,N,28205,N,31331,
+N,N,N,N,N,N,N,23662,N,N,30058,26208,N,28797,N,N,N,N,N,22316,N,N,N,N,N,30021,
+28256,N,N,23397,N,23902,N,N,22896,26915,N,N,N,N,N,N,N,N,N,N,29049,N,29252,
+24651,N,N,N,N,N,N,N,N,26916,N,N,25145,N,N,N,N,N,N,N,25393,31851,19752,N,19510,
+N,N,28763,N,N,N,N,N,N,N,N,26170,N,N,19753,N,N,N,N,N,29507,N,N,N,N,N,N,N,N,N,
+24921,N,N,28459,N,N,N,26437,N,N,24681,N,29509,N,N,21568,21823,23854,N,31100,N,
+19520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25890,N,N,N,20024,N,N,N,22610,31062,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28970,20049,N,N,30279,N,23403,N,24446,N,
+N,22625,N,30579,N,22375,N,N,N,N,N,N,N,N,N,N,N,21630,N,N,20796,N,25935,N,19254,
+N,23096,N,N,N,N,N,19780,N,N,N,N,N,22078,N,N,N,25146,N,N,N,N,N,20312,N,N,N,
+24652,27513,N,N,N,N,N,N,N,N,32125,N,N,N,N,N,22376,19288,N,N,N,26978,N,N,N,
+26682,N,N,N,25415,N,N,N,N,27725,N,27726,N,22079,N,N,N,25383,N,24406,32104,N,N,
+N,N,N,N,N,N,N,28257,30248,23933,N,N,N,N,N,N,N,30779,N,26705,N,N,N,N,31063,N,N,
+N,N,N,N,N,N,20078,N,N,27727,26917,22101,N,19781,N,27962,20797,N,N,20286,N,N,
+27707,N,N,N,21041,N,N,N,N,19561,N,22852,27004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,20798,N,N,N,N,N,27708,N,N,25901,N,N,N,N,N,N,30512,N,19562,N,N,N,21316,
+N,N,22080,N,N,N,22141,N,N,N,N,N,N,N,N,N,N,N,24865,N,24125,N,30249,N,N,N,23076,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22052,30022,N,24866,26950,N,N,N,29253,N,N,N,N,
+N,29801,22124,27475,N,N,N,N,27709,25180,24171,28764,N,27455,N,22350,20799,N,N,
+N,N,N,N,N,N,N,29995,N,N,N,N,31101,N,19036,N,N,N,19782,29238,N,N,23934,N,N,N,
+19511,23352,N,N,N,N,20585,N,20061,27456,N,32034,N,N,N,N,N,30795,N,N,N,N,N,N,N,
+N,27222,28976,N,N,N,N,N,N,N,23374,N,30531,N,N,N,N,N,N,N,N,N,N,N,23375,19236,N,
+N,30816,N,N,31575,N,N,27466,24609,N,N,N,N,N,N,N,N,N,N,N,20045,N,N,21596,N,N,N,
+32088,N,N,N,N,21110,29239,N,N,31350,30250,31351,22630,N,29745,N,N,N,N,N,N,N,N,
+N,N,N,N,N,26706,N,19013,19563,N,N,N,N,N,N,N,25198,N,N,N,N,N,25147,N,30509,N,N,
+N,30817,N,N,N,N,N,N,N,N,N,29548,N,N,N,N,24097,N,N,N,N,N,N,N,N,N,N,N,N,25725,N,
+N,25452,N,23855,23856,N,N,19255,26707,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24867,
+21088,N,N,N,N,28798,N,N,N,N,26918,19314,N,N,N,N,N,N,28019,23641,24653,N,N,N,N,
+30554,23353,N,N,N,N,N,N,N,19502,N,23131,N,N,N,N,19783,N,N,N,N,N,N,N,N,N,N,
+23857,N,22575,25379,N,N,20079,N,N,29299,N,N,N,N,30771,N,N,N,N,N,N,N,N,N,N,
+24654,N,30077,N,N,N,N,27500,N,N,21317,31852,21083,21611,N,24098,N,N,N,25958,N,
+N,N,N,N,N,28720,N,N,N,N,N,N,N,N,N,N,21828,N,N,N,N,N,N,28020,N,N,N,25453,N,
+26690,N,28021,22396,N,27963,N,N,30251,N,N,N,N,N,29240,30280,N,N,N,N,N,21350,
+29277,20287,N,27436,20288,N,26152,32105,N,20289,N,24671,24172,N,N,N,N,24610,N,
+N,N,N,N,N,N,N,29759,25199,N,22897,28999,N,19256,N,N,N,N,N,N,N,N,31102,23354,
+23157,N,N,N,N,N,N,N,N,30316,23132,31332,N,24655,N,N,N,N,N,N,23858,N,N,N,N,
+26153,N,28531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29549,N,N,N,N,N,N,N,N,N,N,
+27514,N,31078,N,N,N,N,N,N,N,19037,21854,N,19038,24420,N,N,N,26237,N,29996,N,N,
+N,N,N,25717,N,N,N,N,N,N,N,N,N,N,N,N,26979,N,27979,20324,N,N,N,22611,N,N,N,N,N,
+N,23859,21612,N,N,29241,N,24375,N,N,N,N,N,19278,31576,N,N,20569,N,N,23890,
+30580,26460,25637,N,31779,N,23355,N,N,N,29242,27005,20554,N,30038,22853,25652,
+N,27943,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27197,26238,N,30532,29997,N,22880,N,
+N,N,18996,N,N,30818,20290,N,27710,N,N,N,25908,19784,28232,N,N,N,N,N,N,N,N,N,
+26440,N,N,N,N,N,N,N,N,N,N,N,19785,31031,29032,22898,23413,18997,22854,N,N,N,
+22601,N,N,N,N,N,N,N,N,N,N,N,N,N,22827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27964,N,
+N,22612,N,N,N,23642,N,25148,N,N,31853,27744,21118,N,26951,26154,N,N,N,N,N,N,
+25200,N,N,N,N,N,N,31291,N,29998,31530,N,N,N,N,27771,N,27711,31832,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21605,N,N,N,31043,N,N,N,
+28258,N,N,N,N,N,N,N,N,N,N,N,N,N,22377,28022,N,N,N,24173,N,N,N,N,N,N,N,19564,N,
+25454,N,N,N,N,N,26708,N,N,N,31352,N,N,N,N,N,N,23860,25653,22576,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,22613,N,N,N,29802,N,N,N,20025,N,N,N,22113,20306,N,20534,N,
+N,N,N,N,N,20002,N,N,29550,N,N,N,N,N,29560,N,N,N,N,N,N,N,N,N,N,N,N,23628,N,
+20555,N,N,N,31780,19786,22356,24099,N,25696,N,N,N,N,28233,N,N,N,25181,30078,
+21548,N,N,N,N,N,21841,N,22640,30787,27223,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,30039,N,N,22591,N,N,N,N,32064,N,N,N,N,N,N,27437,N,N,N,N,21802,
+N,N,N,N,N,N,N,N,N,N,N,26408,N,N,N,N,N,N,N,N,N,N,N,N,N,28234,N,N,N,19047,N,N,N,
+N,N,30819,N,21597,N,N,27224,N,N,N,N,31577,28023,N,N,25909,N,N,N,N,N,20525,N,N,
+N,N,29041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25149,N,N,N,25416,N,N,N,N,
+22869,N,N,24362,N,N,N,N,23356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30820,N,N,N,N,N,
+29050,N,N,25910,29551,N,N,31578,24928,N,22828,N,30059,N,24630,N,N,26952,N,
+19279,N,25417,N,N,N,24174,N,N,N,N,N,N,N,N,25150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,23663,N,22053,N,N,N,N,N,25201,N,N,N,N,N,N,N,22142,22817,N,22592,23643,N,N,
+27965,24376,N,27173,N,N,N,22317,N,N,29561,N,28024,N,30023,N,N,N,N,N,N,24906,
+27491,N,29278,N,N,N,N,N,N,N,N,N,N,N,N,N,30796,N,27225,N,21318,N,23398,N,N,N,N,
+N,29999,N,N,N,N,20080,N,N,N,N,27006,N,N,N,N,N,31542,N,N,N,N,N,N,N,N,N,25202,N,
+N,N,N,20338,30521,22899,N,N,24907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+23133,N,N,23097,N,N,N,N,N,N,N,27515,N,19257,N,N,28025,N,N,N,N,N,N,24672,N,N,N,
+N,N,N,N,N,N,N,29760,N,32060,24369,25455,N,N,N,N,24611,32057,N,N,N,N,N,N,N,N,N,
+28721,N,N,N,N,N,N,19787,N,N,N,N,N,N,N,27966,N,N,N,21824,25456,28026,N,N,N,N,N,
+26980,N,N,N,N,N,N,21869,26461,N,N,N,N,N,N,21622,25911,N,N,N,23399,25151,N,N,N,
+N,N,N,N,N,N,N,N,N,28235,N,N,22388,28765,N,N,N,20011,26462,N,N,N,22102,24908,N,
+N,26675,N,N,N,N,N,N,N,N,N,N,N,25966,23586,N,N,24656,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,21813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21793,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,31579,N,31051,N,N,N,19315,29733,N,N,N,N,N,31304,22103,N,26981,31580,N,N,
+N,N,N,N,N,32080,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31606,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,23077,N,23357,N,N,N,N,N,N,27746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19831,
+28766,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+24175,N,N,N,21297,N,N,N,N,N,N,N,N,31854,N,N,N,N,26691,N,29000,N,N,N,20081,N,N,
+N,N,31085,N,N,N,N,N,N,N,N,29300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25654,30009,N,
+23664,25457,N,N,N,N,26661,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29243,N,24100,N,23116,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,19049,N,N,N,N,N,N,25434,N,31833,N,N,N,N,N,N,N,27226,N,N,N,
+N,N,N,31044,N,25380,N,N,N,N,N,N,N,N,N,N,N,31581,N,28490,N,26692,N,N,N,N,N,N,N,
+N,N,21836,N,N,N,N,N,N,N,N,N,N,27479,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22829,N,
+N,31531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21337,N,N,N,N,N,N,21794,N,N,N,N,N,N,N,
+N,N,30302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23158,N,N,N,N,
+N,N,N,N,N,N,N,24657,N,N,26920,N,N,30073,N,N,N,N,N,N,31279,N,27516,N,N,24682,
+25394,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21829,N,N,29027,21870,
+N,N,N,N,N,N,N,N,N,N,N,N,N,19788,N,N,N,N,27993,N,N,N,N,22593,N,N,N,N,31340,N,N,
+N,N,N,29035,N,N,N,N,N,31292,26210,N,N,N,N,31333,25210,N,N,N,18998,N,25655,N,
+27227,N,30074,N,N,N,31532,20291,27517,N,N,N,N,30842,N,N,24377,N,N,N,N,24945,N,
+21028,N,N,N,N,30075,N,N,N,N,N,N,20570,20571,N,27198,22833,N,N,N,N,N,18999,N,N,
+21351,N,30821,N,N,N,N,21298,N,N,N,25152,29279,N,N,N,N,N,N,19813,N,N,N,N,N,N,N,
+N,N,N,N,N,31020,N,N,N,N,N,N,N,N,19789,N,N,N,N,N,N,N,N,N,N,N,N,28206,22062,N,N,
+N,N,N,N,N,N,N,N,N,N,22378,N,N,N,N,26464,27438,N,N,N,20313,N,N,23629,28027,N,
+24176,N,22379,N,N,N,N,N,N,24101,N,N,N,N,N,N,N,N,N,N,24407,23376,23377,N,N,
+21795,N,N,N,N,28722,23644,N,N,N,N,N,N,N,N,19048,N,30822,23630,N,N,N,N,27228,
+23378,N,N,N,N,N,N,N,N,N,N,N,26931,N,N,N,N,30555,N,N,N,N,N,N,N,N,N,N,N,25384,N,
+22318,N,N,24673,N,N,N,N,N,19258,N,N,25937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,20572,N,N,N,N,21825,N,N,N,N,N,22602,N,N,N,N,N,N,N,25385,N,N,N,
+N,N,N,N,N,N,N,N,N,24612,N,26921,N,21319,N,N,23645,30766,N,N,N,19512,N,N,N,
+20526,N,N,N,22642,N,N,25418,N,N,N,N,N,N,N,N,N,N,19503,N,N,N,N,N,N,N,21549,
+30289,N,N,N,N,N,N,N,20556,N,N,N,N,N,N,N,19014,N,N,21826,N,N,20026,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,19015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31280,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,24408,N,N,N,30010,25963,N,28532,23861,N,N,N,N,19754,N,
+25458,N,31607,N,30544,N,N,N,N,32058,N,N,32097,30334,20800,N,N,26693,N,25656,N,
+24936,N,N,N,19521,N,21101,N,N,N,N,23358,N,N,24674,N,N,N,31305,N,N,24909,N,
+19000,N,N,N,29280,29001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24177,N,N,N,
+28767,30788,N,N,N,N,N,28236,N,N,24178,N,26441,N,25203,26465,N,N,25419,N,N,
+25420,N,N,N,20344,28460,N,32126,31781,31281,24409,N,24658,N,N,N,29786,N,N,N,N,
+N,N,N,N,N,N,N,29002,N,20003,N,N,N,N,29244,27747,N,N,N,N,N,24613,N,30507,N,N,
+27439,N,N,N,N,N,25950,N,24868,19755,N,22900,26662,19790,24937,N,31855,N,24675,
+N,N,N,N,N,25153,N,20004,N,N,N,N,N,N,24102,N,N,27518,N,27485,28768,N,N,29787,N,
+25204,N,N,21320,N,N,N,29803,N,28213,N,30040,N,N,21855,N,N,N,22117,N,N,N,N,
+27440,29795,N,N,N,N,25421,N,N,N,N,29812,31282,N,N,28533,19039,N,27441,27967,N,
+N,32073,N,N,N,N,25638,31012,28723,N,25964,N,N,N,20839,22855,25687,27229,N,
+21623,N,N,N,N,N,N,N,N,N,23098,N,23117,N,N,N,31052,N,24922,23359,N,19525,27728,
+19259,N,24179,N,N,26922,N,N,N,N,N,N,N,22856,N,N,28259,22333,N,N,N,N,N,N,20292,
+N,N,N,N,N,20557,N,N,N,N,N,N,N,31782,N,N,N,N,N,N,N,29051,N,N,N,N,32082,20801,N,
+N,N,N,N,N,N,N,25435,N,21321,N,23631,N,N,N,N,N,N,N,N,N,19565,N,N,N,N,N,24103,N,
+N,26171,27681,N,N,N,19513,N,N,31582,N,N,N,N,N,26466,N,N,21569,N,N,N,N,N,N,N,N,
+N,23592,N,N,N,N,N,25154,N,29528,25939,N,N,29529,N,N,N,29510,19803,N,N,N,N,N,N,
+N,19756,N,31811,N,N,N,N,21607,N,20802,N,31013,N,26709,N,N,N,N,N,N,N,N,25422,N,
+N,N,N,21578,N,N,N,N,N,N,24410,N,N,N,N,N,N,N,N,31583,26467,N,N,N,N,N,N,N,N,N,N,
+N,N,N,30843,25423,N,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,22631,N,22857,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,30767,28534,N,23862,28207,19832,N,N,N,N,24120,31783,30588,
+30513,20027,29729,N,N,28237,24878,N,N,27715,20350,N,30783,22626,21352,N,N,
+24104,29796,27714,N,22901,31045,23891,22129,27772,31856,N,N,27968,19001,N,
+28260,N,N,N,N,N,N,29281,N,24121,N,N,N,N,N,N,22130,N,24180,N,24411,N,23379,N,
+31335,22627,29761,N,23863,N,N,N,29301,N,N,21550,N,N,N,N,N,N,22131,N,N,N,N,N,N,
+23864,20293,24415,29246,30241,N,27467,29052,N,29511,N,N,24683,N,N,N,N,N,28028,
+N,N,24923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,28261,N,24181,N,N,N,N,31315,N,N,N,N,29003,N,N,20527,23865,N,N,20803,N,
+N,N,N,N,N,N,N,N,N,N,N,N,30001,N,N,N,N,27206,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28769,
+N,N,N,N,N,N,N,N,N,30252,N,N,N,N,30041,N,N,N,N,N,N,N,N,N,N,28779,N,N,N,N,N,N,
+23866,N,N,N,29247,N,N,N,N,N,N,N,30533,N,N,N,N,23330,29302,N,N,19002,N,N,N,N,N,
+N,N,N,N,N,N,30581,N,19301,N,N,N,28262,N,24659,N,N,N,N,20005,N,N,N,N,N,N,22104,
+N,N,N,21551,26953,N,N,N,N,21326,29762,N,N,N,N,N,N,N,N,N,N,N,N,N,19302,N,N,N,N,
+N,N,N,N,N,N,N,28961,N,N,N,N,N,27442,N,N,N,N,28962,N,N,N,N,N,N,N,N,N,N,N,N,
+27443,N,28724,N,N,19316,21552,29490,31543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30060,N,
+N,N,N,N,28263,29746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30061,N,20339,N,N,N,
+N,N,N,N,N,N,N,28770,N,N,N,N,N,28238,N,N,29004,N,N,25912,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22389,25459,20325,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,20294,N,N,N,N,N,N,N,N,N,29491,25688,20345,20314,N,N,N,N,31309,N,N,
+N,N,N,N,N,N,N,N,N,N,26211,N,N,N,N,N,N,N,N,N,N,N,29282,N,N,N,N,N,N,N,N,N,N,N,N,
+30062,N,N,19003,N,N,25436,20082,N,22105,N,N,N,28208,N,N,N,N,N,N,N,N,29797,
+22594,23632,19566,N,N,N,N,N,21856,30282,32074,22614,29775,N,N,N,N,N,N,22054,
+23614,N,23380,22343,N,N,N,N,29310,N,N,N,29005,N,N,N,N,25155,23646,N,23647,N,N,
+28461,26155,N,N,N,N,31069,27199,N,N,N,28462,N,N,N,29776,20083,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,26156,N,20062,N,N,21881,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25460,
+19792,N,N,N,N,N,N,21816,N,N,30589,N,23593,N,N,N,N,24182,N,23594,29283,26932,
+21084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26982,N,N,25462,N,N,N,N,N,N,N,N,26442,N,N,
+20558,N,N,23159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19004,N,N,N,28264,23134,N,
+29303,N,N,25211,N,19494,N,N,N,N,23099,N,28265,N,N,N,30042,30556,24938,20033,
+21553,N,32049,26173,N,31533,N,N,30823,N,24910,N,30562,30063,20295,N,N,21554,
+19567,N,21608,N,28239,30551,N,N,24614,22081,24924,28771,29028,23665,22055,N,N,
+N,N,N,N,N,N,N,N,29813,N,N,29006,29284,N,N,20528,N,N,27759,N,N,N,31034,N,27445,
+N,N,21613,25156,N,N,N,N,26983,N,N,27444,27169,N,30780,20006,N,31046,31834,N,
+21555,21305,27230,N,N,N,26923,N,N,24929,21327,29814,N,27200,24911,N,19514,N,N,
+N,N,N,28266,N,N,N,28772,29492,21614,N,N,29248,N,N,29029,N,29763,24660,N,27446,
+N,22305,19304,N,31021,26925,22628,31283,25157,31805,N,N,27716,22577,N,23595,N,
+N,N,N,21796,N,27497,N,N,N,26683,N,N,N,22615,N,N,N,N,N,N,N,N,31534,20833,N,N,
+23360,N,30014,N,24183,N,N,N,N,19067,30534,20296,N,N,N,24912,N,N,28240,N,N,N,N,
+N,N,N,N,26996,N,N,N,N,N,N,N,N,20084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+21837,N,N,20315,N,N,N,N,N,N,23867,N,N,N,N,20012,N,N,N,N,N,N,N,26984,N,N,N,N,N,
+N,N,21556,25671,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30043,N,N,31297,N,N,N,24105,N,N,
+N,N,N,N,N,N,N,N,N,N,N,21624,N,N,N,N,N,28535,N,N,N,N,21299,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,27447,28536,30044,27980,23381,29007,N,N,N,29008,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,30002,N,N,N,N,N,N,22830,21804,N,25158,N,N,N,N,N,N,N,N,
+32035,N,31589,24363,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25205,N,30253,N,30003,N,28725,
+N,N,N,N,24869,N,N,N,N,N,N,N,N,N,30045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27682,28029,
+N,30004,31544,N,23331,N,N,22090,19289,N,N,N,N,N,N,N,N,N,N,25940,N,N,N,N,N,N,
+29562,N,27448,N,24631,22380,29036,25903,21857,22381,20817,N,N,N,N,N,24946,
+28537,N,N,N,23868,30300,N,N,N,N,N,28773,N,N,N,29764,N,N,26985,N,N,N,N,N,N,N,N,
+N,N,29563,21615,N,N,19490,30590,24380,N,N,N,N,27469,N,N,N,N,N,N,20535,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22082,N,N,N,N,N,26669,N,N,N,N,28463,19237,N,
+N,N,N,19305,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,N,19526,N,N,N,26215,N,N,27207,
+N,N,N,23332,N,20297,25212,28538,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,27486,N,N,30024,N,21598,N,N,N,N,N,N,N,N,N,N,N,24661,N,28464,N,N,25159,N,
+22831,N,N,N,31079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26469,N,N,20298,
+24913,N,25160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28539,N,N,31353,N,N,23666,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24615,N,N,N,N,N,30824,N,N,N,N,N,N,N,N,N,N,N,N,
+N,19306,N,N,N,19260,22114,N,N,N,N,N,N,N,N,N,N,N,30046,N,N,N,N,N,N,N,30047,N,
+28214,N,N,N,25206,21322,28540,20804,28465,N,20805,N,20574,N,22881,N,N,24632,N,
+N,19793,29497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26444,N,22056,
+20007,N,21557,N,N,N,N,N,N,25672,N,N,N,N,N,N,21300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,27449,N,N,N,N,N,N,19317,N,N,N,N,N,N,30301,N,28963,N,N,N,N,N,N,N,N,N,N,
+N,N,N,19527,N,N,N,N,N,N,N,26954,N,24944,N,N,N,30048,N,N,N,N,N,N,N,N,31535,N,N,
+N,19281,N,N,N,N,31584,29285,N,N,27760,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+28780,N,N,N,N,N,N,N,N,N,N,N,N,N,28267,N,N,N,N,N,N,N,N,N,N,N,N,26955,N,N,19568,
+N,N,22319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29473,31861,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,28964,N,N,N,N,N,N,N,N,N,N,N,N,24662,N,N,N,N,N,28466,N,N,N,N,N,
+N,N,N,N,29777,N,N,30497,N,N,N,N,N,N,N,N,N,N,N,29009,N,N,N,N,N,N,N,N,N,N,N,N,
+19068,19069,N,N,N,N,N,N,N,N,20046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,29512,N,29498,28030,N,N,N,N,N,N,N,N,23078,N,N,24684,N,N,
+N,N,N,30797,N,19282,N,N,N,27470,N,31064,31065,19040,23114,N,N,N,19238,N,N,N,N,
+N,N,N,N,N,N,19016,31086,23404,N,N,20529,N,N,N,N,21871,N,N,N,26227,N,N,N,N,N,N,
+N,N,N,26402,25689,N,N,N,N,N,N,N,N,N,N,25697,N,N,31812,N,N,N,N,N,N,N,N,N,31087,
+20340,30566,N,N,N,N,N,20028,N,N,N,N,29765,23587,23869,N,N,N,N,29766,N,N,N,N,N,
+N,N,N,30753,N,N,N,26710,N,N,N,23361,N,N,N,N,N,N,N,N,28774,N,N,N,25657,30317,N,
+31022,N,23870,N,N,N,N,N,N,22320,22632,19261,N,N,31066,N,N,N,N,N,N,N,N,N,N,
+30798,31088,24685,25395,29747,N,N,27202,29286,28726,N,N,N,N,N,23382,N,N,N,N,N,
+27492,N,N,29287,N,22357,21558,31080,22337,N,N,N,N,25941,N,N,N,N,N,N,N,26986,
+22348,N,N,N,21353,25161,N,31835,19757,N,N,N,N,N,19504,27170,N,N,25718,20544,N,
+28727,28193,N,N,N,N,N,N,22390,N,N,N,25162,25163,N,31311,N,N,N,N,N,N,27487,N,N,
+N,N,N,22091,N,N,N,29748,N,N,N,N,27981,25682,N,N,27177,25658,29474,19794,N,
+30283,N,29030,27969,26684,28241,N,N,N,N,N,N,28775,25164,N,N,25642,N,30049,
+27994,N,N,N,N,N,22382,20849,N,N,N,N,26987,26988,24676,N,N,N,N,23079,23892,N,
+27171,N,N,N,22083,22132,N,23135,N,28467,25165,N,N,N,N,N,28541,29288,N,N,N,N,N,
+N,N,N,N,28485,N,26471,N,N,22397,N,N,26446,N,N,24412,N,31047,N,N,N,N,N,N,N,N,
+22902,N,N,N,N,N,N,N,N,24364,N,22106,N,N,N,N,N,N,23588,N,N,N,28728,N,N,N,N,
+21882,N,25719,N,N,N,22084,N,N,N,N,N,N,N,N,29804,N,N,N,N,28542,N,N,N,N,N,28705,
+N,24106,N,N,23100,22652,N,N,N,N,N,N,31316,N,N,N,27749,N,N,N,N,N,N,31784,N,N,
+27750,N,N,22603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31545,N,25683,N,19833,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,20307,N,N,N,N,N,N,N,19050,N,N,20308,N,30781,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29767,N,N,N,N,27231,N,N,N,N,N,N,N,31067,
+N,N,N,N,N,N,N,N,21559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27493,N,N,
+24914,N,N,N,N,27172,N,N,N,31298,31585,31341,28706,19569,N,31267,25207,N,25166,
+N,26997,N,24939,N,N,N,26472,26711,23160,21579,N,N,N,30582,22085,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,21609,N,N,31354,N,N,N,N,N,N,N,19570,30557,N,24122,N,
+N,N,N,N,N,N,N,N,N,20008,N,N,N,N,N,28729,25726,25673,N,N,N,N,N,25684,N,N,N,
+27203,N,28468,N,N,N,22334,N,N,N,N,N,N,31586,N,19795,N,N,N,28469,N,N,N,31337,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31014,N,N,N,N,N,N,24381,N,30535,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,30845,N,N,30844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+24107,23400,N,N,25437,N,24930,20806,N,N,N,N,N,N,N,N,N,N,30288,27494,23161,N,N,
+N,N,27719,N,N,N,N,N,N,N,24184,30825,25438,20085,N,N,N,N,N,31299,25943,N,27720,
+N,N,N,29513,N,N,25659,N,N,N,N,26158,N,N,N,N,N,28470,N,23615,N,N,N,N,N,N,N,
+20029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22595,N,N,N,
+20559,N,20346,29514,24663,N,N,N,20807,26926,N,26685,N,N,31300,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25167,N,N,31301,N,N,N,31032,N,N,N,N,N,N,N,23648,
+N,N,31536,N,N,N,22569,25951,31015,N,N,30318,N,30284,25208,N,N,N,N,27761,N,N,N,
+N,N,N,N,23136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29010,21068,20299,N,N,19005,N,N,N,
+23871,N,N,N,30319,N,24185,N,N,N,N,N,N,N,N,N,N,N,N,N,31284,N,N,N,21805,N,N,N,N,
+N,N,N,N,N,N,N,N,N,29031,24126,N,N,N,N,N,N,23616,N,N,N,N,N,20808,20809,N,N,N,N,
+N,N,N,N,N,30782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19318,N,N,N,N,21625,N,N,N,N,
+N,30050,24915,N,N,N,N,N,N,N,N,22633,N,N,30846,N,20300,N,N,N,N,N,N,N,32036,N,N,
+N,N,N,N,N,20086,N,31312,N,N,19571,26174,N,N,N,30254,N,N,21872,N,N,20810,N,N,N,
+31806,21873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19817,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25168,
+29815,N,N,N,19796,N,N,N,N,N,N,N,N,N,N,N,N,26403,N,N,N,N,N,N,N,N,23333,25169,N,
+N,N,N,N,N,N,N,N,N,N,N,22306,N,N,30563,N,N,N,N,N,N,27174,N,N,N,N,N,N,N,N,N,N,
+20513,N,N,N,N,20058,31595,23334,23390,22629,N,N,N,N,N,N,N,N,N,27232,N,N,N,N,
+22570,N,N,N,N,N,25952,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22107,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28486,N,N,30826,N,N,N,N,N,N,
+N,N,N,N,N,N,N,25685,N,N,N,N,N,N,N,N,N,N,N,20087,N,N,24664,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22383,N,N,N,N,N,N,N,N,N,N,N,N,29805,N,N,N,N,N,
+N,N,N,N,N,N,N,N,19814,N,N,N,19572,30051,N,N,25674,N,23649,N,N,31048,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,31807,N,N,N,N,N,N,N,N,N,N,N,N,26663,N,N,N,N,N,N,N,N,22596,
+N,N,N,N,N,N,N,N,N,N,N,19262,N,23598,N,N,N,N,N,N,N,N,N,N,N,N,N,22391,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28776,N,23872,N,20301,N,N,N,N,N,N,N,N,N,
+23667,22832,N,26217,25660,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27204,N,N,N,N,N,N,
+N,N,N,N,25708,N,25701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31608,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,19515,N,N,N,N,N,N,N,N,N,N,N,25661,N,N,19804,22903,
+N,N,N,N,N,N,N,N,N,N,23903,N,N,N,N,N,27982,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22864,
+N,N,N,N,N,25891,N,N,N,N,31053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19758,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,20302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,30255,N,N,N,N,N,32083,27501,22108,25892,N,N,N,21814,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22109,
+N,N,N,31081,N,N,N,26404,N,22115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20811,
+22116,N,N,N,21874,N,N,N,N,N,24186,N,22392,N,N,N,N,N,22634,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,20309,22653,N,N,N,N,N,22571,N,N,32075,N,N,N,N,31836,N,N,N,N,N,N,N,N,N,
+24616,21875,N,N,32089,N,N,19491,N,N,N,22905,N,N,21354,30069,N,28487,N,N,N,N,N,
+N,N,N,N,21338,N,N,N,N,N,N,N,N,N,N,N,23101,26664,23599,N,N,N,N,N,28707,N,N,N,N,
+19797,N,N,N,N,N,N,N,N,N,N,N,N,24617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,24108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28730,28209,N,N,28210,N,N,N,30285,
+N,N,N,N,N,N,N,N,N,N,N,N,28242,N,22086,N,N,N,N,N,24677,N,N,29499,N,25953,N,N,N,
+N,N,N,N,N,N,N,25675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22307,N,N,23362,
+N,N,N,N,19070,N,N,N,N,N,N,20303,12321,12322,33089,33090,12323,33091,33092,
+12324,12325,12326,12327,33093,33094,33095,33096,33097,12328,12329,12330,12331,
+12332,12333,12334,12335,33098,12336,12337,12338,12339,12340,33099,33100,12341,
+33101,33102,33103,12342,33104,33105,33106,33107,33108,33109,33110,12343,12344,
+33111,12345,12346,12347,33112,33113,33114,33121,33122,33123,12348,12349,33124,
+33125,12350,33126,33127,33128,12351,33129,33130,33131,33132,33133,33134,33135,
+33136,33137,33138,12352,33139,12353,33140,33141,33142,33143,33144,33145,12354,
+33146,33153,33154,12355,33155,33156,33157,12356,33158,33159,33160,33161,33162,
+33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175,
+33176,12357,12358,33177,33178,12359,33179,33180,12360,12361,33181,12362,33182,
+33183,33184,33185,33186,12363,12364,33187,12365,12366,12367,12368,33188,33189,
+12369,12370,12371,12372,33190,33191,33192,12373,33193,33194,33195,12374,33196,
+33197,33198,33199,33200,33201,33202,12375,12376,33203,12377,12378,12379,33204,
+33205,33206,33207,33208,33209,12380,12381,12382,33210,12383,33211,33212,12384,
+12385,33213,33214,33215,33216,33217,33218,33219,12386,12387,33220,12388,12389,
+12390,33221,33222,33223,12391,33224,33225,12392,33226,33227,33228,12393,33229,
+33230,33231,12394,33232,33233,33234,33235,33236,33237,33238,33239,12395,33240,
+12396,33241,33242,33243,33244,33245,33246,33247,33248,12397,12398,33249,33250,
+12399,33251,33252,12400,12401,33253,12402,33254,12403,33255,33256,12404,12405,
+12406,33257,12407,33258,12408,12409,33259,33260,33261,33262,33263,12410,12411,
+33264,33265,12412,33266,33267,33268,12413,33269,12414,33270,33271,33272,33273,
+33274,12577,12578,33275,12579,33276,12580,33277,33278,33345,33346,33347,33348,
+12581,33349,33350,33351,12582,33352,33353,33354,12583,33355,33356,33357,33358,
+33359,33360,33361,33362,12584,33363,33364,12585,12586,33365,33366,33367,33368,
+33369,33370,12587,12588,33377,33378,12589,33379,33380,33381,12590,33382,33383,
+33384,33385,33386,33387,33388,12591,12592,33389,12593,33390,12594,33391,33392,
+33393,33394,33395,33396,12595,33397,33398,33399,12596,33400,33401,33402,12597,
+33409,33410,33411,33412,33413,33414,33415,33416,12598,33417,12599,33418,33419,
+33420,33421,33422,33423,33424,33425,12600,12601,33426,33427,12602,33428,33429,
+12603,12604,12605,12606,33430,33431,33432,33433,12607,12608,12609,33434,12610,
+33435,12611,12612,33436,33437,33438,33439,33440,12613,12614,33441,33442,12615,
+33443,33444,33445,12616,33446,33447,33448,33449,33450,33451,33452,33453,33454,
+33455,33456,12617,12618,33457,33458,33459,33460,33461,33462,12619,33463,33464,
+33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477,
+33478,33479,33480,12620,33481,33482,33483,33484,33485,33486,33487,33488,12621,
+12622,33489,33490,12623,33491,33492,33493,12624,33494,33495,33496,33497,33498,
+33499,33500,12625,12626,33501,12627,33502,33503,33504,33505,33506,33507,33508,
+33509,12628,33510,33511,33512,12629,33513,33514,33515,12630,33516,33517,33518,
+33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531,
+33532,33533,33534,12631,12632,33601,33602,12633,33603,33604,12634,12635,12636,
+33605,33606,33607,33608,33609,33610,12637,12638,33611,12639,33612,12640,33613,
+33614,33615,33616,33617,33618,12641,33619,33620,33621,33622,33623,33624,33625,
+33626,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644,
+33645,33646,33647,33648,33649,33650,33651,12642,12643,33652,33653,12644,33654,
+33655,12645,12646,33656,12647,33657,33658,33665,33666,33667,12648,12649,33668,
+12650,33669,12651,12652,33670,33671,33672,12653,33673,12654,12655,12656,33674,
+12657,33675,33676,33677,12658,33678,12659,33679,33680,33681,33682,33683,12660,
+12661,33684,12662,12663,12664,33685,33686,33687,12665,33688,33689,12666,12667,
+33690,33691,12668,33692,33693,33694,12669,33695,33696,33697,33698,33699,33700,
+33701,12670,12833,33702,12834,12835,12836,33703,33704,33705,33706,33707,33708,
+12837,12838,33709,33710,33711,33712,33713,33714,12839,33715,33716,33717,33718,
+33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731,
+33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744,
+33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757,
+33758,33759,33760,33761,12840,12841,12842,33762,12843,33763,33764,33765,12844,
+33766,33767,33768,33769,33770,33771,33772,12845,12846,33773,12847,12848,12849,
+33774,33775,33776,33777,33778,33779,12850,12851,33780,33781,12852,33782,33783,
+33784,33785,33786,33787,33788,33789,33790,33857,33858,12853,33859,33860,12854,
+33861,12855,33862,33863,33864,33865,33866,33867,12856,33868,33869,33870,12857,
+33871,33872,33873,12858,33874,33875,33876,33877,33878,33879,33880,33881,33882,
+33889,12859,12860,33890,33891,33892,33893,12861,33894,33895,12862,33896,33897,
+33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910,
+33911,33912,33913,33914,33921,33922,33923,33924,33925,33926,33927,33928,12863,
+12864,33929,33930,12865,33931,12866,33932,12867,33933,33934,33935,33936,33937,
+33938,33939,12868,12869,33940,12870,33941,12871,12872,12873,33942,33943,33944,
+33945,12874,12875,33946,33947,33948,33949,33950,33951,12876,33952,33953,33954,
+33955,33956,33957,33958,33959,33960,33961,33962,12877,12878,33963,33964,33965,
+33966,33967,33968,12879,12880,33969,33970,33971,33972,33973,33974,33975,33976,
+33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,12881,33988,
+33989,33990,33991,33992,33993,12882,33994,33995,33996,12883,33997,33998,33999,
+12884,34000,34001,34002,34003,34004,34005,34006,12885,12886,34007,34008,34009,
+12887,34010,34011,34012,34013,34014,34015,12888,34016,34017,34018,34019,34020,
+34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033,
+34034,34035,34036,34037,34038,34039,34040,34041,34042,12889,12890,34043,34044,
+12891,34045,34046,34113,12892,34114,34115,34116,34117,34118,34119,12893,12894,
+12895,34120,12896,34121,12897,12898,34122,34123,34124,34125,34126,12899,34127,
+34128,34129,34130,34131,34132,34133,12900,34134,34135,34136,34137,34138,34145,
+34146,34147,34148,34149,34150,12901,12902,34151,34152,34153,34154,34155,34156,
+12903,12904,34157,34158,12905,34159,34160,34161,12906,34162,34163,34164,34165,
+34166,34167,34168,12907,12908,34169,34170,12909,34177,34178,34179,34180,34181,
+34182,34183,12910,34184,34185,34186,12911,34187,34188,34189,12912,34190,34191,
+34192,34193,34194,34195,34196,12913,12914,34197,34198,34199,34200,34201,34202,
+34203,34204,34205,34206,12915,34207,34208,34209,34210,34211,34212,34213,34214,
+34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227,
+34228,34229,34230,34231,34232,34233,12916,12917,34234,34235,12918,34236,12919,
+34237,12920,34238,12921,34239,34240,34241,34242,12922,12923,12924,34243,12925,
+34244,12926,34245,34246,34247,13089,34248,34249,34250,34251,34252,34253,34254,
+34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267,
+34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,13090,13091,34278,
+34279,13092,34280,34281,34282,13093,34283,34284,34285,34286,34287,34288,34289,
+13094,13095,34290,13096,34291,13097,34292,34293,34294,34295,34296,34297,13098,
+13099,13100,34298,13101,34299,34300,13102,13103,13104,13105,34301,34302,34369,
+34370,34371,13106,13107,34372,13108,13109,13110,13111,13112,34373,13113,34374,
+13114,13115,13116,34375,34376,13117,34377,34378,34379,13118,34380,34381,34382,
+34383,34384,34385,34386,13119,13120,34387,13121,13122,13123,34388,34389,34390,
+34391,34392,34393,13124,13125,34394,34401,13126,34402,34403,34404,13127,34405,
+34406,34407,34408,34409,34410,34411,13128,34412,34413,34414,34415,13129,34416,
+34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34433,34434,34435,
+34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448,
+34449,34450,34451,34452,34453,34454,34455,13130,13131,34456,13132,13133,34457,
+34458,34459,13134,34460,13135,13136,34461,34462,34463,34464,13137,13138,34465,
+13139,13140,13141,34466,34467,34468,34469,34470,13142,13143,13144,34471,34472,
+13145,34473,34474,34475,13146,34476,34477,34478,34479,34480,34481,34482,13147,
+13148,34483,13149,13150,13151,34484,34485,34486,34487,34488,34489,13152,13153,
+34490,34491,13154,34492,34493,34494,13155,34495,34496,34497,34498,34499,34500,
+34501,13156,13157,34502,34503,13158,13159,34504,34505,13160,34506,34507,34508,
+13161,34509,34510,34511,13162,34512,34513,34514,34515,34516,34517,34518,34519,
+34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532,
+34533,34534,13163,13164,34535,34536,13165,34537,34538,34539,13166,34540,13167,
+34541,34542,34543,34544,34545,13168,13169,34546,13170,34547,13171,34548,34549,
+34550,34551,13172,13173,13174,34552,34553,34554,13175,34555,34556,34557,13176,
+34558,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,13177,34635,
+34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648,
+34649,34650,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667,
+34668,34669,34670,34671,34672,34673,34674,34675,13178,34676,34677,34678,13179,
+34679,34680,34681,13180,34682,34689,34690,34691,34692,34693,34694,13181,13182,
+34695,13345,34696,34697,34698,34699,34700,34701,34702,34703,13346,13347,34704,
+34705,13348,34706,34707,34708,13349,34709,34710,34711,34712,34713,34714,34715,
+34716,13350,34717,13351,34718,13352,34719,34720,34721,34722,34723,34724,13353,
+13354,34725,34726,13355,34727,34728,13356,13357,34729,34730,34731,34732,34733,
+34734,34735,13358,13359,34736,13360,34737,13361,34738,34739,34740,34741,34742,
+34743,13362,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754,
+34755,34756,34757,34758,34759,34760,34761,34762,13363,34763,34764,34765,34766,
+34767,34768,34769,13364,34770,34771,34772,34773,34774,34775,34776,34777,34778,
+34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791,
+34792,34793,34794,34795,34796,13365,34797,34798,34799,13366,34800,34801,34802,
+13367,34803,34804,34805,34806,34807,34808,34809,13368,13369,34810,34811,34812,
+34813,34814,34881,34882,34883,34884,34885,13370,13371,34886,34887,34888,34889,
+34890,34891,13372,34892,34893,34894,34895,34896,34897,34898,13373,13374,34899,
+34900,34901,13375,34902,34903,34904,34905,34906,34913,13376,13377,34914,34915,
+13378,34916,34917,34918,13379,13380,13381,34919,34920,34921,34922,34923,13382,
+13383,34924,13384,34925,13385,13386,34926,34927,34928,13387,34929,13388,34930,
+34931,34932,13389,34933,34934,34935,13390,34936,34937,34938,34945,34946,34947,
+34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960,
+13391,13392,34961,34962,13393,34963,34964,34965,13394,34966,13395,34967,34968,
+34969,34970,34971,13396,13397,34972,13398,34973,13399,34974,34975,34976,34977,
+13400,34978,13401,13402,13403,34979,13404,34980,34981,13405,13406,13407,13408,
+13409,34982,34983,34984,13410,13411,13412,34985,13413,13414,13415,13416,13417,
+34986,34987,34988,13418,13419,13420,34989,34990,13421,34991,34992,34993,13422,
+34994,34995,34996,34997,34998,34999,35000,13423,13424,35001,13425,13426,13427,
+35002,35003,35004,35005,35006,35007,13428,35008,35009,35010,35011,35012,35013,
+35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026,
+35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039,
+35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052,
+35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,13429,13430,13431,
+35063,13432,35064,35065,13433,13434,35066,13435,13436,35067,35068,35069,35070,
+13437,13438,35137,13601,35138,13602,35139,13603,35140,35141,13604,35142,13605,
+13606,35143,35144,13607,35145,35146,35147,13608,35148,35149,35150,35151,35152,
+35153,35154,13609,13610,35155,13611,13612,13613,35156,35157,35158,35159,35160,
+35161,13614,35162,35169,35170,13615,35171,35172,35173,13616,35174,35175,35176,
+35177,35178,35179,35180,35181,35182,35183,35184,13617,13618,35185,35186,35187,
+35188,35189,35190,13619,35191,35192,35193,13620,35194,35201,35202,35203,35204,
+35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,
+35218,35219,35220,35221,35222,13621,13622,35223,35224,13623,35225,35226,13624,
+13625,35227,13626,35228,13627,35229,35230,35231,13628,13629,35232,13630,35233,
+13631,35234,13632,35235,13633,35236,35237,13634,35238,35239,35240,13635,35241,
+35242,35243,13636,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,
+35254,35255,35256,35257,35258,35259,35260,35261,35262,13637,35263,35264,35265,
+35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278,
+35279,35280,35281,13638,35282,35283,35284,35285,35286,35287,35288,13639,35289,
+35290,35291,13640,35292,35293,35294,13641,35295,35296,35297,35298,35299,35300,
+35301,13642,13643,35302,13644,35303,35304,35305,35306,35307,35308,35309,35310,
+13645,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322,
+35323,35324,35325,35326,35393,35394,35395,35396,35397,35398,35399,35400,35401,
+35402,35403,13646,13647,35404,35405,13648,35406,35407,35408,13649,35409,35410,
+35411,35412,35413,35414,35415,13650,13651,35416,13652,35417,13653,35418,35425,
+35426,35427,35428,35429,13654,35430,35431,35432,35433,35434,35435,35436,35437,
+35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,13655,35449,
+35450,35457,35458,35459,35460,35461,13656,35462,35463,35464,35465,35466,35467,
+35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480,
+35481,13657,35482,35483,35484,35485,35486,35487,13658,35488,35489,35490,13659,
+35491,35492,35493,13660,35494,35495,35496,35497,35498,35499,35500,35501,13661,
+35502,13662,35503,13663,35504,35505,35506,35507,35508,35509,13664,35510,35511,
+35512,13665,35513,35514,35515,13666,35516,35517,35518,35519,35520,35521,35522,
+13667,35523,35524,35525,35526,13668,35527,35528,35529,35530,35531,35532,13669,
+13670,35533,35534,13671,35535,35536,13672,13673,35537,13674,35538,35539,35540,
+35541,35542,13675,13676,35543,13677,35544,13678,35545,35546,35547,35548,35549,
+35550,13679,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561,
+35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574,
+35575,35576,35577,13680,13681,35578,35579,13682,35580,35581,13683,13684,35582,
+35649,35650,35651,35652,35653,35654,13685,13686,35655,13687,13688,13689,13690,
+35656,35657,35658,35659,35660,13691,13692,35661,35662,13693,35663,35664,35665,
+13694,35666,35667,35668,35669,35670,35671,35672,13857,13858,35673,13859,13860,
+13861,35674,35681,35682,35683,35684,13862,13863,13864,35685,35686,13865,35687,
+35688,35689,13866,35690,35691,35692,35693,35694,35695,35696,13867,13868,35697,
+13869,13870,13871,35698,35699,35700,35701,35702,35703,35704,35705,35706,35713,
+35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726,
+35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739,
+35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752,
+35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765,
+13872,13873,35766,35767,13874,35768,35769,35770,13875,35771,13876,13877,35772,
+35773,35774,35775,13878,13879,35776,13880,13881,13882,35777,35778,35779,35780,
+35781,13883,13884,13885,35782,35783,13886,35784,35785,35786,13887,35787,35788,
+35789,35790,35791,35792,35793,13888,13889,35794,13890,13891,13892,35795,35796,
+35797,35798,35799,35800,13893,35801,35802,35803,35804,35805,35806,35807,35808,
+35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,13894,35820,
+35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833,
+35834,35835,35836,35837,35838,35905,35906,35907,35908,35909,35910,35911,35912,
+35913,35914,35915,35916,35917,35918,35919,35920,13895,13896,35921,35922,13897,
+35923,35924,35925,13898,35926,35927,35928,35929,35930,35937,35938,35939,35940,
+35941,35942,35943,13899,35944,35945,35946,35947,35948,35949,13900,35950,35951,
+35952,35953,35954,35955,35956,13901,35957,35958,35959,35960,35961,35962,35969,
+35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,13902,
+35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994,
+35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,
+36008,13903,36009,36010,36011,13904,36012,36013,36014,36015,36016,36017,36018,
+36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,
+36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,
+36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,
+36058,36059,36060,36061,36062,13905,13906,36063,36064,13907,36065,36066,36067,
+13908,36068,36069,36070,36071,36072,36073,13909,13910,36074,36075,36076,36077,
+13911,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,
+36090,36091,36092,36093,36094,36161,36162,36163,36164,36165,36166,36167,36168,
+36169,36170,36171,36172,36173,36174,36175,36176,36177,13912,36178,36179,36180,
+36181,36182,36183,36184,36185,36186,36193,36194,36195,36196,36197,36198,36199,
+36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,13913,36211,
+36212,36213,13914,36214,36215,36216,13915,36217,36218,36225,36226,36227,36228,
+36229,13916,13917,36230,36231,36232,13918,36233,36234,36235,36236,36237,36238,
+36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251,
+36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264,
+36265,36266,13919,13920,36267,36268,13921,36269,36270,13922,13923,36271,36272,
+36273,36274,36275,36276,36277,13924,13925,36278,13926,36279,36280,36281,36282,
+36283,36284,36285,36286,13927,36287,36288,36289,13928,36290,36291,36292,13929,
+36293,36294,36295,36296,36297,36298,36299,13930,13931,36300,36301,36302,36303,
+36304,36305,36306,36307,36308,36309,13932,36310,36311,36312,13933,36313,36314,
+36315,13934,36316,36317,36318,36319,36320,36321,36322,13935,13936,36323,13937,
+36324,13938,36325,36326,36327,36328,36329,36330,13939,13940,36331,36332,13941,
+36333,36334,36335,13942,36336,36337,36338,36339,36340,36341,36342,13943,13944,
+36343,13945,13946,13947,13948,36344,36345,36346,13949,13950,14113,14114,36347,
+36348,14115,36349,36350,36417,14116,36418,36419,36420,36421,36422,36423,36424,
+14117,14118,36425,14119,14120,14121,36426,36427,36428,36429,36430,36431,14122,
+14123,36432,36433,14124,36434,36435,36436,36437,36438,36439,36440,36441,36442,
+36449,36450,36451,36452,36453,14125,36454,14126,36455,36456,36457,36458,36459,
+36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472,
+36473,36474,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491,
+36492,36493,36494,14127,14128,36495,36496,14129,36497,36498,36499,14130,36500,
+36501,36502,36503,36504,36505,36506,14131,14132,36507,14133,14134,14135,36508,
+36509,36510,36511,36512,14136,14137,14138,36513,36514,14139,36515,36516,36517,
+14140,36518,36519,36520,36521,36522,36523,36524,14141,14142,36525,14143,36526,
+14144,36527,36528,36529,36530,36531,36532,14145,14146,36533,36534,14147,36535,
+36536,36537,14148,36538,36539,36540,36541,36542,36543,36544,14149,14150,36545,
+14151,14152,14153,36546,36547,36548,36549,36550,36551,14154,36552,36553,36554,
+14155,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566,
+14156,36567,14157,36568,36569,36570,36571,36572,36573,36574,36575,14158,14159,
+36576,36577,14160,36578,36579,36580,14161,36581,36582,36583,36584,36585,36586,
+36587,14162,14163,36588,14164,36589,14165,36590,36591,36592,36593,36594,36595,
+14166,36596,36597,36598,14167,36599,36600,36601,36602,36603,36604,36605,36606,
+36673,36674,36675,36676,36677,36678,36679,36680,14168,36681,36682,36683,36684,
+36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,
+36698,36705,36706,36707,36708,36709,36710,36711,36712,14169,36713,36714,36715,
+36716,36717,36718,36719,14170,36720,36721,36722,14171,36723,36724,36725,14172,
+36726,36727,36728,36729,36730,36737,36738,14173,14174,36739,14175,36740,14176,
+36741,36742,36743,36744,36745,36746,14177,36747,36748,36749,14178,36750,36751,
+36752,14179,36753,36754,36755,36756,36757,36758,36759,36760,14180,36761,14181,
+36762,14182,36763,36764,36765,36766,36767,36768,14183,14184,36769,36770,14185,
+36771,36772,36773,14186,36774,36775,36776,36777,36778,36779,36780,14187,14188,
+36781,14189,36782,14190,36783,36784,36785,36786,36787,36788,14191,36789,36790,
+36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803,
+36804,36805,36806,36807,14192,36808,36809,36810,36811,36812,36813,36814,14193,
+36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827,
+36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840,
+36841,14194,14195,36842,36843,14196,36844,36845,36846,14197,36847,36848,36849,
+36850,36851,36852,36853,14198,36854,36855,14199,36856,14200,36857,36858,36859,
+36860,36861,36862,14201,14202,36929,36930,14203,36931,36932,36933,14204,36934,
+36935,36936,36937,36938,36939,36940,14205,14206,36941,14369,36942,14370,36943,
+36944,36945,36946,36947,36948,14371,14372,36949,36950,14373,36951,36952,36953,
+14374,36954,36961,36962,36963,36964,36965,36966,14375,14376,36967,14377,36968,
+14378,14379,36969,36970,14380,14381,36971,36972,36973,36974,36975,36976,36977,
+36978,36979,36980,36981,36982,36983,36984,36985,36986,36993,36994,36995,36996,
+36997,36998,36999,37000,37001,37002,37003,37004,37005,14382,14383,37006,37007,
+14384,37008,37009,37010,14385,37011,37012,37013,37014,37015,37016,37017,14386,
+14387,37018,14388,37019,14389,37020,37021,37022,37023,37024,37025,14390,14391,
+37026,37027,14392,37028,14393,14394,14395,14396,14397,37029,37030,37031,37032,
+37033,14398,14399,37034,14400,37035,14401,14402,37036,37037,14403,37038,14404,
+14405,14406,37039,37040,14407,37041,37042,37043,14408,37044,37045,37046,37047,
+37048,37049,37050,14409,14410,37051,14411,14412,14413,14414,37052,37053,37054,
+37055,37056,14415,14416,37057,37058,37059,37060,37061,37062,14417,37063,37064,
+37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,14418,37075,37076,
+37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089,
+37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102,
+37103,37104,37105,37106,37107,37108,14419,14420,37109,37110,14421,37111,37112,
+37113,14422,37114,14423,37115,37116,37117,37118,37185,14424,14425,37186,14426,
+37187,14427,14428,37188,37189,37190,37191,14429,14430,14431,37192,37193,14432,
+37194,37195,37196,14433,37197,37198,37199,37200,37201,37202,37203,14434,14435,
+37204,14436,14437,14438,37205,37206,37207,37208,37209,37210,14439,14440,37217,
+37218,14441,37219,37220,37221,14442,37222,37223,37224,37225,37226,37227,37228,
+37229,37230,37231,14443,14444,14445,37232,14446,37233,37234,37235,37236,14447,
+37237,37238,37239,37240,37241,37242,37249,37250,37251,37252,37253,37254,37255,
+37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268,
+37269,14448,14449,37270,14450,14451,37271,37272,37273,14452,37274,14453,37275,
+37276,37277,37278,37279,14454,14455,37280,14456,37281,14457,37282,37283,37284,
+37285,37286,37287,14458,37288,37289,37290,14459,37291,37292,37293,37294,37295,
+37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,14460,14461,37306,
+37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319,
+37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332,
+37333,37334,37335,37336,37337,37338,37339,14462,37340,37341,37342,14625,37343,
+37344,37345,14626,37346,37347,37348,37349,37350,37351,37352,37353,14627,37354,
+14628,37355,14629,37356,37357,37358,37359,37360,37361,14630,37362,37363,37364,
+14631,37365,37366,37367,14632,37368,37369,37370,37371,37372,37373,37374,37441,
+14633,37442,14634,37443,37444,37445,37446,37447,37448,37449,37450,14635,14636,
+14637,37451,14638,37452,37453,14639,14640,14641,14642,37454,37455,37456,37457,
+37458,14643,14644,37459,14645,37460,14646,37461,37462,37463,14647,37464,14648,
+14649,37465,37466,37473,14650,37474,37475,37476,14651,37477,37478,37479,37480,
+37481,37482,37483,37484,14652,37485,14653,37486,37487,37488,37489,37490,37491,
+37492,37493,14654,37494,37495,37496,37497,37498,37505,37506,37507,37508,37509,
+37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522,
+37523,37524,37525,37526,14655,37527,37528,37529,14656,37530,37531,37532,14657,
+37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545,
+37546,37547,37548,37549,37550,37551,14658,37552,37553,37554,14659,37555,37556,
+37557,14660,37558,37559,37560,37561,37562,37563,37564,14661,37565,37566,14662,
+37567,37568,37569,37570,37571,37572,37573,37574,14663,37575,37576,37577,14664,
+37578,37579,37580,14665,37581,37582,37583,37584,37585,37586,37587,14666,37588,
+37589,14667,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600,
+37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613,
+37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,14668,
+14669,37626,37627,14670,37628,37629,14671,14672,37630,14673,37697,37698,37699,
+37700,37701,14674,14675,37702,14676,14677,14678,37703,14679,37704,14680,37705,
+37706,14681,14682,14683,14684,14685,37707,37708,14686,14687,14688,14689,14690,
+37709,37710,37711,37712,14691,14692,37713,14693,37714,14694,37715,37716,37717,
+14695,37718,37719,14696,14697,37720,37721,14698,37722,37729,37730,14699,37731,
+37732,37733,37734,37735,37736,37737,14700,14701,37738,14702,14703,14704,37739,
+37740,37741,14705,37742,37743,14706,14707,37744,37745,14708,37746,37747,37748,
+37749,37750,37751,37752,37753,37754,37761,37762,37763,14709,37764,37765,37766,
+37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779,
+37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,
+37793,37794,37795,37796,37797,37798,37799,37800,37801,14710,14711,37802,37803,
+14712,37804,37805,14713,14714,37806,14715,37807,37808,37809,37810,37811,14716,
+14717,37812,14718,37813,14881,14882,37814,37815,37816,37817,37818,14883,14884,
+37819,37820,14885,37821,37822,14886,14887,37823,37824,37825,37826,37827,37828,
+37829,14888,14889,37830,14890,14891,14892,37831,37832,37833,37834,37835,37836,
+14893,14894,37837,37838,14895,37839,37840,37841,14896,37842,37843,37844,37845,
+37846,37847,37848,37849,14897,37850,14898,14899,14900,37851,37852,37853,14901,
+37854,37855,14902,37856,37857,37858,14903,37859,37860,37861,37862,37863,37864,
+37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,
+37878,37879,37880,37881,14904,14905,14906,37882,14907,37883,37884,37885,14908,
+37886,37953,37954,37955,37956,37957,37958,14909,14910,37959,14911,37960,14912,
+37961,37962,37963,37964,37965,37966,14913,37967,37968,37969,14914,37970,37971,
+37972,37973,37974,37975,37976,37977,37978,37985,37986,37987,37988,37989,37990,
+14915,37991,37992,37993,37994,37995,37996,37997,14916,37998,37999,38000,38001,
+38002,38003,38004,38005,38006,38007,38008,38009,38010,38017,38018,38019,38020,
+38021,38022,14917,38023,38024,38025,38026,38027,38028,38029,14918,14919,38030,
+38031,14920,38032,38033,38034,14921,38035,38036,38037,38038,38039,38040,38041,
+14922,14923,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,14924,
+38052,38053,38054,14925,38055,38056,38057,38058,38059,38060,38061,38062,38063,
+38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076,
+38077,14926,14927,38078,38079,14928,38080,38081,14929,14930,14931,14932,38082,
+38083,38084,38085,38086,14933,14934,38087,14935,38088,14936,38089,38090,38091,
+14937,14938,38092,14939,38093,38094,38095,38096,38097,38098,38099,14940,38100,
+38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,14941,38111,38112,
+38113,38114,38115,38116,38117,14942,38118,38119,38120,38121,38122,38123,38124,
+38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137,
+38138,38139,38140,38141,38142,38209,38210,14943,14944,38211,38212,14945,38213,
+38214,38215,14946,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225,
+38226,38227,14947,38228,38229,38230,38231,38232,38233,14948,38234,38241,38242,
+14949,38243,38244,38245,14950,38246,38247,38248,38249,38250,38251,38252,14951,
+38253,38254,14952,38255,14953,38256,38257,38258,38259,38260,38261,14954,14955,
+38262,38263,14956,38264,38265,38266,14957,38273,38274,38275,38276,38277,38278,
+38279,14958,14959,38280,14960,38281,38282,38283,38284,38285,38286,38287,38288,
+38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301,
+38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314,
+38315,38316,14961,14962,38317,38318,14963,38319,38320,38321,14964,38322,14965,
+38323,38324,38325,38326,38327,14966,14967,38328,14968,38329,14969,14970,14971,
+38330,38331,38332,38333,14972,14973,38334,38335,14974,38336,38337,38338,15137,
+38339,15138,38340,38341,38342,38343,38344,15139,15140,38345,15141,15142,15143,
+38346,38347,38348,38349,38350,15144,15145,15146,38351,38352,15147,38353,38354,
+38355,15148,38356,38357,38358,38359,38360,38361,38362,15149,15150,38363,15151,
+15152,15153,38364,38365,38366,38367,38368,38369,15154,15155,38370,38371,38372,
+38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,15156,38384,
+38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397,
+38398,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476,
+38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,15157,
+15158,38489,38490,15159,38497,38498,15160,15161,38499,38500,38501,38502,38503,
+38504,38505,15162,38506,38507,15163,15164,15165,38508,38509,38510,38511,38512,
+38513,15166,38514,38515,38516,38517,38518,38519,38520,38521,38522,38529,38530,
+38531,38532,38533,38534,38535,38536,38537,38538,38539,15167,38540,38541,38542,
+38543,38544,38545,15168,15169,38546,38547,38548,38549,38550,38551,38552,38553,
+38554,38555,38556,38557,38558,38559,15170,15171,38560,15172,15173,15174,38561,
+38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574,
+38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587,
+38588,38589,38590,38591,38592,38593,38594,15175,15176,38595,38596,15177,38597,
+38598,38599,15178,38600,38601,38602,38603,38604,38605,38606,15179,15180,38607,
+38608,38609,15181,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619,
+38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632,
+38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645,
+38646,38647,38648,38649,38650,38651,38652,38653,38654,38721,38722,38723,38724,
+38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,
+15182,38738,38739,38740,38741,38742,38743,38744,38745,38746,38753,38754,38755,
+38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768,
+38769,38770,15183,38771,38772,38773,38774,38775,38776,38777,38778,38785,38786,
+38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,15184,38797,38798,
+38799,38800,38801,38802,15185,15186,38803,38804,15187,38805,38806,38807,15188,
+38808,38809,38810,38811,38812,38813,38814,15189,38815,38816,15190,38817,15191,
+38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830,
+38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843,
+38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,
+38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,
+38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,
+38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895,
+38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,15192,
+38908,38909,38910,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,
+38987,38988,38989,38990,38991,38992,38993,15193,38994,38995,38996,38997,38998,
+38999,15194,39000,39001,39002,15195,39009,39010,39011,15196,39012,39013,39014,
+39015,39016,39017,39018,15197,15198,39019,39020,39021,39022,39023,39024,39025,
+39026,39027,39028,39029,39030,39031,39032,39033,39034,39041,39042,39043,39044,
+39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057,
+39058,39059,39060,39061,39062,15199,15200,39063,39064,15201,39065,39066,39067,
+15202,39068,39069,39070,39071,39072,39073,39074,15203,15204,39075,15205,39076,
+15206,39077,39078,39079,39080,39081,39082,15207,15208,39083,15209,15210,39084,
+39085,15211,15212,15213,15214,39086,39087,39088,39089,39090,15215,15216,39091,
+15217,15218,15219,39092,39093,39094,15220,39095,39096,15221,15222,39097,39098,
+15223,39099,39100,39101,15224,39102,39103,39104,39105,39106,39107,39108,15225,
+15226,39109,15227,15228,15229,39110,39111,39112,39113,39114,39115,15230,15393,
+39116,39117,15394,39118,39119,39120,15395,39121,39122,39123,39124,39125,39126,
+39127,15396,15397,39128,15398,39129,15399,39130,39131,39132,39133,39134,39135,
+15400,39136,39137,39138,15401,39139,39140,39141,15402,39142,39143,39144,39145,
+39146,39147,39148,15403,39149,39150,39151,39152,15404,39153,39154,39155,39156,
+39157,39158,15405,15406,15407,15408,15409,39159,39160,15410,15411,39161,15412,
+15413,39162,39163,39164,39165,15414,15415,39166,15416,15417,15418,39233,39234,
+39235,39236,15419,39237,15420,15421,39238,39239,15422,39240,39241,39242,15423,
+39243,39244,39245,39246,39247,39248,39249,15424,15425,39250,15426,15427,15428,
+39251,39252,39253,39254,39255,39256,15429,15430,39257,39258,15431,39265,39266,
+39267,15432,39268,39269,39270,39271,39272,39273,39274,15433,15434,39275,15435,
+15436,15437,39276,39277,39278,39279,39280,39281,15438,39282,39283,39284,15439,
+39285,39286,39287,15440,39288,39289,39290,39297,39298,39299,39300,39301,39302,
+39303,39304,39305,15441,39306,39307,39308,39309,39310,39311,15442,15443,15444,
+39312,15445,39313,39314,39315,15446,39316,15447,39317,39318,39319,39320,39321,
+15448,15449,39322,15450,39323,15451,39324,39325,39326,15452,39327,39328,15453,
+15454,39329,39330,15455,39331,39332,39333,15456,39334,39335,39336,39337,39338,
+39339,39340,39341,39342,39343,39344,39345,15457,39346,39347,39348,39349,39350,
+39351,15458,39352,39353,39354,15459,39355,39356,39357,15460,39358,39359,39360,
+39361,39362,39363,39364,15461,39365,39366,15462,15463,39367,39368,39369,39370,
+39371,39372,39373,15464,39374,39375,39376,15465,39377,39378,39379,15466,39380,
+39381,39382,39383,39384,39385,39386,15467,15468,39387,15469,39388,39389,39390,
+39391,39392,39393,39394,39395,15470,15471,39396,39397,15472,39398,39399,39400,
+15473,39401,39402,39403,39404,39405,39406,39407,15474,15475,39408,15476,39409,
+15477,39410,39411,39412,39413,39414,39415,15478,15479,39416,39417,15480,39418,
+39419,15481,15482,39420,39421,39422,39489,39490,39491,39492,15483,15484,39493,
+15485,39494,15486,39495,15649,39496,15650,15651,39497,15652,39498,39499,39500,
+39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,
+39514,39521,39522,15653,39523,39524,39525,39526,39527,39528,39529,15654,15655,
+39530,39531,15656,39532,39533,39534,15657,39535,39536,39537,39538,39539,39540,
+39541,15658,39542,39543,39544,39545,15659,39546,39553,39554,39555,39556,39557,
+15660,15661,39558,39559,15662,39560,39561,39562,15663,39563,39564,39565,39566,
+39567,39568,39569,15664,15665,39570,15666,39571,15667,39572,39573,39574,39575,
+39576,39577,15668,15669,39578,39579,39580,39581,39582,39583,15670,39584,39585,
+39586,39587,39588,39589,39590,15671,39591,39592,15672,39593,15673,39594,39595,
+39596,39597,39598,39599,15674,15675,39600,39601,15676,39602,39603,39604,15677,
+15678,39605,39606,39607,39608,39609,39610,15679,15680,39611,15681,39612,15682,
+39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625,
+39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638,
+39639,39640,39641,39642,39643,39644,39645,39646,15683,15684,39647,39648,15685,
+39649,39650,15686,15687,39651,39652,39653,39654,39655,39656,15688,15689,15690,
+39657,15691,39658,15692,39659,39660,39661,39662,15693,39663,15694,15695,39664,
+15696,15697,39665,39666,39667,15698,39668,39669,39670,39671,39672,39673,39674,
+15699,15700,39675,39676,15701,15702,39677,39678,39745,39746,39747,15703,15704,
+15705,39748,39749,15706,39750,39751,39752,15707,39753,39754,39755,39756,39757,
+39758,39759,15708,15709,39760,39761,15710,15711,39762,39763,39764,39765,39766,
+39767,39768,39769,39770,39777,39778,39779,39780,39781,39782,39783,39784,39785,
+39786,39787,39788,39789,39790,39791,39792,39793,39794,15712,39795,39796,39797,
+39798,39799,39800,39801,39802,39809,39810,39811,39812,39813,39814,39815,39816,
+39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,
+39830,39831,39832,39833,39834,15713,15714,39835,39836,15715,39837,39838,39839,
+15716,39840,15717,39841,39842,39843,39844,39845,15718,15719,39846,39847,15720,
+15721,39848,39849,39850,39851,39852,39853,15722,39854,39855,39856,15723,39857,
+39858,39859,15724,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,
+39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,
+39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,
+39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908,
+39909,39910,15725,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,
+39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,
+15726,15727,39934,40001,15728,40002,40003,15729,15730,40004,15731,40005,40006,
+40007,40008,40009,15732,15733,40010,40011,40012,15734,40013,40014,40015,40016,
+40017,40018,15735,15736,40019,40020,15737,40021,40022,40023,40024,40025,40026,
+40033,40034,40035,40036,40037,40038,40039,40040,40041,15738,40042,40043,40044,
+40045,40046,40047,40048,15739,40049,40050,40051,40052,40053,40054,40055,40056,
+40057,40058,40065,40066,40067,40068,40069,40070,40071,40072,40073,15740,40074,
+40075,40076,40077,40078,40079,40080,15741,40081,40082,40083,15742,40084,40085,
+40086,15905,40087,40088,40089,40090,40091,40092,40093,15906,15907,40094,40095,
+40096,40097,40098,40099,40100,40101,40102,40103,15908,40104,40105,40106,40107,
+40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120,
+40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,15909,15910,40131,
+40132,15911,40133,40134,40135,15912,40136,40137,40138,40139,40140,40141,40142,
+15913,15914,40143,40144,40145,15915,40146,40147,40148,40149,40150,40151,15916,
+40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164,
+40165,40166,40167,40168,40169,40170,15917,40171,40172,40173,40174,40175,40176,
+40177,15918,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188,
+40189,40190,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267,
+40268,40269,40270,15919,40271,40272,40273,15920,40274,40275,40276,40277,40278,
+40279,40280,40281,40282,40289,40290,40291,40292,40293,40294,40295,40296,40297,
+40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,
+40311,40312,40313,40314,40321,40322,40323,40324,40325,40326,40327,40328,40329,
+15921,40330,40331,40332,40333,40334,40335,15922,15923,40336,40337,15924,40338,
+40339,40340,15925,40341,15926,40342,40343,40344,40345,15927,15928,15929,40346,
+40347,40348,40349,40350,40351,40352,40353,40354,40355,15930,40356,40357,40358,
+15931,40359,40360,40361,15932,40362,40363,40364,40365,40366,40367,40368,15933,
+40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,15934,15935,
+40380,40381,15936,40382,40383,40384,15937,40385,40386,40387,40388,40389,40390,
+40391,15938,15939,40392,15940,40393,15941,40394,40395,40396,40397,40398,40399,
+15942,15943,40400,40401,15944,15945,15946,40402,15947,15948,15949,40403,40404,
+40405,40406,15950,15951,15952,40407,15953,15954,15955,40408,40409,40410,15956,
+15957,40411,15958,15959,40412,40413,15960,40414,40415,40416,15961,40417,40418,
+40419,40420,40421,40422,40423,15962,15963,40424,15964,15965,15966,40425,40426,
+40427,40428,40429,40430,15967,15968,40431,40432,15969,40433,40434,40435,15970,
+40436,40437,15971,40438,40439,40440,40441,15972,15973,40442,15974,40443,15975,
+40444,40445,40446,15976,40513,15977,15978,40514,40515,40516,15979,40517,40518,
+40519,15980,40520,40521,40522,40523,40524,40525,40526,40527,15981,40528,40529,
+40530,40531,40532,40533,40534,40535,40536,40537,15982,15983,40538,40545,15984,
+15985,40546,15986,15987,15988,15989,40547,40548,40549,40550,40551,15990,15991,
+15992,15993,15994,15995,15996,40552,15997,40553,15998,40554,16161,16162,40555,
+40556,16163,40557,40558,40559,16164,40560,40561,40562,40563,40564,40565,40566,
+16165,16166,40567,16167,40568,16168,40569,40570,40577,40578,40579,40580,16169,
+16170,16171,40581,16172,40582,40583,40584,16173,40585,16174,16175,40586,40587,
+40588,40589,16176,16177,16178,16179,16180,16181,40590,40591,40592,16182,16183,
+16184,16185,40593,40594,40595,16186,40596,40597,40598,16187,40599,40600,40601,
+40602,40603,40604,40605,16188,16189,40606,16190,16191,40607,40608,40609,40610,
+40611,40612,40613,16192,16193,40614,40615,16194,40616,40617,40618,16195,16196,
+16197,40619,16198,40620,40621,16199,16200,16201,40622,16202,40623,16203,40624,
+16204,40625,40626,40627,40628,16205,16206,40629,40630,16207,40631,40632,40633,
+16208,40634,40635,40636,40637,40638,40639,40640,16209,16210,40641,16211,16212,
+16213,40642,40643,40644,40645,40646,40647,16214,16215,40648,40649,16216,40650,
+40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,16217,40661,40662,
+16218,40663,16219,40664,40665,40666,40667,40668,40669,16220,16221,40670,40671,
+16222,40672,40673,40674,16223,40675,40676,40677,40678,40679,40680,40681,16224,
+16225,40682,16226,40683,16227,40684,40685,40686,40687,40688,40689,16228,16229,
+40690,40691,16230,40692,40693,40694,16231,40695,40696,40697,40698,40699,40700,
+40701,16232,16233,40702,16234,40769,16235,40770,40771,40772,40773,40774,40775,
+16236,16237,40776,40777,16238,40778,40779,40780,16239,16240,16241,40781,40782,
+40783,40784,40785,16242,16243,40786,16244,40787,16245,40788,40789,40790,40791,
+40792,40793,16246,16247,40794,40801,16248,40802,40803,40804,16249,40805,40806,
+40807,40808,40809,40810,40811,16250,16251,40812,40813,16252,16253,40814,40815,
+40816,40817,40818,40819,16254,16417,40820,40821,16418,40822,40823,40824,16419,
+40825,40826,40833,40834,40835,40836,40837,16420,16421,40838,40839,40840,16422,
+40841,40842,40843,40844,40845,40846,16423,16424,40847,40848,16425,40849,40850,
+40851,16426,40852,40853,40854,40855,40856,40857,40858,16427,16428,40859,16429,
+40860,16430,40861,40862,40863,40864,40865,40866,16431,16432,40867,40868,16433,
+40869,40870,40871,16434,40872,40873,40874,40875,40876,40877,40878,16435,16436,
+40879,16437,40880,16438,40881,16439,40882,40883,40884,40885,16440,16441,40886,
+40887,16442,40888,40889,40890,16443,40891,40892,40893,40894,40895,16444,40896,
+16445,16446,40897,16447,40898,16448,16449,16450,16451,16452,16453,16454,16455,
+40899,40900,40901,16456,40902,40903,40904,16457,40905,40906,40907,40908,40909,
+40910,40911,16458,40912,40913,16459,40914,40915,40916,40917,40918,40919,40920,
+40921,16460,16461,40922,40923,16462,40924,40925,40926,16463,16464,16465,40927,
+40928,40929,40930,16466,16467,16468,40931,16469,16470,16471,16472,40932,40933,
+40934,16473,40935,16474,16475,40936,40937,16476,40938,16477,16478,16479,40939,
+16480,40940,40941,40942,40943,40944,16481,16482,40945,16483,16484,16485,16486,
+40946,40947,40948,40949,40950,16487,16488,40951,40952,16489,40953,40954,40955,
+16490,40956,40957,40958,41025,41026,41027,41028,16491,16492,41029,16493,16494,
+16495,41030,41031,41032,41033,41034,41035,16496,16497,41036,41037,16498,41038,
+16499,41039,16500,41040,41041,41042,41043,41044,41045,41046,16501,41047,41048,
+41049,41050,16502,41057,41058,41059,41060,41061,41062,16503,41063,41064,41065,
+16504,41066,41067,41068,16505,41069,41070,41071,41072,41073,41074,41075,41076,
+41077,41078,41079,41080,41081,41082,41089,41090,41091,41092,41093,16506,16507,
+41094,41095,16508,41096,41097,41098,16509,41099,16510,41100,41101,41102,41103,
+41104,16673,16674,41105,16675,41106,16676,16677,41107,41108,41109,41110,41111,
+16678,16679,41112,41113,16680,41114,41115,41116,16681,41117,41118,41119,41120,
+41121,41122,41123,16682,16683,41124,16684,41125,16685,41126,41127,41128,41129,
+41130,41131,16686,41132,41133,41134,16687,41135,41136,41137,16688,41138,41139,
+41140,41141,41142,41143,41144,16689,16690,41145,41146,16691,16692,41147,41148,
+41149,41150,41151,41152,16693,41153,41154,41155,41156,41157,41158,41159,41160,
+41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,
+41174,41175,41176,41177,41178,41179,16694,16695,41180,41181,16696,41182,41183,
+41184,16697,41185,16698,41186,41187,41188,41189,41190,16699,16700,41191,16701,
+41192,16702,16703,16704,41193,41194,41195,16705,16706,16707,41196,41197,41198,
+41199,41200,41201,16708,41202,41203,41204,41205,41206,41207,41208,41209,16709,
+41210,16710,41211,16711,41212,41213,41214,41281,41282,41283,16712,41284,41285,
+41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298,
+41299,41300,41301,41302,16713,16714,41303,41304,41305,41306,41313,41314,16715,
+41315,41316,41317,16716,41318,41319,41320,16717,41321,41322,41323,41324,41325,
+41326,41327,16718,16719,41328,16720,41329,16721,41330,41331,41332,41333,41334,
+41335,16722,16723,41336,41337,16724,41338,41345,41346,41347,41348,41349,41350,
+41351,41352,41353,41354,41355,41356,41357,41358,41359,16725,41360,41361,41362,
+41363,41364,41365,16726,16727,41366,41367,16728,41368,41369,41370,16729,16730,
+16731,41371,41372,41373,41374,41375,16732,16733,41376,16734,41537,16735,41538,
+41539,41540,41541,41542,41543,16736,41544,41545,41546,41547,41548,41549,41550,
+41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,16737,
+41569,41570,41571,41572,41573,41574,41575,16738,41576,41577,41578,41579,41580,
+41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,
+41594,41601,41602,41603,41604,41605,41606,41607,41608,16739,16740,41609,41610,
+16741,41611,41612,41613,16742,41614,41615,41616,41617,41618,41619,41620,16743,
+16744,41621,16745,41622,41623,41624,41625,41626,41627,41628,41629,16746,41630,
+41631,41632,16747,41793,41794,41795,16748,41796,41797,41798,41799,41800,41801,
+41802,16749,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813,
+16750,16751,41814,41815,16752,41816,41817,41818,16753,41825,41826,41827,41828,
+41829,41830,41831,16754,16755,41832,16756,41833,16757,41834,41835,41836,41837,
+41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850,
+41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869,
+41870,41871,41872,41873,16758,16759,41874,41875,16760,41876,41877,16761,16762,
+41878,16763,41879,41880,41881,41882,41883,16764,16765,41884,16766,41885,16929,
+16930,41886,41887,16931,16932,41888,16933,16934,42049,42050,16935,42051,16936,
+42052,16937,42053,42054,16938,42055,42056,42057,42058,16939,16940,42059,16941,
+16942,16943,42060,42061,42062,42063,42064,42065,16944,16945,42066,42067,16946,
+42068,42069,42070,16947,42071,42072,42073,42074,42081,42082,42083,16948,16949,
+42084,16950,16951,16952,42085,42086,42087,42088,42089,42090,16953,42091,42092,
+42093,16954,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104,
+42105,42106,42113,42114,42115,16955,42116,42117,42118,42119,42120,42121,42122,
+42123,42124,42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135,
+42136,42137,42138,42139,42140,42141,42142,42143,42144,42305,42306,42307,42308,
+42309,16956,16957,42310,42311,16958,42312,42313,42314,16959,42315,42316,42317,
+42318,42319,42320,42321,16960,16961,42322,16962,16963,16964,42323,42324,42325,
+42326,42327,42328,16965,42329,42330,42337,42338,42339,42340,42341,42342,42343,
+42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,16966,42355,
+42356,42357,42358,42359,42360,16967,42361,42362,42369,42370,42371,42372,42373,
+42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,16968,
+42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,
+42399,42400,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,
+42572,42573,42574,42575,42576,42577,42578,42579,42580,16969,16970,42581,42582,
+16971,42583,42584,42585,16972,42586,42593,42594,42595,42596,42597,42598,16973,
+16974,42599,16975,42600,16976,42601,16977,42602,42603,42604,42605,16978,16979,
+42606,42607,42608,42609,42610,42611,16980,42612,42613,42614,42615,42616,42617,
+42618,42625,42626,42627,42628,16981,42629,42630,42631,42632,42633,42634,42635,
+16982,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647,
+42648,42649,42650,42651,42652,42653,42654,16983,42655,42656,42817,42818,42819,
+42820,42821,16984,42822,42823,42824,16985,42825,42826,42827,16986,42828,42829,
+42830,42831,42832,42833,42834,16987,16988,42835,42836,42837,42838,42839,42840,
+42841,42842,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859,
+42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,16989,
+42872,42873,42874,42881,42882,42883,16990,16991,42884,42885,16992,42886,42887,
+42888,16993,42889,42890,42891,42892,42893,42894,42895,16994,16995,42896,42897,
+42898,16996,42899,42900,42901,42902,42903,42904,16997,42905,42906,42907,42908,
+42909,42910,42911,42912,43073,43074,43075,43076,43077,43078,43079,43080,43081,
+43082,43083,16998,16999,43084,43085,43086,43087,43088,43089,43090,43091,43092,
+43093,43094,43095,43096,43097,43098,43105,43106,43107,43108,43109,43110,43111,
+43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,17000,
+43124,43125,43126,43127,43128,43129,43130,43137,43138,43139,43140,43141,43142,
+43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155,
+43156,17001,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167,
+43168,43329,43330,43331,43332,43333,43334,43335,43336,43337,43338,43339,43340,
+43341,43342,43343,17002,43344,43345,43346,43347,43348,43349,43350,43351,43352,
+43353,43354,43361,43362,43363,43364,17003,43365,43366,17004,43367,17005,43368,
+43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381,
+43382,43383,43384,43385,43386,43393,43394,43395,43396,43397,43398,43399,43400,
+43401,43402,43403,43404,43405,43406,43407,17006,17007,43408,43409,17008,43410,
+43411,43412,17009,43413,43414,43415,43416,43417,43418,43419,17010,17011,43420,
+43421,43422,17012,17013,43423,43424,43585,43586,17014,17015,17016,43587,43588,
+17017,43589,17018,43590,17019,43591,43592,43593,43594,43595,43596,43597,17020,
+17021,43598,17022,17185,17186,17187,43599,43600,43601,43602,43603,17188,17189,
+43604,43605,17190,43606,43607,43608,17191,43609,43610,43617,43618,43619,43620,
+43621,17192,17193,43622,17194,17195,17196,43623,43624,43625,43626,43627,43628,
+17197,43629,43630,43631,17198,43632,17199,43633,17200,43634,43635,43636,43637,
+43638,43639,43640,17201,43641,43642,43649,43650,17202,43651,43652,43653,43654,
+43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667,
+43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680,
+43841,43842,43843,43844,17203,17204,43845,43846,17205,43847,43848,43849,17206,
+43850,43851,43852,43853,43854,43855,43856,17207,17208,43857,17209,17210,17211,
+43858,43859,43860,43861,43862,43863,17212,17213,43864,43865,17214,43866,43873,
+43874,17215,43875,43876,43877,43878,43879,43880,43881,17216,17217,43882,17218,
+43883,17219,43884,43885,43886,43887,43888,43889,17220,43890,43891,43892,17221,
+43893,43894,43895,43896,43897,43898,43905,43906,43907,43908,43909,43910,43911,
+43912,43913,17222,43914,43915,43916,43917,43918,43919,43920,17223,43921,43922,
+43923,17224,43924,43925,43926,43927,43928,43929,43930,43931,43932,43933,43934,
+43935,43936,44097,44098,44099,17225,44100,44101,44102,44103,44104,44105,17226,
+17227,44106,44107,17228,44108,44109,44110,17229,44111,44112,44113,44114,44115,
+44116,44117,17230,17231,44118,17232,44119,17233,44120,44121,44122,44129,44130,
+44131,17234,44132,44133,44134,17235,44135,44136,44137,17236,44138,44139,44140,
+44141,44142,44143,44144,44145,44146,44147,44148,44149,17237,44150,44151,44152,
+44153,44154,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171,
+44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184,
+44185,44186,44187,44188,44189,17238,44190,44191,44192,17239,44353,44354,44355,
+17240,44356,44357,44358,44359,44360,44361,44362,17241,17242,44363,17243,44364,
+17244,44365,44366,44367,44368,44369,44370,17245,44371,44372,44373,44374,44375,
+44376,44377,44378,44385,44386,44387,44388,44389,44390,44391,17246,44392,44393,
+44394,44395,44396,44397,44398,44399,44400,44401,44402,17247,17248,44403,44404,
+17249,44405,44406,44407,17250,44408,44409,44410,44417,44418,44419,44420,17251,
+17252,44421,17253,44422,17254,44423,44424,44425,44426,44427,44428,17255,44429,
+44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,
+44443,44444,44445,44446,44447,17256,44448,44609,44610,44611,44612,44613,44614,
+17257,44615,44616,44617,17258,44618,44619,44620,44621,44622,44623,44624,44625,
+44626,44627,44628,44629,44630,44631,44632,44633,44634,44641,44642,44643,44644,
+44645,44646,17259,44647,44648,44649,17260,44650,44651,44652,17261,44653,44654,
+44655,44656,44657,44658,44659,17262,17263,44660,17264,44661,17265,44662,44663,
+44664,44665,44666,44673,17266,44674,44675,44676,17267,44677,44678,44679,17268,
+44680,44681,44682,44683,44684,44685,44686,17269,44687,44688,44689,44690,17270,
+44691,44692,44693,44694,44695,44696,17271,17272,44697,44698,17273,44699,44700,
+44701,17274,44702,44703,44704,44865,44866,44867,44868,17275,17276,44869,17277,
+44870,17278,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881,
+44882,44883,44884,44885,44886,44887,44888,44889,44890,44897,44898,44899,44900,
+44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,17441,17442,44911,
+44912,17443,44913,44914,17444,17445,17446,44915,44916,44917,44918,44919,44920,
+17447,17448,44921,17449,44922,17450,44929,44930,44931,44932,44933,44934,17451,
+17452,44935,44936,17453,44937,44938,44939,17454,44940,44941,44942,44943,44944,
+44945,44946,17455,17456,44947,17457,44948,17458,44949,44950,44951,44952,44953,
+44954,17459,17460,44955,44956,17461,44957,44958,44959,17462,44960,45121,45122,
+45123,45124,45125,45126,17463,17464,45127,17465,17466,17467,45128,45129,45130,
+45131,45132,45133,17468,17469,45134,45135,45136,45137,45138,45139,45140,45141,
+45142,45143,45144,45145,45146,45153,45154,45155,45156,45157,45158,17470,45159,
+45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172,
+45173,45174,45175,45176,45177,45178,45185,45186,45187,45188,45189,45190,45191,
+45192,45193,45194,45195,45196,45197,45198,17471,17472,45199,45200,17473,45201,
+45202,17474,17475,45203,45204,45205,45206,45207,45208,45209,17476,17477,45210,
+17478,17479,17480,45211,45212,45213,45214,45215,45216,17481,17482,45377,45378,
+17483,45379,45380,45381,17484,45382,45383,45384,45385,45386,45387,45388,17485,
+17486,45389,17487,45390,17488,45391,45392,45393,45394,45395,45396,17489,45397,
+45398,45399,17490,45400,45401,45402,17491,45409,45410,45411,45412,45413,45414,
+45415,17492,17493,45416,17494,17495,17496,45417,45418,45419,45420,45421,45422,
+17497,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434,
+45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453,
+45454,45455,17498,17499,45456,45457,17500,45458,45459,45460,17501,45461,45462,
+45463,45464,45465,45466,45467,17502,17503,45468,17504,45469,17505,45470,45471,
+45472,45633,45634,45635,17506,17507,45636,45637,17508,45638,45639,45640,17509,
+45641,45642,45643,45644,45645,45646,45647,17510,45648,45649,45650,45651,17511,
+45652,45653,45654,45655,45656,45657,17512,45658,45665,45666,45667,45668,45669,
+45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682,
+45683,17513,45684,45685,45686,45687,45688,45689,17514,45690,45697,45698,45699,
+45700,45701,45702,17515,45703,45704,45705,45706,45707,45708,45709,45710,45711,
+45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,17516,45722,45723,
+45724,45725,45726,45727,45728,45889,45890,45891,45892,45893,45894,45895,45896,
+45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,17517,
+17518,45909,45910,17519,45911,45912,45913,17520,45914,45921,45922,45923,45924,
+45925,45926,17521,17522,45927,17523,45928,17524,45929,45930,45931,45932,45933,
+45934,17525,45935,45936,45937,17526,45938,45939,45940,17527,45941,45942,45943,
+45944,45945,45946,45953,45954,45955,45956,45957,45958,17528,45959,45960,45961,
+45962,45963,45964,17529,45965,45966,45967,45968,45969,45970,45971,45972,45973,
+45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,17530,46145,
+46146,46147,46148,46149,46150,17531,17532,46151,46152,17533,46153,46154,46155,
+17534,46156,46157,46158,46159,46160,46161,46162,17697,17698,46163,17699,46164,
+17700,46165,46166,46167,46168,46169,46170,17701,46177,46178,46179,17702,46180,
+46181,46182,17703,46183,46184,46185,46186,46187,46188,46189,17704,46190,46191,
+46192,46193,46194,46195,46196,46197,46198,46199,46200,17705,17706,46201,46202,
+17707,46209,46210,46211,17708,46212,46213,46214,46215,46216,46217,46218,17709,
+17710,46219,46220,46221,17711,46222,46223,46224,46225,46226,46227,46228,46229,
+46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46401,46402,
+46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,
+17712,17713,46416,46417,17714,46418,46419,46420,17715,46421,46422,46423,46424,
+46425,46426,46433,17716,17717,46434,17718,46435,17719,46436,46437,46438,46439,
+46440,46441,17720,17721,46442,46443,17722,46444,46445,46446,17723,17724,46447,
+46448,46449,46450,46451,46452,17725,17726,46453,17727,17728,17729,46454,46455,
+46456,46457,46458,46465,17730,17731,46466,46467,17732,46468,46469,46470,17733,
+46471,46472,46473,46474,46475,46476,46477,17734,17735,46478,17736,17737,17738,
+46479,46480,46481,46482,46483,46484,17739,46485,46486,46487,46488,46489,46490,
+46491,46492,46493,46494,46495,46496,46657,46658,46659,46660,46661,46662,46663,
+46664,17740,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675,
+46676,46677,46678,46679,46680,46681,46682,46689,46690,46691,46692,46693,46694,
+46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,17741,17742,46705,
+46706,17743,46707,46708,46709,17744,46710,17745,46711,46712,46713,46714,46721,
+17746,17747,46722,17748,17749,17750,46723,46724,46725,46726,46727,46728,17751,
+17752,46729,46730,17753,46731,46732,46733,17754,46734,46735,46736,46737,46738,
+46739,46740,17755,17756,46741,17757,46742,17758,46743,46744,46745,46746,46747,
+46748,17759,46749,46750,46751,17760,46752,46913,46914,46915,46916,46917,46918,
+46919,46920,46921,46922,46923,46924,46925,46926,17761,46927,46928,46929,46930,
+46931,46932,46933,17762,46934,46935,46936,17763,46937,46938,46945,46946,46947,
+46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960,
+46961,46962,46963,46964,46965,17764,17765,46966,46967,17766,46968,46969,46970,
+17767,46977,46978,46979,46980,46981,46982,46983,17768,17769,46984,17770,46985,
+17771,46986,46987,46988,46989,17772,46990,17773,46991,46992,46993,17774,46994,
+46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007,
+47008,47169,47170,47171,47172,47173,47174,47175,47176,17775,47177,47178,47179,
+47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192,
+47193,47194,47201,47202,47203,47204,47205,47206,47207,47208,47209,17776,47210,
+47211,47212,17777,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222,
+47223,47224,47225,47226,17778,47233,17779,47234,47235,47236,47237,47238,47239,
+17780,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251,
+47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264,
+47425,47426,17781,17782,47427,47428,17783,47429,47430,47431,17784,47432,47433,
+47434,47435,47436,47437,47438,17785,17786,47439,17787,47440,17788,47441,47442,
+47443,47444,47445,47446,17789,47447,47448,47449,47450,47457,47458,47459,47460,
+47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,17790,47472,
+47473,47474,47475,47476,47477,47478,17953,47479,47480,47481,47482,47489,47490,
+47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503,
+47504,47505,47506,47507,47508,47509,47510,47511,17954,17955,47512,47513,17956,
+47514,47515,47516,17957,47517,47518,47519,47520,47681,47682,47683,17958,17959,
+47684,47685,47686,17960,47687,47688,47689,47690,47691,47692,17961,47693,47694,
+47695,17962,47696,47697,47698,17963,47699,47700,47701,47702,47703,47704,47705,
+17964,47706,47713,47714,47715,17965,47716,47717,47718,47719,47720,47721,17966,
+17967,47722,47723,17968,47724,47725,17969,17970,47726,17971,47727,47728,47729,
+47730,47731,17972,17973,47732,17974,47733,47734,47735,47736,47737,47738,47745,
+47746,17975,47747,47748,47749,17976,47750,47751,47752,17977,47753,47754,47755,
+47756,47757,47758,47759,17978,17979,47760,47761,47762,47763,47764,47765,47766,
+47767,47768,47769,17980,17981,47770,47771,17982,47772,47773,47774,17983,47775,
+47776,47937,47938,47939,47940,47941,17984,17985,47942,17986,47943,17987,47944,
+47945,47946,47947,47948,47949,17988,17989,17990,47950,17991,47951,47952,47953,
+17992,47954,17993,47955,47956,47957,47958,47959,17994,17995,47960,17996,17997,
+17998,47961,47962,47969,17999,47970,47971,18000,18001,47972,47973,18002,47974,
+47975,47976,18003,47977,47978,47979,47980,47981,47982,47983,18004,18005,47984,
+18006,18007,18008,47985,47986,47987,47988,47989,47990,18009,18010,47991,47992,
+47993,47994,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011,
+48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024,
+48025,48026,48027,48028,48029,48030,48031,48032,48193,48194,48195,48196,48197,
+48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210,
+18011,18012,48211,48212,18013,48213,48214,48215,18014,48216,48217,48218,48225,
+48226,48227,48228,18015,18016,48229,18017,18018,18019,48230,48231,48232,48233,
+48234,48235,18020,18021,48236,48237,18022,48238,48239,48240,18023,48241,48242,
+48243,48244,48245,48246,48247,18024,18025,48248,18026,48249,18027,48250,48257,
+48258,48259,48260,48261,18028,48262,48263,48264,18029,48265,48266,48267,18030,
+48268,48269,48270,48271,48272,48273,48274,18031,18032,48275,48276,18033,18034,
+48277,48278,48279,48280,48281,48282,18035,48283,48284,48285,48286,48287,48288,
+48449,18036,48450,48451,48452,48453,48454,48455,48456,48457,18037,48458,18038,
+48459,48460,48461,48462,48463,48464,48465,48466,18039,18040,48467,48468,18041,
+48469,48470,48471,18042,48472,48473,48474,48481,48482,48483,48484,18043,18044,
+48485,18045,48486,18046,48487,48488,48489,48490,48491,48492,18209,48493,48494,
+48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48513,
+48514,48515,48516,48517,48518,18210,48519,48520,48521,48522,48523,48524,48525,
+48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538,
+48539,48540,48541,48542,48543,48544,48705,48706,48707,48708,48709,48710,48711,
+48712,18211,48713,48714,48715,18212,48716,48717,48718,48719,48720,48721,48722,
+48723,48724,48725,48726,48727,48728,48729,48730,48737,48738,48739,48740,48741,
+48742,48743,48744,18213,48745,48746,48747,18214,48748,48749,48750,18215,48751,
+48752,48753,48754,48755,48756,48757,48758,18216,48759,18217,48760,48761,48762,
+48769,48770,48771,48772,48773,18218,18219,48774,48775,18220,48776,48777,18221,
+18222,48778,18223,48779,48780,48781,48782,48783,18224,18225,48784,18226,48785,
+18227,48786,48787,48788,48789,48790,48791,18228,48792,48793,48794,48795,48796,
+48797,48798,48799,48800,48961,48962,48963,48964,48965,48966,48967,48968,48969,
+48970,48971,18229,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981,
+48982,48983,48984,48985,48986,48993,48994,48995,48996,48997,48998,48999,49000,
+49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,18230,49012,
+49013,49014,18231,49015,49016,49017,18232,49018,49025,49026,49027,49028,49029,
+49030,18233,49031,49032,18234,49033,49034,49035,49036,49037,49038,49039,49040,
+18235,49041,49042,49043,18236,49044,49045,49046,18237,49047,49048,49049,49050,
+49051,49052,49053,18238,49054,49055,18239,49056,18240,49217,49218,49219,49220,
+49221,49222,18241,49223,49224,49225,18242,49226,49227,49228,18243,49229,49230,
+49231,49232,49233,49234,49235,18244,18245,49236,18246,49237,49238,49239,49240,
+49241,49242,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259,
+49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272,
+49273,49274,49281,49282,49283,49284,18247,18248,49285,49286,18249,49287,49288,
+49289,18250,49290,49291,49292,49293,49294,49295,49296,18251,18252,49297,18253,
+49298,18254,49299,49300,49301,49302,49303,49304,18255,18256,49305,49306,18257,
+49307,49308,49309,18258,49310,49311,49312,49473,18259,49474,49475,18260,18261,
+49476,18262,49477,18263,49478,49479,49480,49481,49482,49483,18264,18265,49484,
+49485,18266,49486,49487,49488,18267,49489,49490,49491,49492,49493,49494,49495,
+18268,18269,49496,18270,18271,18272,49497,49498,49505,49506,49507,49508,18273,
+49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521,
+49522,49523,49524,49525,49526,49527,49528,18274,49529,49530,49537,49538,49539,
+49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552,
+49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565,
+49566,49567,49568,18275,18276,49729,49730,18277,49731,49732,49733,18278,49734,
+18279,49735,49736,49737,49738,49739,18280,18281,49740,18282,49741,18283,49742,
+49743,49744,49745,49746,49747,18284,18285,49748,49749,18286,49750,49751,49752,
+18287,49753,49754,49761,49762,49763,49764,49765,18288,18289,49766,18290,49767,
+18291,49768,49769,49770,49771,49772,49773,18292,18293,49774,49775,18294,49776,
+49777,49778,18295,49779,49780,49781,49782,49783,49784,49785,18296,18297,49786,
+18298,18299,18300,49793,49794,49795,49796,49797,49798,18301,49799,49800,49801,
+18302,49802,49803,49804,18465,49805,49806,49807,49808,49809,49810,49811,49812,
+18466,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,18467,18468,
+49823,49824,18469,49985,49986,49987,18470,49988,49989,49990,49991,18471,49992,
+49993,18472,18473,49994,18474,49995,18475,49996,49997,49998,18476,49999,50000,
+18477,18478,50001,50002,18479,50003,50004,50005,18480,50006,50007,50008,50009,
+50010,50017,50018,50019,50020,50021,18481,50022,18482,50023,50024,50025,50026,
+50027,50028,18483,18484,50029,50030,18485,50031,50032,50033,50034,50035,50036,
+50037,50038,50039,50040,50041,50042,50049,50050,18486,50051,18487,50052,50053,
+50054,50055,50056,50057,18488,18489,50058,50059,18490,50060,50061,50062,18491,
+50063,50064,50065,50066,50067,50068,50069,50070,18492,50071,18493,50072,18494,
+50073,50074,50075,50076,50077,50078,18495,50079,50080,50241,18496,50242,50243,
+50244,18497,50245,50246,50247,50248,50249,50250,50251,50252,18498,50253,18499,
+50254,50255,50256,50257,50258,50259,50260,50261,18500,18501,50262,50263,18502,
+50264,50265,50266,18503,50273,50274,50275,50276,18504,50277,50278,18505,50279,
+50280,18506,50281,18507,50282,50283,50284,50285,50286,50287,18508,50288,50289,
+50290,18509,50291,50292,50293,18510,50294,50295,50296,50297,50298,50305,50306,
+18511,50307,50308,50309,50310,18512,50311,50312,50313,50314,50315,50316,18513,
+18514,50317,50318,18515,50319,50320,50321,18516,50322,50323,50324,50325,50326,
+50327,50328,50329,50330,50331,50332,50333,18517,50334,50335,50336,50497,50498,
+50499,18518,18519,50500,50501,18520,50502,50503,50504,18521,50505,50506,50507,
+50508,50509,50510,50511,18522,18523,50512,18524,50513,18525,50514,50515,50516,
+50517,50518,50519,18526,18527,50520,50521,18528,50522,50529,50530,18529,50531,
+50532,50533,50534,50535,50536,50537,18530,50538,50539,18531,50540,18532,50541,
+50542,50543,50544,50545,50546,18533,18534,50547,50548,18535,50549,18536,18537,
+18538,18539,50550,50551,50552,50553,50554,50561,18540,18541,50562,18542,50563,
+18543,50564,50565,50566,18544,50567,50568,18545,50569,50570,50571,18546,50572,
+50573,50574,18547,50575,50576,50577,50578,50579,50580,50581,18548,18549,50582,
+50583,50584,18550,50585,50586,50587,50588,50589,50590,18551,18552,50591,50592,
+18553,50753,50754,50755,18554,50756,50757,50758,50759,50760,50761,50762,18555,
+18556,50763,18557,50764,18558,50765,50766,50767,50768,50769,50770,19280,19286,
+19303,19791,19816,20013,20347,20514,20536,20560,20573,20820,20821,20824,20827,
+20828,20829,20830,20831,20832,20834,20835,20836,20837,20838,20840,20841,20842,
+20843,20845,20847,20848,20850,20854,20858,20860,20861,20862,21026,21027,21031,
+21032,21033,21034,21035,21037,21042,21054,21058,21059,21060,21062,21063,21064,
+21065,21066,21067,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,
+21079,21081,21082,21086,21087,21089,21090,21092,21093,21094,21095,21096,21097,
+21098,21099,21104,21105,21106,21107,21108,21109,21111,21112,21606,21628,21797,
+21803,21806,22072,22093,22347,22372,23365,23396,23589,23845,23893,23924,24188,
+24190,24371,24417,24424,24689,24877,24941,25461,25633,25641,25902,25905,25906,
+25913,25915,25916,25924,25934,25936,25938,25942,25978,25979,25980,25982,26145,
+26148,26151,26157,26159,26160,26161,26163,26167,26168,26172,26180,26182,26183,
+26186,26194,26198,26201,26204,26207,26209,26212,26213,26214,26216,26218,26219,
+26220,26223,26225,26226,26229,26230,26231,26233,26401,26406,26409,26410,26412,
+26413,26416,26431,26433,26438,26439,26443,26445,26447,26448,26451,26463,26468,
+26470,26487,26727,26728,26736,26737,26743,26745,26747,26750,26919,26924,26956,
+26999,27201,27237,27252,27255,27260,27262,27428,27431,27433,27434,27450,27451,
+27453,27457,27458,27462,27463,27468,27471,27472,27473,27474,27480,27686,27687,
+27690,27695,27696,27697,27698,27701,27704,27706,27712,27713,27717,27718,27721,
+27722,27733,27741,27742,27745,27748,27751,27752,27767,27768,27770,27937,27938,
+27939,28014,28251,29245,29306,29489,29735,29806,30324,30326,30520,30536,30547,
+30811,30832,31265,31266,31334,31785,8993,8994,8995,8996,8997,8998,8999,9000,
+9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,
+9016,9017,9018,9019,9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,
+9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,
+9046,9047,9048,9049,9050,9051,8492,9053,9054,9055,9056,9057,9058,9059,9060,
+9061,9062,9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,
+9076,9077,9078,9079,9080,9081,9082,9083,9084,9085,8742,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,8523,8524,8574,9086,N,8525,9052,
+};
+
+static const struct unim_index cp949_encmap[256] = {
+{__cp949_encmap+0,161,254},{__cp949_encmap+94,17,103},{__cp949_encmap+181,199,
+221},{__cp949_encmap+204,145,201},{__cp949_encmap+261,1,81},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+342,21,172},{
+__cp949_encmap+494,3,212},{__cp949_encmap+704,0,165},{__cp949_encmap+870,18,18
+},{__cp949_encmap+871,96,233},{__cp949_encmap+1009,0,209},{__cp949_encmap+1219
+,5,109},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{__cp949_encmap+1324,0,246},{__cp949_encmap+1571,49,142},{__cp949_encmap+
+1665,0,127},{__cp949_encmap+1793,128,221},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__cp949_encmap+1887,0,251},{__cp949_encmap+2139,1,250},{
+__cp949_encmap+2389,2,255},{__cp949_encmap+2643,0,253},{__cp949_encmap+2897,0,
+255},{__cp949_encmap+3153,5,248},{__cp949_encmap+3397,3,250},{__cp949_encmap+
+3645,4,254},{__cp949_encmap+3896,6,250},{__cp949_encmap+4141,3,252},{
+__cp949_encmap+4391,0,253},{__cp949_encmap+4645,15,255},{__cp949_encmap+4886,
+1,233},{__cp949_encmap+5119,5,250},{__cp949_encmap+5365,1,253},{__cp949_encmap
++5618,7,254},{__cp949_encmap+5866,2,251},{__cp949_encmap+6116,1,255},{
+__cp949_encmap+6371,15,251},{__cp949_encmap+6608,1,255},{__cp949_encmap+6863,
+0,255},{__cp949_encmap+7119,1,247},{__cp949_encmap+7366,13,254},{
+__cp949_encmap+7608,0,255},{__cp949_encmap+7864,6,255},{__cp949_encmap+8114,0,
+254},{__cp949_encmap+8369,18,250},{__cp949_encmap+8602,0,255},{__cp949_encmap+
+8858,2,251},{__cp949_encmap+9108,4,236},{__cp949_encmap+9341,8,243},{
+__cp949_encmap+9577,11,251},{__cp949_encmap+9818,23,255},{__cp949_encmap+10051
+,1,254},{__cp949_encmap+10305,1,253},{__cp949_encmap+10558,4,255},{
+__cp949_encmap+10810,0,253},{__cp949_encmap+11064,10,254},{__cp949_encmap+
+11309,1,247},{__cp949_encmap+11556,1,252},{__cp949_encmap+11808,0,254},{
+__cp949_encmap+12063,1,243},{__cp949_encmap+12306,2,251},{__cp949_encmap+12556
+,1,251},{__cp949_encmap+12807,0,255},{__cp949_encmap+13063,15,233},{
+__cp949_encmap+13282,7,254},{__cp949_encmap+13530,0,251},{__cp949_encmap+13782
+,9,156},{__cp949_encmap+13930,54,252},{__cp949_encmap+14129,0,253},{
+__cp949_encmap+14383,2,254},{__cp949_encmap+14636,5,254},{__cp949_encmap+14886
+,1,253},{__cp949_encmap+15139,3,252},{__cp949_encmap+15389,17,255},{
+__cp949_encmap+15628,2,254},{__cp949_encmap+15881,0,254},{__cp949_encmap+16136
+,5,253},{__cp949_encmap+16385,7,248},{__cp949_encmap+16627,0,254},{
+__cp949_encmap+16882,0,154},{__cp949_encmap+17037,55,253},{__cp949_encmap+
+17236,4,243},{__cp949_encmap+17476,10,254},{__cp949_encmap+17721,3,253},{
+__cp949_encmap+17972,0,253},{__cp949_encmap+18226,2,245},{__cp949_encmap+18470
+,13,252},{__cp949_encmap+18710,4,246},{__cp949_encmap+18953,4,127},{
+__cp949_encmap+19077,119,226},{__cp949_encmap+19185,28,251},{__cp949_encmap+
+19409,0,255},{__cp949_encmap+19665,0,254},{__cp949_encmap+19920,3,255},{
+__cp949_encmap+20173,1,238},{__cp949_encmap+20411,26,232},{__cp949_encmap+
+20618,13,246},{__cp949_encmap+20852,9,250},{__cp949_encmap+21094,26,244},{
+__cp949_encmap+21313,7,156},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+21463,0,255},{
+__cp949_encmap+21719,0,255},{__cp949_encmap+21975,0,255},{__cp949_encmap+22231
+,0,255},{__cp949_encmap+22487,0,255},{__cp949_encmap+22743,0,255},{
+__cp949_encmap+22999,0,255},{__cp949_encmap+23255,0,255},{__cp949_encmap+23511
+,0,255},{__cp949_encmap+23767,0,255},{__cp949_encmap+24023,0,255},{
+__cp949_encmap+24279,0,255},{__cp949_encmap+24535,0,255},{__cp949_encmap+24791
+,0,255},{__cp949_encmap+25047,0,255},{__cp949_encmap+25303,0,255},{
+__cp949_encmap+25559,0,255},{__cp949_encmap+25815,0,255},{__cp949_encmap+26071
+,0,255},{__cp949_encmap+26327,0,255},{__cp949_encmap+26583,0,255},{
+__cp949_encmap+26839,0,255},{__cp949_encmap+27095,0,255},{__cp949_encmap+27351
+,0,255},{__cp949_encmap+27607,0,255},{__cp949_encmap+27863,0,255},{
+__cp949_encmap+28119,0,255},{__cp949_encmap+28375,0,255},{__cp949_encmap+28631
+,0,255},{__cp949_encmap+28887,0,255},{__cp949_encmap+29143,0,255},{
+__cp949_encmap+29399,0,255},{__cp949_encmap+29655,0,255},{__cp949_encmap+29911
+,0,255},{__cp949_encmap+30167,0,255},{__cp949_encmap+30423,0,255},{
+__cp949_encmap+30679,0,255},{__cp949_encmap+30935,0,255},{__cp949_encmap+31191
+,0,255},{__cp949_encmap+31447,0,255},{__cp949_encmap+31703,0,255},{
+__cp949_encmap+31959,0,255},{__cp949_encmap+32215,0,255},{__cp949_encmap+32471
+,0,163},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+32635,0,255},{
+__cp949_encmap+32891,0,11},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+
+32903,1,230},
+};
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/mappings_tw.h b/sys/src/cmd/python/Modules/cjkcodecs/mappings_tw.h
new file mode 100644
index 000000000..ec3f9f746
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/mappings_tw.h
@@ -0,0 +1,2633 @@
+static const ucs2_t __big5_decmap[16702] = {
+12288,65292,12289,12290,65294,8226,65307,65306,65311,65281,65072,8230,8229,
+65104,65380,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,
+9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,
+65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,
+65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,65115,65116,65117,
+65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,167,
+12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,12963,
+8453,8254,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,65120,
+65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,8734,8786,
+8801,65122,65123,65124,65125,65126,8764,8745,8746,8869,8736,8735,8895,13266,
+13265,8747,8750,8757,8756,9792,9794,9793,9737,8593,8595,8592,8594,8598,8599,
+8601,8600,8741,8739,65295,65340,65295,65340,65284,165,12306,162,163,65285,
+65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,13217,13198,
+13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,31950,9601,
+9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,9609,9532,
+9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9582,9584,9583,9552,
+9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,65297,65298,65299,
+65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,8548,8549,8550,8551,
+8552,8553,12321,12322,12323,12324,12325,12326,12327,12328,12329,21313,21316,
+21317,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,
+65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,
+65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,
+65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,
+65370,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,
+932,933,934,935,936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,
+958,959,960,961,963,964,965,966,967,968,969,12549,12550,12551,12552,12553,
+12554,12555,12556,12557,12558,12559,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,12560,12561,12562,12563,12564,12565,12566,12567,
+12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,
+12581,12582,12583,12584,12585,729,713,714,711,715,19968,20057,19969,19971,
+20035,20061,20102,20108,20154,20799,20837,20843,20960,20992,20993,21147,21269,
+21313,21340,21448,19977,19979,19976,19978,20011,20024,20961,20037,20040,20063,
+20062,20110,20129,20800,20995,21242,21315,21449,21475,22303,22763,22805,22823,
+22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,24037,24049,24050,
+24051,24062,24178,24318,24331,24339,25165,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19985,19984,19981,20013,20016,20025,20043,
+23609,20104,20113,20117,20114,20116,20130,20161,20160,20163,20166,20167,20173,
+20170,20171,20164,20803,20801,20839,20845,20846,20844,20887,20982,20998,20999,
+21000,21243,21246,21247,21270,21305,21320,21319,21317,21342,21380,21451,21450,
+21453,22764,22825,22827,22826,22829,23380,23569,23588,23610,23663,24052,24187,
+24319,24340,24341,24515,25096,25142,25163,25166,25903,25991,26007,26020,26041,
+26085,26352,26376,26408,27424,27490,27513,27595,27604,27611,27663,27700,28779,
+29226,29238,29243,29255,29273,29275,29356,29579,19993,19990,19989,19988,19992,
+20027,20045,20047,20046,20197,20184,20180,20181,20182,20183,20195,20196,20185,
+20190,20805,20804,20873,20874,20908,20985,20986,20984,21002,21152,21151,21253,
+21254,21271,21277,20191,21322,21321,21345,21344,21359,21358,21435,21487,21476,
+21491,21484,21486,21481,21480,21500,21496,21493,21483,21478,21482,21490,21489,
+21488,21477,21485,21499,22235,22234,22806,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22830,22833,22900,22902,23381,23427,23612,
+24040,24039,24038,24066,24067,24179,24188,24321,24344,24343,24517,25098,25171,
+25172,25170,25169,26021,26086,26414,26412,26410,26411,26413,27491,27597,27665,
+27664,27704,27713,27712,27710,29359,29572,29577,29916,29926,29976,29983,29992,
+29993,30000,30001,30002,30003,30091,30333,30382,30399,30446,30683,30690,30707,
+31034,31166,31348,31435,19998,19999,20050,20051,20073,20121,20132,20134,20133,
+20223,20233,20249,20234,20245,20237,20240,20241,20239,20210,20214,20219,20208,
+20211,20221,20225,20235,20809,20807,20806,20808,20840,20849,20877,20912,21015,
+21009,21010,21006,21014,21155,21256,21281,21280,21360,21361,21513,21519,21516,
+21514,21520,21505,21515,21508,21521,21517,21512,21507,21518,21510,21522,22240,
+22238,22237,22323,22320,22312,22317,22316,22319,22313,22809,22810,22839,22840,
+22916,22904,22915,22909,22905,22914,22913,23383,23384,23431,23432,23429,23433,
+23546,23574,23673,24030,24070,24182,24180,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24335,24347,24537,24534,25102,25100,25101,
+25104,25187,25179,25176,25910,26089,26088,26092,26093,26354,26355,26377,26429,
+26420,26417,26421,27425,27492,27515,27670,27741,27735,27737,27743,27744,27728,
+27733,27745,27739,27725,27726,28784,29279,29277,30334,31481,31859,31992,32566,
+32650,32701,32769,32771,32780,32786,32819,32895,32905,32907,32908,33251,33258,
+33267,33276,33292,33307,33311,33390,33394,33406,34411,34880,34892,34915,35199,
+38433,20018,20136,20301,20303,20295,20311,20318,20276,20315,20309,20272,20304,
+20305,20285,20282,20280,20291,20308,20284,20294,20323,20316,20320,20271,20302,
+20278,20313,20317,20296,20314,20812,20811,20813,20853,20918,20919,21029,21028,
+21033,21034,21032,21163,21161,21162,21164,21283,21363,21365,21533,21549,21534,
+21566,21542,21582,21543,21574,21571,21555,21576,21570,21531,21545,21578,21561,
+21563,21560,21550,21557,21558,21536,21564,21568,21553,21547,21535,21548,22250,
+22256,22244,22251,22346,22353,22336,22349,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22343,22350,22334,22352,22351,22331,22767,
+22846,22941,22930,22952,22942,22947,22937,22934,22925,22948,22931,22922,22949,
+23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,23614,23696,
+23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,24420,24418,
+24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,25105,25220,
+25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,25234,25199,
+25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,26463,26446,
+26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,27493,27599,
+27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,27760,27788,
+27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,27796,27800,
+27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,29996,29995,
+30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,32918,32915,
+32925,32920,32923,32922,32946,33391,33426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33419,33421,35211,35282,35328,35895,35910,
+35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,36806,36805,36804,
+24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,38446,38449,38442,
+38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,20381,20365,20339,
+20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,20347,20374,20350,
+20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,20925,20989,21051,
+21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,21332,21331,21329,
+21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,21624,21653,21632,
+21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,21658,21602,21608,
+21643,21629,21646,22266,22403,22391,22378,22377,22369,22374,22372,22396,22812,
+22857,22855,22856,22852,22868,22974,22971,22996,22969,22958,22993,22982,22992,
+22989,22987,22995,22986,22959,22963,22994,22981,23391,23396,23395,23447,23450,
+23448,23452,23449,23451,23578,23624,23621,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23622,23735,23713,23736,23721,23723,23729,
+23731,24088,24090,24086,24085,24091,24081,24184,24218,24215,24220,24213,24214,
+24310,24358,24359,24361,24448,24449,24447,24444,24541,24544,24573,24565,24575,
+24591,24596,24623,24629,24598,24618,24597,24609,24615,24617,24619,24603,25110,
+25109,25151,25150,25152,25215,25289,25292,25284,25279,25282,25273,25298,25307,
+25259,25299,25300,25291,25288,25256,25277,25276,25296,25305,25287,25293,25269,
+25306,25265,25304,25302,25303,25286,25260,25294,25918,26023,26044,26106,26132,
+26131,26124,26118,26114,26126,26112,26127,26133,26122,26119,26381,26379,26477,
+26507,26517,26481,26524,26483,26487,26503,26525,26519,26479,26480,26495,26505,
+26494,26512,26485,26522,26515,26492,26474,26482,27427,27494,27495,27519,27667,
+27675,27875,27880,27891,27825,27852,27877,27827,27837,27838,27836,27874,27819,
+27861,27859,27832,27844,27833,27841,27822,27863,27845,27889,27839,27835,27873,
+27867,27850,27820,27887,27868,27862,27872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28821,28814,28818,28810,28825,29228,29229,
+29240,29256,29287,29289,29376,29390,29401,29399,29392,29609,29608,29599,29611,
+29605,30013,30109,30105,30106,30340,30402,30450,30452,30693,30717,31038,31040,
+31041,31177,31176,31354,31353,31482,31998,32596,32652,32651,32773,32954,32933,
+32930,32945,32929,32939,32937,32948,32938,32943,33253,33278,33293,33459,33437,
+33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,
+33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,
+37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,
+38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,
+20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,
+20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,
+21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,
+21670,21683,21703,21698,21693,21674,21697,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21700,21704,21679,21675,21681,21691,21673,
+21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,22865,
+22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,23014,
+23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,23627,
+23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,24421,
+24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,24616,
+24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,25366,
+25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,25332,
+25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,26143,
+26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,26613,
+26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,26585,
+26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,27954,
+27946,27969,27941,27916,27953,27934,27927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27963,27965,27966,27958,27931,27893,27961,
+27943,27960,27945,27950,27957,27918,27947,28843,28858,28851,28844,28847,28845,
+28856,28846,28836,29232,29298,29295,29300,29417,29408,29409,29623,29642,29627,
+29618,29645,29632,29619,29978,29997,30031,30028,30030,30027,30123,30116,30117,
+30114,30115,30328,30342,30343,30344,30408,30406,30403,30405,30465,30457,30456,
+30473,30475,30462,30460,30471,30684,30722,30740,30732,30733,31046,31049,31048,
+31047,31161,31162,31185,31186,31179,31359,31361,31487,31485,31869,32002,32005,
+32000,32009,32007,32004,32006,32568,32654,32703,32772,32784,32781,32785,32822,
+32982,32997,32986,32963,32964,32972,32993,32987,32974,32990,32996,32989,33268,
+33314,33511,33539,33541,33507,33499,33510,33540,33509,33538,33545,33490,33495,
+33521,33537,33500,33492,33489,33502,33491,33503,33519,33542,34384,34425,34427,
+34426,34893,34923,35201,35284,35336,35330,35331,35998,36000,36212,36211,36276,
+36557,36556,36848,36838,36834,36842,36837,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36845,36843,36836,36840,37066,37070,37057,
+37059,37195,37194,37325,38274,38480,38475,38476,38477,38754,38761,38859,38893,
+38899,38913,39080,39131,39135,39318,39321,20056,20147,20492,20493,20515,20463,
+20518,20517,20472,20521,20502,20486,20540,20511,20506,20498,20497,20474,20480,
+20500,20520,20465,20513,20491,20505,20504,20467,20462,20525,20522,20478,20523,
+20489,20860,20900,20901,20898,20941,20940,20934,20939,21078,21084,21076,21083,
+21085,21290,21375,21407,21405,21471,21736,21776,21761,21815,21756,21733,21746,
+21766,21754,21780,21737,21741,21729,21769,21742,21738,21734,21799,21767,21757,
+21775,22275,22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,
+23064,23068,23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,
+23640,23472,23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,
+23789,23805,23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,
+24237,24231,24369,24466,24465,24464,24665,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24675,24677,24656,24661,24685,24681,24687,
+24708,24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,
+25406,25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,
+25421,25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,
+26181,26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,
+26708,26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,
+26693,26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,
+28010,28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,
+28020,28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,
+28879,29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,
+29674,29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,
+30140,30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,
+30697,30768,30759,30776,30749,30772,30775,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30757,30765,30752,30751,30770,31061,31056,
+31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,
+31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,
+32020,32016,32021,32026,32028,32013,32025,32027,32570,32607,32660,32709,32705,
+32774,32792,32789,32793,32791,32829,32831,33009,33026,33008,33029,33005,33012,
+33030,33016,33011,33032,33021,33034,33020,33007,33261,33260,33280,33296,33322,
+33323,33320,33324,33467,33579,33618,33620,33610,33592,33616,33609,33589,33588,
+33615,33586,33593,33590,33559,33600,33585,33576,33603,34388,34442,34474,34451,
+34468,34473,34444,34467,34460,34928,34935,34945,34946,34941,34937,35352,35344,
+35342,35340,35349,35338,35351,35347,35350,35343,35345,35912,35962,35961,36001,
+36002,36215,36524,36562,36564,36559,36785,36865,36870,36855,36864,36858,36852,
+36867,36861,36869,36856,37013,37089,37085,37090,37202,37197,37196,37336,37341,
+37335,37340,37337,38275,38498,38499,38497,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38491,38493,38500,38488,38494,38587,39138,
+39340,39592,39640,39717,39730,39740,20094,20602,20605,20572,20551,20547,20556,
+20570,20553,20581,20598,20558,20565,20597,20596,20599,20559,20495,20591,20589,
+20828,20885,20976,21098,21103,21202,21209,21208,21205,21264,21263,21273,21311,
+21312,21310,21443,26364,21830,21866,21862,21828,21854,21857,21827,21834,21809,
+21846,21839,21845,21807,21860,21816,21806,21852,21804,21859,21811,21825,21847,
+22280,22283,22281,22495,22533,22538,22534,22496,22500,22522,22530,22581,22519,
+22521,22816,22882,23094,23105,23113,23142,23146,23104,23100,23138,23130,23110,
+23114,23408,23495,23493,23492,23490,23487,23494,23561,23560,23559,23648,23644,
+23645,23815,23814,23822,23835,23830,23842,23825,23849,23828,23833,23844,23847,
+23831,24034,24120,24118,24115,24119,24247,24248,24246,24245,24254,24373,24375,
+24407,24428,24425,24427,24471,24473,24478,24472,24481,24480,24476,24703,24739,
+24713,24736,24744,24779,24756,24806,24765,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24773,24763,24757,24796,24764,24792,24789,
+24774,24799,24760,24794,24775,25114,25115,25160,25504,25511,25458,25494,25506,
+25509,25463,25447,25496,25514,25457,25513,25481,25475,25499,25451,25512,25476,
+25480,25497,25505,25516,25490,25487,25472,25467,25449,25448,25466,25949,25942,
+25937,25945,25943,21855,25935,25944,25941,25940,26012,26011,26028,26063,26059,
+26060,26062,26205,26202,26212,26216,26214,26206,26361,21207,26395,26753,26799,
+26786,26771,26805,26751,26742,26801,26791,26775,26800,26755,26820,26797,26758,
+26757,26772,26781,26792,26783,26785,26754,27442,27578,27627,27628,27691,28046,
+28092,28147,28121,28082,28129,28108,28132,28155,28154,28165,28103,28107,28079,
+28113,28078,28126,28153,28088,28151,28149,28101,28114,28186,28085,28122,28139,
+28120,28138,28145,28142,28136,28102,28100,28074,28140,28095,28134,28921,28937,
+28938,28925,28911,29245,29309,29313,29468,29467,29462,29459,29465,29575,29701,
+29706,29699,29702,29694,29709,29920,29942,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29943,29980,29986,30053,30054,30050,30064,
+30095,30164,30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,
+30518,30520,30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,
+31528,31515,31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,
+32046,32057,32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,
+32666,32716,32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,
+33060,33282,33333,33335,33334,33337,33678,33694,33688,33656,33698,33686,33725,
+33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,34389,24426,
+34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,34974,34952,
+34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,35377,35373,
+35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,36199,36198,
+36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,36880,36885,
+36894,36896,36879,36898,36886,36891,36884,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37096,37101,37117,37207,37326,37365,37350,
+37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,38516,38518,38519,
+38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,40565,40575,40613,
+40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,26368,20977,21106,
+21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,21927,21884,21898,
+21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,21934,21919,21822,
+21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,22575,22570,22580,
+22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,23194,23167,23186,
+23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,23601,23884,23888,
+23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,24258,24260,24380,
+24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,24867,24826,24853,
+24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,25119,25161,25507,
+25484,25551,25536,25577,25545,25542,25549,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25554,25571,25552,25569,25558,25581,25582,
+25462,25588,25578,25563,25682,25562,25593,25950,25958,25954,25955,26001,26000,
+26031,26222,26224,26228,26230,26223,26257,26234,26238,26231,26366,26367,26399,
+26397,26874,26837,26848,26840,26839,26885,26847,26869,26862,26855,26873,26834,
+26866,26851,26827,26829,26893,26898,26894,26825,26842,26990,26875,27454,27450,
+27453,27544,27542,27580,27631,27694,27695,27692,28207,28216,28244,28193,28210,
+28263,28234,28192,28197,28195,28187,28251,28248,28196,28246,28270,28205,28198,
+28271,28212,28237,28218,28204,28227,28189,28222,28363,28297,28185,28238,28259,
+28228,28274,28265,28255,28953,28954,28966,28976,28961,28982,29038,28956,29260,
+29316,29312,29494,29477,29492,29481,29754,29738,29747,29730,29733,29749,29750,
+29748,29743,29723,29734,29736,29989,29990,30059,30058,30178,30171,30179,30169,
+30168,30174,30176,30331,30332,30358,30355,30388,30428,30543,30701,30813,30828,
+30831,31245,31240,31243,31237,31232,31384,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31383,31382,31461,31459,31561,31574,31558,
+31568,31570,31572,31565,31563,31567,31569,31903,31909,32094,32080,32104,32085,
+32043,32110,32114,32097,32102,32098,32112,32115,21892,32724,32725,32779,32850,
+32901,33109,33108,33099,33105,33102,33081,33094,33086,33100,33107,33140,33298,
+33308,33769,33795,33784,33805,33760,33733,33803,33729,33775,33777,33780,33879,
+33802,33776,33804,33740,33789,33778,33738,33848,33806,33796,33756,33799,33748,
+33759,34395,34527,34521,34541,34516,34523,34532,34512,34526,34903,35009,35010,
+34993,35203,35222,35387,35424,35413,35422,35388,35393,35412,35419,35408,35398,
+35380,35386,35382,35414,35937,35970,36015,36028,36019,36029,36033,36027,36032,
+36020,36023,36022,36031,36024,36234,36229,36225,36302,36317,36299,36314,36305,
+36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,
+37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,
+37392,37383,37393,38292,38287,38283,38289,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38291,38290,38286,38538,38542,38539,38525,
+38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,38860,
+38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,40653,
+40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,20679,
+21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,21990,
+21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,21961,
+22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,22626,
+22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,23913,
+23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,24863,
+24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,24845,
+24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,25628,
+25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,26248,
+26262,26244,26264,26253,26371,27028,26989,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26970,26999,26976,26964,26997,26928,27010,
+26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,27506,27584,
+27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,28357,28325,
+28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,28340,29006,
+29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,28998,29032,
+29014,29242,29266,29495,29509,29503,29502,29807,29786,29781,29791,29790,29761,
+29759,29785,29787,29788,30070,30072,30208,30192,30209,30194,30193,30202,30207,
+30196,30195,30430,30431,30555,30571,30566,30558,30563,30585,30570,30572,30556,
+30565,30568,30562,30702,30862,30896,30871,30872,30860,30857,30844,30865,30867,
+30847,31098,31103,31105,33836,31165,31260,31258,31264,31252,31263,31262,31391,
+31392,31607,31680,31584,31598,31591,31921,31923,31925,32147,32121,32145,32129,
+32143,32091,32622,32617,32618,32626,32681,32680,32676,32854,32856,32902,32900,
+33137,33136,33144,33125,33134,33139,33131,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33145,33146,33126,33285,33351,33922,33911,
+33853,33841,33909,33894,33899,33865,33900,33883,33852,33845,33889,33891,33897,
+33901,33862,34398,34396,34399,34553,34579,34568,34567,34560,34558,34555,34562,
+34563,34566,34570,34905,35039,35028,35033,35036,35032,35037,35041,35018,35029,
+35026,35228,35299,35435,35442,35443,35430,35433,35440,35463,35452,35427,35488,
+35441,35461,35437,35426,35438,35436,35449,35451,35390,35432,35938,35978,35977,
+36042,36039,36040,36036,36018,36035,36034,36037,36321,36319,36328,36335,36339,
+36346,36330,36324,36326,36530,36611,36617,36606,36618,36767,36786,36939,36938,
+36947,36930,36948,36924,36949,36944,36935,36943,36942,36941,36945,36926,36929,
+37138,37143,37228,37226,37225,37321,37431,37463,37432,37437,37440,37438,37467,
+37451,37476,37457,37428,37449,37453,37445,37433,37439,37466,38296,38552,38548,
+38549,38605,38603,38601,38602,38647,38651,38649,38646,38742,38772,38774,38928,
+38929,38931,38922,38930,38924,39164,39156,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39165,39166,39347,39345,39348,39649,40169,
+40578,40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,
+20721,20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,
+22013,22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,
+22294,22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,
+22890,22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,
+23525,23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,
+24151,24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,
+24931,24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,
+25681,25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,
+27048,27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,
+27053,27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,
+28457,28478,28448,28460,28431,28418,28450,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28415,28399,28422,28465,28472,28466,28451,
+28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,
+29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,
+29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,
+30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,
+31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,
+31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,
+32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,
+32862,32858,32903,33104,33152,33167,33160,33162,33151,33154,33255,33274,33287,
+33300,33310,33355,33993,33983,33990,33988,33945,33950,33970,33948,33995,33976,
+33984,34003,33936,33980,34001,33994,34623,34588,34619,34594,34597,34612,34584,
+34645,34615,34601,35059,35074,35060,35065,35064,35069,35048,35098,35055,35494,
+35468,35486,35491,35469,35489,35475,35492,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35498,35493,35496,35480,35473,35482,35495,
+35946,35981,35980,36051,36049,36050,36203,36249,36245,36348,36628,36626,36629,
+36627,36771,36960,36952,36956,36963,36953,36958,36962,36957,36955,37145,37144,
+37150,37237,37240,37239,37236,37496,37504,37509,37528,37526,37499,37523,37532,
+37544,37500,37521,38305,38312,38313,38307,38309,38308,38553,38556,38555,38604,
+38610,38656,38780,38789,38902,38935,38936,39087,39089,39171,39173,39180,39177,
+39361,39599,39600,39654,39745,39746,40180,40182,40179,40636,40763,40778,20740,
+20736,20731,20725,20729,20738,20744,20745,20741,20956,21127,21128,21129,21133,
+21130,21232,21426,22062,22075,22073,22066,22079,22068,22057,22099,22094,22103,
+22132,22070,22063,22064,22656,22687,22686,22707,22684,22702,22697,22694,22893,
+23305,23291,23307,23285,23308,23304,23534,23532,23529,23531,23652,23653,23965,
+23956,24162,24159,24161,24290,24282,24287,24285,24291,24288,24392,24433,24503,
+24501,24950,24935,24942,24925,24917,24962,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24956,24944,24939,24958,24999,24976,25003,
+24974,25004,24986,24996,24980,25006,25134,25705,25711,25721,25758,25778,25736,
+25744,25776,25765,25747,25749,25769,25746,25774,25773,25771,25754,25772,25753,
+25762,25779,25973,25975,25976,26286,26283,26292,26289,27171,27167,27112,27137,
+27166,27161,27133,27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,
+27556,27589,27590,28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,
+28526,28558,28538,28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,
+29105,29096,29270,29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,
+30249,30239,30244,30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,
+30603,30923,30917,30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,
+31287,31291,31407,31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,
+31946,32224,32244,32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,
+32158,32217,32242,32249,32629,32631,32687,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32745,32806,33179,33180,33181,33184,33178,
+33176,34071,34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,
+34085,34047,34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,
+34643,34907,34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,
+35477,35531,35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,
+35916,35918,35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,
+36065,36205,36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,
+36538,36637,36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,
+36973,36983,37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,
+37610,37548,37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,
+38662,38663,38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,
+39186,39192,39389,39376,39391,39387,39377,39381,39378,39385,39607,39662,39663,
+39719,39749,39748,39799,39791,40198,40201,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40195,40617,40638,40654,22696,40786,20754,
+20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,22105,22123,22137,
+22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,22134,22721,22718,
+22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,24977,25001,24970,
+25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,25788,25818,25796,
+25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,26297,26308,26311,
+26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,27233,27211,27207,
+27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,28580,28609,28583,
+28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,29138,29128,29141,
+29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,29855,29854,29922,
+29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,30629,30952,30938,
+30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,31761,31689,31716,
+31707,31713,31721,31718,31957,31958,32266,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32273,32264,32283,32291,32286,32285,32265,
+32272,32633,32690,32752,32753,32750,32808,33203,33193,33192,33275,33288,33368,
+33369,34122,34137,34120,34152,34153,34115,34121,34157,34154,34142,34691,34719,
+34718,34722,34701,34913,35114,35122,35109,35115,35105,35242,35238,35558,35578,
+35563,35569,35584,35548,35559,35566,35582,35585,35586,35575,35565,35571,35574,
+35580,35947,35949,35987,36084,36420,36401,36404,36418,36409,36405,36667,36655,
+36664,36659,36776,36774,36981,36980,36984,36978,36988,36986,37172,37266,37664,
+37686,37624,37683,37679,37666,37628,37675,37636,37658,37648,37670,37665,37653,
+37678,37657,38331,38567,38568,38570,38613,38670,38673,38678,38669,38675,38671,
+38747,38748,38758,38808,38960,38968,38971,38967,38957,38969,38948,39184,39208,
+39198,39195,39201,39194,39405,39394,39409,39608,39612,39675,39661,39720,39825,
+40213,40227,40230,40232,40210,40219,40664,40660,40845,40860,20778,20767,20769,
+20786,21237,22158,22144,22160,22149,22151,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22159,22741,22739,22737,22734,23344,23338,
+23332,23418,23607,23656,23996,23994,23997,23992,24171,24396,24509,25033,25026,
+25031,25062,25035,25138,25140,25806,25802,25816,25824,25840,25830,25836,25841,
+25826,25837,25986,25987,26329,26326,27264,27284,27268,27298,27292,27355,27299,
+27262,27287,27280,27296,27484,27566,27610,27656,28632,28657,28639,28640,28635,
+28644,28651,28655,28544,28652,28641,28649,28629,28654,28656,29159,29151,29166,
+29158,29157,29165,29164,29172,29152,29237,29254,29552,29554,29865,29872,29862,
+29864,30278,30274,30284,30442,30643,30634,30640,30636,30631,30637,30703,30967,
+30970,30964,30959,30977,31143,31146,31319,31423,31751,31757,31742,31735,31756,
+31712,31968,31964,31966,31970,31967,31961,31965,32302,32318,32326,32311,32306,
+32323,32299,32317,32305,32325,32321,32308,32313,32328,32309,32319,32303,32580,
+32755,32764,32881,32882,32880,32879,32883,33222,33219,33210,33218,33216,33215,
+33213,33225,33214,33256,33289,33393,34218,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34180,34174,34204,34193,34196,34223,34203,
+34183,34216,34186,34407,34752,34769,34739,34770,34758,34731,34747,34746,34760,
+34763,35131,35126,35140,35128,35133,35244,35598,35607,35609,35611,35594,35616,
+35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,36425,
+36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,36994,
+36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,37656,
+37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,38584,
+38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,39850,
+39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,22165,
+22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,25851,
+25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,27487,
+27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,29176,
+29559,29557,29863,29887,29973,30294,30296,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30290,30653,30655,30651,30652,30990,31150,
+31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,31975,32340,
+32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,33229,33231,
+33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,34796,34802,
+34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,36451,36454,
+36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,37328,37780,
+37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,38358,38352,
+38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,38989,38991,
+38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,39683,39686,
+39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,40672,40725,
+40748,20787,22181,22750,22751,22754,23541,40848,24300,25074,25079,25078,25077,
+25856,25871,26336,26333,27365,27357,27354,27347,28699,28703,28712,28698,28701,
+28693,28696,29190,29197,29272,29346,29560,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29562,29885,29898,29923,30087,30086,30303,
+30305,30663,31001,31153,31339,31337,31806,31807,31800,31805,31799,31808,32363,
+32365,32377,32361,32362,32645,32371,32694,32697,32696,33240,34281,34269,34282,
+34261,34276,34277,34295,34811,34821,34829,34809,34814,35168,35167,35158,35166,
+35649,35676,35672,35657,35674,35662,35663,35654,35673,36104,36106,36476,36466,
+36487,36470,36460,36474,36468,36692,36686,36781,37002,37003,37297,37294,37857,
+37841,37855,37827,37832,37852,37853,37846,37858,37837,37848,37860,37847,37864,
+38364,38580,38627,38698,38695,38753,38876,38907,39006,39000,39003,39100,39237,
+39241,39446,39449,39693,39912,39911,39894,39899,40329,40289,40306,40298,40300,
+40594,40599,40595,40628,21240,22184,22199,22198,22196,22204,22756,23360,23363,
+23421,23542,24009,25080,25082,25880,25876,25881,26342,26407,27372,28734,28720,
+28722,29200,29563,29903,30306,30309,31014,31018,31020,31019,31431,31478,31820,
+31811,31821,31983,31984,36782,32381,32380,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32386,32588,32768,33242,33382,34299,34297,
+34321,34298,34310,34315,34311,34314,34836,34837,35172,35258,35320,35696,35692,
+35686,35695,35679,35691,36111,36109,36489,36481,36485,36482,37300,37323,37912,
+37891,37885,38369,38704,39108,39250,39249,39336,39467,39472,39479,39477,39955,
+39949,40569,40629,40680,40751,40799,40803,40801,20791,20792,22209,22208,22210,
+22804,23660,24013,25084,25086,25885,25884,26005,26345,27387,27396,27386,27570,
+28748,29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,
+34330,34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,
+36493,36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,
+38712,38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,
+39761,39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,
+20796,20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,
+28753,28760,29568,29924,30090,30318,30316,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31155,31840,31839,32894,32893,33247,35186,
+35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,
+38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,
+40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,
+27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,
+35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,
+39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,
+30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,
+37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,
+40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,
+38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,
+39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,
+40474,29224,39530,39729,40475,40478,31858,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12542,12445,12446,12293,12353,12354,12355,
+12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,
+12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,
+12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,
+12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,
+12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,
+12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,
+12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,
+12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,
+12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,
+12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,
+12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,
+12512,12513,12514,12515,12516,12517,12518,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12519,12520,12521,12522,12523,12524,12525,
+12526,12527,12528,12529,12530,12531,12532,12533,12534,1044,1045,1025,1046,
+1047,1048,1049,1050,1051,1052,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
+1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
+1097,1098,1099,1100,1101,1102,1103,9312,9313,9314,9315,9316,9317,9318,9319,
+9320,9321,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,20034,20060,20981,
+21274,21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,
+20014,20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,
+24063,26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,
+20186,21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,
+23667,24068,24192,24194,24521,25097,25168,27669,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27702,27715,27711,27707,29358,29360,
+29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,
+20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,
+21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,
+22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,23678,24031,
+24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,25185,25190,
+25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,26426,26431,
+26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,28785,29278,
+29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,33407,34381,
+35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,20283,20322,
+20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,20287,20321,
+20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,21391,21552,
+21559,21546,21588,21573,21529,21532,21541,21528,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21565,21583,21569,21544,21540,21575,
+22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,22848,22950,22936,
+22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,23592,23594,23693,
+23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,24074,24078,24203,
+24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,24528,24557,24552,
+24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,24564,25146,25219,
+25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,25224,25207,25213,
+25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,26457,26453,26444,
+26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,27755,27780,27787,
+27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,27763,27749,27771,
+27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,29381,29589,29591,
+29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,32917,32921,32912,
+32914,32924,33424,33423,33413,33422,33425,33427,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33418,33411,33412,35960,36809,36799,
+37023,37025,37029,37022,37031,37024,38448,38440,38447,38445,20019,20376,20348,
+20357,20349,20352,20359,20342,20340,20361,20356,20343,20300,20375,20330,20378,
+20345,20353,20344,20368,20380,20372,20382,20370,20354,20373,20331,20334,20894,
+20924,20926,21045,21042,21043,21062,21041,21180,21258,21259,21308,21394,21396,
+21639,21631,21633,21649,21634,21640,21611,21626,21630,21605,21612,21620,21606,
+21645,21615,21601,21600,21656,21603,21607,21604,22263,22265,22383,22386,22381,
+22379,22385,22384,22390,22400,22389,22395,22387,22388,22370,22376,22397,22796,
+22853,22965,22970,22991,22990,22962,22988,22977,22966,22972,22979,22998,22961,
+22973,22976,22984,22964,22983,23394,23397,23443,23445,23620,23623,23726,23716,
+23712,23733,23727,23720,23724,23711,23715,23725,23714,23722,23719,23709,23717,
+23734,23728,23718,24087,24084,24089,24360,24354,24355,24356,24404,24450,24446,
+24445,24542,24549,24621,24614,24601,24626,24587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24628,24586,24599,24627,24602,24606,
+24620,24610,24589,24592,24622,24595,24593,24588,24585,24604,25108,25149,25261,
+25268,25297,25278,25258,25270,25290,25262,25267,25263,25275,25257,25264,25272,
+25917,26024,26043,26121,26108,26116,26130,26120,26107,26115,26123,26125,26117,
+26109,26129,26128,26358,26378,26501,26476,26510,26514,26486,26491,26520,26502,
+26500,26484,26509,26508,26490,26527,26513,26521,26499,26493,26497,26488,26489,
+26516,27429,27520,27518,27614,27677,27795,27884,27883,27886,27865,27830,27860,
+27821,27879,27831,27856,27842,27834,27843,27846,27885,27890,27858,27869,27828,
+27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,
+28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,
+29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,
+29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,
+30449,30448,30453,30712,30716,30713,30715,30714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30711,31042,31039,31173,31352,31355,
+31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,33472,
+33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,33441,
+33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,36811,
+36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,38460,
+38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,20411,
+20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,21309,
+21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,21687,
+21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,21680,
+22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,22437,
+22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,23037,
+23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,23021,
+23464,23628,23760,23768,23756,23767,23755,23771,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23774,23770,23753,23751,23754,23766,
+23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,24099,24096,
+24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,24631,24633,
+24660,24690,24670,24645,24659,24647,24649,24667,24652,24640,24642,24671,24612,
+24644,24664,24678,24686,25154,25155,25295,25357,25355,25333,25358,25347,25323,
+25337,25359,25356,25336,25334,25344,25363,25364,25338,25365,25339,25328,25921,
+25923,26026,26047,26166,26145,26162,26165,26140,26150,26146,26163,26155,26170,
+26141,26164,26169,26158,26383,26384,26561,26610,26568,26554,26588,26555,26616,
+26584,26560,26551,26565,26603,26596,26591,26549,26573,26547,26615,26614,26606,
+26595,26562,26553,26574,26599,26608,26546,26620,26566,26605,26572,26542,26598,
+26587,26618,26569,26570,26563,26602,26571,27432,27522,27524,27574,27606,27608,
+27616,27680,27681,27944,27956,27949,27935,27964,27967,27922,27914,27866,27955,
+27908,27929,27962,27930,27921,27904,27933,27970,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27905,27928,27959,27907,27919,27968,
+27911,27936,27948,27912,27938,27913,27920,28855,28831,28862,28849,28848,28833,
+28852,28853,28841,29249,29257,29258,29292,29296,29299,29294,29386,29412,29416,
+29419,29407,29418,29414,29411,29573,29644,29634,29640,29637,29625,29622,29621,
+29620,29675,29631,29639,29630,29635,29638,29624,29643,29932,29934,29998,30023,
+30024,30119,30122,30329,30404,30472,30467,30468,30469,30474,30455,30459,30458,
+30695,30696,30726,30737,30738,30725,30736,30735,30734,30729,30723,30739,31050,
+31052,31051,31045,31044,31189,31181,31183,31190,31182,31360,31358,31441,31488,
+31489,31866,31864,31865,31871,31872,31873,32003,32008,32001,32600,32657,32653,
+32702,32775,32782,32783,32788,32823,32984,32967,32992,32977,32968,32962,32976,
+32965,32995,32985,32988,32970,32981,32969,32975,32983,32998,32973,33279,33313,
+33428,33497,33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,
+33505,33522,33525,33548,33531,33526,33520,33514,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33508,33504,33530,33523,33517,34423,
+34420,34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,
+36833,36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,
+37331,38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,
+20507,20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,
+20527,20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,
+21074,21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,
+21747,21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,
+21752,21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,
+22461,22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,
+23085,23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,
+23638,23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,
+24234,24236,24371,24368,24423,24669,24666,24679,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24641,24738,24712,24704,24722,24705,
+24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,
+25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,
+25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,
+25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,
+26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,
+26702,26692,26676,26653,26642,26644,26662,26664,26670,26701,26682,26661,26656,
+27436,27439,27437,27441,27444,27501,32898,27528,27622,27620,27624,27619,27618,
+27623,27685,28026,28003,28004,28022,27917,28001,28050,27992,28002,28013,28015,
+28049,28045,28143,28031,28038,27998,28007,28000,28055,28016,28028,27999,28034,
+28056,27951,28008,28043,28030,28032,28036,27926,28035,28027,28029,28021,28048,
+28892,28883,28881,28893,28875,32569,28898,28887,28882,28894,28896,28884,28877,
+28869,28870,28871,28890,28878,28897,29250,29304,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29303,29302,29440,29434,29428,29438,
+29430,29427,29435,29441,29651,29657,29669,29654,29628,29671,29667,29673,29660,
+29650,29659,29652,29661,29658,29655,29656,29672,29918,29919,29940,29941,29985,
+30043,30047,30128,30145,30139,30148,30144,30143,30134,30138,30346,30409,30493,
+30491,30480,30483,30482,30499,30481,30485,30489,30490,30498,30503,30755,30764,
+30754,30773,30767,30760,30766,30763,30753,30761,30771,30762,30769,31060,31067,
+31055,31068,31059,31058,31057,31211,31212,31200,31214,31213,31210,31196,31198,
+31197,31366,31369,31365,31371,31372,31370,31367,31448,31504,31492,31507,31493,
+31503,31496,31498,31502,31497,31506,31876,31889,31882,31884,31880,31885,31877,
+32030,32029,32017,32014,32024,32022,32019,32031,32018,32015,32012,32604,32609,
+32606,32608,32605,32603,32662,32658,32707,32706,32704,32790,32830,32825,33018,
+33010,33017,33013,33025,33019,33024,33281,33327,33317,33587,33581,33604,33561,
+33617,33573,33622,33599,33601,33574,33564,33570,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33602,33614,33563,33578,33544,33596,
+33613,33558,33572,33568,33591,33583,33577,33607,33605,33612,33619,33566,33580,
+33611,33575,33608,34387,34386,34466,34472,34454,34445,34449,34462,34439,34455,
+34438,34443,34458,34437,34469,34457,34465,34471,34453,34456,34446,34461,34448,
+34452,34883,34884,34925,34933,34934,34930,34944,34929,34943,34927,34947,34942,
+34932,34940,35346,35911,35927,35963,36004,36003,36214,36216,36277,36279,36278,
+36561,36563,36862,36853,36866,36863,36859,36868,36860,36854,37078,37088,37081,
+37082,37091,37087,37093,37080,37083,37079,37084,37092,37200,37198,37199,37333,
+37346,37338,38492,38495,38588,39139,39647,39727,20095,20592,20586,20577,20574,
+20576,20563,20555,20573,20594,20552,20557,20545,20571,20554,20578,20501,20549,
+20575,20585,20587,20579,20580,20550,20544,20590,20595,20567,20561,20944,21099,
+21101,21100,21102,21206,21203,21293,21404,21877,21878,21820,21837,21840,21812,
+21802,21841,21858,21814,21813,21808,21842,21829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21772,21810,21861,21838,21817,21832,
+21805,21819,21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,
+22509,22525,22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,
+22497,22542,22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,
+23136,23128,23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,
+23140,23127,23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,
+23152,23145,23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,
+23819,23837,23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,
+23839,23854,24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,
+24479,24714,24720,24710,24766,24752,24762,24787,24788,24783,24804,24793,24797,
+24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,25482,25474,
+25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,25454,25519,
+25461,25500,25453,25518,25468,25508,25403,25503,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25464,25477,25473,25489,25485,25456,
+25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,26759,26768,26780,
+26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,26740,26802,26767,
+26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,26774,26763,26784,
+26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,27447,27448,27537,
+27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,28076,28137,28130,
+28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,28124,28125,28123,
+28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,28112,28146,28115,
+28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,28940,28912,28932,
+28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,28930,28942,29310,
+29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,29439,29455,29470,
+29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,29692,29695,29708,
+29707,29684,29704,30052,30051,30158,30162,30159,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30155,30156,30161,30160,30351,30345,
+30419,30521,30511,30509,30513,30514,30516,30515,30525,30501,30523,30517,30792,
+30802,30793,30797,30794,30796,30758,30789,30800,31076,31079,31081,31082,31075,
+31083,31073,31163,31226,31224,31222,31223,31375,31380,31376,31541,31559,31540,
+31525,31536,31522,31524,31539,31512,31530,31517,31537,31531,31533,31535,31538,
+31544,31514,31523,31892,31896,31894,31907,32053,32061,32056,32054,32058,32069,
+32044,32041,32065,32071,32062,32063,32074,32059,32040,32611,32661,32668,32669,
+32667,32714,32715,32717,32720,32721,32711,32719,32713,32799,32798,32795,32839,
+32835,32840,33048,33061,33049,33051,33069,33055,33068,33054,33057,33045,33063,
+33053,33058,33297,33336,33331,33338,33332,33330,33396,33680,33699,33704,33677,
+33658,33651,33700,33652,33679,33665,33685,33689,33653,33684,33705,33661,33667,
+33676,33693,33691,33706,33675,33662,33701,33711,33672,33687,33712,33663,33702,
+33671,33710,33654,33690,34393,34390,34495,34487,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34498,34497,34501,34490,34480,34504,
+34489,34483,34488,34508,34484,34491,34492,34499,34493,34494,34898,34953,34965,
+34984,34978,34986,34970,34961,34977,34975,34968,34983,34969,34971,34967,34980,
+34988,34956,34963,34958,35202,35286,35289,35285,35376,35367,35372,35358,35897,
+35899,35932,35933,35965,36005,36221,36219,36217,36284,36290,36281,36287,36289,
+36568,36574,36573,36572,36567,36576,36577,36900,36875,36881,36892,36876,36897,
+37103,37098,37104,37108,37106,37107,37076,37099,37100,37097,37206,37208,37210,
+37203,37205,37356,37364,37361,37363,37368,37348,37369,37354,37355,37367,37352,
+37358,38266,38278,38280,38524,38509,38507,38513,38511,38591,38762,38916,39141,
+39319,20635,20629,20628,20638,20619,20643,20611,20620,20622,20637,20584,20636,
+20626,20610,20615,20831,20948,21266,21265,21412,21415,21905,21928,21925,21933,
+21879,22085,21922,21907,21896,21903,21941,21889,21923,21906,21924,21885,21900,
+21926,21887,21909,21921,21902,22284,22569,22583,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22553,22558,22567,22563,22568,22517,
+22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,22587,
+22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,23189,
+23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,23183,
+23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,23875,
+23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,23857,
+23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,24408,
+24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,24854,
+24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,24836,
+24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,25546,
+25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,25555,
+25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,25948,
+25960,25957,25996,26013,26014,26030,26064,26066,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26236,26220,26235,26240,26225,26233,
+26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,26895,26838,
+26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,26992,26804,
+26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,26903,26830,
+26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,26823,27449,
+27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,27696,28156,
+28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,28225,28253,
+28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,28252,28257,
+28209,28200,28256,28273,28267,28217,28194,28208,28243,28261,28199,28280,28260,
+28279,28245,28281,28242,28262,28213,28214,28250,28960,28958,28975,28923,28974,
+28977,28963,28965,28962,28978,28959,28968,28986,28955,29259,29274,29320,29321,
+29318,29317,29323,29458,29451,29488,29474,29489,29491,29479,29490,29485,29478,
+29475,29493,29452,29742,29740,29744,29739,29718,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29722,29729,29741,29745,29732,29731,
+29725,29737,29728,29746,29947,29999,30063,30060,30183,30170,30177,30182,30173,
+30175,30180,30167,30357,30354,30426,30534,30535,30532,30541,30533,30538,30542,
+30539,30540,30686,30700,30816,30820,30821,30812,30829,30833,30826,30830,30832,
+30825,30824,30814,30818,31092,31091,31090,31088,31234,31242,31235,31244,31236,
+31385,31462,31460,31562,31547,31556,31560,31564,31566,31552,31576,31557,31906,
+31902,31912,31905,32088,32111,32099,32083,32086,32103,32106,32079,32109,32092,
+32107,32082,32084,32105,32081,32095,32078,32574,32575,32613,32614,32674,32672,
+32673,32727,32849,32847,32848,33022,32980,33091,33098,33106,33103,33095,33085,
+33101,33082,33254,33262,33271,33272,33273,33284,33340,33341,33343,33397,33595,
+33743,33785,33827,33728,33768,33810,33767,33764,33788,33782,33808,33734,33736,
+33771,33763,33727,33793,33757,33765,33752,33791,33761,33739,33742,33750,33781,
+33737,33801,33807,33758,33809,33798,33730,33779,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33749,33786,33735,33745,33770,33811,
+33731,33772,33774,33732,33787,33751,33762,33819,33755,33790,34520,34530,34534,
+34515,34531,34522,34538,34525,34539,34524,34540,34537,34519,34536,34513,34888,
+34902,34901,35002,35031,35001,35000,35008,35006,34998,35004,34999,35005,34994,
+35073,35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,
+35415,35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,
+36026,36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,
+36316,36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,
+36581,36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,
+37126,37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,
+37217,37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,
+37376,37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,
+37398,38267,38285,38284,38288,38535,38526,38536,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38537,38531,38528,38594,38600,38595,
+38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,
+20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,
+20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,
+21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,
+21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,
+22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,
+23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,
+23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,
+23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,
+24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,
+24886,24882,24878,24902,24879,24911,24873,24896,25120,37224,25123,25125,25124,
+25541,25585,25579,25616,25618,25609,25632,25636,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25651,25667,25631,25621,25624,25657,
+25655,25634,25635,25612,25638,25648,25640,25665,25653,25647,25610,25626,25664,
+25637,25639,25611,25575,25627,25646,25633,25614,25967,26002,26067,26246,26252,
+26261,26256,26251,26250,26265,26260,26232,26400,26982,26975,26936,26958,26978,
+26993,26943,26949,26986,26937,26946,26967,26969,27002,26952,26953,26933,26988,
+26931,26941,26981,26864,27000,26932,26985,26944,26991,26948,26998,26968,26945,
+26996,26956,26939,26955,26935,26972,26959,26961,26930,26962,26927,27003,26940,
+27462,27461,27459,27458,27464,27457,27547,64013,27643,27644,27641,27639,27640,
+28315,28374,28360,28303,28352,28319,28307,28308,28320,28337,28345,28358,28370,
+28349,28353,28318,28361,28343,28336,28365,28326,28367,28338,28350,28355,28380,
+28376,28313,28306,28302,28301,28324,28321,28351,28339,28368,28362,28311,28334,
+28323,28999,29012,29010,29027,29024,28993,29021,29026,29042,29048,29034,29025,
+28994,29016,28995,29003,29040,29023,29008,29011,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28996,29005,29018,29263,29325,29324,
+29329,29328,29326,29500,29506,29499,29498,29504,29514,29513,29764,29770,29771,
+29778,29777,29783,29760,29775,29776,29774,29762,29766,29773,29780,29921,29951,
+29950,29949,29981,30073,30071,27011,30191,30223,30211,30199,30206,30204,30201,
+30200,30224,30203,30198,30189,30197,30205,30361,30389,30429,30549,30559,30560,
+30546,30550,30554,30569,30567,30548,30553,30573,30688,30855,30874,30868,30863,
+30852,30869,30853,30854,30881,30851,30841,30873,30848,30870,30843,31100,31106,
+31101,31097,31249,31256,31257,31250,31255,31253,31266,31251,31259,31248,31395,
+31394,31390,31467,31590,31588,31597,31604,31593,31602,31589,31603,31601,31600,
+31585,31608,31606,31587,31922,31924,31919,32136,32134,32128,32141,32127,32133,
+32122,32142,32123,32131,32124,32140,32148,32132,32125,32146,32621,32619,32615,
+32616,32620,32678,32677,32679,32731,32732,32801,33124,33120,33143,33116,33129,
+33115,33122,33138,26401,33118,33142,33127,33135,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33092,33121,33309,33353,33348,33344,
+33346,33349,34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,
+33895,33840,33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,
+33844,33914,33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,
+33904,33849,33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,
+33918,33860,33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,
+34549,34637,34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,
+35038,35035,35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,
+35292,35302,35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,
+35444,35450,35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,
+36201,36241,36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,
+36337,36334,36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,
+36608,36613,36615,36616,36610,36619,36946,36927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36932,36937,36925,37136,37133,37135,
+37137,37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,
+37477,37470,37507,37422,37450,37446,37485,37484,37455,37472,37479,37487,37430,
+37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,37462,37426,38303,
+38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,38648,38645,38771,
+38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,39346,39344,39349,
+39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,20695,20712,20723,
+20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,20952,21120,21121,
+21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,22044,22017,22035,
+22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,22662,22657,22655,
+22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,22676,22671,22782,
+22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,23266,23264,23259,
+23276,23262,23261,23257,23272,23263,23415,23520,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23523,23651,23938,23936,23933,23942,
+23930,23937,23927,23946,23945,23944,23934,23932,23949,23929,23935,24152,24153,
+24147,24280,24273,24279,24270,24284,24277,24281,24274,24276,24388,24387,24431,
+24502,24876,24872,24897,24926,24945,24947,24914,24915,24946,24940,24960,24948,
+24916,24954,24923,24933,24891,24938,24929,24918,25129,25127,25131,25643,25677,
+25691,25693,25716,25718,25714,25715,25725,25717,25702,25766,25678,25730,25694,
+25692,25675,25683,25696,25680,25727,25663,25708,25707,25689,25701,25719,25971,
+26016,26273,26272,26271,26373,26372,26402,27057,27062,27081,27040,27086,27030,
+27056,27052,27068,27025,27033,27022,27047,27021,27049,27070,27055,27071,27076,
+27069,27044,27092,27065,27082,27034,27087,27059,27027,27050,27041,27038,27097,
+27031,27024,27074,27061,27045,27078,27466,27469,27467,27550,27551,27552,27587,
+27588,27646,28366,28405,28401,28419,28453,28408,28471,28411,28462,28425,28494,
+28441,28442,28455,28440,28475,28434,28397,28426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28470,28531,28409,28398,28461,28480,
+28464,28476,28469,28395,28423,28430,28483,28421,28413,28406,28473,28444,28412,
+28474,28447,28429,28446,28424,28449,29063,29072,29065,29056,29061,29058,29071,
+29051,29062,29057,29079,29252,29267,29335,29333,29331,29507,29517,29521,29516,
+29794,29811,29809,29813,29810,29799,29806,29952,29954,29955,30077,30096,30230,
+30216,30220,30229,30225,30218,30228,30392,30593,30588,30597,30594,30574,30592,
+30575,30590,30595,30898,30890,30900,30893,30888,30846,30891,30878,30885,30880,
+30892,30882,30884,31128,31114,31115,31126,31125,31124,31123,31127,31112,31122,
+31120,31275,31306,31280,31279,31272,31270,31400,31403,31404,31470,31624,31644,
+31626,31633,31632,31638,31629,31628,31643,31630,31621,31640,21124,31641,31652,
+31618,31931,31935,31932,31930,32167,32183,32194,32163,32170,32193,32192,32197,
+32157,32206,32196,32198,32203,32204,32175,32185,32150,32188,32159,32166,32174,
+32169,32161,32201,32627,32738,32739,32741,32734,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32804,32861,32860,33161,33158,33155,
+33159,33165,33164,33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,
+33966,33963,33977,33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,
+33954,33940,33991,33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,
+34007,34004,34002,34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,
+34590,34593,34585,34587,34627,34604,34625,34622,34630,34592,34610,34602,34605,
+34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,34577,
+35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,35051,
+35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,35478,
+35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,36362,
+36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,37148,
+37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,37541,
+37540,37494,37531,37498,37536,37524,37546,37517,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37542,37530,37547,37497,37527,37503,
+37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,37516,37529,
+37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,38781,38778,
+38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,39085,39086,
+39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,39367,39601,
+39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,20735,20739,
+20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,21132,21233,
+21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,22080,22067,
+22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,22691,22703,
+22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,23298,23289,
+23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,23957,23968,
+23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,24289,24393,
+24498,24971,24963,24953,25009,25008,24994,24969,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24987,24979,25007,25005,24991,24978,
+25002,24993,24973,24934,25011,25133,25710,25712,25750,25760,25733,25751,25756,
+25743,25739,25738,25740,25763,25759,25704,25777,25752,25974,25978,25977,25979,
+26034,26035,26293,26288,26281,26290,26295,26282,26287,27136,27142,27159,27109,
+27128,27157,27121,27108,27168,27135,27116,27106,27163,27165,27134,27175,27122,
+27118,27156,27127,27111,27200,27144,27110,27131,27149,27132,27115,27145,27140,
+27160,27173,27151,27126,27174,27143,27124,27158,27473,27557,27555,27554,27558,
+27649,27648,27647,27650,28481,28454,28542,28551,28614,28562,28557,28553,28556,
+28514,28495,28549,28506,28566,28534,28524,28546,28501,28530,28498,28496,28503,
+28564,28563,28509,28416,28513,28523,28541,28519,28560,28499,28555,28521,28543,
+28565,28515,28535,28522,28539,29106,29103,29083,29104,29088,29082,29097,29109,
+29085,29093,29086,29092,29089,29098,29084,29095,29107,29336,29338,29528,29522,
+29534,29535,29536,29533,29531,29537,29530,29529,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29538,29831,29833,29834,29830,29825,
+29821,29829,29832,29820,29817,29960,29959,30078,30245,30238,30233,30237,30236,
+30243,30234,30248,30235,30364,30365,30366,30363,30605,30607,30601,30600,30925,
+30907,30927,30924,30929,30926,30932,30920,30915,30916,30921,31130,31137,31136,
+31132,31138,31131,27510,31289,31410,31412,31411,31671,31691,31678,31660,31694,
+31663,31673,31690,31669,31941,31944,31948,31947,32247,32219,32234,32231,32215,
+32225,32259,32250,32230,32246,32241,32240,32238,32223,32630,32684,32688,32685,
+32749,32747,32746,32748,32742,32744,32868,32871,33187,33183,33182,33173,33186,
+33177,33175,33302,33359,33363,33362,33360,33358,33361,34084,34107,34063,34048,
+34089,34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,
+34036,34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,
+34088,34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,
+34041,34072,34080,34096,34059,34073,34095,34402,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34646,34659,34660,34679,34785,34675,
+34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,
+34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,
+34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,
+35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,
+35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,
+36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,
+36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,
+36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,
+36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,
+37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,
+37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,
+37581,37589,37577,37600,37598,37607,37585,37587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37557,37601,37574,37556,38268,38316,
+38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,38792,
+38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,39162,
+39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,39382,
+39384,39371,39383,39372,39603,39660,39659,39667,39666,39665,39750,39747,39783,
+39796,39793,39782,39798,39797,39792,39784,39780,39788,40188,40186,40189,40191,
+40183,40199,40192,40185,40187,40200,40197,40196,40579,40659,40719,40720,20764,
+20755,20759,20762,20753,20958,21300,21473,22128,22112,22126,22131,22118,22115,
+22125,22130,22110,22135,22300,22299,22728,22717,22729,22719,22714,22722,22716,
+22726,23319,23321,23323,23329,23316,23315,23312,23318,23336,23322,23328,23326,
+23535,23980,23985,23977,23975,23989,23984,23982,23978,23976,23986,23981,23983,
+23988,24167,24168,24166,24175,24297,24295,24294,24296,24293,24395,24508,24989,
+25000,24982,25029,25012,25030,25025,25036,25018,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25023,25016,24972,25815,25814,25808,
+25807,25801,25789,25737,25795,25819,25843,25817,25907,25983,25980,26018,26312,
+26302,26304,26314,26315,26319,26301,26299,26298,26316,26403,27188,27238,27209,
+27239,27186,27240,27198,27229,27245,27254,27227,27217,27176,27226,27195,27199,
+27201,27242,27236,27216,27215,27220,27247,27241,27232,27196,27230,27222,27221,
+27213,27214,27206,27477,27476,27478,27559,27562,27563,27592,27591,27652,27651,
+27654,28589,28619,28579,28615,28604,28622,28616,28510,28612,28605,28574,28618,
+28584,28676,28581,28590,28602,28588,28586,28623,28607,28600,28578,28617,28587,
+28621,28591,28594,28592,29125,29122,29119,29112,29142,29120,29121,29131,29140,
+29130,29127,29135,29117,29144,29116,29126,29146,29147,29341,29342,29545,29542,
+29543,29548,29541,29547,29546,29823,29850,29856,29844,29842,29845,29857,29963,
+30080,30255,30253,30257,30269,30259,30268,30261,30258,30256,30395,30438,30618,
+30621,30625,30620,30619,30626,30627,30613,30617,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30615,30941,30953,30949,30954,30942,
+30947,30939,30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,
+31413,31409,31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,
+31722,31714,31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,
+32279,32268,32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,
+32269,32276,32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,
+33201,33190,33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,
+33365,33366,33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,
+34113,34146,34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,
+34151,34144,34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,
+34711,34707,34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,
+34717,34692,34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,
+35106,35113,35107,35119,35116,35103,35313,35552,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35554,35570,35572,35573,35549,35604,
+35556,35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,
+36085,36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,
+36421,36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,
+36663,36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,
+37261,37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,
+37650,37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,
+37684,37634,37668,37631,37673,37689,37685,37674,37652,37644,37643,37630,37641,
+37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,38325,38333,38569,
+38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,38959,38962,39204,
+39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,39402,39401,39399,
+39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,39813,39815,39804,
+39806,39803,39810,39827,39826,39824,39802,39829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39805,39816,40229,40215,40224,40222,
+40212,40233,40221,40216,40226,40208,40217,40223,40584,40582,40583,40622,40621,
+40661,40662,40698,40722,40765,20774,20773,20770,20772,20768,20777,21236,22163,
+22156,22157,22150,22148,22147,22142,22146,22143,22145,22742,22740,22735,22738,
+23341,23333,23346,23331,23340,23335,23334,23343,23342,23419,23537,23538,23991,
+24172,24170,24510,24507,25027,25013,25020,25063,25056,25061,25060,25064,25054,
+25839,25833,25827,25835,25828,25832,25985,25984,26038,26074,26322,27277,27286,
+27265,27301,27273,27295,27291,27297,27294,27271,27283,27278,27285,27267,27304,
+27300,27281,27263,27302,27290,27269,27276,27282,27483,27565,27657,28620,28585,
+28660,28628,28643,28636,28653,28647,28646,28638,28658,28637,28642,28648,29153,
+29169,29160,29170,29156,29168,29154,29555,29550,29551,29847,29874,29867,29840,
+29866,29869,29873,29861,29871,29968,29969,29970,29967,30084,30275,30280,30281,
+30279,30372,30441,30645,30635,30642,30647,30646,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30644,30641,30632,30704,30963,30973,
+30978,30971,30972,30962,30981,30969,30974,30980,31147,31144,31324,31323,31318,
+31320,31316,31322,31422,31424,31425,31749,31759,31730,31744,31743,31739,31758,
+31732,31755,31731,31746,31753,31747,31745,31736,31741,31750,31728,31729,31760,
+31754,31976,32301,32316,32322,32307,38984,32312,32298,32329,32320,32327,32297,
+32332,32304,32315,32310,32324,32314,32581,32639,32638,32637,32756,32754,32812,
+33211,33220,33228,33226,33221,33223,33212,33257,33371,33370,33372,34179,34176,
+34191,34215,34197,34208,34187,34211,34171,34212,34202,34206,34167,34172,34185,
+34209,34170,34168,34135,34190,34198,34182,34189,34201,34205,34177,34210,34178,
+34184,34181,34169,34166,34200,34192,34207,34408,34750,34730,34733,34757,34736,
+34732,34745,34741,34748,34734,34761,34755,34754,34764,34743,34735,34756,34762,
+34740,34742,34751,34744,34749,34782,34738,35125,35123,35132,35134,35137,35154,
+35127,35138,35245,35247,35246,35314,35315,35614,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35608,35606,35601,35589,35595,35618,
+35599,35602,35605,35591,35597,35592,35590,35612,35603,35610,35919,35952,35954,
+35953,35951,35989,35988,36089,36207,36430,36429,36435,36432,36428,36423,36675,
+36672,36997,36990,37176,37274,37282,37275,37273,37279,37281,37277,37280,37793,
+37763,37807,37732,37718,37703,37756,37720,37724,37750,37705,37712,37713,37728,
+37741,37775,37708,37738,37753,37719,37717,37714,37711,37745,37751,37755,37729,
+37726,37731,37735,37760,37710,37721,38343,38336,38345,38339,38341,38327,38574,
+38576,38572,38688,38687,38680,38685,38681,38810,38817,38812,38814,38813,38869,
+38868,38897,38977,38980,38986,38985,38981,38979,39205,39211,39212,39210,39219,
+39218,39215,39213,39217,39216,39320,39331,39329,39426,39418,39412,39415,39417,
+39416,39414,39419,39421,39422,39420,39427,39614,39678,39677,39681,39676,39752,
+39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,40243,
+40257,40295,40246,40238,40239,40241,40248,40240,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40261,40258,40259,40254,40247,40256,
+40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,40740,40739,
+40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,22169,22896,
+23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,25066,25072,
+25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,26075,26330,
+26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,27316,27309,
+27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,28672,28667,
+28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,29888,29877,
+29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,30291,30295,
+30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,30992,30994,
+30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,31782,31784,
+31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,32352,32343,
+32339,32693,32691,32759,32760,32885,33233,33234,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33232,33375,33374,34228,34246,34240,
+34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,34248,34245,34225,
+34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,34779,34795,34794,
+34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,34724,34775,34777,
+34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,35153,35145,35626,
+35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,35621,35639,35622,
+35638,35630,35620,35643,35645,35642,35906,35957,35993,35992,35991,36094,36100,
+36098,36096,36444,36450,36448,36439,36438,36446,36453,36455,36443,36442,36449,
+36445,36457,36436,36678,36679,36680,36683,37160,37178,37179,37182,37288,37285,
+37287,37295,37290,37813,37772,37778,37815,37787,37789,37769,37799,37774,37802,
+37790,37798,37781,37768,37785,37791,37773,37809,37777,37810,37796,37800,37812,
+37795,37797,38354,38355,38353,38579,38615,38618,24002,38623,38616,38621,38691,
+38690,38693,38828,38830,38824,38827,38820,38826,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38818,38821,38871,38873,38870,38872,
+38906,38992,38993,38994,39096,39233,39228,39226,39439,39435,39433,39437,39428,
+39441,39434,39429,39431,39430,39616,39644,39688,39684,39685,39721,39733,39754,
+39756,39755,39879,39878,39875,39871,39873,39861,39864,39891,39862,39876,39865,
+39869,40284,40275,40271,40266,40283,40267,40281,40278,40268,40279,40274,40276,
+40287,40280,40282,40590,40588,40671,40705,40704,40726,40741,40747,40746,40745,
+40744,40780,40789,20788,20789,21142,21239,21428,22187,22189,22182,22183,22186,
+22188,22746,22749,22747,22802,23357,23358,23359,24003,24176,24511,25083,25863,
+25872,25869,25865,25868,25870,25988,26078,26077,26334,27367,27360,27340,27345,
+27353,27339,27359,27356,27344,27371,27343,27341,27358,27488,27568,27660,28697,
+28711,28704,28694,28715,28705,28706,28707,28713,28695,28708,28700,28714,29196,
+29194,29191,29186,29189,29349,29350,29348,29347,29345,29899,29893,29879,29891,
+29974,30304,30665,30666,30660,30705,31005,31003,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31009,31004,30999,31006,31152,31335,
+31336,31795,31804,31801,31788,31803,31980,31978,32374,32373,32376,32368,32375,
+32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,
+33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,
+34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,
+34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,
+34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,
+35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,
+35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,
+36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,
+37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,
+37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,
+38362,38363,38625,38697,38699,38700,38696,38694,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38835,38839,38838,38877,38878,38879,
+39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,39335,
+39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,39444,
+39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,39906,
+39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,40330,
+40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,40304,
+40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,40640,
+40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,22755,
+23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,26079,
+26344,26339,26340,27379,27376,27370,27368,27385,27377,27374,27375,28732,28725,
+28719,28727,28724,28721,28738,28728,28735,28730,28729,28736,28731,28723,28737,
+29203,29204,29352,29565,29564,29882,30379,30378,30398,30445,30668,30670,30671,
+30669,30706,31013,31011,31015,31016,31012,31017,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31154,31342,31340,31341,31479,31817,
+31816,31818,31815,31813,31982,32379,32382,32385,32384,32698,32767,32889,33243,
+33241,33291,33384,33385,34338,34303,34305,34302,34331,34304,34294,34308,34313,
+34309,34316,34301,34841,34832,34833,34839,34835,34838,35171,35174,35257,35319,
+35680,35690,35677,35688,35683,35685,35687,35693,36270,36486,36488,36484,36697,
+36694,36695,36693,36696,36698,37005,37187,37185,37303,37301,37298,37299,37899,
+37907,37883,37920,37903,37908,37886,37909,37904,37928,37913,37901,37877,37888,
+37879,37895,37902,37910,37906,37882,37897,37880,37898,37887,37884,37900,37878,
+37905,37894,38366,38368,38367,38702,38703,38841,38843,38909,38910,39008,39010,
+39011,39007,39105,39106,39248,39246,39257,39244,39243,39251,39474,39476,39473,
+39468,39466,39478,39465,39470,39480,39469,39623,39626,39622,39696,39698,39697,
+39947,39944,39927,39941,39954,39928,40000,39943,39950,39942,39959,39956,39945,
+40351,40345,40356,40349,40338,40344,40336,40347,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40352,40340,40348,40362,40343,40353,
+40346,40354,40360,40350,40355,40383,40361,40342,40358,40359,40601,40603,40602,
+40677,40676,40679,40678,40752,40750,40795,40800,40798,40797,40793,40849,20794,
+20793,21144,21143,22211,22205,22206,23368,23367,24011,24015,24305,25085,25883,
+27394,27388,27395,27384,27392,28739,28740,28746,28744,28745,28741,28742,29213,
+29210,29209,29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,
+32391,32392,32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,
+34339,34332,34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,
+34848,34852,34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,
+35706,35707,36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,
+37305,37951,37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,
+37937,38373,38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,
+39254,39481,39485,39494,39492,39490,39489,39482,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39487,39629,39701,39703,39704,39702,
+39738,39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,
+40380,40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,
+40364,40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,
+40731,40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,
+23371,23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,
+28757,28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,
+30381,31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,
+32591,32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,
+34858,34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,
+36501,36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,
+37963,37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,
+39259,39502,39507,39508,39500,39503,39496,39498,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39497,39506,39504,39632,39705,39723,
+39739,39766,39765,40006,40008,39999,40004,39993,39987,40001,39996,39991,39988,
+39986,39997,39990,40411,40402,40414,40410,40395,40400,40412,40401,40415,40425,
+40409,40408,40406,40437,40405,40413,40630,40688,40757,40755,40754,40770,40811,
+40853,40866,20797,21145,22760,22759,22898,23373,24024,34863,24399,25089,25091,
+25092,25897,25893,26006,26347,27409,27410,27407,27594,28763,28762,29218,29570,
+29569,29571,30320,30676,31847,31846,32405,33388,34362,34368,34361,34364,34353,
+34363,34366,34864,34866,34862,34867,35190,35188,35187,35326,35724,35726,35723,
+35720,35909,36121,36504,36708,36707,37308,37986,37973,37981,37975,37982,38852,
+38853,38912,39510,39513,39710,39711,39712,40018,40024,40016,40010,40013,40011,
+40021,40025,40012,40014,40443,40439,40431,40419,40427,40440,40420,40438,40417,
+40430,40422,40434,40432,40418,40428,40436,40435,40424,40429,40642,40656,40690,
+40691,40710,40732,40760,40759,40758,40771,40783,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40817,40816,40814,40815,22227,22221,
+23374,23661,25901,26349,26350,27411,28767,28769,28765,28768,29219,29915,29925,
+30677,31032,31159,31158,31850,32407,32649,33389,34371,34872,34871,34869,34891,
+35732,35733,36510,36511,36512,36509,37310,37309,37314,37995,37992,37993,38629,
+38726,38723,38727,38855,38885,39518,39637,39769,40035,40039,40038,40034,40030,
+40032,40450,40446,40455,40451,40454,40453,40448,40449,40457,40447,40445,40452,
+40608,40734,40774,40820,40821,40822,22228,25902,26040,27416,27417,27415,27418,
+28770,29222,29354,30680,30681,31033,31849,31851,31990,32410,32408,32411,32409,
+33248,33249,34374,34375,34376,35193,35194,35196,35195,35327,35736,35737,36517,
+36516,36515,37998,37997,37999,38001,38003,38729,39026,39263,40040,40046,40045,
+40459,40461,40464,40463,40466,40465,40609,40693,40713,40775,40824,40827,40826,
+40825,22302,28774,31855,34876,36274,36518,37315,38004,38008,38006,38005,39520,
+40052,40051,40049,40053,40468,40467,40694,40714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40868,28776,28773,31991,34410,34878,
+34877,34879,35742,35996,36521,36553,38731,39027,39028,39116,39265,39339,39524,
+39526,39527,39716,40469,40471,40776,25095,27422,29223,34380,36520,38018,38016,
+38017,39529,39528,39726,40473,29225,34379,35743,38019,40057,40631,30325,39531,
+40058,40477,28777,28778,40612,40830,40777,40856,
+};
+
+static const struct dbcs_index big5_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_decmap+0,64,254},{
+__big5_decmap+191,64,254},{__big5_decmap+382,64,191},{__big5_decmap+510,64,254
+},{__big5_decmap+701,64,254},{__big5_decmap+892,64,254},{__big5_decmap+1083,
+64,254},{__big5_decmap+1274,64,254},{__big5_decmap+1465,64,254},{__big5_decmap
++1656,64,254},{__big5_decmap+1847,64,254},{__big5_decmap+2038,64,254},{
+__big5_decmap+2229,64,254},{__big5_decmap+2420,64,254},{__big5_decmap+2611,64,
+254},{__big5_decmap+2802,64,254},{__big5_decmap+2993,64,254},{__big5_decmap+
+3184,64,254},{__big5_decmap+3375,64,254},{__big5_decmap+3566,64,254},{
+__big5_decmap+3757,64,254},{__big5_decmap+3948,64,254},{__big5_decmap+4139,64,
+254},{__big5_decmap+4330,64,254},{__big5_decmap+4521,64,254},{__big5_decmap+
+4712,64,254},{__big5_decmap+4903,64,254},{__big5_decmap+5094,64,254},{
+__big5_decmap+5285,64,254},{__big5_decmap+5476,64,254},{__big5_decmap+5667,64,
+254},{__big5_decmap+5858,64,254},{__big5_decmap+6049,64,254},{__big5_decmap+
+6240,64,254},{__big5_decmap+6431,64,254},{__big5_decmap+6622,64,254},{
+__big5_decmap+6813,64,254},{__big5_decmap+7004,64,254},{__big5_decmap+7195,64,
+252},{0,0,0},{__big5_decmap+7384,64,254},{__big5_decmap+7575,64,254},{
+__big5_decmap+7766,64,254},{__big5_decmap+7957,64,254},{__big5_decmap+8148,64,
+254},{__big5_decmap+8339,64,254},{__big5_decmap+8530,64,254},{__big5_decmap+
+8721,64,254},{__big5_decmap+8912,64,254},{__big5_decmap+9103,64,254},{
+__big5_decmap+9294,64,254},{__big5_decmap+9485,64,254},{__big5_decmap+9676,64,
+254},{__big5_decmap+9867,64,254},{__big5_decmap+10058,64,254},{__big5_decmap+
+10249,64,254},{__big5_decmap+10440,64,254},{__big5_decmap+10631,64,254},{
+__big5_decmap+10822,64,254},{__big5_decmap+11013,64,254},{__big5_decmap+11204,
+64,254},{__big5_decmap+11395,64,254},{__big5_decmap+11586,64,254},{
+__big5_decmap+11777,64,254},{__big5_decmap+11968,64,254},{__big5_decmap+12159,
+64,254},{__big5_decmap+12350,64,254},{__big5_decmap+12541,64,254},{
+__big5_decmap+12732,64,254},{__big5_decmap+12923,64,254},{__big5_decmap+13114,
+64,254},{__big5_decmap+13305,64,254},{__big5_decmap+13496,64,254},{
+__big5_decmap+13687,64,254},{__big5_decmap+13878,64,254},{__big5_decmap+14069,
+64,254},{__big5_decmap+14260,64,254},{__big5_decmap+14451,64,254},{
+__big5_decmap+14642,64,254},{__big5_decmap+14833,64,254},{__big5_decmap+15024,
+64,254},{__big5_decmap+15215,64,254},{__big5_decmap+15406,64,254},{
+__big5_decmap+15597,64,254},{__big5_decmap+15788,64,254},{__big5_decmap+15979,
+64,254},{__big5_decmap+16170,64,254},{__big5_decmap+16361,64,254},{
+__big5_decmap+16552,64,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __big5_encmap[21764] = {
+41542,41543,N,41540,N,41393,N,N,N,N,N,N,N,N,41560,41427,N,N,N,N,N,41296,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41425,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41426,41918,N,41916,41917,41919,
+N,41413,N,N,N,N,N,N,N,N,N,N,N,41915,41796,41797,41798,41799,41800,41801,41802,
+41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,N,41813,41814,
+41815,41816,41817,41818,41819,N,N,N,N,N,N,N,41820,41821,41822,41823,41824,
+41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,N,
+41837,41838,41839,41840,41841,41842,41843,51123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,51121,51122,51124,51125,51126,51127,51128,51129,51130,N,N,N,N,N,N,51131,
+51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144,
+51145,51146,51147,51148,51149,51151,51152,51153,51154,51155,51156,51157,51158,
+51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171,
+51172,51173,51174,51175,51176,N,51150,41302,41304,N,N,N,41381,41382,N,N,41383,
+41384,N,N,N,N,41285,N,N,41292,41291,N,N,N,N,N,N,N,N,N,N,N,41388,N,N,41387,N,N,
+N,N,N,41392,N,N,41410,41546,N,41409,N,N,N,41547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41657,41658,
+41659,41660,41661,41662,41663,41664,41665,41666,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41462,41460,41463,41461,N,N,
+41464,41465,41467,41466,41428,N,N,N,41435,41448,41447,N,N,41469,N,41468,N,N,N,
+41444,41445,41452,N,N,41453,N,N,N,N,N,41455,41454,N,N,N,N,N,N,41443,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41436,N,N,N,N,N,N,N,N,N,N,N,N,N,41434,41437,N,
+N,N,N,41432,41433,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41446,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41449,51177,51178,51179,51180,51181,
+51182,51183,51184,51185,51186,N,N,N,N,N,N,N,N,N,N,51187,51188,51189,51190,
+51191,51192,51193,51194,51195,51196,41591,N,41592,N,N,N,N,N,N,N,N,N,41594,N,N,
+N,41595,N,N,N,41596,N,N,N,41597,N,N,N,41589,N,N,N,N,N,N,N,41588,N,N,N,N,N,N,N,
+41587,N,N,N,N,N,N,N,41586,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,41636,N,N,N,N,N,N,N,N,N,N,N,N,N,41637,N,N,41639,N,N,N,N,N,N,N,N,41638,N,
+N,41598,41633,41635,41634,41644,41645,41646,41306,N,N,N,N,N,N,N,N,N,N,N,N,
+41570,41571,41572,41573,41574,41575,41576,41577,41584,41583,41582,41581,41580,
+41579,41578,N,N,N,N,41590,41593,N,N,N,N,N,N,N,N,N,N,41405,41404,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,41398,41397,N,N,N,N,N,N,N,N,41407,41406,N,N,N,N,N,N,N,N,
+41403,41402,N,N,N,41395,N,N,41399,41396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41640,41641,41643,41642,41401,41400,N,N,41459,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41456,41458,41457,41280,41282,41283,41394,N,50852,N,N,41329,41330,41325,41326,
+41333,41334,41337,41338,41321,41322,41541,N,41317,41318,N,N,N,N,N,N,N,41385,
+41386,N,N,41667,41668,41669,41670,41671,41672,41673,41674,41675,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50853,50854,50855,50856,50857,50858,50859,
+50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872,
+50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885,
+50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898,
+50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911,
+50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924,
+50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,N,N,N,N,N,N,
+N,N,N,50850,50851,N,N,50936,50937,50938,50939,50940,50941,50942,51008,51009,
+51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022,
+51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035,
+51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048,
+51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061,
+51062,51063,51064,51065,51066,51067,51068,51069,51070,51105,51106,51107,51108,
+51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,N,N,N,
+N,N,N,N,50849,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853,
+41854,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900,
+41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913,
+41914,41408,41557,41558,N,N,N,N,N,N,N,N,N,N,N,N,41552,41553,41554,N,N,41556,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41559,N,N,N,
+N,N,N,N,N,N,41555,N,N,41451,41450,N,N,41551,42048,42050,N,42051,N,N,N,51525,
+42070,42068,42071,42069,51526,42147,51535,51533,42146,42145,N,N,42306,42305,
+42304,N,42307,42238,N,N,N,N,42464,42465,N,N,N,N,N,N,43203,N,N,N,N,42072,N,
+42148,51536,N,42149,51555,42730,52145,N,N,N,N,42073,42150,N,42308,51556,N,N,N,
+N,N,51520,42052,N,42075,N,51527,42076,N,N,42151,N,42309,42311,42310,N,N,42466,
+42467,N,N,43204,N,44476,42049,N,N,51521,42053,42078,42077,N,N,N,N,N,N,N,N,N,
+42468,N,N,N,N,N,N,N,N,N,43205,N,N,N,N,N,N,N,N,N,N,45230,54347,N,N,46787,56497,
+56498,N,42054,N,42153,N,N,43206,42055,51528,42079,N,N,42154,42156,51537,42157,
+42155,N,N,N,42469,N,43207,N,N,43208,43845,N,42080,42158,N,42470,42472,42471,N,
+42731,N,N,43209,43210,43846,43847,N,N,N,N,44477,N,N,56499,N,N,63190,42056,N,N,
+N,N,N,42160,42159,51538,42161,42167,N,42162,42163,51540,51539,42165,42166,N,
+42164,N,N,N,N,N,N,42314,42315,42316,42317,42313,42320,51562,N,51558,51561,
+42321,42337,N,51560,N,42318,42319,42312,N,N,51557,51559,N,N,N,N,N,N,42485,
+51632,42482,42486,51642,51630,42483,51634,N,N,N,42484,N,42487,N,42473,51633,
+42488,51637,N,51641,51638,N,N,51635,42474,42476,42489,N,42478,51627,42481,
+42479,42480,51643,51640,51631,42477,N,N,51628,42475,N,N,N,51636,N,N,N,N,51639,
+N,N,N,N,N,N,N,N,N,51629,51814,N,42818,42740,N,N,51815,42737,N,42820,N,42745,N,
+42744,51803,42748,42743,51808,51816,N,51812,N,42746,N,N,42749,42734,42823,
+51805,N,N,52157,42732,42819,42733,42741,42742,51810,51806,42747,42739,51802,
+42735,51813,42821,42824,42738,42816,42822,42736,51811,42817,51817,51804,42750,
+51807,N,N,51809,N,43224,52159,52171,43216,N,52172,43211,43221,N,N,43214,52153,
+43222,52152,52156,52163,52161,43230,43225,52147,52149,43227,43215,52150,52162,
+52169,43220,52155,52148,43219,52151,43223,52154,N,43218,N,43213,N,43228,52164,
+43229,52168,N,52166,52170,43226,52158,52146,N,52160,43217,52165,43212,52167,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,43862,43850,N,N,52704,52712,N,43849,43857,43869,N,
+52718,52716,52711,N,N,N,43851,52717,52707,43865,43856,43864,52702,N,52714,N,
+52705,43860,52706,N,52701,43867,43854,43863,43853,N,52703,52708,N,52715,43861,
+43858,52710,43866,52713,52709,43855,43868,43859,43852,43848,N,N,N,N,N,N,N,N,N,
+N,52719,N,44503,44481,N,44497,N,44502,53456,53455,53460,53461,44484,N,44493,N,
+N,N,44506,44494,N,N,N,N,53449,44487,53450,N,44508,N,44499,44478,44479,53469,
+45247,N,44492,44491,53451,44495,54363,44486,53462,44501,44500,44490,53454,
+53463,N,53448,44489,53464,44498,53452,44480,N,44483,44482,53465,44496,44485,
+44505,44507,53459,44504,N,53467,53453,53468,N,53457,N,53466,N,53458,N,N,N,N,
+44488,N,N,N,54371,54359,N,45235,N,54364,54370,45234,54357,45238,54361,54354,
+45236,54358,45241,45246,N,54375,N,54353,N,45242,N,54374,N,N,45237,54360,45233,
+54355,54351,54365,54352,54350,54362,54368,54369,45239,N,N,55387,54366,54349,
+54367,N,45249,54372,45248,54348,N,54356,54373,45244,45243,45240,45245,N,N,
+45231,N,N,45232,N,N,46024,N,55390,55383,N,46021,N,55391,N,N,N,55381,55384,
+46020,55385,N,N,46023,55389,N,55379,55378,46025,N,46026,46022,46027,55377,
+55388,55386,55380,N,N,N,46019,55382,N,N,N,N,N,N,N,N,46794,46788,56503,46797,
+56509,56512,46790,46791,56506,46789,56515,46795,56516,N,56511,46796,N,56500,
+46793,56501,N,56510,56508,N,56504,46792,56502,46798,56507,56514,56505,56513,N,
+N,47542,47539,N,47540,N,57593,57585,47538,47535,57586,N,N,47537,57589,N,57591,
+N,N,57598,N,N,57597,57592,47534,57584,47532,57587,47543,57590,N,57594,47536,
+47533,57596,57595,47541,N,57588,N,48120,58604,N,58601,48121,N,48119,N,58608,
+58605,58598,48118,N,48122,58599,48117,48125,58602,58603,48123,48124,58609,
+58606,58607,N,N,N,48810,59640,48807,59637,48809,48811,N,59638,48808,N,59639,N,
+59636,N,N,49270,60605,49271,60603,N,60604,60602,60601,N,N,60606,49269,N,N,
+61368,61369,N,58600,61367,49272,50015,61931,61932,N,50391,50392,62913,62912,
+50540,50539,63440,N,42057,42081,42169,N,42168,42323,42322,42492,42491,42493,
+42490,N,42826,42825,42827,N,N,N,N,43232,N,43231,43233,N,43870,N,41561,53470,
+41562,45250,41564,41563,55392,N,41565,47544,41566,N,42058,N,42170,42494,43234,
+N,42059,42173,42171,42172,N,N,42560,N,N,N,42828,43236,43235,43237,N,N,N,44509,
+N,N,N,48812,N,N,N,N,N,N,51534,N,42324,42325,N,N,42561,N,51818,N,43872,43871,
+53472,53471,45251,N,42174,51541,N,N,N,N,N,52173,N,43873,N,44512,N,44510,44511,
+N,N,N,N,48813,N,42326,N,N,N,42562,51644,N,N,N,N,42829,42830,N,51819,N,N,52174,
+43238,52175,N,N,N,N,N,53474,53475,44515,N,53476,N,53473,44516,44514,44513,
+53477,N,54376,N,N,N,55393,N,N,56517,57664,N,N,N,48126,48814,59641,N,42060,
+42074,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45252,46029,N,47545,N,51522,42175,N,42329,
+42327,42328,N,N,43239,42061,42062,N,42082,N,N,42176,42177,42178,51646,42330,N,
+51563,N,42566,N,51647,42564,42565,51645,N,N,42567,42563,N,N,N,N,51820,43756,
+51821,N,N,51822,N,N,42832,42831,N,N,42835,42833,42834,N,N,N,43245,N,43244,
+52180,52177,52178,N,52176,43246,43242,43241,N,43243,43240,N,N,N,N,N,43247,N,
+43875,52720,N,52179,43880,N,52721,43876,43879,43878,43877,43874,N,N,N,53480,N,
+44519,53483,44517,N,N,N,53479,44520,44518,44521,53481,53482,N,53478,53484,N,N,
+N,N,N,N,46033,45253,54377,54379,54378,54380,45254,N,N,46030,N,46031,46032,N,
+46800,56519,N,56518,56520,56521,46801,N,46799,57665,57666,47547,47546,58202,N,
+N,48192,48193,48194,48196,58610,58611,48195,N,N,N,48815,N,48816,N,N,61933,
+62915,62914,63441,N,42063,N,N,N,42332,42331,N,N,42568,N,N,51648,N,N,42837,
+42838,42836,42839,51823,51824,N,N,N,N,N,N,N,N,N,N,N,N,43249,52181,N,43248,N,
+52722,43884,52723,43883,N,N,N,43881,N,43882,N,N,N,53485,N,N,N,N,45255,54382,N,
+45258,54381,45541,45257,45256,N,46036,N,46035,46034,46802,N,N,46805,46806,
+46804,N,46803,N,N,57667,N,57668,N,N,N,58613,48197,58612,N,48817,60607,49273,N,
+61934,50261,N,42083,42179,51542,N,42180,42181,42333,42334,N,42569,51825,52182,
+52183,N,43885,53486,45260,45259,55395,55394,N,N,42064,42182,42335,N,45261,
+51523,N,51564,42336,N,51650,42571,42570,51649,42840,N,N,N,N,N,N,44522,N,N,
+54383,N,46807,57669,47548,N,N,59642,N,N,62461,N,42183,N,N,52184,52724,45264,
+45262,45263,42065,N,42084,41677,42186,N,42185,42184,42339,42338,N,51565,51651,
+N,N,N,43253,43250,43252,43251,N,N,43886,N,N,46037,N,42066,N,42187,N,42341,
+42340,N,51826,N,N,43254,N,N,N,N,N,51543,N,42343,42342,42572,42573,51827,42841,
+N,42842,N,43255,43256,43257,N,43887,52725,N,N,44523,N,N,51524,N,42188,N,N,N,N,
+N,51652,N,N,N,51828,51829,N,N,52185,N,52186,N,52727,52726,52729,52728,43888,N,
+54384,44525,53487,44524,N,N,N,N,55396,46038,N,55397,N,N,N,N,57670,47549,N,N,N,
+N,48198,N,61935,N,N,N,N,51544,N,42344,N,N,N,N,N,N,N,45265,N,N,N,N,42067,42085,
+42190,42189,N,42191,N,N,N,N,N,N,43259,N,43258,43260,N,N,N,43889,N,N,N,44526,N,
+59643,49743,42086,42346,42361,42356,N,42351,42350,42357,42355,42348,42362,
+42349,42345,42360,42359,42358,42347,N,42354,N,N,42353,N,N,42363,42352,42579,N,
+42585,42581,N,42587,51653,42584,42574,42577,42580,42576,42583,42586,42575,
+42578,42582,42588,N,N,N,N,N,51838,51835,N,42855,51836,42843,42845,42869,42864,
+N,N,N,51877,51837,42847,42849,51876,42856,51832,42868,42870,42844,42861,N,
+51830,42867,N,42852,N,42862,42863,51831,42860,42858,N,42859,42865,51873,42846,
+N,42866,51875,42854,42851,N,51834,42850,51878,42853,N,42857,N,N,N,42848,51874,
+N,N,N,N,51833,N,N,N,N,N,N,N,N,N,N,N,52203,52202,43343,52205,52207,52196,52199,
+52206,43344,N,N,52193,52197,N,N,52201,52809,43339,52813,43261,52198,43262,
+43340,43333,43329,N,52194,43332,43337,43346,52195,52188,43331,52189,52191,N,
+43334,N,43336,52187,52192,N,N,43345,43341,52200,43347,N,43338,52190,43335,N,N,
+43330,43328,N,52204,N,43342,N,N,N,N,N,52808,52731,52811,N,N,52733,43896,43944,
+43892,43943,43901,43940,43890,52732,52803,43939,52815,43941,N,43897,N,N,52805,
+52802,43895,N,52730,43942,52810,43900,52812,43945,43891,43902,43899,52800,
+43937,52806,52807,43898,43938,43894,N,N,N,N,43893,52734,N,N,N,N,N,N,52804,N,N,
+N,N,N,N,N,52814,N,53572,44539,53489,N,53494,44532,44608,53492,44527,44537,
+44542,53499,N,44538,44541,N,N,53502,44533,53493,N,N,N,53570,53571,N,44535,
+53569,44531,44611,N,53496,44529,N,53574,53497,53501,44534,44610,53498,44540,
+53568,53575,54433,N,53573,44612,44528,53500,53491,N,44536,N,N,53490,N,N,53495,
+N,N,N,N,N,N,N,N,N,N,N,53488,44609,N,N,54391,N,45284,54439,45282,45279,54396,
+45275,54434,45286,54390,54395,54394,44530,45281,54437,N,54440,54387,N,46056,N,
+54441,45287,N,45273,45270,54398,45267,N,54438,N,45274,54442,N,54388,54436,
+45277,54389,54392,54397,N,N,45278,45276,45288,N,N,N,N,45283,N,45271,45522,N,
+45272,54393,45285,45280,54435,45269,N,N,N,45268,N,N,N,N,N,N,N,N,N,N,54385,
+54386,55402,N,N,N,46039,46042,55413,46062,55416,46040,55409,46046,46052,46525,
+N,N,46050,55406,46063,46043,46051,55414,56535,55419,55407,N,55398,55411,55405,
+46049,55417,N,N,46045,46065,46058,N,46047,46044,N,46055,N,55418,55404,55410,
+55412,55400,55415,46041,55399,N,46048,46064,46060,55401,46054,N,N,46061,46057,
+46053,N,55408,N,N,N,N,N,46059,N,N,N,56533,56529,N,56544,56522,56531,46821,
+46822,46814,56540,46824,56527,56526,56524,56542,46812,56536,56525,46815,56534,
+46810,56530,56537,56539,N,N,56543,46819,56523,46813,56528,N,46808,N,46820,
+56538,46816,46817,46823,46811,41567,46809,56532,N,N,N,N,N,46818,N,N,56541,N,N,
+N,47565,47560,N,57685,57681,N,57675,47554,47550,57684,47551,57678,57680,N,
+57683,N,47556,N,47563,47557,N,N,57673,47558,47559,57676,47564,N,57674,57679,
+47555,57672,47561,47553,N,N,N,47552,57677,57682,N,47562,N,N,N,N,N,N,N,57671,N,
+48205,58695,N,58692,N,48199,48211,48212,N,48202,58690,48204,58617,48210,N,
+58694,48201,58696,48200,N,58691,58693,48203,58689,58618,58615,N,N,55403,58621,
+N,58614,58620,58619,N,58616,N,48207,N,N,N,N,48206,N,N,N,48208,58622,48818,
+58688,N,N,N,59717,N,59645,N,48830,59714,48822,48826,59713,N,48825,48821,48824,
+48819,48829,59715,59646,48828,59644,48827,59716,59712,48209,N,48831,59718,
+48823,48820,N,N,N,N,60614,60616,49275,60617,60615,60613,60612,49277,60611,
+49278,N,N,N,N,60609,60610,49274,49313,49276,N,N,60608,N,49744,N,61372,61370,
+61375,61373,N,61371,61374,N,N,N,N,N,N,N,50016,61938,61939,50262,N,61940,61936,
+61941,61937,49745,N,N,N,62462,62529,50265,62528,50264,50263,N,N,N,N,50266,
+62917,62918,N,50394,50393,50395,62916,N,63192,63191,N,50541,50543,50542,63193,
+50632,63654,N,N,N,50673,N,63653,63726,N,N,51529,N,N,42365,42364,N,42591,42590,
+51655,42589,51654,N,N,42873,51881,N,51880,N,N,42871,42874,N,N,51879,N,42872,N,
+N,N,N,N,N,52208,N,52209,43348,N,N,N,N,43946,53576,53577,44613,44614,N,N,54444,
+45289,45291,54443,45290,55420,46066,N,N,N,N,46825,46826,56545,N,47567,N,47566,
+N,58697,59720,59719,N,63851,42087,51545,N,51566,51567,N,N,N,N,42594,42598,
+51657,N,42596,42595,51656,42597,42593,N,N,42592,51658,N,N,N,N,N,N,42918,N,N,
+42915,N,42877,51882,N,N,N,51883,N,42913,N,51885,42875,51886,51884,42878,42914,
+42917,42916,42876,51887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43353,52222,N,43355,N,
+43354,N,52288,43352,43351,52213,N,52212,N,52210,52215,52214,52211,52220,52221,
+52218,52216,43350,N,N,N,52219,43356,52289,N,N,52217,N,43947,43349,N,N,N,N,N,N,
+N,43948,52820,N,N,52826,N,N,N,43954,52824,52830,N,52821,52825,52827,52829,
+52823,N,52822,52817,52818,43949,N,43951,43950,52819,52828,N,N,N,N,N,N,N,N,
+43953,N,N,N,N,N,N,52816,53587,N,53586,53591,53582,N,53585,53584,N,53588,N,
+53592,44615,44618,N,N,53583,53589,N,N,N,44617,53578,N,43952,54458,53590,N,
+53581,N,44616,53580,N,N,N,N,N,N,54449,N,N,45292,45296,54465,54447,54461,45297,
+54463,N,54469,N,54473,N,N,54464,54452,54460,N,54474,54472,54462,54457,54450,
+55462,54448,45301,54455,45302,45298,54445,54467,54453,54451,54470,45299,N,
+54476,45293,45295,54459,54454,44619,45294,54456,54471,54475,54466,N,54468,N,N,
+N,54446,N,N,N,N,55457,N,55466,55465,46074,55458,N,46075,46073,N,55460,46070,
+55464,N,55459,55461,55421,46068,N,55474,55473,55470,46067,46071,46072,53579,
+55467,46069,45300,55469,55422,55472,55471,N,55475,N,56559,N,55468,N,N,N,N,N,N,
+N,N,55463,56551,46836,46839,46834,56550,56554,56549,N,46828,46838,56546,46832,
+56553,N,46830,46829,56556,46831,56558,N,56555,46827,N,N,N,46837,56560,56548,
+56557,N,N,56547,N,N,46833,N,46835,N,56552,N,56561,N,N,57693,47568,57699,N,N,
+47573,57695,57702,57687,47575,47569,57692,48213,57691,57700,47570,N,47574,
+57690,57696,57701,57686,47572,57694,N,N,57698,57704,57688,57697,N,47571,57703,
+N,N,N,57689,N,N,N,48217,58699,48215,48214,58701,58706,N,58702,N,58705,48220,N,
+48805,48219,N,58698,58704,N,48218,58703,N,58700,N,48216,N,N,N,N,N,N,59725,N,
+59727,59722,48833,59724,N,48832,59726,N,N,48835,59728,48834,59721,59723,N,N,N,
+N,49317,60620,N,49316,60621,49315,60619,49314,60618,N,49747,49746,61942,61944,
+N,61943,50017,50018,N,N,50019,62530,50267,N,N,63443,63442,50674,N,42088,42192,
+N,N,42919,N,N,N,N,52831,N,N,N,N,46076,46077,N,56562,47576,57705,58707,51546,N,
+N,51888,N,N,N,N,N,52290,52832,53593,44620,N,N,61945,N,50396,42089,42366,51568,
+N,42599,42600,N,43357,N,N,N,45303,N,47578,N,47579,47577,N,42090,N,42193,42195,
+42194,51547,42196,42401,51569,N,42402,N,N,N,N,N,42601,42602,N,N,N,51659,N,
+42920,N,51889,N,N,N,43361,52291,N,43359,43360,43358,53594,N,N,N,43958,43957,
+43959,43956,N,52833,43362,43955,N,44621,44622,N,44623,N,54477,N,N,N,46078,
+55476,45304,N,N,N,N,46840,N,47581,47580,57706,N,48221,48836,N,61376,63194,
+63444,42091,42403,N,42404,51665,42604,42607,N,51663,51661,42606,51664,51666,
+51660,42609,42608,42605,42603,51662,N,N,N,N,42931,N,N,42928,51894,51897,51896,
+N,42922,42930,N,N,42927,51893,51891,42926,N,N,N,42921,42924,N,51892,51899,
+51895,42925,42929,42932,51890,51898,42923,N,N,N,N,N,43367,43375,N,52303,52296,
+43376,52307,52292,52299,N,N,43366,52293,43364,52300,52304,43363,N,52305,52298,
+N,52301,N,43378,43369,52308,52306,N,43374,43372,52297,43371,52295,52294,43370,
+43368,43377,43373,43365,N,52302,N,43961,N,43968,52847,43960,52839,52835,N,
+52851,52834,N,43963,52844,43966,43969,N,43964,52848,43967,N,44630,52854,52836,
+N,N,52838,52845,52849,52853,52850,52843,52846,N,N,52840,43971,52842,52841,
+52852,43962,52837,43970,N,43965,N,N,N,N,N,44636,53602,N,44635,N,N,53600,N,
+44624,N,44629,N,53599,53596,53601,44625,53595,N,44628,44626,N,53603,44627,
+44631,N,N,44632,N,44634,N,N,N,44633,N,N,N,53597,53598,N,N,N,N,53604,N,54484,
+45305,55490,54483,54502,N,N,45376,N,54500,N,45310,45306,54509,54493,54496,N,
+45379,54506,54498,45307,45380,N,54503,54501,N,N,54486,54507,54495,54490,N,
+54480,54508,54492,54479,N,45378,54497,54510,54494,54482,54487,54478,N,45377,N,
+54491,54488,45308,54481,N,54505,45309,N,54489,54485,N,N,54504,N,N,N,N,N,N,
+46144,55483,N,55480,55497,55485,55498,N,46146,N,N,N,55494,55491,N,N,N,N,N,
+55492,55495,55499,N,54499,55501,56647,N,46147,55502,55478,55488,N,55493,N,N,
+46145,46148,55500,55503,55482,55479,N,N,55481,N,N,55486,55484,46149,N,55496,N,
+N,55487,N,55489,55477,56570,56568,46914,46912,56643,56569,56644,56640,56567,
+56646,56566,56573,46846,46845,46844,56571,56641,46841,46913,N,56564,N,56574,
+56563,56572,46842,56642,56565,46843,56645,N,N,N,N,N,N,N,57710,47586,47585,
+47587,57722,57712,57718,57707,57721,57720,57724,57717,47582,57716,47588,N,
+57709,47583,N,57723,47584,57711,57714,57719,57713,57708,N,N,N,N,57715,58709,
+48225,58712,58711,58714,58716,N,48223,N,58710,N,58708,58717,58715,58713,N,
+58719,N,58718,48227,48222,N,48224,48226,N,N,58720,59735,N,N,59734,59733,N,
+59736,59729,N,59730,59738,59731,N,48837,59740,N,59739,59732,N,60625,49320,
+60623,60628,60627,59737,N,49319,N,60626,60622,60630,60629,49318,N,60624,N,
+48838,N,N,N,49748,N,N,N,61377,61946,61947,61948,50268,N,N,50269,N,62531,N,
+62920,62919,N,N,63195,63196,63445,63655,N,42092,42093,N,42094,42197,42405,
+51667,42610,42611,N,42935,42936,42934,42933,N,43379,N,N,52309,43381,43380,
+52310,N,N,N,43972,N,44637,53605,N,54512,N,45381,46151,54511,46150,N,47589,N,
+57725,48839,N,49321,60631,N,50270,N,50544,N,51570,N,42406,51571,42614,N,42612,
+42613,42615,N,42938,42937,N,51900,42939,N,N,51901,52311,N,52312,N,43382,43384,
+43386,43383,43387,43385,N,N,N,N,N,43976,43973,43975,43977,43974,53606,52855,N,
+N,N,53608,53607,44643,N,44639,N,N,44640,44642,44644,44641,N,44646,44645,N,N,N,
+N,N,45386,54514,54513,45385,N,45384,45383,45387,45382,N,N,55509,55506,46153,
+55505,55510,N,46155,55508,46152,46154,55507,N,56648,N,56649,56650,N,N,N,N,
+47590,47598,57726,47592,47596,57761,47597,47593,47594,47591,47595,48230,55504,
+48231,48229,N,48228,59741,48840,60632,60633,N,N,50020,50271,N,42095,N,42616,
+43978,N,53609,44647,N,N,45390,45389,45388,46156,46157,55511,47599,48841,42096,
+51548,42198,51572,N,N,51668,42617,N,N,N,43388,N,N,N,N,56651,N,N,42097,N,42199,
+51669,N,N,51902,N,51903,N,42940,N,N,N,55512,46158,N,56652,N,N,N,49322,42098,
+42152,42200,51573,42407,N,42944,42943,42941,42942,N,N,52313,43390,43425,52314,
+43389,N,N,43982,52856,43981,43979,43980,44650,44648,N,N,53611,44649,53610,N,
+44638,54515,N,N,45392,45393,N,N,45391,N,47600,57762,48232,48233,N,58721,49323,
+61378,61379,N,50397,63656,51531,42201,N,42099,N,51575,51574,N,N,N,N,42618,
+51671,51672,51670,N,51673,N,N,N,N,N,N,N,51911,N,51906,51908,51910,51907,42948,
+51904,N,51905,42945,42946,51909,51912,42947,51913,N,N,N,N,N,N,N,52328,N,52322,
+52317,43427,52325,52323,52316,52329,52332,52327,52320,43429,52326,43430,52321,
+52324,52315,52319,52331,43431,N,43432,N,52318,52330,43426,43428,N,N,N,N,N,N,N,
+N,N,N,N,N,N,52907,52900,52906,52899,52901,52861,52859,N,52908,52905,52857,N,
+43984,52903,52904,N,52902,52860,52858,43983,52898,52862,N,N,52897,52909,N,N,N,
+N,N,N,N,N,44655,N,44654,N,53612,44651,53614,N,44656,53615,N,N,44659,N,44657,
+53616,52910,53618,N,44653,N,44652,N,53613,53617,44658,N,N,N,N,45395,45394,N,N,
+N,54517,54521,54523,45396,54526,N,45400,54593,N,45402,N,45398,45406,N,45403,
+54519,45397,N,54518,54516,54595,54520,N,45399,54594,45404,54525,54524,45405,
+54522,45401,N,N,N,N,54596,N,54592,55527,55534,55523,46161,55519,55535,55513,
+55532,55530,55524,N,55533,55526,N,55518,55536,55516,55529,55514,N,55537,N,
+46162,N,55531,56655,55517,46159,N,55521,N,46160,55520,55525,N,N,55522,N,N,N,
+55528,N,N,N,N,56659,N,N,N,56662,56654,N,56656,N,56661,56660,46915,N,55515,
+56658,N,N,46916,N,56653,56657,N,N,N,N,57769,N,57776,57767,N,57774,57765,57773,
+57777,57764,57768,57763,N,47601,N,57766,47602,57772,57771,57770,N,N,57775,N,N,
+N,N,58725,58727,48235,58728,N,58723,N,58722,58732,N,58730,48234,58733,58724,
+58729,58731,58726,N,N,N,N,59745,59750,59744,59749,N,59742,59752,59748,59753,
+59747,59743,59751,N,59754,59746,N,60634,49327,N,49325,N,49324,49326,N,N,61380,
+N,61810,61949,N,N,62532,62533,N,50272,N,62921,N,50398,N,62922,N,63198,50546,N,
+50545,63197,50633,N,63446,N,N,N,N,42100,42619,51674,51914,43189,45407,N,N,
+42101,42410,42409,42408,N,N,42949,N,N,44660,N,56663,42102,42103,42104,42202,N,
+N,43985,N,52911,N,N,N,46163,42105,51549,42411,42412,51576,N,42620,N,N,N,51915,
+N,42950,N,51916,N,N,43438,N,N,52334,43436,43435,52333,43433,52335,43434,43437,
+N,43986,N,43988,52915,52912,52913,52914,52916,43987,N,N,53620,53619,N,44662,N,
+44661,N,N,N,N,N,45410,54598,N,45409,45411,45408,N,N,N,N,46165,54597,N,46166,
+55539,N,46167,55538,46164,N,N,N,N,56666,56668,46917,56667,56665,56664,N,N,N,
+57780,47607,47605,N,47606,57778,57779,N,47603,58737,58735,N,48237,58736,48238,
+48236,47604,N,N,59757,59755,59756,58734,60636,49328,60635,61381,61382,59758,
+61950,N,42106,42413,42622,51675,42621,N,43439,46918,N,42203,42414,43989,46168,
+N,51577,N,51578,N,51676,N,N,42952,51920,51918,42953,51917,51919,51921,N,42951,
+N,N,N,N,N,43443,43444,43441,N,N,43440,52920,43442,N,N,N,43990,N,52919,52921,
+52918,52922,43991,44665,53621,N,53623,44663,53624,44664,53622,N,52917,54599,
+54602,54603,54600,45415,45414,45412,45413,54601,N,N,N,N,45416,N,N,46170,46171,
+N,46172,56669,56671,56673,46920,46919,46169,56672,56670,N,57784,N,N,57782,
+57788,47608,57789,57786,47609,57783,57781,57787,48240,58739,57785,48242,58740,
+48241,48244,58741,48239,48243,N,59763,59761,59760,59762,59759,N,N,50022,N,
+62534,62535,N,62923,63199,50773,N,N,43445,42954,N,N,43992,N,N,N,42107,42204,
+42415,51677,N,42955,51922,N,52923,43993,N,47610,42108,N,N,N,42657,N,N,46921,
+42109,42205,42206,N,42417,42416,N,51678,42658,N,51923,N,42956,N,N,52337,52338,
+52339,N,43446,43447,52336,43448,N,N,N,43994,52924,N,53626,44666,N,53625,N,
+45417,54604,45418,54605,N,N,N,46173,N,N,N,56674,N,N,57791,57790,N,47611,N,
+48245,58742,48842,59764,49329,N,50547,63448,N,N,N,N,52340,N,52925,45419,55540,
+46922,N,N,N,49749,N,N,N,N,42958,N,42957,43995,N,53627,N,45421,45891,45422,
+45420,46174,N,57792,47612,48246,N,51532,51679,N,51925,42959,51924,42960,N,N,
+43452,52343,52342,43451,43449,43450,52341,N,N,43997,52926,44000,43996,44002,
+43998,43999,44001,N,N,N,44669,44668,44667,N,N,N,54607,45423,45426,45424,N,
+54606,45429,N,45425,54608,45428,45427,N,N,N,55542,55541,N,46177,46175,46176,
+55543,46923,56676,46924,56675,N,N,58743,N,N,48248,57793,48247,N,47613,N,60638,
+59765,49330,60637,62016,62536,62537,N,42207,N,42418,N,N,N,51579,N,N,42962,
+42964,N,51682,51928,51927,51926,N,51681,51680,42660,42963,42961,42659,N,N,N,
+43453,52344,N,43454,51933,N,51935,51934,52345,N,N,51930,N,42968,42966,N,51929,
+51931,51937,N,42965,N,51932,51941,43456,N,51938,42967,N,51936,51939,N,43455,N,
+43457,51940,N,N,N,N,N,N,N,N,52399,52386,52350,52398,52393,44007,43458,52394,
+52397,44003,52396,43459,43464,43462,52387,N,52348,52389,43469,52400,44004,
+52390,N,44005,43465,52392,N,52941,44006,52347,43466,44008,43467,43463,43468,
+52391,52346,52395,43460,N,N,52349,52388,52385,43461,N,52927,N,52928,N,N,N,N,N,
+N,52938,53665,52939,44014,52942,52932,44013,52934,N,52935,N,N,52937,44009,N,N,
+44707,N,N,52933,52929,44708,N,N,52943,44670,53629,52936,N,53628,52931,52940,N,
+N,44012,44705,44018,44706,52944,53630,44011,44710,44017,44016,44015,44709,
+52945,44711,44010,N,52930,N,N,N,N,N,N,N,N,N,N,N,N,45430,53668,53670,N,53672,
+44712,44718,54611,53676,53667,45432,54609,N,44717,44715,53678,N,54610,N,53669,
+N,44716,53673,44719,53675,N,N,44714,53674,53677,53671,N,44713,45433,N,53666,
+45431,N,N,N,N,45434,N,N,N,N,N,N,N,54613,54622,46180,N,45436,45475,46181,54624,
+45482,55545,54614,45474,45477,45438,54612,54626,54629,55625,N,54627,55549,
+45473,45480,45484,54621,55544,54625,45435,55546,54628,55548,54617,N,46178,N,
+54615,54616,45479,N,N,45478,54619,45483,54623,45476,54620,N,45481,46182,46179,
+55547,N,54618,N,45437,N,N,N,N,N,N,N,N,N,46187,46191,55616,46929,46189,55620,
+46193,56677,55622,46931,46185,46188,55623,N,55624,55630,46195,46932,N,55626,
+55631,55619,46942,N,46933,46194,55617,55632,N,46941,46192,46926,55629,N,46196,
+55621,55550,46186,55618,N,55627,N,46925,46930,46183,55628,N,46928,N,N,N,46184,
+N,N,N,46940,57795,56688,N,56680,57794,N,56684,56686,N,N,56683,N,46939,N,56682,
+46943,N,N,N,57810,N,N,46938,47680,56689,57796,N,N,46936,56681,56685,47614,
+46927,56678,56679,47681,46935,46937,46934,56687,N,N,57800,57801,57806,48253,
+57813,N,47687,N,47686,57808,N,48252,57797,47685,N,57812,47683,47684,N,57809,
+58794,48250,46190,N,57811,48291,57803,N,48251,N,48290,57798,57802,57799,57805,
+47688,48249,47682,N,58746,57807,N,48289,N,48292,N,57804,N,48254,58745,N,N,N,N,
+N,58750,48846,58744,59811,58793,48296,N,48294,48844,58790,58786,48300,N,59768,
+N,N,N,48298,58785,N,59766,N,58789,N,58792,58749,N,48299,N,N,48293,59767,48845,
+58791,48295,48297,58788,48301,58787,58748,58747,48843,58795,59770,60640,48848,
+N,59810,N,59774,N,60641,N,48849,59809,N,59772,49332,60639,N,59769,59771,49333,
+48851,49331,48850,49335,59773,48847,N,N,N,N,N,N,N,N,61391,N,61383,N,N,N,N,N,
+60647,61384,60643,N,N,49750,60645,60644,49334,60642,60646,61392,61388,61390,N,
+61385,61386,N,61389,61387,50023,N,N,50026,50025,50024,50273,62538,50274,62017,
+50399,62924,50400,50548,50634,63449,N,63450,63451,N,N,63930,42208,51580,42419,
+N,42662,42663,42661,N,42664,42970,42969,N,52401,43471,43470,N,N,53679,45485,
+45486,N,N,N,46197,56690,46944,46945,56692,56694,56693,N,57815,N,57814,47689,
+57816,N,58796,48302,N,48852,N,49336,49751,49337,N,42209,N,N,N,51942,N,N,52402,
+43473,43472,43474,44019,52946,52947,N,N,53680,44720,45487,46198,55633,42210,N,
+42110,42211,N,51581,42423,42422,42420,42421,N,N,N,42667,51689,51691,42666,
+51683,N,51684,N,51690,51686,51688,42665,51685,51692,51687,N,N,N,N,N,N,42977,
+42986,42984,51952,51949,51957,42982,51958,N,42975,51955,N,42981,51951,51950,
+42979,51956,42980,43475,42974,51953,N,51943,42971,N,42990,51948,51954,42976,
+42978,N,51944,N,51945,51946,N,42989,42983,42988,51947,42987,42973,42972,42985,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43489,52414,52407,43484,43503,52403,52410,52412,
+52415,43498,N,52411,52404,43496,52408,N,52416,43481,N,52413,43491,43490,52406,
+43479,N,N,43480,N,43478,N,43502,43494,43488,43476,52409,43487,43477,43495,
+43504,52948,43492,52405,43482,43485,43486,N,43500,43501,43499,43493,43497,
+43483,44020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,52954,44097,44024,44026,44096,52966,
+44029,53681,44721,44099,52951,52959,44030,52958,52955,52963,52965,44023,44027,
+44098,44723,52960,44025,44101,52953,N,N,N,44028,44722,44022,N,52950,52957,
+52949,52952,52956,53682,44100,N,52961,52962,52964,44021,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44737,53694,44735,44736,53684,53700,N,44726,N,N,54630,53702,53696,
+N,53687,N,53705,53690,44732,54653,53693,44734,44725,N,53707,53695,44728,53688,
+53685,53686,44729,53701,53708,44731,53692,53691,44739,44738,44724,44730,44733,
+53704,N,N,53698,44727,53683,53706,53697,53699,53703,N,N,N,N,N,N,N,N,N,N,54631,
+N,45495,45515,45514,N,45503,N,54649,54645,54642,54694,45498,45490,N,N,54647,
+46248,45494,54689,N,45516,45513,54651,54634,N,N,45512,54691,54633,45501,45505,
+54690,N,54643,45506,45500,54632,N,46200,54693,54641,45511,54644,54692,45510,N,
+55634,N,45491,54639,45496,45507,N,45502,54648,54638,54636,54654,45488,45508,
+45492,46199,54652,45493,N,45489,45504,45499,45497,54640,45509,54637,54650,
+54646,55636,55635,N,N,N,N,N,N,N,N,N,N,N,54635,55652,N,46202,N,55658,55641,
+55655,56695,46205,55659,55662,46204,55644,55661,55660,46206,55637,46201,46243,
+N,46241,55657,N,55647,46245,55664,55656,55665,46253,46251,55654,55653,N,55651,
+55645,46244,N,46242,53689,55638,N,56759,55639,46203,46250,56697,N,46246,46247,
+55640,55663,56696,55648,55643,46249,55649,55646,N,N,46254,46960,N,N,56700,
+56753,56758,56746,46956,56763,46953,56698,N,56699,46946,46955,56740,46958,
+46959,56741,N,56754,56760,46954,N,46948,56739,56701,56762,56744,56745,56702,
+56756,56747,56757,56749,N,46949,57817,46952,46950,56761,56752,56748,N,N,56737,
+47699,56751,46957,56743,N,56742,N,N,N,46951,46947,57838,56755,56750,N,56738,N,
+N,N,N,N,N,N,57833,N,57818,57829,N,57836,47697,46252,57834,47692,N,N,N,47691,
+57841,N,57819,57832,57820,57831,47695,57835,55650,N,N,N,57842,57827,47698,
+58810,48303,N,57840,57839,47700,58797,48304,58798,N,57823,57824,57821,57826,
+57822,57843,47694,48305,47696,47701,N,57825,N,57837,N,N,57830,N,N,58801,N,
+47690,48308,59818,58806,58805,58807,N,N,58804,48309,N,48315,48312,N,48313,
+58799,58802,58812,48321,48319,N,58803,55642,48306,58809,58800,N,48322,58808,
+47693,48311,57828,N,N,48314,N,48318,48320,48317,48316,N,48310,58811,48307,
+48323,N,N,N,N,N,N,N,48856,48857,59817,48866,48863,N,48854,48861,59819,48859,
+48853,N,48860,N,59816,49339,48855,N,48862,49338,59815,59814,N,48864,N,48865,N,
+59813,59812,49340,59822,48858,59820,N,N,N,N,49341,N,49346,60650,60652,N,49343,
+N,60653,60649,N,60651,49344,49347,N,60648,49342,49345,49753,59821,49752,N,N,
+49758,61396,N,49756,49757,61399,61395,49754,61393,50027,61397,N,61398,61394,N,
+49755,62018,N,62021,N,N,62022,62020,62023,50028,62019,N,N,62542,50276,62541,
+62540,62539,50275,50277,N,62925,50402,50401,N,N,63201,63200,63203,50635,50549,
+63453,63202,N,N,63452,50637,50636,50675,63657,63727,42212,N,N,55666,59823,N,N,
+42668,51959,42993,42991,N,42992,N,52417,43505,44102,N,52967,N,52968,N,44103,
+53710,N,44740,44741,53709,N,N,N,N,45523,N,45519,N,54695,45526,45525,45518,
+45521,45524,45520,N,N,55670,45517,46255,N,N,N,46257,46258,55669,55672,46256,
+55667,55671,N,55668,N,46961,N,N,56764,N,N,47702,57844,48867,48324,58813,48325,
+48326,58815,58814,58816,59825,N,N,59824,60655,60654,49348,49349,62024,N,N,
+42213,N,N,N,N,55673,N,N,N,46260,46259,56765,N,61400,50403,63454,42214,N,44742,
+N,45528,45527,55674,55675,46962,57845,47703,59826,N,42215,42424,N,43506,52418,
+N,52969,44104,45529,N,55676,46261,46963,N,58817,58818,N,N,60656,49759,63728,
+42216,N,52419,43507,44105,N,52970,N,44743,53714,53712,53713,44744,53711,N,N,N,
+N,45531,45532,54696,45533,45530,55677,N,55678,56766,N,N,47705,47704,N,N,60657,
+61401,N,62026,62025,62543,N,51550,44106,N,N,42217,42425,N,42670,42669,N,N,
+42671,42672,51694,51693,51960,42994,51963,51962,51961,51964,N,N,N,N,43508,
+52425,52421,52430,43515,N,43513,52426,52422,52429,43512,43584,52424,52420,
+43518,52427,43511,52428,43514,43516,52432,52431,52423,43510,43509,43517,N,N,N,
+N,N,N,52975,52981,N,44112,44109,52972,52977,N,44115,44107,52976,44110,44113,N,
+N,52979,N,44108,52984,44111,N,44114,52973,52978,52982,52974,52971,N,N,52983,
+52980,N,N,N,N,N,N,44752,44745,44748,N,44751,N,53717,N,44746,53715,N,44750,N,N,
+44747,N,53718,44749,N,N,N,N,N,N,54700,45535,54699,54701,45534,45539,53716,N,
+54698,54702,N,45536,54697,45538,N,45537,N,55719,N,55714,N,46262,46266,46263,
+55717,55720,N,46264,N,46265,46270,56775,55718,46268,55715,55713,N,46269,N,
+55716,N,N,N,46969,N,56767,46966,46967,46965,56772,56771,56768,46971,N,N,56770,
+46267,N,N,56774,56769,46968,46964,46970,56773,N,N,N,47708,N,57848,57847,57846,
+47706,N,N,N,N,N,47707,58821,58824,48328,N,N,48327,58825,58820,48330,58822,N,
+48329,58819,N,58823,48873,48870,59835,59834,N,59833,59828,N,59829,N,N,N,48871,
+N,48868,48872,59827,48869,59830,59831,59836,N,N,59832,N,N,60658,N,N,N,49351,N,
+61404,49350,61402,61403,49760,50030,62027,N,50029,N,N,62545,62546,N,50278,N,
+62544,50404,N,63455,50638,63658,63659,N,42218,N,42673,42674,42995,N,52433,
+44116,44753,45540,N,N,45266,N,46271,46272,46028,55721,N,46972,57850,57849,N,N,
+42219,42675,52434,43586,N,43585,N,52985,52986,N,53719,53720,44754,44755,N,
+44756,54703,N,N,45542,N,46274,N,46273,56776,57210,57851,59837,N,N,49761,50279,
+42220,N,42428,42429,42427,42430,42426,N,N,42678,N,51702,42677,42679,N,N,51697,
+51696,51699,51698,51701,42676,51695,51700,N,N,N,N,N,51965,43005,51966,52035,
+43004,N,52039,52034,52037,42997,42998,42999,43000,N,43072,N,52033,43002,43073,
+N,52032,52038,N,43001,52036,43003,42996,43006,N,N,N,N,N,N,N,N,N,43607,N,52436,
+43587,N,43597,43598,43590,43608,43592,52444,43603,52439,43593,52454,52455,
+52447,52440,43606,52452,43601,43599,N,52453,N,52451,52443,52435,52442,43594,N,
+43600,N,43588,52446,52445,52437,N,43602,52449,52438,43605,52456,43589,N,43596,
+52441,52450,43604,N,43591,43595,N,52448,N,N,N,N,N,N,N,N,N,N,N,N,N,N,53083,
+44124,44137,N,53078,53068,44130,53066,44123,53061,44133,53074,52990,53057,N,N,
+N,N,53060,52987,53073,53089,44128,53062,53080,N,52989,53087,53088,53091,53082,
+53067,53075,44134,44121,44129,44141,44118,44120,N,N,N,53059,44138,44131,53085,
+53056,44140,44135,53065,N,N,44139,53072,53064,44132,53084,53076,N,44126,53090,
+53063,44122,53081,53071,44127,53077,44119,52988,44136,44771,44125,53070,53069,
+53058,N,53086,N,53079,N,N,44117,53740,44778,53741,N,53729,44767,44779,N,53722,
+N,53731,53739,N,53721,53748,44757,N,N,N,53747,53742,N,53743,44765,44776,53733,
+N,53734,53744,53735,N,53730,53724,53725,53738,53732,N,N,44758,44762,53746,
+53726,44774,44770,N,N,44773,44780,44763,44775,53737,44777,44760,N,44759,53723,
+N,53727,44768,53745,53736,53728,44772,44769,N,44761,44764,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,54724,N,54708,54709,54713,N,54728,54725,N,54718,54717,
+45549,54721,54736,54704,N,54737,54723,54741,54729,45548,54727,45543,45564,
+45554,N,45558,45557,54705,N,54734,54740,54732,54739,N,N,54720,54706,54738,
+54722,45546,45559,N,54731,45552,N,N,N,54730,54707,45560,N,45562,54733,45563,
+45545,54714,54735,N,N,45551,45561,54716,54726,54711,54715,45556,54710,45544,
+45553,45550,54719,44766,55744,45547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45555,N,55747,
+55769,55758,46294,N,46289,55741,46290,55757,N,55750,55763,46286,55723,55765,
+46276,55731,46279,46278,N,46295,N,55725,55759,55760,46281,46277,55739,N,46288,
+55734,N,55761,46284,55753,55766,55728,55733,55727,N,46283,55746,56798,55729,
+46287,55738,55762,46282,55735,55732,55749,46285,46275,46297,55752,55751,55724,
+46280,55764,55740,55742,N,55755,55754,55722,46291,46293,55730,55737,55745,
+46292,55736,55748,55767,N,55756,N,N,N,N,N,N,N,N,N,N,N,N,N,55768,N,N,N,N,55726,
+N,N,N,N,56818,47014,N,56816,56795,56800,56793,N,56812,56779,56786,N,56810,
+56820,56796,N,56783,56802,56807,56787,N,56804,56784,N,N,56791,56792,47016,
+56811,56809,N,56780,56814,N,56815,56817,47020,47012,N,54712,56788,56806,56789,
+47009,47025,56813,47023,47019,56778,47011,N,56781,47024,N,56797,56777,N,47017,
+56801,56785,47018,56794,46974,46296,56803,55743,56782,N,N,56808,47013,56805,
+47010,56799,47021,56790,56819,N,N,N,N,N,N,47015,57030,N,N,47022,N,N,N,N,N,N,
+57930,57928,N,57950,57926,N,57944,46973,47711,57922,57949,N,57927,57941,47716,
+47709,N,57947,N,57920,57946,N,47727,57937,57953,47725,57929,47710,57931,57945,
+47719,57924,47723,47713,57933,57923,57852,N,57943,47720,57952,57853,47717,N,
+57939,N,47718,57925,57936,57932,57934,N,47712,57951,47726,57935,N,57954,N,N,
+57854,57940,47715,47724,47722,57921,57942,47721,N,N,47714,57938,N,N,N,N,57948,
+N,N,N,N,N,N,N,N,58837,N,58833,58829,58849,58846,48333,N,N,58853,58836,48344,
+58843,N,N,58832,58842,48341,58862,N,58859,58845,58830,N,N,58850,58852,48337,
+58840,58835,58826,48334,48342,N,58855,48343,58827,58861,58848,58854,48340,N,N,
+58851,N,58858,N,48345,N,48339,58844,58831,58863,58828,58856,48336,N,58838,N,
+58839,48335,48332,58834,48338,N,48331,N,58857,58860,58841,59850,N,N,N,N,N,N,N,
+N,N,59842,N,59838,48886,N,N,48875,48880,48876,59852,59863,48874,59844,59853,
+58847,59854,N,N,48881,N,59869,48885,48888,59840,N,48884,N,59867,59868,59858,
+59857,59849,N,N,59859,59866,59865,N,48879,48877,59851,59848,N,59845,59864,
+48887,59862,48883,48882,N,59856,N,59839,59841,59843,59861,59855,48878,N,59846,
+N,59860,N,N,N,N,N,N,59847,N,N,N,N,N,N,N,49359,60741,49352,60661,N,60737,49354,
+60744,N,60668,N,60663,N,N,60745,60659,60670,N,49361,60740,60746,60669,49353,
+60736,60660,49360,N,N,60743,60665,49356,N,60667,60664,49362,60666,49355,49358,
+60739,60662,60742,N,60738,N,N,N,49763,61415,49768,49769,N,N,N,49762,61414,N,
+61411,61412,49766,61406,61410,49765,N,61407,N,N,N,N,49767,49764,N,61405,61409,
+61413,N,N,N,62033,62030,62039,N,62038,62036,62031,N,50034,N,N,N,N,N,62032,
+50033,49357,62035,50032,62040,62034,62029,61408,N,N,N,50031,N,62028,62550,N,
+62549,62037,50280,N,62553,62554,62548,62552,N,62547,N,N,N,N,62929,62551,50407,
+50405,62927,62930,N,62926,62928,50406,N,N,N,63205,63206,50550,63204,N,N,N,
+63458,50639,63456,63457,63660,N,N,50774,63731,63729,63730,63732,N,N,N,63931,N,
+42221,42680,N,43609,N,52457,N,N,53092,N,N,N,53749,53751,N,53750,N,53752,45565,
+54743,53753,N,54742,54744,54745,55770,46299,55771,55773,46300,46298,55772,N,
+56826,56824,56823,N,56822,56821,47026,56825,47728,57955,57957,47729,57956,
+48347,N,48346,58864,N,N,59871,59870,59872,N,N,48889,N,60747,49363,N,61416,
+49770,62041,50551,42222,42431,42681,43074,43610,43611,N,N,44142,N,N,53754,N,N,
+N,N,47027,N,N,N,59089,48890,49771,42223,N,42682,N,N,52459,43612,52458,N,53093,
+44143,53094,N,44144,N,53756,44782,44781,N,54750,54748,54749,54747,N,54746,N,N,
+55774,55777,46302,55775,46301,55776,N,56827,N,N,57958,57959,57960,N,58867,
+58866,48348,58865,58868,59873,N,N,59874,59875,N,60748,49364,49772,62042,N,
+50408,51551,N,44145,53095,44783,N,N,45566,N,46303,55778,N,47029,47028,N,N,
+57961,57962,48349,48350,59877,59876,61417,63459,42224,51552,42432,N,43075,
+52040,N,44146,47030,42225,N,53096,44147,53097,N,49365,42226,N,N,52460,N,53098,
+N,53826,53825,53758,N,53757,53827,53824,N,N,45632,45633,N,N,46304,55779,N,
+55780,55781,N,N,N,56897,56898,56896,N,56829,56830,47031,57963,58871,58870,
+58869,58872,59879,59878,48891,59880,N,49366,60749,N,61418,62043,63207,N,42227,
+42434,42433,N,43613,51553,51582,42683,N,51703,52041,52042,43614,N,52461,N,
+44148,53099,53100,N,44784,44788,53828,44787,44785,44786,N,54751,45634,46307,N,
+46305,46306,55782,N,N,47730,42228,N,51617,N,42435,N,N,51620,N,N,42438,51619,
+42437,42436,43076,51618,N,N,51704,N,N,N,51708,51710,51776,42693,42694,51707,
+42689,N,51705,N,51709,42690,N,42685,N,42686,N,42692,51706,42684,43077,42687,
+42688,42691,N,N,N,52059,52057,52044,43089,52051,43084,52045,N,52053,N,52050,
+43087,52049,43094,52058,43096,N,43098,N,52043,N,43085,52060,N,43092,43095,N,
+52549,43079,43102,43093,52046,43082,43097,52054,43080,43081,52547,52047,43088,
+43099,52061,52048,43086,N,43091,52462,43100,52055,43090,N,43101,43078,52052,
+43083,52056,52548,N,N,N,N,N,N,N,N,N,N,N,N,N,43626,43642,52469,43633,N,52555,
+43618,N,43621,52546,N,52467,52471,43629,43631,52474,43638,43624,43622,43623,
+43637,52551,43632,52473,52475,43630,43635,52476,52554,N,44149,43641,N,43619,
+52553,N,52557,52472,52559,52544,43628,52468,43627,43645,43634,N,52466,53109,
+43640,43644,52545,52550,N,43646,43639,43625,43615,N,43620,N,52470,43616,52558,
+N,52464,52463,52477,52465,43643,44789,43636,52478,43617,N,44198,N,N,N,52556,
+53116,53153,N,53156,53111,N,N,53159,53162,53164,53108,44150,44155,53833,44205,
+53157,53165,53115,53107,N,N,N,53860,44158,53154,53112,53114,44197,N,53117,
+44157,53104,53160,N,53163,N,N,44154,N,44200,53101,44202,44152,44206,53161,
+53103,44203,53854,52552,44156,44151,53110,53102,44204,44196,53155,44201,44199,
+53113,44193,53105,44194,44195,53106,53158,44153,53118,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,53836,44797,44867,N,N,N,53845,53851,53847,53834,53837,53830,
+53831,44874,44794,53846,53855,44869,44790,N,44864,53838,44866,53839,53849,N,N,
+N,44868,53864,53832,44796,44795,44872,53829,53862,53850,53863,53857,53843,
+53858,N,53852,53861,53859,44873,53844,44793,44792,44865,44871,53856,44870,
+53841,45635,N,53865,53840,53835,44798,44875,44791,N,53848,53853,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,45669,54753,54757,N,45650,45648,N,N,45639,54755,54754,
+45659,N,54760,45653,N,54778,54855,45636,54775,54768,45671,54752,N,54780,N,
+45668,45656,45667,45646,54764,54782,54774,45647,45641,54853,N,54781,54848,
+45649,45657,54850,54762,54779,54767,54852,45662,45638,45660,54772,54770,54771,
+45651,54766,54765,45640,54759,54854,45642,54769,45672,N,45666,54758,45663,
+45661,45670,54776,45665,53842,54777,45664,54849,45637,54773,45655,54761,45654,
+N,45652,45644,45643,55783,54851,54763,N,N,55804,N,45645,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,46401,45658,46318,55798,46332,N,55786,46315,46311,55881,46317,
+46321,46316,46325,55885,55876,N,N,55793,46330,46324,55805,46308,55882,55875,
+46312,55799,46327,55893,55894,N,46309,55880,46329,55803,55789,55790,46333,
+55794,55801,55795,N,46331,46404,55791,55784,55785,N,55787,46314,55800,N,46328,
+46402,N,N,55802,55891,55883,46310,55889,46322,N,46320,N,55895,46319,55873,
+55796,55806,46407,55877,55874,55792,46403,55887,55884,55892,46313,55872,46406,
+N,55879,N,N,46323,46326,N,55878,46405,55797,54756,N,N,55888,55886,55890,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,55788,46400,N,N,N,56929,56928,56902,47037,N,56927,56905,
+56906,N,47047,56936,47042,56926,N,56899,47048,47038,56914,56904,56907,56931,
+47032,56938,56930,47041,56919,47052,N,N,47051,47045,N,N,56937,47033,56917,
+56908,56921,56933,47053,N,47035,56916,N,56909,47044,N,47043,56912,56922,56932,
+56903,56913,47036,56923,47049,47040,56910,47039,56901,56915,56935,46334,47792,
+56918,57964,56920,56934,47046,56911,47034,47050,48368,56900,N,56925,N,N,N,
+56924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58026,47789,57981,58020,47778,N,57966,47791,
+N,47735,57965,58032,47793,57969,58019,N,57971,58035,58031,47733,47777,58963,
+47790,47741,57967,N,58030,47779,58027,58040,57973,57982,N,N,58038,58028,47740,
+N,N,57980,47734,47732,47784,N,N,57978,57975,57976,N,58034,N,58039,58037,47738,
+58041,47742,47783,N,57968,58874,57977,N,47736,47788,47785,47739,58021,57972,
+47786,58023,47780,47782,47731,N,58025,58017,57970,47781,58033,58036,57979,
+58024,N,47737,48351,58022,58873,N,58029,N,N,N,N,N,N,N,N,N,N,57974,58948,58958,
+48354,58957,58969,48356,58955,N,58959,48367,N,58950,48359,N,58962,59888,48371,
+48370,58964,58947,58974,48365,N,48355,58967,N,58971,58976,58965,58953,48358,
+48361,48369,48364,N,58956,58018,N,N,58952,58975,48360,N,48363,58977,48352,
+58966,58875,58972,49375,N,58954,N,48353,58949,48357,58876,47787,58945,N,58970,
+58946,58944,48362,N,58968,N,58878,58961,58960,58973,58951,48366,N,N,N,N,N,N,
+59891,N,48969,48894,59968,59883,48961,59895,48968,48963,59893,60751,59899,
+59970,59898,59881,59896,59972,59974,48893,59973,48964,48970,N,48967,N,59902,
+48966,59897,N,59885,59890,N,59901,48965,48962,48892,48960,59889,N,58877,59884,
+59887,59969,59892,59882,60750,59971,59886,59900,N,N,N,N,60753,49379,N,N,49367,
+N,N,49371,60755,60761,60759,49369,49370,49377,60762,60754,49372,N,60758,60757,
+60763,49378,N,49373,49376,60756,49380,49374,49381,49368,60760,N,60752,N,N,
+61431,N,N,49777,61428,61430,N,49775,61426,61427,61422,N,N,59894,61423,49776,
+61419,N,49773,61432,49774,61420,61421,61425,49779,N,49778,N,N,61424,50040,
+62047,62053,50041,62044,50038,50035,62055,50039,N,50036,62046,62049,62050,
+62051,62054,N,61429,62045,50037,62052,62056,62048,N,N,N,62557,50282,62560,
+50283,62568,62559,62556,N,62558,62562,62565,62564,62567,62555,N,50281,62563,
+62566,62569,62561,62931,62932,62936,62937,N,62934,62935,62933,N,50409,N,N,N,N,
+50552,63211,N,N,63208,63209,63210,50553,N,63461,63460,N,63663,50676,63661,
+63664,63662,63733,50775,50789,63907,63852,N,63906,63952,63953,42229,N,N,N,N,
+42695,51777,N,N,52062,N,43103,N,43106,N,52063,N,43104,43105,N,N,N,N,52568,
+52570,52565,52562,52564,N,N,N,43684,N,N,N,43682,N,N,52566,43683,52563,52560,
+43681,52567,N,52561,43685,52569,N,N,N,N,53167,N,53171,N,N,44215,N,N,N,N,53174,
+N,44207,44210,44212,44214,44211,53170,53169,N,44209,53172,53173,N,53166,44213,
+N,44208,N,N,N,53168,N,N,N,N,N,N,53879,53880,53881,44880,N,44876,53870,N,53878,
+53883,44881,N,53868,53874,53867,53877,N,N,53873,44877,44879,53882,N,53866,
+53869,53875,N,53876,53884,53872,N,44878,N,N,N,N,N,N,N,N,N,N,45677,54862,N,N,
+54864,54860,N,54872,54858,54871,45673,54856,55899,54866,45676,N,54867,54870,N,
+54874,N,54863,N,54868,N,N,45674,45675,54873,54861,54857,54875,N,54865,N,N,
+54869,N,N,N,54859,N,46408,46409,55909,46415,N,55897,55906,55896,46412,55904,
+55902,N,55903,46410,N,55907,N,N,N,N,N,55900,55898,46411,55901,55905,N,N,N,
+46413,N,N,N,55908,N,N,N,N,N,N,56944,56951,56953,56993,N,47066,56939,N,47058,N,
+56954,47063,56994,47054,N,56957,N,56941,56958,56940,N,47068,N,56952,47055,
+56995,N,47060,56945,47065,56956,56943,56950,56946,56942,47057,47064,47062,
+47059,47067,47056,56949,N,47061,N,46414,N,56955,N,56947,N,N,N,N,N,56948,N,N,
+58049,N,47796,N,N,58045,58051,58047,N,47798,58046,58050,58042,N,58044,47797,N,
+N,N,N,58048,58043,N,47799,N,47794,N,N,58052,N,47795,58983,58980,58992,58986,
+58988,48372,58982,58990,N,N,58989,58987,N,58993,48375,58984,58991,N,48373,N,N,
+58979,58981,48374,58978,58994,N,58985,N,N,59978,48977,N,N,59989,59987,48971,
+59977,59980,59981,59976,48981,48982,59975,59990,59985,48975,48972,59984,59982,
+N,N,48978,59986,48973,N,48974,N,59983,48976,59979,N,59988,48979,59991,59992,
+48980,N,N,49383,49390,60764,60770,N,60768,49386,49385,49382,60766,N,N,N,49388,
+49387,49384,N,60769,60765,60767,N,49389,N,N,N,49783,61435,N,49780,49781,61437,
+49782,61434,61433,62060,61436,N,62061,50042,62059,N,N,62058,N,62057,50043,N,N,
+50284,N,N,62570,62571,N,N,N,N,62940,62939,50410,N,62938,63212,63213,N,N,63462,
+63665,N,N,63734,63932,50809,63942,42230,N,43686,43687,N,N,44216,N,N,N,N,49391,
+42231,N,43688,44882,47069,42232,N,45678,47800,51554,N,53175,53885,N,58053,N,
+49392,42233,43689,53176,53177,55910,46416,N,N,56996,N,N,47070,58054,N,N,48376,
+N,50044,42234,55911,42235,N,42697,51778,42696,43109,43108,43107,52064,N,N,N,
+43690,N,43691,52571,N,53178,N,53181,44218,53179,N,44217,53180,44219,N,53922,
+53921,53886,44883,N,54877,54878,45679,54876,54879,46418,45680,N,N,46417,55915,
+55914,N,55912,55913,N,55916,56998,56997,57001,N,57000,56999,47801,58057,N,
+58056,47802,58055,58995,N,58996,48377,N,59993,59994,N,N,62066,50045,62065,
+62064,62062,62063,50411,62572,63214,63735,N,42236,N,51621,42439,51622,N,N,N,
+51779,51780,N,N,N,N,52070,N,N,52066,N,52065,43692,52069,43111,52067,43110,
+52071,52068,N,N,52575,53182,52573,52580,N,43693,N,43696,52581,52577,N,52578,N,
+52572,43695,52574,43694,52579,N,52576,N,N,53186,44221,44222,N,53189,53183,N,
+53188,N,53184,44220,53187,53185,N,N,N,N,N,N,N,53928,53925,N,53927,44888,44887,
+44885,53924,53929,44884,44886,53926,54887,53923,53930,N,N,N,N,N,54882,54886,N,
+54885,55918,55929,N,N,54888,N,54883,55917,45684,N,N,45683,54881,54884,45685,N,
+45682,45681,54880,54889,N,N,N,55920,55927,N,46420,55926,55923,N,46422,N,N,N,
+55925,N,N,55919,55921,55924,55922,46421,55928,46419,47071,N,N,57005,57004,
+57002,N,47074,47073,57006,N,57003,58058,47803,47072,N,N,N,57008,57007,N,58061,
+58059,48378,N,47804,58060,58998,N,N,N,N,48379,58997,59006,59005,59003,N,59002,
+58999,59000,59001,59004,59041,N,N,59999,59996,59997,48983,59995,60001,60000,
+59998,N,60772,60773,49393,N,49394,60771,N,49785,61438,49784,50046,N,50081,
+50285,62574,62573,62941,63215,50554,63464,63463,63465,42440,53190,44889,45686,
+54890,42441,51623,42237,N,N,51781,N,N,N,52076,52074,52075,52072,43112,52073,N,
+N,N,N,N,52589,N,43699,52587,52583,52586,N,52582,43701,52585,N,43698,43697,N,
+43700,52588,52584,N,N,N,N,44226,44229,53198,53197,53196,44223,53205,53195,N,
+44225,53935,N,53202,53200,44228,N,53192,53203,N,53194,53204,53201,53193,N,
+44224,53206,53191,44227,N,N,N,N,53940,53931,53942,N,53934,53945,53946,53932,
+53944,53941,53939,53943,44895,N,44893,N,N,53937,N,53933,N,53936,53947,53938,
+44894,53199,N,44890,44892,N,N,N,N,N,54904,54893,54891,N,54892,N,54899,N,54900,
+54896,45691,54901,54898,54895,N,45689,54894,45687,45690,54897,54905,44891,
+45688,54903,54902,45692,N,N,N,N,N,N,N,N,55934,N,N,N,55969,46432,N,55975,N,N,
+55977,55970,46426,55974,55973,46427,46433,N,46434,55976,46424,55933,55931,
+55971,55930,46431,55932,55972,55978,46425,46430,46428,46429,N,N,N,46423,N,N,N,
+N,47081,57015,47080,57019,N,57009,N,57020,N,N,N,57010,57011,N,57021,57018,
+57016,57017,57013,57012,N,57022,47077,N,57014,N,47082,47076,47083,47084,N,
+47079,47078,N,N,58062,47806,47805,N,N,58067,N,48380,47807,N,N,47809,58068,
+47075,47808,58064,58066,58063,N,58065,N,N,N,59051,N,N,59050,59047,48448,60002,
+48449,59046,N,48382,N,59048,59045,59042,59049,59043,59044,48381,N,N,N,N,60777,
+N,60006,N,60005,60007,N,60774,48986,N,60003,N,48984,N,48988,48987,60004,60008,
+N,48985,N,60781,49397,49786,49398,49395,60778,60776,N,60779,N,60782,49396,
+60780,60775,N,N,61506,61509,62069,61504,N,62575,61510,N,50082,61508,49787,
+61505,61507,61511,62070,N,62068,N,N,N,N,50083,62067,N,N,N,50286,N,N,N,N,50413,
+63217,50412,63219,63216,63218,50640,63666,42442,52590,53948,53949,45693,57023,
+48989,50084,50555,63667,42443,N,52591,41568,N,N,53207,N,53208,N,N,N,N,N,53950,
+53951,45694,45729,N,N,N,55979,N,57026,57025,57024,58069,N,58070,58071,47810,N,
+N,59053,59052,N,N,60009,48990,48991,N,60786,60783,60784,60785,61513,61512,
+49788,62071,62942,42444,N,44230,N,45730,57027,N,42445,N,53952,45731,N,N,46435,
+46436,N,42446,42447,51782,43114,43113,44231,53209,55980,42448,42449,42450,
+42451,N,N,N,43115,43116,52078,52077,N,N,43702,52594,52592,52593,N,N,N,N,N,N,
+53210,53211,N,N,44235,44233,N,44234,44232,N,N,N,N,44896,N,N,N,N,44900,44899,
+53953,44898,44897,N,53954,N,N,45734,54907,54906,45732,45733,N,N,N,46438,46437,
+55982,N,N,55981,45735,N,N,N,N,N,47085,57029,47086,57028,N,N,N,58072,59054,
+48450,60010,N,N,N,60787,N,50086,50085,N,N,50556,42452,52595,N,N,45736,58073,
+47811,N,N,52079,52080,N,N,52596,43704,43705,N,N,43703,N,N,N,N,44239,44240,
+44237,44238,N,53212,N,N,53213,44236,N,N,N,N,53955,N,44904,44905,N,45739,53961,
+N,44910,44908,53962,53957,44907,44906,44901,53960,53959,53956,44909,N,53958,
+44902,N,44903,N,N,45740,54945,54946,45741,54908,54910,54948,54947,54909,N,
+45737,45738,N,55990,46443,46442,55984,46440,N,55987,46444,55988,46445,55985,
+46439,46441,55989,N,55986,55983,N,N,N,N,N,57042,N,57031,47088,47091,47090,
+47095,47094,57043,57041,57034,57038,57037,47092,57040,57036,57044,57035,47093,
+47087,47089,N,57033,N,N,N,N,58075,47815,58079,47814,58076,47813,N,57032,57039,
+58078,N,47816,58080,58077,58074,N,N,59057,59061,59063,59059,59058,59056,48453,
+48451,48456,48457,59060,48454,59055,48455,47812,59062,48452,N,N,N,60012,N,
+60011,60019,60013,60018,60015,48992,60017,N,N,48993,N,48994,N,60016,60014,N,N,
+N,N,49400,60788,N,N,49399,60791,60789,60790,N,N,49401,N,N,N,61517,N,49825,
+61518,N,N,49789,61519,49790,61516,61520,N,61514,N,N,50087,62072,50088,50287,N,
+61515,50288,N,N,N,50414,62943,N,50558,63220,50557,N,63466,50677,50678,N,N,
+63948,N,N,44241,53214,N,46446,46447,42453,42698,51783,N,52081,43117,N,43706,N,
+44242,44243,44244,54950,53963,44911,N,N,45742,54949,N,N,55992,46449,N,55991,
+46448,N,N,57045,48458,59067,59064,59065,59066,N,N,N,N,N,60792,N,61521,N,N,N,
+62577,62576,N,63221,42454,52597,44912,N,N,N,46450,57046,N,N,58081,N,48459,
+60020,N,61522,62578,42455,N,N,43707,44247,53215,44248,44246,N,44245,53964,
+44913,N,N,44914,44915,N,N,N,45744,54951,45743,N,N,N,N,N,55993,45745,46451,
+57047,47096,47097,N,47817,N,47818,48460,48996,60021,48995,N,60793,49402,N,
+61523,62579,42456,43118,52600,52599,43708,52598,43709,52601,N,53221,44251,
+44250,53223,53222,44255,N,44254,44249,N,53217,53218,53219,N,44256,53216,44252,
+53220,44253,N,N,N,N,53967,53971,53969,53968,N,53972,N,N,N,53973,53974,53966,N,
+53965,N,44917,44918,N,53975,53970,N,54960,N,53976,44919,44916,N,N,N,54954,N,
+54953,N,54955,54956,54958,54957,54962,45749,45746,45750,54952,45751,54961,
+45748,54959,45747,N,N,N,N,N,55996,55998,55994,55995,N,N,55999,56001,56002,
+55997,56000,46452,N,N,57051,N,57056,57048,57052,N,N,57057,57053,47098,47171,N,
+47101,57049,57050,47822,47174,47102,N,47172,47100,57055,47173,57054,47169,
+47099,47170,57058,58086,58088,N,N,N,N,N,N,N,N,N,47168,N,N,58083,47820,58089,
+47821,58087,58082,58085,58090,47819,58084,N,48462,59071,59070,N,48465,48463,
+59068,48461,59069,N,48464,N,N,N,60029,N,60065,N,60030,60022,60026,60025,60023,
+48998,48999,48997,60024,60027,60028,N,49000,N,49472,60835,N,49404,60795,49406,
+49473,N,N,49405,60834,60796,49403,60833,60794,60798,60797,N,N,61525,49828,
+49829,49826,N,49827,N,N,61524,N,62075,N,N,50089,N,62073,62074,N,62580,62583,
+62581,62582,62944,N,N,50415,63467,63668,N,50679,63736,63737,50790,42457,44257,
+N,56003,N,57059,N,42458,43119,N,43710,N,53224,53225,44920,N,N,56004,46453,
+47175,49474,60836,62076,62584,42459,N,N,N,52641,52602,52604,52606,52605,52603,
+43711,44258,53234,N,53229,53226,N,N,53233,N,N,44260,44261,53232,53231,53230,
+53227,53228,53235,44259,N,N,N,N,N,N,N,N,44924,N,44964,44963,53985,53979,53977,
+N,44961,54969,44922,53982,53986,53988,53984,53978,44962,53983,53981,44921,
+53989,44965,53987,44925,53980,N,44926,44923,N,N,N,N,N,N,N,N,N,N,45753,N,54970,
+N,N,54963,54965,54967,N,54968,54966,45754,N,54971,N,54964,N,N,N,N,N,N,N,N,N,
+56008,46454,56016,N,56005,N,56017,N,56006,56007,N,N,56015,56014,56011,45752,
+46455,56009,56012,46456,56013,56010,N,N,N,N,N,N,N,57070,N,57074,47182,N,58096,
+47185,57072,N,N,57069,57064,57066,57067,57060,N,47181,N,N,47180,N,47176,57063,
+N,47183,N,47184,57062,57065,57073,47178,47179,57071,57061,N,N,N,58098,47824,
+58100,57068,58102,47828,58103,58099,N,47825,58095,47827,58092,58097,58101,
+58094,N,N,47177,N,58091,47826,58093,N,N,N,N,N,48468,59073,48472,N,48470,N,N,
+47823,N,59080,59081,48467,N,N,59079,59082,48469,48466,59075,59072,59077,59074,
+48473,59076,N,N,59078,48471,N,N,N,N,49002,60072,N,60066,60070,60076,60077,
+60073,60074,60071,N,60068,N,49004,49001,60067,60069,N,49003,60075,N,49478,N,N,
+60842,60837,49477,N,N,49475,N,60844,49476,60840,60841,60838,60845,61526,49479,
+60839,N,60846,60843,N,N,N,61530,N,N,61527,N,49830,N,61531,61533,61532,61528,
+61529,N,N,62115,N,50090,N,62078,62114,62077,62116,N,N,62113,N,62586,62589,
+62585,50289,62587,62588,62590,50290,50292,50291,62945,N,62947,N,62946,N,N,N,
+63222,N,N,63669,63738,42460,N,N,52082,43712,52643,43713,43714,52642,N,53240,
+53239,44262,44265,44264,44263,53236,53238,53237,N,N,53992,44967,53996,53995,
+53994,53990,44966,44970,44973,N,N,44974,53991,53993,44972,44971,44969,44968,
+54978,N,54976,54972,45755,N,54973,45756,54974,54975,54977,N,45757,N,N,56021,N,
+56020,56019,56018,N,N,N,N,57078,47186,N,57075,57077,N,47187,N,47188,57076,N,N,
+N,N,N,58177,N,58105,58106,N,47831,47829,47830,58179,N,58178,58110,58109,58108,
+58107,58176,58104,N,59083,59088,59086,N,N,N,59085,59084,59087,N,60078,N,49005,
+49480,60848,N,49481,60847,61535,61534,49831,N,62117,50091,62625,50593,63223,N,
+63671,63670,51624,44266,44267,54979,N,47190,42461,43122,43121,43120,N,N,N,
+52644,N,N,43716,43715,N,44270,N,53242,53245,53243,N,44268,44269,N,N,53241,
+53244,N,44981,N,N,N,54003,54005,54004,44978,53999,N,N,44976,44975,N,44979,
+44977,N,44980,54002,53997,53998,54001,54000,N,N,N,N,N,N,N,54982,54983,54981,N,
+54980,45758,46461,N,56022,56024,56026,46460,N,N,46458,N,56023,46459,56025,
+46457,N,N,57153,57079,57082,57086,47194,57084,N,57083,57080,57081,47192,57152,
+47191,N,47196,47195,47193,N,57085,N,N,N,58185,N,58184,N,N,58180,N,N,47832,
+58183,58182,47833,N,N,N,N,N,48478,N,59090,N,48479,48475,48477,N,48474,48476,N,
+N,N,60079,N,49008,60081,60080,N,58181,49010,49009,49006,49007,N,N,N,N,N,60853,
+N,60851,49482,60852,N,60854,60850,60849,N,N,61536,49834,49832,49833,N,N,N,N,
+62118,62119,50093,N,50092,62627,62628,62626,N,63224,63225,N,N,42462,51784,
+43123,N,52645,43718,43717,52646,N,N,53312,44271,53246,44272,N,N,44982,54008,
+54006,54012,44983,54007,54011,54009,54010,N,N,54984,54986,N,45759,N,54985,
+45760,46498,46497,46462,56027,N,N,N,N,57156,47197,47198,N,57155,57154,N,N,N,N,
+58186,47835,47834,58187,58188,N,48481,48480,N,60085,59091,59093,59092,60084,
+60082,60086,60083,N,49011,N,N,N,60855,49483,60856,60857,N,N,49835,49836,N,
+50293,N,N,50641,42463,N,N,N,N,N,53313,N,N,N,N,N,N,54013,44984,N,N,N,N,N,46010,
+46009,N,N,46500,56029,46499,56028,N,N,N,N,57157,N,47836,58189,47837,N,N,N,N,N,
+N,50294,62629,N,42699,43719,52647,N,44274,N,44273,53314,53315,N,N,54080,54082,
+44985,N,54084,54087,54085,N,N,N,54086,54083,54014,44986,54088,54081,N,N,N,N,
+54995,45766,55004,45763,N,54997,45767,N,45761,N,54992,55005,54993,54990,45765,
+N,45762,N,54996,54999,45764,55000,45768,55001,54991,54998,55002,54994,54989,
+54987,N,N,55003,N,N,56031,N,N,N,N,56036,N,N,N,56032,56038,46503,54988,56033,
+46501,56030,46508,56034,46507,56035,46509,46504,46510,46505,N,46506,N,46502,N,
+56037,N,N,N,N,N,N,N,47201,57168,N,57171,57159,57164,57158,47203,N,57162,N,N,N,
+57160,47202,N,57167,57166,57163,57165,57161,47841,57170,47199,57169,N,N,N,N,N,
+N,N,N,N,58205,N,47848,58200,N,47847,58190,N,58192,47840,58197,58196,58199,
+47845,58194,58193,N,N,47844,47839,58195,47842,58201,58203,N,58198,58191,47843,
+N,N,48489,47838,N,N,58204,N,N,N,N,N,N,N,59097,48482,N,59099,N,48483,N,N,48485,
+59102,N,59094,47846,59100,N,N,N,N,59096,N,47200,48488,N,N,48484,N,48486,48487,
+N,49014,59101,59095,48490,N,59098,N,N,N,N,N,60096,60091,N,N,60101,49012,60093,
+49016,60099,60090,60087,60102,49489,49017,60098,60088,49015,60092,49019,60089,
+60094,49018,60097,60100,N,N,N,N,60875,60876,60860,60867,60865,N,N,49487,60872,
+60095,N,60863,N,60873,49486,60862,60861,60871,60868,60870,N,60858,60874,49484,
+N,60869,60878,60866,49488,49485,60864,60859,60877,49013,N,N,N,N,N,N,N,61539,N,
+N,61537,61543,49840,61541,61540,49842,61546,49841,N,61547,61544,49838,61545,
+61538,49839,49837,62123,61542,N,N,61548,N,N,62120,N,N,N,50098,50096,62122,N,
+62124,62121,50097,50094,50095,50099,N,N,50296,N,62634,N,62633,62631,62630,
+62632,N,50295,50297,N,N,50416,N,N,62949,62948,N,N,63226,N,63228,63230,63229,
+63227,N,N,50595,50594,N,N,50643,50642,50644,63469,63468,N,63739,63672,63740,
+50776,N,50777,63853,N,N,50814,42700,N,52648,N,N,53317,53318,53316,N,N,44275,N,
+53319,53320,53321,N,N,54089,54095,N,N,54093,44987,54091,N,54092,54094,N,N,N,
+54090,45769,N,55006,45771,55008,45770,55007,N,N,N,N,N,56040,46511,N,56042,
+56039,55009,N,46512,N,N,56041,N,N,N,N,N,N,57174,N,47204,57172,47205,57173,
+47206,N,N,N,47849,58209,58206,58208,47850,47851,58207,N,N,N,N,N,59103,N,N,
+59104,N,48491,59106,59105,N,41569,N,60106,60107,60103,N,60104,49020,49021,
+60105,N,49495,N,N,49491,49496,49492,49494,49490,N,49493,N,N,N,N,49843,60879,N,
+62126,N,62125,N,62635,50298,50299,63297,62950,N,63296,N,63741,63908,42701,N,N,
+43124,N,52649,43720,44278,53324,44276,53322,44281,44277,44282,44280,53323,
+44279,44991,44990,54106,44999,54099,54105,44995,54098,54104,54102,44994,44996,
+54101,44989,54100,45000,44997,45001,44998,54097,54096,54103,44992,44988,44993,
+N,N,N,N,N,55024,55017,N,46517,55016,N,45775,45782,45779,45785,45784,45780,N,
+55010,55013,N,55012,45776,55014,55023,45777,55011,55020,55021,45778,55018,
+45783,45773,45781,55015,45772,55019,N,N,55022,N,N,N,56059,56050,46514,56057,
+56054,56046,56055,46516,56047,N,56043,N,N,47212,56052,N,46513,56058,N,46520,
+46522,56045,N,N,46521,56048,46515,56056,56049,56053,N,56051,46518,56044,46523,
+45774,46519,46524,N,N,N,N,N,47208,57181,57183,57185,57189,N,57179,57177,47210,
+N,57184,57188,57180,57176,N,57175,N,N,N,57186,57178,57182,47211,N,47209,57190,
+47207,57187,N,58226,N,N,N,N,N,47854,58218,48504,58228,47857,58232,47863,58213,
+N,N,58229,58210,N,58231,58214,N,47870,47867,58230,58224,47853,47861,47860,N,
+47859,47865,N,58211,47866,58225,47862,47852,58227,47855,47856,47864,58216,
+58215,58212,N,58220,58217,58221,47869,N,58233,47858,58222,58223,N,58219,N,N,N,
+47868,N,N,N,N,59111,48496,48505,48501,59108,N,48498,48502,59120,48492,59112,N,
+48500,N,N,59115,59110,48499,48503,59109,N,48497,N,59119,48494,59118,59117,
+48506,58738,48493,N,59116,59107,N,48507,59114,48495,59113,N,N,N,N,49058,49063,
+49022,60120,60111,60123,60115,60121,49064,49057,60108,60114,60124,60117,60122,
+60110,N,N,60118,49059,60116,49062,49061,60112,60113,60109,60119,49060,60126,
+60125,N,N,N,60890,60886,49503,N,60880,49497,49513,60892,49505,49501,60883,
+49508,49511,60894,49500,60885,49509,60896,60893,60881,49504,49498,49512,60888,
+49507,60882,49502,60895,49506,49499,60889,49510,60887,N,N,60891,N,N,N,61550,
+61556,49849,61559,49844,49845,61551,61558,61553,49850,49847,N,61549,N,49846,
+61555,61557,49848,61554,61552,N,N,N,N,62136,50103,50104,50100,N,50101,N,62132,
+62130,N,62134,50106,62135,62128,62127,62131,62129,50102,62133,62636,50302,
+50301,62637,N,62639,62638,50337,N,N,N,62955,62952,62953,N,62951,62954,50418,
+62956,N,50417,N,63298,N,50645,50647,63470,50646,63673,63808,63810,63742,63809,
+50796,42702,N,44283,53871,45002,N,N,45786,56060,56061,N,N,N,60127,49514,60897,
+N,N,49851,N,62138,62137,50338,62957,N,63299,50680,51785,N,N,43721,43125,N,N,
+53325,N,N,54112,54107,54111,54109,45003,54110,54108,N,55025,N,56062,56128,
+57193,57194,47214,47215,57192,57195,57191,47213,N,47936,N,47216,58234,N,48508,
+59121,48509,N,49065,60130,60128,60129,60900,60899,60898,N,N,N,62139,N,50105,
+62140,63300,50681,63674,42703,43723,43722,53327,44284,N,N,53326,54114,N,45004,
+55026,54113,N,N,N,45788,55029,55027,55028,45787,N,56130,56131,56129,N,47219,
+57197,57196,57198,47218,47217,N,N,59122,59124,N,48510,59123,60131,49066,61561,
+N,61560,50107,62141,50109,50108,62640,62958,50419,42704,53328,44285,54117,
+45006,54116,54115,N,45005,N,55035,N,55037,55030,55031,45789,55032,45790,55036,
+55033,55034,45791,N,46526,46527,N,56132,N,N,N,57199,57200,N,58238,47939,47937,
+47938,58235,58236,N,58237,59129,N,59130,48545,59127,59126,59128,59125,49069,
+60132,49067,49068,60902,49515,60901,61352,N,61562,61563,49852,N,49853,49516,
+62142,62143,62641,50339,42705,N,42706,44286,43724,45007,53329,N,N,N,46528,
+42707,44353,53330,53331,44352,44354,42708,N,53332,45009,54118,45011,45008,
+45010,N,55105,45792,N,55104,55038,N,57201,N,N,58273,N,48546,N,49070,60134,
+60133,N,60903,N,N,N,62959,N,N,42709,52083,52650,44355,53333,N,54120,N,N,N,
+45012,54119,45013,N,N,N,55107,N,N,45794,55106,55108,N,45793,N,N,N,N,56134,
+56135,56133,46529,N,N,N,47220,N,47221,N,47941,N,58275,58274,47940,N,N,N,N,N,
+59131,N,N,59132,N,N,N,N,60135,N,N,49520,49519,49517,49518,49521,N,61564,49855,
+49854,62144,62642,N,N,N,50597,50596,42710,N,N,53755,N,47223,46530,47222,47942,
+N,42711,51625,42712,42713,N,N,52651,52086,N,52087,43127,N,52084,43126,N,43129,
+52085,43131,43130,52088,43128,N,N,N,43729,43727,52653,N,43726,N,N,N,43731,
+43733,43730,N,52656,52652,43734,N,43728,43132,N,43732,52655,N,N,52654,N,43725,
+N,N,N,N,N,N,N,53339,44359,44360,53341,N,53335,53338,53347,53345,N,44361,53351,
+44364,53348,53340,53337,N,N,56137,53346,44356,53349,53334,53343,44358,44363,
+53344,44367,44365,N,53336,44362,N,53342,44366,44357,53350,N,N,N,N,N,N,45018,N,
+45027,45016,45014,54122,45022,45019,54124,N,N,45021,54123,54121,54126,45026,
+45024,56136,54127,54125,45015,N,N,45017,45020,N,45023,N,45025,N,N,N,N,N,N,N,N,
+N,N,55118,45796,N,55109,55111,N,55112,N,55120,55116,55114,N,55117,55121,45797,
+45801,55110,N,55119,N,45799,N,45798,55115,55113,N,45795,45800,N,N,N,N,N,N,N,N,
+46536,56145,N,N,56143,46538,N,N,N,N,56138,57249,N,46537,56142,N,N,56139,46533,
+46539,56144,46535,56141,47943,46534,56140,46540,46532,46531,N,N,N,N,N,57207,
+57205,N,57211,N,57203,57250,57208,N,57202,47227,47267,57213,N,57206,N,47230,N,
+N,47228,57214,47225,47224,57209,47229,46541,N,57212,57204,47226,47265,47266,N,
+N,N,N,47948,47944,N,47949,58278,N,N,58277,58279,47946,58276,47947,58282,58281,
+58280,N,47945,N,N,N,N,N,59201,N,59204,48552,59203,48551,48547,48548,48549,
+59200,59134,48550,N,59202,59133,N,N,60137,60147,49073,49072,N,60141,60143,N,
+60138,N,60142,60136,60145,49071,60144,60140,N,60146,N,60139,49524,60904,60910,
+49528,49530,49527,49526,N,49525,49523,60905,60908,49522,60909,N,49529,60907,N,
+60906,49856,N,49857,61601,61565,61566,N,N,62146,N,62145,50110,62644,50340,
+62643,N,62960,63301,50598,63811,63812,50648,42714,N,43735,56146,47950,49531,
+60911,42715,N,45029,45028,56147,N,N,N,60148,42716,44368,N,N,56148,56149,56150,
+47951,49074,42717,N,43736,53352,45030,54128,45802,N,56151,47268,N,47952,49075,
+49532,49858,62645,42718,43737,N,N,45031,55122,46542,N,47953,58283,59205,N,N,N,
+N,42719,46543,57251,47954,42720,52657,53353,44369,N,N,54130,N,N,45034,N,45032,
+45033,45035,N,N,54129,N,N,55127,55124,55126,45803,45805,45804,55123,45806,
+55125,N,56152,56153,N,56154,57254,N,57255,N,57253,57256,N,47269,N,57252,N,
+47955,N,N,59210,59206,59209,59211,59208,59207,N,60149,60150,60151,49076,49077,
+60913,60912,60914,N,61603,61602,N,62148,N,62149,62147,N,50341,N,62646,62647,N,
+63302,63471,63675,42721,43133,N,49533,42722,N,55128,56155,N,50753,51786,N,N,N,
+51787,51789,42723,51790,51788,N,N,52130,52131,52091,N,N,N,N,52129,43169,N,
+43170,52092,52090,52089,52093,43134,52094,53354,N,N,N,52662,43740,52661,52663,
+N,43739,52668,43743,52658,52672,52678,43750,52675,43747,N,52665,52671,52673,N,
+52660,43746,43741,52666,43748,43751,43745,N,43738,52670,52664,52677,43753,
+43749,43744,52669,45036,52667,43742,43752,N,52659,N,52674,52676,N,N,N,N,N,N,N,
+N,N,N,N,N,N,44386,44380,44388,44385,53361,53364,44381,N,53355,N,44374,44384,N,
+44387,44389,53410,53367,N,44373,53409,44377,44375,44370,53359,N,53374,53363,
+53366,53413,N,44390,53373,44382,53368,53412,53365,53369,53372,N,N,53357,53411,
+53371,N,N,53356,53360,44383,44378,44371,44376,44372,44391,53358,54181,44379,N,
+N,53370,52801,N,N,N,N,N,N,N,N,54184,45050,N,54134,N,54179,54141,N,54194,N,
+54186,N,54142,N,54185,54136,54140,54197,45053,54189,54180,45037,54195,54132,N,
+54188,N,45052,45047,54131,45045,45044,45049,54187,45041,45048,53362,56156,
+54182,N,N,54138,45051,54139,54177,45054,54133,54191,N,54190,54198,45043,45040,
+54196,54192,54183,54178,45046,45042,54135,45038,54193,45039,N,54137,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,55134,55136,55141,55161,45820,
+45810,N,55133,45821,45822,55144,55151,55157,N,55138,N,55145,N,N,45888,55159,
+55154,45818,45816,55150,55146,55132,45807,55137,55129,N,45815,45817,55142,
+55139,45812,55155,45809,55140,55162,55148,N,55147,45808,N,45819,N,45811,55130,
+55135,55152,55158,45889,55131,55143,55149,45814,N,N,55160,55153,55156,N,N,N,N,
+N,N,N,N,N,N,N,N,45813,N,56172,56160,46551,56189,56231,56234,46549,56168,56227,
+56169,56183,46562,56179,46559,N,56180,56157,N,56228,N,N,46568,56225,56181,
+56236,56176,57288,N,56239,46566,56174,56186,46569,46548,56178,56237,56171,
+56164,56175,N,56163,56161,46544,56229,56170,56232,N,56233,46552,46557,46553,
+46561,56190,46554,56182,56166,N,46546,56158,56226,56235,56165,46560,56240,
+56177,56173,N,46545,46565,N,56188,46567,N,56184,46556,46550,46558,46547,46564,
+56185,56167,56187,56162,56230,N,N,N,N,N,N,N,56238,N,N,N,N,N,N,N,56159,N,N,N,N,
+N,57287,N,57309,47189,57292,N,57290,57269,47273,57285,57305,57281,47281,57304,
+57279,46563,57295,57280,57302,47280,47272,N,57258,57266,N,57291,57283,57308,
+57286,47286,57303,N,47277,N,57289,57297,57270,57296,N,57313,57265,57298,N,
+57311,N,57259,46555,N,57273,57272,47279,N,57276,57278,57293,57310,47282,N,
+47283,N,57264,47275,57268,57306,47284,N,47276,47278,47285,57312,57299,57294,N,
+N,57275,57274,47274,57260,47271,57284,57261,57282,N,N,57271,57307,N,N,N,47270,
+N,N,N,57267,N,N,N,N,N,N,57263,57301,57262,47968,58323,N,N,58306,N,N,58284,
+58314,47960,58299,58309,47963,58302,47961,58287,58317,58286,58305,N,58285,N,N,
+58303,58312,58310,58298,58293,58291,N,58292,58311,58322,58300,47962,N,58295,N,
+58315,N,47965,58294,58288,58304,47969,N,N,47957,47966,58296,58290,N,47959,
+57300,47958,58307,N,47956,47971,47964,58308,58297,58289,58316,58301,47970,
+58320,47967,58319,N,58313,58318,N,N,N,58321,N,N,N,N,N,N,N,N,N,N,N,59251,59252,
+59239,59238,59234,48564,N,48556,59254,59253,57257,59231,59235,59229,N,59248,
+59233,N,59255,59226,59224,59236,59246,59241,48566,59215,N,59245,N,N,N,48567,
+57277,59227,59218,59221,59259,59228,59219,59217,59214,N,48560,59237,48559,
+48563,59232,59240,48553,59256,59260,48555,N,59223,59243,59247,59220,59257,
+48562,N,48561,59212,48565,59250,59222,59242,59216,59230,59225,48557,48558,
+59244,59261,59258,59249,N,N,N,N,N,N,N,N,N,59213,N,48554,60233,N,60224,60227,N,
+49083,60229,60153,60225,60231,49080,49084,49078,N,N,60155,60236,N,N,60230,N,
+60156,60245,60239,60152,60998,60158,49079,N,60234,N,60244,49087,N,60241,60157,
+60228,60232,60226,60246,60243,60240,49081,49082,49086,60154,60247,49085,60237,
+N,N,60235,N,N,N,60238,61011,60992,60997,61010,60996,60923,60993,N,49570,N,
+60916,61005,61007,60915,49569,61009,61001,49576,61008,60994,49578,60921,60242,
+61002,60999,60917,61013,49572,N,N,49573,60919,61000,N,61012,61003,60925,49575,
+49571,61004,60926,61014,60920,60995,61006,60922,60924,N,49867,60918,49577,
+49860,49534,N,N,N,N,49574,49864,61619,N,61609,61604,61610,61620,61624,61623,
+49866,49865,N,N,61611,61625,61614,61606,N,61608,61607,61613,61618,61605,61612,
+61617,49863,N,61615,N,49861,61616,49859,49862,62165,61621,N,N,50114,N,62157,
+62161,62153,62156,N,62164,50112,62169,62162,N,62154,62170,62163,50115,50116,
+62167,N,62155,50111,50113,62150,62158,62152,N,62168,62166,62151,62159,N,N,N,
+62654,50117,62160,50343,50345,50342,N,62659,62651,62649,62653,62650,N,N,62655,
+62657,50346,50348,N,62656,50349,50347,62658,N,N,N,N,50344,N,N,N,N,N,50420,
+62961,62967,50422,62652,62966,N,62973,62964,62971,62970,62648,62965,61622,
+62974,62963,62968,N,62972,62962,N,63306,50421,62969,N,N,63476,63307,63305,
+63303,63304,63308,N,50649,63474,63472,63477,63475,N,63478,50650,63473,N,N,
+63676,N,N,63813,63814,63815,N,N,63943,63933,51791,43754,N,44392,N,54200,54199,
+45120,45890,55164,N,N,55163,N,46570,47288,N,47287,47289,N,58324,59262,60248,
+60250,60249,N,49579,61015,61626,63909,42724,N,52681,52682,52680,52679,43755,N,
+53417,53415,N,N,53414,N,44393,44395,44394,53416,N,N,N,N,N,N,N,N,54212,54209,
+54207,N,N,45121,54210,45126,54204,54219,N,54221,54205,N,45123,54222,54217,
+54203,54208,54218,54214,54211,N,45128,54220,54206,N,N,54215,54201,45127,45124,
+54213,N,54216,54202,45125,45122,N,N,N,N,45900,55205,45899,N,55208,55211,45896,
+45894,55166,55209,55207,55204,55212,55213,55215,55216,55165,45893,55202,55201,
+55214,45895,55203,45897,45892,55206,45901,N,45898,55210,N,N,N,46577,56255,N,
+56244,46574,N,57319,56253,56241,46572,56246,46575,56250,56248,46578,46571,N,N,
+56242,56245,46576,N,56243,N,56254,56252,56247,56249,56251,46573,N,N,N,N,N,N,N,
+57320,57326,57316,57322,47290,57318,47296,N,N,47295,47294,57325,47297,47298,
+57315,57328,47299,47293,47292,57324,47300,57314,57317,57327,57323,N,N,58356,
+58345,47291,N,N,N,N,47978,58333,58354,58334,47973,N,58331,N,58340,58332,47975,
+58326,58353,47976,58350,58351,58327,47981,58342,N,58336,58343,58330,N,58355,
+58347,58341,58325,47977,58348,N,47980,58352,N,58346,47974,58344,N,58338,47972,
+58329,58337,58349,58335,N,N,58339,N,N,N,N,N,48577,57321,59314,59323,59313,
+59309,59306,48578,59304,47979,59297,48576,59303,48575,59308,59305,59321,59316,
+59310,59315,48571,59307,59326,59298,59299,59322,48572,59327,48574,59328,59312,
+58328,59318,59311,59320,59317,N,N,N,59302,48569,59325,48570,59300,48573,60260,
+59319,59324,N,N,N,N,N,60257,48568,49088,60267,60263,N,60261,60256,60271,N,N,N,
+49092,N,60252,60264,60265,60255,60254,60268,N,60258,60253,60259,N,60270,60251,
+60269,60266,49090,49089,N,N,49091,60262,61643,N,N,N,N,N,61017,49585,61021,
+61018,61025,61031,61020,N,61040,49582,61034,61023,61035,61030,61037,61022,
+49587,49586,61024,61038,61016,61036,49580,N,61028,61027,61032,61019,49584,N,
+49588,61026,61033,49589,61029,N,N,N,N,49581,49583,61639,61637,N,N,61644,61641,
+61645,N,61630,61638,61649,61039,61634,49871,59301,61629,61642,61636,61633,
+61628,61627,61648,N,61632,61631,49869,61640,N,49868,N,N,49870,61635,61647,N,
+62174,62175,N,50121,62172,50118,62180,N,50122,62182,62171,61646,62184,62173,N,
+50119,62179,N,62181,62176,62183,62178,62177,50120,N,N,62661,62662,N,62664,
+50350,50351,62665,62663,N,62660,N,63042,63045,63041,N,50426,63043,50425,50424,
+50423,63044,63313,63311,N,63310,63040,63312,63046,63309,N,63481,63447,63479,
+50651,63480,63482,N,63679,50682,63678,63677,50683,N,50778,63854,63911,63910,
+63912,42725,53418,N,54223,54224,N,N,N,56256,N,63047,63680,42726,44396,53419,N,
+N,N,55217,45902,N,56258,56257,46579,N,47301,59329,48579,N,48580,N,N,N,49093,
+50684,42727,N,N,N,53420,43757,53422,53421,44397,N,54225,N,54232,45129,54230,
+54228,N,54235,54226,54227,45130,N,45134,N,N,54236,45133,54234,54231,54229,
+45131,45132,54233,N,N,N,N,45904,55218,N,45909,55234,45908,55236,N,N,55224,
+45906,55235,N,55219,45907,55231,55227,55229,55223,55230,N,N,45903,55226,N,
+55225,55221,N,55232,N,N,55228,55220,N,55222,45905,55233,N,N,N,N,46582,56269,N,
+N,N,56265,56267,56262,56261,56259,N,56266,56268,56264,N,56263,46580,46581,N,N,
+N,N,N,N,56271,47309,57330,57336,57331,57332,N,57337,N,47311,N,47303,47310,
+57329,56260,47306,47304,57335,57334,47305,47307,57333,47302,N,47308,N,N,N,N,N,
+58358,47988,N,N,58434,58433,N,58363,47990,58432,58359,58360,47982,47984,N,
+58365,58357,47986,47985,58361,58366,58364,47987,58362,56270,47983,N,N,59330,
+59337,48582,N,59341,48586,59333,59331,N,59340,N,48581,59339,48583,48584,59332,
+48585,59338,59334,59335,59336,47989,N,N,N,60272,60284,N,49098,60279,60281,N,
+49096,60273,60277,N,60280,49094,49097,60283,60275,60276,60282,60274,60278,
+49095,61042,N,61041,49591,61047,49593,N,N,49590,61043,49594,61044,N,N,61045,
+61048,N,49592,N,61654,N,N,61657,N,61651,61653,N,N,61652,61655,61656,61046,
+61650,N,N,50125,62188,62191,62193,62186,62187,62190,62192,50126,50124,50123,
+62189,62185,62666,50352,N,62667,N,N,63049,50427,63051,50428,63048,63050,50600,
+N,63314,50599,63485,63484,N,63483,N,N,63816,63817,63819,63818,N,51792,42728,N,
+44398,55237,46583,N,57338,49872,N,62194,N,N,43171,N,N,N,45911,N,N,N,45910,N,
+56272,46584,56274,56273,N,N,57339,47312,58435,58438,58437,N,58436,59342,59344,
+59343,N,49100,N,N,N,49099,N,49595,61049,61051,61050,N,N,49873,N,N,N,62196,
+62195,N,62668,50353,N,N,50429,63316,63315,50779,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,43172,53423,44399,55240,55238,N,N,55239,56276,56277,57411,56275,N,57340,
+57409,57408,57410,47313,57342,57341,57412,N,58441,58439,N,58440,59347,59345,N,
+N,59346,60285,61052,61053,49874,N,62197,62669,50354,N,63052,63317,50601,N,
+63486,63820,43173,N,44401,44402,53424,N,N,53425,44400,N,45140,N,45138,N,45137,
+45144,45136,45145,54237,45142,N,45139,45143,45141,45135,N,N,45919,N,45913,
+55244,45918,N,N,45920,45914,N,45915,N,55242,N,N,45912,N,55243,45917,N,N,55241,
+45916,N,N,46660,N,46662,N,N,56280,46661,46585,46589,N,47332,57417,56282,46590,
+N,N,56285,56286,46659,N,56288,N,56290,N,56291,56279,56278,56292,46658,56289,
+56287,N,46656,46587,46663,56283,56284,56281,N,46657,N,N,46588,N,46586,57416,
+47327,47322,N,N,47317,N,47333,47318,N,47314,47329,47326,47328,N,47319,47324,
+47315,47316,57424,57421,57413,57418,N,47330,57425,47331,47321,N,N,57415,N,
+57423,57419,57422,57420,47325,57414,47320,N,N,N,58444,47992,47995,N,58446,N,
+48037,58445,47997,N,48591,58447,N,48036,58443,48038,N,N,N,47993,N,47323,47996,
+N,47994,47998,48034,47991,48039,48035,N,48033,58442,N,N,N,N,48598,N,48594,N,N,
+N,48601,N,59350,48602,59362,59355,48587,59363,59357,48597,59358,N,48596,59361,
+48590,59359,59349,48589,60330,48595,N,48592,N,48600,N,59348,N,59352,48588,
+59351,59353,59354,48599,59356,59360,59364,N,48603,49106,60325,60331,60328,
+60286,60332,60321,N,60327,N,49101,49107,60333,N,N,49103,N,49113,49108,60335,
+60329,49104,60322,49114,60323,60324,49115,49112,48593,N,49102,60336,49116,N,
+49109,60334,49105,49110,49111,N,49603,61092,61101,61098,61100,N,49600,61093,N,
+61099,49596,61095,49604,61091,61096,61103,60326,61097,61090,49597,61089,49598,
+61104,49599,61102,49602,61054,N,49601,N,61094,61660,61674,61669,61671,61659,
+49875,N,61658,49878,49877,N,61673,61665,61662,61668,N,61661,N,61663,61672,
+61670,N,49876,61677,61675,61666,61676,61667,N,62201,50127,62273,N,N,63055,
+50134,61664,62199,50130,62200,62205,N,N,50132,50133,62198,62272,62274,62202,
+62204,62206,62203,62275,50129,50135,50131,N,50128,62672,N,50359,62670,N,N,
+62674,N,62675,50357,62676,62673,N,62671,50360,50356,62677,N,50358,50355,N,N,N,
+50430,N,N,50496,63054,63053,63056,63057,N,50497,63318,63323,50602,N,63320,N,
+63319,63322,63321,N,63555,N,50652,63554,63552,N,63553,N,N,N,50686,50685,63681,
+63682,50752,N,63821,63822,50791,N,50797,N,63913,63944,43174,N,55245,N,55246,
+57426,58448,59365,49606,N,49605,61678,62276,N,63556,43175,54238,45146,45921,
+57428,57427,48604,59366,48605,61105,49879,N,N,N,50806,43176,52683,54239,N,N,
+45922,N,55247,55248,N,56293,N,46664,47334,N,57430,57429,57431,N,58449,58450,
+48040,49117,48606,49118,N,61109,61106,61108,61107,49607,N,61679,62278,62277,
+52132,45148,45147,54240,N,55249,N,N,56295,56294,46665,N,57433,57434,57432,N,N,
+47336,47335,N,48042,48041,N,59367,60339,60337,60338,49119,61111,61110,N,61682,
+61681,61680,62279,N,63914,43177,44403,N,44404,45149,45150,54242,54241,55250,N,
+45928,45926,45923,45927,45925,45924,N,N,46666,56298,N,47341,46668,46673,56300,
+46675,46674,46677,56299,56296,46671,46667,46669,56297,46676,46672,46670,47343,
+47342,47340,47344,N,47338,47339,N,47337,N,57435,N,N,58452,N,48044,48045,48043,
+N,58451,N,58453,N,59370,59372,N,48615,59373,48608,59369,48607,48617,48613,
+48614,48610,59368,48609,59374,59371,N,48616,N,48611,48612,60341,N,60343,60342,
+N,60344,49120,60340,N,N,49611,61112,49608,49612,49610,49609,61683,61686,N,
+61685,N,61684,49880,62280,62281,50136,62282,50137,N,N,50362,N,50361,63058,N,N,
+50498,63059,63324,50603,50604,N,63557,N,50754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43178,N,45930,45929,57436,57437,N,48046,
+60345,48618,60346,61113,43179,N,53426,44406,44405,N,54243,45151,54244,55253,N,
+55252,N,55251,N,N,56302,46680,N,N,56301,46679,N,N,N,56303,46678,N,57439,57442,
+57440,57441,57445,57438,57446,57443,57444,48048,58454,N,N,48047,N,59378,59376,
+N,N,48619,59375,59377,N,48620,N,60347,N,60348,49613,N,62284,62286,62283,62285,
+62678,63060,N,N,63855,43180,44407,54245,54247,54246,N,55256,45932,N,55254,N,
+45931,55257,N,55258,55255,N,N,56315,46688,56307,56313,N,N,46683,46686,56306,
+46681,56310,57452,46685,N,56305,N,56311,56308,56314,56304,56312,46684,46687,
+56309,46682,N,47346,57448,47345,57455,57454,47352,N,47353,57456,47347,57453,
+47351,57458,57449,N,57451,47348,57447,57450,57457,47349,57459,N,N,N,N,N,47350,
+N,48049,58459,58465,58457,58466,N,58456,58461,58467,58464,58463,58462,N,58455,
+58460,N,N,58458,N,48625,48622,59387,59457,59459,59456,59384,59386,59461,59458,
+59388,59462,59385,59460,48623,48629,48627,59379,48628,48624,59380,59382,59381,
+59389,59390,N,48626,N,48621,N,N,59383,N,60358,49122,N,60349,49123,49126,60354,
+N,60351,49125,N,N,60355,60356,60350,60359,60352,60357,49124,N,49121,60353,N,
+61119,49616,49614,49617,49615,61118,61115,61114,N,61117,N,N,61116,61765,49886,
+61691,61690,N,49881,61761,61760,61687,61763,61692,49885,61689,61762,61688,
+49882,49884,61693,49883,61694,N,61764,62290,N,50142,62287,N,62291,N,N,50139,
+62289,50144,N,50141,N,62288,N,50143,62292,50138,N,N,N,N,50364,50366,N,62681,
+50365,62679,50140,62680,50363,50499,50501,63062,50500,63061,N,63329,50605,
+63328,50606,63326,63325,63330,63331,63558,N,63327,N,N,63686,63683,63684,63685,
+50780,N,63825,63824,63823,63856,N,63934,63915,50798,43181,45152,N,N,N,N,N,
+47354,N,N,N,N,N,N,N,48630,N,N,60360,N,N,49887,N,62293,N,N,N,N,N,N,63916,43182,
+43758,44409,44408,N,45155,N,54248,45153,54249,45154,N,N,55263,55259,N,N,45933,
+55262,55261,55260,45934,55264,55265,N,N,N,56387,56385,56389,56390,56396,N,
+56392,56394,N,56386,56316,N,56393,N,N,56395,56388,56391,56317,46690,56384,
+56318,46689,46691,N,47357,57461,57463,57462,57467,47355,N,57464,57460,57465,
+57466,47356,47358,57468,N,58471,58470,N,58468,58469,48051,48053,48050,48052,
+59469,59470,59465,N,59466,48632,48637,48631,48638,48633,59467,N,N,59468,59464,
+48704,48635,N,N,48634,48636,N,59463,N,60362,49128,N,N,60364,49130,60367,60363,
+60361,60366,49129,60365,N,49127,N,N,49619,49622,61121,N,49620,61120,49618,
+49621,61766,61767,61768,49888,N,61769,N,49889,50146,62296,62297,62295,62294,
+62298,50145,62685,62683,62684,62686,62682,62687,63064,N,63065,63063,50502,
+63332,50607,63333,63560,63559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43183,46692,N,N,
+47424,N,N,N,48054,N,N,49132,N,49131,N,N,N,N,50147,50300,50503,43184,45156,
+47425,N,62299,N,N,N,N,N,N,N,N,N,N,52134,N,N,43185,N,43188,43187,43186,N,N,
+52133,N,52685,N,52687,43759,N,N,43761,52684,52686,43760,52689,52688,52690,N,N,
+N,N,N,N,N,N,53430,53428,44412,53427,44451,44414,44411,N,44452,N,44413,44450,N,
+44449,53429,N,44410,N,N,N,45162,54251,54257,45159,45166,N,45161,54254,54256,
+45164,54250,54253,45160,45157,54252,45163,54255,45165,45158,N,N,N,N,55267,
+55270,45936,N,45946,45942,55268,N,N,45950,45943,45948,45938,N,45935,45937,
+45949,55269,45941,45944,45940,45945,55271,45947,45939,55266,N,N,N,N,N,N,N,N,
+56397,46693,56399,N,46695,46697,N,56398,46694,46698,N,46696,N,N,N,47431,57507,
+47439,57470,N,47440,47429,N,57505,N,N,47434,N,57506,47427,47426,N,47437,47436,
+47435,47433,47438,57469,47428,47430,47432,N,N,48056,48059,N,48063,48057,48062,
+48060,N,48055,N,48061,48058,N,N,N,59474,48707,48705,N,59475,N,48708,48706,
+59473,59472,N,49136,59471,49134,49133,60368,48709,49135,60369,49138,60370,
+49137,49624,61123,49623,49628,49626,49627,49891,49625,61122,60371,49890,49892,
+N,50148,50149,N,62688,N,50654,50653,43190,N,N,51797,45167,N,51794,51795,51793,
+N,51796,N,N,52138,52135,52140,52136,43191,43194,N,52137,43193,52139,N,N,43192,
+N,N,N,N,52693,52695,43764,52691,52694,52692,43762,43765,N,43763,N,N,N,N,53432,
+53436,53433,N,44455,N,44456,N,53435,N,53437,53439,N,44453,53438,N,N,44454,N,N,
+N,N,N,55278,53434,54258,54267,54265,54260,54261,54266,54268,45169,N,54263,
+54259,45168,45170,54262,54269,54264,N,N,45985,55281,55273,55279,55280,45986,N,
+55272,55274,53431,55276,55277,55275,46700,N,N,N,56406,60372,56407,56404,45987,
+46702,56403,56409,56408,46699,56412,56402,56411,56400,56410,56405,46701,N,
+57514,N,57509,57515,57510,57508,57511,47441,N,57513,N,57512,47442,48065,48064,
+58478,58481,58473,58477,48066,58476,58474,58480,58475,58472,58479,N,59481,
+48712,61770,59478,59479,59477,56401,48711,59482,59476,48710,48713,59480,60373,
+49139,60374,60375,N,61124,49629,61771,61772,N,N,61773,62301,62300,62690,N,
+62689,63067,63068,63066,63334,50608,43195,44458,44457,45173,45172,54336,54337,
+54270,N,45171,55285,N,55286,55282,45988,55283,N,55284,N,N,N,N,56415,56417,
+56413,56416,46703,56414,46704,N,N,56691,47445,47444,N,47443,N,57516,57517,N,N,
+58483,58485,48070,48067,N,48069,48068,58484,58482,N,N,N,N,N,59489,59486,59487,
+48717,59488,59483,59484,48714,N,48715,59485,48716,N,60379,N,60380,60377,60378,
+49140,60376,N,N,N,N,N,61128,61125,61127,49632,61131,49631,61129,61132,61130,
+61126,49630,N,61775,N,61776,61774,N,61778,49893,49894,62303,50151,61777,62302,
+50150,62693,62694,50367,62692,N,62691,N,63069,50504,N,63561,63688,63687,N,
+50755,50781,63689,63857,N,50799,43196,43766,N,47446,N,50368,43197,44459,45989,
+46705,49895,43767,N,53441,53440,54338,N,45176,45174,45178,54340,N,45177,45175,
+N,N,N,N,54339,45992,55292,N,45991,45993,55362,45995,55294,55360,55287,45994,
+55363,N,N,55289,N,55290,55288,45990,N,55361,55291,55293,N,N,N,56429,N,56428,
+56426,56418,56433,56421,56431,56438,56430,46713,N,46709,56419,N,56425,46711,N,
+56424,46712,46714,56427,N,46706,46707,56439,56437,N,56436,56422,N,56434,N,
+46710,N,N,N,N,46708,56435,56420,56423,56432,N,N,N,N,N,58554,57527,N,57520,
+57539,57548,57523,47457,N,57536,47447,47449,47461,57521,N,N,47450,47452,47462,
+47451,N,N,N,N,47460,57529,N,57518,47458,57528,47454,57546,47459,57544,57532,
+57542,47456,57519,57545,57540,N,57547,47448,N,N,47463,47453,N,N,57525,N,57533,
+57537,N,57541,47455,57524,57522,57534,N,N,N,N,57531,57530,N,57535,57538,N,
+57543,N,N,N,58488,N,48071,58532,58490,48076,48080,58541,58549,58534,48072,N,
+58538,57526,N,48073,58545,58550,58542,N,58544,58553,58546,58494,58537,N,N,
+48081,N,48077,58492,58539,48075,58533,48074,58547,58530,58489,48078,58552,N,N,
+58491,58543,58540,58535,58487,58486,58529,58548,48079,58551,58493,58531,48722,
+N,N,N,N,N,48730,48725,59556,59553,59495,48720,N,N,N,48719,48726,N,N,N,59493,
+48724,59505,59491,59492,48718,59555,48728,59508,59513,59507,60398,59503,59511,
+59509,59496,59490,59517,48727,59518,N,59512,N,59501,59499,59494,N,N,N,59502,
+59515,59498,59514,59554,N,N,48723,N,59510,59516,59506,59500,48721,N,N,N,58536,
+59504,48729,59497,N,N,N,N,N,60404,49143,60403,60400,60484,49147,N,60481,60408,
+60483,60393,60406,N,49149,N,60385,N,60383,60482,N,60480,60414,60397,60396,
+60386,49216,N,60392,60402,60413,49219,60485,N,49640,49221,49150,60390,N,60399,
+60382,60384,49141,49218,49146,60391,60407,60401,49217,60381,49635,60409,60412,
+49148,N,60395,49220,49145,N,N,N,49144,60405,60411,49142,N,60388,60410,N,N,
+60389,N,N,N,N,N,N,N,N,N,60394,61138,N,61143,49637,49639,61149,49633,61164,
+61155,61144,61145,61154,N,49646,61153,61137,61152,61140,61165,49645,49643,
+61141,N,61160,N,61146,61159,N,61161,61136,49638,N,61162,N,N,61150,N,49642,
+61147,N,N,49644,61156,N,N,N,49636,61142,61157,N,61151,60387,61158,61139,N,
+49641,N,61163,N,49634,61134,N,N,N,N,61792,61785,49897,N,61780,61795,61787,
+61148,N,61797,61781,N,49896,61791,49898,49906,49904,61793,49905,61783,N,61784,
+61789,61794,N,61133,49899,61802,61799,61803,61790,61786,61800,62314,61788,N,
+49902,N,49901,61135,49903,61796,61798,49900,61801,61779,N,61782,N,N,N,N,N,N,N,
+N,62323,N,62307,50155,62321,N,N,62305,50156,N,62316,N,62312,50161,62322,62306,
+62309,50153,62324,N,62317,62320,50159,50164,50162,62313,62308,N,50157,50158,
+62304,50154,N,50152,50160,62319,50163,N,62315,62325,50165,N,N,N,62311,N,62318,
+N,N,N,N,N,N,62707,62786,62709,62716,62310,62714,62697,62784,50371,62701,62718,
+62708,N,N,50370,N,N,62788,62710,N,62715,62717,62695,62785,62706,62711,62699,
+62703,62787,62713,62696,62700,62702,62712,N,50369,62705,N,N,N,N,N,N,62698,N,N,
+N,N,N,N,N,62704,63073,63078,50511,63080,N,50505,N,63076,63082,50510,50506,N,
+50507,63072,63079,50509,63077,50508,63071,63075,63074,N,63070,63081,N,N,N,
+50609,63341,63344,63340,63342,63343,63337,63338,63335,N,N,63339,63336,50610,
+50611,N,N,63563,N,63565,N,N,N,N,N,63564,63566,N,50656,N,63562,50655,50657,N,N,
+N,63691,63692,50756,63690,N,63827,63826,63828,50783,63829,50782,63830,63858,
+63861,63860,50792,63859,N,N,N,50802,50800,50801,50807,63936,63937,63935,63945,
+43768,N,N,55364,56440,59557,62326,N,N,43769,N,44460,45179,N,N,55365,N,55366,
+45996,N,46717,56442,56441,46755,46716,56443,46718,46754,46753,46715,N,N,N,
+47464,N,N,57552,57550,N,57551,57549,N,48082,N,48085,48087,48086,N,N,48083,
+48084,N,59559,59558,48731,59560,N,59561,48732,N,N,N,60493,60491,61171,N,60489,
+60490,49222,60486,60494,60488,60492,61167,N,N,61169,N,61170,49651,61166,49650,
+61168,49647,49648,49649,60487,N,N,49909,61806,61804,61805,49907,49910,49908,N,
+N,N,62327,62328,50166,N,62789,62791,62790,50372,50512,63085,63084,63083,43770,
+N,51626,N,51800,42729,51798,51801,51799,N,N,N,52142,N,43201,N,43202,52144,
+43199,52143,52141,43200,43198,N,N,N,N,N,N,52696,52699,43773,52698,52697,N,
+43772,43771,N,43840,52700,43774,N,N,N,N,N,53446,44462,44463,44464,53447,53443,
+44461,53444,N,53445,53442,N,N,N,45220,N,N,45217,54341,45218,45221,54342,N,
+45182,45180,45181,45219,N,N,N,N,N,45997,55369,46005,55368,N,55371,46001,55370,
+46763,45999,46002,45998,46003,46004,46000,N,N,N,55367,46759,56445,N,56483,N,N,
+56482,46764,46760,46761,56444,56446,56481,46756,46758,N,46762,46757,N,N,57555,
+57553,57554,47466,47467,N,57556,47465,48088,N,48090,48089,N,58555,N,N,58556,
+59563,N,59562,N,N,49223,49224,60495,49225,N,61174,N,61172,N,61173,49652,N,
+61807,50167,N,N,N,49653,43841,N,45222,54343,N,N,55372,46006,46765,56484,56486,
+46767,46766,46768,46769,56485,47470,47471,47469,48091,47468,57557,N,N,N,48092,
+59564,60496,49226,49654,61808,61812,49913,61809,49914,49912,61813,49915,61811,
+N,62329,49911,50168,N,63693,N,N,43842,46008,46007,N,N,N,N,46770,56488,56487,
+46771,N,N,57561,47475,47472,57560,47474,57558,47473,N,57559,N,58557,48093,N,
+59567,N,48733,59565,48734,48735,59566,48736,N,60497,N,49230,49227,49232,60499,
+49228,60498,49231,N,N,49229,N,61177,61179,N,N,49655,61178,49656,61176,61175,N,
+61815,61814,49916,61816,62334,50170,62333,62330,50169,62331,62332,N,62792,
+62793,50373,N,50515,N,N,63086,N,N,50513,50514,63087,N,N,50612,50613,63345,N,N,
+50757,63695,50759,N,63694,63696,50758,63831,N,63917,N,N,N,N,N,N,43843,N,N,N,
+47476,N,58558,N,59568,49233,49234,N,43844,N,48737,50171,44465,N,N,N,49235,N,
+50658,44466,55373,N,56489,N,56491,N,56490,N,57565,57562,47477,N,47478,57563,
+57564,N,58560,58565,48094,58559,58561,58568,58563,58567,58564,58562,58566,
+48095,N,N,59571,N,59569,48739,N,48738,59570,48740,N,N,N,N,60502,N,N,60501,
+49236,60500,61180,N,61182,61249,61248,N,49657,61181,61857,49917,61821,61858,
+49918,N,61819,N,61822,61820,61817,49984,61818,N,N,N,N,62369,N,N,62371,62370,N,
+62794,N,62795,N,N,N,63088,N,50615,N,50614,63567,63568,50760,63697,N,50793,N,
+44467,46772,58570,58569,59573,59572,N,N,49658,61251,61250,61861,61859,61862,
+61860,N,N,50172,62372,62373,62374,N,63089,N,63346,N,63698,N,N,N,N,N,N,N,44468,
+N,N,60503,61252,N,44469,N,N,48096,N,60504,49985,61863,50173,N,62796,62797,
+50516,63569,44470,46011,46012,55374,46773,46774,56492,46775,N,47482,N,47484,
+57567,57568,57566,47479,47480,47483,47481,N,N,58571,48097,48098,N,N,59580,
+48743,59575,59574,N,59579,48741,N,N,49243,N,59576,59581,59578,59577,N,48742,N,
+49241,N,60506,49237,N,60507,N,N,60505,N,49240,49238,49242,N,49239,N,N,N,N,N,
+61253,N,61258,61254,61257,49659,N,60884,61256,61255,N,49988,49986,49989,49987,
+61864,61865,61866,49990,N,N,N,62378,50240,62376,N,50241,62375,62377,50174,
+62801,62798,N,62799,62800,63090,50518,N,50517,N,63348,63347,50616,N,N,N,50659,
+50761,50784,63832,63918,63919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44471,56493,N,N,57569,
+58572,58573,48099,N,48100,59582,48744,N,N,49660,N,61867,N,49991,62381,50242,
+62380,62382,62379,63093,62802,62803,N,50374,N,63092,N,N,63091,N,63349,63920,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,44472,N,N,N,44473,N,N,45223,54344,N,55375,N,46776,N,
+46779,46777,56494,N,46781,N,46778,N,N,46780,N,47486,N,57570,N,N,57571,59584,N,
+47485,47521,47522,58575,N,58574,48101,N,48102,N,58576,59583,48104,48745,N,
+48103,N,N,N,49244,59585,48747,48746,59586,59589,59587,59588,48748,N,49249,
+49247,N,N,49246,60509,N,49248,N,N,60508,61259,N,60510,49245,60511,61262,61260,
+61261,61266,49995,61265,61268,61267,61264,61263,N,49661,N,N,N,N,61870,N,61869,
+49994,49992,49993,N,61868,N,62385,N,50243,N,62384,62383,50244,N,62808,62807,N,
+62805,N,62804,50376,50375,62809,63350,50617,63095,50519,63094,62806,N,63351,
+50660,N,50785,63833,N,63921,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44474,55376,61269,44475,
+N,N,58578,58577,60512,N,N,61271,N,61270,N,49996,62386,62387,50377,N,N,63922,
+45224,46783,46782,57572,57574,47524,57573,47523,47525,57575,N,N,N,58580,58582,
+58581,N,58584,N,N,N,48105,58583,58579,N,N,N,58585,N,59596,N,59599,59601,59591,
+59595,59592,48750,48753,48755,59593,59594,48754,59597,59600,59598,48756,N,
+48752,59590,48749,N,48751,N,N,49251,60518,60516,60515,N,60521,N,60520,60519,N,
+60514,49250,60513,N,60517,49252,N,N,61274,N,61278,61275,61277,61276,61273,
+61279,61282,61280,61281,49728,49662,61272,61283,61875,61878,61880,61879,N,
+61873,61877,61872,N,61874,49997,61871,N,61876,N,N,62400,62389,50245,N,N,50246,
+62388,62393,62399,62391,62398,N,62395,N,62394,62397,62392,62390,N,62396,N,
+62816,62814,50378,62813,62819,62817,N,50379,62812,62810,N,62811,50381,62815,
+50380,62818,63096,63102,N,N,63097,50523,63137,50522,63101,63100,50521,63099,
+50520,63098,N,63357,63393,63358,N,63355,50619,63352,63356,63395,N,63394,63353,
+63354,50618,63570,50663,N,63571,50661,50662,N,N,63699,50762,63862,N,50794,N,
+63923,50795,63924,63925,63939,63938,50810,63949,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,45225,N,N,57577,N,57576,N,48106,48107,58586,N,59602,60524,N,N,
+48757,49253,60522,N,60525,49254,N,61284,60523,61881,49998,62401,N,N,N,62822,
+62820,N,N,62821,N,N,63138,N,50524,63396,50666,50620,50664,50665,63700,50786,N,
+45226,N,N,N,61882,N,N,54345,N,47526,N,58587,N,N,48108,58588,N,N,N,59604,59603,
+49256,48758,48759,N,59607,59606,59605,N,N,60526,60529,N,60528,60527,49255,
+61288,61286,61285,61287,N,49999,61884,61885,50000,N,61883,N,62403,62402,62405,
+50247,62404,N,62823,62825,62824,N,N,63139,63142,63140,63141,63397,50621,N,N,N,
+63572,63573,63574,N,50763,50787,63926,45227,N,48760,49257,61886,N,63398,N,N,
+63940,54346,N,50811,45228,60530,N,61887,N,62406,N,N,63143,63399,45229,N,58589,
+58590,N,48109,48110,59609,48762,48761,59608,N,61289,N,61888,61890,61889,50003,
+50002,50001,N,50526,63144,N,50525,63401,63400,N,50764,63701,46013,57578,N,N,N,
+58593,58591,58592,N,N,59618,N,59613,59610,59617,N,N,N,59619,N,N,48764,59616,
+59612,N,N,59611,59615,59614,48763,N,N,60541,60536,60534,60577,60535,N,60531,N,
+60537,N,N,60532,61298,60533,60578,N,N,N,N,N,N,N,60540,49258,60539,60538,N,
+60542,N,N,N,N,61290,61293,N,N,61292,N,61300,61295,61299,N,61297,61296,61294,N,
+61291,N,49731,49730,N,49732,49729,61301,N,N,N,N,N,61896,61899,N,61897,61901,N,
+N,N,61902,N,61894,50008,61895,N,61893,61900,N,61892,61891,50007,50005,50004,N,
+N,N,N,N,N,N,N,61898,62415,62421,50250,62416,N,62419,62423,50251,62418,N,62410,
+N,62409,62422,62413,N,62411,62420,62412,50249,50248,N,62407,62408,62417,N,N,N,
+62414,N,N,N,N,N,N,62828,62831,N,N,N,N,50006,62829,62835,62833,62827,62838,N,
+62826,N,50383,62834,N,N,N,62830,50382,62837,N,N,62836,N,N,N,N,63147,63146,N,N,
+N,63153,N,63149,63152,50528,N,N,63150,63151,N,63145,63148,50527,N,N,N,50623,
+63412,63407,63411,N,63414,63410,N,63406,N,50625,63409,63413,50624,63404,62832,
+63408,N,N,63405,N,63402,N,63403,50622,63578,63580,63583,63579,63584,N,63577,N,
+63575,N,50667,63581,50669,50668,63576,63582,N,N,N,N,63706,50765,63707,N,63705,
+63702,N,N,63704,63703,63834,N,N,N,N,63836,63835,N,N,63865,N,63864,63863,63866,
+N,50803,50804,63946,63950,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,46014,56495,57581,N,47527,57579,N,N,57580,N,N,N,58594,58595,48113,48111,
+58596,48112,59624,N,59627,59621,59628,59620,59622,N,59623,59626,N,N,48801,
+59631,59630,48765,59625,59629,48766,N,N,N,N,N,N,60588,N,49263,N,60583,49259,N,
+60580,60586,60589,N,49264,N,60585,60582,60590,60581,N,60587,49260,N,60579,
+49261,N,49262,60584,N,N,N,61353,61306,61307,61310,61308,N,61302,N,N,61305,
+61349,61309,N,N,49733,N,61351,61348,49734,61350,61303,61346,61347,N,61345,N,N,
+N,N,61906,61908,61911,N,N,61905,N,50009,61913,61904,61914,N,61910,61912,61916,
+61909,61917,61907,61903,50010,N,61915,50011,50253,N,N,N,N,N,61304,62449,62440,
+50255,62436,50256,N,N,62445,62439,62429,50254,62442,62437,62438,N,62424,62431,
+62446,N,62443,N,62435,N,62447,62430,62425,62444,N,62427,62441,62432,62448,
+62428,50252,62426,62433,62434,N,N,N,62845,N,62843,N,62882,N,62894,62885,62844,
+62840,62887,62846,62883,62842,62890,62839,62881,62886,62888,62891,62841,N,
+62895,62896,62889,62893,62884,N,63169,63172,N,50529,N,63171,63176,63174,50530,
+63165,63155,63154,50532,63167,63168,63164,63156,N,63161,62892,N,63157,50531,
+63163,N,63162,N,63158,63170,N,63159,63419,63173,63175,63166,63160,63420,63422,
+63416,50626,N,63429,63427,50627,63426,63425,63418,63415,63421,63430,63417,
+63423,N,63593,63598,63588,63591,50670,63595,N,63602,63424,N,63589,63599,63603,
+63594,63587,63597,N,63596,63601,63600,63428,63592,63586,63590,50766,50767,
+63585,N,63718,63709,63717,63714,63715,63708,63711,63719,63713,63712,63710,N,
+63716,N,63837,N,63838,N,63840,63839,63842,63841,63868,63867,63927,N,63928,N,
+63941,50808,50812,N,63951,50813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,46015,N,N,N,50384,63177,N,
+50768,50769,N,46016,57582,N,47528,59632,N,N,60592,60593,60591,61355,61354,
+49735,61919,61356,61918,N,N,62451,50257,50259,62450,N,N,50258,N,62897,62899,
+62898,63178,50533,N,50671,63720,63843,N,N,63954,46017,N,58597,N,48802,N,N,N,
+60595,60594,N,61357,N,N,N,50260,50385,63431,63947,N,N,N,46018,48114,N,48803,N,
+62452,N,63604,46784,N,N,N,N,61358,N,N,N,50788,46785,48804,49736,63605,46786,N,
+59633,49266,60596,60597,N,49265,N,61359,49740,49738,49739,49737,61920,50012,N,
+N,N,62901,62900,62903,62902,50386,N,N,63179,N,63181,63180,50534,63432,N,63606,
+63607,50672,63844,63869,50805,N,56496,60598,61360,62453,57583,N,61361,61922,
+61921,N,N,N,N,63608,50770,N,63845,63870,N,N,N,47529,59634,59635,N,60599,47530,
+N,50013,61923,N,63183,50535,63184,63182,63609,N,63721,N,47531,N,61364,61363,
+61362,61924,N,N,61928,61927,61926,61925,50014,62454,62905,50387,62904,63185,
+63435,63434,50628,63433,63612,63611,63610,N,N,48115,N,60600,49741,N,62455,
+62456,63436,63613,N,N,63722,63846,63929,63956,48116,49742,61929,62457,63186,
+63614,N,N,48806,N,61365,61930,62458,62459,62460,62910,N,62906,50536,62909,
+62908,50388,62907,50390,N,50389,63188,63187,50537,50538,N,N,50630,63437,50629,
+N,63651,63652,63650,63649,50772,N,63723,63724,63725,50771,63847,63850,63849,
+63848,N,N,63955,N,N,N,N,N,N,N,N,N,N,N,N,N,N,49267,N,N,50021,62911,63189,N,
+50631,63438,N,N,63957,N,N,N,49268,N,N,N,61366,N,63439,N,63905,51530,56828,
+41290,41303,N,41305,41307,41311,41312,41315,41316,41319,41320,41323,41324,
+41327,41328,41331,41332,41335,41336,41339,41340,N,N,N,N,41414,41415,41418,
+41419,41416,41417,41308,41293,N,41295,N,41297,41298,41299,41300,N,41341,41342,
+41377,41378,41379,41380,41420,41421,41422,41438,41439,41440,41441,41442,N,N,
+41548,41549,41550,41289,N,41389,41539,41544,41390,N,41309,41310,41391,41423,
+41281,41424,41284,41537,41647,41648,41649,41650,41651,41652,41653,41654,41655,
+41656,41287,41286,41429,41431,41430,41288,41545,41679,41680,41681,41682,41683,
+41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696,
+41697,41698,41699,41700,41701,41702,41703,41704,N,41538,N,N,41412,N,41705,
+41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718,
+41719,41720,41721,41722,41723,41724,41725,41726,41792,41793,41794,41795,41313,
+41301,41314,N,N,N,N,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41411,
+};
+
+static const struct unim_index big5_encmap[256] = {
+{__big5_encmap+0,162,247},{0,0,0},{__big5_encmap+86,199,217},{__big5_encmap+
+105,145,201},{__big5_encmap+162,1,81},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{__big5_encmap+243,19,62},{__big5_encmap+287,3,153},{
+__big5_encmap+438,26,191},{0,0,0},{__big5_encmap+604,96,125},{__big5_encmap+
+634,0,229},{__big5_encmap+864,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+926,0,254},{__big5_encmap+1181,
+5,41},{__big5_encmap+1218,163,163},{__big5_encmap+1219,142,213},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+1291,0,255},{
+__big5_encmap+1547,0,254},{__big5_encmap+1802,0,255},{__big5_encmap+2058,0,253
+},{__big5_encmap+2312,0,255},{__big5_encmap+2568,5,252},{__big5_encmap+2816,1,
+255},{__big5_encmap+3071,1,255},{__big5_encmap+3326,0,255},{__big5_encmap+3582
+,1,253},{__big5_encmap+3835,0,255},{__big5_encmap+4091,3,255},{__big5_encmap+
+4344,0,255},{__big5_encmap+4600,1,250},{__big5_encmap+4850,1,255},{
+__big5_encmap+5105,0,255},{__big5_encmap+5361,2,255},{__big5_encmap+5615,1,255
+},{__big5_encmap+5870,0,255},{__big5_encmap+6126,0,255},{__big5_encmap+6382,0,
+255},{__big5_encmap+6638,0,249},{__big5_encmap+6888,6,255},{__big5_encmap+7138
+,0,253},{__big5_encmap+7392,0,255},{__big5_encmap+7648,0,255},{__big5_encmap+
+7904,18,253},{__big5_encmap+8140,4,255},{__big5_encmap+8392,0,252},{
+__big5_encmap+8645,0,255},{__big5_encmap+8901,0,249},{__big5_encmap+9151,0,253
+},{__big5_encmap+9405,0,255},{__big5_encmap+9661,0,255},{__big5_encmap+9917,0,
+255},{__big5_encmap+10173,0,255},{__big5_encmap+10429,1,255},{__big5_encmap+
+10684,0,255},{__big5_encmap+10940,0,255},{__big5_encmap+11196,0,255},{
+__big5_encmap+11452,0,254},{__big5_encmap+11707,1,253},{__big5_encmap+11960,2,
+255},{__big5_encmap+12214,1,251},{__big5_encmap+12465,0,255},{__big5_encmap+
+12721,0,255},{__big5_encmap+12977,0,254},{__big5_encmap+13232,0,251},{
+__big5_encmap+13484,3,156},{__big5_encmap+13638,54,255},{__big5_encmap+13840,
+0,254},{__big5_encmap+14095,0,255},{__big5_encmap+14351,0,254},{__big5_encmap+
+14606,0,255},{__big5_encmap+14862,1,255},{__big5_encmap+15117,0,255},{
+__big5_encmap+15373,0,254},{__big5_encmap+15628,0,255},{__big5_encmap+15884,0,
+254},{__big5_encmap+16139,1,255},{__big5_encmap+16394,0,255},{__big5_encmap+
+16650,0,159},{__big5_encmap+16810,55,254},{__big5_encmap+17010,0,255},{
+__big5_encmap+17266,0,255},{__big5_encmap+17522,0,255},{__big5_encmap+17778,0,
+255},{__big5_encmap+18034,0,255},{__big5_encmap+18290,0,255},{__big5_encmap+
+18546,0,255},{__big5_encmap+18802,0,131},{__big5_encmap+18934,119,229},{
+__big5_encmap+19045,28,255},{__big5_encmap+19273,0,255},{__big5_encmap+19529,
+0,254},{__big5_encmap+19784,0,255},{__big5_encmap+20040,1,254},{__big5_encmap+
+20294,1,253},{__big5_encmap+20547,5,255},{__big5_encmap+20798,0,255},{
+__big5_encmap+21054,0,255},{__big5_encmap+21310,0,164},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{__big5_encmap+21475,12,13},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+21477,48,
+107},{__big5_encmap+21537,1,227},
+};
+
+static const ucs2_t __cp950ext_decmap[224] = {
+8231,U,U,U,U,U,U,U,U,65105,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,U,U,U,U,U,175,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,
+U,U,U,U,U,U,U,65374,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8853,8857,8725,65128,U,65509,
+U,65504,65505,8364,30849,37561,35023,22715,24658,31911,23290,9556,9574,9559,
+9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,9575,9563,
+9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,9584,9583,
+9619,
+};
+
+static const struct dbcs_index cp950ext_decmap[256] = {
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+0,69,243
+},{__cp950ext_decmap+175,65,71},{__cp950ext_decmap+182,225,225},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+183,214,254
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+};
+
+static const DBCHAR __cp950ext_encmap[581] = {
+41410,41285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41953,41537,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+41458,N,N,N,41459,63992,63974,63983,63965,63976,63985,63967,63980,63989,63971,
+63982,63991,63973,N,63986,63968,N,63988,63970,63975,63984,63966,63981,63990,
+63972,N,63987,63969,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,63998,63961,63964,63962,63958,63963,63960,63959,41294,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538,41470,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41536,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41443,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
+N,N,N,41542,41543,N,N,N,41540,
+};
+
+static const struct unim_index cp950ext_encmap[256] = {
+{__cp950ext_encmap+0,175,175},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
+{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+1,39,172},{0,
+0,0},{__cp950ext_encmap+135,21,153},{0,0,0},{0,0,0},{__cp950ext_encmap+268,81,
+147},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{__cp950ext_encmap+335,187,187},{0,0,0},{__cp950ext_encmap+
+336,250,250},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+337,
+82,82},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+338,129,129},{0,0,0},{
+0,0,0},{0,0,0},{__cp950ext_encmap+339,167,167},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+
+340,207,207},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{__cp950ext_encmap+341,185,185},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{
+0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0
+},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,
+0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+342,81,104},{
+__cp950ext_encmap+366,15,229},
+};
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.c b/sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.c
new file mode 100644
index 000000000..7c6b98935
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.c
@@ -0,0 +1,1793 @@
+/*
+ * multibytecodec.c: Common Multibyte Codec Implementation
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+#include "multibytecodec.h"
+
+typedef struct {
+ const Py_UNICODE *inbuf, *inbuf_top, *inbuf_end;
+ unsigned char *outbuf, *outbuf_end;
+ PyObject *excobj, *outobj;
+} MultibyteEncodeBuffer;
+
+typedef struct {
+ const unsigned char *inbuf, *inbuf_top, *inbuf_end;
+ Py_UNICODE *outbuf, *outbuf_end;
+ PyObject *excobj, *outobj;
+} MultibyteDecodeBuffer;
+
+PyDoc_STRVAR(MultibyteCodec_Encode__doc__,
+"I.encode(unicode[, errors]) -> (string, length consumed)\n\
+\n\
+Return an encoded string version of `unicode'. errors may be given to\n\
+set a different error handling scheme. Default is 'strict' meaning that\n\
+encoding errors raise a UnicodeEncodeError. Other possible values are\n\
+'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\
+registered with codecs.register_error that can handle UnicodeEncodeErrors.");
+
+PyDoc_STRVAR(MultibyteCodec_Decode__doc__,
+"I.decode(string[, errors]) -> (unicodeobject, length consumed)\n\
+\n\
+Decodes `string' using I, an MultibyteCodec instance. errors may be given\n\
+to set a different error handling scheme. Default is 'strict' meaning\n\
+that encoding errors raise a UnicodeDecodeError. Other possible values\n\
+are 'ignore' and 'replace' as well as any other name registerd with\n\
+codecs.register_error that is able to handle UnicodeDecodeErrors.");
+
+static char *codeckwarglist[] = {"input", "errors", NULL};
+static char *incnewkwarglist[] = {"errors", NULL};
+static char *incrementalkwarglist[] = {"input", "final", NULL};
+static char *streamkwarglist[] = {"stream", "errors", NULL};
+
+static PyObject *multibytecodec_encode(MultibyteCodec *,
+ MultibyteCodec_State *, const Py_UNICODE **, Py_ssize_t,
+ PyObject *, int);
+
+#define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */
+
+static PyObject *
+make_tuple(PyObject *object, Py_ssize_t len)
+{
+ PyObject *v, *w;
+
+ if (object == NULL)
+ return NULL;
+
+ v = PyTuple_New(2);
+ if (v == NULL) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(v, 0, object);
+
+ w = PyInt_FromSsize_t(len);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(v, 1, w);
+
+ return v;
+}
+
+static PyObject *
+internal_error_callback(const char *errors)
+{
+ if (errors == NULL || strcmp(errors, "strict") == 0)
+ return ERROR_STRICT;
+ else if (strcmp(errors, "ignore") == 0)
+ return ERROR_IGNORE;
+ else if (strcmp(errors, "replace") == 0)
+ return ERROR_REPLACE;
+ else
+ return PyString_FromString(errors);
+}
+
+static PyObject *
+call_error_callback(PyObject *errors, PyObject *exc)
+{
+ PyObject *args, *cb, *r;
+
+ assert(PyString_Check(errors));
+ cb = PyCodec_LookupError(PyString_AS_STRING(errors));
+ if (cb == NULL)
+ return NULL;
+
+ args = PyTuple_New(1);
+ if (args == NULL) {
+ Py_DECREF(cb);
+ return NULL;
+ }
+
+ PyTuple_SET_ITEM(args, 0, exc);
+ Py_INCREF(exc);
+
+ r = PyObject_CallObject(cb, args);
+ Py_DECREF(args);
+ Py_DECREF(cb);
+ return r;
+}
+
+static PyObject *
+codecctx_errors_get(MultibyteStatefulCodecContext *self)
+{
+ const char *errors;
+
+ if (self->errors == ERROR_STRICT)
+ errors = "strict";
+ else if (self->errors == ERROR_IGNORE)
+ errors = "ignore";
+ else if (self->errors == ERROR_REPLACE)
+ errors = "replace";
+ else {
+ Py_INCREF(self->errors);
+ return self->errors;
+ }
+
+ return PyString_FromString(errors);
+}
+
+static int
+codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value,
+ void *closure)
+{
+ PyObject *cb;
+
+ if (!PyString_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "errors must be a string");
+ return -1;
+ }
+
+ cb = internal_error_callback(PyString_AS_STRING(value));
+ if (cb == NULL)
+ return -1;
+
+ ERROR_DECREF(self->errors);
+ self->errors = cb;
+ return 0;
+}
+
+/* This getset handlers list is used by all the stateful codec objects */
+static PyGetSetDef codecctx_getsets[] = {
+ {"errors", (getter)codecctx_errors_get,
+ (setter)codecctx_errors_set,
+ PyDoc_STR("how to treat errors")},
+ {NULL,}
+};
+
+static int
+expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize)
+{
+ Py_ssize_t orgpos, orgsize;
+
+ orgpos = (Py_ssize_t)((char *)buf->outbuf -
+ PyString_AS_STRING(buf->outobj));
+ orgsize = PyString_GET_SIZE(buf->outobj);
+ if (_PyString_Resize(&buf->outobj, orgsize + (
+ esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1)
+ return -1;
+
+ buf->outbuf = (unsigned char *)PyString_AS_STRING(buf->outobj) +orgpos;
+ buf->outbuf_end = (unsigned char *)PyString_AS_STRING(buf->outobj)
+ + PyString_GET_SIZE(buf->outobj);
+
+ return 0;
+}
+#define REQUIRE_ENCODEBUFFER(buf, s) { \
+ if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end) \
+ if (expand_encodebuffer(buf, s) == -1) \
+ goto errorexit; \
+}
+
+static int
+expand_decodebuffer(MultibyteDecodeBuffer *buf, Py_ssize_t esize)
+{
+ Py_ssize_t orgpos, orgsize;
+
+ orgpos = (Py_ssize_t)(buf->outbuf - PyUnicode_AS_UNICODE(buf->outobj));
+ orgsize = PyUnicode_GET_SIZE(buf->outobj);
+ if (PyUnicode_Resize(&buf->outobj, orgsize + (
+ esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1)
+ return -1;
+
+ buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj) + orgpos;
+ buf->outbuf_end = PyUnicode_AS_UNICODE(buf->outobj)
+ + PyUnicode_GET_SIZE(buf->outobj);
+
+ return 0;
+}
+#define REQUIRE_DECODEBUFFER(buf, s) { \
+ if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end) \
+ if (expand_decodebuffer(buf, s) == -1) \
+ goto errorexit; \
+}
+
+
+/**
+ * MultibyteCodec object
+ */
+
+static int
+multibytecodec_encerror(MultibyteCodec *codec,
+ MultibyteCodec_State *state,
+ MultibyteEncodeBuffer *buf,
+ PyObject *errors, Py_ssize_t e)
+{
+ PyObject *retobj = NULL, *retstr = NULL, *tobj;
+ Py_ssize_t retstrsize, newpos;
+ Py_ssize_t esize, start, end;
+ const char *reason;
+
+ if (e > 0) {
+ reason = "illegal multibyte sequence";
+ esize = e;
+ }
+ else {
+ switch (e) {
+ case MBERR_TOOSMALL:
+ REQUIRE_ENCODEBUFFER(buf, -1);
+ return 0; /* retry it */
+ case MBERR_TOOFEW:
+ reason = "incomplete multibyte sequence";
+ esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+ break;
+ case MBERR_INTERNAL:
+ PyErr_SetString(PyExc_RuntimeError,
+ "internal codec error");
+ return -1;
+ default:
+ PyErr_SetString(PyExc_RuntimeError,
+ "unknown runtime error");
+ return -1;
+ }
+ }
+
+ if (errors == ERROR_REPLACE) {
+ const Py_UNICODE replchar = '?', *inbuf = &replchar;
+ Py_ssize_t r;
+
+ for (;;) {
+ Py_ssize_t outleft;
+
+ outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf);
+ r = codec->encode(state, codec->config, &inbuf, 1,
+ &buf->outbuf, outleft, 0);
+ if (r == MBERR_TOOSMALL) {
+ REQUIRE_ENCODEBUFFER(buf, -1);
+ continue;
+ }
+ else
+ break;
+ }
+
+ if (r != 0) {
+ REQUIRE_ENCODEBUFFER(buf, 1);
+ *buf->outbuf++ = '?';
+ }
+ }
+ if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) {
+ buf->inbuf += esize;
+ return 0;
+ }
+
+ start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top);
+ end = start + esize;
+
+ /* use cached exception object if available */
+ if (buf->excobj == NULL) {
+ buf->excobj = PyUnicodeEncodeError_Create(codec->encoding,
+ buf->inbuf_top,
+ buf->inbuf_end - buf->inbuf_top,
+ start, end, reason);
+ if (buf->excobj == NULL)
+ goto errorexit;
+ }
+ else
+ if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 ||
+ PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 ||
+ PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0)
+ goto errorexit;
+
+ if (errors == ERROR_STRICT) {
+ PyCodec_StrictErrors(buf->excobj);
+ goto errorexit;
+ }
+
+ retobj = call_error_callback(errors, buf->excobj);
+ if (retobj == NULL)
+ goto errorexit;
+
+ if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
+ !PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) ||
+ !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) ||
+ PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoding error handler must return "
+ "(unicode, int) tuple");
+ goto errorexit;
+ }
+
+ {
+ const Py_UNICODE *uraw = PyUnicode_AS_UNICODE(tobj);
+
+ retstr = multibytecodec_encode(codec, state, &uraw,
+ PyUnicode_GET_SIZE(tobj), ERROR_STRICT,
+ MBENC_FLUSH);
+ if (retstr == NULL)
+ goto errorexit;
+ }
+
+ retstrsize = PyString_GET_SIZE(retstr);
+ REQUIRE_ENCODEBUFFER(buf, retstrsize);
+
+ memcpy(buf->outbuf, PyString_AS_STRING(retstr), retstrsize);
+ buf->outbuf += retstrsize;
+
+ newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
+ if (newpos < 0 && !PyErr_Occurred())
+ newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
+ if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
+ PyErr_Clear();
+ PyErr_Format(PyExc_IndexError,
+ "position %zd from error handler out of bounds",
+ newpos);
+ goto errorexit;
+ }
+ buf->inbuf = buf->inbuf_top + newpos;
+
+ Py_DECREF(retobj);
+ Py_DECREF(retstr);
+ return 0;
+
+errorexit:
+ Py_XDECREF(retobj);
+ Py_XDECREF(retstr);
+ return -1;
+}
+
+static int
+multibytecodec_decerror(MultibyteCodec *codec,
+ MultibyteCodec_State *state,
+ MultibyteDecodeBuffer *buf,
+ PyObject *errors, Py_ssize_t e)
+{
+ PyObject *retobj = NULL, *retuni = NULL;
+ Py_ssize_t retunisize, newpos;
+ const char *reason;
+ Py_ssize_t esize, start, end;
+
+ if (e > 0) {
+ reason = "illegal multibyte sequence";
+ esize = e;
+ }
+ else {
+ switch (e) {
+ case MBERR_TOOSMALL:
+ REQUIRE_DECODEBUFFER(buf, -1);
+ return 0; /* retry it */
+ case MBERR_TOOFEW:
+ reason = "incomplete multibyte sequence";
+ esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+ break;
+ case MBERR_INTERNAL:
+ PyErr_SetString(PyExc_RuntimeError,
+ "internal codec error");
+ return -1;
+ default:
+ PyErr_SetString(PyExc_RuntimeError,
+ "unknown runtime error");
+ return -1;
+ }
+ }
+
+ if (errors == ERROR_REPLACE) {
+ REQUIRE_DECODEBUFFER(buf, 1);
+ *buf->outbuf++ = Py_UNICODE_REPLACEMENT_CHARACTER;
+ }
+ if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) {
+ buf->inbuf += esize;
+ return 0;
+ }
+
+ start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top);
+ end = start + esize;
+
+ /* use cached exception object if available */
+ if (buf->excobj == NULL) {
+ buf->excobj = PyUnicodeDecodeError_Create(codec->encoding,
+ (const char *)buf->inbuf_top,
+ (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top),
+ start, end, reason);
+ if (buf->excobj == NULL)
+ goto errorexit;
+ }
+ else
+ if (PyUnicodeDecodeError_SetStart(buf->excobj, start) ||
+ PyUnicodeDecodeError_SetEnd(buf->excobj, end) ||
+ PyUnicodeDecodeError_SetReason(buf->excobj, reason))
+ goto errorexit;
+
+ if (errors == ERROR_STRICT) {
+ PyCodec_StrictErrors(buf->excobj);
+ goto errorexit;
+ }
+
+ retobj = call_error_callback(errors, buf->excobj);
+ if (retobj == NULL)
+ goto errorexit;
+
+ if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
+ !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) ||
+ !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) ||
+ PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) {
+ PyErr_SetString(PyExc_TypeError,
+ "decoding error handler must return "
+ "(unicode, int) tuple");
+ goto errorexit;
+ }
+
+ retunisize = PyUnicode_GET_SIZE(retuni);
+ if (retunisize > 0) {
+ REQUIRE_DECODEBUFFER(buf, retunisize);
+ memcpy((char *)buf->outbuf, PyUnicode_AS_DATA(retuni),
+ retunisize * Py_UNICODE_SIZE);
+ buf->outbuf += retunisize;
+ }
+
+ newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
+ if (newpos < 0 && !PyErr_Occurred())
+ newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
+ if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
+ PyErr_Clear();
+ PyErr_Format(PyExc_IndexError,
+ "position %zd from error handler out of bounds",
+ newpos);
+ goto errorexit;
+ }
+ buf->inbuf = buf->inbuf_top + newpos;
+ Py_DECREF(retobj);
+ return 0;
+
+errorexit:
+ Py_XDECREF(retobj);
+ return -1;
+}
+
+static PyObject *
+multibytecodec_encode(MultibyteCodec *codec,
+ MultibyteCodec_State *state,
+ const Py_UNICODE **data, Py_ssize_t datalen,
+ PyObject *errors, int flags)
+{
+ MultibyteEncodeBuffer buf;
+ Py_ssize_t finalsize, r = 0;
+
+ if (datalen == 0)
+ return PyString_FromString("");
+
+ buf.excobj = NULL;
+ buf.inbuf = buf.inbuf_top = *data;
+ buf.inbuf_end = buf.inbuf_top + datalen;
+ buf.outobj = PyString_FromStringAndSize(NULL, datalen * 2 + 16);
+ if (buf.outobj == NULL)
+ goto errorexit;
+ buf.outbuf = (unsigned char *)PyString_AS_STRING(buf.outobj);
+ buf.outbuf_end = buf.outbuf + PyString_GET_SIZE(buf.outobj);
+
+ while (buf.inbuf < buf.inbuf_end) {
+ Py_ssize_t inleft, outleft;
+
+ /* we don't reuse inleft and outleft here.
+ * error callbacks can relocate the cursor anywhere on buffer*/
+ inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf);
+ outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
+ r = codec->encode(state, codec->config, &buf.inbuf, inleft,
+ &buf.outbuf, outleft, flags);
+ *data = buf.inbuf;
+ if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH)))
+ break;
+ else if (multibytecodec_encerror(codec, state, &buf, errors,r))
+ goto errorexit;
+ else if (r == MBERR_TOOFEW)
+ break;
+ }
+
+ if (codec->encreset != NULL)
+ for (;;) {
+ Py_ssize_t outleft;
+
+ outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
+ r = codec->encreset(state, codec->config, &buf.outbuf,
+ outleft);
+ if (r == 0)
+ break;
+ else if (multibytecodec_encerror(codec, state,
+ &buf, errors, r))
+ goto errorexit;
+ }
+
+ finalsize = (Py_ssize_t)((char *)buf.outbuf -
+ PyString_AS_STRING(buf.outobj));
+
+ if (finalsize != PyString_GET_SIZE(buf.outobj))
+ if (_PyString_Resize(&buf.outobj, finalsize) == -1)
+ goto errorexit;
+
+ Py_XDECREF(buf.excobj);
+ return buf.outobj;
+
+errorexit:
+ Py_XDECREF(buf.excobj);
+ Py_XDECREF(buf.outobj);
+ return NULL;
+}
+
+static PyObject *
+MultibyteCodec_Encode(MultibyteCodecObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ MultibyteCodec_State state;
+ Py_UNICODE *data;
+ PyObject *errorcb, *r, *arg, *ucvt;
+ const char *errors = NULL;
+ Py_ssize_t datalen;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode",
+ codeckwarglist, &arg, &errors))
+ return NULL;
+
+ if (PyUnicode_Check(arg))
+ ucvt = NULL;
+ else {
+ arg = ucvt = PyObject_Unicode(arg);
+ if (arg == NULL)
+ return NULL;
+ else if (!PyUnicode_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "couldn't convert the object to unicode.");
+ Py_DECREF(ucvt);
+ return NULL;
+ }
+ }
+
+ data = PyUnicode_AS_UNICODE(arg);
+ datalen = PyUnicode_GET_SIZE(arg);
+
+ errorcb = internal_error_callback(errors);
+ if (errorcb == NULL) {
+ Py_XDECREF(ucvt);
+ return NULL;
+ }
+
+ if (self->codec->encinit != NULL &&
+ self->codec->encinit(&state, self->codec->config) != 0)
+ goto errorexit;
+ r = multibytecodec_encode(self->codec, &state,
+ (const Py_UNICODE **)&data, datalen, errorcb,
+ MBENC_FLUSH | MBENC_RESET);
+ if (r == NULL)
+ goto errorexit;
+
+ ERROR_DECREF(errorcb);
+ Py_XDECREF(ucvt);
+ return make_tuple(r, datalen);
+
+errorexit:
+ ERROR_DECREF(errorcb);
+ Py_XDECREF(ucvt);
+ return NULL;
+}
+
+static PyObject *
+MultibyteCodec_Decode(MultibyteCodecObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ MultibyteCodec_State state;
+ MultibyteDecodeBuffer buf;
+ PyObject *errorcb;
+ const char *data, *errors = NULL;
+ Py_ssize_t datalen, finalsize;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|z:decode",
+ codeckwarglist, &data, &datalen, &errors))
+ return NULL;
+
+ errorcb = internal_error_callback(errors);
+ if (errorcb == NULL)
+ return NULL;
+
+ if (datalen == 0) {
+ ERROR_DECREF(errorcb);
+ return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0);
+ }
+
+ buf.excobj = NULL;
+ buf.inbuf = buf.inbuf_top = (unsigned char *)data;
+ buf.inbuf_end = buf.inbuf_top + datalen;
+ buf.outobj = PyUnicode_FromUnicode(NULL, datalen);
+ if (buf.outobj == NULL)
+ goto errorexit;
+ buf.outbuf = PyUnicode_AS_UNICODE(buf.outobj);
+ buf.outbuf_end = buf.outbuf + PyUnicode_GET_SIZE(buf.outobj);
+
+ if (self->codec->decinit != NULL &&
+ self->codec->decinit(&state, self->codec->config) != 0)
+ goto errorexit;
+
+ while (buf.inbuf < buf.inbuf_end) {
+ Py_ssize_t inleft, outleft, r;
+
+ inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf);
+ outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
+
+ r = self->codec->decode(&state, self->codec->config,
+ &buf.inbuf, inleft, &buf.outbuf, outleft);
+ if (r == 0)
+ break;
+ else if (multibytecodec_decerror(self->codec, &state,
+ &buf, errorcb, r))
+ goto errorexit;
+ }
+
+ finalsize = (Py_ssize_t)(buf.outbuf -
+ PyUnicode_AS_UNICODE(buf.outobj));
+
+ if (finalsize != PyUnicode_GET_SIZE(buf.outobj))
+ if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
+ goto errorexit;
+
+ Py_XDECREF(buf.excobj);
+ ERROR_DECREF(errorcb);
+ return make_tuple(buf.outobj, datalen);
+
+errorexit:
+ ERROR_DECREF(errorcb);
+ Py_XDECREF(buf.excobj);
+ Py_XDECREF(buf.outobj);
+
+ return NULL;
+}
+
+static struct PyMethodDef multibytecodec_methods[] = {
+ {"encode", (PyCFunction)MultibyteCodec_Encode,
+ METH_VARARGS | METH_KEYWORDS,
+ MultibyteCodec_Encode__doc__},
+ {"decode", (PyCFunction)MultibyteCodec_Decode,
+ METH_VARARGS | METH_KEYWORDS,
+ MultibyteCodec_Decode__doc__},
+ {NULL, NULL},
+};
+
+static void
+multibytecodec_dealloc(MultibyteCodecObject *self)
+{
+ PyObject_Del(self);
+}
+
+static PyTypeObject MultibyteCodec_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "MultibyteCodec", /* tp_name */
+ sizeof(MultibyteCodecObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)multibytecodec_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iterext */
+ multibytecodec_methods, /* tp_methods */
+};
+
+
+/**
+ * Utility functions for stateful codec mechanism
+ */
+
+#define STATEFUL_DCTX(o) ((MultibyteStatefulDecoderContext *)(o))
+#define STATEFUL_ECTX(o) ((MultibyteStatefulEncoderContext *)(o))
+
+static PyObject *
+encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx,
+ PyObject *unistr, int final)
+{
+ PyObject *ucvt, *r = NULL;
+ Py_UNICODE *inbuf, *inbuf_end, *inbuf_tmp = NULL;
+ Py_ssize_t datalen, origpending;
+
+ if (PyUnicode_Check(unistr))
+ ucvt = NULL;
+ else {
+ unistr = ucvt = PyObject_Unicode(unistr);
+ if (unistr == NULL)
+ return NULL;
+ else if (!PyUnicode_Check(unistr)) {
+ PyErr_SetString(PyExc_TypeError,
+ "couldn't convert the object to unicode.");
+ Py_DECREF(ucvt);
+ return NULL;
+ }
+ }
+
+ datalen = PyUnicode_GET_SIZE(unistr);
+ origpending = ctx->pendingsize;
+
+ if (origpending > 0) {
+ inbuf_tmp = PyMem_New(Py_UNICODE, datalen + ctx->pendingsize);
+ if (inbuf_tmp == NULL)
+ goto errorexit;
+ memcpy(inbuf_tmp, ctx->pending,
+ Py_UNICODE_SIZE * ctx->pendingsize);
+ memcpy(inbuf_tmp + ctx->pendingsize,
+ PyUnicode_AS_UNICODE(unistr),
+ Py_UNICODE_SIZE * datalen);
+ datalen += ctx->pendingsize;
+ ctx->pendingsize = 0;
+ inbuf = inbuf_tmp;
+ }
+ else
+ inbuf = (Py_UNICODE *)PyUnicode_AS_UNICODE(unistr);
+
+ inbuf_end = inbuf + datalen;
+
+ r = multibytecodec_encode(ctx->codec, &ctx->state,
+ (const Py_UNICODE **)&inbuf,
+ datalen, ctx->errors, final ? MBENC_FLUSH : 0);
+ if (r == NULL) {
+ /* recover the original pending buffer */
+ if (origpending > 0)
+ memcpy(ctx->pending, inbuf_tmp,
+ Py_UNICODE_SIZE * origpending);
+ ctx->pendingsize = origpending;
+ goto errorexit;
+ }
+
+ if (inbuf < inbuf_end) {
+ ctx->pendingsize = (Py_ssize_t)(inbuf_end - inbuf);
+ if (ctx->pendingsize > MAXENCPENDING) {
+ /* normal codecs can't reach here */
+ ctx->pendingsize = 0;
+ PyErr_SetString(PyExc_UnicodeError,
+ "pending buffer overflow");
+ goto errorexit;
+ }
+ memcpy(ctx->pending, inbuf,
+ ctx->pendingsize * Py_UNICODE_SIZE);
+ }
+
+ if (inbuf_tmp != NULL)
+ PyMem_Del(inbuf_tmp);
+ Py_XDECREF(ucvt);
+ return r;
+
+errorexit:
+ if (inbuf_tmp != NULL)
+ PyMem_Del(inbuf_tmp);
+ Py_XDECREF(r);
+ Py_XDECREF(ucvt);
+ return NULL;
+}
+
+static int
+decoder_append_pending(MultibyteStatefulDecoderContext *ctx,
+ MultibyteDecodeBuffer *buf)
+{
+ Py_ssize_t npendings;
+
+ npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+ if (npendings + ctx->pendingsize > MAXDECPENDING) {
+ PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
+ return -1;
+ }
+ memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings);
+ ctx->pendingsize += npendings;
+ return 0;
+}
+
+static int
+decoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data,
+ Py_ssize_t size)
+{
+ buf->inbuf = buf->inbuf_top = (const unsigned char *)data;
+ buf->inbuf_end = buf->inbuf_top + size;
+ if (buf->outobj == NULL) { /* only if outobj is not allocated yet */
+ buf->outobj = PyUnicode_FromUnicode(NULL, size);
+ if (buf->outobj == NULL)
+ return -1;
+ buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj);
+ buf->outbuf_end = buf->outbuf +
+ PyUnicode_GET_SIZE(buf->outobj);
+ }
+
+ return 0;
+}
+
+static int
+decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx,
+ MultibyteDecodeBuffer *buf)
+{
+ while (buf->inbuf < buf->inbuf_end) {
+ Py_ssize_t inleft, outleft;
+ Py_ssize_t r;
+
+ inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
+ outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf);
+
+ r = ctx->codec->decode(&ctx->state, ctx->codec->config,
+ &buf->inbuf, inleft, &buf->outbuf, outleft);
+ if (r == 0 || r == MBERR_TOOFEW)
+ break;
+ else if (multibytecodec_decerror(ctx->codec, &ctx->state,
+ buf, ctx->errors, r))
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * MultibyteIncrementalEncoder object
+ */
+
+static PyObject *
+mbiencoder_encode(MultibyteIncrementalEncoderObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ PyObject *data;
+ int final = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode",
+ incrementalkwarglist, &data, &final))
+ return NULL;
+
+ return encoder_encode_stateful(STATEFUL_ECTX(self), data, final);
+}
+
+static PyObject *
+mbiencoder_reset(MultibyteIncrementalEncoderObject *self)
+{
+ if (self->codec->decreset != NULL &&
+ self->codec->decreset(&self->state, self->codec->config) != 0)
+ return NULL;
+ self->pendingsize = 0;
+
+ Py_RETURN_NONE;
+}
+
+static struct PyMethodDef mbiencoder_methods[] = {
+ {"encode", (PyCFunction)mbiencoder_encode,
+ METH_VARARGS | METH_KEYWORDS, NULL},
+ {"reset", (PyCFunction)mbiencoder_reset,
+ METH_NOARGS, NULL},
+ {NULL, NULL},
+};
+
+static PyObject *
+mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ MultibyteIncrementalEncoderObject *self;
+ PyObject *codec = NULL;
+ char *errors = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder",
+ incnewkwarglist, &errors))
+ return NULL;
+
+ self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ codec = PyObject_GetAttrString((PyObject *)type, "codec");
+ if (codec == NULL)
+ goto errorexit;
+ if (!MultibyteCodec_Check(codec)) {
+ PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+ goto errorexit;
+ }
+
+ self->codec = ((MultibyteCodecObject *)codec)->codec;
+ self->pendingsize = 0;
+ self->errors = internal_error_callback(errors);
+ if (self->errors == NULL)
+ goto errorexit;
+ if (self->codec->encinit != NULL &&
+ self->codec->encinit(&self->state, self->codec->config) != 0)
+ goto errorexit;
+
+ Py_DECREF(codec);
+ return (PyObject *)self;
+
+errorexit:
+ Py_XDECREF(self);
+ Py_XDECREF(codec);
+ return NULL;
+}
+
+static int
+mbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return 0;
+}
+
+static int
+mbiencoder_traverse(MultibyteIncrementalEncoderObject *self,
+ visitproc visit, void *arg)
+{
+ if (ERROR_ISCUSTOM(self->errors))
+ Py_VISIT(self->errors);
+ return 0;
+}
+
+static void
+mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ ERROR_DECREF(self->errors);
+ self->ob_type->tp_free(self);
+}
+
+static PyTypeObject MultibyteIncrementalEncoder_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "MultibyteIncrementalEncoder", /* tp_name */
+ sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)mbiencoder_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+ | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)mbiencoder_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iterext */
+ mbiencoder_methods, /* tp_methods */
+ 0, /* tp_members */
+ codecctx_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ mbiencoder_init, /* tp_init */
+ 0, /* tp_alloc */
+ mbiencoder_new, /* tp_new */
+};
+
+
+/**
+ * MultibyteIncrementalDecoder object
+ */
+
+static PyObject *
+mbidecoder_decode(MultibyteIncrementalDecoderObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ MultibyteDecodeBuffer buf;
+ char *data, *wdata;
+ Py_ssize_t wsize, finalsize = 0, size, origpending;
+ int final = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "t#|i:decode",
+ incrementalkwarglist, &data, &size, &final))
+ return NULL;
+
+ buf.outobj = buf.excobj = NULL;
+ origpending = self->pendingsize;
+
+ if (self->pendingsize == 0) {
+ wsize = size;
+ wdata = data;
+ }
+ else {
+ wsize = size + self->pendingsize;
+ wdata = PyMem_Malloc(wsize);
+ if (wdata == NULL)
+ goto errorexit;
+ memcpy(wdata, self->pending, self->pendingsize);
+ memcpy(wdata + self->pendingsize, data, size);
+ self->pendingsize = 0;
+ }
+
+ if (decoder_prepare_buffer(&buf, wdata, wsize) != 0)
+ goto errorexit;
+
+ if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf))
+ goto errorexit;
+
+ if (final && buf.inbuf < buf.inbuf_end) {
+ if (multibytecodec_decerror(self->codec, &self->state,
+ &buf, self->errors, MBERR_TOOFEW)) {
+ /* recover the original pending buffer */
+ memcpy(self->pending, wdata, origpending);
+ self->pendingsize = origpending;
+ goto errorexit;
+ }
+ }
+
+ if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */
+ if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0)
+ goto errorexit;
+ }
+
+ finalsize = (Py_ssize_t)(buf.outbuf - PyUnicode_AS_UNICODE(buf.outobj));
+ if (finalsize != PyUnicode_GET_SIZE(buf.outobj))
+ if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
+ goto errorexit;
+
+ if (wdata != data)
+ PyMem_Del(wdata);
+ Py_XDECREF(buf.excobj);
+ return buf.outobj;
+
+errorexit:
+ if (wdata != NULL && wdata != data)
+ PyMem_Del(wdata);
+ Py_XDECREF(buf.excobj);
+ Py_XDECREF(buf.outobj);
+ return NULL;
+}
+
+static PyObject *
+mbidecoder_reset(MultibyteIncrementalDecoderObject *self)
+{
+ if (self->codec->decreset != NULL &&
+ self->codec->decreset(&self->state, self->codec->config) != 0)
+ return NULL;
+ self->pendingsize = 0;
+
+ Py_RETURN_NONE;
+}
+
+static struct PyMethodDef mbidecoder_methods[] = {
+ {"decode", (PyCFunction)mbidecoder_decode,
+ METH_VARARGS | METH_KEYWORDS, NULL},
+ {"reset", (PyCFunction)mbidecoder_reset,
+ METH_NOARGS, NULL},
+ {NULL, NULL},
+};
+
+static PyObject *
+mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ MultibyteIncrementalDecoderObject *self;
+ PyObject *codec = NULL;
+ char *errors = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder",
+ incnewkwarglist, &errors))
+ return NULL;
+
+ self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ codec = PyObject_GetAttrString((PyObject *)type, "codec");
+ if (codec == NULL)
+ goto errorexit;
+ if (!MultibyteCodec_Check(codec)) {
+ PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+ goto errorexit;
+ }
+
+ self->codec = ((MultibyteCodecObject *)codec)->codec;
+ self->pendingsize = 0;
+ self->errors = internal_error_callback(errors);
+ if (self->errors == NULL)
+ goto errorexit;
+ if (self->codec->decinit != NULL &&
+ self->codec->decinit(&self->state, self->codec->config) != 0)
+ goto errorexit;
+
+ Py_DECREF(codec);
+ return (PyObject *)self;
+
+errorexit:
+ Py_XDECREF(self);
+ Py_XDECREF(codec);
+ return NULL;
+}
+
+static int
+mbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return 0;
+}
+
+static int
+mbidecoder_traverse(MultibyteIncrementalDecoderObject *self,
+ visitproc visit, void *arg)
+{
+ if (ERROR_ISCUSTOM(self->errors))
+ Py_VISIT(self->errors);
+ return 0;
+}
+
+static void
+mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ ERROR_DECREF(self->errors);
+ self->ob_type->tp_free(self);
+}
+
+static PyTypeObject MultibyteIncrementalDecoder_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "MultibyteIncrementalDecoder", /* tp_name */
+ sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)mbidecoder_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+ | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)mbidecoder_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iterext */
+ mbidecoder_methods, /* tp_methods */
+ 0, /* tp_members */
+ codecctx_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ mbidecoder_init, /* tp_init */
+ 0, /* tp_alloc */
+ mbidecoder_new, /* tp_new */
+};
+
+
+/**
+ * MultibyteStreamReader object
+ */
+
+static PyObject *
+mbstreamreader_iread(MultibyteStreamReaderObject *self,
+ const char *method, Py_ssize_t sizehint)
+{
+ MultibyteDecodeBuffer buf;
+ PyObject *cres;
+ Py_ssize_t rsize, finalsize = 0;
+
+ if (sizehint == 0)
+ return PyUnicode_FromUnicode(NULL, 0);
+
+ buf.outobj = buf.excobj = NULL;
+ cres = NULL;
+
+ for (;;) {
+ if (sizehint < 0)
+ cres = PyObject_CallMethod(self->stream,
+ (char *)method, NULL);
+ else
+ cres = PyObject_CallMethod(self->stream,
+ (char *)method, "i", sizehint);
+ if (cres == NULL)
+ goto errorexit;
+
+ if (!PyString_Check(cres)) {
+ PyErr_SetString(PyExc_TypeError,
+ "stream function returned a "
+ "non-string object");
+ goto errorexit;
+ }
+
+ if (self->pendingsize > 0) {
+ PyObject *ctr;
+ char *ctrdata;
+
+ rsize = PyString_GET_SIZE(cres) + self->pendingsize;
+ ctr = PyString_FromStringAndSize(NULL, rsize);
+ if (ctr == NULL)
+ goto errorexit;
+ ctrdata = PyString_AS_STRING(ctr);
+ memcpy(ctrdata, self->pending, self->pendingsize);
+ memcpy(ctrdata + self->pendingsize,
+ PyString_AS_STRING(cres),
+ PyString_GET_SIZE(cres));
+ Py_DECREF(cres);
+ cres = ctr;
+ self->pendingsize = 0;
+ }
+
+ rsize = PyString_GET_SIZE(cres);
+ if (decoder_prepare_buffer(&buf, PyString_AS_STRING(cres),
+ rsize) != 0)
+ goto errorexit;
+
+ if (rsize > 0 && decoder_feed_buffer(
+ (MultibyteStatefulDecoderContext *)self, &buf))
+ goto errorexit;
+
+ if (rsize == 0 || sizehint < 0) { /* end of file */
+ if (buf.inbuf < buf.inbuf_end &&
+ multibytecodec_decerror(self->codec, &self->state,
+ &buf, self->errors, MBERR_TOOFEW))
+ goto errorexit;
+ }
+
+ if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */
+ if (decoder_append_pending(STATEFUL_DCTX(self),
+ &buf) != 0)
+ goto errorexit;
+ }
+
+ finalsize = (Py_ssize_t)(buf.outbuf -
+ PyUnicode_AS_UNICODE(buf.outobj));
+ Py_DECREF(cres);
+ cres = NULL;
+
+ if (sizehint < 0 || finalsize != 0 || rsize == 0)
+ break;
+
+ sizehint = 1; /* read 1 more byte and retry */
+ }
+
+ if (finalsize != PyUnicode_GET_SIZE(buf.outobj))
+ if (PyUnicode_Resize(&buf.outobj, finalsize) == -1)
+ goto errorexit;
+
+ Py_XDECREF(cres);
+ Py_XDECREF(buf.excobj);
+ return buf.outobj;
+
+errorexit:
+ Py_XDECREF(cres);
+ Py_XDECREF(buf.excobj);
+ Py_XDECREF(buf.outobj);
+ return NULL;
+}
+
+static PyObject *
+mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args)
+{
+ PyObject *sizeobj = NULL;
+ Py_ssize_t size;
+
+ if (!PyArg_UnpackTuple(args, "read", 0, 1, &sizeobj))
+ return NULL;
+
+ if (sizeobj == Py_None || sizeobj == NULL)
+ size = -1;
+ else if (PyInt_Check(sizeobj))
+ size = PyInt_AsSsize_t(sizeobj);
+ else {
+ PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
+ return NULL;
+ }
+
+ return mbstreamreader_iread(self, "read", size);
+}
+
+static PyObject *
+mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args)
+{
+ PyObject *sizeobj = NULL;
+ Py_ssize_t size;
+
+ if (!PyArg_UnpackTuple(args, "readline", 0, 1, &sizeobj))
+ return NULL;
+
+ if (sizeobj == Py_None || sizeobj == NULL)
+ size = -1;
+ else if (PyInt_Check(sizeobj))
+ size = PyInt_AsSsize_t(sizeobj);
+ else {
+ PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
+ return NULL;
+ }
+
+ return mbstreamreader_iread(self, "readline", size);
+}
+
+static PyObject *
+mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args)
+{
+ PyObject *sizehintobj = NULL, *r, *sr;
+ Py_ssize_t sizehint;
+
+ if (!PyArg_UnpackTuple(args, "readlines", 0, 1, &sizehintobj))
+ return NULL;
+
+ if (sizehintobj == Py_None || sizehintobj == NULL)
+ sizehint = -1;
+ else if (PyInt_Check(sizehintobj))
+ sizehint = PyInt_AsSsize_t(sizehintobj);
+ else {
+ PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
+ return NULL;
+ }
+
+ r = mbstreamreader_iread(self, "read", sizehint);
+ if (r == NULL)
+ return NULL;
+
+ sr = PyUnicode_Splitlines(r, 1);
+ Py_DECREF(r);
+ return sr;
+}
+
+static PyObject *
+mbstreamreader_reset(MultibyteStreamReaderObject *self)
+{
+ if (self->codec->decreset != NULL &&
+ self->codec->decreset(&self->state, self->codec->config) != 0)
+ return NULL;
+ self->pendingsize = 0;
+
+ Py_RETURN_NONE;
+}
+
+static struct PyMethodDef mbstreamreader_methods[] = {
+ {"read", (PyCFunction)mbstreamreader_read,
+ METH_VARARGS, NULL},
+ {"readline", (PyCFunction)mbstreamreader_readline,
+ METH_VARARGS, NULL},
+ {"readlines", (PyCFunction)mbstreamreader_readlines,
+ METH_VARARGS, NULL},
+ {"reset", (PyCFunction)mbstreamreader_reset,
+ METH_NOARGS, NULL},
+ {NULL, NULL},
+};
+
+static PyMemberDef mbstreamreader_members[] = {
+ {"stream", T_OBJECT,
+ offsetof(MultibyteStreamReaderObject, stream),
+ READONLY, NULL},
+ {NULL,}
+};
+
+static PyObject *
+mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ MultibyteStreamReaderObject *self;
+ PyObject *stream, *codec = NULL;
+ char *errors = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader",
+ streamkwarglist, &stream, &errors))
+ return NULL;
+
+ self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ codec = PyObject_GetAttrString((PyObject *)type, "codec");
+ if (codec == NULL)
+ goto errorexit;
+ if (!MultibyteCodec_Check(codec)) {
+ PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+ goto errorexit;
+ }
+
+ self->codec = ((MultibyteCodecObject *)codec)->codec;
+ self->stream = stream;
+ Py_INCREF(stream);
+ self->pendingsize = 0;
+ self->errors = internal_error_callback(errors);
+ if (self->errors == NULL)
+ goto errorexit;
+ if (self->codec->decinit != NULL &&
+ self->codec->decinit(&self->state, self->codec->config) != 0)
+ goto errorexit;
+
+ Py_DECREF(codec);
+ return (PyObject *)self;
+
+errorexit:
+ Py_XDECREF(self);
+ Py_XDECREF(codec);
+ return NULL;
+}
+
+static int
+mbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return 0;
+}
+
+static int
+mbstreamreader_traverse(MultibyteStreamReaderObject *self,
+ visitproc visit, void *arg)
+{
+ if (ERROR_ISCUSTOM(self->errors))
+ Py_VISIT(self->errors);
+ Py_VISIT(self->stream);
+ return 0;
+}
+
+static void
+mbstreamreader_dealloc(MultibyteStreamReaderObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ ERROR_DECREF(self->errors);
+ Py_DECREF(self->stream);
+ self->ob_type->tp_free(self);
+}
+
+static PyTypeObject MultibyteStreamReader_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "MultibyteStreamReader", /* tp_name */
+ sizeof(MultibyteStreamReaderObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)mbstreamreader_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+ | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)mbstreamreader_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iterext */
+ mbstreamreader_methods, /* tp_methods */
+ mbstreamreader_members, /* tp_members */
+ codecctx_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ mbstreamreader_init, /* tp_init */
+ 0, /* tp_alloc */
+ mbstreamreader_new, /* tp_new */
+};
+
+
+/**
+ * MultibyteStreamWriter object
+ */
+
+static int
+mbstreamwriter_iwrite(MultibyteStreamWriterObject *self,
+ PyObject *unistr)
+{
+ PyObject *str, *wr;
+
+ str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0);
+ if (str == NULL)
+ return -1;
+
+ wr = PyObject_CallMethod(self->stream, "write", "O", str);
+ Py_DECREF(str);
+ if (wr == NULL)
+ return -1;
+
+ Py_DECREF(wr);
+ return 0;
+}
+
+static PyObject *
+mbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj)
+{
+ if (mbstreamwriter_iwrite(self, strobj))
+ return NULL;
+ else
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines)
+{
+ PyObject *strobj;
+ int i, r;
+
+ if (!PySequence_Check(lines)) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg must be a sequence object");
+ return NULL;
+ }
+
+ for (i = 0; i < PySequence_Length(lines); i++) {
+ /* length can be changed even within this loop */
+ strobj = PySequence_GetItem(lines, i);
+ if (strobj == NULL)
+ return NULL;
+
+ r = mbstreamwriter_iwrite(self, strobj);
+ Py_DECREF(strobj);
+ if (r == -1)
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+mbstreamwriter_reset(MultibyteStreamWriterObject *self)
+{
+ const Py_UNICODE *pending;
+ PyObject *pwrt;
+
+ pending = self->pending;
+ pwrt = multibytecodec_encode(self->codec, &self->state,
+ &pending, self->pendingsize, self->errors,
+ MBENC_FLUSH | MBENC_RESET);
+ /* some pending buffer can be truncated when UnicodeEncodeError is
+ * raised on 'strict' mode. but, 'reset' method is designed to
+ * reset the pending buffer or states so failed string sequence
+ * ought to be missed */
+ self->pendingsize = 0;
+ if (pwrt == NULL)
+ return NULL;
+
+ if (PyString_Size(pwrt) > 0) {
+ PyObject *wr;
+ wr = PyObject_CallMethod(self->stream, "write", "O", pwrt);
+ if (wr == NULL) {
+ Py_DECREF(pwrt);
+ return NULL;
+ }
+ }
+ Py_DECREF(pwrt);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ MultibyteStreamWriterObject *self;
+ PyObject *stream, *codec = NULL;
+ char *errors = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter",
+ streamkwarglist, &stream, &errors))
+ return NULL;
+
+ self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ codec = PyObject_GetAttrString((PyObject *)type, "codec");
+ if (codec == NULL)
+ goto errorexit;
+ if (!MultibyteCodec_Check(codec)) {
+ PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
+ goto errorexit;
+ }
+
+ self->codec = ((MultibyteCodecObject *)codec)->codec;
+ self->stream = stream;
+ Py_INCREF(stream);
+ self->pendingsize = 0;
+ self->errors = internal_error_callback(errors);
+ if (self->errors == NULL)
+ goto errorexit;
+ if (self->codec->encinit != NULL &&
+ self->codec->encinit(&self->state, self->codec->config) != 0)
+ goto errorexit;
+
+ Py_DECREF(codec);
+ return (PyObject *)self;
+
+errorexit:
+ Py_XDECREF(self);
+ Py_XDECREF(codec);
+ return NULL;
+}
+
+static int
+mbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return 0;
+}
+
+static int
+mbstreamwriter_traverse(MultibyteStreamWriterObject *self,
+ visitproc visit, void *arg)
+{
+ if (ERROR_ISCUSTOM(self->errors))
+ Py_VISIT(self->errors);
+ Py_VISIT(self->stream);
+ return 0;
+}
+
+static void
+mbstreamwriter_dealloc(MultibyteStreamWriterObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ ERROR_DECREF(self->errors);
+ Py_DECREF(self->stream);
+ self->ob_type->tp_free(self);
+}
+
+static struct PyMethodDef mbstreamwriter_methods[] = {
+ {"write", (PyCFunction)mbstreamwriter_write,
+ METH_O, NULL},
+ {"writelines", (PyCFunction)mbstreamwriter_writelines,
+ METH_O, NULL},
+ {"reset", (PyCFunction)mbstreamwriter_reset,
+ METH_NOARGS, NULL},
+ {NULL, NULL},
+};
+
+static PyMemberDef mbstreamwriter_members[] = {
+ {"stream", T_OBJECT,
+ offsetof(MultibyteStreamWriterObject, stream),
+ READONLY, NULL},
+ {NULL,}
+};
+
+static PyTypeObject MultibyteStreamWriter_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "MultibyteStreamWriter", /* tp_name */
+ sizeof(MultibyteStreamWriterObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)mbstreamwriter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+ | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)mbstreamwriter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iterext */
+ mbstreamwriter_methods, /* tp_methods */
+ mbstreamwriter_members, /* tp_members */
+ codecctx_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ mbstreamwriter_init, /* tp_init */
+ 0, /* tp_alloc */
+ mbstreamwriter_new, /* tp_new */
+};
+
+
+/**
+ * Exposed factory function
+ */
+
+static PyObject *
+__create_codec(PyObject *ignore, PyObject *arg)
+{
+ MultibyteCodecObject *self;
+ MultibyteCodec *codec;
+
+ if (!PyCObject_Check(arg)) {
+ PyErr_SetString(PyExc_ValueError, "argument type invalid");
+ return NULL;
+ }
+
+ codec = PyCObject_AsVoidPtr(arg);
+ if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0)
+ return NULL;
+
+ self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type);
+ if (self == NULL)
+ return NULL;
+ self->codec = codec;
+
+ return (PyObject *)self;
+}
+
+static struct PyMethodDef __methods[] = {
+ {"__create_codec", (PyCFunction)__create_codec, METH_O},
+ {NULL, NULL},
+};
+
+PyMODINIT_FUNC
+init_multibytecodec(void)
+{
+ int i;
+ PyObject *m;
+ PyTypeObject *typelist[] = {
+ &MultibyteIncrementalEncoder_Type,
+ &MultibyteIncrementalDecoder_Type,
+ &MultibyteStreamReader_Type,
+ &MultibyteStreamWriter_Type,
+ NULL
+ };
+
+ if (PyType_Ready(&MultibyteCodec_Type) < 0)
+ return;
+
+ m = Py_InitModule("_multibytecodec", __methods);
+ if (m == NULL)
+ return;
+
+ for (i = 0; typelist[i] != NULL; i++) {
+ if (PyType_Ready(typelist[i]) < 0)
+ return;
+ Py_INCREF(typelist[i]);
+ PyModule_AddObject(m, typelist[i]->tp_name,
+ (PyObject *)typelist[i]);
+ }
+
+ if (PyErr_Occurred())
+ Py_FatalError("can't initialize the _multibytecodec module");
+}
diff --git a/sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.h b/sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.h
new file mode 100644
index 000000000..22ea5d4ab
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.h
@@ -0,0 +1,138 @@
+/*
+ * multibytecodec.h: Common Multibyte Codec Implementation
+ *
+ * Written by Hye-Shik Chang <perky@FreeBSD.org>
+ */
+
+#ifndef _PYTHON_MULTIBYTECODEC_H_
+#define _PYTHON_MULTIBYTECODEC_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef uint32_t
+typedef uint32_t ucs4_t;
+#else
+typedef unsigned int ucs4_t;
+#endif
+
+#ifdef uint16_t
+typedef uint16_t ucs2_t, DBCHAR;
+#else
+typedef unsigned short ucs2_t, DBCHAR;
+#endif
+
+typedef union {
+ void *p;
+ int i;
+ unsigned char c[8];
+ ucs2_t u2[4];
+ ucs4_t u4[2];
+} MultibyteCodec_State;
+
+typedef int (*mbcodec_init)(const void *config);
+typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
+ const void *config,
+ const Py_UNICODE **inbuf, Py_ssize_t inleft,
+ unsigned char **outbuf, Py_ssize_t outleft,
+ int flags);
+typedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
+ const void *config);
+typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
+ const void *config,
+ unsigned char **outbuf, Py_ssize_t outleft);
+typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
+ const void *config,
+ const unsigned char **inbuf, Py_ssize_t inleft,
+ Py_UNICODE **outbuf, Py_ssize_t outleft);
+typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
+ const void *config);
+typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
+ const void *config);
+
+typedef struct {
+ const char *encoding;
+ const void *config;
+ mbcodec_init codecinit;
+ mbencode_func encode;
+ mbencodeinit_func encinit;
+ mbencodereset_func encreset;
+ mbdecode_func decode;
+ mbdecodeinit_func decinit;
+ mbdecodereset_func decreset;
+} MultibyteCodec;
+
+typedef struct {
+ PyObject_HEAD
+ MultibyteCodec *codec;
+} MultibyteCodecObject;
+
+#define MultibyteCodec_Check(op) ((op)->ob_type == &MultibyteCodec_Type)
+
+#define _MultibyteStatefulCodec_HEAD \
+ PyObject_HEAD \
+ MultibyteCodec *codec; \
+ MultibyteCodec_State state; \
+ PyObject *errors;
+typedef struct {
+ _MultibyteStatefulCodec_HEAD
+} MultibyteStatefulCodecContext;
+
+#define MAXENCPENDING 2
+#define _MultibyteStatefulEncoder_HEAD \
+ _MultibyteStatefulCodec_HEAD \
+ Py_UNICODE pending[MAXENCPENDING]; \
+ Py_ssize_t pendingsize;
+typedef struct {
+ _MultibyteStatefulEncoder_HEAD
+} MultibyteStatefulEncoderContext;
+
+#define MAXDECPENDING 8
+#define _MultibyteStatefulDecoder_HEAD \
+ _MultibyteStatefulCodec_HEAD \
+ unsigned char pending[MAXDECPENDING]; \
+ Py_ssize_t pendingsize;
+typedef struct {
+ _MultibyteStatefulDecoder_HEAD
+} MultibyteStatefulDecoderContext;
+
+typedef struct {
+ _MultibyteStatefulEncoder_HEAD
+} MultibyteIncrementalEncoderObject;
+
+typedef struct {
+ _MultibyteStatefulDecoder_HEAD
+} MultibyteIncrementalDecoderObject;
+
+typedef struct {
+ _MultibyteStatefulDecoder_HEAD
+ PyObject *stream;
+} MultibyteStreamReaderObject;
+
+typedef struct {
+ _MultibyteStatefulEncoder_HEAD
+ PyObject *stream;
+} MultibyteStreamWriterObject;
+
+/* positive values for illegal sequences */
+#define MBERR_TOOSMALL (-1) /* insufficient output buffer space */
+#define MBERR_TOOFEW (-2) /* incomplete input buffer */
+#define MBERR_INTERNAL (-3) /* internal runtime error */
+
+#define ERROR_STRICT (PyObject *)(1)
+#define ERROR_IGNORE (PyObject *)(2)
+#define ERROR_REPLACE (PyObject *)(3)
+#define ERROR_ISCUSTOM(p) ((p) < ERROR_STRICT || ERROR_REPLACE < (p))
+#define ERROR_DECREF(p) do { \
+ if (p != NULL && ERROR_ISCUSTOM(p)) { \
+ Py_DECREF(p); \
+ } \
+} while (0);
+
+#define MBENC_FLUSH 0x0001 /* encode all characters encodable */
+#define MBENC_MAX MBENC_FLUSH
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/sys/src/cmd/python/Modules/clmodule.c b/sys/src/cmd/python/Modules/clmodule.c
new file mode 100644
index 000000000..a535e031f
--- /dev/null
+++ b/sys/src/cmd/python/Modules/clmodule.c
@@ -0,0 +1,2559 @@
+
+
+/* Cl objects */
+
+#define CLDEBUG
+
+#include <stdarg.h>
+#include <cl.h>
+#if defined(CL_JPEG_SOFTWARE) && !defined(CL_JPEG_COSMO)
+#include <dmedia/cl_cosmo.h>
+#endif
+#include "Python.h"
+
+typedef struct {
+ PyObject_HEAD
+ int ob_isCompressor; /* Compressor or Decompressor */
+ CL_Handle ob_compressorHdl;
+ int *ob_paramtypes;
+ int ob_nparams;
+} clobject;
+
+static PyObject *ClError; /* exception cl.error */
+
+static int error_handler_called = 0;
+
+/*
+ * We want to use the function prototypes that are available in the C
+ * compiler on the SGI. Because of that, we need to declare the first
+ * argument of the compressor and decompressor methods as "object *",
+ * even though they are really "clobject *". Therefore we cast the
+ * argument to the proper type using this macro.
+ */
+#define SELF ((clobject *) self)
+
+/********************************************************************
+ Utility routines.
+********************************************************************/
+static void
+cl_ErrorHandler(CL_Handle handle, int code, const char *fmt, ...)
+{
+ va_list ap;
+ char errbuf[BUFSIZ]; /* hopefully big enough */
+ char *p;
+
+ if (PyErr_Occurred()) /* don't change existing error */
+ return;
+ error_handler_called = 1;
+ va_start(ap, fmt);
+ vsprintf(errbuf, fmt, ap);
+ va_end(ap);
+ p = &errbuf[strlen(errbuf) - 1]; /* swat the line feed */
+ if (*p == '\n')
+ *p = 0;
+ PyErr_SetString(ClError, errbuf);
+}
+
+/*
+ * This assumes that params are always in the range 0 to some maximum.
+ */
+static int
+param_type_is_float(clobject *self, int param)
+{
+ int bufferlength;
+
+ if (self->ob_paramtypes == NULL) {
+ error_handler_called = 0;
+ bufferlength = clQueryParams(self->ob_compressorHdl, 0, 0);
+ if (error_handler_called)
+ return -1;
+
+ self->ob_paramtypes = PyMem_NEW(int, bufferlength);
+ if (self->ob_paramtypes == NULL)
+ return -1;
+ self->ob_nparams = bufferlength / 2;
+
+ (void) clQueryParams(self->ob_compressorHdl,
+ self->ob_paramtypes, bufferlength);
+ if (error_handler_called) {
+ PyMem_DEL(self->ob_paramtypes);
+ self->ob_paramtypes = NULL;
+ return -1;
+ }
+ }
+
+ if (param < 0 || param >= self->ob_nparams)
+ return -1;
+
+ if (self->ob_paramtypes[param*2 + 1] == CL_FLOATING_ENUM_VALUE ||
+ self->ob_paramtypes[param*2 + 1] == CL_FLOATING_RANGE_VALUE)
+ return 1;
+ else
+ return 0;
+}
+
+/********************************************************************
+ Single image compression/decompression.
+********************************************************************/
+static PyObject *
+cl_CompressImage(PyObject *self, PyObject *args)
+{
+ int compressionScheme, width, height, originalFormat;
+ float compressionRatio;
+ int frameBufferSize, compressedBufferSize;
+ char *frameBuffer;
+ PyObject *compressedBuffer;
+
+ if (!PyArg_ParseTuple(args, "iiiifs#", &compressionScheme,
+ &width, &height,
+ &originalFormat, &compressionRatio, &frameBuffer,
+ &frameBufferSize))
+ return NULL;
+
+ retry:
+ compressedBuffer = PyString_FromStringAndSize(NULL, frameBufferSize);
+ if (compressedBuffer == NULL)
+ return NULL;
+
+ compressedBufferSize = frameBufferSize;
+ error_handler_called = 0;
+ if (clCompressImage(compressionScheme, width, height, originalFormat,
+ compressionRatio, (void *) frameBuffer,
+ &compressedBufferSize,
+ (void *) PyString_AsString(compressedBuffer))
+ == FAILURE || error_handler_called) {
+ Py_DECREF(compressedBuffer);
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "clCompressImage failed");
+ return NULL;
+ }
+
+ if (compressedBufferSize > frameBufferSize) {
+ frameBufferSize = compressedBufferSize;
+ Py_DECREF(compressedBuffer);
+ goto retry;
+ }
+
+ if (compressedBufferSize < frameBufferSize)
+ _PyString_Resize(&compressedBuffer, compressedBufferSize);
+
+ return compressedBuffer;
+}
+
+static PyObject *
+cl_DecompressImage(PyObject *self, PyObject *args)
+{
+ int compressionScheme, width, height, originalFormat;
+ char *compressedBuffer;
+ int compressedBufferSize, frameBufferSize;
+ PyObject *frameBuffer;
+
+ if (!PyArg_ParseTuple(args, "iiiis#", &compressionScheme, &width, &height,
+ &originalFormat, &compressedBuffer,
+ &compressedBufferSize))
+ return NULL;
+
+ frameBufferSize = width * height * CL_BytesPerPixel(originalFormat);
+
+ frameBuffer = PyString_FromStringAndSize(NULL, frameBufferSize);
+ if (frameBuffer == NULL)
+ return NULL;
+
+ error_handler_called = 0;
+ if (clDecompressImage(compressionScheme, width, height, originalFormat,
+ compressedBufferSize, compressedBuffer,
+ (void *) PyString_AsString(frameBuffer))
+ == FAILURE || error_handler_called) {
+ Py_DECREF(frameBuffer);
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "clDecompressImage failed");
+ return NULL;
+ }
+
+ return frameBuffer;
+}
+
+/********************************************************************
+ Sequential compression/decompression.
+********************************************************************/
+#define CheckCompressor(self) if ((self)->ob_compressorHdl == NULL) { \
+ PyErr_SetString(PyExc_RuntimeError, "(de)compressor not active"); \
+ return NULL; \
+}
+
+static PyObject *
+doClose(clobject *self, int (*close_func)(CL_Handle))
+{
+ CheckCompressor(self);
+
+ error_handler_called = 0;
+ if ((*close_func)(self->ob_compressorHdl) == FAILURE ||
+ error_handler_called) {
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "close failed");
+ return NULL;
+ }
+
+ self->ob_compressorHdl = NULL;
+
+ if (self->ob_paramtypes)
+ PyMem_DEL(self->ob_paramtypes);
+ self->ob_paramtypes = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+clm_CloseCompressor(PyObject *self)
+{
+ return doClose(SELF, clCloseCompressor);
+}
+
+static PyObject *
+clm_CloseDecompressor(PyObject *self)
+{
+ return doClose(SELF, clCloseDecompressor);
+}
+
+static PyObject *
+clm_Compress(PyObject *self, PyObject *args)
+{
+ int numberOfFrames;
+ int frameBufferSize, compressedBufferSize, size;
+ char *frameBuffer;
+ PyObject *data;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "(is#)", &numberOfFrames,
+ &frameBuffer, &frameBufferSize))
+ return NULL;
+
+ error_handler_called = 0;
+ size = clGetParam(SELF->ob_compressorHdl, CL_COMPRESSED_BUFFER_SIZE);
+ compressedBufferSize = size;
+ if (error_handler_called)
+ return NULL;
+
+ data = PyString_FromStringAndSize(NULL, size);
+ if (data == NULL)
+ return NULL;
+
+ error_handler_called = 0;
+ if (clCompress(SELF->ob_compressorHdl, numberOfFrames,
+ (void *) frameBuffer, &compressedBufferSize,
+ (void *) PyString_AsString(data)) == FAILURE ||
+ error_handler_called) {
+ Py_DECREF(data);
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "compress failed");
+ return NULL;
+ }
+
+ if (compressedBufferSize < size)
+ if (_PyString_Resize(&data, compressedBufferSize))
+ return NULL;
+
+ if (compressedBufferSize > size) {
+ /* we didn't get all "compressed" data */
+ Py_DECREF(data);
+ PyErr_SetString(ClError,
+ "compressed data is more than fitted");
+ return NULL;
+ }
+
+ return data;
+}
+
+static PyObject *
+clm_Decompress(PyObject *self, PyObject *args)
+{
+ PyObject *data;
+ int numberOfFrames;
+ char *compressedData;
+ int compressedDataSize, dataSize;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "(is#)", &numberOfFrames, &compressedData,
+ &compressedDataSize))
+ return NULL;
+
+ error_handler_called = 0;
+ dataSize = clGetParam(SELF->ob_compressorHdl, CL_FRAME_BUFFER_SIZE);
+ if (error_handler_called)
+ return NULL;
+
+ data = PyString_FromStringAndSize(NULL, dataSize);
+ if (data == NULL)
+ return NULL;
+
+ error_handler_called = 0;
+ if (clDecompress(SELF->ob_compressorHdl, numberOfFrames,
+ compressedDataSize, (void *) compressedData,
+ (void *) PyString_AsString(data)) == FAILURE ||
+ error_handler_called) {
+ Py_DECREF(data);
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "decompress failed");
+ return NULL;
+ }
+
+ return data;
+}
+
+static PyObject *
+doParams(clobject *self, PyObject *args, int (*func)(CL_Handle, int *, int),
+ int modified)
+{
+ PyObject *list, *v;
+ int *PVbuffer;
+ int length;
+ int i;
+ float number;
+
+ CheckCompressor(self);
+
+ if (!PyArg_Parse(args, "O", &list))
+ return NULL;
+ if (!PyList_Check(list)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ length = PyList_Size(list);
+ PVbuffer = PyMem_NEW(int, length);
+ if (PVbuffer == NULL)
+ return PyErr_NoMemory();
+ for (i = 0; i < length; i++) {
+ v = PyList_GetItem(list, i);
+ if (PyFloat_Check(v)) {
+ number = PyFloat_AsDouble(v);
+ PVbuffer[i] = CL_TypeIsInt(number);
+ } else if (PyInt_Check(v)) {
+ PVbuffer[i] = PyInt_AsLong(v);
+ if ((i & 1) &&
+ param_type_is_float(self, PVbuffer[i-1]) > 0) {
+ number = PVbuffer[i];
+ PVbuffer[i] = CL_TypeIsInt(number);
+ }
+ } else {
+ PyMem_DEL(PVbuffer);
+ PyErr_BadArgument();
+ return NULL;
+ }
+ }
+
+ error_handler_called = 0;
+ (*func)(self->ob_compressorHdl, PVbuffer, length);
+ if (error_handler_called) {
+ PyMem_DEL(PVbuffer);
+ return NULL;
+ }
+
+ if (modified) {
+ for (i = 0; i < length; i++) {
+ if ((i & 1) &&
+ param_type_is_float(self, PVbuffer[i-1]) > 0) {
+ number = CL_TypeIsFloat(PVbuffer[i]);
+ v = PyFloat_FromDouble(number);
+ } else
+ v = PyInt_FromLong(PVbuffer[i]);
+ PyList_SetItem(list, i, v);
+ }
+ }
+
+ PyMem_DEL(PVbuffer);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+clm_GetParams(PyObject *self, PyObject *args)
+{
+ return doParams(SELF, args, clGetParams, 1);
+}
+
+static PyObject *
+clm_SetParams(PyObject *self, PyObject *args)
+{
+ return doParams(SELF, args, clSetParams, 0);
+}
+
+static PyObject *
+do_get(clobject *self, PyObject *args, int (*func)(CL_Handle, int))
+{
+ int paramID, value;
+ float fvalue;
+
+ CheckCompressor(self);
+
+ if (!PyArg_Parse(args, "i", &paramID))
+ return NULL;
+
+ error_handler_called = 0;
+ value = (*func)(self->ob_compressorHdl, paramID);
+ if (error_handler_called)
+ return NULL;
+
+ if (param_type_is_float(self, paramID) > 0) {
+ fvalue = CL_TypeIsFloat(value);
+ return PyFloat_FromDouble(fvalue);
+ }
+
+ return PyInt_FromLong(value);
+}
+
+static PyObject *
+clm_GetParam(PyObject *self, PyObject *args)
+{
+ return do_get(SELF, args, clGetParam);
+}
+
+static PyObject *
+clm_GetDefault(PyObject *self, PyObject *args)
+{
+ return do_get(SELF, args, clGetDefault);
+}
+
+static PyObject *
+clm_SetParam(PyObject *self, PyObject *args)
+{
+ int paramID, value;
+ float fvalue;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "(ii)", &paramID, &value)) {
+ PyErr_Clear();
+ if (!PyArg_Parse(args, "(if)", &paramID, &fvalue)) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "bad argument list (format '(ii)' or '(if)')");
+ return NULL;
+ }
+ value = CL_TypeIsInt(fvalue);
+ } else {
+ if (param_type_is_float(SELF, paramID) > 0) {
+ fvalue = value;
+ value = CL_TypeIsInt(fvalue);
+ }
+ }
+
+ error_handler_called = 0;
+ value = clSetParam(SELF->ob_compressorHdl, paramID, value);
+ if (error_handler_called)
+ return NULL;
+
+ if (param_type_is_float(SELF, paramID) > 0)
+ return PyFloat_FromDouble(CL_TypeIsFloat(value));
+ else
+ return PyInt_FromLong(value);
+}
+
+static PyObject *
+clm_GetParamID(PyObject *self, PyObject *args)
+{
+ char *name;
+ int value;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "s", &name))
+ return NULL;
+
+ error_handler_called = 0;
+ value = clGetParamID(SELF->ob_compressorHdl, name);
+ if (value == FAILURE || error_handler_called) {
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "getparamid failed");
+ return NULL;
+ }
+
+ return PyInt_FromLong(value);
+}
+
+static PyObject *
+clm_QueryParams(PyObject *self)
+{
+ int bufferlength;
+ int *PVbuffer;
+ PyObject *list;
+ int i;
+
+ CheckCompressor(SELF);
+
+ error_handler_called = 0;
+ bufferlength = clQueryParams(SELF->ob_compressorHdl, 0, 0);
+ if (error_handler_called)
+ return NULL;
+
+ PVbuffer = PyMem_NEW(int, bufferlength);
+ if (PVbuffer == NULL)
+ return PyErr_NoMemory();
+
+ bufferlength = clQueryParams(SELF->ob_compressorHdl, PVbuffer,
+ bufferlength);
+ if (error_handler_called) {
+ PyMem_DEL(PVbuffer);
+ return NULL;
+ }
+
+ list = PyList_New(bufferlength);
+ if (list == NULL) {
+ PyMem_DEL(PVbuffer);
+ return NULL;
+ }
+
+ for (i = 0; i < bufferlength; i++) {
+ if (i & 1)
+ PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+ else if (PVbuffer[i] == 0) {
+ Py_INCREF(Py_None);
+ PyList_SetItem(list, i, Py_None);
+ } else
+ PyList_SetItem(list, i,
+ PyString_FromString((char *) PVbuffer[i]));
+ }
+
+ PyMem_DEL(PVbuffer);
+
+ return list;
+}
+
+static PyObject *
+clm_GetMinMax(PyObject *self, PyObject *args)
+{
+ int param, min, max;
+ float fmin, fmax;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "i", &param))
+ return NULL;
+
+ clGetMinMax(SELF->ob_compressorHdl, param, &min, &max);
+
+ if (param_type_is_float(SELF, param) > 0) {
+ fmin = CL_TypeIsFloat(min);
+ fmax = CL_TypeIsFloat(max);
+ return Py_BuildValue("(ff)", fmin, fmax);
+ }
+
+ return Py_BuildValue("(ii)", min, max);
+}
+
+static PyObject *
+clm_GetName(PyObject *self, PyObject *args)
+{
+ int param;
+ char *name;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "i", &param))
+ return NULL;
+
+ error_handler_called = 0;
+ name = clGetName(SELF->ob_compressorHdl, param);
+ if (name == NULL || error_handler_called) {
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "getname failed");
+ return NULL;
+ }
+
+ return PyString_FromString(name);
+}
+
+static PyObject *
+clm_QuerySchemeFromHandle(PyObject *self)
+{
+ CheckCompressor(SELF);
+ return PyInt_FromLong(clQuerySchemeFromHandle(SELF->ob_compressorHdl));
+}
+
+static PyObject *
+clm_ReadHeader(PyObject *self, PyObject *args)
+{
+ char *header;
+ int headerSize;
+
+ CheckCompressor(SELF);
+
+ if (!PyArg_Parse(args, "s#", &header, &headerSize))
+ return NULL;
+
+ return PyInt_FromLong(clReadHeader(SELF->ob_compressorHdl,
+ headerSize, header));
+}
+
+static PyMethodDef compressor_methods[] = {
+ {"close", clm_CloseCompressor, METH_NOARGS}, /* alias */
+ {"CloseCompressor", clm_CloseCompressor, METH_NOARGS},
+ {"Compress", clm_Compress, METH_OLDARGS},
+ {"GetDefault", clm_GetDefault, METH_OLDARGS},
+ {"GetMinMax", clm_GetMinMax, METH_OLDARGS},
+ {"GetName", clm_GetName, METH_OLDARGS},
+ {"GetParam", clm_GetParam, METH_OLDARGS},
+ {"GetParamID", clm_GetParamID, METH_OLDARGS},
+ {"GetParams", clm_GetParams, METH_OLDARGS},
+ {"QueryParams", clm_QueryParams, METH_NOARGS},
+ {"QuerySchemeFromHandle",clm_QuerySchemeFromHandle, METH_NOARGS},
+ {"SetParam", clm_SetParam, METH_OLDARGS},
+ {"SetParams", clm_SetParams, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef decompressor_methods[] = {
+ {"close", clm_CloseDecompressor, METH_NOARGS}, /* alias */
+ {"CloseDecompressor", clm_CloseDecompressor, METH_NOARGS},
+ {"Decompress", clm_Decompress, METH_OLDARGS},
+ {"GetDefault", clm_GetDefault, METH_OLDARGS},
+ {"GetMinMax", clm_GetMinMax, METH_OLDARGS},
+ {"GetName", clm_GetName, METH_OLDARGS},
+ {"GetParam", clm_GetParam, METH_OLDARGS},
+ {"GetParamID", clm_GetParamID, METH_OLDARGS},
+ {"GetParams", clm_GetParams, METH_OLDARGS},
+ {"ReadHeader", clm_ReadHeader, METH_OLDARGS},
+ {"QueryParams", clm_QueryParams, METH_NOARGS},
+ {"QuerySchemeFromHandle",clm_QuerySchemeFromHandle, METH_NOARGS},
+ {"SetParam", clm_SetParam, METH_OLDARGS},
+ {"SetParams", clm_SetParams, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+cl_dealloc(PyObject *self)
+{
+ if (SELF->ob_compressorHdl) {
+ if (SELF->ob_isCompressor)
+ clCloseCompressor(SELF->ob_compressorHdl);
+ else
+ clCloseDecompressor(SELF->ob_compressorHdl);
+ }
+ PyObject_Del(self);
+}
+
+static PyObject *
+cl_getattr(PyObject *self, char *name)
+{
+ if (SELF->ob_isCompressor)
+ return Py_FindMethod(compressor_methods, self, name);
+ else
+ return Py_FindMethod(decompressor_methods, self, name);
+}
+
+static PyTypeObject Cltype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "cl.cl", /*tp_name*/
+ sizeof(clobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cl_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)cl_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+};
+
+static PyObject *
+doOpen(PyObject *self, PyObject *args, int (*open_func)(int, CL_Handle *),
+ int iscompressor)
+{
+ int scheme;
+ clobject *new;
+
+ if (!PyArg_ParseTuple(args, "i", &scheme))
+ return NULL;
+
+ new = PyObject_New(clobject, &Cltype);
+ if (new == NULL)
+ return NULL;
+
+ new->ob_compressorHdl = NULL;
+ new->ob_isCompressor = iscompressor;
+ new->ob_paramtypes = NULL;
+
+ error_handler_called = 0;
+ if ((*open_func)(scheme, &new->ob_compressorHdl) == FAILURE ||
+ error_handler_called) {
+ Py_DECREF(new);
+ if (!error_handler_called)
+ PyErr_SetString(ClError, "Open(De)Compressor failed");
+ return NULL;
+ }
+ return (PyObject *)new;
+}
+
+static PyObject *
+cl_OpenCompressor(PyObject *self, PyObject *args)
+{
+ return doOpen(self, args, clOpenCompressor, 1);
+}
+
+static PyObject *
+cl_OpenDecompressor(PyObject *self, PyObject *args)
+{
+ return doOpen(self, args, clOpenDecompressor, 0);
+}
+
+static PyObject *
+cl_QueryScheme(PyObject *self, PyObject *args)
+{
+ char *header;
+ int headerlen;
+ int scheme;
+
+ if (!PyArg_ParseTuple(args, "s#", &header, &headerlen))
+ return NULL;
+
+ scheme = clQueryScheme(header);
+ if (scheme < 0) {
+ PyErr_SetString(ClError, "unknown compression scheme");
+ return NULL;
+ }
+
+ return PyInt_FromLong(scheme);
+}
+
+static PyObject *
+cl_QueryMaxHeaderSize(PyObject *self, PyObject *args)
+{
+ int scheme;
+
+ if (!PyArg_ParseTuple(args, "i", &scheme))
+ return NULL;
+
+ return PyInt_FromLong(clQueryMaxHeaderSize(scheme));
+}
+
+static PyObject *
+cl_QueryAlgorithms(PyObject *self, PyObject *args)
+{
+ int algorithmMediaType;
+ int bufferlength;
+ int *PVbuffer;
+ PyObject *list;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "i", &algorithmMediaType))
+ return NULL;
+
+ error_handler_called = 0;
+ bufferlength = clQueryAlgorithms(algorithmMediaType, 0, 0);
+ if (error_handler_called)
+ return NULL;
+
+ PVbuffer = PyMem_NEW(int, bufferlength);
+ if (PVbuffer == NULL)
+ return PyErr_NoMemory();
+
+ bufferlength = clQueryAlgorithms(algorithmMediaType, PVbuffer,
+ bufferlength);
+ if (error_handler_called) {
+ PyMem_DEL(PVbuffer);
+ return NULL;
+ }
+
+ list = PyList_New(bufferlength);
+ if (list == NULL) {
+ PyMem_DEL(PVbuffer);
+ return NULL;
+ }
+
+ for (i = 0; i < bufferlength; i++) {
+ if (i & 1)
+ PyList_SetItem(list, i, PyInt_FromLong(PVbuffer[i]));
+ else if (PVbuffer[i] == 0) {
+ Py_INCREF(Py_None);
+ PyList_SetItem(list, i, Py_None);
+ } else
+ PyList_SetItem(list, i,
+ PyString_FromString((char *) PVbuffer[i]));
+ }
+
+ PyMem_DEL(PVbuffer);
+
+ return list;
+}
+
+static PyObject *
+cl_QuerySchemeFromName(PyObject *self, PyObject *args)
+{
+ int algorithmMediaType;
+ char *name;
+ int scheme;
+
+ if (!PyArg_ParseTuple(args, "is", &algorithmMediaType, &name))
+ return NULL;
+
+ error_handler_called = 0;
+ scheme = clQuerySchemeFromName(algorithmMediaType, name);
+ if (error_handler_called) {
+ PyErr_SetString(ClError, "unknown compression scheme");
+ return NULL;
+ }
+
+ return PyInt_FromLong(scheme);
+}
+
+static PyObject *
+cl_GetAlgorithmName(PyObject *self, PyObject *args)
+{
+ int scheme;
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "i", &scheme))
+ return NULL;
+
+ name = clGetAlgorithmName(scheme);
+ if (name == 0) {
+ PyErr_SetString(ClError, "unknown compression scheme");
+ return NULL;
+ }
+
+ return PyString_FromString(name);
+}
+
+static PyObject *
+do_set(PyObject *self, PyObject *args, int (*func)(int, int, int))
+{
+ int scheme, paramID, value;
+ float fvalue;
+ int is_float = 0;
+
+ if (!PyArg_ParseTuple(args, "iii", &scheme, &paramID, &value)) {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "iif", &scheme, &paramID, &fvalue)) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "bad argument list (format '(iii)' or '(iif)')");
+ return NULL;
+ }
+ value = CL_TypeIsInt(fvalue);
+ is_float = 1;
+ } else {
+ /* check some parameters which we know to be floats */
+ switch (scheme) {
+ case CL_COMPRESSION_RATIO:
+ case CL_SPEED:
+ fvalue = value;
+ value = CL_TypeIsInt(fvalue);
+ is_float = 1;
+ break;
+ }
+ }
+
+ error_handler_called = 0;
+ value = (*func)(scheme, paramID, value);
+ if (error_handler_called)
+ return NULL;
+
+ if (is_float)
+ return PyFloat_FromDouble(CL_TypeIsFloat(value));
+ else
+ return PyInt_FromLong(value);
+}
+
+static PyObject *
+cl_SetDefault(PyObject *self, PyObject *args)
+{
+ return do_set(self, args, clSetDefault);
+}
+
+static PyObject *
+cl_SetMin(PyObject *self, PyObject *args)
+{
+ return do_set(self, args, clSetMin);
+}
+
+static PyObject *
+cl_SetMax(PyObject *self, PyObject *args)
+{
+ return do_set(self, args, clSetMax);
+}
+
+#define func(name, handler) \
+static PyObject *cl_##name(PyObject *self, PyObject *args) \
+{ \
+ int x; \
+ if (!PyArg_ParseTuple(args, "i", &x)) return NULL; \
+ return Py##handler(CL_##name(x)); \
+}
+
+#define func2(name, handler) \
+static PyObject *cl_##name(PyObject *self, PyObject *args) \
+{ \
+ int a1, a2; \
+ if (!PyArg_ParseTuple(args, "ii", &a1, &a2)) return NULL; \
+ return Py##handler(CL_##name(a1, a2)); \
+}
+
+func(BytesPerSample, Int_FromLong)
+func(BytesPerPixel, Int_FromLong)
+func(AudioFormatName, String_FromString)
+func(VideoFormatName, String_FromString)
+func(AlgorithmNumber, Int_FromLong)
+func(AlgorithmType, Int_FromLong)
+func2(Algorithm, Int_FromLong)
+func(ParamNumber, Int_FromLong)
+func(ParamType, Int_FromLong)
+func2(ParamID, Int_FromLong)
+
+#ifdef CLDEBUG
+ static PyObject *
+cvt_type(PyObject *self, PyObject *args)
+{
+ int number;
+ float fnumber;
+
+ if (PyArg_Parse(args, "i", &number))
+ return PyFloat_FromDouble(CL_TypeIsFloat(number));
+ else {
+ PyErr_Clear();
+ if (PyArg_Parse(args, "f", &fnumber))
+ return PyInt_FromLong(CL_TypeIsInt(fnumber));
+ return NULL;
+ }
+}
+#endif
+
+static PyMethodDef cl_methods[] = {
+ {"CompressImage", cl_CompressImage, METH_VARARGS},
+ {"DecompressImage", cl_DecompressImage, METH_VARARGS},
+ {"GetAlgorithmName", cl_GetAlgorithmName, METH_VARARGS},
+ {"OpenCompressor", cl_OpenCompressor, METH_VARARGS},
+ {"OpenDecompressor", cl_OpenDecompressor, METH_VARARGS},
+ {"QueryAlgorithms", cl_QueryAlgorithms, METH_VARARGS},
+ {"QueryMaxHeaderSize", cl_QueryMaxHeaderSize, METH_VARARGS},
+ {"QueryScheme", cl_QueryScheme, METH_VARARGS},
+ {"QuerySchemeFromName", cl_QuerySchemeFromName, METH_VARARGS},
+ {"SetDefault", cl_SetDefault, METH_VARARGS},
+ {"SetMax", cl_SetMax, METH_VARARGS},
+ {"SetMin", cl_SetMin, METH_VARARGS},
+ {"BytesPerSample", cl_BytesPerSample, METH_VARARGS},
+ {"BytesPerPixel", cl_BytesPerPixel, METH_VARARGS},
+ {"AudioFormatName", cl_AudioFormatName, METH_VARARGS},
+ {"VideoFormatName", cl_VideoFormatName, METH_VARARGS},
+ {"AlgorithmNumber", cl_AlgorithmNumber, METH_VARARGS},
+ {"AlgorithmType", cl_AlgorithmType, METH_VARARGS},
+ {"Algorithm", cl_Algorithm, METH_VARARGS},
+ {"ParamNumber", cl_ParamNumber, METH_VARARGS},
+ {"ParamType", cl_ParamType, METH_VARARGS},
+ {"ParamID", cl_ParamID, METH_VARARGS},
+#ifdef CLDEBUG
+ {"cvt_type", cvt_type, METH_VARARGS},
+#endif
+ {NULL, NULL} /* Sentinel */
+};
+
+#ifdef CL_JPEG_SOFTWARE
+#define IRIX_5_3_LIBRARY
+#endif
+
+void
+initcl(void)
+{
+ PyObject *m, *d, *x;
+
+ m = Py_InitModule("cl", cl_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ ClError = PyErr_NewException("cl.error", NULL, NULL);
+ (void) PyDict_SetItemString(d, "error", ClError);
+
+#ifdef CL_ADDED_ALGORITHM_ERROR
+ x = PyInt_FromLong(CL_ADDED_ALGORITHM_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "ADDED_ALGORITHM_ERROR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ALAW
+ x = PyInt_FromLong(CL_ALAW);
+ if (x == NULL || PyDict_SetItemString(d, "ALAW", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ALGORITHM_ID
+ x = PyInt_FromLong(CL_ALGORITHM_ID);
+ if (x == NULL || PyDict_SetItemString(d, "ALGORITHM_ID", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ALGORITHM_TABLE_FULL
+ x = PyInt_FromLong(CL_ALGORITHM_TABLE_FULL);
+ if (x == NULL || PyDict_SetItemString(d, "ALGORITHM_TABLE_FULL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ALGORITHM_VERSION
+ x = PyInt_FromLong(CL_ALGORITHM_VERSION);
+ if (x == NULL || PyDict_SetItemString(d, "ALGORITHM_VERSION", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ALG_AUDIO
+ x = PyInt_FromLong(CL_ALG_AUDIO);
+ if (x == NULL || PyDict_SetItemString(d, "ALG_AUDIO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ALG_VIDEO
+ x = PyInt_FromLong(CL_ALG_VIDEO);
+ if (x == NULL || PyDict_SetItemString(d, "ALG_VIDEO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AUDIO
+ x = PyInt_FromLong(CL_AUDIO);
+ if (x == NULL || PyDict_SetItemString(d, "AUDIO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_BITRATE_POLICY
+ x = PyInt_FromLong(CL_AWARE_BITRATE_POLICY);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_BITRATE_POLICY", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_BITRATE_TARGET
+ x = PyInt_FromLong(CL_AWARE_BITRATE_TARGET);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_BITRATE_TARGET", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_CHANNEL_POLICY
+ x = PyInt_FromLong(CL_AWARE_CHANNEL_POLICY);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_CHANNEL_POLICY", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_CONST_QUAL
+ x = PyInt_FromLong(CL_AWARE_CONST_QUAL);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_CONST_QUAL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_ERROR
+ x = PyInt_FromLong(CL_AWARE_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_ERROR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_FIXED_RATE
+ x = PyInt_FromLong(CL_AWARE_FIXED_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_FIXED_RATE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_INDEPENDENT
+ x = PyInt_FromLong(CL_AWARE_INDEPENDENT);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_INDEPENDENT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_JOINT_STEREO
+ x = PyInt_FromLong(CL_AWARE_JOINT_STEREO);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_JOINT_STEREO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_LAYER
+ x = PyInt_FromLong(CL_AWARE_LAYER);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_LAYER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_LOSSLESS
+ x = PyInt_FromLong(CL_AWARE_LOSSLESS);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_LOSSLESS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MPEG_AUDIO
+ x = PyInt_FromLong(CL_AWARE_MPEG_AUDIO);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_MPEG_AUDIO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MPEG_LAYER_I
+ x = PyInt_FromLong(CL_AWARE_MPEG_LAYER_I);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_MPEG_LAYER_I", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MPEG_LAYER_II
+ x = PyInt_FromLong(CL_AWARE_MPEG_LAYER_II);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_MPEG_LAYER_II", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_MULTIRATE
+ x = PyInt_FromLong(CL_AWARE_MULTIRATE);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_MULTIRATE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_NOISE_MARGIN
+ x = PyInt_FromLong(CL_AWARE_NOISE_MARGIN);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_NOISE_MARGIN", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_AWARE_STEREO
+ x = PyInt_FromLong(CL_AWARE_STEREO);
+ if (x == NULL || PyDict_SetItemString(d, "AWARE_STEREO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_ALGORITHM_NAME
+ x = PyInt_FromLong(CL_BAD_ALGORITHM_NAME);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_ALGORITHM_NAME", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_ALGORITHM_TYPE
+ x = PyInt_FromLong(CL_BAD_ALGORITHM_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_ALGORITHM_TYPE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BLOCK_SIZE
+ x = PyInt_FromLong(CL_BAD_BLOCK_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BLOCK_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BOARD
+ x = PyInt_FromLong(CL_BAD_BOARD);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BOARD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFERING
+ x = PyInt_FromLong(CL_BAD_BUFFERING);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERING", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFERLENGTH_NEG
+ x = PyInt_FromLong(CL_BAD_BUFFERLENGTH_NEG);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_NEG", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFERLENGTH_ODD
+ x = PyInt_FromLong(CL_BAD_BUFFERLENGTH_ODD);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFERLENGTH_ODD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_EXISTS
+ x = PyInt_FromLong(CL_BAD_BUFFER_EXISTS);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_EXISTS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_HANDLE
+ x = PyInt_FromLong(CL_BAD_BUFFER_HANDLE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_HANDLE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_POINTER
+ x = PyInt_FromLong(CL_BAD_BUFFER_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_QUERY_SIZE
+ x = PyInt_FromLong(CL_BAD_BUFFER_QUERY_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_QUERY_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_SIZE
+ x = PyInt_FromLong(CL_BAD_BUFFER_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_SIZE_POINTER
+ x = PyInt_FromLong(CL_BAD_BUFFER_SIZE_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_SIZE_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_BUFFER_TYPE
+ x = PyInt_FromLong(CL_BAD_BUFFER_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_BUFFER_TYPE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_COMPRESSION_SCHEME
+ x = PyInt_FromLong(CL_BAD_COMPRESSION_SCHEME);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_COMPRESSION_SCHEME", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_COMPRESSOR_HANDLE
+ x = PyInt_FromLong(CL_BAD_COMPRESSOR_HANDLE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_COMPRESSOR_HANDLE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_COMPRESSOR_HANDLE_POINTER
+ x = PyInt_FromLong(CL_BAD_COMPRESSOR_HANDLE_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_COMPRESSOR_HANDLE_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_FRAME_SIZE
+ x = PyInt_FromLong(CL_BAD_FRAME_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_FRAME_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_FUNCTIONALITY
+ x = PyInt_FromLong(CL_BAD_FUNCTIONALITY);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_FUNCTIONALITY", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_FUNCTION_POINTER
+ x = PyInt_FromLong(CL_BAD_FUNCTION_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_FUNCTION_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_HEADER_SIZE
+ x = PyInt_FromLong(CL_BAD_HEADER_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_HEADER_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_INITIAL_VALUE
+ x = PyInt_FromLong(CL_BAD_INITIAL_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_INITIAL_VALUE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_INTERNAL_FORMAT
+ x = PyInt_FromLong(CL_BAD_INTERNAL_FORMAT);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_INTERNAL_FORMAT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_LICENSE
+ x = PyInt_FromLong(CL_BAD_LICENSE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_LICENSE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_MIN_GT_MAX
+ x = PyInt_FromLong(CL_BAD_MIN_GT_MAX);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_MIN_GT_MAX", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_NO_BUFFERSPACE
+ x = PyInt_FromLong(CL_BAD_NO_BUFFERSPACE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_NO_BUFFERSPACE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_NUMBER_OF_BLOCKS
+ x = PyInt_FromLong(CL_BAD_NUMBER_OF_BLOCKS);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_NUMBER_OF_BLOCKS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PARAM
+ x = PyInt_FromLong(CL_BAD_PARAM);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PARAM_ID_POINTER
+ x = PyInt_FromLong(CL_BAD_PARAM_ID_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM_ID_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PARAM_TYPE
+ x = PyInt_FromLong(CL_BAD_PARAM_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PARAM_TYPE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_POINTER
+ x = PyInt_FromLong(CL_BAD_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_PVBUFFER
+ x = PyInt_FromLong(CL_BAD_PVBUFFER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_PVBUFFER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_SCHEME_POINTER
+ x = PyInt_FromLong(CL_BAD_SCHEME_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_SCHEME_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_STREAM_HEADER
+ x = PyInt_FromLong(CL_BAD_STREAM_HEADER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_STREAM_HEADER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_STRING_POINTER
+ x = PyInt_FromLong(CL_BAD_STRING_POINTER);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_STRING_POINTER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BAD_TEXT_STRING_PTR
+ x = PyInt_FromLong(CL_BAD_TEXT_STRING_PTR);
+ if (x == NULL || PyDict_SetItemString(d, "BAD_TEXT_STRING_PTR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BEST_FIT
+ x = PyInt_FromLong(CL_BEST_FIT);
+ if (x == NULL || PyDict_SetItemString(d, "BEST_FIT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BIDIRECTIONAL
+ x = PyInt_FromLong(CL_BIDIRECTIONAL);
+ if (x == NULL || PyDict_SetItemString(d, "BIDIRECTIONAL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BITRATE
+ x = PyInt_FromLong(CL_BITRATE);
+ if (x == NULL || PyDict_SetItemString(d, "BITRATE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BITRATE_POLICY
+ x = PyInt_FromLong(CL_BITRATE_POLICY);
+ if (x == NULL || PyDict_SetItemString(d, "BITRATE_POLICY", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BITRATE_TARGET
+ x = PyInt_FromLong(CL_BITRATE_TARGET);
+ if (x == NULL || PyDict_SetItemString(d, "BITRATE_TARGET", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BITS_PER_COMPONENT
+ x = PyInt_FromLong(CL_BITS_PER_COMPONENT);
+ if (x == NULL || PyDict_SetItemString(d, "BITS_PER_COMPONENT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BLENDING
+ x = PyInt_FromLong(CL_BLENDING);
+ if (x == NULL || PyDict_SetItemString(d, "BLENDING", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BLOCK_SIZE
+ x = PyInt_FromLong(CL_BLOCK_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "BLOCK_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BOTTOM_UP
+ x = PyInt_FromLong(CL_BOTTOM_UP);
+ if (x == NULL || PyDict_SetItemString(d, "BOTTOM_UP", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BUFFER_NOT_CREATED
+ x = PyInt_FromLong(CL_BUFFER_NOT_CREATED);
+ if (x == NULL || PyDict_SetItemString(d, "BUFFER_NOT_CREATED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BUF_COMPRESSED
+ x = PyInt_FromLong(CL_BUF_COMPRESSED);
+ if (x == NULL || PyDict_SetItemString(d, "BUF_COMPRESSED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BUF_DATA
+ x = PyInt_FromLong(CL_BUF_DATA);
+ if (x == NULL || PyDict_SetItemString(d, "BUF_DATA", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_BUF_FRAME
+ x = PyInt_FromLong(CL_BUF_FRAME);
+ if (x == NULL || PyDict_SetItemString(d, "BUF_FRAME", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_CHANNEL_POLICY
+ x = PyInt_FromLong(CL_CHANNEL_POLICY);
+ if (x == NULL || PyDict_SetItemString(d, "CHANNEL_POLICY", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_CHROMA_THRESHOLD
+ x = PyInt_FromLong(CL_CHROMA_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "CHROMA_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_CODEC
+ x = PyInt_FromLong(CL_CODEC);
+ if (x == NULL || PyDict_SetItemString(d, "CODEC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COMPONENTS
+ x = PyInt_FromLong(CL_COMPONENTS);
+ if (x == NULL || PyDict_SetItemString(d, "COMPONENTS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COMPRESSED_BUFFER_SIZE
+ x = PyInt_FromLong(CL_COMPRESSED_BUFFER_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "COMPRESSED_BUFFER_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COMPRESSION_RATIO
+ x = PyInt_FromLong(CL_COMPRESSION_RATIO);
+ if (x == NULL || PyDict_SetItemString(d, "COMPRESSION_RATIO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COMPRESSOR
+ x = PyInt_FromLong(CL_COMPRESSOR);
+ if (x == NULL || PyDict_SetItemString(d, "COMPRESSOR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_CONTINUOUS_BLOCK
+ x = PyInt_FromLong(CL_CONTINUOUS_BLOCK);
+ if (x == NULL || PyDict_SetItemString(d, "CONTINUOUS_BLOCK", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_CONTINUOUS_NONBLOCK
+ x = PyInt_FromLong(CL_CONTINUOUS_NONBLOCK);
+ if (x == NULL || PyDict_SetItemString(d, "CONTINUOUS_NONBLOCK", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_CODEC_CONTROL
+ x = PyInt_FromLong(CL_COSMO_CODEC_CONTROL);
+ if (x == NULL || PyDict_SetItemString(d, "COSMO_CODEC_CONTROL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_NUM_PARAMS
+ x = PyInt_FromLong(CL_COSMO_NUM_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "COSMO_NUM_PARAMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_VALUE_BASE
+ x = PyInt_FromLong(CL_COSMO_VALUE_BASE);
+ if (x == NULL || PyDict_SetItemString(d, "COSMO_VALUE_BASE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_VIDEO_MANUAL_CONTROL
+ x = PyInt_FromLong(CL_COSMO_VIDEO_MANUAL_CONTROL);
+ if (x == NULL || PyDict_SetItemString(d, "COSMO_VIDEO_MANUAL_CONTROL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_COSMO_VIDEO_TRANSFER_MODE
+ x = PyInt_FromLong(CL_COSMO_VIDEO_TRANSFER_MODE);
+ if (x == NULL || PyDict_SetItemString(d, "COSMO_VIDEO_TRANSFER_MODE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_DATA
+ x = PyInt_FromLong(CL_DATA);
+ if (x == NULL || PyDict_SetItemString(d, "DATA", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_DECOMPRESSOR
+ x = PyInt_FromLong(CL_DECOMPRESSOR);
+ if (x == NULL || PyDict_SetItemString(d, "DECOMPRESSOR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_DSO_ERROR
+ x = PyInt_FromLong(CL_DSO_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "DSO_ERROR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_EDGE_THRESHOLD
+ x = PyInt_FromLong(CL_EDGE_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "EDGE_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ENABLE_IMAGEINFO
+ x = PyInt_FromLong(CL_ENABLE_IMAGEINFO);
+ if (x == NULL || PyDict_SetItemString(d, "ENABLE_IMAGEINFO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_END_OF_SEQUENCE
+ x = PyInt_FromLong(CL_END_OF_SEQUENCE);
+ if (x == NULL || PyDict_SetItemString(d, "END_OF_SEQUENCE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ENUM_VALUE
+ x = PyInt_FromLong(CL_ENUM_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "ENUM_VALUE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_EXACT_COMPRESSION_RATIO
+ x = PyInt_FromLong(CL_EXACT_COMPRESSION_RATIO);
+ if (x == NULL || PyDict_SetItemString(d, "EXACT_COMPRESSION_RATIO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_EXTERNAL_DEVICE
+ x = PyInt_FromLong((long) CL_EXTERNAL_DEVICE);
+ if (x == NULL || PyDict_SetItemString(d, "EXTERNAL_DEVICE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FLOATING_ENUM_VALUE
+ x = PyInt_FromLong(CL_FLOATING_ENUM_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "FLOATING_ENUM_VALUE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FLOATING_RANGE_VALUE
+ x = PyInt_FromLong(CL_FLOATING_RANGE_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "FLOATING_RANGE_VALUE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT
+ x = PyInt_FromLong(CL_FORMAT);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_ABGR
+ x = PyInt_FromLong(CL_FORMAT_ABGR);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_ABGR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_BGR
+ x = PyInt_FromLong(CL_FORMAT_BGR);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_BGR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_BGR233
+ x = PyInt_FromLong(CL_FORMAT_BGR233);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_BGR233", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_GRAYSCALE
+ x = PyInt_FromLong(CL_FORMAT_GRAYSCALE);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_GRAYSCALE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_MONO
+ x = PyInt_FromLong(CL_FORMAT_MONO);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_MONO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_RBG323
+ x = PyInt_FromLong(CL_FORMAT_RBG323);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_RBG323", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_STEREO_INTERLEAVED
+ x = PyInt_FromLong(CL_FORMAT_STEREO_INTERLEAVED);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_STEREO_INTERLEAVED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_XBGR
+ x = PyInt_FromLong(CL_FORMAT_XBGR);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_XBGR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_YCbCr
+ x = PyInt_FromLong(CL_FORMAT_YCbCr);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_YCbCr", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_YCbCr422
+ x = PyInt_FromLong(CL_FORMAT_YCbCr422);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_YCbCr422", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FORMAT_YCbCr422DC
+ x = PyInt_FromLong(CL_FORMAT_YCbCr422DC);
+ if (x == NULL || PyDict_SetItemString(d, "FORMAT_YCbCr422DC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME
+ x = PyInt_FromLong(CL_FRAME);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAMES_PER_CHUNK
+ x = PyInt_FromLong(CL_FRAMES_PER_CHUNK);
+ if (x == NULL || PyDict_SetItemString(d, "FRAMES_PER_CHUNK", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_BUFFER_SIZE
+ x = PyInt_FromLong(CL_FRAME_BUFFER_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME_BUFFER_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_BUFFER_SIZE_ZERO
+ x = PyInt_FromLong(CL_FRAME_BUFFER_SIZE_ZERO);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME_BUFFER_SIZE_ZERO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_INDEX
+ x = PyInt_FromLong(CL_FRAME_INDEX);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME_INDEX", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_RATE
+ x = PyInt_FromLong(CL_FRAME_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME_RATE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_SIZE
+ x = PyInt_FromLong(CL_FRAME_SIZE);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME_SIZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_FRAME_TYPE
+ x = PyInt_FromLong(CL_FRAME_TYPE);
+ if (x == NULL || PyDict_SetItemString(d, "FRAME_TYPE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_G711_ALAW
+ x = PyInt_FromLong(CL_G711_ALAW);
+ if (x == NULL || PyDict_SetItemString(d, "G711_ALAW", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_G711_ALAW_SOFTWARE
+ x = PyInt_FromLong(CL_G711_ALAW_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "G711_ALAW_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_G711_ULAW
+ x = PyInt_FromLong(CL_G711_ULAW);
+ if (x == NULL || PyDict_SetItemString(d, "G711_ULAW", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_G711_ULAW_SOFTWARE
+ x = PyInt_FromLong(CL_G711_ULAW_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "G711_ULAW_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_GRAYSCALE
+ x = PyInt_FromLong(CL_GRAYSCALE);
+ if (x == NULL || PyDict_SetItemString(d, "GRAYSCALE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_HDCC
+ x = PyInt_FromLong(CL_HDCC);
+ if (x == NULL || PyDict_SetItemString(d, "HDCC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_HDCC_SAMPLES_PER_TILE
+ x = PyInt_FromLong(CL_HDCC_SAMPLES_PER_TILE);
+ if (x == NULL || PyDict_SetItemString(d, "HDCC_SAMPLES_PER_TILE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_HDCC_SOFTWARE
+ x = PyInt_FromLong(CL_HDCC_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "HDCC_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_HDCC_TILE_THRESHOLD
+ x = PyInt_FromLong(CL_HDCC_TILE_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "HDCC_TILE_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_HEADER_START_CODE
+ x = PyInt_FromLong(CL_HEADER_START_CODE);
+ if (x == NULL || PyDict_SetItemString(d, "HEADER_START_CODE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGEINFO_FIELDMASK
+ x = PyInt_FromLong(CL_IMAGEINFO_FIELDMASK);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGEINFO_FIELDMASK", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_BOTTOM
+ x = PyInt_FromLong(CL_IMAGE_CROP_BOTTOM);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_BOTTOM", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_LEFT
+ x = PyInt_FromLong(CL_IMAGE_CROP_LEFT);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_LEFT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_RIGHT
+ x = PyInt_FromLong(CL_IMAGE_CROP_RIGHT);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_RIGHT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_CROP_TOP
+ x = PyInt_FromLong(CL_IMAGE_CROP_TOP);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGE_CROP_TOP", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_HEIGHT
+ x = PyInt_FromLong(CL_IMAGE_HEIGHT);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGE_HEIGHT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMAGE_WIDTH
+ x = PyInt_FromLong(CL_IMAGE_WIDTH);
+ if (x == NULL || PyDict_SetItemString(d, "IMAGE_WIDTH", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMPACT_CODEC_CONTROL
+ x = PyInt_FromLong(CL_IMPACT_CODEC_CONTROL);
+ if (x == NULL || PyDict_SetItemString(d, "IMPACT_CODEC_CONTROL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMPACT_FRAME_INTERLEAVE
+ x = PyInt_FromLong(CL_IMPACT_FRAME_INTERLEAVE);
+ if (x == NULL || PyDict_SetItemString(d, "IMPACT_FRAME_INTERLEAVE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_IMPACT_NUM_PARAMS
+ x = PyInt_FromLong(CL_IMPACT_NUM_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "IMPACT_NUM_PARAMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_INTERNAL_FORMAT
+ x = PyInt_FromLong(CL_INTERNAL_FORMAT);
+ if (x == NULL || PyDict_SetItemString(d, "INTERNAL_FORMAT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_INTERNAL_IMAGE_HEIGHT
+ x = PyInt_FromLong(CL_INTERNAL_IMAGE_HEIGHT);
+ if (x == NULL || PyDict_SetItemString(d, "INTERNAL_IMAGE_HEIGHT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_INTERNAL_IMAGE_WIDTH
+ x = PyInt_FromLong(CL_INTERNAL_IMAGE_WIDTH);
+ if (x == NULL || PyDict_SetItemString(d, "INTERNAL_IMAGE_WIDTH", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_INTRA
+ x = PyInt_FromLong(CL_INTRA);
+ if (x == NULL || PyDict_SetItemString(d, "INTRA", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG
+ x = PyInt_FromLong(CL_JPEG);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_COSMO
+ x = PyInt_FromLong(CL_JPEG_COSMO);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_COSMO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_ERROR
+ x = PyInt_FromLong(CL_JPEG_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_ERROR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_IMPACT
+ x = PyInt_FromLong(CL_JPEG_IMPACT);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_IMPACT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_NUM_PARAMS
+ x = PyInt_FromLong(CL_JPEG_NUM_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_NUM_PARAMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_QUALITY_FACTOR
+ x = PyInt_FromLong(CL_JPEG_QUALITY_FACTOR);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_QUALITY_FACTOR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_QUANTIZATION_TABLES
+ x = PyInt_FromLong(CL_JPEG_QUANTIZATION_TABLES);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_QUANTIZATION_TABLES", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_SOFTWARE
+ x = PyInt_FromLong(CL_JPEG_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_JPEG_STREAM_HEADERS
+ x = PyInt_FromLong(CL_JPEG_STREAM_HEADERS);
+ if (x == NULL || PyDict_SetItemString(d, "JPEG_STREAM_HEADERS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_KEYFRAME
+ x = PyInt_FromLong(CL_KEYFRAME);
+ if (x == NULL || PyDict_SetItemString(d, "KEYFRAME", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_KEYFRAME_DISTANCE
+ x = PyInt_FromLong(CL_KEYFRAME_DISTANCE);
+ if (x == NULL || PyDict_SetItemString(d, "KEYFRAME_DISTANCE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_LAST_FRAME_INDEX
+ x = PyInt_FromLong(CL_LAST_FRAME_INDEX);
+ if (x == NULL || PyDict_SetItemString(d, "LAST_FRAME_INDEX", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_LAYER
+ x = PyInt_FromLong(CL_LAYER);
+ if (x == NULL || PyDict_SetItemString(d, "LAYER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_LUMA_THRESHOLD
+ x = PyInt_FromLong(CL_LUMA_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "LUMA_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_AUDIO_ALGORITHMS
+ x = PyInt_FromLong(CL_MAX_NUMBER_OF_AUDIO_ALGORITHMS);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_AUDIO_ALGORITHMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_FORMATS
+ x = PyInt_FromLong(CL_MAX_NUMBER_OF_FORMATS);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_FORMATS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_ORIGINAL_FORMATS
+ x = PyInt_FromLong(CL_MAX_NUMBER_OF_ORIGINAL_FORMATS);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_ORIGINAL_FORMATS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_PARAMS
+ x = PyInt_FromLong(CL_MAX_NUMBER_OF_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_PARAMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MAX_NUMBER_OF_VIDEO_ALGORITHMS
+ x = PyInt_FromLong(CL_MAX_NUMBER_OF_VIDEO_ALGORITHMS);
+ if (x == NULL || PyDict_SetItemString(d, "MAX_NUMBER_OF_VIDEO_ALGORITHMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MONO
+ x = PyInt_FromLong(CL_MONO);
+ if (x == NULL || PyDict_SetItemString(d, "MONO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_AWARE
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_AWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_AWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_LAYER
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_LAYER);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_LAYER", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_LAYER_I
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_LAYER_I);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_LAYER_I", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_LAYER_II
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_LAYER_II);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_LAYER_II", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_DUAL
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_DUAL);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_DUAL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_JOINT
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_JOINT);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_JOINT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_SINGLE
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_SINGLE);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_SINGLE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_MODE_STEREO
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_MODE_STEREO);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_MODE_STEREO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_AUDIO_SOFTWARE
+ x = PyInt_FromLong(CL_MPEG1_AUDIO_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_AUDIO_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_END_OF_STREAM
+ x = PyInt_FromLong(CL_MPEG1_END_OF_STREAM);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_END_OF_STREAM", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_ERROR
+ x = PyInt_FromLong(CL_MPEG1_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_ERROR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_NUM_PARAMS
+ x = PyInt_FromLong(CL_MPEG1_NUM_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_NUM_PARAMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_M
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_M);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_M", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_X
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_X);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_X", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_Y
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_Y);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_B_Y", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_X
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_X);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_X", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_Y
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_Y);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_MAX_MOTION_VECTOR_LENGTH_P_Y", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_N
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_N);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_N", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS_MAXIMUM
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS_MAXIMUM);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS_MAXIMUM", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS_MEDIUM
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS_MEDIUM);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS_MEDIUM", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTNESS_NONE
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTNESS_NONE);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTNESS_NONE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG1_VIDEO_SOFTWARE
+ x = PyInt_FromLong(CL_MPEG1_VIDEO_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG1_VIDEO_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MPEG_VIDEO
+ x = PyInt_FromLong(CL_MPEG_VIDEO);
+ if (x == NULL || PyDict_SetItemString(d, "MPEG_VIDEO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MULTIRATE_AWARE
+ x = PyInt_FromLong(CL_MULTIRATE_AWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MULTIRATE_AWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC1
+ x = PyInt_FromLong(CL_MVC1);
+ if (x == NULL || PyDict_SetItemString(d, "MVC1", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC1_SOFTWARE
+ x = PyInt_FromLong(CL_MVC1_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MVC1_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2
+ x = PyInt_FromLong(CL_MVC2);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_BLENDING
+ x = PyInt_FromLong(CL_MVC2_BLENDING);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_BLENDING", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_BLENDING_OFF
+ x = PyInt_FromLong(CL_MVC2_BLENDING_OFF);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_BLENDING_OFF", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_BLENDING_ON
+ x = PyInt_FromLong(CL_MVC2_BLENDING_ON);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_BLENDING_ON", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_CHROMA_THRESHOLD
+ x = PyInt_FromLong(CL_MVC2_CHROMA_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_CHROMA_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_EDGE_THRESHOLD
+ x = PyInt_FromLong(CL_MVC2_EDGE_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_EDGE_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_ERROR
+ x = PyInt_FromLong(CL_MVC2_ERROR);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_ERROR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_LUMA_THRESHOLD
+ x = PyInt_FromLong(CL_MVC2_LUMA_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_LUMA_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC2_SOFTWARE
+ x = PyInt_FromLong(CL_MVC2_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MVC2_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC3_QUALITY_LEVEL
+ x = PyInt_FromLong(CL_MVC3_QUALITY_LEVEL);
+ if (x == NULL || PyDict_SetItemString(d, "MVC3_QUALITY_LEVEL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_MVC3_SOFTWARE
+ x = PyInt_FromLong(CL_MVC3_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "MVC3_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NEXT_NOT_AVAILABLE
+ x = PyInt_FromLong(CL_NEXT_NOT_AVAILABLE);
+ if (x == NULL || PyDict_SetItemString(d, "NEXT_NOT_AVAILABLE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NOISE_MARGIN
+ x = PyInt_FromLong(CL_NOISE_MARGIN);
+ if (x == NULL || PyDict_SetItemString(d, "NOISE_MARGIN", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NONE
+ x = PyInt_FromLong(CL_NONE);
+ if (x == NULL || PyDict_SetItemString(d, "NONE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_FORMATS
+ x = PyInt_FromLong(CL_NUMBER_OF_FORMATS);
+ if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_FORMATS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_FRAMES
+ x = PyInt_FromLong(CL_NUMBER_OF_FRAMES);
+ if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_FRAMES", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_PARAMS
+ x = PyInt_FromLong(CL_NUMBER_OF_PARAMS);
+ if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_PARAMS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_PARAMS_FREEZE
+ x = PyInt_FromLong(CL_NUMBER_OF_PARAMS_FREEZE);
+ if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_PARAMS_FREEZE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_NUMBER_OF_VIDEO_FORMATS
+ x = PyInt_FromLong(CL_NUMBER_OF_VIDEO_FORMATS);
+ if (x == NULL || PyDict_SetItemString(d, "NUMBER_OF_VIDEO_FORMATS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ORIENTATION
+ x = PyInt_FromLong(CL_ORIENTATION);
+ if (x == NULL || PyDict_SetItemString(d, "ORIENTATION", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ORIGINAL_FORMAT
+ x = PyInt_FromLong(CL_ORIGINAL_FORMAT);
+ if (x == NULL || PyDict_SetItemString(d, "ORIGINAL_FORMAT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_PARAM_OUT_OF_RANGE
+ x = PyInt_FromLong(CL_PARAM_OUT_OF_RANGE);
+ if (x == NULL || PyDict_SetItemString(d, "PARAM_OUT_OF_RANGE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_PIXEL_ASPECT
+ x = PyInt_FromLong(CL_PIXEL_ASPECT);
+ if (x == NULL || PyDict_SetItemString(d, "PIXEL_ASPECT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_PREDICTED
+ x = PyInt_FromLong(CL_PREDICTED);
+ if (x == NULL || PyDict_SetItemString(d, "PREDICTED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_PREROLL
+ x = PyInt_FromLong(CL_PREROLL);
+ if (x == NULL || PyDict_SetItemString(d, "PREROLL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_FACTOR
+ x = PyInt_FromLong(CL_QUALITY_FACTOR);
+ if (x == NULL || PyDict_SetItemString(d, "QUALITY_FACTOR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_LEVEL
+ x = PyInt_FromLong(CL_QUALITY_LEVEL);
+ if (x == NULL || PyDict_SetItemString(d, "QUALITY_LEVEL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_SPATIAL
+ x = PyInt_FromLong(CL_QUALITY_SPATIAL);
+ if (x == NULL || PyDict_SetItemString(d, "QUALITY_SPATIAL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_QUALITY_TEMPORAL
+ x = PyInt_FromLong(CL_QUALITY_TEMPORAL);
+ if (x == NULL || PyDict_SetItemString(d, "QUALITY_TEMPORAL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_QUANTIZATION_TABLES
+ x = PyInt_FromLong(CL_QUANTIZATION_TABLES);
+ if (x == NULL || PyDict_SetItemString(d, "QUANTIZATION_TABLES", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RANGE_VALUE
+ x = PyInt_FromLong(CL_RANGE_VALUE);
+ if (x == NULL || PyDict_SetItemString(d, "RANGE_VALUE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RGB
+ x = PyInt_FromLong(CL_RGB);
+ if (x == NULL || PyDict_SetItemString(d, "RGB", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RGB332
+ x = PyInt_FromLong(CL_RGB332);
+ if (x == NULL || PyDict_SetItemString(d, "RGB332", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RGB8
+ x = PyInt_FromLong(CL_RGB8);
+ if (x == NULL || PyDict_SetItemString(d, "RGB8", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RGBA
+ x = PyInt_FromLong(CL_RGBA);
+ if (x == NULL || PyDict_SetItemString(d, "RGBA", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RGBX
+ x = PyInt_FromLong(CL_RGBX);
+ if (x == NULL || PyDict_SetItemString(d, "RGBX", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RLE
+ x = PyInt_FromLong(CL_RLE);
+ if (x == NULL || PyDict_SetItemString(d, "RLE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RLE24
+ x = PyInt_FromLong(CL_RLE24);
+ if (x == NULL || PyDict_SetItemString(d, "RLE24", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RLE24_SOFTWARE
+ x = PyInt_FromLong(CL_RLE24_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "RLE24_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RLE_SOFTWARE
+ x = PyInt_FromLong(CL_RLE_SOFTWARE);
+ if (x == NULL || PyDict_SetItemString(d, "RLE_SOFTWARE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RTR
+ x = PyInt_FromLong(CL_RTR);
+ if (x == NULL || PyDict_SetItemString(d, "RTR", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RTR1
+ x = PyInt_FromLong(CL_RTR1);
+ if (x == NULL || PyDict_SetItemString(d, "RTR1", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_RTR_QUALITY_LEVEL
+ x = PyInt_FromLong(CL_RTR_QUALITY_LEVEL);
+ if (x == NULL || PyDict_SetItemString(d, "RTR_QUALITY_LEVEL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_SAMPLES_PER_TILE
+ x = PyInt_FromLong(CL_SAMPLES_PER_TILE);
+ if (x == NULL || PyDict_SetItemString(d, "SAMPLES_PER_TILE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_SCHEME_BUSY
+ x = PyInt_FromLong(CL_SCHEME_BUSY);
+ if (x == NULL || PyDict_SetItemString(d, "SCHEME_BUSY", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_SCHEME_NOT_AVAILABLE
+ x = PyInt_FromLong(CL_SCHEME_NOT_AVAILABLE);
+ if (x == NULL || PyDict_SetItemString(d, "SCHEME_NOT_AVAILABLE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_SPEED
+ x = PyInt_FromLong(CL_SPEED);
+ if (x == NULL || PyDict_SetItemString(d, "SPEED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_STEREO_INTERLEAVED
+ x = PyInt_FromLong(CL_STEREO_INTERLEAVED);
+ if (x == NULL || PyDict_SetItemString(d, "STEREO_INTERLEAVED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_STREAM_HEADERS
+ x = PyInt_FromLong(CL_STREAM_HEADERS);
+ if (x == NULL || PyDict_SetItemString(d, "STREAM_HEADERS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_TILE_THRESHOLD
+ x = PyInt_FromLong(CL_TILE_THRESHOLD);
+ if (x == NULL || PyDict_SetItemString(d, "TILE_THRESHOLD", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_TOP_DOWN
+ x = PyInt_FromLong(CL_TOP_DOWN);
+ if (x == NULL || PyDict_SetItemString(d, "TOP_DOWN", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_ULAW
+ x = PyInt_FromLong(CL_ULAW);
+ if (x == NULL || PyDict_SetItemString(d, "ULAW", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_UNCOMPRESSED
+ x = PyInt_FromLong(CL_UNCOMPRESSED);
+ if (x == NULL || PyDict_SetItemString(d, "UNCOMPRESSED", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_UNCOMPRESSED_AUDIO
+ x = PyInt_FromLong(CL_UNCOMPRESSED_AUDIO);
+ if (x == NULL || PyDict_SetItemString(d, "UNCOMPRESSED_AUDIO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_UNCOMPRESSED_VIDEO
+ x = PyInt_FromLong(CL_UNCOMPRESSED_VIDEO);
+ if (x == NULL || PyDict_SetItemString(d, "UNCOMPRESSED_VIDEO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_UNKNOWN_SCHEME
+ x = PyInt_FromLong(CL_UNKNOWN_SCHEME);
+ if (x == NULL || PyDict_SetItemString(d, "UNKNOWN_SCHEME", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_VIDEO
+ x = PyInt_FromLong(CL_VIDEO);
+ if (x == NULL || PyDict_SetItemString(d, "VIDEO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_Y
+ x = PyInt_FromLong(CL_Y);
+ if (x == NULL || PyDict_SetItemString(d, "Y", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr
+ x = PyInt_FromLong(CL_YCbCr);
+ if (x == NULL || PyDict_SetItemString(d, "YCbCr", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr422
+ x = PyInt_FromLong(CL_YCbCr422);
+ if (x == NULL || PyDict_SetItemString(d, "YCbCr422", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr422DC
+ x = PyInt_FromLong(CL_YCbCr422DC);
+ if (x == NULL || PyDict_SetItemString(d, "YCbCr422DC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YCbCr422HC
+ x = PyInt_FromLong(CL_YCbCr422HC);
+ if (x == NULL || PyDict_SetItemString(d, "YCbCr422HC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YUV
+ x = PyInt_FromLong(CL_YUV);
+ if (x == NULL || PyDict_SetItemString(d, "YUV", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YUV422
+ x = PyInt_FromLong(CL_YUV422);
+ if (x == NULL || PyDict_SetItemString(d, "YUV422", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YUV422DC
+ x = PyInt_FromLong(CL_YUV422DC);
+ if (x == NULL || PyDict_SetItemString(d, "YUV422DC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef CL_YUV422HC
+ x = PyInt_FromLong(CL_YUV422HC);
+ if (x == NULL || PyDict_SetItemString(d, "YUV422HC", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_STEREO
+ x = PyInt_FromLong(AWCMP_STEREO);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_STEREO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_JOINT_STEREO
+ x = PyInt_FromLong(AWCMP_JOINT_STEREO);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_JOINT_STEREO", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_INDEPENDENT
+ x = PyInt_FromLong(AWCMP_INDEPENDENT);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_INDEPENDENT", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_FIXED_RATE
+ x = PyInt_FromLong(AWCMP_FIXED_RATE);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_FIXED_RATE", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_CONST_QUAL
+ x = PyInt_FromLong(AWCMP_CONST_QUAL);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_CONST_QUAL", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_LOSSLESS
+ x = PyInt_FromLong(AWCMP_LOSSLESS);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_LOSSLESS", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_MPEG_LAYER_I
+ x = PyInt_FromLong(AWCMP_MPEG_LAYER_I);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_MPEG_LAYER_I", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+#ifdef AWCMP_MPEG_LAYER_II
+ x = PyInt_FromLong(AWCMP_MPEG_LAYER_II);
+ if (x == NULL || PyDict_SetItemString(d, "AWCMP_MPEG_LAYER_II", x) < 0)
+ return;
+ Py_DECREF(x);
+#endif
+
+ (void) clSetErrorHandler(cl_ErrorHandler);
+}
diff --git a/sys/src/cmd/python/Modules/cmathmodule.c b/sys/src/cmd/python/Modules/cmathmodule.c
new file mode 100644
index 000000000..ec48ce8d7
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cmathmodule.c
@@ -0,0 +1,426 @@
+/* Complex math module */
+
+/* much code borrowed from mathmodule.c */
+
+#include "Python.h"
+
+#ifndef M_PI
+#define M_PI (3.141592653589793239)
+#endif
+
+/* First, the C functions that do the real work */
+
+/* constants */
+static Py_complex c_one = {1., 0.};
+static Py_complex c_half = {0.5, 0.};
+static Py_complex c_i = {0., 1.};
+static Py_complex c_halfi = {0., 0.5};
+
+/* forward declarations */
+static Py_complex c_log(Py_complex);
+static Py_complex c_prodi(Py_complex);
+static Py_complex c_sqrt(Py_complex);
+static PyObject * math_error(void);
+
+
+static Py_complex
+c_acos(Py_complex x)
+{
+ return c_neg(c_prodi(c_log(c_sum(x,c_prod(c_i,
+ c_sqrt(c_diff(c_one,c_prod(x,x))))))));
+}
+
+PyDoc_STRVAR(c_acos_doc,
+"acos(x)\n"
+"\n"
+"Return the arc cosine of x.");
+
+
+static Py_complex
+c_acosh(Py_complex x)
+{
+ Py_complex z;
+ z = c_sqrt(c_half);
+ z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x,c_one)),
+ c_sqrt(c_diff(x,c_one)))));
+ return c_sum(z, z);
+}
+
+PyDoc_STRVAR(c_acosh_doc,
+"acosh(x)\n"
+"\n"
+"Return the hyperbolic arccosine of x.");
+
+
+static Py_complex
+c_asin(Py_complex x)
+{
+ /* -i * log[(sqrt(1-x**2) + i*x] */
+ const Py_complex squared = c_prod(x, x);
+ const Py_complex sqrt_1_minus_x_sq = c_sqrt(c_diff(c_one, squared));
+ return c_neg(c_prodi(c_log(
+ c_sum(sqrt_1_minus_x_sq, c_prodi(x))
+ ) ) );
+}
+
+PyDoc_STRVAR(c_asin_doc,
+"asin(x)\n"
+"\n"
+"Return the arc sine of x.");
+
+
+static Py_complex
+c_asinh(Py_complex x)
+{
+ Py_complex z;
+ z = c_sqrt(c_half);
+ z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x, c_i)),
+ c_sqrt(c_diff(x, c_i)))));
+ return c_sum(z, z);
+}
+
+PyDoc_STRVAR(c_asinh_doc,
+"asinh(x)\n"
+"\n"
+"Return the hyperbolic arc sine of x.");
+
+
+static Py_complex
+c_atan(Py_complex x)
+{
+ return c_prod(c_halfi,c_log(c_quot(c_sum(c_i,x),c_diff(c_i,x))));
+}
+
+PyDoc_STRVAR(c_atan_doc,
+"atan(x)\n"
+"\n"
+"Return the arc tangent of x.");
+
+
+static Py_complex
+c_atanh(Py_complex x)
+{
+ return c_prod(c_half,c_log(c_quot(c_sum(c_one,x),c_diff(c_one,x))));
+}
+
+PyDoc_STRVAR(c_atanh_doc,
+"atanh(x)\n"
+"\n"
+"Return the hyperbolic arc tangent of x.");
+
+
+static Py_complex
+c_cos(Py_complex x)
+{
+ Py_complex r;
+ r.real = cos(x.real)*cosh(x.imag);
+ r.imag = -sin(x.real)*sinh(x.imag);
+ return r;
+}
+
+PyDoc_STRVAR(c_cos_doc,
+"cos(x)\n"
+"n"
+"Return the cosine of x.");
+
+
+static Py_complex
+c_cosh(Py_complex x)
+{
+ Py_complex r;
+ r.real = cos(x.imag)*cosh(x.real);
+ r.imag = sin(x.imag)*sinh(x.real);
+ return r;
+}
+
+PyDoc_STRVAR(c_cosh_doc,
+"cosh(x)\n"
+"n"
+"Return the hyperbolic cosine of x.");
+
+
+static Py_complex
+c_exp(Py_complex x)
+{
+ Py_complex r;
+ double l = exp(x.real);
+ r.real = l*cos(x.imag);
+ r.imag = l*sin(x.imag);
+ return r;
+}
+
+PyDoc_STRVAR(c_exp_doc,
+"exp(x)\n"
+"\n"
+"Return the exponential value e**x.");
+
+
+static Py_complex
+c_log(Py_complex x)
+{
+ Py_complex r;
+ double l = hypot(x.real,x.imag);
+ r.imag = atan2(x.imag, x.real);
+ r.real = log(l);
+ return r;
+}
+
+
+static Py_complex
+c_log10(Py_complex x)
+{
+ Py_complex r;
+ double l = hypot(x.real,x.imag);
+ r.imag = atan2(x.imag, x.real)/log(10.);
+ r.real = log10(l);
+ return r;
+}
+
+PyDoc_STRVAR(c_log10_doc,
+"log10(x)\n"
+"\n"
+"Return the base-10 logarithm of x.");
+
+
+/* internal function not available from Python */
+static Py_complex
+c_prodi(Py_complex x)
+{
+ Py_complex r;
+ r.real = -x.imag;
+ r.imag = x.real;
+ return r;
+}
+
+
+static Py_complex
+c_sin(Py_complex x)
+{
+ Py_complex r;
+ r.real = sin(x.real) * cosh(x.imag);
+ r.imag = cos(x.real) * sinh(x.imag);
+ return r;
+}
+
+PyDoc_STRVAR(c_sin_doc,
+"sin(x)\n"
+"\n"
+"Return the sine of x.");
+
+
+static Py_complex
+c_sinh(Py_complex x)
+{
+ Py_complex r;
+ r.real = cos(x.imag) * sinh(x.real);
+ r.imag = sin(x.imag) * cosh(x.real);
+ return r;
+}
+
+PyDoc_STRVAR(c_sinh_doc,
+"sinh(x)\n"
+"\n"
+"Return the hyperbolic sine of x.");
+
+
+static Py_complex
+c_sqrt(Py_complex x)
+{
+ Py_complex r;
+ double s,d;
+ if (x.real == 0. && x.imag == 0.)
+ r = x;
+ else {
+ s = sqrt(0.5*(fabs(x.real) + hypot(x.real,x.imag)));
+ d = 0.5*x.imag/s;
+ if (x.real > 0.) {
+ r.real = s;
+ r.imag = d;
+ }
+ else if (x.imag >= 0.) {
+ r.real = d;
+ r.imag = s;
+ }
+ else {
+ r.real = -d;
+ r.imag = -s;
+ }
+ }
+ return r;
+}
+
+PyDoc_STRVAR(c_sqrt_doc,
+"sqrt(x)\n"
+"\n"
+"Return the square root of x.");
+
+
+static Py_complex
+c_tan(Py_complex x)
+{
+ Py_complex r;
+ double sr,cr,shi,chi;
+ double rs,is,rc,ic;
+ double d;
+ sr = sin(x.real);
+ cr = cos(x.real);
+ shi = sinh(x.imag);
+ chi = cosh(x.imag);
+ rs = sr * chi;
+ is = cr * shi;
+ rc = cr * chi;
+ ic = -sr * shi;
+ d = rc*rc + ic * ic;
+ r.real = (rs*rc + is*ic) / d;
+ r.imag = (is*rc - rs*ic) / d;
+ return r;
+}
+
+PyDoc_STRVAR(c_tan_doc,
+"tan(x)\n"
+"\n"
+"Return the tangent of x.");
+
+
+static Py_complex
+c_tanh(Py_complex x)
+{
+ Py_complex r;
+ double si,ci,shr,chr;
+ double rs,is,rc,ic;
+ double d;
+ si = sin(x.imag);
+ ci = cos(x.imag);
+ shr = sinh(x.real);
+ chr = cosh(x.real);
+ rs = ci * shr;
+ is = si * chr;
+ rc = ci * chr;
+ ic = si * shr;
+ d = rc*rc + ic*ic;
+ r.real = (rs*rc + is*ic) / d;
+ r.imag = (is*rc - rs*ic) / d;
+ return r;
+}
+
+PyDoc_STRVAR(c_tanh_doc,
+"tanh(x)\n"
+"\n"
+"Return the hyperbolic tangent of x.");
+
+static PyObject *
+cmath_log(PyObject *self, PyObject *args)
+{
+ Py_complex x;
+ Py_complex y;
+
+ if (!PyArg_ParseTuple(args, "D|D", &x, &y))
+ return NULL;
+
+ errno = 0;
+ PyFPE_START_PROTECT("complex function", return 0)
+ x = c_log(x);
+ if (PyTuple_GET_SIZE(args) == 2)
+ x = c_quot(x, c_log(y));
+ PyFPE_END_PROTECT(x)
+ if (errno != 0)
+ return math_error();
+ Py_ADJUST_ERANGE2(x.real, x.imag);
+ return PyComplex_FromCComplex(x);
+}
+
+PyDoc_STRVAR(cmath_log_doc,
+"log(x[, base]) -> the logarithm of x to the given base.\n\
+If the base not specified, returns the natural logarithm (base e) of x.");
+
+
+/* And now the glue to make them available from Python: */
+
+static PyObject *
+math_error(void)
+{
+ if (errno == EDOM)
+ PyErr_SetString(PyExc_ValueError, "math domain error");
+ else if (errno == ERANGE)
+ PyErr_SetString(PyExc_OverflowError, "math range error");
+ else /* Unexpected math error */
+ PyErr_SetFromErrno(PyExc_ValueError);
+ return NULL;
+}
+
+static PyObject *
+math_1(PyObject *args, Py_complex (*func)(Py_complex))
+{
+ Py_complex x;
+ if (!PyArg_ParseTuple(args, "D", &x))
+ return NULL;
+ errno = 0;
+ PyFPE_START_PROTECT("complex function", return 0)
+ x = (*func)(x);
+ PyFPE_END_PROTECT(x)
+ Py_ADJUST_ERANGE2(x.real, x.imag);
+ if (errno != 0)
+ return math_error();
+ else
+ return PyComplex_FromCComplex(x);
+}
+
+#define FUNC1(stubname, func) \
+ static PyObject * stubname(PyObject *self, PyObject *args) { \
+ return math_1(args, func); \
+ }
+
+FUNC1(cmath_acos, c_acos)
+FUNC1(cmath_acosh, c_acosh)
+FUNC1(cmath_asin, c_asin)
+FUNC1(cmath_asinh, c_asinh)
+FUNC1(cmath_atan, c_atan)
+FUNC1(cmath_atanh, c_atanh)
+FUNC1(cmath_cos, c_cos)
+FUNC1(cmath_cosh, c_cosh)
+FUNC1(cmath_exp, c_exp)
+FUNC1(cmath_log10, c_log10)
+FUNC1(cmath_sin, c_sin)
+FUNC1(cmath_sinh, c_sinh)
+FUNC1(cmath_sqrt, c_sqrt)
+FUNC1(cmath_tan, c_tan)
+FUNC1(cmath_tanh, c_tanh)
+
+
+PyDoc_STRVAR(module_doc,
+"This module is always available. It provides access to mathematical\n"
+"functions for complex numbers.");
+
+static PyMethodDef cmath_methods[] = {
+ {"acos", cmath_acos, METH_VARARGS, c_acos_doc},
+ {"acosh", cmath_acosh, METH_VARARGS, c_acosh_doc},
+ {"asin", cmath_asin, METH_VARARGS, c_asin_doc},
+ {"asinh", cmath_asinh, METH_VARARGS, c_asinh_doc},
+ {"atan", cmath_atan, METH_VARARGS, c_atan_doc},
+ {"atanh", cmath_atanh, METH_VARARGS, c_atanh_doc},
+ {"cos", cmath_cos, METH_VARARGS, c_cos_doc},
+ {"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc},
+ {"exp", cmath_exp, METH_VARARGS, c_exp_doc},
+ {"log", cmath_log, METH_VARARGS, cmath_log_doc},
+ {"log10", cmath_log10, METH_VARARGS, c_log10_doc},
+ {"sin", cmath_sin, METH_VARARGS, c_sin_doc},
+ {"sinh", cmath_sinh, METH_VARARGS, c_sinh_doc},
+ {"sqrt", cmath_sqrt, METH_VARARGS, c_sqrt_doc},
+ {"tan", cmath_tan, METH_VARARGS, c_tan_doc},
+ {"tanh", cmath_tanh, METH_VARARGS, c_tanh_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+initcmath(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("cmath", cmath_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ PyModule_AddObject(m, "pi",
+ PyFloat_FromDouble(atan(1.0) * 4.0));
+ PyModule_AddObject(m, "e", PyFloat_FromDouble(exp(1.0)));
+}
diff --git a/sys/src/cmd/python/Modules/collectionsmodule.c b/sys/src/cmd/python/Modules/collectionsmodule.c
new file mode 100644
index 000000000..9d128fc95
--- /dev/null
+++ b/sys/src/cmd/python/Modules/collectionsmodule.c
@@ -0,0 +1,1370 @@
+#include "Python.h"
+#include "structmember.h"
+
+/* collections module implementation of a deque() datatype
+ Written and maintained by Raymond D. Hettinger <python@rcn.com>
+ Copyright (c) 2004 Python Software Foundation.
+ All rights reserved.
+*/
+
+/* The block length may be set to any number over 1. Larger numbers
+ * reduce the number of calls to the memory allocator but take more
+ * memory. Ideally, BLOCKLEN should be set with an eye to the
+ * length of a cache line.
+ */
+
+#define BLOCKLEN 62
+#define CENTER ((BLOCKLEN - 1) / 2)
+
+/* A `dequeobject` is composed of a doubly-linked list of `block` nodes.
+ * This list is not circular (the leftmost block has leftlink==NULL,
+ * and the rightmost block has rightlink==NULL). A deque d's first
+ * element is at d.leftblock[leftindex] and its last element is at
+ * d.rightblock[rightindex]; note that, unlike as for Python slice
+ * indices, these indices are inclusive on both ends. By being inclusive
+ * on both ends, algorithms for left and right operations become
+ * symmetrical which simplifies the design.
+ *
+ * The list of blocks is never empty, so d.leftblock and d.rightblock
+ * are never equal to NULL.
+ *
+ * The indices, d.leftindex and d.rightindex are always in the range
+ * 0 <= index < BLOCKLEN.
+ * Their exact relationship is:
+ * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex.
+ *
+ * Empty deques have d.len == 0; d.leftblock==d.rightblock;
+ * d.leftindex == CENTER+1; and d.rightindex == CENTER.
+ * Checking for d.len == 0 is the intended way to see whether d is empty.
+ *
+ * Whenever d.leftblock == d.rightblock,
+ * d.leftindex + d.len - 1 == d.rightindex.
+ *
+ * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex
+ * become indices into distinct blocks and either may be larger than the
+ * other.
+ */
+
+typedef struct BLOCK {
+ struct BLOCK *leftlink;
+ struct BLOCK *rightlink;
+ PyObject *data[BLOCKLEN];
+} block;
+
+static block *
+newblock(block *leftlink, block *rightlink, int len) {
+ block *b;
+ /* To prevent len from overflowing INT_MAX on 64-bit machines, we
+ * refuse to allocate new blocks if the current len is dangerously
+ * close. There is some extra margin to prevent spurious arithmetic
+ * overflows at various places. The following check ensures that
+ * the blocks allocated to the deque, in the worst case, can only
+ * have INT_MAX-2 entries in total.
+ */
+ if (len >= INT_MAX - 2*BLOCKLEN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot add more blocks to the deque");
+ return NULL;
+ }
+ b = PyMem_Malloc(sizeof(block));
+ if (b == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ b->leftlink = leftlink;
+ b->rightlink = rightlink;
+ return b;
+}
+
+typedef struct {
+ PyObject_HEAD
+ block *leftblock;
+ block *rightblock;
+ int leftindex; /* in range(BLOCKLEN) */
+ int rightindex; /* in range(BLOCKLEN) */
+ int len;
+ long state; /* incremented whenever the indices move */
+ PyObject *weakreflist; /* List of weak references */
+} dequeobject;
+
+static PyTypeObject deque_type;
+
+static PyObject *
+deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ dequeobject *deque;
+ block *b;
+
+ if (type == &deque_type && !_PyArg_NoKeywords("deque()", kwds))
+ return NULL;
+
+ /* create dequeobject structure */
+ deque = (dequeobject *)type->tp_alloc(type, 0);
+ if (deque == NULL)
+ return NULL;
+
+ b = newblock(NULL, NULL, 0);
+ if (b == NULL) {
+ Py_DECREF(deque);
+ return NULL;
+ }
+
+ assert(BLOCKLEN >= 2);
+ deque->leftblock = b;
+ deque->rightblock = b;
+ deque->leftindex = CENTER + 1;
+ deque->rightindex = CENTER;
+ deque->len = 0;
+ deque->state = 0;
+ deque->weakreflist = NULL;
+
+ return (PyObject *)deque;
+}
+
+static PyObject *
+deque_append(dequeobject *deque, PyObject *item)
+{
+ deque->state++;
+ if (deque->rightindex == BLOCKLEN-1) {
+ block *b = newblock(deque->rightblock, NULL, deque->len);
+ if (b == NULL)
+ return NULL;
+ assert(deque->rightblock->rightlink == NULL);
+ deque->rightblock->rightlink = b;
+ deque->rightblock = b;
+ deque->rightindex = -1;
+ }
+ Py_INCREF(item);
+ deque->len++;
+ deque->rightindex++;
+ deque->rightblock->data[deque->rightindex] = item;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
+
+static PyObject *
+deque_appendleft(dequeobject *deque, PyObject *item)
+{
+ deque->state++;
+ if (deque->leftindex == 0) {
+ block *b = newblock(NULL, deque->leftblock, deque->len);
+ if (b == NULL)
+ return NULL;
+ assert(deque->leftblock->leftlink == NULL);
+ deque->leftblock->leftlink = b;
+ deque->leftblock = b;
+ deque->leftindex = BLOCKLEN;
+ }
+ Py_INCREF(item);
+ deque->len++;
+ deque->leftindex--;
+ deque->leftblock->data[deque->leftindex] = item;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
+
+static PyObject *
+deque_pop(dequeobject *deque, PyObject *unused)
+{
+ PyObject *item;
+ block *prevblock;
+
+ if (deque->len == 0) {
+ PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
+ return NULL;
+ }
+ item = deque->rightblock->data[deque->rightindex];
+ deque->rightindex--;
+ deque->len--;
+ deque->state++;
+
+ if (deque->rightindex == -1) {
+ if (deque->len == 0) {
+ assert(deque->leftblock == deque->rightblock);
+ assert(deque->leftindex == deque->rightindex+1);
+ /* re-center instead of freeing a block */
+ deque->leftindex = CENTER + 1;
+ deque->rightindex = CENTER;
+ } else {
+ prevblock = deque->rightblock->leftlink;
+ assert(deque->leftblock != deque->rightblock);
+ PyMem_Free(deque->rightblock);
+ prevblock->rightlink = NULL;
+ deque->rightblock = prevblock;
+ deque->rightindex = BLOCKLEN - 1;
+ }
+ }
+ return item;
+}
+
+PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
+
+static PyObject *
+deque_popleft(dequeobject *deque, PyObject *unused)
+{
+ PyObject *item;
+ block *prevblock;
+
+ if (deque->len == 0) {
+ PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
+ return NULL;
+ }
+ assert(deque->leftblock != NULL);
+ item = deque->leftblock->data[deque->leftindex];
+ deque->leftindex++;
+ deque->len--;
+ deque->state++;
+
+ if (deque->leftindex == BLOCKLEN) {
+ if (deque->len == 0) {
+ assert(deque->leftblock == deque->rightblock);
+ assert(deque->leftindex == deque->rightindex+1);
+ /* re-center instead of freeing a block */
+ deque->leftindex = CENTER + 1;
+ deque->rightindex = CENTER;
+ } else {
+ assert(deque->leftblock != deque->rightblock);
+ prevblock = deque->leftblock->rightlink;
+ PyMem_Free(deque->leftblock);
+ assert(prevblock != NULL);
+ prevblock->leftlink = NULL;
+ deque->leftblock = prevblock;
+ deque->leftindex = 0;
+ }
+ }
+ return item;
+}
+
+PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
+
+static PyObject *
+deque_extend(dequeobject *deque, PyObject *iterable)
+{
+ PyObject *it, *item;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+
+ while ((item = PyIter_Next(it)) != NULL) {
+ deque->state++;
+ if (deque->rightindex == BLOCKLEN-1) {
+ block *b = newblock(deque->rightblock, NULL,
+ deque->len);
+ if (b == NULL) {
+ Py_DECREF(item);
+ Py_DECREF(it);
+ return NULL;
+ }
+ assert(deque->rightblock->rightlink == NULL);
+ deque->rightblock->rightlink = b;
+ deque->rightblock = b;
+ deque->rightindex = -1;
+ }
+ deque->len++;
+ deque->rightindex++;
+ deque->rightblock->data[deque->rightindex] = item;
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(extend_doc,
+"Extend the right side of the deque with elements from the iterable");
+
+static PyObject *
+deque_extendleft(dequeobject *deque, PyObject *iterable)
+{
+ PyObject *it, *item;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+
+ while ((item = PyIter_Next(it)) != NULL) {
+ deque->state++;
+ if (deque->leftindex == 0) {
+ block *b = newblock(NULL, deque->leftblock,
+ deque->len);
+ if (b == NULL) {
+ Py_DECREF(item);
+ Py_DECREF(it);
+ return NULL;
+ }
+ assert(deque->leftblock->leftlink == NULL);
+ deque->leftblock->leftlink = b;
+ deque->leftblock = b;
+ deque->leftindex = BLOCKLEN;
+ }
+ deque->len++;
+ deque->leftindex--;
+ deque->leftblock->data[deque->leftindex] = item;
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(extendleft_doc,
+"Extend the left side of the deque with elements from the iterable");
+
+static int
+_deque_rotate(dequeobject *deque, Py_ssize_t n)
+{
+ int i, len=deque->len, halflen=(len+1)>>1;
+ PyObject *item, *rv;
+
+ if (len == 0)
+ return 0;
+ if (n > halflen || n < -halflen) {
+ n %= len;
+ if (n > halflen)
+ n -= len;
+ else if (n < -halflen)
+ n += len;
+ }
+
+ for (i=0 ; i<n ; i++) {
+ item = deque_pop(deque, NULL);
+ assert (item != NULL);
+ rv = deque_appendleft(deque, item);
+ Py_DECREF(item);
+ if (rv == NULL)
+ return -1;
+ Py_DECREF(rv);
+ }
+ for (i=0 ; i>n ; i--) {
+ item = deque_popleft(deque, NULL);
+ assert (item != NULL);
+ rv = deque_append(deque, item);
+ Py_DECREF(item);
+ if (rv == NULL)
+ return -1;
+ Py_DECREF(rv);
+ }
+ return 0;
+}
+
+static PyObject *
+deque_rotate(dequeobject *deque, PyObject *args)
+{
+ int n=1;
+
+ if (!PyArg_ParseTuple(args, "|i:rotate", &n))
+ return NULL;
+ if (_deque_rotate(deque, n) == 0)
+ Py_RETURN_NONE;
+ return NULL;
+}
+
+PyDoc_STRVAR(rotate_doc,
+"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
+
+static Py_ssize_t
+deque_len(dequeobject *deque)
+{
+ return deque->len;
+}
+
+static PyObject *
+deque_remove(dequeobject *deque, PyObject *value)
+{
+ Py_ssize_t i, n=deque->len;
+
+ for (i=0 ; i<n ; i++) {
+ PyObject *item = deque->leftblock->data[deque->leftindex];
+ int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
+
+ if (deque->len != n) {
+ PyErr_SetString(PyExc_IndexError,
+ "deque mutated during remove().");
+ return NULL;
+ }
+ if (cmp > 0) {
+ PyObject *tgt = deque_popleft(deque, NULL);
+ assert (tgt != NULL);
+ Py_DECREF(tgt);
+ if (_deque_rotate(deque, i) == -1)
+ return NULL;
+ Py_RETURN_NONE;
+ }
+ else if (cmp < 0) {
+ _deque_rotate(deque, i);
+ return NULL;
+ }
+ _deque_rotate(deque, -1);
+ }
+ PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
+ return NULL;
+}
+
+PyDoc_STRVAR(remove_doc,
+"D.remove(value) -- remove first occurrence of value.");
+
+static int
+deque_clear(dequeobject *deque)
+{
+ PyObject *item;
+
+ while (deque->len) {
+ item = deque_pop(deque, NULL);
+ assert (item != NULL);
+ Py_DECREF(item);
+ }
+ assert(deque->leftblock == deque->rightblock &&
+ deque->leftindex - 1 == deque->rightindex &&
+ deque->len == 0);
+ return 0;
+}
+
+static PyObject *
+deque_item(dequeobject *deque, int i)
+{
+ block *b;
+ PyObject *item;
+ int n, index=i;
+
+ if (i < 0 || i >= deque->len) {
+ PyErr_SetString(PyExc_IndexError,
+ "deque index out of range");
+ return NULL;
+ }
+
+ if (i == 0) {
+ i = deque->leftindex;
+ b = deque->leftblock;
+ } else if (i == deque->len - 1) {
+ i = deque->rightindex;
+ b = deque->rightblock;
+ } else {
+ i += deque->leftindex;
+ n = i / BLOCKLEN;
+ i %= BLOCKLEN;
+ if (index < (deque->len >> 1)) {
+ b = deque->leftblock;
+ while (n--)
+ b = b->rightlink;
+ } else {
+ n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
+ b = deque->rightblock;
+ while (n--)
+ b = b->leftlink;
+ }
+ }
+ item = b->data[i];
+ Py_INCREF(item);
+ return item;
+}
+
+/* delitem() implemented in terms of rotate for simplicity and reasonable
+ performance near the end points. If for some reason this method becomes
+ popular, it is not hard to re-implement this using direct data movement
+ (similar to code in list slice assignment) and achieve a two or threefold
+ performance boost.
+*/
+
+static int
+deque_del_item(dequeobject *deque, Py_ssize_t i)
+{
+ PyObject *item;
+
+ assert (i >= 0 && i < deque->len);
+ if (_deque_rotate(deque, -i) == -1)
+ return -1;
+
+ item = deque_popleft(deque, NULL);
+ assert (item != NULL);
+ Py_DECREF(item);
+
+ return _deque_rotate(deque, i);
+}
+
+static int
+deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
+{
+ PyObject *old_value;
+ block *b;
+ Py_ssize_t n, len=deque->len, halflen=(len+1)>>1, index=i;
+
+ if (i < 0 || i >= len) {
+ PyErr_SetString(PyExc_IndexError,
+ "deque index out of range");
+ return -1;
+ }
+ if (v == NULL)
+ return deque_del_item(deque, i);
+
+ i += deque->leftindex;
+ n = i / BLOCKLEN;
+ i %= BLOCKLEN;
+ if (index <= halflen) {
+ b = deque->leftblock;
+ while (n--)
+ b = b->rightlink;
+ } else {
+ n = (deque->leftindex + len - 1) / BLOCKLEN - n;
+ b = deque->rightblock;
+ while (n--)
+ b = b->leftlink;
+ }
+ Py_INCREF(v);
+ old_value = b->data[i];
+ b->data[i] = v;
+ Py_DECREF(old_value);
+ return 0;
+}
+
+static PyObject *
+deque_clearmethod(dequeobject *deque)
+{
+ int rv;
+
+ rv = deque_clear(deque);
+ assert (rv != -1);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
+
+static void
+deque_dealloc(dequeobject *deque)
+{
+ PyObject_GC_UnTrack(deque);
+ if (deque->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) deque);
+ if (deque->leftblock != NULL) {
+ deque_clear(deque);
+ assert(deque->leftblock != NULL);
+ PyMem_Free(deque->leftblock);
+ }
+ deque->leftblock = NULL;
+ deque->rightblock = NULL;
+ deque->ob_type->tp_free(deque);
+}
+
+static int
+deque_traverse(dequeobject *deque, visitproc visit, void *arg)
+{
+ block *b;
+ PyObject *item;
+ int index;
+ int indexlo = deque->leftindex;
+
+ for (b = deque->leftblock; b != NULL; b = b->rightlink) {
+ const int indexhi = b == deque->rightblock ?
+ deque->rightindex :
+ BLOCKLEN - 1;
+
+ for (index = indexlo; index <= indexhi; ++index) {
+ item = b->data[index];
+ Py_VISIT(item);
+ }
+ indexlo = 0;
+ }
+ return 0;
+}
+
+static long
+deque_nohash(PyObject *self)
+{
+ PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
+ return -1;
+}
+
+static PyObject *
+deque_copy(PyObject *deque)
+{
+ return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
+ deque, NULL);
+}
+
+PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
+
+static PyObject *
+deque_reduce(dequeobject *deque)
+{
+ PyObject *dict, *result, *it;
+
+ dict = PyObject_GetAttrString((PyObject *)deque, "__dict__");
+ if (dict == NULL) {
+ PyErr_Clear();
+ dict = Py_None;
+ Py_INCREF(dict);
+ }
+ it = PyObject_GetIter((PyObject *)deque);
+ if (it == NULL) {
+ Py_DECREF(dict);
+ return NULL;
+ }
+ result = Py_BuildValue("O()ON", deque->ob_type, dict, it);
+ Py_DECREF(dict);
+ return result;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyObject *
+deque_repr(PyObject *deque)
+{
+ PyObject *aslist, *result, *fmt;
+ int i;
+
+ i = Py_ReprEnter(deque);
+ if (i != 0) {
+ if (i < 0)
+ return NULL;
+ return PyString_FromString("[...]");
+ }
+
+ aslist = PySequence_List(deque);
+ if (aslist == NULL) {
+ Py_ReprLeave(deque);
+ return NULL;
+ }
+
+ fmt = PyString_FromString("deque(%r)");
+ if (fmt == NULL) {
+ Py_DECREF(aslist);
+ Py_ReprLeave(deque);
+ return NULL;
+ }
+ result = PyString_Format(fmt, aslist);
+ Py_DECREF(fmt);
+ Py_DECREF(aslist);
+ Py_ReprLeave(deque);
+ return result;
+}
+
+static int
+deque_tp_print(PyObject *deque, FILE *fp, int flags)
+{
+ PyObject *it, *item;
+ char *emit = ""; /* No separator emitted on first pass */
+ char *separator = ", ";
+ int i;
+
+ i = Py_ReprEnter(deque);
+ if (i != 0) {
+ if (i < 0)
+ return i;
+ fputs("[...]", fp);
+ return 0;
+ }
+
+ it = PyObject_GetIter(deque);
+ if (it == NULL)
+ return -1;
+
+ fputs("deque([", fp);
+ while ((item = PyIter_Next(it)) != NULL) {
+ fputs(emit, fp);
+ emit = separator;
+ if (PyObject_Print(item, fp, 0) != 0) {
+ Py_DECREF(item);
+ Py_DECREF(it);
+ Py_ReprLeave(deque);
+ return -1;
+ }
+ Py_DECREF(item);
+ }
+ Py_ReprLeave(deque);
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return -1;
+ fputs("])", fp);
+ return 0;
+}
+
+static PyObject *
+deque_richcompare(PyObject *v, PyObject *w, int op)
+{
+ PyObject *it1=NULL, *it2=NULL, *x, *y;
+ int b, vs, ws, cmp=-1;
+
+ if (!PyObject_TypeCheck(v, &deque_type) ||
+ !PyObject_TypeCheck(w, &deque_type)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ /* Shortcuts */
+ vs = ((dequeobject *)v)->len;
+ ws = ((dequeobject *)w)->len;
+ if (op == Py_EQ) {
+ if (v == w)
+ Py_RETURN_TRUE;
+ if (vs != ws)
+ Py_RETURN_FALSE;
+ }
+ if (op == Py_NE) {
+ if (v == w)
+ Py_RETURN_FALSE;
+ if (vs != ws)
+ Py_RETURN_TRUE;
+ }
+
+ /* Search for the first index where items are different */
+ it1 = PyObject_GetIter(v);
+ if (it1 == NULL)
+ goto done;
+ it2 = PyObject_GetIter(w);
+ if (it2 == NULL)
+ goto done;
+ for (;;) {
+ x = PyIter_Next(it1);
+ if (x == NULL && PyErr_Occurred())
+ goto done;
+ y = PyIter_Next(it2);
+ if (x == NULL || y == NULL)
+ break;
+ b = PyObject_RichCompareBool(x, y, Py_EQ);
+ if (b == 0) {
+ cmp = PyObject_RichCompareBool(x, y, op);
+ Py_DECREF(x);
+ Py_DECREF(y);
+ goto done;
+ }
+ Py_DECREF(x);
+ Py_DECREF(y);
+ if (b == -1)
+ goto done;
+ }
+ /* We reached the end of one deque or both */
+ Py_XDECREF(x);
+ Py_XDECREF(y);
+ if (PyErr_Occurred())
+ goto done;
+ switch (op) {
+ case Py_LT: cmp = y != NULL; break; /* if w was longer */
+ case Py_LE: cmp = x == NULL; break; /* if v was not longer */
+ case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
+ case Py_NE: cmp = x != y; break; /* if one deque continues */
+ case Py_GT: cmp = x != NULL; break; /* if v was longer */
+ case Py_GE: cmp = y == NULL; break; /* if w was not longer */
+ }
+
+done:
+ Py_XDECREF(it1);
+ Py_XDECREF(it2);
+ if (cmp == 1)
+ Py_RETURN_TRUE;
+ if (cmp == 0)
+ Py_RETURN_FALSE;
+ return NULL;
+}
+
+static int
+deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
+{
+ PyObject *iterable = NULL;
+
+ if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
+ return -1;
+
+ if (iterable != NULL) {
+ PyObject *rv = deque_extend(deque, iterable);
+ if (rv == NULL)
+ return -1;
+ Py_DECREF(rv);
+ }
+ return 0;
+}
+
+static PySequenceMethods deque_as_sequence = {
+ (lenfunc)deque_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)deque_item, /* sq_item */
+ 0, /* sq_slice */
+ (ssizeobjargproc)deque_ass_item, /* sq_ass_item */
+};
+
+/* deque object ********************************************************/
+
+static PyObject *deque_iter(dequeobject *deque);
+static PyObject *deque_reviter(dequeobject *deque);
+PyDoc_STRVAR(reversed_doc,
+ "D.__reversed__() -- return a reverse iterator over the deque");
+
+static PyMethodDef deque_methods[] = {
+ {"append", (PyCFunction)deque_append,
+ METH_O, append_doc},
+ {"appendleft", (PyCFunction)deque_appendleft,
+ METH_O, appendleft_doc},
+ {"clear", (PyCFunction)deque_clearmethod,
+ METH_NOARGS, clear_doc},
+ {"__copy__", (PyCFunction)deque_copy,
+ METH_NOARGS, copy_doc},
+ {"extend", (PyCFunction)deque_extend,
+ METH_O, extend_doc},
+ {"extendleft", (PyCFunction)deque_extendleft,
+ METH_O, extendleft_doc},
+ {"pop", (PyCFunction)deque_pop,
+ METH_NOARGS, pop_doc},
+ {"popleft", (PyCFunction)deque_popleft,
+ METH_NOARGS, popleft_doc},
+ {"__reduce__", (PyCFunction)deque_reduce,
+ METH_NOARGS, reduce_doc},
+ {"remove", (PyCFunction)deque_remove,
+ METH_O, remove_doc},
+ {"__reversed__", (PyCFunction)deque_reviter,
+ METH_NOARGS, reversed_doc},
+ {"rotate", (PyCFunction)deque_rotate,
+ METH_VARARGS, rotate_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(deque_doc,
+"deque(iterable) --> deque object\n\
+\n\
+Build an ordered collection accessible from endpoints only.");
+
+static PyTypeObject deque_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "collections.deque", /* tp_name */
+ sizeof(dequeobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)deque_dealloc, /* tp_dealloc */
+ deque_tp_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ deque_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &deque_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ deque_nohash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ deque_doc, /* tp_doc */
+ (traverseproc)deque_traverse, /* tp_traverse */
+ (inquiry)deque_clear, /* tp_clear */
+ (richcmpfunc)deque_richcompare, /* tp_richcompare */
+ offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
+ (getiterfunc)deque_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ deque_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)deque_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ deque_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+/*********************** Deque Iterator **************************/
+
+typedef struct {
+ PyObject_HEAD
+ int index;
+ block *b;
+ dequeobject *deque;
+ long state; /* state when the iterator is created */
+ int counter; /* number of items remaining for iteration */
+} dequeiterobject;
+
+PyTypeObject dequeiter_type;
+
+static PyObject *
+deque_iter(dequeobject *deque)
+{
+ dequeiterobject *it;
+
+ it = PyObject_New(dequeiterobject, &dequeiter_type);
+ if (it == NULL)
+ return NULL;
+ it->b = deque->leftblock;
+ it->index = deque->leftindex;
+ Py_INCREF(deque);
+ it->deque = deque;
+ it->state = deque->state;
+ it->counter = deque->len;
+ return (PyObject *)it;
+}
+
+static void
+dequeiter_dealloc(dequeiterobject *dio)
+{
+ Py_XDECREF(dio->deque);
+ dio->ob_type->tp_free(dio);
+}
+
+static PyObject *
+dequeiter_next(dequeiterobject *it)
+{
+ PyObject *item;
+
+ if (it->deque->state != it->state) {
+ it->counter = 0;
+ PyErr_SetString(PyExc_RuntimeError,
+ "deque mutated during iteration");
+ return NULL;
+ }
+ if (it->counter == 0)
+ return NULL;
+ assert (!(it->b == it->deque->rightblock &&
+ it->index > it->deque->rightindex));
+
+ item = it->b->data[it->index];
+ it->index++;
+ it->counter--;
+ if (it->index == BLOCKLEN && it->counter > 0) {
+ assert (it->b->rightlink != NULL);
+ it->b = it->b->rightlink;
+ it->index = 0;
+ }
+ Py_INCREF(item);
+ return item;
+}
+
+static PyObject *
+dequeiter_len(dequeiterobject *it)
+{
+ return PyInt_FromLong(it->counter);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dequeiter_methods[] = {
+ {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject dequeiter_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "deque_iterator", /* tp_name */
+ sizeof(dequeiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dequeiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)dequeiter_next, /* tp_iternext */
+ dequeiter_methods, /* tp_methods */
+ 0,
+};
+
+/*********************** Deque Reverse Iterator **************************/
+
+PyTypeObject dequereviter_type;
+
+static PyObject *
+deque_reviter(dequeobject *deque)
+{
+ dequeiterobject *it;
+
+ it = PyObject_New(dequeiterobject, &dequereviter_type);
+ if (it == NULL)
+ return NULL;
+ it->b = deque->rightblock;
+ it->index = deque->rightindex;
+ Py_INCREF(deque);
+ it->deque = deque;
+ it->state = deque->state;
+ it->counter = deque->len;
+ return (PyObject *)it;
+}
+
+static PyObject *
+dequereviter_next(dequeiterobject *it)
+{
+ PyObject *item;
+ if (it->counter == 0)
+ return NULL;
+
+ if (it->deque->state != it->state) {
+ it->counter = 0;
+ PyErr_SetString(PyExc_RuntimeError,
+ "deque mutated during iteration");
+ return NULL;
+ }
+ assert (!(it->b == it->deque->leftblock &&
+ it->index < it->deque->leftindex));
+
+ item = it->b->data[it->index];
+ it->index--;
+ it->counter--;
+ if (it->index == -1 && it->counter > 0) {
+ assert (it->b->leftlink != NULL);
+ it->b = it->b->leftlink;
+ it->index = BLOCKLEN - 1;
+ }
+ Py_INCREF(item);
+ return item;
+}
+
+PyTypeObject dequereviter_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "deque_reverse_iterator", /* tp_name */
+ sizeof(dequeiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dequeiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)dequereviter_next, /* tp_iternext */
+ dequeiter_methods, /* tp_methods */
+ 0,
+};
+
+/* defaultdict type *********************************************************/
+
+typedef struct {
+ PyDictObject dict;
+ PyObject *default_factory;
+} defdictobject;
+
+static PyTypeObject defdict_type; /* Forward */
+
+PyDoc_STRVAR(defdict_missing_doc,
+"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
+ if self.default_factory is None: raise KeyError((key,))\n\
+ self[key] = value = self.default_factory()\n\
+ return value\n\
+");
+
+static PyObject *
+defdict_missing(defdictobject *dd, PyObject *key)
+{
+ PyObject *factory = dd->default_factory;
+ PyObject *value;
+ if (factory == NULL || factory == Py_None) {
+ /* XXX Call dict.__missing__(key) */
+ PyObject *tup;
+ tup = PyTuple_Pack(1, key);
+ if (!tup) return NULL;
+ PyErr_SetObject(PyExc_KeyError, tup);
+ Py_DECREF(tup);
+ return NULL;
+ }
+ value = PyEval_CallObject(factory, NULL);
+ if (value == NULL)
+ return value;
+ if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
+ Py_DECREF(value);
+ return NULL;
+ }
+ return value;
+}
+
+PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
+
+static PyObject *
+defdict_copy(defdictobject *dd)
+{
+ /* This calls the object's class. That only works for subclasses
+ whose class constructor has the same signature. Subclasses that
+ define a different constructor signature must override copy().
+ */
+ return PyObject_CallFunctionObjArgs((PyObject *)dd->dict.ob_type,
+ dd->default_factory, dd, NULL);
+}
+
+static PyObject *
+defdict_reduce(defdictobject *dd)
+{
+ /* __reduce__ must return a 5-tuple as follows:
+
+ - factory function
+ - tuple of args for the factory function
+ - additional state (here None)
+ - sequence iterator (here None)
+ - dictionary iterator (yielding successive (key, value) pairs
+
+ This API is used by pickle.py and copy.py.
+
+ For this to be useful with pickle.py, the default_factory
+ must be picklable; e.g., None, a built-in, or a global
+ function in a module or package.
+
+ Both shallow and deep copying are supported, but for deep
+ copying, the default_factory must be deep-copyable; e.g. None,
+ or a built-in (functions are not copyable at this time).
+
+ This only works for subclasses as long as their constructor
+ signature is compatible; the first argument must be the
+ optional default_factory, defaulting to None.
+ */
+ PyObject *args;
+ PyObject *items;
+ PyObject *result;
+ if (dd->default_factory == NULL || dd->default_factory == Py_None)
+ args = PyTuple_New(0);
+ else
+ args = PyTuple_Pack(1, dd->default_factory);
+ if (args == NULL)
+ return NULL;
+ items = PyObject_CallMethod((PyObject *)dd, "iteritems", "()");
+ if (items == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ result = PyTuple_Pack(5, dd->dict.ob_type, args,
+ Py_None, Py_None, items);
+ Py_DECREF(items);
+ Py_DECREF(args);
+ return result;
+}
+
+static PyMethodDef defdict_methods[] = {
+ {"__missing__", (PyCFunction)defdict_missing, METH_O,
+ defdict_missing_doc},
+ {"copy", (PyCFunction)defdict_copy, METH_NOARGS,
+ defdict_copy_doc},
+ {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
+ defdict_copy_doc},
+ {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
+ reduce_doc},
+ {NULL}
+};
+
+static PyMemberDef defdict_members[] = {
+ {"default_factory", T_OBJECT,
+ offsetof(defdictobject, default_factory), 0,
+ PyDoc_STR("Factory for default value called by __missing__().")},
+ {NULL}
+};
+
+static void
+defdict_dealloc(defdictobject *dd)
+{
+ Py_CLEAR(dd->default_factory);
+ PyDict_Type.tp_dealloc((PyObject *)dd);
+}
+
+static int
+defdict_print(defdictobject *dd, FILE *fp, int flags)
+{
+ int sts;
+ fprintf(fp, "defaultdict(");
+ if (dd->default_factory == NULL)
+ fprintf(fp, "None");
+ else {
+ PyObject_Print(dd->default_factory, fp, 0);
+ }
+ fprintf(fp, ", ");
+ sts = PyDict_Type.tp_print((PyObject *)dd, fp, 0);
+ fprintf(fp, ")");
+ return sts;
+}
+
+static PyObject *
+defdict_repr(defdictobject *dd)
+{
+ PyObject *defrepr;
+ PyObject *baserepr;
+ PyObject *result;
+ baserepr = PyDict_Type.tp_repr((PyObject *)dd);
+ if (baserepr == NULL)
+ return NULL;
+ if (dd->default_factory == NULL)
+ defrepr = PyString_FromString("None");
+ else
+ defrepr = PyObject_Repr(dd->default_factory);
+ if (defrepr == NULL) {
+ Py_DECREF(baserepr);
+ return NULL;
+ }
+ result = PyString_FromFormat("defaultdict(%s, %s)",
+ PyString_AS_STRING(defrepr),
+ PyString_AS_STRING(baserepr));
+ Py_DECREF(defrepr);
+ Py_DECREF(baserepr);
+ return result;
+}
+
+static int
+defdict_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(((defdictobject *)self)->default_factory);
+ return PyDict_Type.tp_traverse(self, visit, arg);
+}
+
+static int
+defdict_tp_clear(defdictobject *dd)
+{
+ Py_CLEAR(dd->default_factory);
+ return PyDict_Type.tp_clear((PyObject *)dd);
+}
+
+static int
+defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ defdictobject *dd = (defdictobject *)self;
+ PyObject *olddefault = dd->default_factory;
+ PyObject *newdefault = NULL;
+ PyObject *newargs;
+ int result;
+ if (args == NULL || !PyTuple_Check(args))
+ newargs = PyTuple_New(0);
+ else {
+ Py_ssize_t n = PyTuple_GET_SIZE(args);
+ if (n > 0) {
+ newdefault = PyTuple_GET_ITEM(args, 0);
+ if (!PyCallable_Check(newdefault)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be callable");
+ return -1;
+ }
+ }
+ newargs = PySequence_GetSlice(args, 1, n);
+ }
+ if (newargs == NULL)
+ return -1;
+ Py_XINCREF(newdefault);
+ dd->default_factory = newdefault;
+ result = PyDict_Type.tp_init(self, newargs, kwds);
+ Py_DECREF(newargs);
+ Py_XDECREF(olddefault);
+ return result;
+}
+
+PyDoc_STRVAR(defdict_doc,
+"defaultdict(default_factory) --> dict with default factory\n\
+\n\
+The default factory is called without arguments to produce\n\
+a new value when a key is not present, in __getitem__ only.\n\
+A defaultdict compares equal to a dict with the same items.\n\
+");
+
+/* See comment in xxsubtype.c */
+#define DEFERRED_ADDRESS(ADDR) 0
+
+static PyTypeObject defdict_type = {
+ PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+ 0, /* ob_size */
+ "collections.defaultdict", /* tp_name */
+ sizeof(defdictobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)defdict_dealloc, /* tp_dealloc */
+ (printfunc)defdict_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)defdict_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ defdict_doc, /* tp_doc */
+ defdict_traverse, /* tp_traverse */
+ (inquiry)defdict_tp_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset*/
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ defdict_methods, /* tp_methods */
+ defdict_members, /* tp_members */
+ 0, /* tp_getset */
+ DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ defdict_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ 0, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+/* module level code ********************************************************/
+
+PyDoc_STRVAR(module_doc,
+"High performance data structures.\n\
+- deque: ordered collection accessible from endpoints only\n\
+- defaultdict: dict subclass with a default value factory\n\
+");
+
+PyMODINIT_FUNC
+initcollections(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("collections", NULL, module_doc);
+ if (m == NULL)
+ return;
+
+ if (PyType_Ready(&deque_type) < 0)
+ return;
+ Py_INCREF(&deque_type);
+ PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
+
+ defdict_type.tp_base = &PyDict_Type;
+ if (PyType_Ready(&defdict_type) < 0)
+ return;
+ Py_INCREF(&defdict_type);
+ PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
+
+ if (PyType_Ready(&dequeiter_type) < 0)
+ return;
+
+ if (PyType_Ready(&dequereviter_type) < 0)
+ return;
+
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/config b/sys/src/cmd/python/Modules/config
new file mode 100644
index 000000000..ef3eb55bc
--- /dev/null
+++ b/sys/src/cmd/python/Modules/config
@@ -0,0 +1,54 @@
+_codecs
+_csv
+#_curses
+#_curses_panel
+_elementtree
+_functools
+_hashlib
+_locale
+_lsprof
+_md5
+_random
+_sha
+_sha256
+_sre
+_ssl
+_struct
+_symtable
+_testcapi
+_weakref
+array
+audioop
+binascii
+bz2
+cPickle
+cStringIO
+cmath
+collections
+datetime
+errno
+fcntl
+fpetest
+grp
+imageop
+itertools
+math
+operator
+parser
+posix
+pure
+pwd
+pyexpat
+rgbimg
+select
+signal
+_socket
+strop
+thread
+time
+unicodedata
+xx
+xxsubtype
+zipimport
+zlib
+#_sqlite3
diff --git a/sys/src/cmd/python/Modules/config.c.in b/sys/src/cmd/python/Modules/config.c.in
new file mode 100644
index 000000000..8c25eea2e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/config.c.in
@@ -0,0 +1,66 @@
+/* -*- C -*- ***********************************************
+Copyright (c) 2000, BeOpen.com.
+Copyright (c) 1995-2000, Corporation for National Research Initiatives.
+Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
+All rights reserved.
+
+See the file "Misc/COPYRIGHT" for information on usage and
+redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+******************************************************************/
+
+/* Module configuration */
+
+/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */
+
+/* This file contains the table of built-in modules.
+ See init_builtin() in import.c. */
+
+#include "Python.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init(void);
+extern void initimp(void);
+extern void initgc(void);
+extern void init_ast(void);
+extern void init_types(void);
+
+struct _inittab _PyImport_Inittab[] = {
+
+/* -- ADDMODULE MARKER 2 -- */
+
+ /* This module lives in marshal.c */
+ {"marshal", PyMarshal_Init},
+
+ /* This lives in import.c */
+ {"imp", initimp},
+
+ /* This lives in Python/Python-ast.c */
+ {"_ast", init_ast},
+
+ /* This lives in Python/_types.c */
+ {"_types", init_types},
+
+ /* These entries are here for sys.builtin_module_names */
+ {"__main__", NULL},
+ {"__builtin__", NULL},
+ {"sys", NULL},
+ {"exceptions", NULL},
+
+ /* This lives in gcmodule.c */
+ {"gc", initgc},
+
+ /* Sentinel */
+ {0, 0}
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/sys/src/cmd/python/Modules/cryptmodule.c b/sys/src/cmd/python/Modules/cryptmodule.c
new file mode 100644
index 000000000..6377f8430
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cryptmodule.c
@@ -0,0 +1,49 @@
+/* cryptmodule.c - by Steve Majewski
+ */
+
+#include "Python.h"
+
+#include <sys/types.h>
+
+#ifdef __VMS
+#include <openssl/des.h>
+#endif
+
+/* Module crypt */
+
+
+static PyObject *crypt_crypt(PyObject *self, PyObject *args)
+{
+ char *word, *salt;
+#ifndef __VMS
+ extern char * crypt(const char *, const char *);
+#endif
+
+ if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) {
+ return NULL;
+ }
+ /* On some platforms (AtheOS) crypt returns NULL for an invalid
+ salt. Return None in that case. XXX Maybe raise an exception? */
+ return Py_BuildValue("s", crypt(word, salt));
+
+}
+
+PyDoc_STRVAR(crypt_crypt__doc__,
+"crypt(word, salt) -> string\n\
+word will usually be a user's password. salt is a 2-character string\n\
+which will be used to select one of 4096 variations of DES. The characters\n\
+in salt must be either \".\", \"/\", or an alphanumeric character. Returns\n\
+the hashed password as a string, which will be composed of characters from\n\
+the same alphabet as the salt.");
+
+
+static PyMethodDef crypt_methods[] = {
+ {"crypt", crypt_crypt, METH_VARARGS, crypt_crypt__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+initcrypt(void)
+{
+ Py_InitModule("crypt", crypt_methods);
+}
diff --git a/sys/src/cmd/python/Modules/cstubs b/sys/src/cmd/python/Modules/cstubs
new file mode 100644
index 000000000..53bd4ab31
--- /dev/null
+++ b/sys/src/cmd/python/Modules/cstubs
@@ -0,0 +1,1364 @@
+
+/*
+Input used to generate the Python module "glmodule.c".
+The stub generator is a Python script called "cgen.py".
+
+Each definition must be contained on one line:
+
+<returntype> <name> <type> <arg> <type> <arg>
+
+<returntype> can be: void, short, long (XXX maybe others?)
+
+<type> can be: char, string, short, float, long, or double
+ string indicates a null terminated string;
+ if <type> is char and <arg> begins with a *, the * is stripped
+ and <type> is changed into string
+
+<arg> has the form <mode> or <mode>[<subscript>]
+ where <mode> can be
+ s: arg is sent
+ r: arg is received (arg is a pointer)
+ and <subscript> can be (N and I are numbers):
+ N
+ argI
+ retval
+ N*argI
+ N*I
+ N*retval
+ In the case where the subscript consists of two parts
+ separated by *, the first part is the width of the matrix, and
+ the second part is the length of the matrix. This order is
+ opposite from the order used in C to declare a two-dimensional
+ matrix.
+*/
+
+/*
+ * An attempt has been made to make this module switch threads on qread
+ * calls. It is far from safe, though.
+ */
+
+#include <gl.h>
+#include <device.h>
+
+#ifdef __sgi
+extern int devport();
+extern int textwritemask();
+extern int pagewritemask();
+extern int gewrite();
+extern int gettp();
+#endif
+
+#include "Python.h"
+#include "cgensupport.h"
+
+/*
+Some stubs are too complicated for the stub generator.
+We can include manually written versions of them here.
+A line starting with '%' gives the name of the function so the stub
+generator can include it in the table of functions.
+*/
+
+% qread
+
+static PyObject *
+gl_qread(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ long retval;
+ short arg1 ;
+ Py_BEGIN_ALLOW_THREADS
+ retval = qread( & arg1 );
+ Py_END_ALLOW_THREADS
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewlongobject(retval));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg1));
+ return v;
+ }
+}
+
+
+/*
+varray -- an array of v.. calls.
+The argument is an array (maybe list or tuple) of points.
+Each point must be a tuple or list of coordinates (x, y, z).
+The points may be 2- or 3-dimensional but must all have the
+same dimension. Float and int values may be mixed however.
+The points are always converted to 3D double precision points
+by assuming z=0.0 if necessary (as indicated in the man page),
+and for each point v3d() is called.
+*/
+
+% varray
+
+static PyObject *
+gl_varray(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ PyObject *v, *w=NULL;
+ int i, n, width;
+ double vec[3];
+ PyObject * (*getitem)(PyObject *, int);
+
+ if (!PyArg_GetObject(args, 1, 0, &v))
+ return NULL;
+
+ if (PyList_Check(v)) {
+ n = PyList_Size(v);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(v)) {
+ n = PyTuple_Size(v);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ if (n == 0) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (n > 0)
+ w = (*getitem)(v, 0);
+
+ width = 0;
+ if (w == NULL) {
+ }
+ else if (PyList_Check(w)) {
+ width = PyList_Size(w);
+ }
+ else if (PyTuple_Check(w)) {
+ width = PyTuple_Size(w);
+ }
+
+ switch (width) {
+ case 2:
+ vec[2] = 0.0;
+ /* Fall through */
+ case 3:
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ w = (*getitem)(v, i);
+ if (!PyArg_GetDoubleArray(w, 1, 0, width, vec))
+ return NULL;
+ v3d(vec);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+vnarray, nvarray -- an array of n3f and v3f calls.
+The argument is an array (list or tuple) of pairs of points and normals.
+Each pair is a tuple (NOT a list) of a point and a normal for that point.
+Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
+Three coordinates must be given. Float and int values may be mixed.
+For each pair, n3f() is called for the normal, and then v3f() is called
+for the vector.
+
+vnarray and nvarray differ only in the order of the vector and normal in
+the pair: vnarray expects (v, n) while nvarray expects (n, v).
+*/
+
+static PyObject *gen_nvarray(); /* Forward */
+
+% nvarray
+
+static PyObject *
+gl_nvarray(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return gen_nvarray(args, 0);
+}
+
+% vnarray
+
+static PyObject *
+gl_vnarray(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return gen_nvarray(args, 1);
+}
+
+/* Generic, internal version of {nv,nv}array: inorm indicates the
+ argument order, 0: normal first, 1: vector first. */
+
+static PyObject *
+gen_nvarray(args, inorm)
+ PyObject *args;
+ int inorm;
+{
+ PyObject *v, *w, *wnorm, *wvec;
+ int i, n;
+ float norm[3], vec[3];
+ PyObject * (*getitem)(PyObject *, int);
+
+ if (!PyArg_GetObject(args, 1, 0, &v))
+ return NULL;
+
+ if (PyList_Check(v)) {
+ n = PyList_Size(v);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(v)) {
+ n = PyTuple_Size(v);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ w = (*getitem)(v, i);
+ if (!PyTuple_Check(w) || PyTuple_Size(w) != 2) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ wnorm = PyTuple_GetItem(w, inorm);
+ wvec = PyTuple_GetItem(w, 1 - inorm);
+ if (!PyArg_GetFloatArray(wnorm, 1, 0, 3, norm) ||
+ !PyArg_GetFloatArray(wvec, 1, 0, 3, vec))
+ return NULL;
+ n3f(norm);
+ v3f(vec);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* nurbssurface(s_knots[], t_knots[], ctl[][], s_order, t_order, type).
+ The dimensions of ctl[] are computed as follows:
+ [len(s_knots) - s_order], [len(t_knots) - t_order]
+*/
+
+% nurbssurface
+
+static PyObject *
+gl_nurbssurface(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ long arg1 ;
+ double * arg2 ;
+ long arg3 ;
+ double * arg4 ;
+ double *arg5 ;
+ long arg6 ;
+ long arg7 ;
+ long arg8 ;
+ long ncoords;
+ long s_byte_stride, t_byte_stride;
+ long s_nctl, t_nctl;
+ long s, t;
+ PyObject *v, *w, *pt;
+ double *pnext;
+ if (!PyArg_GetLongArraySize(args, 6, 0, &arg1))
+ return NULL;
+ if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ if (!PyArg_GetDoubleArray(args, 6, 0, arg1 , arg2))
+ return NULL;
+ if (!PyArg_GetLongArraySize(args, 6, 1, &arg3))
+ return NULL;
+ if ((arg4 = PyMem_NEW(double, arg3 )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ if (!PyArg_GetDoubleArray(args, 6, 1, arg3 , arg4))
+ return NULL;
+ if (!PyArg_GetLong(args, 6, 3, &arg6))
+ return NULL;
+ if (!PyArg_GetLong(args, 6, 4, &arg7))
+ return NULL;
+ if (!PyArg_GetLong(args, 6, 5, &arg8))
+ return NULL;
+ if (arg8 == N_XYZ)
+ ncoords = 3;
+ else if (arg8 == N_XYZW)
+ ncoords = 4;
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ s_nctl = arg1 - arg6;
+ t_nctl = arg3 - arg7;
+ if (!PyArg_GetObject(args, 6, 2, &v))
+ return NULL;
+ if (!PyList_Check(v) || PyList_Size(v) != s_nctl) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ((arg5 = PyMem_NEW(double, s_nctl*t_nctl*ncoords )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ pnext = arg5;
+ for (s = 0; s < s_nctl; s++) {
+ w = PyList_GetItem(v, s);
+ if (w == NULL || !PyList_Check(w) ||
+ PyList_Size(w) != t_nctl) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ for (t = 0; t < t_nctl; t++) {
+ pt = PyList_GetItem(w, t);
+ if (!PyArg_GetDoubleArray(pt, 1, 0, ncoords, pnext))
+ return NULL;
+ pnext += ncoords;
+ }
+ }
+ s_byte_stride = sizeof(double) * ncoords;
+ t_byte_stride = s_byte_stride * s_nctl;
+ nurbssurface( arg1 , arg2 , arg3 , arg4 ,
+ s_byte_stride , t_byte_stride , arg5 , arg6 , arg7 , arg8 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg4);
+ PyMem_DEL(arg5);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* nurbscurve(knots, ctlpoints, order, type).
+ The length of ctlpoints is len(knots)-order. */
+
+%nurbscurve
+
+static PyObject *
+gl_nurbscurve(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ long arg1 ;
+ double * arg2 ;
+ long arg3 ;
+ double * arg4 ;
+ long arg5 ;
+ long arg6 ;
+ int ncoords, npoints;
+ int i;
+ PyObject *v;
+ double *pnext;
+ if (!PyArg_GetLongArraySize(args, 4, 0, &arg1))
+ return NULL;
+ if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ if (!PyArg_GetDoubleArray(args, 4, 0, arg1 , arg2))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 2, &arg5))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 3, &arg6))
+ return NULL;
+ if (arg6 == N_ST)
+ ncoords = 2;
+ else if (arg6 == N_STW)
+ ncoords = 3;
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ npoints = arg1 - arg5;
+ if (!PyArg_GetObject(args, 4, 1, &v))
+ return NULL;
+ if (!PyList_Check(v) || PyList_Size(v) != npoints) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ((arg4 = PyMem_NEW(double, npoints*ncoords )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ pnext = arg4;
+ for (i = 0; i < npoints; i++) {
+ if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+ return NULL;
+ pnext += ncoords;
+ }
+ arg3 = (sizeof(double)) * ncoords;
+ nurbscurve( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg4);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* pwlcurve(points, type).
+ Points is a list of points. Type must be N_ST. */
+
+%pwlcurve
+
+static PyObject *
+gl_pwlcurve(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ PyObject *v;
+ long type;
+ double *data, *pnext;
+ long npoints, ncoords;
+ int i;
+ if (!PyArg_GetObject(args, 2, 0, &v))
+ return NULL;
+ if (!PyArg_GetLong(args, 2, 1, &type))
+ return NULL;
+ if (!PyList_Check(v)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ npoints = PyList_Size(v);
+ if (type == N_ST)
+ ncoords = 2;
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ((data = PyMem_NEW(double, npoints*ncoords)) == NULL) {
+ return PyErr_NoMemory();
+ }
+ pnext = data;
+ for (i = 0; i < npoints; i++) {
+ if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+ return NULL;
+ pnext += ncoords;
+ }
+ pwlcurve(npoints, data, sizeof(double)*ncoords, type);
+ PyMem_DEL(data);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* Picking and Selecting */
+
+static short *pickbuffer = NULL;
+static long pickbuffersize;
+
+static PyObject *
+pick_select(args, func)
+ PyObject *args;
+ void (*func)();
+{
+ if (!PyArg_GetLong(args, 1, 0, &pickbuffersize))
+ return NULL;
+ if (pickbuffer != NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "pick/gselect: already picking/selecting");
+ return NULL;
+ }
+ if ((pickbuffer = PyMem_NEW(short, pickbuffersize)) == NULL) {
+ return PyErr_NoMemory();
+ }
+ (*func)(pickbuffer, pickbuffersize);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+endpick_select(args, func)
+ PyObject *args;
+ long (*func)();
+{
+ PyObject *v, *w;
+ int i, nhits, n;
+ if (!PyArg_NoArgs(args))
+ return NULL;
+ if (pickbuffer == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "endpick/endselect: not in pick/select mode");
+ return NULL;
+ }
+ nhits = (*func)(pickbuffer);
+ if (nhits < 0) {
+ nhits = -nhits; /* How to report buffer overflow otherwise? */
+ }
+ /* Scan the buffer to see how many integers */
+ n = 0;
+ for (; nhits > 0; nhits--) {
+ n += 1 + pickbuffer[n];
+ }
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ /* XXX Could do it nicer and interpret the data structure here,
+ returning a list of lists. But this can be done in Python... */
+ for (i = 0; i < n; i++) {
+ w = PyInt_FromLong((long)pickbuffer[i]);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(v, i, w);
+ }
+ PyMem_DEL(pickbuffer);
+ pickbuffer = NULL;
+ return v;
+}
+
+extern void pick(), gselect();
+extern long endpick(), endselect();
+
+%pick
+static PyObject *gl_pick(self, args) PyObject *self, *args; {
+ return pick_select(args, pick);
+}
+
+%endpick
+static PyObject *gl_endpick(self, args) PyObject *self, *args; {
+ return endpick_select(args, endpick);
+}
+
+%gselect
+static PyObject *gl_gselect(self, args) PyObject *self, *args; {
+ return pick_select(args, gselect);
+}
+
+%endselect
+static PyObject *gl_endselect(self, args) PyObject *self, *args; {
+ return endpick_select(args, endselect);
+}
+
+
+/* XXX The generator botches this one. Here's a quick hack to fix it. */
+
+/* XXX The generator botches this one. Here's a quick hack to fix it. */
+
+% getmatrix float r[16]
+
+static PyObject *
+gl_getmatrix(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ Matrix arg1;
+ PyObject *v, *w;
+ int i, j;
+ getmatrix( arg1 );
+ v = PyList_New(16);
+ if (v == NULL) {
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
+ w = mknewfloatobject(arg1[i][j]);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(v, i*4+j, w);
+ }
+ return v;
+}
+
+/* Here's an alternate version that returns a 4x4 matrix instead of
+ a vector. Unfortunately it is incompatible with loadmatrix and
+ multmatrix... */
+
+% altgetmatrix float r[4][4]
+
+static PyObject *
+gl_altgetmatrix(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ Matrix arg1;
+ PyObject *v, *w;
+ int i, j;
+ getmatrix( arg1 );
+ v = PyList_New(4);
+ if (v == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < 4; i++) {
+ w = PyList_New(4);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(v, i, w);
+ }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ w = mknewfloatobject(arg1[i][j]);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(PyList_GetItem(v, i), j, w);
+ }
+ }
+ return v;
+}
+
+% lrectwrite
+
+static PyObject *
+gl_lrectwrite(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ short x1 ;
+ short y1 ;
+ short x2 ;
+ short y2 ;
+ string parray ;
+ PyObject *s;
+#if 0
+ int pixcount;
+#endif
+ if (!PyArg_GetShort(args, 5, 0, &x1))
+ return NULL;
+ if (!PyArg_GetShort(args, 5, 1, &y1))
+ return NULL;
+ if (!PyArg_GetShort(args, 5, 2, &x2))
+ return NULL;
+ if (!PyArg_GetShort(args, 5, 3, &y2))
+ return NULL;
+ if (!PyArg_GetString(args, 5, 4, &parray))
+ return NULL;
+ if (!PyArg_GetObject(args, 5, 4, &s))
+ return NULL;
+#if 0
+/* Don't check this, it breaks experiments with pixmode(PM_SIZE, ...) */
+ pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+ if (!PyString_Check(s) || PyString_Size(s) != pixcount*sizeof(long)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "string arg to lrectwrite has wrong size");
+ return NULL;
+ }
+#endif
+ lrectwrite( x1 , y1 , x2 , y2 , (unsigned long *) parray );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+% lrectread
+
+static PyObject *
+gl_lrectread(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ short x1 ;
+ short y1 ;
+ short x2 ;
+ short y2 ;
+ PyObject *parray;
+ int pixcount;
+ if (!PyArg_GetShort(args, 4, 0, &x1))
+ return NULL;
+ if (!PyArg_GetShort(args, 4, 1, &y1))
+ return NULL;
+ if (!PyArg_GetShort(args, 4, 2, &x2))
+ return NULL;
+ if (!PyArg_GetShort(args, 4, 3, &y2))
+ return NULL;
+ pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+ parray = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+ if (parray == NULL)
+ return NULL; /* No memory */
+ lrectread(x1, y1, x2, y2, (unsigned long *) PyString_AsString(parray));
+ return parray;
+}
+
+% readdisplay
+
+static PyObject *
+gl_readdisplay(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ short x1, y1, x2, y2;
+ unsigned long *parray, hints;
+ long size, size_ret;
+ PyObject *rv;
+
+ if ( !PyArg_Parse(args, "hhhhl", &x1, &y1, &x2, &y2, &hints) )
+ return 0;
+ size = (long)(x2+1-x1) * (long)(y2+1-y1);
+ rv = PyString_FromStringAndSize((char *)NULL, size*sizeof(long));
+ if ( rv == NULL )
+ return NULL;
+ parray = (unsigned long *)PyString_AsString(rv);
+ size_ret = readdisplay(x1, y1, x2, y2, parray, hints);
+ if ( size_ret != size ) {
+ printf("gl_readdisplay: got %ld pixels, expected %ld\n",
+ size_ret, size);
+ PyErr_SetString(PyExc_RuntimeError, "readdisplay returned unexpected length");
+ return NULL;
+ }
+ return rv;
+}
+
+/* Desperately needed, here are tools to compress and decompress
+ the data manipulated by lrectread/lrectwrite.
+
+ gl.packrect(width, height, packfactor, bigdata) --> smalldata
+ makes 'bigdata' 4*(packfactor**2) times smaller by:
+ - turning it into B/W (a factor 4)
+ - replacing squares of size pacfactor by one
+ representative
+
+ gl.unpackrect(width, height, packfactor, smalldata) --> bigdata
+ is the inverse; the numeric arguments must be *the same*.
+
+ Both work best if width and height are multiples of packfactor
+ (in fact unpackrect will leave garbage bytes).
+*/
+
+% packrect
+
+static PyObject *
+gl_packrect(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ long width, height, packfactor;
+ char *s;
+ PyObject *unpacked, *packed;
+ int pixcount, packedcount, x, y, r, g, b;
+ unsigned long pixel;
+ unsigned char *p;
+ unsigned long *parray;
+ if (!PyArg_GetLong(args, 4, 0, &width))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 1, &height))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 2, &packfactor))
+ return NULL;
+ if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+ return NULL;
+ if (!PyArg_GetObject(args, 4, 3, &unpacked))
+ return NULL;
+ if (width <= 0 || height <= 0 || packfactor <= 0) {
+ PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+ return NULL;
+ }
+ pixcount = width*height;
+ packedcount = ((width+packfactor-1)/packfactor) *
+ ((height+packfactor-1)/packfactor);
+ if (PyString_Size(unpacked) != pixcount*sizeof(long)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "string arg to packrect has wrong size");
+ return NULL;
+ }
+ packed = PyString_FromStringAndSize((char *)NULL, packedcount);
+ if (packed == NULL)
+ return NULL;
+ parray = (unsigned long *) PyString_AsString(unpacked);
+ p = (unsigned char *) PyString_AsString(packed);
+ for (y = 0; y < height; y += packfactor, parray += packfactor*width) {
+ for (x = 0; x < width; x += packfactor) {
+ pixel = parray[x];
+ r = pixel & 0xff;
+ g = (pixel >> 8) & 0xff;
+ b = (pixel >> 16) & 0xff;
+ *p++ = (30*r+59*g+11*b) / 100;
+ }
+ }
+ return packed;
+}
+
+% unpackrect
+
+static unsigned long unpacktab[256];
+static int unpacktab_inited = 0;
+
+static PyObject *
+gl_unpackrect(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ long width, height, packfactor;
+ char *s;
+ PyObject *unpacked, *packed;
+ int pixcount, packedcount;
+ register unsigned char *p;
+ register unsigned long *parray;
+ if (!unpacktab_inited) {
+ register int white;
+ for (white = 256; --white >= 0; )
+ unpacktab[white] = white * 0x010101L;
+ unpacktab_inited++;
+ }
+ if (!PyArg_GetLong(args, 4, 0, &width))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 1, &height))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 2, &packfactor))
+ return NULL;
+ if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+ return NULL;
+ if (!PyArg_GetObject(args, 4, 3, &packed))
+ return NULL;
+ if (width <= 0 || height <= 0 || packfactor <= 0) {
+ PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+ return NULL;
+ }
+ pixcount = width*height;
+ packedcount = ((width+packfactor-1)/packfactor) *
+ ((height+packfactor-1)/packfactor);
+ if (PyString_Size(packed) != packedcount) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "string arg to unpackrect has wrong size");
+ return NULL;
+ }
+ unpacked = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+ if (unpacked == NULL)
+ return NULL;
+ parray = (unsigned long *) PyString_AsString(unpacked);
+ p = (unsigned char *) PyString_AsString(packed);
+ if (packfactor == 1 && width*height > 0) {
+ /* Just expand bytes to longs */
+ register int x = width * height;
+ do {
+ *parray++ = unpacktab[*p++];
+ } while (--x >= 0);
+ }
+ else {
+ register int y;
+ for (y = 0; y < height-packfactor+1;
+ y += packfactor, parray += packfactor*width) {
+ register int x;
+ for (x = 0; x < width-packfactor+1; x += packfactor) {
+ register unsigned long pixel = unpacktab[*p++];
+ register int i;
+ for (i = packfactor*width; (i-=width) >= 0;) {
+ register int j;
+ for (j = packfactor; --j >= 0; )
+ parray[i+x+j] = pixel;
+ }
+ }
+ }
+ }
+ return unpacked;
+}
+
+% gversion
+static PyObject *
+gl_gversion(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char buf[20];
+ gversion(buf);
+ return PyString_FromString(buf);
+}
+
+
+/* void clear - Manual because of clash with termcap */
+%clear
+static PyObject *
+gl_clear(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ __GLclear( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* End of manually written stubs */
+
+%%
+
+long getshade
+if !solaris void devport short s long s
+void rdr2i long s long s
+void rectfs short s short s short s short s
+void rects short s short s short s short s
+void rmv2i long s long s
+void noport
+void popviewport
+void clearhitcode
+void closeobj
+void cursoff
+void curson
+void doublebuffer
+void finish
+void gconfig
+void ginit
+void greset
+void multimap
+void onemap
+void popattributes
+void popmatrix
+void pushattributes
+void pushmatrix
+void pushviewport
+void qreset
+void RGBmode
+void singlebuffer
+void swapbuffers
+void gsync
+void gflush
+void tpon
+void tpoff
+void clkon
+void clkoff
+void ringbell
+#void callfunc
+void gbegin
+void textinit
+void initnames
+void pclos
+void popname
+if !solaris void spclos
+void zclear
+void screenspace
+void reshapeviewport
+void winpush
+void winpop
+void foreground
+void endfullscrn
+if !solaris void endpupmode
+void fullscrn
+if !solaris void pupmode
+void winconstraints
+void pagecolor short s
+void textcolor short s
+void color short s
+void curveit short s
+void font short s
+void linewidth short s
+void setlinestyle short s
+void setmap short s
+void swapinterval short s
+void writemask short s
+if !solaris void textwritemask short s
+void qdevice short s
+void unqdevice short s
+void curvebasis short s
+void curveprecision short s
+void loadname short s
+void passthrough short s
+void pushname short s
+void setmonitor short s
+if !solaris void setshade short s
+void setpattern short s
+if !solaris void pagewritemask short s
+#
+void callobj long s
+void delobj long s
+void editobj long s
+void makeobj long s
+void maketag long s
+void chunksize long s
+void compactify long s
+void deltag long s
+void lsrepeat long s
+void objinsert long s
+void objreplace long s
+void winclose long s
+void blanktime long s
+void freepup long s
+# This is not in the library!?
+###void pupcolor long s
+#
+void backbuffer long s
+void frontbuffer long s
+if !solaris void lsbackup long s
+void resetls long s
+void lampon long s
+void lampoff long s
+void setbell long s
+void blankscreen long s
+void depthcue long s
+void zbuffer long s
+void backface long s
+#
+void cmov2i long s long s
+void draw2i long s long s
+void move2i long s long s
+void pnt2i long s long s
+void patchbasis long s long s
+void patchprecision long s long s
+void pdr2i long s long s
+void pmv2i long s long s
+void rpdr2i long s long s
+void rpmv2i long s long s
+void xfpt2i long s long s
+void objdelete long s long s
+void patchcurves long s long s
+void minsize long s long s
+void maxsize long s long s
+void keepaspect long s long s
+void prefsize long s long s
+void stepunit long s long s
+void fudge long s long s
+void winmove long s long s
+#
+void attachcursor short s short s
+void deflinestyle short s short s
+void noise short s short s
+void picksize short s short s
+void qenter short s short s
+void setdepth short s short s
+void cmov2s short s short s
+void draw2s short s short s
+void move2s short s short s
+void pdr2s short s short s
+void pmv2s short s short s
+void pnt2s short s short s
+void rdr2s short s short s
+void rmv2s short s short s
+void rpdr2s short s short s
+void rpmv2s short s short s
+void xfpt2s short s short s
+#
+void cmov2 float s float s
+void draw2 float s float s
+void move2 float s float s
+void pnt2 float s float s
+void pdr2 float s float s
+void pmv2 float s float s
+void rdr2 float s float s
+void rmv2 float s float s
+void rpdr2 float s float s
+void rpmv2 float s float s
+void xfpt2 float s float s
+#
+void loadmatrix float s[4*4]
+# Really [4][4]
+void multmatrix float s[4*4]
+# Really [4][4]
+void crv float s[3*4]
+# Really [4][3]
+void rcrv float s[4*4]
+# Really [4][4]
+#
+# Methods that have strings.
+#
+void addtopup long s char *s long s
+void charstr char *s
+void getport char *s
+long strwidth char *s
+long winopen char *s
+void wintitle char *s
+#
+# Methods that have 1 long (# of elements) and an array
+#
+void polf long s float s[3*arg1]
+void polf2 long s float s[2*arg1]
+void poly long s float s[3*arg1]
+void poly2 long s float s[2*arg1]
+void crvn long s float s[3*arg1]
+void rcrvn long s float s[4*arg1]
+#
+void polf2i long s long s[2*arg1]
+void polfi long s long s[3*arg1]
+void poly2i long s long s[2*arg1]
+void polyi long s long s[3*arg1]
+#
+void polf2s long s short s[2*arg1]
+void polfs long s short s[3*arg1]
+void polys long s short s[3*arg1]
+void poly2s long s short s[2*arg1]
+#
+void defcursor short s u_short s[128]
+# Is this useful?
+void writepixels short s u_short s[arg1]
+# Should be unsigned short...
+void defbasis long s float s[4*4]
+if !solaris void gewrite short s short s[arg1]
+#
+void rotate short s char s
+# This is not in the library!?
+###void setbutton short s char s
+void rot float s char s
+#
+void circfi long s long s long s
+void circi long s long s long s
+void cmovi long s long s long s
+void drawi long s long s long s
+void movei long s long s long s
+void pnti long s long s long s
+void newtag long s long s long s
+void pdri long s long s long s
+void pmvi long s long s long s
+void rdri long s long s long s
+void rmvi long s long s long s
+void rpdri long s long s long s
+void rpmvi long s long s long s
+void xfpti long s long s long s
+#
+void circ float s float s float s
+void circf float s float s float s
+void cmov float s float s float s
+void draw float s float s float s
+void move float s float s float s
+void pnt float s float s float s
+void scale float s float s float s
+void translate float s float s float s
+void pdr float s float s float s
+void pmv float s float s float s
+void rdr float s float s float s
+void rmv float s float s float s
+void rpdr float s float s float s
+void rpmv float s float s float s
+void xfpt float s float s float s
+#
+void RGBcolor short s short s short s
+void RGBwritemask short s short s short s
+void setcursor short s short s short s
+void tie short s short s short s
+void circfs short s short s short s
+void circs short s short s short s
+void cmovs short s short s short s
+void draws short s short s short s
+void moves short s short s short s
+void pdrs short s short s short s
+void pmvs short s short s short s
+void pnts short s short s short s
+void rdrs short s short s short s
+void rmvs short s short s short s
+void rpdrs short s short s short s
+void rpmvs short s short s short s
+void xfpts short s short s short s
+void curorigin short s short s short s
+void cyclemap short s short s short s
+#
+void patch float s[4*4] float s[4*4] float s[4*4]
+void splf long s float s[3*arg1] u_short s[arg1]
+void splf2 long s float s[2*arg1] u_short s[arg1]
+void splfi long s long s[3*arg1] u_short s[arg1]
+void splf2i long s long s[2*arg1] u_short s[arg1]
+void splfs long s short s[3*arg1] u_short s[arg1]
+void splf2s long s short s[2*arg1] u_short s[arg1]
+###void defpattern short s short s u_short s[arg2*arg2/16]
+#
+void rpatch float s[4*4] float s[4*4] float s[4*4] float s[4*4]
+#
+# routines that send 4 floats
+#
+void ortho2 float s float s float s float s
+void rect float s float s float s float s
+void rectf float s float s float s float s
+void xfpt4 float s float s float s float s
+#
+void textport short s short s short s short s
+void mapcolor short s short s short s short s
+void scrmask short s short s short s short s
+void setvaluator short s short s short s short s
+void viewport short s short s short s short s
+void shaderange short s short s short s short s
+void xfpt4s short s short s short s short s
+void rectfi long s long s long s long s
+void recti long s long s long s long s
+void xfpt4i long s long s long s long s
+void prefposition long s long s long s long s
+#
+void arc float s float s float s short s short s
+void arcf float s float s float s short s short s
+void arcfi long s long s long s short s short s
+void arci long s long s long s short s short s
+#
+void bbox2 short s short s float s float s float s float s
+void bbox2i short s short s long s long s long s long s
+void bbox2s short s short s short s short s short s short s
+void blink short s short s short s short s short s
+void ortho float s float s float s float s float s float s
+void window float s float s float s float s float s float s
+void lookat float s float s float s float s float s float s short s
+#
+void perspective short s float s float s float s
+void polarview float s short s short s short s
+# XXX getichararray not supported
+#void writeRGB short s char s[arg1] char s[arg1] char s[arg1]
+#
+void arcfs short s short s short s short s short s
+void arcs short s short s short s short s short s
+void rectcopy short s short s short s short s short s short s
+if !solaris void RGBcursor short s short s short s short s short s short s short s
+#
+long getbutton short s
+long getcmmode
+long getlsbackup
+long getresetls
+long getdcm
+long getzbuffer
+long ismex
+long isobj long s
+long isqueued short s
+long istag long s
+#
+long genobj
+long gentag
+long getbuffer
+long getcolor
+long getdisplaymode
+long getfont
+long getheight
+long gethitcode
+long getlstyle
+long getlwidth
+long getmap
+long getplanes
+long getwritemask
+long qtest
+long getlsrepeat
+long getmonitor
+long getopenobj
+long getpattern
+long winget
+long winattach
+long getothermonitor
+long newpup
+#
+long getvaluator short s
+void winset long s
+long dopup long s
+void getdepth short r short r
+void getcpos short r short r
+void getsize long r long r
+void getorigin long r long r
+void getviewport short r short r short r short r
+if !solaris void gettp short r short r short r short r
+void getgpos float r float r float r float r
+void winposition long s long s long s long s
+void gRGBcolor short r short r short r
+void gRGBmask short r short r short r
+void getscrmask short r short r short r short r
+###void gRGBcursor short r short r short r short r short r short r short r short r
+void getmcolor short s short r short r short r
+void mapw long s short s short s float r float r float r float r float r float r
+void mapw2 long s short s short s float r float r
+###void defrasterfont short s short s short s Fontchar s[arg3] short s short s[4*arg5]
+###long qread short r
+void getcursor short r u_short r u_short r long r
+#
+# For these we receive arrays of stuff
+#
+###void getdev long s short s[arg1] short r[arg1]
+#XXX not generated correctly yet
+#void getmatrix float r[16]
+###long readpixels short s short r[retval]
+###long readRGB short s char r[retval] char r[retval] char r[retval]
+###long blkqread short s short r[arg1]
+#
+# New 4D routines
+#
+void cmode
+void concave long s
+void curstype long s
+void drawmode long s
+void gammaramp short s[256] short s[256] short s[256]
+long getbackface
+long getdescender
+long getdrawmode
+long getmmode
+long getsm
+long getvideo long s
+void imakebackground
+void lmbind short s short s
+void lmdef long s long s long s float s[arg3]
+void mmode long s
+void normal float s[3]
+void overlay long s
+void RGBrange short s short s short s short s short s short s short s short s
+if !solaris void setvideo long s long s
+void shademodel long s
+void underlay long s
+#
+# New Personal Iris/GT Routines
+#
+void bgnclosedline
+void bgnline
+void bgnpoint
+void bgnpolygon
+void bgnsurface
+void bgntmesh
+void bgntrim
+void endclosedline
+void endline
+void endpoint
+void endpolygon
+void endsurface
+void endtmesh
+void endtrim
+void blendfunction long s long s
+void c3f float s[3]
+void c3i long s[3]
+void c3s short s[3]
+void c4f float s[4]
+void c4i long s[4]
+void c4s short s[4]
+void colorf float s
+void cpack long s
+void czclear long s long s
+void dglclose long s
+long dglopen char *s long s
+long getgdesc long s
+void getnurbsproperty long s float r
+void glcompat long s long s
+void iconsize long s long s
+void icontitle char *s
+void lRGBrange short s short s short s short s short s short s long s long s
+void linesmooth long s
+void lmcolor long s
+void logicop long s
+###long lrectread short s short s short s short s long r[retval]
+###void lrectwrite short s short s short s short s long s[(arg2-arg1+1)*(arg4-arg3+1)]
+### Now manual, with string last arg
+###long rectread short s short s short s short s short r[retval]
+###void rectwrite short s short s short s short s short s[(arg2-arg1+1)*(arg4-arg3+1)]
+void lsetdepth long s long s
+void lshaderange short s short s long s long s
+void n3f float s[3]
+void noborder
+void pntsmooth long s
+void readsource long s
+void rectzoom float s float s
+void sbox float s float s float s float s
+void sboxi long s long s long s long s
+void sboxs short s short s short s short s
+void sboxf float s float s float s float s
+void sboxfi long s long s long s long s
+void sboxfs short s short s short s short s
+void setnurbsproperty long s float s
+void setpup long s long s long s
+void smoothline long s
+void subpixel long s
+void swaptmesh
+long swinopen long s
+void v2f float s[2]
+void v2i long s[2]
+void v2s short s[2]
+void v3f float s[3]
+void v3i long s[3]
+void v3s short s[3]
+void v4f float s[4]
+void v4i long s[4]
+void v4s short s[4]
+void videocmd long s
+long windepth long s
+void wmpack long s
+void zdraw long s
+void zfunction long s
+void zsource long s
+void zwritemask long s
+#
+# uses doubles
+#
+void v2d double s[2]
+void v3d double s[3]
+void v4d double s[4]
+#
+# Why isn't this here?
+#
+void pixmode long s long s
+#
+# New in IRIX 4.0
+#
+long qgetfd
+void dither long s
diff --git a/sys/src/cmd/python/Modules/datetimemodule.c b/sys/src/cmd/python/Modules/datetimemodule.c
new file mode 100644
index 000000000..8207ffd0c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/datetimemodule.c
@@ -0,0 +1,4988 @@
+/* C implementation for the date/time type documented at
+ * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
+ */
+
+#include "Python.h"
+#include "modsupport.h"
+#include "structmember.h"
+
+#include <time.h>
+
+#include "timefuncs.h"
+
+/* Differentiate between building the core module and building extension
+ * modules.
+ */
+#define Py_BUILD_CORE
+#include "datetime.h"
+#undef Py_BUILD_CORE
+
+/* We require that C int be at least 32 bits, and use int virtually
+ * everywhere. In just a few cases we use a temp long, where a Python
+ * API returns a C long. In such cases, we have to ensure that the
+ * final result fits in a C int (this can be an issue on 64-bit boxes).
+ */
+#if SIZEOF_INT < 4
+# error "datetime.c requires that C int have at least 32 bits"
+#endif
+
+#define MINYEAR 1
+#define MAXYEAR 9999
+
+/* Nine decimal digits is easy to communicate, and leaves enough room
+ * so that two delta days can be added w/o fear of overflowing a signed
+ * 32-bit int, and with plenty of room left over to absorb any possible
+ * carries from adding seconds.
+ */
+#define MAX_DELTA_DAYS 999999999
+
+/* Rename the long macros in datetime.h to more reasonable short names. */
+#define GET_YEAR PyDateTime_GET_YEAR
+#define GET_MONTH PyDateTime_GET_MONTH
+#define GET_DAY PyDateTime_GET_DAY
+#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
+#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
+#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
+#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
+
+/* Date accessors for date and datetime. */
+#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
+ ((o)->data[1] = ((v) & 0x00ff)))
+#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
+#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
+
+/* Date/Time accessors for datetime. */
+#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
+#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
+#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
+#define DATE_SET_MICROSECOND(o, v) \
+ (((o)->data[7] = ((v) & 0xff0000) >> 16), \
+ ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
+ ((o)->data[9] = ((v) & 0x0000ff)))
+
+/* Time accessors for time. */
+#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
+#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
+#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
+#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
+#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
+#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
+#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
+#define TIME_SET_MICROSECOND(o, v) \
+ (((o)->data[3] = ((v) & 0xff0000) >> 16), \
+ ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
+ ((o)->data[5] = ((v) & 0x0000ff)))
+
+/* Delta accessors for timedelta. */
+#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
+#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
+#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
+
+#define SET_TD_DAYS(o, v) ((o)->days = (v))
+#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
+#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
+
+/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
+ * p->hastzinfo.
+ */
+#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
+
+/* M is a char or int claiming to be a valid month. The macro is equivalent
+ * to the two-sided Python test
+ * 1 <= M <= 12
+ */
+#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
+
+/* Forward declarations. */
+static PyTypeObject PyDateTime_DateType;
+static PyTypeObject PyDateTime_DateTimeType;
+static PyTypeObject PyDateTime_DeltaType;
+static PyTypeObject PyDateTime_TimeType;
+static PyTypeObject PyDateTime_TZInfoType;
+
+/* ---------------------------------------------------------------------------
+ * Math utilities.
+ */
+
+/* k = i+j overflows iff k differs in sign from both inputs,
+ * iff k^i has sign bit set and k^j has sign bit set,
+ * iff (k^i)&(k^j) has sign bit set.
+ */
+#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
+ ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
+
+/* Compute Python divmod(x, y), returning the quotient and storing the
+ * remainder into *r. The quotient is the floor of x/y, and that's
+ * the real point of this. C will probably truncate instead (C99
+ * requires truncation; C89 left it implementation-defined).
+ * Simplification: we *require* that y > 0 here. That's appropriate
+ * for all the uses made of it. This simplifies the code and makes
+ * the overflow case impossible (divmod(LONG_MIN, -1) is the only
+ * overflow case).
+ */
+static int
+divmod(int x, int y, int *r)
+{
+ int quo;
+
+ assert(y > 0);
+ quo = x / y;
+ *r = x - quo * y;
+ if (*r < 0) {
+ --quo;
+ *r += y;
+ }
+ assert(0 <= *r && *r < y);
+ return quo;
+}
+
+/* Round a double to the nearest long. |x| must be small enough to fit
+ * in a C long; this is not checked.
+ */
+static long
+round_to_long(double x)
+{
+ if (x >= 0.0)
+ x = floor(x + 0.5);
+ else
+ x = ceil(x - 0.5);
+ return (long)x;
+}
+
+/* ---------------------------------------------------------------------------
+ * General calendrical helper functions
+ */
+
+/* For each month ordinal in 1..12, the number of days in that month,
+ * and the number of days before that month in the same year. These
+ * are correct for non-leap years only.
+ */
+static int _days_in_month[] = {
+ 0, /* unused; this vector uses 1-based indexing */
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+static int _days_before_month[] = {
+ 0, /* unused; this vector uses 1-based indexing */
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
+/* year -> 1 if leap year, else 0. */
+static int
+is_leap(int year)
+{
+ /* Cast year to unsigned. The result is the same either way, but
+ * C can generate faster code for unsigned mod than for signed
+ * mod (especially for % 4 -- a good compiler should just grab
+ * the last 2 bits when the LHS is unsigned).
+ */
+ const unsigned int ayear = (unsigned int)year;
+ return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
+}
+
+/* year, month -> number of days in that month in that year */
+static int
+days_in_month(int year, int month)
+{
+ assert(month >= 1);
+ assert(month <= 12);
+ if (month == 2 && is_leap(year))
+ return 29;
+ else
+ return _days_in_month[month];
+}
+
+/* year, month -> number of days in year preceeding first day of month */
+static int
+days_before_month(int year, int month)
+{
+ int days;
+
+ assert(month >= 1);
+ assert(month <= 12);
+ days = _days_before_month[month];
+ if (month > 2 && is_leap(year))
+ ++days;
+ return days;
+}
+
+/* year -> number of days before January 1st of year. Remember that we
+ * start with year 1, so days_before_year(1) == 0.
+ */
+static int
+days_before_year(int year)
+{
+ int y = year - 1;
+ /* This is incorrect if year <= 0; we really want the floor
+ * here. But so long as MINYEAR is 1, the smallest year this
+ * can see is 0 (this can happen in some normalization endcases),
+ * so we'll just special-case that.
+ */
+ assert (year >= 0);
+ if (y >= 0)
+ return y*365 + y/4 - y/100 + y/400;
+ else {
+ assert(y == -1);
+ return -366;
+ }
+}
+
+/* Number of days in 4, 100, and 400 year cycles. That these have
+ * the correct values is asserted in the module init function.
+ */
+#define DI4Y 1461 /* days_before_year(5); days in 4 years */
+#define DI100Y 36524 /* days_before_year(101); days in 100 years */
+#define DI400Y 146097 /* days_before_year(401); days in 400 years */
+
+/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
+static void
+ord_to_ymd(int ordinal, int *year, int *month, int *day)
+{
+ int n, n1, n4, n100, n400, leapyear, preceding;
+
+ /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
+ * leap years repeats exactly every 400 years. The basic strategy is
+ * to find the closest 400-year boundary at or before ordinal, then
+ * work with the offset from that boundary to ordinal. Life is much
+ * clearer if we subtract 1 from ordinal first -- then the values
+ * of ordinal at 400-year boundaries are exactly those divisible
+ * by DI400Y:
+ *
+ * D M Y n n-1
+ * -- --- ---- ---------- ----------------
+ * 31 Dec -400 -DI400Y -DI400Y -1
+ * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
+ * ...
+ * 30 Dec 000 -1 -2
+ * 31 Dec 000 0 -1
+ * 1 Jan 001 1 0 400-year boundary
+ * 2 Jan 001 2 1
+ * 3 Jan 001 3 2
+ * ...
+ * 31 Dec 400 DI400Y DI400Y -1
+ * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
+ */
+ assert(ordinal >= 1);
+ --ordinal;
+ n400 = ordinal / DI400Y;
+ n = ordinal % DI400Y;
+ *year = n400 * 400 + 1;
+
+ /* Now n is the (non-negative) offset, in days, from January 1 of
+ * year, to the desired date. Now compute how many 100-year cycles
+ * precede n.
+ * Note that it's possible for n100 to equal 4! In that case 4 full
+ * 100-year cycles precede the desired day, which implies the
+ * desired day is December 31 at the end of a 400-year cycle.
+ */
+ n100 = n / DI100Y;
+ n = n % DI100Y;
+
+ /* Now compute how many 4-year cycles precede it. */
+ n4 = n / DI4Y;
+ n = n % DI4Y;
+
+ /* And now how many single years. Again n1 can be 4, and again
+ * meaning that the desired day is December 31 at the end of the
+ * 4-year cycle.
+ */
+ n1 = n / 365;
+ n = n % 365;
+
+ *year += n100 * 100 + n4 * 4 + n1;
+ if (n1 == 4 || n100 == 4) {
+ assert(n == 0);
+ *year -= 1;
+ *month = 12;
+ *day = 31;
+ return;
+ }
+
+ /* Now the year is correct, and n is the offset from January 1. We
+ * find the month via an estimate that's either exact or one too
+ * large.
+ */
+ leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
+ assert(leapyear == is_leap(*year));
+ *month = (n + 50) >> 5;
+ preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
+ if (preceding > n) {
+ /* estimate is too large */
+ *month -= 1;
+ preceding -= days_in_month(*year, *month);
+ }
+ n -= preceding;
+ assert(0 <= n);
+ assert(n < days_in_month(*year, *month));
+
+ *day = n + 1;
+}
+
+/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
+static int
+ymd_to_ord(int year, int month, int day)
+{
+ return days_before_year(year) + days_before_month(year, month) + day;
+}
+
+/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
+static int
+weekday(int year, int month, int day)
+{
+ return (ymd_to_ord(year, month, day) + 6) % 7;
+}
+
+/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
+ * first calendar week containing a Thursday.
+ */
+static int
+iso_week1_monday(int year)
+{
+ int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
+ /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
+ int first_weekday = (first_day + 6) % 7;
+ /* ordinal of closest Monday at or before 1/1 */
+ int week1_monday = first_day - first_weekday;
+
+ if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
+ week1_monday += 7;
+ return week1_monday;
+}
+
+/* ---------------------------------------------------------------------------
+ * Range checkers.
+ */
+
+/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
+ * If not, raise OverflowError and return -1.
+ */
+static int
+check_delta_day_range(int days)
+{
+ if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
+ return 0;
+ PyErr_Format(PyExc_OverflowError,
+ "days=%d; must have magnitude <= %d",
+ days, MAX_DELTA_DAYS);
+ return -1;
+}
+
+/* Check that date arguments are in range. Return 0 if they are. If they
+ * aren't, raise ValueError and return -1.
+ */
+static int
+check_date_args(int year, int month, int day)
+{
+
+ if (year < MINYEAR || year > MAXYEAR) {
+ PyErr_SetString(PyExc_ValueError,
+ "year is out of range");
+ return -1;
+ }
+ if (month < 1 || month > 12) {
+ PyErr_SetString(PyExc_ValueError,
+ "month must be in 1..12");
+ return -1;
+ }
+ if (day < 1 || day > days_in_month(year, month)) {
+ PyErr_SetString(PyExc_ValueError,
+ "day is out of range for month");
+ return -1;
+ }
+ return 0;
+}
+
+/* Check that time arguments are in range. Return 0 if they are. If they
+ * aren't, raise ValueError and return -1.
+ */
+static int
+check_time_args(int h, int m, int s, int us)
+{
+ if (h < 0 || h > 23) {
+ PyErr_SetString(PyExc_ValueError,
+ "hour must be in 0..23");
+ return -1;
+ }
+ if (m < 0 || m > 59) {
+ PyErr_SetString(PyExc_ValueError,
+ "minute must be in 0..59");
+ return -1;
+ }
+ if (s < 0 || s > 59) {
+ PyErr_SetString(PyExc_ValueError,
+ "second must be in 0..59");
+ return -1;
+ }
+ if (us < 0 || us > 999999) {
+ PyErr_SetString(PyExc_ValueError,
+ "microsecond must be in 0..999999");
+ return -1;
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------
+ * Normalization utilities.
+ */
+
+/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
+ * factor "lo" units. factor must be > 0. If *lo is less than 0, or
+ * at least factor, enough of *lo is converted into "hi" units so that
+ * 0 <= *lo < factor. The input values must be such that int overflow
+ * is impossible.
+ */
+static void
+normalize_pair(int *hi, int *lo, int factor)
+{
+ assert(factor > 0);
+ assert(lo != hi);
+ if (*lo < 0 || *lo >= factor) {
+ const int num_hi = divmod(*lo, factor, lo);
+ const int new_hi = *hi + num_hi;
+ assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
+ *hi = new_hi;
+ }
+ assert(0 <= *lo && *lo < factor);
+}
+
+/* Fiddle days (d), seconds (s), and microseconds (us) so that
+ * 0 <= *s < 24*3600
+ * 0 <= *us < 1000000
+ * The input values must be such that the internals don't overflow.
+ * The way this routine is used, we don't get close.
+ */
+static void
+normalize_d_s_us(int *d, int *s, int *us)
+{
+ if (*us < 0 || *us >= 1000000) {
+ normalize_pair(s, us, 1000000);
+ /* |s| can't be bigger than about
+ * |original s| + |original us|/1000000 now.
+ */
+
+ }
+ if (*s < 0 || *s >= 24*3600) {
+ normalize_pair(d, s, 24*3600);
+ /* |d| can't be bigger than about
+ * |original d| +
+ * (|original s| + |original us|/1000000) / (24*3600) now.
+ */
+ }
+ assert(0 <= *s && *s < 24*3600);
+ assert(0 <= *us && *us < 1000000);
+}
+
+/* Fiddle years (y), months (m), and days (d) so that
+ * 1 <= *m <= 12
+ * 1 <= *d <= days_in_month(*y, *m)
+ * The input values must be such that the internals don't overflow.
+ * The way this routine is used, we don't get close.
+ */
+static void
+normalize_y_m_d(int *y, int *m, int *d)
+{
+ int dim; /* # of days in month */
+
+ /* This gets muddy: the proper range for day can't be determined
+ * without knowing the correct month and year, but if day is, e.g.,
+ * plus or minus a million, the current month and year values make
+ * no sense (and may also be out of bounds themselves).
+ * Saying 12 months == 1 year should be non-controversial.
+ */
+ if (*m < 1 || *m > 12) {
+ --*m;
+ normalize_pair(y, m, 12);
+ ++*m;
+ /* |y| can't be bigger than about
+ * |original y| + |original m|/12 now.
+ */
+ }
+ assert(1 <= *m && *m <= 12);
+
+ /* Now only day can be out of bounds (year may also be out of bounds
+ * for a datetime object, but we don't care about that here).
+ * If day is out of bounds, what to do is arguable, but at least the
+ * method here is principled and explainable.
+ */
+ dim = days_in_month(*y, *m);
+ if (*d < 1 || *d > dim) {
+ /* Move day-1 days from the first of the month. First try to
+ * get off cheap if we're only one day out of range
+ * (adjustments for timezone alone can't be worse than that).
+ */
+ if (*d == 0) {
+ --*m;
+ if (*m > 0)
+ *d = days_in_month(*y, *m);
+ else {
+ --*y;
+ *m = 12;
+ *d = 31;
+ }
+ }
+ else if (*d == dim + 1) {
+ /* move forward a day */
+ ++*m;
+ *d = 1;
+ if (*m > 12) {
+ *m = 1;
+ ++*y;
+ }
+ }
+ else {
+ int ordinal = ymd_to_ord(*y, *m, 1) +
+ *d - 1;
+ ord_to_ymd(ordinal, y, m, d);
+ }
+ }
+ assert(*m > 0);
+ assert(*d > 0);
+}
+
+/* Fiddle out-of-bounds months and days so that the result makes some kind
+ * of sense. The parameters are both inputs and outputs. Returns < 0 on
+ * failure, where failure means the adjusted year is out of bounds.
+ */
+static int
+normalize_date(int *year, int *month, int *day)
+{
+ int result;
+
+ normalize_y_m_d(year, month, day);
+ if (MINYEAR <= *year && *year <= MAXYEAR)
+ result = 0;
+ else {
+ PyErr_SetString(PyExc_OverflowError,
+ "date value out of range");
+ result = -1;
+ }
+ return result;
+}
+
+/* Force all the datetime fields into range. The parameters are both
+ * inputs and outputs. Returns < 0 on error.
+ */
+static int
+normalize_datetime(int *year, int *month, int *day,
+ int *hour, int *minute, int *second,
+ int *microsecond)
+{
+ normalize_pair(second, microsecond, 1000000);
+ normalize_pair(minute, second, 60);
+ normalize_pair(hour, minute, 60);
+ normalize_pair(day, hour, 24);
+ return normalize_date(year, month, day);
+}
+
+/* ---------------------------------------------------------------------------
+ * Basic object allocation: tp_alloc implementations. These allocate
+ * Python objects of the right size and type, and do the Python object-
+ * initialization bit. If there's not enough memory, they return NULL after
+ * setting MemoryError. All data members remain uninitialized trash.
+ *
+ * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
+ * member is needed. This is ugly, imprecise, and possibly insecure.
+ * tp_basicsize for the time and datetime types is set to the size of the
+ * struct that has room for the tzinfo member, so subclasses in Python will
+ * allocate enough space for a tzinfo member whether or not one is actually
+ * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
+ * part is that PyType_GenericAlloc() (which subclasses in Python end up
+ * using) just happens today to effectively ignore the nitems argument
+ * when tp_itemsize is 0, which it is for these type objects. If that
+ * changes, perhaps the callers of tp_alloc slots in this file should
+ * be changed to force a 0 nitems argument unless the type being allocated
+ * is a base type implemented in this file (so that tp_alloc is time_alloc
+ * or datetime_alloc below, which know about the nitems abuse).
+ */
+
+static PyObject *
+time_alloc(PyTypeObject *type, Py_ssize_t aware)
+{
+ PyObject *self;
+
+ self = (PyObject *)
+ PyObject_MALLOC(aware ?
+ sizeof(PyDateTime_Time) :
+ sizeof(_PyDateTime_BaseTime));
+ if (self == NULL)
+ return (PyObject *)PyErr_NoMemory();
+ PyObject_INIT(self, type);
+ return self;
+}
+
+static PyObject *
+datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
+{
+ PyObject *self;
+
+ self = (PyObject *)
+ PyObject_MALLOC(aware ?
+ sizeof(PyDateTime_DateTime) :
+ sizeof(_PyDateTime_BaseDateTime));
+ if (self == NULL)
+ return (PyObject *)PyErr_NoMemory();
+ PyObject_INIT(self, type);
+ return self;
+}
+
+/* ---------------------------------------------------------------------------
+ * Helpers for setting object fields. These work on pointers to the
+ * appropriate base class.
+ */
+
+/* For date and datetime. */
+static void
+set_date_fields(PyDateTime_Date *self, int y, int m, int d)
+{
+ self->hashcode = -1;
+ SET_YEAR(self, y);
+ SET_MONTH(self, m);
+ SET_DAY(self, d);
+}
+
+/* ---------------------------------------------------------------------------
+ * Create various objects, mostly without range checking.
+ */
+
+/* Create a date instance with no range checking. */
+static PyObject *
+new_date_ex(int year, int month, int day, PyTypeObject *type)
+{
+ PyDateTime_Date *self;
+
+ self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
+ if (self != NULL)
+ set_date_fields(self, year, month, day);
+ return (PyObject *) self;
+}
+
+#define new_date(year, month, day) \
+ new_date_ex(year, month, day, &PyDateTime_DateType)
+
+/* Create a datetime instance with no range checking. */
+static PyObject *
+new_datetime_ex(int year, int month, int day, int hour, int minute,
+ int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
+{
+ PyDateTime_DateTime *self;
+ char aware = tzinfo != Py_None;
+
+ self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
+ if (self != NULL) {
+ self->hastzinfo = aware;
+ set_date_fields((PyDateTime_Date *)self, year, month, day);
+ DATE_SET_HOUR(self, hour);
+ DATE_SET_MINUTE(self, minute);
+ DATE_SET_SECOND(self, second);
+ DATE_SET_MICROSECOND(self, usecond);
+ if (aware) {
+ Py_INCREF(tzinfo);
+ self->tzinfo = tzinfo;
+ }
+ }
+ return (PyObject *)self;
+}
+
+#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
+ new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
+ &PyDateTime_DateTimeType)
+
+/* Create a time instance with no range checking. */
+static PyObject *
+new_time_ex(int hour, int minute, int second, int usecond,
+ PyObject *tzinfo, PyTypeObject *type)
+{
+ PyDateTime_Time *self;
+ char aware = tzinfo != Py_None;
+
+ self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
+ if (self != NULL) {
+ self->hastzinfo = aware;
+ self->hashcode = -1;
+ TIME_SET_HOUR(self, hour);
+ TIME_SET_MINUTE(self, minute);
+ TIME_SET_SECOND(self, second);
+ TIME_SET_MICROSECOND(self, usecond);
+ if (aware) {
+ Py_INCREF(tzinfo);
+ self->tzinfo = tzinfo;
+ }
+ }
+ return (PyObject *)self;
+}
+
+#define new_time(hh, mm, ss, us, tzinfo) \
+ new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
+
+/* Create a timedelta instance. Normalize the members iff normalize is
+ * true. Passing false is a speed optimization, if you know for sure
+ * that seconds and microseconds are already in their proper ranges. In any
+ * case, raises OverflowError and returns NULL if the normalized days is out
+ * of range).
+ */
+static PyObject *
+new_delta_ex(int days, int seconds, int microseconds, int normalize,
+ PyTypeObject *type)
+{
+ PyDateTime_Delta *self;
+
+ if (normalize)
+ normalize_d_s_us(&days, &seconds, &microseconds);
+ assert(0 <= seconds && seconds < 24*3600);
+ assert(0 <= microseconds && microseconds < 1000000);
+
+ if (check_delta_day_range(days) < 0)
+ return NULL;
+
+ self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
+ if (self != NULL) {
+ self->hashcode = -1;
+ SET_TD_DAYS(self, days);
+ SET_TD_SECONDS(self, seconds);
+ SET_TD_MICROSECONDS(self, microseconds);
+ }
+ return (PyObject *) self;
+}
+
+#define new_delta(d, s, us, normalize) \
+ new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
+
+/* ---------------------------------------------------------------------------
+ * tzinfo helpers.
+ */
+
+/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
+ * raise TypeError and return -1.
+ */
+static int
+check_tzinfo_subclass(PyObject *p)
+{
+ if (p == Py_None || PyTZInfo_Check(p))
+ return 0;
+ PyErr_Format(PyExc_TypeError,
+ "tzinfo argument must be None or of a tzinfo subclass, "
+ "not type '%s'",
+ p->ob_type->tp_name);
+ return -1;
+}
+
+/* Return tzinfo.methname(tzinfoarg), without any checking of results.
+ * If tzinfo is None, returns None.
+ */
+static PyObject *
+call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
+{
+ PyObject *result;
+
+ assert(tzinfo && methname && tzinfoarg);
+ assert(check_tzinfo_subclass(tzinfo) >= 0);
+ if (tzinfo == Py_None) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else
+ result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
+ return result;
+}
+
+/* If self has a tzinfo member, return a BORROWED reference to it. Else
+ * return NULL, which is NOT AN ERROR. There are no error returns here,
+ * and the caller must not decref the result.
+ */
+static PyObject *
+get_tzinfo_member(PyObject *self)
+{
+ PyObject *tzinfo = NULL;
+
+ if (PyDateTime_Check(self) && HASTZINFO(self))
+ tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
+ else if (PyTime_Check(self) && HASTZINFO(self))
+ tzinfo = ((PyDateTime_Time *)self)->tzinfo;
+
+ return tzinfo;
+}
+
+/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
+ * result. tzinfo must be an instance of the tzinfo class. If the method
+ * returns None, this returns 0 and sets *none to 1. If the method doesn't
+ * return None or timedelta, TypeError is raised and this returns -1. If it
+ * returnsa timedelta and the value is out of range or isn't a whole number
+ * of minutes, ValueError is raised and this returns -1.
+ * Else *none is set to 0 and the integer method result is returned.
+ */
+static int
+call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
+ int *none)
+{
+ PyObject *u;
+ int result = -1;
+
+ assert(tzinfo != NULL);
+ assert(PyTZInfo_Check(tzinfo));
+ assert(tzinfoarg != NULL);
+
+ *none = 0;
+ u = call_tzinfo_method(tzinfo, name, tzinfoarg);
+ if (u == NULL)
+ return -1;
+
+ else if (u == Py_None) {
+ result = 0;
+ *none = 1;
+ }
+ else if (PyDelta_Check(u)) {
+ const int days = GET_TD_DAYS(u);
+ if (days < -1 || days > 0)
+ result = 24*60; /* trigger ValueError below */
+ else {
+ /* next line can't overflow because we know days
+ * is -1 or 0 now
+ */
+ int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
+ result = divmod(ss, 60, &ss);
+ if (ss || GET_TD_MICROSECONDS(u)) {
+ PyErr_Format(PyExc_ValueError,
+ "tzinfo.%s() must return a "
+ "whole number of minutes",
+ name);
+ result = -1;
+ }
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "tzinfo.%s() must return None or "
+ "timedelta, not '%s'",
+ name, u->ob_type->tp_name);
+ }
+
+ Py_DECREF(u);
+ if (result < -1439 || result > 1439) {
+ PyErr_Format(PyExc_ValueError,
+ "tzinfo.%s() returned %d; must be in "
+ "-1439 .. 1439",
+ name, result);
+ result = -1;
+ }
+ return result;
+}
+
+/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
+ * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
+ * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
+ * doesn't return None or timedelta, TypeError is raised and this returns -1.
+ * If utcoffset() returns an invalid timedelta (out of range, or not a whole
+ * # of minutes), ValueError is raised and this returns -1. Else *none is
+ * set to 0 and the offset is returned (as int # of minutes east of UTC).
+ */
+static int
+call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
+{
+ return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
+}
+
+/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
+ */
+static PyObject *
+offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
+ PyObject *result;
+
+ assert(tzinfo && name && tzinfoarg);
+ if (tzinfo == Py_None) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else {
+ int none;
+ int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
+ &none);
+ if (offset < 0 && PyErr_Occurred())
+ return NULL;
+ if (none) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else
+ result = new_delta(0, offset * 60, 0, 1);
+ }
+ return result;
+}
+
+/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
+ * result. tzinfo must be an instance of the tzinfo class. If dst()
+ * returns None, call_dst returns 0 and sets *none to 1. If dst()
+ & doesn't return None or timedelta, TypeError is raised and this
+ * returns -1. If dst() returns an invalid timedelta for a UTC offset,
+ * ValueError is raised and this returns -1. Else *none is set to 0 and
+ * the offset is returned (as an int # of minutes east of UTC).
+ */
+static int
+call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
+{
+ return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
+}
+
+/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
+ * an instance of the tzinfo class or None. If tzinfo isn't None, and
+ * tzname() doesn't return None or a string, TypeError is raised and this
+ * returns NULL.
+ */
+static PyObject *
+call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
+{
+ PyObject *result;
+
+ assert(tzinfo != NULL);
+ assert(check_tzinfo_subclass(tzinfo) >= 0);
+ assert(tzinfoarg != NULL);
+
+ if (tzinfo == Py_None) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else
+ result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
+
+ if (result != NULL && result != Py_None && ! PyString_Check(result)) {
+ PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
+ "return None or a string, not '%s'",
+ result->ob_type->tp_name);
+ Py_DECREF(result);
+ result = NULL;
+ }
+ return result;
+}
+
+typedef enum {
+ /* an exception has been set; the caller should pass it on */
+ OFFSET_ERROR,
+
+ /* type isn't date, datetime, or time subclass */
+ OFFSET_UNKNOWN,
+
+ /* date,
+ * datetime with !hastzinfo
+ * datetime with None tzinfo,
+ * datetime where utcoffset() returns None
+ * time with !hastzinfo
+ * time with None tzinfo,
+ * time where utcoffset() returns None
+ */
+ OFFSET_NAIVE,
+
+ /* time or datetime where utcoffset() doesn't return None */
+ OFFSET_AWARE
+} naivety;
+
+/* Classify an object as to whether it's naive or offset-aware. See
+ * the "naivety" typedef for details. If the type is aware, *offset is set
+ * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
+ * If the type is offset-naive (or unknown, or error), *offset is set to 0.
+ * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
+ */
+static naivety
+classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
+{
+ int none;
+ PyObject *tzinfo;
+
+ assert(tzinfoarg != NULL);
+ *offset = 0;
+ tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
+ if (tzinfo == Py_None)
+ return OFFSET_NAIVE;
+ if (tzinfo == NULL) {
+ /* note that a datetime passes the PyDate_Check test */
+ return (PyTime_Check(op) || PyDate_Check(op)) ?
+ OFFSET_NAIVE : OFFSET_UNKNOWN;
+ }
+ *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
+ if (*offset == -1 && PyErr_Occurred())
+ return OFFSET_ERROR;
+ return none ? OFFSET_NAIVE : OFFSET_AWARE;
+}
+
+/* Classify two objects as to whether they're naive or offset-aware.
+ * This isn't quite the same as calling classify_utcoffset() twice: for
+ * binary operations (comparison and subtraction), we generally want to
+ * ignore the tzinfo members if they're identical. This is by design,
+ * so that results match "naive" expectations when mixing objects from a
+ * single timezone. So in that case, this sets both offsets to 0 and
+ * both naiveties to OFFSET_NAIVE.
+ * The function returns 0 if everything's OK, and -1 on error.
+ */
+static int
+classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
+ PyObject *tzinfoarg1,
+ PyObject *o2, int *offset2, naivety *n2,
+ PyObject *tzinfoarg2)
+{
+ if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
+ *offset1 = *offset2 = 0;
+ *n1 = *n2 = OFFSET_NAIVE;
+ }
+ else {
+ *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
+ if (*n1 == OFFSET_ERROR)
+ return -1;
+ *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
+ if (*n2 == OFFSET_ERROR)
+ return -1;
+ }
+ return 0;
+}
+
+/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
+ * stuff
+ * ", tzinfo=" + repr(tzinfo)
+ * before the closing ")".
+ */
+static PyObject *
+append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
+{
+ PyObject *temp;
+
+ assert(PyString_Check(repr));
+ assert(tzinfo);
+ if (tzinfo == Py_None)
+ return repr;
+ /* Get rid of the trailing ')'. */
+ assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
+ temp = PyString_FromStringAndSize(PyString_AsString(repr),
+ PyString_Size(repr) - 1);
+ Py_DECREF(repr);
+ if (temp == NULL)
+ return NULL;
+ repr = temp;
+
+ /* Append ", tzinfo=". */
+ PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
+
+ /* Append repr(tzinfo). */
+ PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
+
+ /* Add a closing paren. */
+ PyString_ConcatAndDel(&repr, PyString_FromString(")"));
+ return repr;
+}
+
+/* ---------------------------------------------------------------------------
+ * String format helpers.
+ */
+
+static PyObject *
+format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
+{
+ static const char *DayNames[] = {
+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
+ };
+ static const char *MonthNames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+ char buffer[128];
+ int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
+
+ PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
+ DayNames[wday], MonthNames[GET_MONTH(date) - 1],
+ GET_DAY(date), hours, minutes, seconds,
+ GET_YEAR(date));
+ return PyString_FromString(buffer);
+}
+
+/* Add an hours & minutes UTC offset string to buf. buf has no more than
+ * buflen bytes remaining. The UTC offset is gotten by calling
+ * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
+ * *buf, and that's all. Else the returned value is checked for sanity (an
+ * integer in range), and if that's OK it's converted to an hours & minutes
+ * string of the form
+ * sign HH sep MM
+ * Returns 0 if everything is OK. If the return value from utcoffset() is
+ * bogus, an appropriate exception is set and -1 is returned.
+ */
+static int
+format_utcoffset(char *buf, size_t buflen, const char *sep,
+ PyObject *tzinfo, PyObject *tzinfoarg)
+{
+ int offset;
+ int hours;
+ int minutes;
+ char sign;
+ int none;
+
+ offset = call_utcoffset(tzinfo, tzinfoarg, &none);
+ if (offset == -1 && PyErr_Occurred())
+ return -1;
+ if (none) {
+ *buf = '\0';
+ return 0;
+ }
+ sign = '+';
+ if (offset < 0) {
+ sign = '-';
+ offset = - offset;
+ }
+ hours = divmod(offset, 60, &minutes);
+ PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
+ return 0;
+}
+
+/* I sure don't want to reproduce the strftime code from the time module,
+ * so this imports the module and calls it. All the hair is due to
+ * giving special meanings to the %z and %Z format codes via a preprocessing
+ * step on the format string.
+ * tzinfoarg is the argument to pass to the object's tzinfo method, if
+ * needed.
+ */
+static PyObject *
+wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
+ PyObject *tzinfoarg)
+{
+ PyObject *result = NULL; /* guilty until proved innocent */
+
+ PyObject *zreplacement = NULL; /* py string, replacement for %z */
+ PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
+
+ char *pin; /* pointer to next char in input format */
+ char ch; /* next char in input format */
+
+ PyObject *newfmt = NULL; /* py string, the output format */
+ char *pnew; /* pointer to available byte in output format */
+ int totalnew; /* number bytes total in output format buffer,
+ exclusive of trailing \0 */
+ int usednew; /* number bytes used so far in output format buffer */
+
+ char *ptoappend; /* pointer to string to append to output buffer */
+ int ntoappend; /* # of bytes to append to output buffer */
+
+ assert(object && format && timetuple);
+ assert(PyString_Check(format));
+
+ /* Give up if the year is before 1900.
+ * Python strftime() plays games with the year, and different
+ * games depending on whether envar PYTHON2K is set. This makes
+ * years before 1900 a nightmare, even if the platform strftime
+ * supports them (and not all do).
+ * We could get a lot farther here by avoiding Python's strftime
+ * wrapper and calling the C strftime() directly, but that isn't
+ * an option in the Python implementation of this module.
+ */
+ {
+ long year;
+ PyObject *pyyear = PySequence_GetItem(timetuple, 0);
+ if (pyyear == NULL) return NULL;
+ assert(PyInt_Check(pyyear));
+ year = PyInt_AsLong(pyyear);
+ Py_DECREF(pyyear);
+ if (year < 1900) {
+ PyErr_Format(PyExc_ValueError, "year=%ld is before "
+ "1900; the datetime strftime() "
+ "methods require year >= 1900",
+ year);
+ return NULL;
+ }
+ }
+
+ /* Scan the input format, looking for %z and %Z escapes, building
+ * a new format. Since computing the replacements for those codes
+ * is expensive, don't unless they're actually used.
+ */
+ totalnew = PyString_Size(format) + 1; /* realistic if no %z/%Z */
+ newfmt = PyString_FromStringAndSize(NULL, totalnew);
+ if (newfmt == NULL) goto Done;
+ pnew = PyString_AsString(newfmt);
+ usednew = 0;
+
+ pin = PyString_AsString(format);
+ while ((ch = *pin++) != '\0') {
+ if (ch != '%') {
+ ptoappend = pin - 1;
+ ntoappend = 1;
+ }
+ else if ((ch = *pin++) == '\0') {
+ /* There's a lone trailing %; doesn't make sense. */
+ PyErr_SetString(PyExc_ValueError, "strftime format "
+ "ends with raw %");
+ goto Done;
+ }
+ /* A % has been seen and ch is the character after it. */
+ else if (ch == 'z') {
+ if (zreplacement == NULL) {
+ /* format utcoffset */
+ char buf[100];
+ PyObject *tzinfo = get_tzinfo_member(object);
+ zreplacement = PyString_FromString("");
+ if (zreplacement == NULL) goto Done;
+ if (tzinfo != Py_None && tzinfo != NULL) {
+ assert(tzinfoarg != NULL);
+ if (format_utcoffset(buf,
+ sizeof(buf),
+ "",
+ tzinfo,
+ tzinfoarg) < 0)
+ goto Done;
+ Py_DECREF(zreplacement);
+ zreplacement = PyString_FromString(buf);
+ if (zreplacement == NULL) goto Done;
+ }
+ }
+ assert(zreplacement != NULL);
+ ptoappend = PyString_AS_STRING(zreplacement);
+ ntoappend = PyString_GET_SIZE(zreplacement);
+ }
+ else if (ch == 'Z') {
+ /* format tzname */
+ if (Zreplacement == NULL) {
+ PyObject *tzinfo = get_tzinfo_member(object);
+ Zreplacement = PyString_FromString("");
+ if (Zreplacement == NULL) goto Done;
+ if (tzinfo != Py_None && tzinfo != NULL) {
+ PyObject *temp;
+ assert(tzinfoarg != NULL);
+ temp = call_tzname(tzinfo, tzinfoarg);
+ if (temp == NULL) goto Done;
+ if (temp != Py_None) {
+ assert(PyString_Check(temp));
+ /* Since the tzname is getting
+ * stuffed into the format, we
+ * have to double any % signs
+ * so that strftime doesn't
+ * treat them as format codes.
+ */
+ Py_DECREF(Zreplacement);
+ Zreplacement = PyObject_CallMethod(
+ temp, "replace",
+ "ss", "%", "%%");
+ Py_DECREF(temp);
+ if (Zreplacement == NULL)
+ goto Done;
+ if (!PyString_Check(Zreplacement)) {
+ PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
+ goto Done;
+ }
+ }
+ else
+ Py_DECREF(temp);
+ }
+ }
+ assert(Zreplacement != NULL);
+ ptoappend = PyString_AS_STRING(Zreplacement);
+ ntoappend = PyString_GET_SIZE(Zreplacement);
+ }
+ else {
+ /* percent followed by neither z nor Z */
+ ptoappend = pin - 2;
+ ntoappend = 2;
+ }
+
+ /* Append the ntoappend chars starting at ptoappend to
+ * the new format.
+ */
+ assert(ptoappend != NULL);
+ assert(ntoappend >= 0);
+ if (ntoappend == 0)
+ continue;
+ while (usednew + ntoappend > totalnew) {
+ int bigger = totalnew << 1;
+ if ((bigger >> 1) != totalnew) { /* overflow */
+ PyErr_NoMemory();
+ goto Done;
+ }
+ if (_PyString_Resize(&newfmt, bigger) < 0)
+ goto Done;
+ totalnew = bigger;
+ pnew = PyString_AsString(newfmt) + usednew;
+ }
+ memcpy(pnew, ptoappend, ntoappend);
+ pnew += ntoappend;
+ usednew += ntoappend;
+ assert(usednew <= totalnew);
+ } /* end while() */
+
+ if (_PyString_Resize(&newfmt, usednew) < 0)
+ goto Done;
+ {
+ PyObject *time = PyImport_ImportModule("time");
+ if (time == NULL)
+ goto Done;
+ result = PyObject_CallMethod(time, "strftime", "OO",
+ newfmt, timetuple);
+ Py_DECREF(time);
+ }
+ Done:
+ Py_XDECREF(zreplacement);
+ Py_XDECREF(Zreplacement);
+ Py_XDECREF(newfmt);
+ return result;
+}
+
+static char *
+isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
+{
+ int x;
+ x = PyOS_snprintf(buffer, bufflen,
+ "%04d-%02d-%02d",
+ GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
+ return buffer + x;
+}
+
+static void
+isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
+{
+ int us = DATE_GET_MICROSECOND(dt);
+
+ PyOS_snprintf(buffer, bufflen,
+ "%02d:%02d:%02d", /* 8 characters */
+ DATE_GET_HOUR(dt),
+ DATE_GET_MINUTE(dt),
+ DATE_GET_SECOND(dt));
+ if (us)
+ PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
+}
+
+/* ---------------------------------------------------------------------------
+ * Wrap functions from the time module. These aren't directly available
+ * from C. Perhaps they should be.
+ */
+
+/* Call time.time() and return its result (a Python float). */
+static PyObject *
+time_time(void)
+{
+ PyObject *result = NULL;
+ PyObject *time = PyImport_ImportModule("time");
+
+ if (time != NULL) {
+ result = PyObject_CallMethod(time, "time", "()");
+ Py_DECREF(time);
+ }
+ return result;
+}
+
+/* Build a time.struct_time. The weekday and day number are automatically
+ * computed from the y,m,d args.
+ */
+static PyObject *
+build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
+{
+ PyObject *time;
+ PyObject *result = NULL;
+
+ time = PyImport_ImportModule("time");
+ if (time != NULL) {
+ result = PyObject_CallMethod(time, "struct_time",
+ "((iiiiiiiii))",
+ y, m, d,
+ hh, mm, ss,
+ weekday(y, m, d),
+ days_before_month(y, m) + d,
+ dstflag);
+ Py_DECREF(time);
+ }
+ return result;
+}
+
+/* ---------------------------------------------------------------------------
+ * Miscellaneous helpers.
+ */
+
+/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
+ * The comparisons here all most naturally compute a cmp()-like result.
+ * This little helper turns that into a bool result for rich comparisons.
+ */
+static PyObject *
+diff_to_bool(int diff, int op)
+{
+ PyObject *result;
+ int istrue;
+
+ switch (op) {
+ case Py_EQ: istrue = diff == 0; break;
+ case Py_NE: istrue = diff != 0; break;
+ case Py_LE: istrue = diff <= 0; break;
+ case Py_GE: istrue = diff >= 0; break;
+ case Py_LT: istrue = diff < 0; break;
+ case Py_GT: istrue = diff > 0; break;
+ default:
+ assert(! "op unknown");
+ istrue = 0; /* To shut up compiler */
+ }
+ result = istrue ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+/* Raises a "can't compare" TypeError and returns NULL. */
+static PyObject *
+cmperror(PyObject *a, PyObject *b)
+{
+ PyErr_Format(PyExc_TypeError,
+ "can't compare %s to %s",
+ a->ob_type->tp_name, b->ob_type->tp_name);
+ return NULL;
+}
+
+/* ---------------------------------------------------------------------------
+ * Cached Python objects; these are set by the module init function.
+ */
+
+/* Conversion factors. */
+static PyObject *us_per_us = NULL; /* 1 */
+static PyObject *us_per_ms = NULL; /* 1000 */
+static PyObject *us_per_second = NULL; /* 1000000 */
+static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
+static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
+static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
+static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
+static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
+
+/* ---------------------------------------------------------------------------
+ * Class implementations.
+ */
+
+/*
+ * PyDateTime_Delta implementation.
+ */
+
+/* Convert a timedelta to a number of us,
+ * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
+ * as a Python int or long.
+ * Doing mixed-radix arithmetic by hand instead is excruciating in C,
+ * due to ubiquitous overflow possibilities.
+ */
+static PyObject *
+delta_to_microseconds(PyDateTime_Delta *self)
+{
+ PyObject *x1 = NULL;
+ PyObject *x2 = NULL;
+ PyObject *x3 = NULL;
+ PyObject *result = NULL;
+
+ x1 = PyInt_FromLong(GET_TD_DAYS(self));
+ if (x1 == NULL)
+ goto Done;
+ x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
+ if (x2 == NULL)
+ goto Done;
+ Py_DECREF(x1);
+ x1 = NULL;
+
+ /* x2 has days in seconds */
+ x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
+ if (x1 == NULL)
+ goto Done;
+ x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
+ if (x3 == NULL)
+ goto Done;
+ Py_DECREF(x1);
+ Py_DECREF(x2);
+ x1 = x2 = NULL;
+
+ /* x3 has days+seconds in seconds */
+ x1 = PyNumber_Multiply(x3, us_per_second); /* us */
+ if (x1 == NULL)
+ goto Done;
+ Py_DECREF(x3);
+ x3 = NULL;
+
+ /* x1 has days+seconds in us */
+ x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
+ if (x2 == NULL)
+ goto Done;
+ result = PyNumber_Add(x1, x2);
+
+Done:
+ Py_XDECREF(x1);
+ Py_XDECREF(x2);
+ Py_XDECREF(x3);
+ return result;
+}
+
+/* Convert a number of us (as a Python int or long) to a timedelta.
+ */
+static PyObject *
+microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
+{
+ int us;
+ int s;
+ int d;
+ long temp;
+
+ PyObject *tuple = NULL;
+ PyObject *num = NULL;
+ PyObject *result = NULL;
+
+ tuple = PyNumber_Divmod(pyus, us_per_second);
+ if (tuple == NULL)
+ goto Done;
+
+ num = PyTuple_GetItem(tuple, 1); /* us */
+ if (num == NULL)
+ goto Done;
+ temp = PyLong_AsLong(num);
+ num = NULL;
+ if (temp == -1 && PyErr_Occurred())
+ goto Done;
+ assert(0 <= temp && temp < 1000000);
+ us = (int)temp;
+ if (us < 0) {
+ /* The divisor was positive, so this must be an error. */
+ assert(PyErr_Occurred());
+ goto Done;
+ }
+
+ num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
+ if (num == NULL)
+ goto Done;
+ Py_INCREF(num);
+ Py_DECREF(tuple);
+
+ tuple = PyNumber_Divmod(num, seconds_per_day);
+ if (tuple == NULL)
+ goto Done;
+ Py_DECREF(num);
+
+ num = PyTuple_GetItem(tuple, 1); /* seconds */
+ if (num == NULL)
+ goto Done;
+ temp = PyLong_AsLong(num);
+ num = NULL;
+ if (temp == -1 && PyErr_Occurred())
+ goto Done;
+ assert(0 <= temp && temp < 24*3600);
+ s = (int)temp;
+
+ if (s < 0) {
+ /* The divisor was positive, so this must be an error. */
+ assert(PyErr_Occurred());
+ goto Done;
+ }
+
+ num = PyTuple_GetItem(tuple, 0); /* leftover days */
+ if (num == NULL)
+ goto Done;
+ Py_INCREF(num);
+ temp = PyLong_AsLong(num);
+ if (temp == -1 && PyErr_Occurred())
+ goto Done;
+ d = (int)temp;
+ if ((long)d != temp) {
+ PyErr_SetString(PyExc_OverflowError, "normalized days too "
+ "large to fit in a C int");
+ goto Done;
+ }
+ result = new_delta_ex(d, s, us, 0, type);
+
+Done:
+ Py_XDECREF(tuple);
+ Py_XDECREF(num);
+ return result;
+}
+
+#define microseconds_to_delta(pymicros) \
+ microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
+
+static PyObject *
+multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
+{
+ PyObject *pyus_in;
+ PyObject *pyus_out;
+ PyObject *result;
+
+ pyus_in = delta_to_microseconds(delta);
+ if (pyus_in == NULL)
+ return NULL;
+
+ pyus_out = PyNumber_Multiply(pyus_in, intobj);
+ Py_DECREF(pyus_in);
+ if (pyus_out == NULL)
+ return NULL;
+
+ result = microseconds_to_delta(pyus_out);
+ Py_DECREF(pyus_out);
+ return result;
+}
+
+static PyObject *
+divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
+{
+ PyObject *pyus_in;
+ PyObject *pyus_out;
+ PyObject *result;
+
+ pyus_in = delta_to_microseconds(delta);
+ if (pyus_in == NULL)
+ return NULL;
+
+ pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
+ Py_DECREF(pyus_in);
+ if (pyus_out == NULL)
+ return NULL;
+
+ result = microseconds_to_delta(pyus_out);
+ Py_DECREF(pyus_out);
+ return result;
+}
+
+static PyObject *
+delta_add(PyObject *left, PyObject *right)
+{
+ PyObject *result = Py_NotImplemented;
+
+ if (PyDelta_Check(left) && PyDelta_Check(right)) {
+ /* delta + delta */
+ /* The C-level additions can't overflow because of the
+ * invariant bounds.
+ */
+ int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
+ int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
+ int microseconds = GET_TD_MICROSECONDS(left) +
+ GET_TD_MICROSECONDS(right);
+ result = new_delta(days, seconds, microseconds, 1);
+ }
+
+ if (result == Py_NotImplemented)
+ Py_INCREF(result);
+ return result;
+}
+
+static PyObject *
+delta_negative(PyDateTime_Delta *self)
+{
+ return new_delta(-GET_TD_DAYS(self),
+ -GET_TD_SECONDS(self),
+ -GET_TD_MICROSECONDS(self),
+ 1);
+}
+
+static PyObject *
+delta_positive(PyDateTime_Delta *self)
+{
+ /* Could optimize this (by returning self) if this isn't a
+ * subclass -- but who uses unary + ? Approximately nobody.
+ */
+ return new_delta(GET_TD_DAYS(self),
+ GET_TD_SECONDS(self),
+ GET_TD_MICROSECONDS(self),
+ 0);
+}
+
+static PyObject *
+delta_abs(PyDateTime_Delta *self)
+{
+ PyObject *result;
+
+ assert(GET_TD_MICROSECONDS(self) >= 0);
+ assert(GET_TD_SECONDS(self) >= 0);
+
+ if (GET_TD_DAYS(self) < 0)
+ result = delta_negative(self);
+ else
+ result = delta_positive(self);
+
+ return result;
+}
+
+static PyObject *
+delta_subtract(PyObject *left, PyObject *right)
+{
+ PyObject *result = Py_NotImplemented;
+
+ if (PyDelta_Check(left) && PyDelta_Check(right)) {
+ /* delta - delta */
+ PyObject *minus_right = PyNumber_Negative(right);
+ if (minus_right) {
+ result = delta_add(left, minus_right);
+ Py_DECREF(minus_right);
+ }
+ else
+ result = NULL;
+ }
+
+ if (result == Py_NotImplemented)
+ Py_INCREF(result);
+ return result;
+}
+
+/* This is more natural as a tp_compare, but doesn't work then: for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
+{
+ int diff = 42; /* nonsense */
+
+ if (PyDelta_Check(other)) {
+ diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
+ if (diff == 0) {
+ diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
+ if (diff == 0)
+ diff = GET_TD_MICROSECONDS(self) -
+ GET_TD_MICROSECONDS(other);
+ }
+ }
+ else if (op == Py_EQ || op == Py_NE)
+ diff = 1; /* any non-zero value will do */
+
+ else /* stop this from falling back to address comparison */
+ return cmperror((PyObject *)self, other);
+
+ return diff_to_bool(diff, op);
+}
+
+static PyObject *delta_getstate(PyDateTime_Delta *self);
+
+static long
+delta_hash(PyDateTime_Delta *self)
+{
+ if (self->hashcode == -1) {
+ PyObject *temp = delta_getstate(self);
+ if (temp != NULL) {
+ self->hashcode = PyObject_Hash(temp);
+ Py_DECREF(temp);
+ }
+ }
+ return self->hashcode;
+}
+
+static PyObject *
+delta_multiply(PyObject *left, PyObject *right)
+{
+ PyObject *result = Py_NotImplemented;
+
+ if (PyDelta_Check(left)) {
+ /* delta * ??? */
+ if (PyInt_Check(right) || PyLong_Check(right))
+ result = multiply_int_timedelta(right,
+ (PyDateTime_Delta *) left);
+ }
+ else if (PyInt_Check(left) || PyLong_Check(left))
+ result = multiply_int_timedelta(left,
+ (PyDateTime_Delta *) right);
+
+ if (result == Py_NotImplemented)
+ Py_INCREF(result);
+ return result;
+}
+
+static PyObject *
+delta_divide(PyObject *left, PyObject *right)
+{
+ PyObject *result = Py_NotImplemented;
+
+ if (PyDelta_Check(left)) {
+ /* delta * ??? */
+ if (PyInt_Check(right) || PyLong_Check(right))
+ result = divide_timedelta_int(
+ (PyDateTime_Delta *)left,
+ right);
+ }
+
+ if (result == Py_NotImplemented)
+ Py_INCREF(result);
+ return result;
+}
+
+/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
+ * timedelta constructor. sofar is the # of microseconds accounted for
+ * so far, and there are factor microseconds per current unit, the number
+ * of which is given by num. num * factor is added to sofar in a
+ * numerically careful way, and that's the result. Any fractional
+ * microseconds left over (this can happen if num is a float type) are
+ * added into *leftover.
+ * Note that there are many ways this can give an error (NULL) return.
+ */
+static PyObject *
+accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
+ double *leftover)
+{
+ PyObject *prod;
+ PyObject *sum;
+
+ assert(num != NULL);
+
+ if (PyInt_Check(num) || PyLong_Check(num)) {
+ prod = PyNumber_Multiply(num, factor);
+ if (prod == NULL)
+ return NULL;
+ sum = PyNumber_Add(sofar, prod);
+ Py_DECREF(prod);
+ return sum;
+ }
+
+ if (PyFloat_Check(num)) {
+ double dnum;
+ double fracpart;
+ double intpart;
+ PyObject *x;
+ PyObject *y;
+
+ /* The Plan: decompose num into an integer part and a
+ * fractional part, num = intpart + fracpart.
+ * Then num * factor ==
+ * intpart * factor + fracpart * factor
+ * and the LHS can be computed exactly in long arithmetic.
+ * The RHS is again broken into an int part and frac part.
+ * and the frac part is added into *leftover.
+ */
+ dnum = PyFloat_AsDouble(num);
+ if (dnum == -1.0 && PyErr_Occurred())
+ return NULL;
+ fracpart = modf(dnum, &intpart);
+ x = PyLong_FromDouble(intpart);
+ if (x == NULL)
+ return NULL;
+
+ prod = PyNumber_Multiply(x, factor);
+ Py_DECREF(x);
+ if (prod == NULL)
+ return NULL;
+
+ sum = PyNumber_Add(sofar, prod);
+ Py_DECREF(prod);
+ if (sum == NULL)
+ return NULL;
+
+ if (fracpart == 0.0)
+ return sum;
+ /* So far we've lost no information. Dealing with the
+ * fractional part requires float arithmetic, and may
+ * lose a little info.
+ */
+ assert(PyInt_Check(factor) || PyLong_Check(factor));
+ if (PyInt_Check(factor))
+ dnum = (double)PyInt_AsLong(factor);
+ else
+ dnum = PyLong_AsDouble(factor);
+
+ dnum *= fracpart;
+ fracpart = modf(dnum, &intpart);
+ x = PyLong_FromDouble(intpart);
+ if (x == NULL) {
+ Py_DECREF(sum);
+ return NULL;
+ }
+
+ y = PyNumber_Add(sum, x);
+ Py_DECREF(sum);
+ Py_DECREF(x);
+ *leftover += fracpart;
+ return y;
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "unsupported type for timedelta %s component: %s",
+ tag, num->ob_type->tp_name);
+ return NULL;
+}
+
+static PyObject *
+delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *self = NULL;
+
+ /* Argument objects. */
+ PyObject *day = NULL;
+ PyObject *second = NULL;
+ PyObject *us = NULL;
+ PyObject *ms = NULL;
+ PyObject *minute = NULL;
+ PyObject *hour = NULL;
+ PyObject *week = NULL;
+
+ PyObject *x = NULL; /* running sum of microseconds */
+ PyObject *y = NULL; /* temp sum of microseconds */
+ double leftover_us = 0.0;
+
+ static char *keywords[] = {
+ "days", "seconds", "microseconds", "milliseconds",
+ "minutes", "hours", "weeks", NULL
+ };
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
+ keywords,
+ &day, &second, &us,
+ &ms, &minute, &hour, &week) == 0)
+ goto Done;
+
+ x = PyInt_FromLong(0);
+ if (x == NULL)
+ goto Done;
+
+#define CLEANUP \
+ Py_DECREF(x); \
+ x = y; \
+ if (x == NULL) \
+ goto Done
+
+ if (us) {
+ y = accum("microseconds", x, us, us_per_us, &leftover_us);
+ CLEANUP;
+ }
+ if (ms) {
+ y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
+ CLEANUP;
+ }
+ if (second) {
+ y = accum("seconds", x, second, us_per_second, &leftover_us);
+ CLEANUP;
+ }
+ if (minute) {
+ y = accum("minutes", x, minute, us_per_minute, &leftover_us);
+ CLEANUP;
+ }
+ if (hour) {
+ y = accum("hours", x, hour, us_per_hour, &leftover_us);
+ CLEANUP;
+ }
+ if (day) {
+ y = accum("days", x, day, us_per_day, &leftover_us);
+ CLEANUP;
+ }
+ if (week) {
+ y = accum("weeks", x, week, us_per_week, &leftover_us);
+ CLEANUP;
+ }
+ if (leftover_us) {
+ /* Round to nearest whole # of us, and add into x. */
+ PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
+ if (temp == NULL) {
+ Py_DECREF(x);
+ goto Done;
+ }
+ y = PyNumber_Add(x, temp);
+ Py_DECREF(temp);
+ CLEANUP;
+ }
+
+ self = microseconds_to_delta_ex(x, type);
+ Py_DECREF(x);
+Done:
+ return self;
+
+#undef CLEANUP
+}
+
+static int
+delta_nonzero(PyDateTime_Delta *self)
+{
+ return (GET_TD_DAYS(self) != 0
+ || GET_TD_SECONDS(self) != 0
+ || GET_TD_MICROSECONDS(self) != 0);
+}
+
+static PyObject *
+delta_repr(PyDateTime_Delta *self)
+{
+ if (GET_TD_MICROSECONDS(self) != 0)
+ return PyString_FromFormat("%s(%d, %d, %d)",
+ self->ob_type->tp_name,
+ GET_TD_DAYS(self),
+ GET_TD_SECONDS(self),
+ GET_TD_MICROSECONDS(self));
+ if (GET_TD_SECONDS(self) != 0)
+ return PyString_FromFormat("%s(%d, %d)",
+ self->ob_type->tp_name,
+ GET_TD_DAYS(self),
+ GET_TD_SECONDS(self));
+
+ return PyString_FromFormat("%s(%d)",
+ self->ob_type->tp_name,
+ GET_TD_DAYS(self));
+}
+
+static PyObject *
+delta_str(PyDateTime_Delta *self)
+{
+ int days = GET_TD_DAYS(self);
+ int seconds = GET_TD_SECONDS(self);
+ int us = GET_TD_MICROSECONDS(self);
+ int hours;
+ int minutes;
+ char buf[100];
+ char *pbuf = buf;
+ size_t buflen = sizeof(buf);
+ int n;
+
+ minutes = divmod(seconds, 60, &seconds);
+ hours = divmod(minutes, 60, &minutes);
+
+ if (days) {
+ n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
+ (days == 1 || days == -1) ? "" : "s");
+ if (n < 0 || (size_t)n >= buflen)
+ goto Fail;
+ pbuf += n;
+ buflen -= (size_t)n;
+ }
+
+ n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
+ hours, minutes, seconds);
+ if (n < 0 || (size_t)n >= buflen)
+ goto Fail;
+ pbuf += n;
+ buflen -= (size_t)n;
+
+ if (us) {
+ n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
+ if (n < 0 || (size_t)n >= buflen)
+ goto Fail;
+ pbuf += n;
+ }
+
+ return PyString_FromStringAndSize(buf, pbuf - buf);
+
+ Fail:
+ PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
+ return NULL;
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* __getstate__ isn't exposed */
+static PyObject *
+delta_getstate(PyDateTime_Delta *self)
+{
+ return Py_BuildValue("iii", GET_TD_DAYS(self),
+ GET_TD_SECONDS(self),
+ GET_TD_MICROSECONDS(self));
+}
+
+static PyObject *
+delta_reduce(PyDateTime_Delta* self)
+{
+ return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
+}
+
+#define OFFSET(field) offsetof(PyDateTime_Delta, field)
+
+static PyMemberDef delta_members[] = {
+
+ {"days", T_INT, OFFSET(days), READONLY,
+ PyDoc_STR("Number of days.")},
+
+ {"seconds", T_INT, OFFSET(seconds), READONLY,
+ PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
+
+ {"microseconds", T_INT, OFFSET(microseconds), READONLY,
+ PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
+ {NULL}
+};
+
+static PyMethodDef delta_methods[] = {
+ {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
+ PyDoc_STR("__reduce__() -> (cls, state)")},
+
+ {NULL, NULL},
+};
+
+static char delta_doc[] =
+PyDoc_STR("Difference between two datetime values.");
+
+static PyNumberMethods delta_as_number = {
+ delta_add, /* nb_add */
+ delta_subtract, /* nb_subtract */
+ delta_multiply, /* nb_multiply */
+ delta_divide, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ (unaryfunc)delta_negative, /* nb_negative */
+ (unaryfunc)delta_positive, /* nb_positive */
+ (unaryfunc)delta_abs, /* nb_absolute */
+ (inquiry)delta_nonzero, /* nb_nonzero */
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ 0, /*nb_coerce*/
+ 0, /*nb_int*/
+ 0, /*nb_long*/
+ 0, /*nb_float*/
+ 0, /*nb_oct*/
+ 0, /*nb_hex*/
+ 0, /*nb_inplace_add*/
+ 0, /*nb_inplace_subtract*/
+ 0, /*nb_inplace_multiply*/
+ 0, /*nb_inplace_divide*/
+ 0, /*nb_inplace_remainder*/
+ 0, /*nb_inplace_power*/
+ 0, /*nb_inplace_lshift*/
+ 0, /*nb_inplace_rshift*/
+ 0, /*nb_inplace_and*/
+ 0, /*nb_inplace_xor*/
+ 0, /*nb_inplace_or*/
+ delta_divide, /* nb_floor_divide */
+ 0, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+};
+
+static PyTypeObject PyDateTime_DeltaType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "datetime.timedelta", /* tp_name */
+ sizeof(PyDateTime_Delta), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)delta_repr, /* tp_repr */
+ &delta_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)delta_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)delta_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ delta_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)delta_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ delta_methods, /* tp_methods */
+ delta_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ delta_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/*
+ * PyDateTime_Date implementation.
+ */
+
+/* Accessor properties. */
+
+static PyObject *
+date_year(PyDateTime_Date *self, void *unused)
+{
+ return PyInt_FromLong(GET_YEAR(self));
+}
+
+static PyObject *
+date_month(PyDateTime_Date *self, void *unused)
+{
+ return PyInt_FromLong(GET_MONTH(self));
+}
+
+static PyObject *
+date_day(PyDateTime_Date *self, void *unused)
+{
+ return PyInt_FromLong(GET_DAY(self));
+}
+
+static PyGetSetDef date_getset[] = {
+ {"year", (getter)date_year},
+ {"month", (getter)date_month},
+ {"day", (getter)date_day},
+ {NULL}
+};
+
+/* Constructors. */
+
+static char *date_kws[] = {"year", "month", "day", NULL};
+
+static PyObject *
+date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *self = NULL;
+ PyObject *state;
+ int year;
+ int month;
+ int day;
+
+ /* Check for invocation from pickle with __getstate__ state */
+ if (PyTuple_GET_SIZE(args) == 1 &&
+ PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
+ PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
+ MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
+ {
+ PyDateTime_Date *me;
+
+ me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
+ if (me != NULL) {
+ char *pdata = PyString_AS_STRING(state);
+ memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
+ me->hashcode = -1;
+ }
+ return (PyObject *)me;
+ }
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
+ &year, &month, &day)) {
+ if (check_date_args(year, month, day) < 0)
+ return NULL;
+ self = new_date_ex(year, month, day, type);
+ }
+ return self;
+}
+
+/* Return new date from localtime(t). */
+static PyObject *
+date_local_from_time_t(PyObject *cls, double ts)
+{
+ struct tm *tm;
+ time_t t;
+ PyObject *result = NULL;
+
+ t = _PyTime_DoubleToTimet(ts);
+ if (t == (time_t)-1 && PyErr_Occurred())
+ return NULL;
+ tm = localtime(&t);
+ if (tm)
+ result = PyObject_CallFunction(cls, "iii",
+ tm->tm_year + 1900,
+ tm->tm_mon + 1,
+ tm->tm_mday);
+ else
+ PyErr_SetString(PyExc_ValueError,
+ "timestamp out of range for "
+ "platform localtime() function");
+ return result;
+}
+
+/* Return new date from current time.
+ * We say this is equivalent to fromtimestamp(time.time()), and the
+ * only way to be sure of that is to *call* time.time(). That's not
+ * generally the same as calling C's time.
+ */
+static PyObject *
+date_today(PyObject *cls, PyObject *dummy)
+{
+ PyObject *time;
+ PyObject *result;
+
+ time = time_time();
+ if (time == NULL)
+ return NULL;
+
+ /* Note well: today() is a class method, so this may not call
+ * date.fromtimestamp. For example, it may call
+ * datetime.fromtimestamp. That's why we need all the accuracy
+ * time.time() delivers; if someone were gonzo about optimization,
+ * date.today() could get away with plain C time().
+ */
+ result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
+ Py_DECREF(time);
+ return result;
+}
+
+/* Return new date from given timestamp (Python timestamp -- a double). */
+static PyObject *
+date_fromtimestamp(PyObject *cls, PyObject *args)
+{
+ double timestamp;
+ PyObject *result = NULL;
+
+ if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
+ result = date_local_from_time_t(cls, timestamp);
+ return result;
+}
+
+/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
+ * the ordinal is out of range.
+ */
+static PyObject *
+date_fromordinal(PyObject *cls, PyObject *args)
+{
+ PyObject *result = NULL;
+ int ordinal;
+
+ if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
+ int year;
+ int month;
+ int day;
+
+ if (ordinal < 1)
+ PyErr_SetString(PyExc_ValueError, "ordinal must be "
+ ">= 1");
+ else {
+ ord_to_ymd(ordinal, &year, &month, &day);
+ result = PyObject_CallFunction(cls, "iii",
+ year, month, day);
+ }
+ }
+ return result;
+}
+
+/*
+ * Date arithmetic.
+ */
+
+/* date + timedelta -> date. If arg negate is true, subtract the timedelta
+ * instead.
+ */
+static PyObject *
+add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
+{
+ PyObject *result = NULL;
+ int year = GET_YEAR(date);
+ int month = GET_MONTH(date);
+ int deltadays = GET_TD_DAYS(delta);
+ /* C-level overflow is impossible because |deltadays| < 1e9. */
+ int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
+
+ if (normalize_date(&year, &month, &day) >= 0)
+ result = new_date(year, month, day);
+ return result;
+}
+
+static PyObject *
+date_add(PyObject *left, PyObject *right)
+{
+ if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (PyDate_Check(left)) {
+ /* date + ??? */
+ if (PyDelta_Check(right))
+ /* date + delta */
+ return add_date_timedelta((PyDateTime_Date *) left,
+ (PyDateTime_Delta *) right,
+ 0);
+ }
+ else {
+ /* ??? + date
+ * 'right' must be one of us, or we wouldn't have been called
+ */
+ if (PyDelta_Check(left))
+ /* delta + date */
+ return add_date_timedelta((PyDateTime_Date *) right,
+ (PyDateTime_Delta *) left,
+ 0);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *
+date_subtract(PyObject *left, PyObject *right)
+{
+ if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (PyDate_Check(left)) {
+ if (PyDate_Check(right)) {
+ /* date - date */
+ int left_ord = ymd_to_ord(GET_YEAR(left),
+ GET_MONTH(left),
+ GET_DAY(left));
+ int right_ord = ymd_to_ord(GET_YEAR(right),
+ GET_MONTH(right),
+ GET_DAY(right));
+ return new_delta(left_ord - right_ord, 0, 0, 0);
+ }
+ if (PyDelta_Check(right)) {
+ /* date - delta */
+ return add_date_timedelta((PyDateTime_Date *) left,
+ (PyDateTime_Delta *) right,
+ 1);
+ }
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+
+/* Various ways to turn a date into a string. */
+
+static PyObject *
+date_repr(PyDateTime_Date *self)
+{
+ char buffer[1028];
+ const char *type_name;
+
+ type_name = self->ob_type->tp_name;
+ PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
+ type_name,
+ GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+ return PyString_FromString(buffer);
+}
+
+static PyObject *
+date_isoformat(PyDateTime_Date *self)
+{
+ char buffer[128];
+
+ isoformat_date(self, buffer, sizeof(buffer));
+ return PyString_FromString(buffer);
+}
+
+/* str() calls the appropriate isoformat() method. */
+static PyObject *
+date_str(PyDateTime_Date *self)
+{
+ return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
+}
+
+
+static PyObject *
+date_ctime(PyDateTime_Date *self)
+{
+ return format_ctime(self, 0, 0, 0);
+}
+
+static PyObject *
+date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
+{
+ /* This method can be inherited, and needs to call the
+ * timetuple() method appropriate to self's class.
+ */
+ PyObject *result;
+ PyObject *format;
+ PyObject *tuple;
+ static char *keywords[] = {"format", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
+ &PyString_Type, &format))
+ return NULL;
+
+ tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
+ if (tuple == NULL)
+ return NULL;
+ result = wrap_strftime((PyObject *)self, format, tuple,
+ (PyObject *)self);
+ Py_DECREF(tuple);
+ return result;
+}
+
+/* ISO methods. */
+
+static PyObject *
+date_isoweekday(PyDateTime_Date *self)
+{
+ int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+ return PyInt_FromLong(dow + 1);
+}
+
+static PyObject *
+date_isocalendar(PyDateTime_Date *self)
+{
+ int year = GET_YEAR(self);
+ int week1_monday = iso_week1_monday(year);
+ int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
+ int week;
+ int day;
+
+ week = divmod(today - week1_monday, 7, &day);
+ if (week < 0) {
+ --year;
+ week1_monday = iso_week1_monday(year);
+ week = divmod(today - week1_monday, 7, &day);
+ }
+ else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
+ ++year;
+ week = 0;
+ }
+ return Py_BuildValue("iii", year, week + 1, day + 1);
+}
+
+/* Miscellaneous methods. */
+
+/* This is more natural as a tp_compare, but doesn't work then: for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
+{
+ int diff = 42; /* nonsense */
+
+ if (PyDate_Check(other))
+ diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
+ _PyDateTime_DATE_DATASIZE);
+
+ else if (PyObject_HasAttrString(other, "timetuple")) {
+ /* A hook for other kinds of date objects. */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ else if (op == Py_EQ || op == Py_NE)
+ diff = 1; /* any non-zero value will do */
+
+ else /* stop this from falling back to address comparison */
+ return cmperror((PyObject *)self, other);
+
+ return diff_to_bool(diff, op);
+}
+
+static PyObject *
+date_timetuple(PyDateTime_Date *self)
+{
+ return build_struct_time(GET_YEAR(self),
+ GET_MONTH(self),
+ GET_DAY(self),
+ 0, 0, 0, -1);
+}
+
+static PyObject *
+date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
+{
+ PyObject *clone;
+ PyObject *tuple;
+ int year = GET_YEAR(self);
+ int month = GET_MONTH(self);
+ int day = GET_DAY(self);
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
+ &year, &month, &day))
+ return NULL;
+ tuple = Py_BuildValue("iii", year, month, day);
+ if (tuple == NULL)
+ return NULL;
+ clone = date_new(self->ob_type, tuple, NULL);
+ Py_DECREF(tuple);
+ return clone;
+}
+
+static PyObject *date_getstate(PyDateTime_Date *self);
+
+static long
+date_hash(PyDateTime_Date *self)
+{
+ if (self->hashcode == -1) {
+ PyObject *temp = date_getstate(self);
+ if (temp != NULL) {
+ self->hashcode = PyObject_Hash(temp);
+ Py_DECREF(temp);
+ }
+ }
+ return self->hashcode;
+}
+
+static PyObject *
+date_toordinal(PyDateTime_Date *self)
+{
+ return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
+ GET_DAY(self)));
+}
+
+static PyObject *
+date_weekday(PyDateTime_Date *self)
+{
+ int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+ return PyInt_FromLong(dow);
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* __getstate__ isn't exposed */
+static PyObject *
+date_getstate(PyDateTime_Date *self)
+{
+ return Py_BuildValue(
+ "(N)",
+ PyString_FromStringAndSize((char *)self->data,
+ _PyDateTime_DATE_DATASIZE));
+}
+
+static PyObject *
+date_reduce(PyDateTime_Date *self, PyObject *arg)
+{
+ return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
+}
+
+static PyMethodDef date_methods[] = {
+
+ /* Class methods: */
+
+ {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
+ METH_CLASS,
+ PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
+ "time.time()).")},
+
+ {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
+ METH_CLASS,
+ PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
+ "ordinal.")},
+
+ {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
+ PyDoc_STR("Current date or datetime: same as "
+ "self.__class__.fromtimestamp(time.time()).")},
+
+ /* Instance methods: */
+
+ {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
+ PyDoc_STR("Return ctime() style string.")},
+
+ {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
+ PyDoc_STR("format -> strftime() style string.")},
+
+ {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
+ PyDoc_STR("Return time tuple, compatible with time.localtime().")},
+
+ {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
+ PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
+ "weekday.")},
+
+ {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
+ PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
+
+ {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
+ PyDoc_STR("Return the day of the week represented by the date.\n"
+ "Monday == 1 ... Sunday == 7")},
+
+ {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
+ PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
+ "1 is day 1.")},
+
+ {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
+ PyDoc_STR("Return the day of the week represented by the date.\n"
+ "Monday == 0 ... Sunday == 6")},
+
+ {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
+ PyDoc_STR("Return date with new specified fields.")},
+
+ {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
+ PyDoc_STR("__reduce__() -> (cls, state)")},
+
+ {NULL, NULL}
+};
+
+static char date_doc[] =
+PyDoc_STR("date(year, month, day) --> date object");
+
+static PyNumberMethods date_as_number = {
+ date_add, /* nb_add */
+ date_subtract, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ 0, /* nb_nonzero */
+};
+
+static PyTypeObject PyDateTime_DateType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "datetime.date", /* tp_name */
+ sizeof(PyDateTime_Date), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)date_repr, /* tp_repr */
+ &date_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)date_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)date_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ date_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)date_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ date_methods, /* tp_methods */
+ 0, /* tp_members */
+ date_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ date_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/*
+ * PyDateTime_TZInfo implementation.
+ */
+
+/* This is a pure abstract base class, so doesn't do anything beyond
+ * raising NotImplemented exceptions. Real tzinfo classes need
+ * to derive from this. This is mostly for clarity, and for efficiency in
+ * datetime and time constructors (their tzinfo arguments need to
+ * be subclasses of this tzinfo class, which is easy and quick to check).
+ *
+ * Note: For reasons having to do with pickling of subclasses, we have
+ * to allow tzinfo objects to be instantiated. This wasn't an issue
+ * in the Python implementation (__init__() could raise NotImplementedError
+ * there without ill effect), but doing so in the C implementation hit a
+ * brick wall.
+ */
+
+static PyObject *
+tzinfo_nogo(const char* methodname)
+{
+ PyErr_Format(PyExc_NotImplementedError,
+ "a tzinfo subclass must implement %s()",
+ methodname);
+ return NULL;
+}
+
+/* Methods. A subclass must implement these. */
+
+static PyObject *
+tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
+{
+ return tzinfo_nogo("tzname");
+}
+
+static PyObject *
+tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
+{
+ return tzinfo_nogo("utcoffset");
+}
+
+static PyObject *
+tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
+{
+ return tzinfo_nogo("dst");
+}
+
+static PyObject *
+tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
+{
+ int y, m, d, hh, mm, ss, us;
+
+ PyObject *result;
+ int off, dst;
+ int none;
+ int delta;
+
+ if (! PyDateTime_Check(dt)) {
+ PyErr_SetString(PyExc_TypeError,
+ "fromutc: argument must be a datetime");
+ return NULL;
+ }
+ if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
+ PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
+ "is not self");
+ return NULL;
+ }
+
+ off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
+ if (off == -1 && PyErr_Occurred())
+ return NULL;
+ if (none) {
+ PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
+ "utcoffset() result required");
+ return NULL;
+ }
+
+ dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
+ if (dst == -1 && PyErr_Occurred())
+ return NULL;
+ if (none) {
+ PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
+ "dst() result required");
+ return NULL;
+ }
+
+ y = GET_YEAR(dt);
+ m = GET_MONTH(dt);
+ d = GET_DAY(dt);
+ hh = DATE_GET_HOUR(dt);
+ mm = DATE_GET_MINUTE(dt);
+ ss = DATE_GET_SECOND(dt);
+ us = DATE_GET_MICROSECOND(dt);
+
+ delta = off - dst;
+ mm += delta;
+ if ((mm < 0 || mm >= 60) &&
+ normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
+ return NULL;
+ result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
+ if (result == NULL)
+ return result;
+
+ dst = call_dst(dt->tzinfo, result, &none);
+ if (dst == -1 && PyErr_Occurred())
+ goto Fail;
+ if (none)
+ goto Inconsistent;
+ if (dst == 0)
+ return result;
+
+ mm += dst;
+ if ((mm < 0 || mm >= 60) &&
+ normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
+ goto Fail;
+ Py_DECREF(result);
+ result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
+ return result;
+
+Inconsistent:
+ PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
+ "inconsistent results; cannot convert");
+
+ /* fall thru to failure */
+Fail:
+ Py_DECREF(result);
+ return NULL;
+}
+
+/*
+ * Pickle support. This is solely so that tzinfo subclasses can use
+ * pickling -- tzinfo itself is supposed to be uninstantiable.
+ */
+
+static PyObject *
+tzinfo_reduce(PyObject *self)
+{
+ PyObject *args, *state, *tmp;
+ PyObject *getinitargs, *getstate;
+
+ tmp = PyTuple_New(0);
+ if (tmp == NULL)
+ return NULL;
+
+ getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
+ if (getinitargs != NULL) {
+ args = PyObject_CallObject(getinitargs, tmp);
+ Py_DECREF(getinitargs);
+ if (args == NULL) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Clear();
+ args = tmp;
+ Py_INCREF(args);
+ }
+
+ getstate = PyObject_GetAttrString(self, "__getstate__");
+ if (getstate != NULL) {
+ state = PyObject_CallObject(getstate, tmp);
+ Py_DECREF(getstate);
+ if (state == NULL) {
+ Py_DECREF(args);
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ }
+ else {
+ PyObject **dictptr;
+ PyErr_Clear();
+ state = Py_None;
+ dictptr = _PyObject_GetDictPtr(self);
+ if (dictptr && *dictptr && PyDict_Size(*dictptr))
+ state = *dictptr;
+ Py_INCREF(state);
+ }
+
+ Py_DECREF(tmp);
+
+ if (state == Py_None) {
+ Py_DECREF(state);
+ return Py_BuildValue("(ON)", self->ob_type, args);
+ }
+ else
+ return Py_BuildValue("(ONN)", self->ob_type, args, state);
+}
+
+static PyMethodDef tzinfo_methods[] = {
+
+ {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
+ PyDoc_STR("datetime -> string name of time zone.")},
+
+ {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
+ PyDoc_STR("datetime -> minutes east of UTC (negative for "
+ "west of UTC).")},
+
+ {"dst", (PyCFunction)tzinfo_dst, METH_O,
+ PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
+
+ {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
+ PyDoc_STR("datetime in UTC -> datetime in local time.")},
+
+ {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
+ PyDoc_STR("-> (cls, state)")},
+
+ {NULL, NULL}
+};
+
+static char tzinfo_doc[] =
+PyDoc_STR("Abstract base class for time zone info objects.");
+
+statichere PyTypeObject PyDateTime_TZInfoType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "datetime.tzinfo", /* tp_name */
+ sizeof(PyDateTime_TZInfo), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ tzinfo_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ tzinfo_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ 0, /* tp_free */
+};
+
+/*
+ * PyDateTime_Time implementation.
+ */
+
+/* Accessor properties.
+ */
+
+static PyObject *
+time_hour(PyDateTime_Time *self, void *unused)
+{
+ return PyInt_FromLong(TIME_GET_HOUR(self));
+}
+
+static PyObject *
+time_minute(PyDateTime_Time *self, void *unused)
+{
+ return PyInt_FromLong(TIME_GET_MINUTE(self));
+}
+
+/* The name time_second conflicted with some platform header file. */
+static PyObject *
+py_time_second(PyDateTime_Time *self, void *unused)
+{
+ return PyInt_FromLong(TIME_GET_SECOND(self));
+}
+
+static PyObject *
+time_microsecond(PyDateTime_Time *self, void *unused)
+{
+ return PyInt_FromLong(TIME_GET_MICROSECOND(self));
+}
+
+static PyObject *
+time_tzinfo(PyDateTime_Time *self, void *unused)
+{
+ PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyGetSetDef time_getset[] = {
+ {"hour", (getter)time_hour},
+ {"minute", (getter)time_minute},
+ {"second", (getter)py_time_second},
+ {"microsecond", (getter)time_microsecond},
+ {"tzinfo", (getter)time_tzinfo},
+ {NULL}
+};
+
+/*
+ * Constructors.
+ */
+
+static char *time_kws[] = {"hour", "minute", "second", "microsecond",
+ "tzinfo", NULL};
+
+static PyObject *
+time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *self = NULL;
+ PyObject *state;
+ int hour = 0;
+ int minute = 0;
+ int second = 0;
+ int usecond = 0;
+ PyObject *tzinfo = Py_None;
+
+ /* Check for invocation from pickle with __getstate__ state */
+ if (PyTuple_GET_SIZE(args) >= 1 &&
+ PyTuple_GET_SIZE(args) <= 2 &&
+ PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
+ PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
+ ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
+ {
+ PyDateTime_Time *me;
+ char aware;
+
+ if (PyTuple_GET_SIZE(args) == 2) {
+ tzinfo = PyTuple_GET_ITEM(args, 1);
+ if (check_tzinfo_subclass(tzinfo) < 0) {
+ PyErr_SetString(PyExc_TypeError, "bad "
+ "tzinfo state arg");
+ return NULL;
+ }
+ }
+ aware = (char)(tzinfo != Py_None);
+ me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
+ if (me != NULL) {
+ char *pdata = PyString_AS_STRING(state);
+
+ memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
+ me->hashcode = -1;
+ me->hastzinfo = aware;
+ if (aware) {
+ Py_INCREF(tzinfo);
+ me->tzinfo = tzinfo;
+ }
+ }
+ return (PyObject *)me;
+ }
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
+ &hour, &minute, &second, &usecond,
+ &tzinfo)) {
+ if (check_time_args(hour, minute, second, usecond) < 0)
+ return NULL;
+ if (check_tzinfo_subclass(tzinfo) < 0)
+ return NULL;
+ self = new_time_ex(hour, minute, second, usecond, tzinfo,
+ type);
+ }
+ return self;
+}
+
+/*
+ * Destructor.
+ */
+
+static void
+time_dealloc(PyDateTime_Time *self)
+{
+ if (HASTZINFO(self)) {
+ Py_XDECREF(self->tzinfo);
+ }
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+/*
+ * Indirect access to tzinfo methods.
+ */
+
+/* These are all METH_NOARGS, so don't need to check the arglist. */
+static PyObject *
+time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
+ return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+ "utcoffset", Py_None);
+}
+
+static PyObject *
+time_dst(PyDateTime_Time *self, PyObject *unused) {
+ return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+ "dst", Py_None);
+}
+
+static PyObject *
+time_tzname(PyDateTime_Time *self, PyObject *unused) {
+ return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
+ Py_None);
+}
+
+/*
+ * Various ways to turn a time into a string.
+ */
+
+static PyObject *
+time_repr(PyDateTime_Time *self)
+{
+ char buffer[100];
+ const char *type_name = self->ob_type->tp_name;
+ int h = TIME_GET_HOUR(self);
+ int m = TIME_GET_MINUTE(self);
+ int s = TIME_GET_SECOND(self);
+ int us = TIME_GET_MICROSECOND(self);
+ PyObject *result = NULL;
+
+ if (us)
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
+ else if (s)
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%s(%d, %d, %d)", type_name, h, m, s);
+ else
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%s(%d, %d)", type_name, h, m);
+ result = PyString_FromString(buffer);
+ if (result != NULL && HASTZINFO(self))
+ result = append_keyword_tzinfo(result, self->tzinfo);
+ return result;
+}
+
+static PyObject *
+time_str(PyDateTime_Time *self)
+{
+ return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
+}
+
+/* Even though this silently ignores all arguments, it cannot
+ be fixed to reject them in release25-maint */
+static PyObject *
+time_isoformat(PyDateTime_Time *self, PyObject *unused_args,
+ PyObject *unused_keywords)
+{
+ char buf[100];
+ PyObject *result;
+ /* Reuse the time format code from the datetime type. */
+ PyDateTime_DateTime datetime;
+ PyDateTime_DateTime *pdatetime = &datetime;
+
+ /* Copy over just the time bytes. */
+ memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
+ self->data,
+ _PyDateTime_TIME_DATASIZE);
+
+ isoformat_time(pdatetime, buf, sizeof(buf));
+ result = PyString_FromString(buf);
+ if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
+ return result;
+
+ /* We need to append the UTC offset. */
+ if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
+ Py_None) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyString_ConcatAndDel(&result, PyString_FromString(buf));
+ return result;
+}
+
+static PyObject *
+time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
+{
+ PyObject *result;
+ PyObject *format;
+ PyObject *tuple;
+ static char *keywords[] = {"format", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
+ &PyString_Type, &format))
+ return NULL;
+
+ /* Python's strftime does insane things with the year part of the
+ * timetuple. The year is forced to (the otherwise nonsensical)
+ * 1900 to worm around that.
+ */
+ tuple = Py_BuildValue("iiiiiiiii",
+ 1900, 1, 1, /* year, month, day */
+ TIME_GET_HOUR(self),
+ TIME_GET_MINUTE(self),
+ TIME_GET_SECOND(self),
+ 0, 1, -1); /* weekday, daynum, dst */
+ if (tuple == NULL)
+ return NULL;
+ assert(PyTuple_Size(tuple) == 9);
+ result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
+ Py_DECREF(tuple);
+ return result;
+}
+
+/*
+ * Miscellaneous methods.
+ */
+
+/* This is more natural as a tp_compare, but doesn't work then: for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
+{
+ int diff;
+ naivety n1, n2;
+ int offset1, offset2;
+
+ if (! PyTime_Check(other)) {
+ if (op == Py_EQ || op == Py_NE) {
+ PyObject *result = op == Py_EQ ? Py_False : Py_True;
+ Py_INCREF(result);
+ return result;
+ }
+ /* Stop this from falling back to address comparison. */
+ return cmperror((PyObject *)self, other);
+ }
+ if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
+ other, &offset2, &n2, Py_None) < 0)
+ return NULL;
+ assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
+ /* If they're both naive, or both aware and have the same offsets,
+ * we get off cheap. Note that if they're both naive, offset1 ==
+ * offset2 == 0 at this point.
+ */
+ if (n1 == n2 && offset1 == offset2) {
+ diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
+ _PyDateTime_TIME_DATASIZE);
+ return diff_to_bool(diff, op);
+ }
+
+ if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
+ assert(offset1 != offset2); /* else last "if" handled it */
+ /* Convert everything except microseconds to seconds. These
+ * can't overflow (no more than the # of seconds in 2 days).
+ */
+ offset1 = TIME_GET_HOUR(self) * 3600 +
+ (TIME_GET_MINUTE(self) - offset1) * 60 +
+ TIME_GET_SECOND(self);
+ offset2 = TIME_GET_HOUR(other) * 3600 +
+ (TIME_GET_MINUTE(other) - offset2) * 60 +
+ TIME_GET_SECOND(other);
+ diff = offset1 - offset2;
+ if (diff == 0)
+ diff = TIME_GET_MICROSECOND(self) -
+ TIME_GET_MICROSECOND(other);
+ return diff_to_bool(diff, op);
+ }
+
+ assert(n1 != n2);
+ PyErr_SetString(PyExc_TypeError,
+ "can't compare offset-naive and "
+ "offset-aware times");
+ return NULL;
+}
+
+static long
+time_hash(PyDateTime_Time *self)
+{
+ if (self->hashcode == -1) {
+ naivety n;
+ int offset;
+ PyObject *temp;
+
+ n = classify_utcoffset((PyObject *)self, Py_None, &offset);
+ assert(n != OFFSET_UNKNOWN);
+ if (n == OFFSET_ERROR)
+ return -1;
+
+ /* Reduce this to a hash of another object. */
+ if (offset == 0)
+ temp = PyString_FromStringAndSize((char *)self->data,
+ _PyDateTime_TIME_DATASIZE);
+ else {
+ int hour;
+ int minute;
+
+ assert(n == OFFSET_AWARE);
+ assert(HASTZINFO(self));
+ hour = divmod(TIME_GET_HOUR(self) * 60 +
+ TIME_GET_MINUTE(self) - offset,
+ 60,
+ &minute);
+ if (0 <= hour && hour < 24)
+ temp = new_time(hour, minute,
+ TIME_GET_SECOND(self),
+ TIME_GET_MICROSECOND(self),
+ Py_None);
+ else
+ temp = Py_BuildValue("iiii",
+ hour, minute,
+ TIME_GET_SECOND(self),
+ TIME_GET_MICROSECOND(self));
+ }
+ if (temp != NULL) {
+ self->hashcode = PyObject_Hash(temp);
+ Py_DECREF(temp);
+ }
+ }
+ return self->hashcode;
+}
+
+static PyObject *
+time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
+{
+ PyObject *clone;
+ PyObject *tuple;
+ int hh = TIME_GET_HOUR(self);
+ int mm = TIME_GET_MINUTE(self);
+ int ss = TIME_GET_SECOND(self);
+ int us = TIME_GET_MICROSECOND(self);
+ PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
+ time_kws,
+ &hh, &mm, &ss, &us, &tzinfo))
+ return NULL;
+ tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
+ if (tuple == NULL)
+ return NULL;
+ clone = time_new(self->ob_type, tuple, NULL);
+ Py_DECREF(tuple);
+ return clone;
+}
+
+static int
+time_nonzero(PyDateTime_Time *self)
+{
+ int offset;
+ int none;
+
+ if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
+ /* Since utcoffset is in whole minutes, nothing can
+ * alter the conclusion that this is nonzero.
+ */
+ return 1;
+ }
+ offset = 0;
+ if (HASTZINFO(self) && self->tzinfo != Py_None) {
+ offset = call_utcoffset(self->tzinfo, Py_None, &none);
+ if (offset == -1 && PyErr_Occurred())
+ return -1;
+ }
+ return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* Let basestate be the non-tzinfo data string.
+ * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
+ * So it's a tuple in any (non-error) case.
+ * __getstate__ isn't exposed.
+ */
+static PyObject *
+time_getstate(PyDateTime_Time *self)
+{
+ PyObject *basestate;
+ PyObject *result = NULL;
+
+ basestate = PyString_FromStringAndSize((char *)self->data,
+ _PyDateTime_TIME_DATASIZE);
+ if (basestate != NULL) {
+ if (! HASTZINFO(self) || self->tzinfo == Py_None)
+ result = PyTuple_Pack(1, basestate);
+ else
+ result = PyTuple_Pack(2, basestate, self->tzinfo);
+ Py_DECREF(basestate);
+ }
+ return result;
+}
+
+static PyObject *
+time_reduce(PyDateTime_Time *self, PyObject *arg)
+{
+ return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
+}
+
+static PyMethodDef time_methods[] = {
+
+ {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
+ PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
+ "[+HH:MM].")},
+
+ {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
+ PyDoc_STR("format -> strftime() style string.")},
+
+ {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
+ PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
+
+ {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
+ PyDoc_STR("Return self.tzinfo.tzname(self).")},
+
+ {"dst", (PyCFunction)time_dst, METH_NOARGS,
+ PyDoc_STR("Return self.tzinfo.dst(self).")},
+
+ {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
+ PyDoc_STR("Return time with new specified fields.")},
+
+ {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
+ PyDoc_STR("__reduce__() -> (cls, state)")},
+
+ {NULL, NULL}
+};
+
+static char time_doc[] =
+PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
+\n\
+All arguments are optional. tzinfo may be None, or an instance of\n\
+a tzinfo subclass. The remaining arguments may be ints or longs.\n");
+
+static PyNumberMethods time_as_number = {
+ 0, /* nb_add */
+ 0, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ (inquiry)time_nonzero, /* nb_nonzero */
+};
+
+statichere PyTypeObject PyDateTime_TimeType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "datetime.time", /* tp_name */
+ sizeof(PyDateTime_Time), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)time_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)time_repr, /* tp_repr */
+ &time_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)time_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)time_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ time_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)time_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ time_methods, /* tp_methods */
+ 0, /* tp_members */
+ time_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ time_alloc, /* tp_alloc */
+ time_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/*
+ * PyDateTime_DateTime implementation.
+ */
+
+/* Accessor properties. Properties for day, month, and year are inherited
+ * from date.
+ */
+
+static PyObject *
+datetime_hour(PyDateTime_DateTime *self, void *unused)
+{
+ return PyInt_FromLong(DATE_GET_HOUR(self));
+}
+
+static PyObject *
+datetime_minute(PyDateTime_DateTime *self, void *unused)
+{
+ return PyInt_FromLong(DATE_GET_MINUTE(self));
+}
+
+static PyObject *
+datetime_second(PyDateTime_DateTime *self, void *unused)
+{
+ return PyInt_FromLong(DATE_GET_SECOND(self));
+}
+
+static PyObject *
+datetime_microsecond(PyDateTime_DateTime *self, void *unused)
+{
+ return PyInt_FromLong(DATE_GET_MICROSECOND(self));
+}
+
+static PyObject *
+datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
+{
+ PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyGetSetDef datetime_getset[] = {
+ {"hour", (getter)datetime_hour},
+ {"minute", (getter)datetime_minute},
+ {"second", (getter)datetime_second},
+ {"microsecond", (getter)datetime_microsecond},
+ {"tzinfo", (getter)datetime_tzinfo},
+ {NULL}
+};
+
+/*
+ * Constructors.
+ */
+
+static char *datetime_kws[] = {
+ "year", "month", "day", "hour", "minute", "second",
+ "microsecond", "tzinfo", NULL
+};
+
+static PyObject *
+datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *self = NULL;
+ PyObject *state;
+ int year;
+ int month;
+ int day;
+ int hour = 0;
+ int minute = 0;
+ int second = 0;
+ int usecond = 0;
+ PyObject *tzinfo = Py_None;
+
+ /* Check for invocation from pickle with __getstate__ state */
+ if (PyTuple_GET_SIZE(args) >= 1 &&
+ PyTuple_GET_SIZE(args) <= 2 &&
+ PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
+ PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
+ MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
+ {
+ PyDateTime_DateTime *me;
+ char aware;
+
+ if (PyTuple_GET_SIZE(args) == 2) {
+ tzinfo = PyTuple_GET_ITEM(args, 1);
+ if (check_tzinfo_subclass(tzinfo) < 0) {
+ PyErr_SetString(PyExc_TypeError, "bad "
+ "tzinfo state arg");
+ return NULL;
+ }
+ }
+ aware = (char)(tzinfo != Py_None);
+ me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
+ if (me != NULL) {
+ char *pdata = PyString_AS_STRING(state);
+
+ memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
+ me->hashcode = -1;
+ me->hastzinfo = aware;
+ if (aware) {
+ Py_INCREF(tzinfo);
+ me->tzinfo = tzinfo;
+ }
+ }
+ return (PyObject *)me;
+ }
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
+ &year, &month, &day, &hour, &minute,
+ &second, &usecond, &tzinfo)) {
+ if (check_date_args(year, month, day) < 0)
+ return NULL;
+ if (check_time_args(hour, minute, second, usecond) < 0)
+ return NULL;
+ if (check_tzinfo_subclass(tzinfo) < 0)
+ return NULL;
+ self = new_datetime_ex(year, month, day,
+ hour, minute, second, usecond,
+ tzinfo, type);
+ }
+ return self;
+}
+
+/* TM_FUNC is the shared type of localtime() and gmtime(). */
+typedef struct tm *(*TM_FUNC)(const time_t *timer);
+
+/* Internal helper.
+ * Build datetime from a time_t and a distinct count of microseconds.
+ * Pass localtime or gmtime for f, to control the interpretation of timet.
+ */
+static PyObject *
+datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
+ PyObject *tzinfo)
+{
+ struct tm *tm;
+ PyObject *result = NULL;
+
+ tm = f(&timet);
+ if (tm) {
+ /* The platform localtime/gmtime may insert leap seconds,
+ * indicated by tm->tm_sec > 59. We don't care about them,
+ * except to the extent that passing them on to the datetime
+ * constructor would raise ValueError for a reason that
+ * made no sense to the user.
+ */
+ if (tm->tm_sec > 59)
+ tm->tm_sec = 59;
+ result = PyObject_CallFunction(cls, "iiiiiiiO",
+ tm->tm_year + 1900,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ us,
+ tzinfo);
+ }
+ else
+ PyErr_SetString(PyExc_ValueError,
+ "timestamp out of range for "
+ "platform localtime()/gmtime() function");
+ return result;
+}
+
+/* Internal helper.
+ * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
+ * to control the interpretation of the timestamp. Since a double doesn't
+ * have enough bits to cover a datetime's full range of precision, it's
+ * better to call datetime_from_timet_and_us provided you have a way
+ * to get that much precision (e.g., C time() isn't good enough).
+ */
+static PyObject *
+datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
+ PyObject *tzinfo)
+{
+ time_t timet;
+ double fraction;
+ int us;
+
+ timet = _PyTime_DoubleToTimet(timestamp);
+ if (timet == (time_t)-1 && PyErr_Occurred())
+ return NULL;
+ fraction = timestamp - (double)timet;
+ us = (int)round_to_long(fraction * 1e6);
+ if (us < 0) {
+ /* Truncation towards zero is not what we wanted
+ for negative numbers (Python's mod semantics) */
+ timet -= 1;
+ us += 1000000;
+ }
+ /* If timestamp is less than one microsecond smaller than a
+ * full second, round up. Otherwise, ValueErrors are raised
+ * for some floats. */
+ if (us == 1000000) {
+ timet += 1;
+ us = 0;
+ }
+ return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
+}
+
+/* Internal helper.
+ * Build most accurate possible datetime for current time. Pass localtime or
+ * gmtime for f as appropriate.
+ */
+static PyObject *
+datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
+{
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval t;
+
+#ifdef GETTIMEOFDAY_NO_TZ
+ gettimeofday(&t);
+#else
+ gettimeofday(&t, (struct timezone *)NULL);
+#endif
+ return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
+ tzinfo);
+
+#else /* ! HAVE_GETTIMEOFDAY */
+ /* No flavor of gettimeofday exists on this platform. Python's
+ * time.time() does a lot of other platform tricks to get the
+ * best time it can on the platform, and we're not going to do
+ * better than that (if we could, the better code would belong
+ * in time.time()!) We're limited by the precision of a double,
+ * though.
+ */
+ PyObject *time;
+ double dtime;
+
+ time = time_time();
+ if (time == NULL)
+ return NULL;
+ dtime = PyFloat_AsDouble(time);
+ Py_DECREF(time);
+ if (dtime == -1.0 && PyErr_Occurred())
+ return NULL;
+ return datetime_from_timestamp(cls, f, dtime, tzinfo);
+#endif /* ! HAVE_GETTIMEOFDAY */
+}
+
+/* Return best possible local time -- this isn't constrained by the
+ * precision of a timestamp.
+ */
+static PyObject *
+datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
+{
+ PyObject *self;
+ PyObject *tzinfo = Py_None;
+ static char *keywords[] = {"tz", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
+ &tzinfo))
+ return NULL;
+ if (check_tzinfo_subclass(tzinfo) < 0)
+ return NULL;
+
+ self = datetime_best_possible(cls,
+ tzinfo == Py_None ? localtime : gmtime,
+ tzinfo);
+ if (self != NULL && tzinfo != Py_None) {
+ /* Convert UTC to tzinfo's zone. */
+ PyObject *temp = self;
+ self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
+ Py_DECREF(temp);
+ }
+ return self;
+}
+
+/* Return best possible UTC time -- this isn't constrained by the
+ * precision of a timestamp.
+ */
+static PyObject *
+datetime_utcnow(PyObject *cls, PyObject *dummy)
+{
+ return datetime_best_possible(cls, gmtime, Py_None);
+}
+
+/* Return new local datetime from timestamp (Python timestamp -- a double). */
+static PyObject *
+datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
+{
+ PyObject *self;
+ double timestamp;
+ PyObject *tzinfo = Py_None;
+ static char *keywords[] = {"timestamp", "tz", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
+ keywords, &timestamp, &tzinfo))
+ return NULL;
+ if (check_tzinfo_subclass(tzinfo) < 0)
+ return NULL;
+
+ self = datetime_from_timestamp(cls,
+ tzinfo == Py_None ? localtime : gmtime,
+ timestamp,
+ tzinfo);
+ if (self != NULL && tzinfo != Py_None) {
+ /* Convert UTC to tzinfo's zone. */
+ PyObject *temp = self;
+ self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
+ Py_DECREF(temp);
+ }
+ return self;
+}
+
+/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
+static PyObject *
+datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
+{
+ double timestamp;
+ PyObject *result = NULL;
+
+ if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
+ result = datetime_from_timestamp(cls, gmtime, timestamp,
+ Py_None);
+ return result;
+}
+
+/* Return new datetime from time.strptime(). */
+static PyObject *
+datetime_strptime(PyObject *cls, PyObject *args)
+{
+ PyObject *result = NULL, *obj, *module;
+ const char *string, *format;
+
+ if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
+ return NULL;
+
+ if ((module = PyImport_ImportModule("time")) == NULL)
+ return NULL;
+ obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
+ Py_DECREF(module);
+
+ if (obj != NULL) {
+ int i, good_timetuple = 1;
+ long int ia[6];
+ if (PySequence_Check(obj) && PySequence_Size(obj) >= 6)
+ for (i=0; i < 6; i++) {
+ PyObject *p = PySequence_GetItem(obj, i);
+ if (p == NULL) {
+ Py_DECREF(obj);
+ return NULL;
+ }
+ if (PyInt_Check(p))
+ ia[i] = PyInt_AsLong(p);
+ else
+ good_timetuple = 0;
+ Py_DECREF(p);
+ }
+ else
+ good_timetuple = 0;
+ if (good_timetuple)
+ result = PyObject_CallFunction(cls, "iiiiii",
+ ia[0], ia[1], ia[2], ia[3], ia[4], ia[5]);
+ else
+ PyErr_SetString(PyExc_ValueError,
+ "unexpected value from time.strptime");
+ Py_DECREF(obj);
+ }
+ return result;
+}
+
+/* Return new datetime from date/datetime and time arguments. */
+static PyObject *
+datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
+{
+ static char *keywords[] = {"date", "time", NULL};
+ PyObject *date;
+ PyObject *time;
+ PyObject *result = NULL;
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
+ &PyDateTime_DateType, &date,
+ &PyDateTime_TimeType, &time)) {
+ PyObject *tzinfo = Py_None;
+
+ if (HASTZINFO(time))
+ tzinfo = ((PyDateTime_Time *)time)->tzinfo;
+ result = PyObject_CallFunction(cls, "iiiiiiiO",
+ GET_YEAR(date),
+ GET_MONTH(date),
+ GET_DAY(date),
+ TIME_GET_HOUR(time),
+ TIME_GET_MINUTE(time),
+ TIME_GET_SECOND(time),
+ TIME_GET_MICROSECOND(time),
+ tzinfo);
+ }
+ return result;
+}
+
+/*
+ * Destructor.
+ */
+
+static void
+datetime_dealloc(PyDateTime_DateTime *self)
+{
+ if (HASTZINFO(self)) {
+ Py_XDECREF(self->tzinfo);
+ }
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+/*
+ * Indirect access to tzinfo methods.
+ */
+
+/* These are all METH_NOARGS, so don't need to check the arglist. */
+static PyObject *
+datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
+ return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+ "utcoffset", (PyObject *)self);
+}
+
+static PyObject *
+datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
+ return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
+ "dst", (PyObject *)self);
+}
+
+static PyObject *
+datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
+ return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
+ (PyObject *)self);
+}
+
+/*
+ * datetime arithmetic.
+ */
+
+/* factor must be 1 (to add) or -1 (to subtract). The result inherits
+ * the tzinfo state of date.
+ */
+static PyObject *
+add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
+ int factor)
+{
+ /* Note that the C-level additions can't overflow, because of
+ * invariant bounds on the member values.
+ */
+ int year = GET_YEAR(date);
+ int month = GET_MONTH(date);
+ int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
+ int hour = DATE_GET_HOUR(date);
+ int minute = DATE_GET_MINUTE(date);
+ int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
+ int microsecond = DATE_GET_MICROSECOND(date) +
+ GET_TD_MICROSECONDS(delta) * factor;
+
+ assert(factor == 1 || factor == -1);
+ if (normalize_datetime(&year, &month, &day,
+ &hour, &minute, &second, &microsecond) < 0)
+ return NULL;
+ else
+ return new_datetime(year, month, day,
+ hour, minute, second, microsecond,
+ HASTZINFO(date) ? date->tzinfo : Py_None);
+}
+
+static PyObject *
+datetime_add(PyObject *left, PyObject *right)
+{
+ if (PyDateTime_Check(left)) {
+ /* datetime + ??? */
+ if (PyDelta_Check(right))
+ /* datetime + delta */
+ return add_datetime_timedelta(
+ (PyDateTime_DateTime *)left,
+ (PyDateTime_Delta *)right,
+ 1);
+ }
+ else if (PyDelta_Check(left)) {
+ /* delta + datetime */
+ return add_datetime_timedelta((PyDateTime_DateTime *) right,
+ (PyDateTime_Delta *) left,
+ 1);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *
+datetime_subtract(PyObject *left, PyObject *right)
+{
+ PyObject *result = Py_NotImplemented;
+
+ if (PyDateTime_Check(left)) {
+ /* datetime - ??? */
+ if (PyDateTime_Check(right)) {
+ /* datetime - datetime */
+ naivety n1, n2;
+ int offset1, offset2;
+ int delta_d, delta_s, delta_us;
+
+ if (classify_two_utcoffsets(left, &offset1, &n1, left,
+ right, &offset2, &n2,
+ right) < 0)
+ return NULL;
+ assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
+ if (n1 != n2) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't subtract offset-naive and "
+ "offset-aware datetimes");
+ return NULL;
+ }
+ delta_d = ymd_to_ord(GET_YEAR(left),
+ GET_MONTH(left),
+ GET_DAY(left)) -
+ ymd_to_ord(GET_YEAR(right),
+ GET_MONTH(right),
+ GET_DAY(right));
+ /* These can't overflow, since the values are
+ * normalized. At most this gives the number of
+ * seconds in one day.
+ */
+ delta_s = (DATE_GET_HOUR(left) -
+ DATE_GET_HOUR(right)) * 3600 +
+ (DATE_GET_MINUTE(left) -
+ DATE_GET_MINUTE(right)) * 60 +
+ (DATE_GET_SECOND(left) -
+ DATE_GET_SECOND(right));
+ delta_us = DATE_GET_MICROSECOND(left) -
+ DATE_GET_MICROSECOND(right);
+ /* (left - offset1) - (right - offset2) =
+ * (left - right) + (offset2 - offset1)
+ */
+ delta_s += (offset2 - offset1) * 60;
+ result = new_delta(delta_d, delta_s, delta_us, 1);
+ }
+ else if (PyDelta_Check(right)) {
+ /* datetime - delta */
+ result = add_datetime_timedelta(
+ (PyDateTime_DateTime *)left,
+ (PyDateTime_Delta *)right,
+ -1);
+ }
+ }
+
+ if (result == Py_NotImplemented)
+ Py_INCREF(result);
+ return result;
+}
+
+/* Various ways to turn a datetime into a string. */
+
+static PyObject *
+datetime_repr(PyDateTime_DateTime *self)
+{
+ char buffer[1000];
+ const char *type_name = self->ob_type->tp_name;
+ PyObject *baserepr;
+
+ if (DATE_GET_MICROSECOND(self)) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%s(%d, %d, %d, %d, %d, %d, %d)",
+ type_name,
+ GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+ DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
+ DATE_GET_SECOND(self),
+ DATE_GET_MICROSECOND(self));
+ }
+ else if (DATE_GET_SECOND(self)) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%s(%d, %d, %d, %d, %d, %d)",
+ type_name,
+ GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+ DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
+ DATE_GET_SECOND(self));
+ }
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%s(%d, %d, %d, %d, %d)",
+ type_name,
+ GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+ DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
+ }
+ baserepr = PyString_FromString(buffer);
+ if (baserepr == NULL || ! HASTZINFO(self))
+ return baserepr;
+ return append_keyword_tzinfo(baserepr, self->tzinfo);
+}
+
+static PyObject *
+datetime_str(PyDateTime_DateTime *self)
+{
+ return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
+}
+
+static PyObject *
+datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+{
+ char sep = 'T';
+ static char *keywords[] = {"sep", NULL};
+ char buffer[100];
+ char *cp;
+ PyObject *result;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
+ &sep))
+ return NULL;
+ cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
+ assert(cp != NULL);
+ *cp++ = sep;
+ isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
+ result = PyString_FromString(buffer);
+ if (result == NULL || ! HASTZINFO(self))
+ return result;
+
+ /* We need to append the UTC offset. */
+ if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
+ (PyObject *)self) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyString_ConcatAndDel(&result, PyString_FromString(buffer));
+ return result;
+}
+
+static PyObject *
+datetime_ctime(PyDateTime_DateTime *self)
+{
+ return format_ctime((PyDateTime_Date *)self,
+ DATE_GET_HOUR(self),
+ DATE_GET_MINUTE(self),
+ DATE_GET_SECOND(self));
+}
+
+/* Miscellaneous methods. */
+
+/* This is more natural as a tp_compare, but doesn't work then: for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+static PyObject *
+datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
+{
+ int diff;
+ naivety n1, n2;
+ int offset1, offset2;
+
+ if (! PyDateTime_Check(other)) {
+ /* If other has a "timetuple" attr, that's an advertised
+ * hook for other classes to ask to get comparison control.
+ * However, date instances have a timetuple attr, and we
+ * don't want to allow that comparison. Because datetime
+ * is a subclass of date, when mixing date and datetime
+ * in a comparison, Python gives datetime the first shot
+ * (it's the more specific subtype). So we can stop that
+ * combination here reliably.
+ */
+ if (PyObject_HasAttrString(other, "timetuple") &&
+ ! PyDate_Check(other)) {
+ /* A hook for other kinds of datetime objects. */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (op == Py_EQ || op == Py_NE) {
+ PyObject *result = op == Py_EQ ? Py_False : Py_True;
+ Py_INCREF(result);
+ return result;
+ }
+ /* Stop this from falling back to address comparison. */
+ return cmperror((PyObject *)self, other);
+ }
+
+ if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
+ (PyObject *)self,
+ other, &offset2, &n2,
+ other) < 0)
+ return NULL;
+ assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
+ /* If they're both naive, or both aware and have the same offsets,
+ * we get off cheap. Note that if they're both naive, offset1 ==
+ * offset2 == 0 at this point.
+ */
+ if (n1 == n2 && offset1 == offset2) {
+ diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
+ _PyDateTime_DATETIME_DATASIZE);
+ return diff_to_bool(diff, op);
+ }
+
+ if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
+ PyDateTime_Delta *delta;
+
+ assert(offset1 != offset2); /* else last "if" handled it */
+ delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
+ other);
+ if (delta == NULL)
+ return NULL;
+ diff = GET_TD_DAYS(delta);
+ if (diff == 0)
+ diff = GET_TD_SECONDS(delta) |
+ GET_TD_MICROSECONDS(delta);
+ Py_DECREF(delta);
+ return diff_to_bool(diff, op);
+ }
+
+ assert(n1 != n2);
+ PyErr_SetString(PyExc_TypeError,
+ "can't compare offset-naive and "
+ "offset-aware datetimes");
+ return NULL;
+}
+
+static long
+datetime_hash(PyDateTime_DateTime *self)
+{
+ if (self->hashcode == -1) {
+ naivety n;
+ int offset;
+ PyObject *temp;
+
+ n = classify_utcoffset((PyObject *)self, (PyObject *)self,
+ &offset);
+ assert(n != OFFSET_UNKNOWN);
+ if (n == OFFSET_ERROR)
+ return -1;
+
+ /* Reduce this to a hash of another object. */
+ if (n == OFFSET_NAIVE)
+ temp = PyString_FromStringAndSize(
+ (char *)self->data,
+ _PyDateTime_DATETIME_DATASIZE);
+ else {
+ int days;
+ int seconds;
+
+ assert(n == OFFSET_AWARE);
+ assert(HASTZINFO(self));
+ days = ymd_to_ord(GET_YEAR(self),
+ GET_MONTH(self),
+ GET_DAY(self));
+ seconds = DATE_GET_HOUR(self) * 3600 +
+ (DATE_GET_MINUTE(self) - offset) * 60 +
+ DATE_GET_SECOND(self);
+ temp = new_delta(days,
+ seconds,
+ DATE_GET_MICROSECOND(self),
+ 1);
+ }
+ if (temp != NULL) {
+ self->hashcode = PyObject_Hash(temp);
+ Py_DECREF(temp);
+ }
+ }
+ return self->hashcode;
+}
+
+static PyObject *
+datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+{
+ PyObject *clone;
+ PyObject *tuple;
+ int y = GET_YEAR(self);
+ int m = GET_MONTH(self);
+ int d = GET_DAY(self);
+ int hh = DATE_GET_HOUR(self);
+ int mm = DATE_GET_MINUTE(self);
+ int ss = DATE_GET_SECOND(self);
+ int us = DATE_GET_MICROSECOND(self);
+ PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
+ datetime_kws,
+ &y, &m, &d, &hh, &mm, &ss, &us,
+ &tzinfo))
+ return NULL;
+ tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
+ if (tuple == NULL)
+ return NULL;
+ clone = datetime_new(self->ob_type, tuple, NULL);
+ Py_DECREF(tuple);
+ return clone;
+}
+
+static PyObject *
+datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+{
+ int y, m, d, hh, mm, ss, us;
+ PyObject *result;
+ int offset, none;
+
+ PyObject *tzinfo;
+ static char *keywords[] = {"tz", NULL};
+
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
+ &PyDateTime_TZInfoType, &tzinfo))
+ return NULL;
+
+ if (!HASTZINFO(self) || self->tzinfo == Py_None)
+ goto NeedAware;
+
+ /* Conversion to self's own time zone is a NOP. */
+ if (self->tzinfo == tzinfo) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+
+ /* Convert self to UTC. */
+ offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
+ if (offset == -1 && PyErr_Occurred())
+ return NULL;
+ if (none)
+ goto NeedAware;
+
+ y = GET_YEAR(self);
+ m = GET_MONTH(self);
+ d = GET_DAY(self);
+ hh = DATE_GET_HOUR(self);
+ mm = DATE_GET_MINUTE(self);
+ ss = DATE_GET_SECOND(self);
+ us = DATE_GET_MICROSECOND(self);
+
+ mm -= offset;
+ if ((mm < 0 || mm >= 60) &&
+ normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
+ return NULL;
+
+ /* Attach new tzinfo and let fromutc() do the rest. */
+ result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
+ if (result != NULL) {
+ PyObject *temp = result;
+
+ result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
+ Py_DECREF(temp);
+ }
+ return result;
+
+NeedAware:
+ PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
+ "a naive datetime");
+ return NULL;
+}
+
+static PyObject *
+datetime_timetuple(PyDateTime_DateTime *self)
+{
+ int dstflag = -1;
+
+ if (HASTZINFO(self) && self->tzinfo != Py_None) {
+ int none;
+
+ dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
+ if (dstflag == -1 && PyErr_Occurred())
+ return NULL;
+
+ if (none)
+ dstflag = -1;
+ else if (dstflag != 0)
+ dstflag = 1;
+
+ }
+ return build_struct_time(GET_YEAR(self),
+ GET_MONTH(self),
+ GET_DAY(self),
+ DATE_GET_HOUR(self),
+ DATE_GET_MINUTE(self),
+ DATE_GET_SECOND(self),
+ dstflag);
+}
+
+static PyObject *
+datetime_getdate(PyDateTime_DateTime *self)
+{
+ return new_date(GET_YEAR(self),
+ GET_MONTH(self),
+ GET_DAY(self));
+}
+
+static PyObject *
+datetime_gettime(PyDateTime_DateTime *self)
+{
+ return new_time(DATE_GET_HOUR(self),
+ DATE_GET_MINUTE(self),
+ DATE_GET_SECOND(self),
+ DATE_GET_MICROSECOND(self),
+ Py_None);
+}
+
+static PyObject *
+datetime_gettimetz(PyDateTime_DateTime *self)
+{
+ return new_time(DATE_GET_HOUR(self),
+ DATE_GET_MINUTE(self),
+ DATE_GET_SECOND(self),
+ DATE_GET_MICROSECOND(self),
+ HASTZINFO(self) ? self->tzinfo : Py_None);
+}
+
+static PyObject *
+datetime_utctimetuple(PyDateTime_DateTime *self)
+{
+ int y = GET_YEAR(self);
+ int m = GET_MONTH(self);
+ int d = GET_DAY(self);
+ int hh = DATE_GET_HOUR(self);
+ int mm = DATE_GET_MINUTE(self);
+ int ss = DATE_GET_SECOND(self);
+ int us = 0; /* microseconds are ignored in a timetuple */
+ int offset = 0;
+
+ if (HASTZINFO(self) && self->tzinfo != Py_None) {
+ int none;
+
+ offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
+ if (offset == -1 && PyErr_Occurred())
+ return NULL;
+ }
+ /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
+ * 0 in a UTC timetuple regardless of what dst() says.
+ */
+ if (offset) {
+ /* Subtract offset minutes & normalize. */
+ int stat;
+
+ mm -= offset;
+ stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
+ if (stat < 0) {
+ /* At the edges, it's possible we overflowed
+ * beyond MINYEAR or MAXYEAR.
+ */
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return build_struct_time(y, m, d, hh, mm, ss, 0);
+}
+
+/* Pickle support, a simple use of __reduce__. */
+
+/* Let basestate be the non-tzinfo data string.
+ * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
+ * So it's a tuple in any (non-error) case.
+ * __getstate__ isn't exposed.
+ */
+static PyObject *
+datetime_getstate(PyDateTime_DateTime *self)
+{
+ PyObject *basestate;
+ PyObject *result = NULL;
+
+ basestate = PyString_FromStringAndSize((char *)self->data,
+ _PyDateTime_DATETIME_DATASIZE);
+ if (basestate != NULL) {
+ if (! HASTZINFO(self) || self->tzinfo == Py_None)
+ result = PyTuple_Pack(1, basestate);
+ else
+ result = PyTuple_Pack(2, basestate, self->tzinfo);
+ Py_DECREF(basestate);
+ }
+ return result;
+}
+
+static PyObject *
+datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
+{
+ return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
+}
+
+static PyMethodDef datetime_methods[] = {
+
+ /* Class methods: */
+
+ {"now", (PyCFunction)datetime_now,
+ METH_KEYWORDS | METH_CLASS,
+ PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
+
+ {"utcnow", (PyCFunction)datetime_utcnow,
+ METH_NOARGS | METH_CLASS,
+ PyDoc_STR("Return a new datetime representing UTC day and time.")},
+
+ {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
+ METH_KEYWORDS | METH_CLASS,
+ PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
+
+ {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
+ METH_VARARGS | METH_CLASS,
+ PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
+ "(like time.time()).")},
+
+ {"strptime", (PyCFunction)datetime_strptime,
+ METH_VARARGS | METH_CLASS,
+ PyDoc_STR("string, format -> new datetime parsed from a string "
+ "(like time.strptime()).")},
+
+ {"combine", (PyCFunction)datetime_combine,
+ METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+ PyDoc_STR("date, time -> datetime with same date and time fields")},
+
+ /* Instance methods: */
+
+ {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
+ PyDoc_STR("Return date object with same year, month and day.")},
+
+ {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
+ PyDoc_STR("Return time object with same time but with tzinfo=None.")},
+
+ {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
+ PyDoc_STR("Return time object with same time and tzinfo.")},
+
+ {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
+ PyDoc_STR("Return ctime() style string.")},
+
+ {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
+ PyDoc_STR("Return time tuple, compatible with time.localtime().")},
+
+ {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
+ PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
+
+ {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
+ PyDoc_STR("[sep] -> string in ISO 8601 format, "
+ "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
+ "sep is used to separate the year from the time, and "
+ "defaults to 'T'.")},
+
+ {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
+ PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
+
+ {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
+ PyDoc_STR("Return self.tzinfo.tzname(self).")},
+
+ {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
+ PyDoc_STR("Return self.tzinfo.dst(self).")},
+
+ {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
+ PyDoc_STR("Return datetime with new specified fields.")},
+
+ {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
+ PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
+
+ {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
+ PyDoc_STR("__reduce__() -> (cls, state)")},
+
+ {NULL, NULL}
+};
+
+static char datetime_doc[] =
+PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
+\n\
+The year, month and day arguments are required. tzinfo may be None, or an\n\
+instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
+
+static PyNumberMethods datetime_as_number = {
+ datetime_add, /* nb_add */
+ datetime_subtract, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ 0, /* nb_nonzero */
+};
+
+statichere PyTypeObject PyDateTime_DateTimeType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "datetime.datetime", /* tp_name */
+ sizeof(PyDateTime_DateTime), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)datetime_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)datetime_repr, /* tp_repr */
+ &datetime_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)datetime_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)datetime_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ datetime_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)datetime_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ datetime_methods, /* tp_methods */
+ 0, /* tp_members */
+ datetime_getset, /* tp_getset */
+ &PyDateTime_DateType, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ datetime_alloc, /* tp_alloc */
+ datetime_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+/* ---------------------------------------------------------------------------
+ * Module methods and initialization.
+ */
+
+static PyMethodDef module_methods[] = {
+ {NULL, NULL}
+};
+
+/* C API. Clients get at this via PyDateTime_IMPORT, defined in
+ * datetime.h.
+ */
+static PyDateTime_CAPI CAPI = {
+ &PyDateTime_DateType,
+ &PyDateTime_DateTimeType,
+ &PyDateTime_TimeType,
+ &PyDateTime_DeltaType,
+ &PyDateTime_TZInfoType,
+ new_date_ex,
+ new_datetime_ex,
+ new_time_ex,
+ new_delta_ex,
+ datetime_fromtimestamp,
+ date_fromtimestamp
+};
+
+
+PyMODINIT_FUNC
+initdatetime(void)
+{
+ PyObject *m; /* a module object */
+ PyObject *d; /* its dict */
+ PyObject *x;
+
+ m = Py_InitModule3("datetime", module_methods,
+ "Fast implementation of the datetime type.");
+ if (m == NULL)
+ return;
+
+ if (PyType_Ready(&PyDateTime_DateType) < 0)
+ return;
+ if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
+ return;
+ if (PyType_Ready(&PyDateTime_DeltaType) < 0)
+ return;
+ if (PyType_Ready(&PyDateTime_TimeType) < 0)
+ return;
+ if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
+ return;
+
+ /* timedelta values */
+ d = PyDateTime_DeltaType.tp_dict;
+
+ x = new_delta(0, 0, 1, 0);
+ if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
+ if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
+ if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ /* date values */
+ d = PyDateTime_DateType.tp_dict;
+
+ x = new_date(1, 1, 1);
+ if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_date(MAXYEAR, 12, 31);
+ if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_delta(1, 0, 0, 0);
+ if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ /* time values */
+ d = PyDateTime_TimeType.tp_dict;
+
+ x = new_time(0, 0, 0, 0, Py_None);
+ if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_time(23, 59, 59, 999999, Py_None);
+ if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_delta(0, 0, 1, 0);
+ if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ /* datetime values */
+ d = PyDateTime_DateTimeType.tp_dict;
+
+ x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
+ if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
+ if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ x = new_delta(0, 0, 1, 0);
+ if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
+ return;
+ Py_DECREF(x);
+
+ /* module initialization */
+ PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
+ PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
+
+ Py_INCREF(&PyDateTime_DateType);
+ PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
+
+ Py_INCREF(&PyDateTime_DateTimeType);
+ PyModule_AddObject(m, "datetime",
+ (PyObject *)&PyDateTime_DateTimeType);
+
+ Py_INCREF(&PyDateTime_TimeType);
+ PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
+
+ Py_INCREF(&PyDateTime_DeltaType);
+ PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
+
+ Py_INCREF(&PyDateTime_TZInfoType);
+ PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
+
+ x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
+ NULL);
+ if (x == NULL)
+ return;
+ PyModule_AddObject(m, "datetime_CAPI", x);
+
+ /* A 4-year cycle has an extra leap day over what we'd get from
+ * pasting together 4 single years.
+ */
+ assert(DI4Y == 4 * 365 + 1);
+ assert(DI4Y == days_before_year(4+1));
+
+ /* Similarly, a 400-year cycle has an extra leap day over what we'd
+ * get from pasting together 4 100-year cycles.
+ */
+ assert(DI400Y == 4 * DI100Y + 1);
+ assert(DI400Y == days_before_year(400+1));
+
+ /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
+ * pasting together 25 4-year cycles.
+ */
+ assert(DI100Y == 25 * DI4Y - 1);
+ assert(DI100Y == days_before_year(100+1));
+
+ us_per_us = PyInt_FromLong(1);
+ us_per_ms = PyInt_FromLong(1000);
+ us_per_second = PyInt_FromLong(1000000);
+ us_per_minute = PyInt_FromLong(60000000);
+ seconds_per_day = PyInt_FromLong(24 * 3600);
+ if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
+ us_per_minute == NULL || seconds_per_day == NULL)
+ return;
+
+ /* The rest are too big for 32-bit ints, but even
+ * us_per_week fits in 40 bits, so doubles should be exact.
+ */
+ us_per_hour = PyLong_FromDouble(3600000000.0);
+ us_per_day = PyLong_FromDouble(86400000000.0);
+ us_per_week = PyLong_FromDouble(604800000000.0);
+ if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
+ return;
+}
+
+/* ---------------------------------------------------------------------------
+Some time zone algebra. For a datetime x, let
+ x.n = x stripped of its timezone -- its naive time.
+ x.o = x.utcoffset(), and assuming that doesn't raise an exception or
+ return None
+ x.d = x.dst(), and assuming that doesn't raise an exception or
+ return None
+ x.s = x's standard offset, x.o - x.d
+
+Now some derived rules, where k is a duration (timedelta).
+
+1. x.o = x.s + x.d
+ This follows from the definition of x.s.
+
+2. If x and y have the same tzinfo member, x.s = y.s.
+ This is actually a requirement, an assumption we need to make about
+ sane tzinfo classes.
+
+3. The naive UTC time corresponding to x is x.n - x.o.
+ This is again a requirement for a sane tzinfo class.
+
+4. (x+k).s = x.s
+ This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
+
+5. (x+k).n = x.n + k
+ Again follows from how arithmetic is defined.
+
+Now we can explain tz.fromutc(x). Let's assume it's an interesting case
+(meaning that the various tzinfo methods exist, and don't blow up or return
+None when called).
+
+The function wants to return a datetime y with timezone tz, equivalent to x.
+x is already in UTC.
+
+By #3, we want
+
+ y.n - y.o = x.n [1]
+
+The algorithm starts by attaching tz to x.n, and calling that y. So
+x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
+becomes true; in effect, we want to solve [2] for k:
+
+ (y+k).n - (y+k).o = x.n [2]
+
+By #1, this is the same as
+
+ (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
+
+By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
+Substituting that into [3],
+
+ x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
+ k - (y+k).s - (y+k).d = 0; rearranging,
+ k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
+ k = y.s - (y+k).d
+
+On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
+approximate k by ignoring the (y+k).d term at first. Note that k can't be
+very large, since all offset-returning methods return a duration of magnitude
+less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
+be 0, so ignoring it has no consequence then.
+
+In any case, the new value is
+
+ z = y + y.s [4]
+
+It's helpful to step back at look at [4] from a higher level: it's simply
+mapping from UTC to tz's standard time.
+
+At this point, if
+
+ z.n - z.o = x.n [5]
+
+we have an equivalent time, and are almost done. The insecurity here is
+at the start of daylight time. Picture US Eastern for concreteness. The wall
+time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
+sense then. The docs ask that an Eastern tzinfo class consider such a time to
+be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
+on the day DST starts. We want to return the 1:MM EST spelling because that's
+the only spelling that makes sense on the local wall clock.
+
+In fact, if [5] holds at this point, we do have the standard-time spelling,
+but that takes a bit of proof. We first prove a stronger result. What's the
+difference between the LHS and RHS of [5]? Let
+
+ diff = x.n - (z.n - z.o) [6]
+
+Now
+ z.n = by [4]
+ (y + y.s).n = by #5
+ y.n + y.s = since y.n = x.n
+ x.n + y.s = since z and y are have the same tzinfo member,
+ y.s = z.s by #2
+ x.n + z.s
+
+Plugging that back into [6] gives
+
+ diff =
+ x.n - ((x.n + z.s) - z.o) = expanding
+ x.n - x.n - z.s + z.o = cancelling
+ - z.s + z.o = by #2
+ z.d
+
+So diff = z.d.
+
+If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
+spelling we wanted in the endcase described above. We're done. Contrarily,
+if z.d = 0, then we have a UTC equivalent, and are also done.
+
+If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
+add to z (in effect, z is in tz's standard time, and we need to shift the
+local clock into tz's daylight time).
+
+Let
+
+ z' = z + z.d = z + diff [7]
+
+and we can again ask whether
+
+ z'.n - z'.o = x.n [8]
+
+If so, we're done. If not, the tzinfo class is insane, according to the
+assumptions we've made. This also requires a bit of proof. As before, let's
+compute the difference between the LHS and RHS of [8] (and skipping some of
+the justifications for the kinds of substitutions we've done several times
+already):
+
+ diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
+ x.n - (z.n + diff - z'.o) = replacing diff via [6]
+ x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
+ x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
+ - z.n + z.n - z.o + z'.o = cancel z.n
+ - z.o + z'.o = #1 twice
+ -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
+ z'.d - z.d
+
+So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
+we've found the UTC-equivalent so are done. In fact, we stop with [7] and
+return z', not bothering to compute z'.d.
+
+How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
+a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
+would have to change the result dst() returns: we start in DST, and moving
+a little further into it takes us out of DST.
+
+There isn't a sane case where this can happen. The closest it gets is at
+the end of DST, where there's an hour in UTC with no spelling in a hybrid
+tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
+that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
+UTC) because the docs insist on that, but 0:MM is taken as being in daylight
+time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
+clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
+standard time. Since that's what the local clock *does*, we want to map both
+UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
+in local time, but so it goes -- it's the way the local clock works.
+
+When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
+so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
+z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
+(correctly) concludes that z' is not UTC-equivalent to x.
+
+Because we know z.d said z was in daylight time (else [5] would have held and
+we would have stopped then), and we know z.d != z'.d (else [8] would have held
+and we would have stopped then), and there are only 2 possible values dst() can
+return in Eastern, it follows that z'.d must be 0 (which it is in the example,
+but the reasoning doesn't depend on the example -- it depends on there being
+two possible dst() outcomes, one zero and the other non-zero). Therefore
+z' must be in standard time, and is the spelling we want in this case.
+
+Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
+concerned (because it takes z' as being in standard time rather than the
+daylight time we intend here), but returning it gives the real-life "local
+clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
+tz.
+
+When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
+the 1:MM standard time spelling we want.
+
+So how can this break? One of the assumptions must be violated. Two
+possibilities:
+
+1) [2] effectively says that y.s is invariant across all y belong to a given
+ time zone. This isn't true if, for political reasons or continental drift,
+ a region decides to change its base offset from UTC.
+
+2) There may be versions of "double daylight" time where the tail end of
+ the analysis gives up a step too early. I haven't thought about that
+ enough to say.
+
+In any case, it's clear that the default fromutc() is strong enough to handle
+"almost all" time zones: so long as the standard offset is invariant, it
+doesn't matter if daylight time transition points change from year to year, or
+if daylight time is skipped in some years; it doesn't matter how large or
+small dst() may get within its bounds; and it doesn't even matter if some
+perverse time zone returns a negative dst()). So a breaking case must be
+pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
+--------------------------------------------------------------------------- */
diff --git a/sys/src/cmd/python/Modules/dbmmodule.c b/sys/src/cmd/python/Modules/dbmmodule.c
new file mode 100644
index 000000000..9086c8477
--- /dev/null
+++ b/sys/src/cmd/python/Modules/dbmmodule.c
@@ -0,0 +1,370 @@
+
+/* DBM module using dictionary interface */
+
+
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Some Linux systems install gdbm/ndbm.h, but not ndbm.h. This supports
+ * whichever configure was able to locate.
+ */
+#if defined(HAVE_NDBM_H)
+#include <ndbm.h>
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+static char *which_dbm = "ndbm";
+#else
+static char *which_dbm = "GNU gdbm"; /* EMX port of GDBM */
+#endif
+#elif defined(HAVE_GDBM_NDBM_H)
+#include <gdbm/ndbm.h>
+static char *which_dbm = "GNU gdbm";
+#elif defined(HAVE_BERKDB_H)
+#include <db.h>
+static char *which_dbm = "Berkeley DB";
+#else
+#error "No ndbm.h available!"
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ int di_size; /* -1 means recompute */
+ DBM *di_dbm;
+} dbmobject;
+
+static PyTypeObject Dbmtype;
+
+#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
+#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
+ { PyErr_SetString(DbmError, "DBM object has already been closed"); \
+ return NULL; }
+
+static PyObject *DbmError;
+
+static PyObject *
+newdbmobject(char *file, int flags, int mode)
+{
+ dbmobject *dp;
+
+ dp = PyObject_New(dbmobject, &Dbmtype);
+ if (dp == NULL)
+ return NULL;
+ dp->di_size = -1;
+ if ( (dp->di_dbm = dbm_open(file, flags, mode)) == 0 ) {
+ PyErr_SetFromErrno(DbmError);
+ Py_DECREF(dp);
+ return NULL;
+ }
+ return (PyObject *)dp;
+}
+
+/* Methods */
+
+static void
+dbm_dealloc(register dbmobject *dp)
+{
+ if ( dp->di_dbm )
+ dbm_close(dp->di_dbm);
+ PyObject_Del(dp);
+}
+
+static Py_ssize_t
+dbm_length(dbmobject *dp)
+{
+ if (dp->di_dbm == NULL) {
+ PyErr_SetString(DbmError, "DBM object has already been closed");
+ return -1;
+ }
+ if ( dp->di_size < 0 ) {
+ datum key;
+ int size;
+
+ size = 0;
+ for ( key=dbm_firstkey(dp->di_dbm); key.dptr;
+ key = dbm_nextkey(dp->di_dbm))
+ size++;
+ dp->di_size = size;
+ }
+ return dp->di_size;
+}
+
+static PyObject *
+dbm_subscript(dbmobject *dp, register PyObject *key)
+{
+ datum drec, krec;
+ int tmp_size;
+
+ if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size) )
+ return NULL;
+
+ krec.dsize = tmp_size;
+ check_dbmobject_open(dp);
+ drec = dbm_fetch(dp->di_dbm, krec);
+ if ( drec.dptr == 0 ) {
+ PyErr_SetString(PyExc_KeyError,
+ PyString_AS_STRING((PyStringObject *)key));
+ return NULL;
+ }
+ if ( dbm_error(dp->di_dbm) ) {
+ dbm_clearerr(dp->di_dbm);
+ PyErr_SetString(DbmError, "");
+ return NULL;
+ }
+ return PyString_FromStringAndSize(drec.dptr, drec.dsize);
+}
+
+static int
+dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
+{
+ datum krec, drec;
+ int tmp_size;
+
+ if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) {
+ PyErr_SetString(PyExc_TypeError,
+ "dbm mappings have string indices only");
+ return -1;
+ }
+ krec.dsize = tmp_size;
+ if (dp->di_dbm == NULL) {
+ PyErr_SetString(DbmError, "DBM object has already been closed");
+ return -1;
+ }
+ dp->di_size = -1;
+ if (w == NULL) {
+ if ( dbm_delete(dp->di_dbm, krec) < 0 ) {
+ dbm_clearerr(dp->di_dbm);
+ PyErr_SetString(PyExc_KeyError,
+ PyString_AS_STRING((PyStringObject *)v));
+ return -1;
+ }
+ } else {
+ if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) {
+ PyErr_SetString(PyExc_TypeError,
+ "dbm mappings have string elements only");
+ return -1;
+ }
+ drec.dsize = tmp_size;
+ if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) {
+ dbm_clearerr(dp->di_dbm);
+ PyErr_SetString(DbmError,
+ "cannot add item to database");
+ return -1;
+ }
+ }
+ if ( dbm_error(dp->di_dbm) ) {
+ dbm_clearerr(dp->di_dbm);
+ PyErr_SetString(DbmError, "");
+ return -1;
+ }
+ return 0;
+}
+
+static PyMappingMethods dbm_as_mapping = {
+ (lenfunc)dbm_length, /*mp_length*/
+ (binaryfunc)dbm_subscript, /*mp_subscript*/
+ (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
+};
+
+static PyObject *
+dbm__close(register dbmobject *dp, PyObject *unused)
+{
+ if (dp->di_dbm)
+ dbm_close(dp->di_dbm);
+ dp->di_dbm = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+dbm_keys(register dbmobject *dp, PyObject *unused)
+{
+ register PyObject *v, *item;
+ datum key;
+ int err;
+
+ check_dbmobject_open(dp);
+ v = PyList_New(0);
+ if (v == NULL)
+ return NULL;
+ for (key = dbm_firstkey(dp->di_dbm); key.dptr;
+ key = dbm_nextkey(dp->di_dbm)) {
+ item = PyString_FromStringAndSize(key.dptr, key.dsize);
+ if (item == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ err = PyList_Append(v, item);
+ Py_DECREF(item);
+ if (err != 0) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ }
+ return v;
+}
+
+static PyObject *
+dbm_has_key(register dbmobject *dp, PyObject *args)
+{
+ datum key, val;
+ int tmp_size;
+
+ if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &tmp_size))
+ return NULL;
+ key.dsize = tmp_size;
+ check_dbmobject_open(dp);
+ val = dbm_fetch(dp->di_dbm, key);
+ return PyInt_FromLong(val.dptr != NULL);
+}
+
+static PyObject *
+dbm_get(register dbmobject *dp, PyObject *args)
+{
+ datum key, val;
+ PyObject *defvalue = Py_None;
+ int tmp_size;
+
+ if (!PyArg_ParseTuple(args, "s#|O:get",
+ &key.dptr, &tmp_size, &defvalue))
+ return NULL;
+ key.dsize = tmp_size;
+ check_dbmobject_open(dp);
+ val = dbm_fetch(dp->di_dbm, key);
+ if (val.dptr != NULL)
+ return PyString_FromStringAndSize(val.dptr, val.dsize);
+ else {
+ Py_INCREF(defvalue);
+ return defvalue;
+ }
+}
+
+static PyObject *
+dbm_setdefault(register dbmobject *dp, PyObject *args)
+{
+ datum key, val;
+ PyObject *defvalue = NULL;
+ int tmp_size;
+
+ if (!PyArg_ParseTuple(args, "s#|S:setdefault",
+ &key.dptr, &tmp_size, &defvalue))
+ return NULL;
+ key.dsize = tmp_size;
+ check_dbmobject_open(dp);
+ val = dbm_fetch(dp->di_dbm, key);
+ if (val.dptr != NULL)
+ return PyString_FromStringAndSize(val.dptr, val.dsize);
+ if (defvalue == NULL) {
+ defvalue = PyString_FromStringAndSize(NULL, 0);
+ if (defvalue == NULL)
+ return NULL;
+ }
+ else
+ Py_INCREF(defvalue);
+ val.dptr = PyString_AS_STRING(defvalue);
+ val.dsize = PyString_GET_SIZE(defvalue);
+ if (dbm_store(dp->di_dbm, key, val, DBM_INSERT) < 0) {
+ dbm_clearerr(dp->di_dbm);
+ PyErr_SetString(DbmError, "cannot add item to database");
+ return NULL;
+ }
+ return defvalue;
+}
+
+static PyMethodDef dbm_methods[] = {
+ {"close", (PyCFunction)dbm__close, METH_NOARGS,
+ "close()\nClose the database."},
+ {"keys", (PyCFunction)dbm_keys, METH_NOARGS,
+ "keys() -> list\nReturn a list of all keys in the database."},
+ {"has_key", (PyCFunction)dbm_has_key, METH_VARARGS,
+ "has_key(key} -> boolean\nReturn true iff key is in the database."},
+ {"get", (PyCFunction)dbm_get, METH_VARARGS,
+ "get(key[, default]) -> value\n"
+ "Return the value for key if present, otherwise default."},
+ {"setdefault", (PyCFunction)dbm_setdefault, METH_VARARGS,
+ "setdefault(key[, default]) -> value\n"
+ "Return the value for key if present, otherwise default. If key\n"
+ "is not in the database, it is inserted with default as the value."},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+dbm_getattr(dbmobject *dp, char *name)
+{
+ return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
+}
+
+static PyTypeObject Dbmtype = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "dbm.dbm",
+ sizeof(dbmobject),
+ 0,
+ (destructor)dbm_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)dbm_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &dbm_as_mapping, /*tp_as_mapping*/
+};
+
+/* ----------------------------------------------------------------- */
+
+static PyObject *
+dbmopen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *flags = "r";
+ int iflags;
+ int mode = 0666;
+
+ if ( !PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode) )
+ return NULL;
+ if ( strcmp(flags, "r") == 0 )
+ iflags = O_RDONLY;
+ else if ( strcmp(flags, "w") == 0 )
+ iflags = O_RDWR;
+ else if ( strcmp(flags, "rw") == 0 ) /* B/W compat */
+ iflags = O_RDWR|O_CREAT;
+ else if ( strcmp(flags, "c") == 0 )
+ iflags = O_RDWR|O_CREAT;
+ else if ( strcmp(flags, "n") == 0 )
+ iflags = O_RDWR|O_CREAT|O_TRUNC;
+ else {
+ PyErr_SetString(DbmError,
+ "arg 2 to open should be 'r', 'w', 'c', or 'n'");
+ return NULL;
+ }
+ return newdbmobject(name, iflags, mode);
+}
+
+static PyMethodDef dbmmodule_methods[] = {
+ { "open", (PyCFunction)dbmopen, METH_VARARGS,
+ "open(path[, flag[, mode]]) -> mapping\n"
+ "Return a database object."},
+ { 0, 0 },
+};
+
+PyMODINIT_FUNC
+initdbm(void) {
+ PyObject *m, *d, *s;
+
+ Dbmtype.ob_type = &PyType_Type;
+ m = Py_InitModule("dbm", dbmmodule_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ if (DbmError == NULL)
+ DbmError = PyErr_NewException("dbm.error", NULL, NULL);
+ s = PyString_FromString(which_dbm);
+ if (s != NULL) {
+ PyDict_SetItemString(d, "library", s);
+ Py_DECREF(s);
+ }
+ if (DbmError != NULL)
+ PyDict_SetItemString(d, "error", DbmError);
+}
diff --git a/sys/src/cmd/python/Modules/dlmodule.c b/sys/src/cmd/python/Modules/dlmodule.c
new file mode 100644
index 000000000..5622ed9e7
--- /dev/null
+++ b/sys/src/cmd/python/Modules/dlmodule.c
@@ -0,0 +1,278 @@
+
+/* dl module */
+
+#include "Python.h"
+
+#include <dlfcn.h>
+
+#ifdef __VMS
+#include <unistd.h>
+#endif
+
+#ifndef RTLD_LAZY
+#define RTLD_LAZY 1
+#endif
+
+typedef void *PyUnivPtr;
+typedef struct {
+ PyObject_HEAD
+ PyUnivPtr *dl_handle;
+} dlobject;
+
+static PyTypeObject Dltype;
+
+static PyObject *Dlerror;
+
+static PyObject *
+newdlobject(PyUnivPtr *handle)
+{
+ dlobject *xp;
+ xp = PyObject_New(dlobject, &Dltype);
+ if (xp == NULL)
+ return NULL;
+ xp->dl_handle = handle;
+ return (PyObject *)xp;
+}
+
+static void
+dl_dealloc(dlobject *xp)
+{
+ if (xp->dl_handle != NULL)
+ dlclose(xp->dl_handle);
+ PyObject_Del(xp);
+}
+
+static PyObject *
+dl_close(dlobject *xp)
+{
+ if (xp->dl_handle != NULL) {
+ dlclose(xp->dl_handle);
+ xp->dl_handle = NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+dl_sym(dlobject *xp, PyObject *args)
+{
+ char *name;
+ PyUnivPtr *func;
+ if (PyString_Check(args)) {
+ name = PyString_AS_STRING(args);
+ } else {
+ PyErr_Format(PyExc_TypeError, "expected string, found %.200s",
+ args->ob_type->tp_name);
+ return NULL;
+ }
+ func = dlsym(xp->dl_handle, name);
+ if (func == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyInt_FromLong((long)func);
+}
+
+static PyObject *
+dl_call(dlobject *xp, PyObject *args)
+{
+ PyObject *name;
+ long (*func)(long, long, long, long, long,
+ long, long, long, long, long);
+ long alist[10];
+ long res;
+ Py_ssize_t i;
+ Py_ssize_t n = PyTuple_Size(args);
+ if (n < 1) {
+ PyErr_SetString(PyExc_TypeError, "at least a name is needed");
+ return NULL;
+ }
+ name = PyTuple_GetItem(args, 0);
+ if (!PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "function name must be a string");
+ return NULL;
+ }
+ func = (long (*)(long, long, long, long, long,
+ long, long, long, long, long))
+ dlsym(xp->dl_handle, PyString_AsString(name));
+ if (func == NULL) {
+ PyErr_SetString(PyExc_ValueError, dlerror());
+ return NULL;
+ }
+ if (n-1 > 10) {
+ PyErr_SetString(PyExc_TypeError,
+ "too many arguments (max 10)");
+ return NULL;
+ }
+ for (i = 1; i < n; i++) {
+ PyObject *v = PyTuple_GetItem(args, i);
+ if (PyInt_Check(v))
+ alist[i-1] = PyInt_AsLong(v);
+ else if (PyString_Check(v))
+ alist[i-1] = (long)PyString_AsString(v);
+ else if (v == Py_None)
+ alist[i-1] = (long) ((char *)NULL);
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "arguments must be int, string or None");
+ return NULL;
+ }
+ }
+ for (; i <= 10; i++)
+ alist[i-1] = 0;
+ res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
+ alist[5], alist[6], alist[7], alist[8], alist[9]);
+ return PyInt_FromLong(res);
+}
+
+static PyMethodDef dlobject_methods[] = {
+ {"call", (PyCFunction)dl_call, METH_VARARGS},
+ {"sym", (PyCFunction)dl_sym, METH_O},
+ {"close", (PyCFunction)dl_close, METH_NOARGS},
+ {NULL, NULL} /* Sentinel */
+};
+
+static PyObject *
+dl_getattr(dlobject *xp, char *name)
+{
+ return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
+}
+
+
+static PyTypeObject Dltype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "dl.dl", /*tp_name*/
+ sizeof(dlobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)dl_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)dl_getattr,/*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+static PyObject *
+dl_open(PyObject *self, PyObject *args)
+{
+ char *name;
+ int mode;
+ PyUnivPtr *handle;
+ if (sizeof(int) != sizeof(long) ||
+ sizeof(long) != sizeof(char *)) {
+ PyErr_SetString(PyExc_SystemError,
+ "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
+ return NULL;
+ }
+
+ if (PyArg_ParseTuple(args, "z:open", &name))
+ mode = RTLD_LAZY;
+ else {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "zi:open", &name, &mode))
+ return NULL;
+#ifndef RTLD_NOW
+ if (mode != RTLD_LAZY) {
+ PyErr_SetString(PyExc_ValueError, "mode must be 1");
+ return NULL;
+ }
+#endif
+ }
+ handle = dlopen(name, mode);
+ if (handle == NULL) {
+ PyErr_SetString(Dlerror, dlerror());
+ return NULL;
+ }
+#ifdef __VMS
+ /* Under OpenVMS dlopen doesn't do any check, just save the name
+ * for later use, so we have to check if the file is readable,
+ * the name can be a logical or a file from SYS$SHARE.
+ */
+ if (access(name, R_OK)) {
+ char fname[strlen(name) + 20];
+ strcpy(fname, "SYS$SHARE:");
+ strcat(fname, name);
+ strcat(fname, ".EXE");
+ if (access(fname, R_OK)) {
+ dlclose(handle);
+ PyErr_SetString(Dlerror,
+ "File not found or protection violation");
+ return NULL;
+ }
+ }
+#endif
+ return newdlobject(handle);
+}
+
+static PyMethodDef dl_methods[] = {
+ {"open", dl_open, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* From socketmodule.c
+ * Convenience routine to export an integer value.
+ *
+ * Errors are silently ignored, for better or for worse...
+ */
+static void
+insint(PyObject *d, char *name, int value)
+{
+ PyObject *v = PyInt_FromLong((long) value);
+ if (!v || PyDict_SetItemString(d, name, v))
+ PyErr_Clear();
+
+ Py_XDECREF(v);
+}
+
+PyMODINIT_FUNC
+initdl(void)
+{
+ PyObject *m, *d, *x;
+
+ /* Initialize object type */
+ Dltype.ob_type = &PyType_Type;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("dl", dl_methods);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", x);
+ x = PyInt_FromLong((long)RTLD_LAZY);
+ PyDict_SetItemString(d, "RTLD_LAZY", x);
+#define INSINT(X) insint(d,#X,X)
+#ifdef RTLD_NOW
+ INSINT(RTLD_NOW);
+#endif
+#ifdef RTLD_NOLOAD
+ INSINT(RTLD_NOLOAD);
+#endif
+#ifdef RTLD_GLOBAL
+ INSINT(RTLD_GLOBAL);
+#endif
+#ifdef RTLD_LOCAL
+ INSINT(RTLD_LOCAL);
+#endif
+#ifdef RTLD_PARENT
+ INSINT(RTLD_PARENT);
+#endif
+#ifdef RTLD_GROUP
+ INSINT(RTLD_GROUP);
+#endif
+#ifdef RTLD_WORLD
+ INSINT(RTLD_WORLD);
+#endif
+#ifdef RTLD_NODELETE
+ INSINT(RTLD_NODELETE);
+#endif
+}
diff --git a/sys/src/cmd/python/Modules/errnomodule.c b/sys/src/cmd/python/Modules/errnomodule.c
new file mode 100644
index 000000000..696d396b0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/errnomodule.c
@@ -0,0 +1,788 @@
+
+/* Errno module */
+
+#include "Python.h"
+
+/* Windows socket errors (WSA*) */
+#ifdef MS_WINDOWS
+#include <winsock.h>
+#endif
+
+/*
+ * Pull in the system error definitions
+ */
+
+static PyMethodDef errno_methods[] = {
+ {NULL, NULL}
+};
+
+/* Helper function doing the dictionary inserting */
+
+static void
+_inscode(PyObject *d, PyObject *de, char *name, int code)
+{
+ PyObject *u = PyString_FromString(name);
+ PyObject *v = PyInt_FromLong((long) code);
+
+ /* Don't bother checking for errors; they'll be caught at the end
+ * of the module initialization function by the caller of
+ * initerrno().
+ */
+ if (u && v) {
+ /* insert in modules dict */
+ PyDict_SetItem(d, u, v);
+ /* insert in errorcode dict */
+ PyDict_SetItem(de, v, u);
+ }
+ Py_XDECREF(u);
+ Py_XDECREF(v);
+}
+
+PyDoc_STRVAR(errno__doc__,
+"This module makes available standard errno system symbols.\n\
+\n\
+The value of each symbol is the corresponding integer value,\n\
+e.g., on most systems, errno.ENOENT equals the integer 2.\n\
+\n\
+The dictionary errno.errorcode maps numeric codes to symbol names,\n\
+e.g., errno.errorcode[2] could be the string 'ENOENT'.\n\
+\n\
+Symbols that are not relevant to the underlying system are not defined.\n\
+\n\
+To map error codes to error messages, use the function os.strerror(),\n\
+e.g. os.strerror(2) could return 'No such file or directory'.");
+
+PyMODINIT_FUNC
+initerrno(void)
+{
+ PyObject *m, *d, *de;
+ m = Py_InitModule3("errno", errno_methods, errno__doc__);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ de = PyDict_New();
+ if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0)
+ return;
+
+/* Macro so I don't have to edit each and every line below... */
+#define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code)
+
+ /*
+ * The names and comments are borrowed from linux/include/errno.h,
+ * which should be pretty all-inclusive
+ */
+
+#ifdef ENODEV
+ inscode(d, ds, de, "ENODEV", ENODEV, "No such device");
+#endif
+#ifdef ENOCSI
+ inscode(d, ds, de, "ENOCSI", ENOCSI, "No CSI structure available");
+#endif
+#ifdef EHOSTUNREACH
+ inscode(d, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host");
+#else
+#ifdef WSAEHOSTUNREACH
+ inscode(d, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");
+#endif
+#endif
+#ifdef ENOMSG
+ inscode(d, ds, de, "ENOMSG", ENOMSG, "No message of desired type");
+#endif
+#ifdef EUCLEAN
+ inscode(d, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning");
+#endif
+#ifdef EL2NSYNC
+ inscode(d, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized");
+#endif
+#ifdef EL2HLT
+ inscode(d, ds, de, "EL2HLT", EL2HLT, "Level 2 halted");
+#endif
+#ifdef ENODATA
+ inscode(d, ds, de, "ENODATA", ENODATA, "No data available");
+#endif
+#ifdef ENOTBLK
+ inscode(d, ds, de, "ENOTBLK", ENOTBLK, "Block device required");
+#endif
+#ifdef ENOSYS
+ inscode(d, ds, de, "ENOSYS", ENOSYS, "Function not implemented");
+#endif
+#ifdef EPIPE
+ inscode(d, ds, de, "EPIPE", EPIPE, "Broken pipe");
+#endif
+#ifdef EINVAL
+ inscode(d, ds, de, "EINVAL", EINVAL, "Invalid argument");
+#else
+#ifdef WSAEINVAL
+ inscode(d, ds, de, "EINVAL", WSAEINVAL, "Invalid argument");
+#endif
+#endif
+#ifdef EOVERFLOW
+ inscode(d, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type");
+#endif
+#ifdef EADV
+ inscode(d, ds, de, "EADV", EADV, "Advertise error");
+#endif
+#ifdef EINTR
+ inscode(d, ds, de, "EINTR", EINTR, "Interrupted system call");
+#else
+#ifdef WSAEINTR
+ inscode(d, ds, de, "EINTR", WSAEINTR, "Interrupted system call");
+#endif
+#endif
+#ifdef EUSERS
+ inscode(d, ds, de, "EUSERS", EUSERS, "Too many users");
+#else
+#ifdef WSAEUSERS
+ inscode(d, ds, de, "EUSERS", WSAEUSERS, "Too many users");
+#endif
+#endif
+#ifdef ENOTEMPTY
+ inscode(d, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty");
+#else
+#ifdef WSAENOTEMPTY
+ inscode(d, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty");
+#endif
+#endif
+#ifdef ENOBUFS
+ inscode(d, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available");
+#else
+#ifdef WSAENOBUFS
+ inscode(d, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available");
+#endif
+#endif
+#ifdef EPROTO
+ inscode(d, ds, de, "EPROTO", EPROTO, "Protocol error");
+#endif
+#ifdef EREMOTE
+ inscode(d, ds, de, "EREMOTE", EREMOTE, "Object is remote");
+#else
+#ifdef WSAEREMOTE
+ inscode(d, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote");
+#endif
+#endif
+#ifdef ENAVAIL
+ inscode(d, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available");
+#endif
+#ifdef ECHILD
+ inscode(d, ds, de, "ECHILD", ECHILD, "No child processes");
+#endif
+#ifdef ELOOP
+ inscode(d, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered");
+#else
+#ifdef WSAELOOP
+ inscode(d, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered");
+#endif
+#endif
+#ifdef EXDEV
+ inscode(d, ds, de, "EXDEV", EXDEV, "Cross-device link");
+#endif
+#ifdef E2BIG
+ inscode(d, ds, de, "E2BIG", E2BIG, "Arg list too long");
+#endif
+#ifdef ESRCH
+ inscode(d, ds, de, "ESRCH", ESRCH, "No such process");
+#endif
+#ifdef EMSGSIZE
+ inscode(d, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long");
+#else
+#ifdef WSAEMSGSIZE
+ inscode(d, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long");
+#endif
+#endif
+#ifdef EAFNOSUPPORT
+ inscode(d, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol");
+#else
+#ifdef WSAEAFNOSUPPORT
+ inscode(d, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");
+#endif
+#endif
+#ifdef EBADR
+ inscode(d, ds, de, "EBADR", EBADR, "Invalid request descriptor");
+#endif
+#ifdef EHOSTDOWN
+ inscode(d, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down");
+#else
+#ifdef WSAEHOSTDOWN
+ inscode(d, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down");
+#endif
+#endif
+#ifdef EPFNOSUPPORT
+ inscode(d, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported");
+#else
+#ifdef WSAEPFNOSUPPORT
+ inscode(d, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");
+#endif
+#endif
+#ifdef ENOPROTOOPT
+ inscode(d, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available");
+#else
+#ifdef WSAENOPROTOOPT
+ inscode(d, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");
+#endif
+#endif
+#ifdef EBUSY
+ inscode(d, ds, de, "EBUSY", EBUSY, "Device or resource busy");
+#endif
+#ifdef EWOULDBLOCK
+ inscode(d, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block");
+#else
+#ifdef WSAEWOULDBLOCK
+ inscode(d, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");
+#endif
+#endif
+#ifdef EBADFD
+ inscode(d, ds, de, "EBADFD", EBADFD, "File descriptor in bad state");
+#endif
+#ifdef EDOTDOT
+ inscode(d, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error");
+#endif
+#ifdef EISCONN
+ inscode(d, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected");
+#else
+#ifdef WSAEISCONN
+ inscode(d, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected");
+#endif
+#endif
+#ifdef ENOANO
+ inscode(d, ds, de, "ENOANO", ENOANO, "No anode");
+#endif
+#ifdef ESHUTDOWN
+ inscode(d, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#else
+#ifdef WSAESHUTDOWN
+ inscode(d, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#endif
+#endif
+#ifdef ECHRNG
+ inscode(d, ds, de, "ECHRNG", ECHRNG, "Channel number out of range");
+#endif
+#ifdef ELIBBAD
+ inscode(d, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library");
+#endif
+#ifdef ENONET
+ inscode(d, ds, de, "ENONET", ENONET, "Machine is not on the network");
+#endif
+#ifdef EBADE
+ inscode(d, ds, de, "EBADE", EBADE, "Invalid exchange");
+#endif
+#ifdef EBADF
+ inscode(d, ds, de, "EBADF", EBADF, "Bad file number");
+#else
+#ifdef WSAEBADF
+ inscode(d, ds, de, "EBADF", WSAEBADF, "Bad file number");
+#endif
+#endif
+#ifdef EMULTIHOP
+ inscode(d, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted");
+#endif
+#ifdef EIO
+ inscode(d, ds, de, "EIO", EIO, "I/O error");
+#endif
+#ifdef EUNATCH
+ inscode(d, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached");
+#endif
+#ifdef EPROTOTYPE
+ inscode(d, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket");
+#else
+#ifdef WSAEPROTOTYPE
+ inscode(d, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");
+#endif
+#endif
+#ifdef ENOSPC
+ inscode(d, ds, de, "ENOSPC", ENOSPC, "No space left on device");
+#endif
+#ifdef ENOEXEC
+ inscode(d, ds, de, "ENOEXEC", ENOEXEC, "Exec format error");
+#endif
+#ifdef EALREADY
+ inscode(d, ds, de, "EALREADY", EALREADY, "Operation already in progress");
+#else
+#ifdef WSAEALREADY
+ inscode(d, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress");
+#endif
+#endif
+#ifdef ENETDOWN
+ inscode(d, ds, de, "ENETDOWN", ENETDOWN, "Network is down");
+#else
+#ifdef WSAENETDOWN
+ inscode(d, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down");
+#endif
+#endif
+#ifdef ENOTNAM
+ inscode(d, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file");
+#endif
+#ifdef EACCES
+ inscode(d, ds, de, "EACCES", EACCES, "Permission denied");
+#else
+#ifdef WSAEACCES
+ inscode(d, ds, de, "EACCES", WSAEACCES, "Permission denied");
+#endif
+#endif
+#ifdef ELNRNG
+ inscode(d, ds, de, "ELNRNG", ELNRNG, "Link number out of range");
+#endif
+#ifdef EILSEQ
+ inscode(d, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence");
+#endif
+#ifdef ENOTDIR
+ inscode(d, ds, de, "ENOTDIR", ENOTDIR, "Not a directory");
+#endif
+#ifdef ENOTUNIQ
+ inscode(d, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network");
+#endif
+#ifdef EPERM
+ inscode(d, ds, de, "EPERM", EPERM, "Operation not permitted");
+#endif
+#ifdef EDOM
+ inscode(d, ds, de, "EDOM", EDOM, "Math argument out of domain of func");
+#endif
+#ifdef EXFULL
+ inscode(d, ds, de, "EXFULL", EXFULL, "Exchange full");
+#endif
+#ifdef ECONNREFUSED
+ inscode(d, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused");
+#else
+#ifdef WSAECONNREFUSED
+ inscode(d, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused");
+#endif
+#endif
+#ifdef EISDIR
+ inscode(d, ds, de, "EISDIR", EISDIR, "Is a directory");
+#endif
+#ifdef EPROTONOSUPPORT
+ inscode(d, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported");
+#else
+#ifdef WSAEPROTONOSUPPORT
+ inscode(d, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");
+#endif
+#endif
+#ifdef EROFS
+ inscode(d, ds, de, "EROFS", EROFS, "Read-only file system");
+#endif
+#ifdef EADDRNOTAVAIL
+ inscode(d, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address");
+#else
+#ifdef WSAEADDRNOTAVAIL
+ inscode(d, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");
+#endif
+#endif
+#ifdef EIDRM
+ inscode(d, ds, de, "EIDRM", EIDRM, "Identifier removed");
+#endif
+#ifdef ECOMM
+ inscode(d, ds, de, "ECOMM", ECOMM, "Communication error on send");
+#endif
+#ifdef ESRMNT
+ inscode(d, ds, de, "ESRMNT", ESRMNT, "Srmount error");
+#endif
+#ifdef EREMOTEIO
+ inscode(d, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error");
+#endif
+#ifdef EL3RST
+ inscode(d, ds, de, "EL3RST", EL3RST, "Level 3 reset");
+#endif
+#ifdef EBADMSG
+ inscode(d, ds, de, "EBADMSG", EBADMSG, "Not a data message");
+#endif
+#ifdef ENFILE
+ inscode(d, ds, de, "ENFILE", ENFILE, "File table overflow");
+#endif
+#ifdef ELIBMAX
+ inscode(d, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries");
+#endif
+#ifdef ESPIPE
+ inscode(d, ds, de, "ESPIPE", ESPIPE, "Illegal seek");
+#endif
+#ifdef ENOLINK
+ inscode(d, ds, de, "ENOLINK", ENOLINK, "Link has been severed");
+#endif
+#ifdef ENETRESET
+ inscode(d, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset");
+#else
+#ifdef WSAENETRESET
+ inscode(d, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset");
+#endif
+#endif
+#ifdef ETIMEDOUT
+ inscode(d, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out");
+#else
+#ifdef WSAETIMEDOUT
+ inscode(d, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out");
+#endif
+#endif
+#ifdef ENOENT
+ inscode(d, ds, de, "ENOENT", ENOENT, "No such file or directory");
+#endif
+#ifdef EEXIST
+ inscode(d, ds, de, "EEXIST", EEXIST, "File exists");
+#endif
+#ifdef EDQUOT
+ inscode(d, ds, de, "EDQUOT", EDQUOT, "Quota exceeded");
+#else
+#ifdef WSAEDQUOT
+ inscode(d, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded");
+#endif
+#endif
+#ifdef ENOSTR
+ inscode(d, ds, de, "ENOSTR", ENOSTR, "Device not a stream");
+#endif
+#ifdef EBADSLT
+ inscode(d, ds, de, "EBADSLT", EBADSLT, "Invalid slot");
+#endif
+#ifdef EBADRQC
+ inscode(d, ds, de, "EBADRQC", EBADRQC, "Invalid request code");
+#endif
+#ifdef ELIBACC
+ inscode(d, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library");
+#endif
+#ifdef EFAULT
+ inscode(d, ds, de, "EFAULT", EFAULT, "Bad address");
+#else
+#ifdef WSAEFAULT
+ inscode(d, ds, de, "EFAULT", WSAEFAULT, "Bad address");
+#endif
+#endif
+#ifdef EFBIG
+ inscode(d, ds, de, "EFBIG", EFBIG, "File too large");
+#endif
+#ifdef EDEADLK
+ inscode(d, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur");
+#endif
+#ifdef ENOTCONN
+ inscode(d, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected");
+#else
+#ifdef WSAENOTCONN
+ inscode(d, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");
+#endif
+#endif
+#ifdef EDESTADDRREQ
+ inscode(d, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required");
+#else
+#ifdef WSAEDESTADDRREQ
+ inscode(d, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");
+#endif
+#endif
+#ifdef ELIBSCN
+ inscode(d, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted");
+#endif
+#ifdef ENOLCK
+ inscode(d, ds, de, "ENOLCK", ENOLCK, "No record locks available");
+#endif
+#ifdef EISNAM
+ inscode(d, ds, de, "EISNAM", EISNAM, "Is a named type file");
+#endif
+#ifdef ECONNABORTED
+ inscode(d, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort");
+#else
+#ifdef WSAECONNABORTED
+ inscode(d, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort");
+#endif
+#endif
+#ifdef ENETUNREACH
+ inscode(d, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable");
+#else
+#ifdef WSAENETUNREACH
+ inscode(d, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable");
+#endif
+#endif
+#ifdef ESTALE
+ inscode(d, ds, de, "ESTALE", ESTALE, "Stale NFS file handle");
+#else
+#ifdef WSAESTALE
+ inscode(d, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle");
+#endif
+#endif
+#ifdef ENOSR
+ inscode(d, ds, de, "ENOSR", ENOSR, "Out of streams resources");
+#endif
+#ifdef ENOMEM
+ inscode(d, ds, de, "ENOMEM", ENOMEM, "Out of memory");
+#endif
+#ifdef ENOTSOCK
+ inscode(d, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket");
+#else
+#ifdef WSAENOTSOCK
+ inscode(d, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");
+#endif
+#endif
+#ifdef ESTRPIPE
+ inscode(d, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error");
+#endif
+#ifdef EMLINK
+ inscode(d, ds, de, "EMLINK", EMLINK, "Too many links");
+#endif
+#ifdef ERANGE
+ inscode(d, ds, de, "ERANGE", ERANGE, "Math result not representable");
+#endif
+#ifdef ELIBEXEC
+ inscode(d, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly");
+#endif
+#ifdef EL3HLT
+ inscode(d, ds, de, "EL3HLT", EL3HLT, "Level 3 halted");
+#endif
+#ifdef ECONNRESET
+ inscode(d, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer");
+#else
+#ifdef WSAECONNRESET
+ inscode(d, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer");
+#endif
+#endif
+#ifdef EADDRINUSE
+ inscode(d, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use");
+#else
+#ifdef WSAEADDRINUSE
+ inscode(d, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use");
+#endif
+#endif
+#ifdef EOPNOTSUPP
+ inscode(d, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint");
+#else
+#ifdef WSAEOPNOTSUPP
+ inscode(d, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");
+#endif
+#endif
+#ifdef EREMCHG
+ inscode(d, ds, de, "EREMCHG", EREMCHG, "Remote address changed");
+#endif
+#ifdef EAGAIN
+ inscode(d, ds, de, "EAGAIN", EAGAIN, "Try again");
+#endif
+#ifdef ENAMETOOLONG
+ inscode(d, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long");
+#else
+#ifdef WSAENAMETOOLONG
+ inscode(d, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long");
+#endif
+#endif
+#ifdef ENOTTY
+ inscode(d, ds, de, "ENOTTY", ENOTTY, "Not a typewriter");
+#endif
+#ifdef ERESTART
+ inscode(d, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted");
+#endif
+#ifdef ESOCKTNOSUPPORT
+ inscode(d, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported");
+#else
+#ifdef WSAESOCKTNOSUPPORT
+ inscode(d, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");
+#endif
+#endif
+#ifdef ETIME
+ inscode(d, ds, de, "ETIME", ETIME, "Timer expired");
+#endif
+#ifdef EBFONT
+ inscode(d, ds, de, "EBFONT", EBFONT, "Bad font file format");
+#endif
+#ifdef EDEADLOCK
+ inscode(d, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK");
+#endif
+#ifdef ETOOMANYREFS
+ inscode(d, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice");
+#else
+#ifdef WSAETOOMANYREFS
+ inscode(d, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");
+#endif
+#endif
+#ifdef EMFILE
+ inscode(d, ds, de, "EMFILE", EMFILE, "Too many open files");
+#else
+#ifdef WSAEMFILE
+ inscode(d, ds, de, "EMFILE", WSAEMFILE, "Too many open files");
+#endif
+#endif
+#ifdef ETXTBSY
+ inscode(d, ds, de, "ETXTBSY", ETXTBSY, "Text file busy");
+#endif
+#ifdef EINPROGRESS
+ inscode(d, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress");
+#else
+#ifdef WSAEINPROGRESS
+ inscode(d, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress");
+#endif
+#endif
+#ifdef ENXIO
+ inscode(d, ds, de, "ENXIO", ENXIO, "No such device or address");
+#endif
+#ifdef ENOPKG
+ inscode(d, ds, de, "ENOPKG", ENOPKG, "Package not installed");
+#endif
+#ifdef WSASY
+ inscode(d, ds, de, "WSASY", WSASY, "Error WSASY");
+#endif
+#ifdef WSAEHOSTDOWN
+ inscode(d, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down");
+#endif
+#ifdef WSAENETDOWN
+ inscode(d, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down");
+#endif
+#ifdef WSAENOTSOCK
+ inscode(d, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");
+#endif
+#ifdef WSAEHOSTUNREACH
+ inscode(d, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");
+#endif
+#ifdef WSAELOOP
+ inscode(d, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered");
+#endif
+#ifdef WSAEMFILE
+ inscode(d, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files");
+#endif
+#ifdef WSAESTALE
+ inscode(d, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle");
+#endif
+#ifdef WSAVERNOTSUPPORTED
+ inscode(d, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED");
+#endif
+#ifdef WSAENETUNREACH
+ inscode(d, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable");
+#endif
+#ifdef WSAEPROCLIM
+ inscode(d, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM");
+#endif
+#ifdef WSAEFAULT
+ inscode(d, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address");
+#endif
+#ifdef WSANOTINITIALISED
+ inscode(d, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED");
+#endif
+#ifdef WSAEUSERS
+ inscode(d, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users");
+#endif
+#ifdef WSAMAKEASYNCREPL
+ inscode(d, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL");
+#endif
+#ifdef WSAENOPROTOOPT
+ inscode(d, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");
+#endif
+#ifdef WSAECONNABORTED
+ inscode(d, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort");
+#endif
+#ifdef WSAENAMETOOLONG
+ inscode(d, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long");
+#endif
+#ifdef WSAENOTEMPTY
+ inscode(d, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty");
+#endif
+#ifdef WSAESHUTDOWN
+ inscode(d, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#endif
+#ifdef WSAEAFNOSUPPORT
+ inscode(d, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");
+#endif
+#ifdef WSAETOOMANYREFS
+ inscode(d, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");
+#endif
+#ifdef WSAEACCES
+ inscode(d, ds, de, "WSAEACCES", WSAEACCES, "Permission denied");
+#endif
+#ifdef WSATR
+ inscode(d, ds, de, "WSATR", WSATR, "Error WSATR");
+#endif
+#ifdef WSABASEERR
+ inscode(d, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR");
+#endif
+#ifdef WSADESCRIPTIO
+ inscode(d, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO");
+#endif
+#ifdef WSAEMSGSIZE
+ inscode(d, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long");
+#endif
+#ifdef WSAEBADF
+ inscode(d, ds, de, "WSAEBADF", WSAEBADF, "Bad file number");
+#endif
+#ifdef WSAECONNRESET
+ inscode(d, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer");
+#endif
+#ifdef WSAGETSELECTERRO
+ inscode(d, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO");
+#endif
+#ifdef WSAETIMEDOUT
+ inscode(d, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out");
+#endif
+#ifdef WSAENOBUFS
+ inscode(d, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available");
+#endif
+#ifdef WSAEDISCON
+ inscode(d, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON");
+#endif
+#ifdef WSAEINTR
+ inscode(d, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call");
+#endif
+#ifdef WSAEPROTOTYPE
+ inscode(d, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");
+#endif
+#ifdef WSAHOS
+ inscode(d, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS");
+#endif
+#ifdef WSAEADDRINUSE
+ inscode(d, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use");
+#endif
+#ifdef WSAEADDRNOTAVAIL
+ inscode(d, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");
+#endif
+#ifdef WSAEALREADY
+ inscode(d, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress");
+#endif
+#ifdef WSAEPROTONOSUPPORT
+ inscode(d, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");
+#endif
+#ifdef WSASYSNOTREADY
+ inscode(d, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY");
+#endif
+#ifdef WSAEWOULDBLOCK
+ inscode(d, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");
+#endif
+#ifdef WSAEPFNOSUPPORT
+ inscode(d, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");
+#endif
+#ifdef WSAEOPNOTSUPP
+ inscode(d, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");
+#endif
+#ifdef WSAEISCONN
+ inscode(d, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected");
+#endif
+#ifdef WSAEDQUOT
+ inscode(d, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded");
+#endif
+#ifdef WSAENOTCONN
+ inscode(d, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");
+#endif
+#ifdef WSAEREMOTE
+ inscode(d, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote");
+#endif
+#ifdef WSAEINVAL
+ inscode(d, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument");
+#endif
+#ifdef WSAEINPROGRESS
+ inscode(d, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress");
+#endif
+#ifdef WSAGETSELECTEVEN
+ inscode(d, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN");
+#endif
+#ifdef WSAESOCKTNOSUPPORT
+ inscode(d, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");
+#endif
+#ifdef WSAGETASYNCERRO
+ inscode(d, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO");
+#endif
+#ifdef WSAMAKESELECTREPL
+ inscode(d, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL");
+#endif
+#ifdef WSAGETASYNCBUFLE
+ inscode(d, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE");
+#endif
+#ifdef WSAEDESTADDRREQ
+ inscode(d, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");
+#endif
+#ifdef WSAECONNREFUSED
+ inscode(d, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused");
+#endif
+#ifdef WSAENETRESET
+ inscode(d, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset");
+#endif
+#ifdef WSAN
+ inscode(d, ds, de, "WSAN", WSAN, "Error WSAN");
+#endif
+
+ Py_DECREF(de);
+}
diff --git a/sys/src/cmd/python/Modules/expat/amigaconfig.h b/sys/src/cmd/python/Modules/expat/amigaconfig.h
new file mode 100644
index 000000000..6781a714a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/amigaconfig.h
@@ -0,0 +1,96 @@
+#ifndef AMIGACONFIG_H
+#define AMIGACONFIG_H
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 4321
+
+/* Define to 1 if you have the `bcopy' function. */
+#define HAVE_BCOPY 1
+
+/* Define to 1 if you have the <check.h> header file. */
+#undef HAVE_CHECK_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "expat-bugs@mail.libexpat.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "expat"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "expat 1.95.8"
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.95.8"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* whether byteorder is bigendian */
+#define WORDS_BIGENDIAN
+
+/* Define to specify how much context to retain around the current parse
+ point. */
+#define XML_CONTEXT_BYTES 1024
+
+/* Define to make parameter entity parsing functionality available. */
+#define XML_DTD
+
+/* Define to make XML Namespaces functionality available. */
+#define XML_NS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+
+#endif /* AMIGACONFIG_H */
diff --git a/sys/src/cmd/python/Modules/expat/ascii.h b/sys/src/cmd/python/Modules/expat/ascii.h
new file mode 100644
index 000000000..337e5bb7e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/ascii.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F
diff --git a/sys/src/cmd/python/Modules/expat/asciitab.h b/sys/src/cmd/python/Modules/expat/asciitab.h
new file mode 100644
index 000000000..79a15c28c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/asciitab.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/sys/src/cmd/python/Modules/expat/expat.h b/sys/src/cmd/python/Modules/expat/expat.h
new file mode 100644
index 000000000..cf113eeaf
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/expat.h
@@ -0,0 +1,1013 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_INCLUDED
+#define Expat_INCLUDED 1
+
+#ifdef __VMS
+/* 0 1 2 3 0 1 2 3
+ 1234567890123456789012345678901 1234567890123456789012345678901 */
+#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
+#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
+#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
+#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
+#endif
+
+#include <stdlib.h>
+#include "expat_external.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct *XML_Parser;
+
+/* Should this be defined using stdbool.h when C99 is available? */
+typedef unsigned char XML_Bool;
+#define XML_TRUE ((XML_Bool) 1)
+#define XML_FALSE ((XML_Bool) 0)
+
+/* The XML_Status enum gives the possible return values for several
+ API functions. The preprocessor #defines are included so this
+ stanza can be added to code that still needs to support older
+ versions of Expat 1.95.x:
+
+ #ifndef XML_STATUS_OK
+ #define XML_STATUS_OK 1
+ #define XML_STATUS_ERROR 0
+ #endif
+
+ Otherwise, the #define hackery is quite ugly and would have been
+ dropped.
+*/
+enum XML_Status {
+ XML_STATUS_ERROR = 0,
+#define XML_STATUS_ERROR XML_STATUS_ERROR
+ XML_STATUS_OK = 1,
+#define XML_STATUS_OK XML_STATUS_OK
+ XML_STATUS_SUSPENDED = 2
+#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
+};
+
+enum XML_Error {
+ XML_ERROR_NONE,
+ XML_ERROR_NO_MEMORY,
+ XML_ERROR_SYNTAX,
+ XML_ERROR_NO_ELEMENTS,
+ XML_ERROR_INVALID_TOKEN,
+ XML_ERROR_UNCLOSED_TOKEN,
+ XML_ERROR_PARTIAL_CHAR,
+ XML_ERROR_TAG_MISMATCH,
+ XML_ERROR_DUPLICATE_ATTRIBUTE,
+ XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+ XML_ERROR_PARAM_ENTITY_REF,
+ XML_ERROR_UNDEFINED_ENTITY,
+ XML_ERROR_RECURSIVE_ENTITY_REF,
+ XML_ERROR_ASYNC_ENTITY,
+ XML_ERROR_BAD_CHAR_REF,
+ XML_ERROR_BINARY_ENTITY_REF,
+ XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+ XML_ERROR_MISPLACED_XML_PI,
+ XML_ERROR_UNKNOWN_ENCODING,
+ XML_ERROR_INCORRECT_ENCODING,
+ XML_ERROR_UNCLOSED_CDATA_SECTION,
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+ XML_ERROR_NOT_STANDALONE,
+ XML_ERROR_UNEXPECTED_STATE,
+ XML_ERROR_ENTITY_DECLARED_IN_PE,
+ XML_ERROR_FEATURE_REQUIRES_XML_DTD,
+ XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+ /* Added in 1.95.7. */
+ XML_ERROR_UNBOUND_PREFIX,
+ /* Added in 1.95.8. */
+ XML_ERROR_UNDECLARING_PREFIX,
+ XML_ERROR_INCOMPLETE_PE,
+ XML_ERROR_XML_DECL,
+ XML_ERROR_TEXT_DECL,
+ XML_ERROR_PUBLICID,
+ XML_ERROR_SUSPENDED,
+ XML_ERROR_NOT_SUSPENDED,
+ XML_ERROR_ABORTED,
+ XML_ERROR_FINISHED,
+ XML_ERROR_SUSPEND_PE,
+ /* Added in 2.0. */
+ XML_ERROR_RESERVED_PREFIX_XML,
+ XML_ERROR_RESERVED_PREFIX_XMLNS,
+ XML_ERROR_RESERVED_NAMESPACE_URI
+};
+
+enum XML_Content_Type {
+ XML_CTYPE_EMPTY = 1,
+ XML_CTYPE_ANY,
+ XML_CTYPE_MIXED,
+ XML_CTYPE_NAME,
+ XML_CTYPE_CHOICE,
+ XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+ XML_CQUANT_NONE,
+ XML_CQUANT_OPT,
+ XML_CQUANT_REP,
+ XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+ XML_CQUANT_NONE, and the other fields will be zero or NULL.
+ If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+ numchildren will contain number of elements that may be mixed in
+ and children point to an array of XML_Content cells that will be
+ all of XML_CTYPE_NAME type with no quantification.
+
+ If type == XML_CTYPE_NAME, then the name points to the name, and
+ the numchildren field will be zero and children will be NULL. The
+ quant fields indicates any quantifiers placed on the name.
+
+ CHOICE and SEQ will have name NULL, the number of children in
+ numchildren and children will point, recursively, to an array
+ of XML_Content cells.
+
+ The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ XML_Char * name;
+ unsigned int numchildren;
+ XML_Content * children;
+};
+
+
+/* This is called for an element declaration. See above for
+ description of the model argument. It's the caller's responsibility
+ to free model when finished with it.
+*/
+typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
+ const XML_Char *name,
+ XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser,
+ XML_ElementDeclHandler eldecl);
+
+/* The Attlist declaration handler is called for *each* attribute. So
+ a single Attlist declaration with multiple attributes declared will
+ generate multiple calls to this handler. The "default" parameter
+ may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
+ keyword. The "isrequired" parameter will be true and the default
+ value will be NULL in the case of "#REQUIRED". If "isrequired" is
+ true and default is non-NULL, then this is a "#FIXED" default.
+*/
+typedef void (XMLCALL *XML_AttlistDeclHandler) (
+ void *userData,
+ const XML_Char *elname,
+ const XML_Char *attname,
+ const XML_Char *att_type,
+ const XML_Char *dflt,
+ int isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser,
+ XML_AttlistDeclHandler attdecl);
+
+/* The XML declaration handler is called for *both* XML declarations
+ and text declarations. The way to distinguish is that the version
+ parameter will be NULL for text declarations. The encoding
+ parameter may be NULL for XML declarations. The standalone
+ parameter will be -1, 0, or 1 indicating respectively that there
+ was no standalone parameter in the declaration, that it was given
+ as no, or that it was given as yes.
+*/
+typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser,
+ XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+ void *(*malloc_fcn)(size_t size);
+ void *(*realloc_fcn)(void *ptr, size_t size);
+ void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+ external protocol or NULL if there is none specified.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor. Element type
+ names and attribute names that belong to a namespace will be
+ expanded; unprefixed attribute names are never expanded; unprefixed
+ element type names are expanded only if there is a default
+ namespace. The expanded name is the concatenation of the namespace
+ URI, the namespace separator character, and the local part of the
+ name. If the namespace separator is '\0' then the namespace URI
+ and the local part will be concatenated without any separator.
+ It is a programming error to use the separator '\0' with namespace
+ triplets (see XML_SetReturnNSTriplet).
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suite referred to
+ by memsuite. If memsuite is NULL, then use the standard library memory
+ suite. If namespaceSeparator is non-NULL it creates a parser with
+ namespace processing as described above. The character pointed at
+ will serve as the namespace separator.
+
+ All further memory operations used for the created parser will come from
+ the given suite.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *namespaceSeparator);
+
+/* Prepare a parser object to be re-used. This is particularly
+ valuable when memory allocation overhead is disproportionatly high,
+ such as when a large number of small documnents need to be parsed.
+ All handlers are cleared from the parser, except for the
+ unknownEncodingHandler. The parser's external state is re-initialized
+ except for the values of ns and ns_triplets.
+
+ Added in Expat 1.95.3.
+*/
+XMLPARSEAPI(XML_Bool)
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
+
+/* atts is array of name/value pairs, terminated by 0;
+ names and values are 0 terminated.
+*/
+typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
+ const XML_Char *name,
+ const XML_Char **atts);
+
+typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
+ const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
+ const XML_Char *s,
+ int len);
+
+/* target and data are 0 terminated */
+typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
+ void *userData,
+ const XML_Char *target,
+ const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (XMLCALL *XML_CommentHandler) (void *userData,
+ const XML_Char *data);
+
+typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
+typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+
+/* This is called for any characters in the XML document for which
+ there is no applicable handler. This includes both characters that
+ are part of markup which is of a kind that is not reported
+ (comments, markup declarations), or characters that are part of a
+ construct which could be reported but for which no handler has been
+ supplied. The characters are passed exactly as they were in the XML
+ document except that they will be encoded in UTF-8 or UTF-16.
+ Line boundaries are not normalized. Note that a byte order mark
+ character is not passed to the default handler. There are no
+ guarantees about how characters are divided between calls to the
+ default handler: for example, a comment might be split between
+ multiple calls.
+*/
+typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
+ const XML_Char *s,
+ int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+ any DTD or internal subset is parsed.
+*/
+typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
+ void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *sysid,
+ const XML_Char *pubid,
+ int has_internal_subset);
+
+/* This is called for the start of the DOCTYPE declaration when the
+ closing > is encountered, but after processing any external
+ subset.
+*/
+typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+ argument will be non-zero if the entity is a parameter entity, zero
+ otherwise.
+
+ For internal entities (<!ENTITY foo "bar">), value will
+ be non-NULL and systemId, publicID, and notationName will be NULL.
+ The value string is NOT nul-terminated; the length is provided in
+ the value_length argument. Since it is legal to have zero-length
+ values, do not use this argument to test for internal entities.
+
+ For external entities, value will be NULL and systemId will be
+ non-NULL. The publicId argument will be NULL unless a public
+ identifier was provided. The notationName argument will have a
+ non-NULL value only for unparsed entity declarations.
+
+ Note that is_parameter_entity can't be changed to XML_Bool, since
+ that would break binary compatibility.
+*/
+typedef void (XMLCALL *XML_EntityDeclHandler) (
+ void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser,
+ XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+ This handler has been superceded by the EntityDeclHandler above.
+ It is provided here for backward compatibility.
+
+ This is called for a declaration of an unparsed (NDATA) entity.
+ The base argument is whatever was set by XML_SetBase. The
+ entityName, systemId and notationName arguments will never be
+ NULL. The other arguments may be.
+*/
+typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
+ void *userData,
+ const XML_Char *entityName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+/* This is called for a declaration of notation. The base argument is
+ whatever was set by XML_SetBase. The notationName will never be
+ NULL. The other arguments can be.
+*/
+typedef void (XMLCALL *XML_NotationDeclHandler) (
+ void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+ each namespace declaration. The call to the start and end element
+ handlers occur between the calls to the start and end namespace
+ declaration handlers. For an xmlns attribute, prefix will be
+ NULL. For an xmlns="" attribute, uri will be NULL.
+*/
+typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
+ void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri);
+
+typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
+ void *userData,
+ const XML_Char *prefix);
+
+/* This is called if the document is not standalone, that is, it has an
+ external subset or a reference to a parameter entity, but does not
+ have standalone="yes". If this handler returns XML_STATUS_ERROR,
+ then processing will not continue, and the parser will return a
+ XML_ERROR_NOT_STANDALONE error.
+ If parameter entity parsing is enabled, then in addition to the
+ conditions above this handler will only be called if the referenced
+ entity was actually read.
+*/
+typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+
+/* This is called for a reference to an external parsed general
+ entity. The referenced entity is not automatically parsed. The
+ application can parse it immediately or later using
+ XML_ExternalEntityParserCreate.
+
+ The parser argument is the parser parsing the entity containing the
+ reference; it can be passed as the parser argument to
+ XML_ExternalEntityParserCreate. The systemId argument is the
+ system identifier as specified in the entity declaration; it will
+ not be NULL.
+
+ The base argument is the system identifier that should be used as
+ the base for resolving systemId if systemId was relative; this is
+ set by XML_SetBase; it may be NULL.
+
+ The publicId argument is the public identifier as specified in the
+ entity declaration, or NULL if none was specified; the whitespace
+ in the public identifier will have been normalized as required by
+ the XML spec.
+
+ The context argument specifies the parsing context in the format
+ expected by the context argument to XML_ExternalEntityParserCreate;
+ context is valid only until the handler returns, so if the
+ referenced entity is to be parsed later, it must be copied.
+ context is NULL only when the entity is a parameter entity.
+
+ The handler should return XML_STATUS_ERROR if processing should not
+ continue because of a fatal error in the handling of the external
+ entity. In this case the calling parser will return an
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+
+ Note that unlike other handlers the first argument is the parser,
+ not userData.
+*/
+typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
+ XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* This is called in two situations:
+ 1) An entity reference is encountered for which no declaration
+ has been read *and* this is not an error.
+ 2) An internal entity reference is read, but not expanded, because
+ XML_SetDefaultHandler has been called.
+ Note: skipped parameter entities in declarations and skipped general
+ entities in attribute values cannot be reported, because
+ the event would be out of sync with the reporting of the
+ declarations or attribute values
+*/
+typedef void (XMLCALL *XML_SkippedEntityHandler) (
+ void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler to
+ provide information to the parser about encodings that are unknown
+ to the parser.
+
+ The map[b] member gives information about byte sequences whose
+ first byte is b.
+
+ If map[b] is c where c is >= 0, then b by itself encodes the
+ Unicode scalar value c.
+
+ If map[b] is -1, then the byte sequence is malformed.
+
+ If map[b] is -n, where n >= 2, then b is the first byte of an
+ n-byte sequence that encodes a single Unicode scalar value.
+
+ The data member will be passed as the first argument to the convert
+ function.
+
+ The convert function is used to convert multibyte sequences; s will
+ point to a n-byte sequence where map[(unsigned char)*s] == -n. The
+ convert function must return the Unicode scalar value represented
+ by this byte sequence or -1 if the byte sequence is malformed.
+
+ The convert function may be NULL if the encoding is a single-byte
+ encoding, that is if map[b] >= -1 for all bytes b.
+
+ When the parser is finished with the encoding, then if release is
+ not NULL, it will call release passing it the data member; once
+ release has been called, the convert function will not be called
+ again.
+
+ Expat places certain restrictions on the encodings that are supported
+ using this mechanism.
+
+ 1. Every ASCII character that can appear in a well-formed XML document,
+ other than the characters
+
+ $@\^`{}~
+
+ must be represented by a single byte, and that byte must be the
+ same byte that represents that character in ASCII.
+
+ 2. No character may require more than 4 bytes to encode.
+
+ 3. All characters encoded must have Unicode scalar values <=
+ 0xFFFF, (i.e., characters that would be encoded by surrogates in
+ UTF-16 are not allowed). Note that this restriction doesn't
+ apply to the built-in support for UTF-8 and UTF-16.
+
+ 4. No Unicode character may be encoded by more than one distinct
+ sequence of bytes.
+*/
+typedef struct {
+ int map[256];
+ void *data;
+ int (XMLCALL *convert)(void *data, const char *s);
+ void (XMLCALL *release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+
+ The encodingHandlerData argument is that which was passed as the
+ second argument to XML_SetUnknownEncodingHandler.
+
+ The name argument gives the name of the encoding as specified in
+ the encoding declaration.
+
+ If the callback can provide information about the encoding, it must
+ fill in the XML_Encoding structure, and return XML_STATUS_OK.
+ Otherwise it must return XML_STATUS_ERROR.
+
+ If info does not describe a suitable encoding, then the parser will
+ return an XML_UNKNOWN_ENCODING error.
+*/
+typedef int (XMLCALL *XML_UnknownEncodingHandler) (
+ void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser parser,
+ XML_StartElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser parser,
+ XML_EndElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser,
+ XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+ internal entities. These entity references will be passed to the
+ default handler, or to the skipped entity handler, if one is set.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser,
+ XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+ internal entities. The entity reference will not be passed to the
+ default handler.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+ XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser,
+ XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler);
+
+/* If a non-NULL value for arg is specified here, then it will be
+ passed as the first argument to the external entity ref handler
+ instead of the parser object.
+*/
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
+ void *arg);
+
+XMLPARSEAPI(void)
+XML_SetSkippedEntityHandler(XML_Parser parser,
+ XML_SkippedEntityHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end
+ element, processing instruction or character data. It causes the
+ corresponding markup to be passed to the default handler.
+*/
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+ a name has a prefix (i.e. an explicit namespace qualifier) then
+ that name is returned as a triplet in a single string separated by
+ the separator character specified when the parser was created: URI
+ + sep + local_name + sep + prefix.
+
+ If do_nst is zero, then namespace information is returned in the
+ default manner (URI + sep + local_name) whether or not the name
+ has a prefix.
+
+ Note: Calling XML_SetReturnNSTriplet after XML_Parse or
+ XML_ParseBuffer has no effect.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or NULL. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument to
+ XML_ParserCreate. On success XML_SetEncoding returns non-zero,
+ zero otherwise.
+ Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
+ has no effect and returns XML_STATUS_ERROR.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed as the
+ first argument to callbacks instead of userData. The userData will
+ still be accessible using XML_GetUserData.
+*/
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* If useDTD == XML_TRUE is passed to this function, then the parser
+ will assume that there is an external subset, even if none is
+ specified in the document. In such a case the parser will call the
+ externalEntityRefHandler with a value of NULL for the systemId
+ argument (the publicId and context arguments will be NULL as well).
+ Note: For the purpose of checking WFC: Entity Declared, passing
+ useDTD == XML_TRUE will make the parser behave as if the document
+ had a DTD with an external subset.
+ Note: If this function is called, then this must be done before
+ the first call to XML_Parse or XML_ParseBuffer, since it will
+ have no effect after that. Returns
+ XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
+ Note: If the document does not have a DOCTYPE declaration at all,
+ then startDoctypeDeclHandler and endDoctypeDeclHandler will not
+ be called, despite an external subset being parsed.
+ Note: If XML_DTD is not defined when Expat is compiled, returns
+ XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
+
+
+/* Sets the base to be used for resolving relative URIs in system
+ identifiers in declarations. Resolving relative identifiers is
+ left to the application: this value will be passed through as the
+ base argument to the XML_ExternalEntityRefHandler,
+ XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
+ argument will be copied. Returns XML_STATUS_ERROR if out of memory,
+ XML_STATUS_OK otherwise.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+ to the XML_StartElementHandler that were specified in the start-tag
+ rather than defaulted. Each attribute/value pair counts as 2; thus
+ this correspondds to an index into the atts array passed to the
+ XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+ XML_StartElementHandler, or -1 if there is no ID attribute. Each
+ attribute/value pair counts as 2; thus this correspondds to an
+ index into the atts array passed to the XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
+ detected. The last call to XML_Parse must have isFinal true; len
+ may be zero for this call (or any other).
+
+ Though the return values for these functions has always been
+ described as a Boolean value, the implementation, at least for the
+ 1.95.x series, has always returned exactly one of the XML_Status
+ values.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(enum XML_Status)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
+ Must be called from within a call-back handler, except when aborting
+ (resumable = 0) an already suspended parser. Some call-backs may
+ still follow because they would otherwise get lost. Examples:
+ - endElementHandler() for empty elements when stopped in
+ startElementHandler(),
+ - endNameSpaceDeclHandler() when stopped in endElementHandler(),
+ and possibly others.
+
+ Can be called from most handlers, including DTD related call-backs,
+ except when parsing an external parameter entity and resumable != 0.
+ Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
+ Possible error codes:
+ - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
+ - XML_ERROR_FINISHED: when the parser has already finished.
+ - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
+
+ When resumable != 0 (true) then parsing is suspended, that is,
+ XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
+ Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
+ return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
+
+ *Note*:
+ This will be applied to the current parser instance only, that is, if
+ there is a parent parser then it will continue parsing when the
+ externalEntityRefHandler() returns. It is up to the implementation of
+ the externalEntityRefHandler() to call XML_StopParser() on the parent
+ parser (recursively), if one wants to stop parsing altogether.
+
+ When suspended, parsing can be resumed by calling XML_ResumeParser().
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_StopParser(XML_Parser parser, XML_Bool resumable);
+
+/* Resumes parsing after it has been suspended with XML_StopParser().
+ Must not be called from within a handler call-back. Returns same
+ status codes as XML_Parse() or XML_ParseBuffer().
+ Additional error code XML_ERROR_NOT_SUSPENDED possible.
+
+ *Note*:
+ This must be called on the most deeply nested child parser instance
+ first, and on its parent parser only after the child parser has finished,
+ to be applied recursively until the document entity's parser is restarted.
+ That is, the parent parser will not resume by itself and it is up to the
+ application to call XML_ResumeParser() on it at the appropriate moment.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_ResumeParser(XML_Parser parser);
+
+enum XML_Parsing {
+ XML_INITIALIZED,
+ XML_PARSING,
+ XML_FINISHED,
+ XML_SUSPENDED
+};
+
+typedef struct {
+ enum XML_Parsing parsing;
+ XML_Bool finalBuffer;
+} XML_ParsingStatus;
+
+/* Returns status of parser with respect to being initialized, parsing,
+ finished, or suspended and processing the final buffer.
+ XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
+ XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
+*/
+XMLPARSEAPI(void)
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
+
+/* Creates an XML_Parser object that can parse an external general
+ entity; context is a '\0'-terminated string specifying the parse
+ context; encoding is a '\0'-terminated string giving the name of
+ the externally specified encoding, or NULL if there is no
+ externally specified encoding. The context string consists of a
+ sequence of tokens separated by formfeeds (\f); a token consisting
+ of a name specifies that the general entity of the name is open; a
+ token of the form prefix=uri specifies the namespace for a
+ particular prefix; a token of the form =uri specifies the default
+ namespace. This can be called at any point after the first call to
+ an ExternalEntityRefHandler so longer as the parser has not yet
+ been freed. The new parser is completely independent and may
+ safely be used in a separate thread. The handlers and userData are
+ initialized from the parser argument. Returns NULL if out of memory.
+ Otherwise returns a new XML_Parser object.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+ XML_PARAM_ENTITY_PARSING_NEVER,
+ XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+ XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+ subset). If parsing of parameter entities is enabled, then
+ references to external parameter entities (including the external
+ DTD subset) will be passed to the handler set with
+ XML_SetExternalEntityRefHandler. The context passed will be 0.
+
+ Unlike external general entities, external parameter entities can
+ only be parsed synchronously. If the external parameter entity is
+ to be parsed, it must be parsed during the call to the external
+ entity ref handler: the complete sequence of
+ XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
+ XML_ParserFree calls must be made during this call. After
+ XML_ExternalEntityParserCreate has been called to create the parser
+ for the external parameter entity (context must be 0 for this
+ call), it is illegal to make any calls on the old parser until
+ XML_ParserFree has been called on the newly created parser.
+ If the library has been compiled without support for parameter
+ entity parsing (ie without XML_DTD being defined), then
+ XML_SetParamEntityParsing will return 0 if parsing of parameter
+ entities is requested; otherwise it will return non-zero.
+ Note: If XML_SetParamEntityParsing is called after XML_Parse or
+ XML_ParseBuffer, then it has no effect and will always return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing parsing);
+
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+ XML_GetErrorCode returns information about the error.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse
+ location. They may be called from any callback called to report
+ some parse event; in this case the location is the location of the
+ first of the sequence of characters that generated the event. When
+ called from callbacks generated by declarations in the document
+ prologue, the location identified isn't as neatly defined, but will
+ be within the relevant markup. When called outside of the callback
+ functions, the position indicated will be just past the last parse
+ event (regardless of whether there was an associated callback).
+
+ They may also be called after returning from a call to XML_Parse
+ or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
+ the location is the location of the character at which the error
+ was detected; otherwise the location is the location of the last
+ parse event, as described above.
+*/
+XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+ Returns 0 if the event is in an internal entity.
+*/
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+ the integer pointed to by offset to the offset within this buffer
+ of the current parse position, and sets the integer pointed to by size
+ to the size of this buffer (the number of input bytes). Otherwise
+ returns a NULL pointer. Also returns a NULL pointer if a parse isn't
+ active.
+
+ NOTE: The character pointer returned should not be used outside
+ the handler that makes the call.
+*/
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser,
+ int *offset,
+ int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees the content model passed to the element declaration handler */
+XMLPARSEAPI(void)
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);
+
+/* Exposing the memory handling functions used in Expat */
+XMLPARSEAPI(void *)
+XML_MemMalloc(XML_Parser parser, size_t size);
+
+XMLPARSEAPI(void *)
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
+
+XMLPARSEAPI(void)
+XML_MemFree(XML_Parser parser, void *ptr);
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(enum XML_Error code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+ int major;
+ int minor;
+ int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+ number information for this version of expat.
+*/
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+/* Added in Expat 1.95.5. */
+enum XML_FeatureEnum {
+ XML_FEATURE_END = 0,
+ XML_FEATURE_UNICODE,
+ XML_FEATURE_UNICODE_WCHAR_T,
+ XML_FEATURE_DTD,
+ XML_FEATURE_CONTEXT_BYTES,
+ XML_FEATURE_MIN_SIZE,
+ XML_FEATURE_SIZEOF_XML_CHAR,
+ XML_FEATURE_SIZEOF_XML_LCHAR,
+ XML_FEATURE_NS
+ /* Additional features must be added to the end of this enum. */
+};
+
+typedef struct {
+ enum XML_FeatureEnum feature;
+ const XML_LChar *name;
+ long int value;
+} XML_Feature;
+
+XMLPARSEAPI(const XML_Feature *)
+XML_GetFeatureList(void);
+
+
+/* Expat follows the GNU/Linux convention of odd number minor version for
+ beta/development releases and even number minor version for stable
+ releases. Micro is bumped with each release, and set to 0 with each
+ change to major or minor version.
+*/
+#define XML_MAJOR_VERSION 2
+#define XML_MINOR_VERSION 0
+#define XML_MICRO_VERSION 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_INCLUDED */
diff --git a/sys/src/cmd/python/Modules/expat/expat_config.h b/sys/src/cmd/python/Modules/expat/expat_config.h
new file mode 100644
index 000000000..b8c1639b9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/expat_config.h
@@ -0,0 +1,19 @@
+/*
+ * Expat configuration for python. This file is not part of the expat
+ * distribution.
+ */
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H
+
+#include <pyconfig.h>
+#ifdef WORDS_BIGENDIAN
+#define BYTEORDER 4321
+#else
+#define BYTEORDER 1234
+#endif
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+#endif /* EXPAT_CONFIG_H */
diff --git a/sys/src/cmd/python/Modules/expat/expat_external.h b/sys/src/cmd/python/Modules/expat/expat_external.h
new file mode 100644
index 000000000..f05401419
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/expat_external.h
@@ -0,0 +1,119 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_External_INCLUDED
+#define Expat_External_INCLUDED 1
+
+/* External API definitions */
+
+/* Namespace external symbols to allow multiple libexpat version to
+ co-exist. */
+#include "pyexpatns.h"
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+#define XML_USE_MSC_EXTENSIONS 1
+#endif
+
+/* Expat tries very hard to make the API boundary very specifically
+ defined. There are two macros defined to control this boundary;
+ each of these can be defined before including this header to
+ achieve some different behavior, but doing so it not recommended or
+ tested frequently.
+
+ XMLCALL - The calling convention to use for all calls across the
+ "library boundary." This will default to cdecl, and
+ try really hard to tell the compiler that's what we
+ want.
+
+ XMLIMPORT - Whatever magic is needed to note that a function is
+ to be imported from a dynamically loaded library
+ (.dll, .so, or .sl, depending on your platform).
+
+ The XMLCALL macro was added in Expat 1.95.7. The only one which is
+ expected to be directly useful in client code is XMLCALL.
+
+ Note that on at least some Unix versions, the Expat library must be
+ compiled with the cdecl calling convention as the default since
+ system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+#if defined(XML_USE_MSC_EXTENSIONS)
+#define XMLCALL __cdecl
+#elif defined(__GNUC__) && defined(__i386)
+#define XMLCALL __attribute__((cdecl))
+#else
+/* For any platform which uses this definition and supports more than
+ one calling convention, we need to extend this definition to
+ declare the convention used on that platform, if it's possible to
+ do so.
+
+ If this is the case for your platform, please file a bug report
+ with information on how to identify your platform via the C
+ pre-processor and how to specify the same calling convention as the
+ platform's malloc() implementation.
+*/
+#define XMLCALL
+#endif
+#endif /* not defined XMLCALL */
+
+
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)
+#ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+#ifdef XML_USE_MSC_EXTENSIONS
+#define XMLIMPORT __declspec(dllimport)
+#endif
+
+#endif
+#endif /* not defined XML_STATIC */
+
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+#define XMLIMPORT
+#endif
+
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_UNICODE
+#endif
+
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+#ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+#else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE_WCHAR_T */
+#else /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
+typedef __int64 XML_Index;
+typedef unsigned __int64 XML_Size;
+#else
+typedef long long XML_Index;
+typedef unsigned long long XML_Size;
+#endif
+#else
+typedef long XML_Index;
+typedef unsigned long XML_Size;
+#endif /* XML_LARGE_SIZE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_External_INCLUDED */
diff --git a/sys/src/cmd/python/Modules/expat/iasciitab.h b/sys/src/cmd/python/Modules/expat/iasciitab.h
new file mode 100644
index 000000000..24a1d5ccc
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/iasciitab.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/sys/src/cmd/python/Modules/expat/internal.h b/sys/src/cmd/python/Modules/expat/internal.h
new file mode 100644
index 000000000..ff056c659
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/internal.h
@@ -0,0 +1,73 @@
+/* internal.h
+
+ Internal definitions used by Expat. This is not needed to compile
+ client code.
+
+ The following calling convention macros are defined for frequently
+ called functions:
+
+ FASTCALL - Used for those internal functions that have a simple
+ body and a low number of arguments and local variables.
+
+ PTRCALL - Used for functions called though function pointers.
+
+ PTRFASTCALL - Like PTRCALL, but for low number of arguments.
+
+ inline - Used for selected internal functions for which inlining
+ may improve performance on some platforms.
+
+ Note: Use of these macros is based on judgement, not hard rules,
+ and therefore subject to change.
+*/
+
+#if defined(__GNUC__) && defined(__i386__)
+/* We'll use this version by default only where we know it helps.
+
+ regparm() generates warnings on Solaris boxes. See SF bug #692878.
+
+ Instability reported with egcs on a RedHat Linux 7.3.
+ Let's comment out:
+ #define FASTCALL __attribute__((stdcall, regparm(3)))
+ and let's try this:
+*/
+#define FASTCALL __attribute__((regparm(3)))
+#define PTRFASTCALL __attribute__((regparm(3)))
+#endif
+
+/* Using __fastcall seems to have an unexpected negative effect under
+ MS VC++, especially for function pointers, so we won't use it for
+ now on that platform. It may be reconsidered for a future release
+ if it can be made more effective.
+ Likely reason: __fastcall on Windows is like stdcall, therefore
+ the compiler cannot perform stack optimizations for call clusters.
+*/
+
+/* Make sure all of these are defined if they aren't already. */
+
+#ifndef FASTCALL
+#define FASTCALL
+#endif
+
+#ifndef PTRCALL
+#define PTRCALL
+#endif
+
+#ifndef PTRFASTCALL
+#define PTRFASTCALL
+#endif
+
+#ifndef XML_MIN_SIZE
+#if !defined(__cplusplus) && !defined(inline)
+#ifdef __GNUC__
+#define inline __inline
+#endif /* __GNUC__ */
+#endif
+#endif /* XML_MIN_SIZE */
+
+#ifdef __cplusplus
+#define inline inline
+#else
+#ifndef inline
+#define inline
+#endif
+#endif
diff --git a/sys/src/cmd/python/Modules/expat/latin1tab.h b/sys/src/cmd/python/Modules/expat/latin1tab.h
new file mode 100644
index 000000000..53c25d76b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/latin1tab.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/sys/src/cmd/python/Modules/expat/macconfig.h b/sys/src/cmd/python/Modules/expat/macconfig.h
new file mode 100644
index 000000000..2725caaf5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/macconfig.h
@@ -0,0 +1,53 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+**
+*/
+
+#ifndef MACCONFIG_H
+#define MACCONFIG_H
+
+
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 4321
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* whether byteorder is bigendian */
+#define WORDS_BIGENDIAN
+
+/* Define to specify how much context to retain around the current parse
+ point. */
+#undef XML_CONTEXT_BYTES
+
+/* Define to make parameter entity parsing functionality available. */
+#define XML_DTD
+
+/* Define to make XML Namespaces functionality available. */
+#define XML_NS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#define off_t long
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+
+#endif /* ifndef MACCONFIG_H */
diff --git a/sys/src/cmd/python/Modules/expat/nametab.h b/sys/src/cmd/python/Modules/expat/nametab.h
new file mode 100644
index 000000000..b05e62c77
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/nametab.h
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/sys/src/cmd/python/Modules/expat/pyexpatns.h b/sys/src/cmd/python/Modules/expat/pyexpatns.h
new file mode 100644
index 000000000..7fbd341c2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/pyexpatns.h
@@ -0,0 +1,124 @@
+/* Copyright (c) 2005-2006 ActiveState Software Inc.
+ *
+ * Namespace all expat exported symbols to avoid dynamic loading symbol
+ * collisions when embedding Python.
+ *
+ * The Problem:
+ * - you embed Python in some app
+ * - the app dynamically loads libexpat of version X
+ * - the embedded Python imports pyexpat (which was built against
+ * libexpat version X+n)
+ * --> pyexpat gets the expat symbols from the already loaded and *older*
+ * libexpat: crash (Specifically the crash we observed was in
+ * getting an old XML_ErrorString (from xmlparse.c) and then calling
+ * it with newer values in the XML_Error enum:
+ *
+ * // pyexpat.c, line 1970
+ * ...
+ * // Added in Expat 1.95.7.
+ * MYCONST(XML_ERROR_UNBOUND_PREFIX);
+ * ...
+ *
+ *
+ * The Solution:
+ * Prefix all a exported symbols with "PyExpat_". This is similar to
+ * what Mozilla does for some common libs:
+ * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115
+ *
+ * The list of relevant exported symbols can be had with this command:
+ *
+ nm pyexpat.so \
+ | grep -v " [a-zBUA] " \
+ | grep -v "_fini\|_init\|initpyexpat"
+ *
+ * If any of those symbols are NOT prefixed with "PyExpat_" then
+ * a #define should be added for it here.
+ */
+
+#ifndef PYEXPATNS_H
+#define PYEXPATNS_H
+
+#define XML_DefaultCurrent PyExpat_XML_DefaultCurrent
+#define XML_ErrorString PyExpat_XML_ErrorString
+#define XML_ExpatVersion PyExpat_XML_ExpatVersion
+#define XML_ExpatVersionInfo PyExpat_XML_ExpatVersionInfo
+#define XML_ExternalEntityParserCreate PyExpat_XML_ExternalEntityParserCreate
+#define XML_FreeContentModel PyExpat_XML_FreeContentModel
+#define XML_GetBase PyExpat_XML_GetBase
+#define XML_GetBuffer PyExpat_XML_GetBuffer
+#define XML_GetCurrentByteCount PyExpat_XML_GetCurrentByteCount
+#define XML_GetCurrentByteIndex PyExpat_XML_GetCurrentByteIndex
+#define XML_GetCurrentColumnNumber PyExpat_XML_GetCurrentColumnNumber
+#define XML_GetCurrentLineNumber PyExpat_XML_GetCurrentLineNumber
+#define XML_GetErrorCode PyExpat_XML_GetErrorCode
+#define XML_GetFeatureList PyExpat_XML_GetFeatureList
+#define XML_GetIdAttributeIndex PyExpat_XML_GetIdAttributeIndex
+#define XML_GetInputContext PyExpat_XML_GetInputContext
+#define XML_GetParsingStatus PyExpat_XML_GetParsingStatus
+#define XML_GetSpecifiedAttributeCount PyExpat_XML_GetSpecifiedAttributeCount
+#define XmlGetUtf16InternalEncoding PyExpat_XmlGetUtf16InternalEncoding
+#define XmlGetUtf16InternalEncodingNS PyExpat_XmlGetUtf16InternalEncodingNS
+#define XmlGetUtf8InternalEncoding PyExpat_XmlGetUtf8InternalEncoding
+#define XmlGetUtf8InternalEncodingNS PyExpat_XmlGetUtf8InternalEncodingNS
+#define XmlInitEncoding PyExpat_XmlInitEncoding
+#define XmlInitEncodingNS PyExpat_XmlInitEncodingNS
+#define XmlInitUnknownEncoding PyExpat_XmlInitUnknownEncoding
+#define XmlInitUnknownEncodingNS PyExpat_XmlInitUnknownEncodingNS
+#define XML_MemFree PyExpat_XML_MemFree
+#define XML_MemMalloc PyExpat_XML_MemMalloc
+#define XML_MemRealloc PyExpat_XML_MemRealloc
+#define XML_Parse PyExpat_XML_Parse
+#define XML_ParseBuffer PyExpat_XML_ParseBuffer
+#define XML_ParserCreate PyExpat_XML_ParserCreate
+#define XML_ParserCreate_MM PyExpat_XML_ParserCreate_MM
+#define XML_ParserCreateNS PyExpat_XML_ParserCreateNS
+#define XML_ParserFree PyExpat_XML_ParserFree
+#define XML_ParserReset PyExpat_XML_ParserReset
+#define XmlParseXmlDecl PyExpat_XmlParseXmlDecl
+#define XmlParseXmlDeclNS PyExpat_XmlParseXmlDeclNS
+#define XmlPrologStateInit PyExpat_XmlPrologStateInit
+#define XmlPrologStateInitExternalEntity PyExpat_XmlPrologStateInitExternalEntity
+#define XML_ResumeParser PyExpat_XML_ResumeParser
+#define XML_SetAttlistDeclHandler PyExpat_XML_SetAttlistDeclHandler
+#define XML_SetBase PyExpat_XML_SetBase
+#define XML_SetCdataSectionHandler PyExpat_XML_SetCdataSectionHandler
+#define XML_SetCharacterDataHandler PyExpat_XML_SetCharacterDataHandler
+#define XML_SetCommentHandler PyExpat_XML_SetCommentHandler
+#define XML_SetDefaultHandler PyExpat_XML_SetDefaultHandler
+#define XML_SetDefaultHandlerExpand PyExpat_XML_SetDefaultHandlerExpand
+#define XML_SetDoctypeDeclHandler PyExpat_XML_SetDoctypeDeclHandler
+#define XML_SetElementDeclHandler PyExpat_XML_SetElementDeclHandler
+#define XML_SetElementHandler PyExpat_XML_SetElementHandler
+#define XML_SetEncoding PyExpat_XML_SetEncoding
+#define XML_SetEndCdataSectionHandler PyExpat_XML_SetEndCdataSectionHandler
+#define XML_SetEndDoctypeDeclHandler PyExpat_XML_SetEndDoctypeDeclHandler
+#define XML_SetEndElementHandler PyExpat_XML_SetEndElementHandler
+#define XML_SetEndNamespaceDeclHandler PyExpat_XML_SetEndNamespaceDeclHandler
+#define XML_SetEntityDeclHandler PyExpat_XML_SetEntityDeclHandler
+#define XML_SetExternalEntityRefHandler PyExpat_XML_SetExternalEntityRefHandler
+#define XML_SetExternalEntityRefHandlerArg PyExpat_XML_SetExternalEntityRefHandlerArg
+#define XML_SetNamespaceDeclHandler PyExpat_XML_SetNamespaceDeclHandler
+#define XML_SetNotationDeclHandler PyExpat_XML_SetNotationDeclHandler
+#define XML_SetNotStandaloneHandler PyExpat_XML_SetNotStandaloneHandler
+#define XML_SetParamEntityParsing PyExpat_XML_SetParamEntityParsing
+#define XML_SetProcessingInstructionHandler PyExpat_XML_SetProcessingInstructionHandler
+#define XML_SetReturnNSTriplet PyExpat_XML_SetReturnNSTriplet
+#define XML_SetSkippedEntityHandler PyExpat_XML_SetSkippedEntityHandler
+#define XML_SetStartCdataSectionHandler PyExpat_XML_SetStartCdataSectionHandler
+#define XML_SetStartDoctypeDeclHandler PyExpat_XML_SetStartDoctypeDeclHandler
+#define XML_SetStartElementHandler PyExpat_XML_SetStartElementHandler
+#define XML_SetStartNamespaceDeclHandler PyExpat_XML_SetStartNamespaceDeclHandler
+#define XML_SetUnknownEncodingHandler PyExpat_XML_SetUnknownEncodingHandler
+#define XML_SetUnparsedEntityDeclHandler PyExpat_XML_SetUnparsedEntityDeclHandler
+#define XML_SetUserData PyExpat_XML_SetUserData
+#define XML_SetXmlDeclHandler PyExpat_XML_SetXmlDeclHandler
+#define XmlSizeOfUnknownEncoding PyExpat_XmlSizeOfUnknownEncoding
+#define XML_StopParser PyExpat_XML_StopParser
+#define XML_UseForeignDTD PyExpat_XML_UseForeignDTD
+#define XML_UseParserAsHandlerArg PyExpat_XML_UseParserAsHandlerArg
+#define XmlUtf16Encode PyExpat_XmlUtf16Encode
+#define XmlUtf8Encode PyExpat_XmlUtf8Encode
+
+
+#endif /* !PYEXPATNS_H */
+
diff --git a/sys/src/cmd/python/Modules/expat/utf8tab.h b/sys/src/cmd/python/Modules/expat/utf8tab.h
new file mode 100644
index 000000000..7bb3e7760
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/utf8tab.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/sys/src/cmd/python/Modules/expat/winconfig.h b/sys/src/cmd/python/Modules/expat/winconfig.h
new file mode 100644
index 000000000..c1b791d62
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/winconfig.h
@@ -0,0 +1,30 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+*/
+
+#ifndef WINCONFIG_H
+#define WINCONFIG_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <memory.h>
+#include <string.h>
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+/* we will assume all Windows platforms are little endian */
+#define BYTEORDER 1234
+
+/* Windows has memmove() available. */
+#define HAVE_MEMMOVE
+
+#endif /* ndef WINCONFIG_H */
diff --git a/sys/src/cmd/python/Modules/expat/xmlparse.c b/sys/src/cmd/python/Modules/expat/xmlparse.c
new file mode 100644
index 000000000..e04426d0c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmlparse.c
@@ -0,0 +1,6268 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#define XML_BUILDING_EXPAT 1
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#elif defined(HAVE_EXPAT_CONFIG_H)
+#include <expat_config.h>
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+#include <string.h> /* memset(), memcpy() */
+#include <assert.h>
+
+#include "expat.h"
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) (const wchar_t)x
+#define XML_L(x) L ## x
+#else
+#define XML_T(x) (const unsigned short)x
+#define XML_L(x) x
+#endif
+
+#else
+
+#define XML_T(x) x
+#define XML_L(x) x
+
+#endif
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+/* Handle the case where memmove() doesn't exist. */
+#ifndef HAVE_MEMMOVE
+#ifdef HAVE_BCOPY
+#define memmove(d,s,l) bcopy((s),(d),(l))
+#else
+#error memmove does not exist on this platform, nor is a substitute available
+#endif /* HAVE_BCOPY */
+#endif /* HAVE_MEMMOVE */
+
+#include "internal.h"
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+ KEY name;
+} NAMED;
+
+typedef struct {
+ NAMED **v;
+ unsigned char power;
+ size_t size;
+ size_t used;
+ const XML_Memory_Handling_Suite *mem;
+} HASH_TABLE;
+
+/* Basic character hash algorithm, taken from Python's string hash:
+ h = h * 1000003 ^ character, the constant being a prime number.
+
+*/
+#ifdef XML_UNICODE
+#define CHAR_HASH(h, c) \
+ (((h) * 0xF4243) ^ (unsigned short)(c))
+#else
+#define CHAR_HASH(h, c) \
+ (((h) * 0xF4243) ^ (unsigned char)(c))
+#endif
+
+/* For probing (after a collision) we need a step size relative prime
+ to the hash table size, which is a power of 2. We use double-hashing,
+ since we can calculate a second hash value cheaply by taking those bits
+ of the first hash value that were discarded (masked out) when the table
+ index was calculated: index = hash & mask, where mask = table->size - 1.
+ We limit the maximum step size to table->size / 4 (mask >> 2) and make
+ it odd, since odd numbers are always relative prime to a power of 2.
+*/
+#define SECOND_HASH(hash, mask, power) \
+ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power) \
+ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
+
+typedef struct {
+ NAMED **p;
+ NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_ATTS_VERSION 0xFFFFFFFF
+#define INIT_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+ struct prefix *prefix;
+ struct binding *nextTagBinding;
+ struct binding *prevPrefixBinding;
+ const struct attribute_id *attId;
+ XML_Char *uri;
+ int uriLen;
+ int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+ const XML_Char *name;
+ BINDING *binding;
+} PREFIX;
+
+typedef struct {
+ const XML_Char *str;
+ const XML_Char *localPart;
+ const XML_Char *prefix;
+ int strLen;
+ int uriLen;
+ int prefixLen;
+} TAG_NAME;
+
+/* TAG represents an open element.
+ The name of the element is stored in both the document and API
+ encodings. The memory buffer 'buf' is a separately-allocated
+ memory area which stores the name. During the XML_Parse()/
+ XMLParseBuffer() when the element is open, the memory for the 'raw'
+ version of the name (in the document encoding) is shared with the
+ document buffer. If the element is open across calls to
+ XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
+ contain the 'raw' name as well.
+
+ A parser re-uses these structures, maintaining a list of allocated
+ TAG objects in a free list.
+*/
+typedef struct tag {
+ struct tag *parent; /* parent of this element */
+ const char *rawName; /* tagName in the original encoding */
+ int rawNameLength;
+ TAG_NAME name; /* tagName in the API encoding */
+ char *buf; /* buffer for name components */
+ char *bufEnd; /* end of the buffer */
+ BINDING *bindings;
+} TAG;
+
+typedef struct {
+ const XML_Char *name;
+ const XML_Char *textPtr;
+ int textLen; /* length in XML_Chars */
+ int processed; /* # of processed bytes - when suspended */
+ const XML_Char *systemId;
+ const XML_Char *base;
+ const XML_Char *publicId;
+ const XML_Char *notation;
+ XML_Bool open;
+ XML_Bool is_param;
+ XML_Bool is_internal; /* true if declared in internal subset outside PE */
+} ENTITY;
+
+typedef struct {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ const XML_Char * name;
+ int firstchild;
+ int lastchild;
+ int childcnt;
+ int nextsib;
+} CONTENT_SCAFFOLD;
+
+#define INIT_SCAFFOLD_ELEMENTS 32
+
+typedef struct block {
+ struct block *next;
+ int size;
+ XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+ BLOCK *blocks;
+ BLOCK *freeBlocks;
+ const XML_Char *end;
+ XML_Char *ptr;
+ XML_Char *start;
+ const XML_Memory_Handling_Suite *mem;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+ an attribute has been specified. */
+typedef struct attribute_id {
+ XML_Char *name;
+ PREFIX *prefix;
+ XML_Bool maybeTokenized;
+ XML_Bool xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+ const ATTRIBUTE_ID *id;
+ XML_Bool isCdata;
+ const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+ unsigned long version;
+ unsigned long hash;
+ const XML_Char *uriName;
+} NS_ATT;
+
+typedef struct {
+ const XML_Char *name;
+ PREFIX *prefix;
+ const ATTRIBUTE_ID *idAtt;
+ int nDefaultAtts;
+ int allocDefaultAtts;
+ DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+ HASH_TABLE generalEntities;
+ HASH_TABLE elementTypes;
+ HASH_TABLE attributeIds;
+ HASH_TABLE prefixes;
+ STRING_POOL pool;
+ STRING_POOL entityValuePool;
+ /* false once a parameter entity reference has been skipped */
+ XML_Bool keepProcessing;
+ /* true once an internal or external PE reference has been encountered;
+ this includes the reference to an external subset */
+ XML_Bool hasParamEntityRefs;
+ XML_Bool standalone;
+#ifdef XML_DTD
+ /* indicates if external PE has been read */
+ XML_Bool paramEntityRead;
+ HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+ PREFIX defaultPrefix;
+ /* === scaffolding for building content model === */
+ XML_Bool in_eldecl;
+ CONTENT_SCAFFOLD *scaffold;
+ unsigned contentStringLen;
+ unsigned scaffSize;
+ unsigned scaffCount;
+ int scaffLevel;
+ int *scaffIndex;
+} DTD;
+
+typedef struct open_internal_entity {
+ const char *internalEventPtr;
+ const char *internalEventEndPtr;
+ struct open_internal_entity *next;
+ ENTITY *entity;
+ int startTagLevel;
+ XML_Bool betweenDecl; /* WFC: PE Between Declarations */
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+static Processor externalParEntProcessor;
+static Processor externalParEntInitProcessor;
+static Processor entityValueProcessor;
+static Processor entityValueInitProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+static Processor internalEntityProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+ const char *s, const char *next);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+ const char *end, int tok, const char *next, const char **nextPtr,
+ XML_Bool haveMore);
+static enum XML_Error
+processInternalEntity(XML_Parser parser, ENTITY *entity,
+ XML_Bool betweenDecl);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+ const char *start, const char *end, const char **endPtr,
+ XML_Bool haveMore);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+ const char *end, const char **nextPtr, XML_Bool haveMore);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+ const char *end, const char **nextPtr, XML_Bool haveMore);
+#endif /* XML_DTD */
+
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+ const XML_Char *uri, BINDING **bindingsPtr);
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
+ XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+ const char *, const char *, STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+ const char *, const char *, STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+
+static const XML_Char * getContext(XML_Parser parser);
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context);
+
+static void FASTCALL normalizePublicId(XML_Char *s);
+
+static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
+/* do not call if parentParser != NULL */
+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+static int
+copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void FASTCALL
+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL hashTableClear(HASH_TABLE *);
+static void FASTCALL hashTableDestroy(HASH_TABLE *);
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
+
+static void FASTCALL
+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolClear(STRING_POOL *);
+static void FASTCALL poolDestroy(STRING_POOL *);
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s);
+
+static int FASTCALL nextScaffoldPart(XML_Parser parser);
+static XML_Content * build_model(XML_Parser parser);
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser, const ENCODING *enc,
+ const char *ptr, const char *end);
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep,
+ DTD *dtd);
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+ (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+ ? 0 \
+ : ((*((pool)->ptr)++ = c), 1))
+
+struct XML_ParserStruct {
+ /* The first member must be userData so that the XML_GetUserData
+ macro works. */
+ void *m_userData;
+ void *m_handlerArg;
+ char *m_buffer;
+ const XML_Memory_Handling_Suite m_mem;
+ /* first character to be parsed */
+ const char *m_bufferPtr;
+ /* past last character to be parsed */
+ char *m_bufferEnd;
+ /* allocated end of buffer */
+ const char *m_bufferLim;
+ XML_Index m_parseEndByteIndex;
+ const char *m_parseEndPtr;
+ XML_Char *m_dataBuf;
+ XML_Char *m_dataBufEnd;
+ XML_StartElementHandler m_startElementHandler;
+ XML_EndElementHandler m_endElementHandler;
+ XML_CharacterDataHandler m_characterDataHandler;
+ XML_ProcessingInstructionHandler m_processingInstructionHandler;
+ XML_CommentHandler m_commentHandler;
+ XML_StartCdataSectionHandler m_startCdataSectionHandler;
+ XML_EndCdataSectionHandler m_endCdataSectionHandler;
+ XML_DefaultHandler m_defaultHandler;
+ XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+ XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+ XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+ XML_NotationDeclHandler m_notationDeclHandler;
+ XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+ XML_NotStandaloneHandler m_notStandaloneHandler;
+ XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+ XML_Parser m_externalEntityRefHandlerArg;
+ XML_SkippedEntityHandler m_skippedEntityHandler;
+ XML_UnknownEncodingHandler m_unknownEncodingHandler;
+ XML_ElementDeclHandler m_elementDeclHandler;
+ XML_AttlistDeclHandler m_attlistDeclHandler;
+ XML_EntityDeclHandler m_entityDeclHandler;
+ XML_XmlDeclHandler m_xmlDeclHandler;
+ const ENCODING *m_encoding;
+ INIT_ENCODING m_initEncoding;
+ const ENCODING *m_internalEncoding;
+ const XML_Char *m_protocolEncodingName;
+ XML_Bool m_ns;
+ XML_Bool m_ns_triplets;
+ void *m_unknownEncodingMem;
+ void *m_unknownEncodingData;
+ void *m_unknownEncodingHandlerData;
+ void (XMLCALL *m_unknownEncodingRelease)(void *);
+ PROLOG_STATE m_prologState;
+ Processor *m_processor;
+ enum XML_Error m_errorCode;
+ const char *m_eventPtr;
+ const char *m_eventEndPtr;
+ const char *m_positionPtr;
+ OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+ OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
+ XML_Bool m_defaultExpandInternalEntities;
+ int m_tagLevel;
+ ENTITY *m_declEntity;
+ const XML_Char *m_doctypeName;
+ const XML_Char *m_doctypeSysid;
+ const XML_Char *m_doctypePubid;
+ const XML_Char *m_declAttributeType;
+ const XML_Char *m_declNotationName;
+ const XML_Char *m_declNotationPublicId;
+ ELEMENT_TYPE *m_declElementType;
+ ATTRIBUTE_ID *m_declAttributeId;
+ XML_Bool m_declAttributeIsCdata;
+ XML_Bool m_declAttributeIsId;
+ DTD *m_dtd;
+ const XML_Char *m_curBase;
+ TAG *m_tagStack;
+ TAG *m_freeTagList;
+ BINDING *m_inheritedBindings;
+ BINDING *m_freeBindingList;
+ int m_attsSize;
+ int m_nSpecifiedAtts;
+ int m_idAttIndex;
+ ATTRIBUTE *m_atts;
+ NS_ATT *m_nsAtts;
+ unsigned long m_nsAttsVersion;
+ unsigned char m_nsAttsPower;
+ POSITION m_position;
+ STRING_POOL m_tempPool;
+ STRING_POOL m_temp2Pool;
+ char *m_groupConnector;
+ unsigned int m_groupSize;
+ XML_Char m_namespaceSeparator;
+ XML_Parser m_parentParser;
+ XML_ParsingStatus m_parsingStatus;
+#ifdef XML_DTD
+ XML_Bool m_isParamEntity;
+ XML_Bool m_useForeignDTD;
+ enum XML_ParamEntityParsing m_paramEntityParsing;
+#endif
+};
+
+#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (parser->m_mem.free_fcn((p)))
+
+#define userData (parser->m_userData)
+#define handlerArg (parser->m_handlerArg)
+#define startElementHandler (parser->m_startElementHandler)
+#define endElementHandler (parser->m_endElementHandler)
+#define characterDataHandler (parser->m_characterDataHandler)
+#define processingInstructionHandler \
+ (parser->m_processingInstructionHandler)
+#define commentHandler (parser->m_commentHandler)
+#define startCdataSectionHandler \
+ (parser->m_startCdataSectionHandler)
+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
+#define defaultHandler (parser->m_defaultHandler)
+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler \
+ (parser->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (parser->m_notationDeclHandler)
+#define startNamespaceDeclHandler \
+ (parser->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (parser->m_notStandaloneHandler)
+#define externalEntityRefHandler \
+ (parser->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg \
+ (parser->m_externalEntityRefHandlerArg)
+#define internalEntityRefHandler \
+ (parser->m_internalEntityRefHandler)
+#define skippedEntityHandler (parser->m_skippedEntityHandler)
+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
+#define elementDeclHandler (parser->m_elementDeclHandler)
+#define attlistDeclHandler (parser->m_attlistDeclHandler)
+#define entityDeclHandler (parser->m_entityDeclHandler)
+#define xmlDeclHandler (parser->m_xmlDeclHandler)
+#define encoding (parser->m_encoding)
+#define initEncoding (parser->m_initEncoding)
+#define internalEncoding (parser->m_internalEncoding)
+#define unknownEncodingMem (parser->m_unknownEncodingMem)
+#define unknownEncodingData (parser->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+ (parser->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
+#define protocolEncodingName (parser->m_protocolEncodingName)
+#define ns (parser->m_ns)
+#define ns_triplets (parser->m_ns_triplets)
+#define prologState (parser->m_prologState)
+#define processor (parser->m_processor)
+#define errorCode (parser->m_errorCode)
+#define eventPtr (parser->m_eventPtr)
+#define eventEndPtr (parser->m_eventEndPtr)
+#define positionPtr (parser->m_positionPtr)
+#define position (parser->m_position)
+#define openInternalEntities (parser->m_openInternalEntities)
+#define freeInternalEntities (parser->m_freeInternalEntities)
+#define defaultExpandInternalEntities \
+ (parser->m_defaultExpandInternalEntities)
+#define tagLevel (parser->m_tagLevel)
+#define buffer (parser->m_buffer)
+#define bufferPtr (parser->m_bufferPtr)
+#define bufferEnd (parser->m_bufferEnd)
+#define parseEndByteIndex (parser->m_parseEndByteIndex)
+#define parseEndPtr (parser->m_parseEndPtr)
+#define bufferLim (parser->m_bufferLim)
+#define dataBuf (parser->m_dataBuf)
+#define dataBufEnd (parser->m_dataBufEnd)
+#define _dtd (parser->m_dtd)
+#define curBase (parser->m_curBase)
+#define declEntity (parser->m_declEntity)
+#define doctypeName (parser->m_doctypeName)
+#define doctypeSysid (parser->m_doctypeSysid)
+#define doctypePubid (parser->m_doctypePubid)
+#define declAttributeType (parser->m_declAttributeType)
+#define declNotationName (parser->m_declNotationName)
+#define declNotationPublicId (parser->m_declNotationPublicId)
+#define declElementType (parser->m_declElementType)
+#define declAttributeId (parser->m_declAttributeId)
+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
+#define declAttributeIsId (parser->m_declAttributeIsId)
+#define freeTagList (parser->m_freeTagList)
+#define freeBindingList (parser->m_freeBindingList)
+#define inheritedBindings (parser->m_inheritedBindings)
+#define tagStack (parser->m_tagStack)
+#define atts (parser->m_atts)
+#define attsSize (parser->m_attsSize)
+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
+#define idAttIndex (parser->m_idAttIndex)
+#define nsAtts (parser->m_nsAtts)
+#define nsAttsVersion (parser->m_nsAttsVersion)
+#define nsAttsPower (parser->m_nsAttsPower)
+#define tempPool (parser->m_tempPool)
+#define temp2Pool (parser->m_temp2Pool)
+#define groupConnector (parser->m_groupConnector)
+#define groupSize (parser->m_groupSize)
+#define namespaceSeparator (parser->m_namespaceSeparator)
+#define parentParser (parser->m_parentParser)
+#define ps_parsing (parser->m_parsingStatus.parsing)
+#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
+#ifdef XML_DTD
+#define isParamEntity (parser->m_isParamEntity)
+#define useForeignDTD (parser->m_useForeignDTD)
+#define paramEntityParsing (parser->m_paramEntityParsing)
+#endif /* XML_DTD */
+
+XML_Parser XMLCALL
+XML_ParserCreate(const XML_Char *encodingName)
+{
+ return XML_ParserCreate_MM(encodingName, NULL, NULL);
+}
+
+XML_Parser XMLCALL
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+ XML_Char tmp[2];
+ *tmp = nsSep;
+ return XML_ParserCreate_MM(encodingName, NULL, tmp);
+}
+
+static const XML_Char implicitContext[] = {
+ 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+ 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+};
+
+XML_Parser XMLCALL
+XML_ParserCreate_MM(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep)
+{
+ XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
+ if (parser != NULL && ns) {
+ /* implicit context only set for root parser, since child
+ parsers (i.e. external entity parsers) will inherit it
+ */
+ if (!setContext(parser, implicitContext)) {
+ XML_ParserFree(parser);
+ return NULL;
+ }
+ }
+ return parser;
+}
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep,
+ DTD *dtd)
+{
+ XML_Parser parser;
+
+ if (memsuite) {
+ XML_Memory_Handling_Suite *mtemp;
+ parser = (XML_Parser)
+ memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+ if (parser != NULL) {
+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+ mtemp->malloc_fcn = memsuite->malloc_fcn;
+ mtemp->realloc_fcn = memsuite->realloc_fcn;
+ mtemp->free_fcn = memsuite->free_fcn;
+ }
+ }
+ else {
+ XML_Memory_Handling_Suite *mtemp;
+ parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
+ if (parser != NULL) {
+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+ mtemp->malloc_fcn = malloc;
+ mtemp->realloc_fcn = realloc;
+ mtemp->free_fcn = free;
+ }
+ }
+
+ if (!parser)
+ return parser;
+
+ buffer = NULL;
+ bufferLim = NULL;
+
+ attsSize = INIT_ATTS_SIZE;
+ atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
+ if (atts == NULL) {
+ FREE(parser);
+ return NULL;
+ }
+ dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+ if (dataBuf == NULL) {
+ FREE(atts);
+ FREE(parser);
+ return NULL;
+ }
+ dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+ if (dtd)
+ _dtd = dtd;
+ else {
+ _dtd = dtdCreate(&parser->m_mem);
+ if (_dtd == NULL) {
+ FREE(dataBuf);
+ FREE(atts);
+ FREE(parser);
+ return NULL;
+ }
+ }
+
+ freeBindingList = NULL;
+ freeTagList = NULL;
+ freeInternalEntities = NULL;
+
+ groupSize = 0;
+ groupConnector = NULL;
+
+ unknownEncodingHandler = NULL;
+ unknownEncodingHandlerData = NULL;
+
+ namespaceSeparator = '!';
+ ns = XML_FALSE;
+ ns_triplets = XML_FALSE;
+
+ nsAtts = NULL;
+ nsAttsVersion = 0;
+ nsAttsPower = 0;
+
+ poolInit(&tempPool, &(parser->m_mem));
+ poolInit(&temp2Pool, &(parser->m_mem));
+ parserInit(parser, encodingName);
+
+ if (encodingName && !protocolEncodingName) {
+ XML_ParserFree(parser);
+ return NULL;
+ }
+
+ if (nameSep) {
+ ns = XML_TRUE;
+ internalEncoding = XmlGetInternalEncodingNS();
+ namespaceSeparator = *nameSep;
+ }
+ else {
+ internalEncoding = XmlGetInternalEncoding();
+ }
+
+ return parser;
+}
+
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName)
+{
+ processor = prologInitProcessor;
+ XmlPrologStateInit(&prologState);
+ protocolEncodingName = (encodingName != NULL
+ ? poolCopyString(&tempPool, encodingName)
+ : NULL);
+ curBase = NULL;
+ XmlInitEncoding(&initEncoding, &encoding, 0);
+ userData = NULL;
+ handlerArg = NULL;
+ startElementHandler = NULL;
+ endElementHandler = NULL;
+ characterDataHandler = NULL;
+ processingInstructionHandler = NULL;
+ commentHandler = NULL;
+ startCdataSectionHandler = NULL;
+ endCdataSectionHandler = NULL;
+ defaultHandler = NULL;
+ startDoctypeDeclHandler = NULL;
+ endDoctypeDeclHandler = NULL;
+ unparsedEntityDeclHandler = NULL;
+ notationDeclHandler = NULL;
+ startNamespaceDeclHandler = NULL;
+ endNamespaceDeclHandler = NULL;
+ notStandaloneHandler = NULL;
+ externalEntityRefHandler = NULL;
+ externalEntityRefHandlerArg = parser;
+ skippedEntityHandler = NULL;
+ elementDeclHandler = NULL;
+ attlistDeclHandler = NULL;
+ entityDeclHandler = NULL;
+ xmlDeclHandler = NULL;
+ bufferPtr = buffer;
+ bufferEnd = buffer;
+ parseEndByteIndex = 0;
+ parseEndPtr = NULL;
+ declElementType = NULL;
+ declAttributeId = NULL;
+ declEntity = NULL;
+ doctypeName = NULL;
+ doctypeSysid = NULL;
+ doctypePubid = NULL;
+ declAttributeType = NULL;
+ declNotationName = NULL;
+ declNotationPublicId = NULL;
+ declAttributeIsCdata = XML_FALSE;
+ declAttributeIsId = XML_FALSE;
+ memset(&position, 0, sizeof(POSITION));
+ errorCode = XML_ERROR_NONE;
+ eventPtr = NULL;
+ eventEndPtr = NULL;
+ positionPtr = NULL;
+ openInternalEntities = NULL;
+ defaultExpandInternalEntities = XML_TRUE;
+ tagLevel = 0;
+ tagStack = NULL;
+ inheritedBindings = NULL;
+ nSpecifiedAtts = 0;
+ unknownEncodingMem = NULL;
+ unknownEncodingRelease = NULL;
+ unknownEncodingData = NULL;
+ parentParser = NULL;
+ ps_parsing = XML_INITIALIZED;
+#ifdef XML_DTD
+ isParamEntity = XML_FALSE;
+ useForeignDTD = XML_FALSE;
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+/* moves list of bindings to freeBindingList */
+static void FASTCALL
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
+{
+ while (bindings) {
+ BINDING *b = bindings;
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ }
+}
+
+XML_Bool XMLCALL
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
+{
+ TAG *tStk;
+ OPEN_INTERNAL_ENTITY *openEntityList;
+ if (parentParser)
+ return XML_FALSE;
+ /* move tagStack to freeTagList */
+ tStk = tagStack;
+ while (tStk) {
+ TAG *tag = tStk;
+ tStk = tStk->parent;
+ tag->parent = freeTagList;
+ moveToFreeBindingList(parser, tag->bindings);
+ tag->bindings = NULL;
+ freeTagList = tag;
+ }
+ /* move openInternalEntities to freeInternalEntities */
+ openEntityList = openInternalEntities;
+ while (openEntityList) {
+ OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
+ openEntityList = openEntity->next;
+ openEntity->next = freeInternalEntities;
+ freeInternalEntities = openEntity;
+ }
+ moveToFreeBindingList(parser, inheritedBindings);
+ FREE(unknownEncodingMem);
+ if (unknownEncodingRelease)
+ unknownEncodingRelease(unknownEncodingData);
+ poolClear(&tempPool);
+ poolClear(&temp2Pool);
+ parserInit(parser, encodingName);
+ dtdReset(_dtd, &parser->m_mem);
+ return setContext(parser, implicitContext);
+}
+
+enum XML_Status XMLCALL
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+ /* Block after XML_Parse()/XML_ParseBuffer() has been called.
+ XXX There's no way for the caller to determine which of the
+ XXX possible error cases caused the XML_STATUS_ERROR return.
+ */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return XML_STATUS_ERROR;
+ if (encodingName == NULL)
+ protocolEncodingName = NULL;
+ else {
+ protocolEncodingName = poolCopyString(&tempPool, encodingName);
+ if (!protocolEncodingName)
+ return XML_STATUS_ERROR;
+ }
+ return XML_STATUS_OK;
+}
+
+XML_Parser XMLCALL
+XML_ExternalEntityParserCreate(XML_Parser oldParser,
+ const XML_Char *context,
+ const XML_Char *encodingName)
+{
+ XML_Parser parser = oldParser;
+ DTD *newDtd = NULL;
+ DTD *oldDtd = _dtd;
+ XML_StartElementHandler oldStartElementHandler = startElementHandler;
+ XML_EndElementHandler oldEndElementHandler = endElementHandler;
+ XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler
+ = processingInstructionHandler;
+ XML_CommentHandler oldCommentHandler = commentHandler;
+ XML_StartCdataSectionHandler oldStartCdataSectionHandler
+ = startCdataSectionHandler;
+ XML_EndCdataSectionHandler oldEndCdataSectionHandler
+ = endCdataSectionHandler;
+ XML_DefaultHandler oldDefaultHandler = defaultHandler;
+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
+ = unparsedEntityDeclHandler;
+ XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
+ = startNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
+ = endNamespaceDeclHandler;
+ XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler
+ = externalEntityRefHandler;
+ XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
+ XML_UnknownEncodingHandler oldUnknownEncodingHandler
+ = unknownEncodingHandler;
+ XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
+ XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
+ XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
+ XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
+ ELEMENT_TYPE * oldDeclElementType = declElementType;
+
+ void *oldUserData = userData;
+ void *oldHandlerArg = handlerArg;
+ XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+ XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+ enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
+ int oldInEntityValue = prologState.inEntityValue;
+#endif
+ XML_Bool oldns_triplets = ns_triplets;
+
+#ifdef XML_DTD
+ if (!context)
+ newDtd = oldDtd;
+#endif /* XML_DTD */
+
+ /* Note that the magical uses of the pre-processor to make field
+ access look more like C++ require that `parser' be overwritten
+ here. This makes this function more painful to follow than it
+ would be otherwise.
+ */
+ if (ns) {
+ XML_Char tmp[2];
+ *tmp = namespaceSeparator;
+ parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
+ }
+ else {
+ parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
+ }
+
+ if (!parser)
+ return NULL;
+
+ startElementHandler = oldStartElementHandler;
+ endElementHandler = oldEndElementHandler;
+ characterDataHandler = oldCharacterDataHandler;
+ processingInstructionHandler = oldProcessingInstructionHandler;
+ commentHandler = oldCommentHandler;
+ startCdataSectionHandler = oldStartCdataSectionHandler;
+ endCdataSectionHandler = oldEndCdataSectionHandler;
+ defaultHandler = oldDefaultHandler;
+ unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+ notationDeclHandler = oldNotationDeclHandler;
+ startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+ endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+ notStandaloneHandler = oldNotStandaloneHandler;
+ externalEntityRefHandler = oldExternalEntityRefHandler;
+ skippedEntityHandler = oldSkippedEntityHandler;
+ unknownEncodingHandler = oldUnknownEncodingHandler;
+ elementDeclHandler = oldElementDeclHandler;
+ attlistDeclHandler = oldAttlistDeclHandler;
+ entityDeclHandler = oldEntityDeclHandler;
+ xmlDeclHandler = oldXmlDeclHandler;
+ declElementType = oldDeclElementType;
+ userData = oldUserData;
+ if (oldUserData == oldHandlerArg)
+ handlerArg = userData;
+ else
+ handlerArg = parser;
+ if (oldExternalEntityRefHandlerArg != oldParser)
+ externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+ defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+ ns_triplets = oldns_triplets;
+ parentParser = oldParser;
+#ifdef XML_DTD
+ paramEntityParsing = oldParamEntityParsing;
+ prologState.inEntityValue = oldInEntityValue;
+ if (context) {
+#endif /* XML_DTD */
+ if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
+ || !setContext(parser, context)) {
+ XML_ParserFree(parser);
+ return NULL;
+ }
+ processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+ }
+ else {
+ /* The DTD instance referenced by _dtd is shared between the document's
+ root parser and external PE parsers, therefore one does not need to
+ call setContext. In addition, one also *must* not call setContext,
+ because this would overwrite existing prefix->binding pointers in
+ _dtd with ones that get destroyed with the external PE parser.
+ This would leave those prefixes with dangling pointers.
+ */
+ isParamEntity = XML_TRUE;
+ XmlPrologStateInitExternalEntity(&prologState);
+ processor = externalParEntInitProcessor;
+ }
+#endif /* XML_DTD */
+ return parser;
+}
+
+static void FASTCALL
+destroyBindings(BINDING *bindings, XML_Parser parser)
+{
+ for (;;) {
+ BINDING *b = bindings;
+ if (!b)
+ break;
+ bindings = b->nextTagBinding;
+ FREE(b->uri);
+ FREE(b);
+ }
+}
+
+void XMLCALL
+XML_ParserFree(XML_Parser parser)
+{
+ TAG *tagList;
+ OPEN_INTERNAL_ENTITY *entityList;
+ if (parser == NULL)
+ return;
+ /* free tagStack and freeTagList */
+ tagList = tagStack;
+ for (;;) {
+ TAG *p;
+ if (tagList == NULL) {
+ if (freeTagList == NULL)
+ break;
+ tagList = freeTagList;
+ freeTagList = NULL;
+ }
+ p = tagList;
+ tagList = tagList->parent;
+ FREE(p->buf);
+ destroyBindings(p->bindings, parser);
+ FREE(p);
+ }
+ /* free openInternalEntities and freeInternalEntities */
+ entityList = openInternalEntities;
+ for (;;) {
+ OPEN_INTERNAL_ENTITY *openEntity;
+ if (entityList == NULL) {
+ if (freeInternalEntities == NULL)
+ break;
+ entityList = freeInternalEntities;
+ freeInternalEntities = NULL;
+ }
+ openEntity = entityList;
+ entityList = entityList->next;
+ FREE(openEntity);
+ }
+
+ destroyBindings(freeBindingList, parser);
+ destroyBindings(inheritedBindings, parser);
+ poolDestroy(&tempPool);
+ poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+ /* external parameter entity parsers share the DTD structure
+ parser->m_dtd with the root parser, so we must not destroy it
+ */
+ if (!isParamEntity && _dtd)
+#else
+ if (_dtd)
+#endif /* XML_DTD */
+ dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
+ FREE((void *)atts);
+ FREE(groupConnector);
+ FREE(buffer);
+ FREE(dataBuf);
+ FREE(nsAtts);
+ FREE(unknownEncodingMem);
+ if (unknownEncodingRelease)
+ unknownEncodingRelease(unknownEncodingData);
+ FREE(parser);
+}
+
+void XMLCALL
+XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+ handlerArg = parser;
+}
+
+enum XML_Error XMLCALL
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
+{
+#ifdef XML_DTD
+ /* block after XML_Parse()/XML_ParseBuffer() has been called */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
+ useForeignDTD = useDTD;
+ return XML_ERROR_NONE;
+#else
+ return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
+#endif
+}
+
+void XMLCALL
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
+{
+ /* block after XML_Parse()/XML_ParseBuffer() has been called */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return;
+ ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
+}
+
+void XMLCALL
+XML_SetUserData(XML_Parser parser, void *p)
+{
+ if (handlerArg == userData)
+ handlerArg = userData = p;
+ else
+ userData = p;
+}
+
+enum XML_Status XMLCALL
+XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+ if (p) {
+ p = poolCopyString(&_dtd->pool, p);
+ if (!p)
+ return XML_STATUS_ERROR;
+ curBase = p;
+ }
+ else
+ curBase = NULL;
+ return XML_STATUS_OK;
+}
+
+const XML_Char * XMLCALL
+XML_GetBase(XML_Parser parser)
+{
+ return curBase;
+}
+
+int XMLCALL
+XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+ return nSpecifiedAtts;
+}
+
+int XMLCALL
+XML_GetIdAttributeIndex(XML_Parser parser)
+{
+ return idAttIndex;
+}
+
+void XMLCALL
+XML_SetElementHandler(XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end)
+{
+ startElementHandler = start;
+ endElementHandler = end;
+}
+
+void XMLCALL
+XML_SetStartElementHandler(XML_Parser parser,
+ XML_StartElementHandler start) {
+ startElementHandler = start;
+}
+
+void XMLCALL
+XML_SetEndElementHandler(XML_Parser parser,
+ XML_EndElementHandler end) {
+ endElementHandler = end;
+}
+
+void XMLCALL
+XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler)
+{
+ characterDataHandler = handler;
+}
+
+void XMLCALL
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler)
+{
+ processingInstructionHandler = handler;
+}
+
+void XMLCALL
+XML_SetCommentHandler(XML_Parser parser,
+ XML_CommentHandler handler)
+{
+ commentHandler = handler;
+}
+
+void XMLCALL
+XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end)
+{
+ startCdataSectionHandler = start;
+ endCdataSectionHandler = end;
+}
+
+void XMLCALL
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start) {
+ startCdataSectionHandler = start;
+}
+
+void XMLCALL
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end) {
+ endCdataSectionHandler = end;
+}
+
+void XMLCALL
+XML_SetDefaultHandler(XML_Parser parser,
+ XML_DefaultHandler handler)
+{
+ defaultHandler = handler;
+ defaultExpandInternalEntities = XML_FALSE;
+}
+
+void XMLCALL
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+ XML_DefaultHandler handler)
+{
+ defaultHandler = handler;
+ defaultExpandInternalEntities = XML_TRUE;
+}
+
+void XMLCALL
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end)
+{
+ startDoctypeDeclHandler = start;
+ endDoctypeDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start) {
+ startDoctypeDeclHandler = start;
+}
+
+void XMLCALL
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+ XML_EndDoctypeDeclHandler end) {
+ endDoctypeDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler)
+{
+ unparsedEntityDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetNotationDeclHandler(XML_Parser parser,
+ XML_NotationDeclHandler handler)
+{
+ notationDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end)
+{
+ startNamespaceDeclHandler = start;
+ endNamespaceDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start) {
+ startNamespaceDeclHandler = start;
+}
+
+void XMLCALL
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end) {
+ endNamespaceDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler)
+{
+ notStandaloneHandler = handler;
+}
+
+void XMLCALL
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler)
+{
+ externalEntityRefHandler = handler;
+}
+
+void XMLCALL
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+ if (arg)
+ externalEntityRefHandlerArg = (XML_Parser)arg;
+ else
+ externalEntityRefHandlerArg = parser;
+}
+
+void XMLCALL
+XML_SetSkippedEntityHandler(XML_Parser parser,
+ XML_SkippedEntityHandler handler)
+{
+ skippedEntityHandler = handler;
+}
+
+void XMLCALL
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *data)
+{
+ unknownEncodingHandler = handler;
+ unknownEncodingHandlerData = data;
+}
+
+void XMLCALL
+XML_SetElementDeclHandler(XML_Parser parser,
+ XML_ElementDeclHandler eldecl)
+{
+ elementDeclHandler = eldecl;
+}
+
+void XMLCALL
+XML_SetAttlistDeclHandler(XML_Parser parser,
+ XML_AttlistDeclHandler attdecl)
+{
+ attlistDeclHandler = attdecl;
+}
+
+void XMLCALL
+XML_SetEntityDeclHandler(XML_Parser parser,
+ XML_EntityDeclHandler handler)
+{
+ entityDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetXmlDeclHandler(XML_Parser parser,
+ XML_XmlDeclHandler handler) {
+ xmlDeclHandler = handler;
+}
+
+int XMLCALL
+XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing peParsing)
+{
+ /* block after XML_Parse()/XML_ParseBuffer() has been called */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return 0;
+#ifdef XML_DTD
+ paramEntityParsing = peParsing;
+ return 1;
+#else
+ return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+enum XML_Status XMLCALL
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ errorCode = XML_ERROR_SUSPENDED;
+ return XML_STATUS_ERROR;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return XML_STATUS_ERROR;
+ default:
+ ps_parsing = XML_PARSING;
+ }
+
+ if (len == 0) {
+ ps_finalBuffer = (XML_Bool)isFinal;
+ if (!isFinal)
+ return XML_STATUS_OK;
+ positionPtr = bufferPtr;
+ parseEndPtr = bufferEnd;
+
+ /* If data are left over from last buffer, and we now know that these
+ data are the final chunk of input, then we have to check them again
+ to detect errors based on that fact.
+ */
+ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+
+ if (errorCode == XML_ERROR_NONE) {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ positionPtr = bufferPtr;
+ return XML_STATUS_SUSPENDED;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ ps_parsing = XML_FINISHED;
+ /* fall through */
+ default:
+ return XML_STATUS_OK;
+ }
+ }
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+#ifndef XML_CONTEXT_BYTES
+ else if (bufferPtr == bufferEnd) {
+ const char *end;
+ int nLeftOver;
+ enum XML_Error result;
+ parseEndByteIndex += len;
+ positionPtr = s;
+ ps_finalBuffer = (XML_Bool)isFinal;
+
+ errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ else {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ result = XML_STATUS_SUSPENDED;
+ break;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ result = XML_STATUS_OK;
+ if (isFinal) {
+ ps_parsing = XML_FINISHED;
+ return result;
+ }
+ }
+ }
+
+ XmlUpdatePosition(encoding, positionPtr, end, &position);
+ nLeftOver = s + len - end;
+ if (nLeftOver) {
+ if (buffer == NULL || nLeftOver > bufferLim - buffer) {
+ /* FIXME avoid integer overflow */
+ char *temp;
+ temp = (buffer == NULL
+ ? (char *)MALLOC(len * 2)
+ : (char *)REALLOC(buffer, len * 2));
+ if (temp == NULL) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return XML_STATUS_ERROR;
+ }
+ buffer = temp;
+ if (!buffer) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ eventPtr = eventEndPtr = NULL;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ bufferLim = buffer + len * 2;
+ }
+ memcpy(buffer, end, nLeftOver);
+ }
+ bufferPtr = buffer;
+ bufferEnd = buffer + nLeftOver;
+ positionPtr = bufferPtr;
+ parseEndPtr = bufferEnd;
+ eventPtr = bufferPtr;
+ eventEndPtr = bufferPtr;
+ return result;
+ }
+#endif /* not defined XML_CONTEXT_BYTES */
+ else {
+ void *buff = XML_GetBuffer(parser, len);
+ if (buff == NULL)
+ return XML_STATUS_ERROR;
+ else {
+ memcpy(buff, s, len);
+ return XML_ParseBuffer(parser, len, isFinal);
+ }
+ }
+}
+
+enum XML_Status XMLCALL
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+ const char *start;
+ enum XML_Status result = XML_STATUS_OK;
+
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ errorCode = XML_ERROR_SUSPENDED;
+ return XML_STATUS_ERROR;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return XML_STATUS_ERROR;
+ default:
+ ps_parsing = XML_PARSING;
+ }
+
+ start = bufferPtr;
+ positionPtr = start;
+ bufferEnd += len;
+ parseEndPtr = bufferEnd;
+ parseEndByteIndex += len;
+ ps_finalBuffer = (XML_Bool)isFinal;
+
+ errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
+
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ else {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ result = XML_STATUS_SUSPENDED;
+ break;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ if (isFinal) {
+ ps_parsing = XML_FINISHED;
+ return result;
+ }
+ default: ; /* should not happen */
+ }
+ }
+
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ positionPtr = bufferPtr;
+ return result;
+}
+
+void * XMLCALL
+XML_GetBuffer(XML_Parser parser, int len)
+{
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ errorCode = XML_ERROR_SUSPENDED;
+ return NULL;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return NULL;
+ default: ;
+ }
+
+ if (len > bufferLim - bufferEnd) {
+ /* FIXME avoid integer overflow */
+ int neededSize = len + (int)(bufferEnd - bufferPtr);
+#ifdef XML_CONTEXT_BYTES
+ int keep = (int)(bufferPtr - buffer);
+
+ if (keep > XML_CONTEXT_BYTES)
+ keep = XML_CONTEXT_BYTES;
+ neededSize += keep;
+#endif /* defined XML_CONTEXT_BYTES */
+ if (neededSize <= bufferLim - buffer) {
+#ifdef XML_CONTEXT_BYTES
+ if (keep < bufferPtr - buffer) {
+ int offset = (int)(bufferPtr - buffer) - keep;
+ memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+ bufferEnd -= offset;
+ bufferPtr -= offset;
+ }
+#else
+ memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+ bufferEnd = buffer + (bufferEnd - bufferPtr);
+ bufferPtr = buffer;
+#endif /* not defined XML_CONTEXT_BYTES */
+ }
+ else {
+ char *newBuf;
+ int bufferSize = (int)(bufferLim - bufferPtr);
+ if (bufferSize == 0)
+ bufferSize = INIT_BUFFER_SIZE;
+ do {
+ bufferSize *= 2;
+ } while (bufferSize < neededSize);
+ newBuf = (char *)MALLOC(bufferSize);
+ if (newBuf == 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+ bufferLim = newBuf + bufferSize;
+#ifdef XML_CONTEXT_BYTES
+ if (bufferPtr) {
+ int keep = (int)(bufferPtr - buffer);
+ if (keep > XML_CONTEXT_BYTES)
+ keep = XML_CONTEXT_BYTES;
+ memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+ FREE(buffer);
+ buffer = newBuf;
+ bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+ bufferPtr = buffer + keep;
+ }
+ else {
+ bufferEnd = newBuf + (bufferEnd - bufferPtr);
+ bufferPtr = buffer = newBuf;
+ }
+#else
+ if (bufferPtr) {
+ memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+ FREE(buffer);
+ }
+ bufferEnd = newBuf + (bufferEnd - bufferPtr);
+ bufferPtr = buffer = newBuf;
+#endif /* not defined XML_CONTEXT_BYTES */
+ }
+ }
+ return bufferEnd;
+}
+
+enum XML_Status XMLCALL
+XML_StopParser(XML_Parser parser, XML_Bool resumable)
+{
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ if (resumable) {
+ errorCode = XML_ERROR_SUSPENDED;
+ return XML_STATUS_ERROR;
+ }
+ ps_parsing = XML_FINISHED;
+ break;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return XML_STATUS_ERROR;
+ default:
+ if (resumable) {
+#ifdef XML_DTD
+ if (isParamEntity) {
+ errorCode = XML_ERROR_SUSPEND_PE;
+ return XML_STATUS_ERROR;
+ }
+#endif
+ ps_parsing = XML_SUSPENDED;
+ }
+ else
+ ps_parsing = XML_FINISHED;
+ }
+ return XML_STATUS_OK;
+}
+
+enum XML_Status XMLCALL
+XML_ResumeParser(XML_Parser parser)
+{
+ enum XML_Status result = XML_STATUS_OK;
+
+ if (ps_parsing != XML_SUSPENDED) {
+ errorCode = XML_ERROR_NOT_SUSPENDED;
+ return XML_STATUS_ERROR;
+ }
+ ps_parsing = XML_PARSING;
+
+ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ else {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ result = XML_STATUS_SUSPENDED;
+ break;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ if (ps_finalBuffer) {
+ ps_parsing = XML_FINISHED;
+ return result;
+ }
+ default: ;
+ }
+ }
+
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ positionPtr = bufferPtr;
+ return result;
+}
+
+void XMLCALL
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
+{
+ assert(status != NULL);
+ *status = parser->m_parsingStatus;
+}
+
+enum XML_Error XMLCALL
+XML_GetErrorCode(XML_Parser parser)
+{
+ return errorCode;
+}
+
+XML_Index XMLCALL
+XML_GetCurrentByteIndex(XML_Parser parser)
+{
+ if (eventPtr)
+ return parseEndByteIndex - (parseEndPtr - eventPtr);
+ return -1;
+}
+
+int XMLCALL
+XML_GetCurrentByteCount(XML_Parser parser)
+{
+ if (eventEndPtr && eventPtr)
+ return (int)(eventEndPtr - eventPtr);
+ return 0;
+}
+
+const char * XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+{
+#ifdef XML_CONTEXT_BYTES
+ if (eventPtr && buffer) {
+ *offset = (int)(eventPtr - buffer);
+ *size = (int)(bufferEnd - buffer);
+ return buffer;
+ }
+#endif /* defined XML_CONTEXT_BYTES */
+ return (char *) 0;
+}
+
+XML_Size XMLCALL
+XML_GetCurrentLineNumber(XML_Parser parser)
+{
+ if (eventPtr && eventPtr >= positionPtr) {
+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+ positionPtr = eventPtr;
+ }
+ return position.lineNumber + 1;
+}
+
+XML_Size XMLCALL
+XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+ if (eventPtr && eventPtr >= positionPtr) {
+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+ positionPtr = eventPtr;
+ }
+ return position.columnNumber;
+}
+
+void XMLCALL
+XML_FreeContentModel(XML_Parser parser, XML_Content *model)
+{
+ FREE(model);
+}
+
+void * XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size)
+{
+ return MALLOC(size);
+}
+
+void * XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
+{
+ return REALLOC(ptr, size);
+}
+
+void XMLCALL
+XML_MemFree(XML_Parser parser, void *ptr)
+{
+ FREE(ptr);
+}
+
+void XMLCALL
+XML_DefaultCurrent(XML_Parser parser)
+{
+ if (defaultHandler) {
+ if (openInternalEntities)
+ reportDefault(parser,
+ internalEncoding,
+ openInternalEntities->internalEventPtr,
+ openInternalEntities->internalEventEndPtr);
+ else
+ reportDefault(parser, encoding, eventPtr, eventEndPtr);
+ }
+}
+
+const XML_LChar * XMLCALL
+XML_ErrorString(enum XML_Error code)
+{
+ static const XML_LChar* const message[] = {
+ 0,
+ XML_L("out of memory"),
+ XML_L("syntax error"),
+ XML_L("no element found"),
+ XML_L("not well-formed (invalid token)"),
+ XML_L("unclosed token"),
+ XML_L("partial character"),
+ XML_L("mismatched tag"),
+ XML_L("duplicate attribute"),
+ XML_L("junk after document element"),
+ XML_L("illegal parameter entity reference"),
+ XML_L("undefined entity"),
+ XML_L("recursive entity reference"),
+ XML_L("asynchronous entity"),
+ XML_L("reference to invalid character number"),
+ XML_L("reference to binary entity"),
+ XML_L("reference to external entity in attribute"),
+ XML_L("XML or text declaration not at start of entity"),
+ XML_L("unknown encoding"),
+ XML_L("encoding specified in XML declaration is incorrect"),
+ XML_L("unclosed CDATA section"),
+ XML_L("error in processing external entity reference"),
+ XML_L("document is not standalone"),
+ XML_L("unexpected parser state - please send a bug report"),
+ XML_L("entity declared in parameter entity"),
+ XML_L("requested feature requires XML_DTD support in Expat"),
+ XML_L("cannot change setting once parsing has begun"),
+ XML_L("unbound prefix"),
+ XML_L("must not undeclare prefix"),
+ XML_L("incomplete markup in parameter entity"),
+ XML_L("XML declaration not well-formed"),
+ XML_L("text declaration not well-formed"),
+ XML_L("illegal character(s) in public id"),
+ XML_L("parser suspended"),
+ XML_L("parser not suspended"),
+ XML_L("parsing aborted"),
+ XML_L("parsing finished"),
+ XML_L("cannot suspend in external parameter entity"),
+ XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
+ XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
+ XML_L("prefix must not be bound to one of the reserved namespace names")
+ };
+ if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+ return message[code];
+ return NULL;
+}
+
+const XML_LChar * XMLCALL
+XML_ExpatVersion(void) {
+
+ /* V1 is used to string-ize the version number. However, it would
+ string-ize the actual version macro *names* unless we get them
+ substituted before being passed to V1. CPP is defined to expand
+ a macro, then rescan for more expansions. Thus, we use V2 to expand
+ the version macros, then CPP will expand the resulting V1() macro
+ with the correct numerals. */
+ /* ### I'm assuming cpp is portable in this respect... */
+
+#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+
+ return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
+
+#undef V1
+#undef V2
+}
+
+XML_Expat_Version XMLCALL
+XML_ExpatVersionInfo(void)
+{
+ XML_Expat_Version version;
+
+ version.major = XML_MAJOR_VERSION;
+ version.minor = XML_MINOR_VERSION;
+ version.micro = XML_MICRO_VERSION;
+
+ return version;
+}
+
+const XML_Feature * XMLCALL
+XML_GetFeatureList(void)
+{
+ static const XML_Feature features[] = {
+ {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
+ sizeof(XML_Char)},
+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
+ sizeof(XML_LChar)},
+#ifdef XML_UNICODE
+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
+#endif
+#ifdef XML_UNICODE_WCHAR_T
+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
+#endif
+#ifdef XML_DTD
+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
+#endif
+#ifdef XML_CONTEXT_BYTES
+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
+ XML_CONTEXT_BYTES},
+#endif
+#ifdef XML_MIN_SIZE
+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
+#endif
+#ifdef XML_NS
+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},
+#endif
+ {XML_FEATURE_END, NULL, 0}
+ };
+
+ return features;
+}
+
+/* Initially tag->rawName always points into the parse buffer;
+ for those TAG instances opened while the current parse buffer was
+ processed, and not yet closed, we need to store tag->rawName in a more
+ permanent location, since the parse buffer is about to be discarded.
+*/
+static XML_Bool
+storeRawNames(XML_Parser parser)
+{
+ TAG *tag = tagStack;
+ while (tag) {
+ int bufSize;
+ int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
+ char *rawNameBuf = tag->buf + nameLen;
+ /* Stop if already stored. Since tagStack is a stack, we can stop
+ at the first entry that has already been copied; everything
+ below it in the stack is already been accounted for in a
+ previous call to this function.
+ */
+ if (tag->rawName == rawNameBuf)
+ break;
+ /* For re-use purposes we need to ensure that the
+ size of tag->buf is a multiple of sizeof(XML_Char).
+ */
+ bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
+ if (bufSize > tag->bufEnd - tag->buf) {
+ char *temp = (char *)REALLOC(tag->buf, bufSize);
+ if (temp == NULL)
+ return XML_FALSE;
+ /* if tag->name.str points to tag->buf (only when namespace
+ processing is off) then we have to update it
+ */
+ if (tag->name.str == (XML_Char *)tag->buf)
+ tag->name.str = (XML_Char *)temp;
+ /* if tag->name.localPart is set (when namespace processing is on)
+ then update it as well, since it will always point into tag->buf
+ */
+ if (tag->name.localPart)
+ tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
+ (XML_Char *)tag->buf);
+ tag->buf = temp;
+ tag->bufEnd = temp + bufSize;
+ rawNameBuf = temp + nameLen;
+ }
+ memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
+ tag->rawName = rawNameBuf;
+ tag = tag->parent;
+ }
+ return XML_TRUE;
+}
+
+static enum XML_Error PTRCALL
+contentProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doContent(parser, 0, encoding, start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result == XML_ERROR_NONE) {
+ if (!storeRawNames(parser))
+ return XML_ERROR_NO_MEMORY;
+ }
+ return result;
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+ processor = externalEntityInitProcessor2;
+ return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor2(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ const char *next = start; /* XmlContentTok doesn't always set the last arg */
+ int tok = XmlContentTok(encoding, start, end, &next);
+ switch (tok) {
+ case XML_TOK_BOM:
+ /* If we are at the end of the buffer, this would cause the next stage,
+ i.e. externalEntityInitProcessor3, to pass control directly to
+ doContent (by detecting XML_TOK_NONE) without processing any xml text
+ declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
+ */
+ if (next == end && !ps_finalBuffer) {
+ *endPtr = next;
+ return XML_ERROR_NONE;
+ }
+ start = next;
+ break;
+ case XML_TOK_PARTIAL:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_PARTIAL_CHAR;
+ }
+ processor = externalEntityInitProcessor3;
+ return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor3(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ int tok;
+ const char *next = start; /* XmlContentTok doesn't always set the last arg */
+ eventPtr = start;
+ tok = XmlContentTok(encoding, start, end, &next);
+ eventEndPtr = next;
+
+ switch (tok) {
+ case XML_TOK_XML_DECL:
+ {
+ enum XML_Error result;
+ result = processXmlDecl(parser, 1, start, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *endPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ start = next;
+ }
+ }
+ break;
+ case XML_TOK_PARTIAL:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ }
+ processor = externalEntityContentProcessor;
+ tagLevel = 1;
+ return externalEntityContentProcessor(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityContentProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doContent(parser, 1, encoding, start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result == XML_ERROR_NONE) {
+ if (!storeRawNames(parser))
+ return XML_ERROR_NO_MEMORY;
+ }
+ return result;
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+ int startTagLevel,
+ const ENCODING *enc,
+ const char *s,
+ const char *end,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+ /* save one level of indirection */
+ DTD * const dtd = _dtd;
+
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+
+ for (;;) {
+ const char *next = s; /* XmlContentTok doesn't always set the last arg */
+ int tok = XmlContentTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_TRAILING_CR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ *eventEndPP = end;
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, end);
+ /* We are at the end of the final buffer, should we check for
+ XML_SUSPENDED, XML_FINISHED?
+ */
+ if (startTagLevel == 0)
+ return XML_ERROR_NO_ELEMENTS;
+ if (tagLevel != startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ *nextPtr = end;
+ return XML_ERROR_NONE;
+ case XML_TOK_NONE:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ if (startTagLevel > 0) {
+ if (tagLevel != startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_NO_ELEMENTS;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_ENTITY_REF:
+ {
+ const XML_Char *name;
+ ENTITY *entity;
+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (ch) {
+ if (characterDataHandler)
+ characterDataHandler(handlerArg, &ch, 1);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ name = poolStoreString(&dtd->pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+ poolDiscard(&dtd->pool);
+ /* First, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal,
+ otherwise call the skipped entity or default handler.
+ */
+ if (!dtd->hasParamEntityRefs || dtd->standalone) {
+ if (!entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (!entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ }
+ else if (!entity) {
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, name, 0);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->notation)
+ return XML_ERROR_BINARY_ENTITY_REF;
+ if (entity->textPtr) {
+ enum XML_Error result;
+ if (!defaultExpandInternalEntities) {
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, entity->name, 0);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ result = processInternalEntity(parser, entity, XML_FALSE);
+ if (result != XML_ERROR_NONE)
+ return result;
+ }
+ else if (externalEntityRefHandler) {
+ const XML_Char *context;
+ entity->open = XML_TRUE;
+ context = getContext(parser);
+ entity->open = XML_FALSE;
+ if (!context)
+ return XML_ERROR_NO_MEMORY;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ context,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ poolDiscard(&tempPool);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ case XML_TOK_START_TAG_NO_ATTS:
+ /* fall through */
+ case XML_TOK_START_TAG_WITH_ATTS:
+ {
+ TAG *tag;
+ enum XML_Error result;
+ XML_Char *toPtr;
+ if (freeTagList) {
+ tag = freeTagList;
+ freeTagList = freeTagList->parent;
+ }
+ else {
+ tag = (TAG *)MALLOC(sizeof(TAG));
+ if (!tag)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
+ if (!tag->buf) {
+ FREE(tag);
+ return XML_ERROR_NO_MEMORY;
+ }
+ tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+ }
+ tag->bindings = NULL;
+ tag->parent = tagStack;
+ tagStack = tag;
+ tag->name.localPart = NULL;
+ tag->name.prefix = NULL;
+ tag->rawName = s + enc->minBytesPerChar;
+ tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+ ++tagLevel;
+ {
+ const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+ const char *fromPtr = tag->rawName;
+ toPtr = (XML_Char *)tag->buf;
+ for (;;) {
+ int bufSize;
+ int convLen;
+ XmlConvert(enc,
+ &fromPtr, rawNameEnd,
+ (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+ convLen = (int)(toPtr - (XML_Char *)tag->buf);
+ if (fromPtr == rawNameEnd) {
+ tag->name.strLen = convLen;
+ break;
+ }
+ bufSize = (int)(tag->bufEnd - tag->buf) << 1;
+ {
+ char *temp = (char *)REALLOC(tag->buf, bufSize);
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = temp;
+ tag->bufEnd = temp + bufSize;
+ toPtr = (XML_Char *)temp + convLen;
+ }
+ }
+ }
+ tag->name.str = (XML_Char *)tag->buf;
+ *toPtr = XML_T('\0');
+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+ if (result)
+ return result;
+ if (startElementHandler)
+ startElementHandler(handlerArg, tag->name.str,
+ (const XML_Char **)atts);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ poolClear(&tempPool);
+ break;
+ }
+ case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+ /* fall through */
+ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+ {
+ const char *rawName = s + enc->minBytesPerChar;
+ enum XML_Error result;
+ BINDING *bindings = NULL;
+ XML_Bool noElmHandlers = XML_TRUE;
+ TAG_NAME name;
+ name.str = poolStoreString(&tempPool, enc, rawName,
+ rawName + XmlNameLength(enc, rawName));
+ if (!name.str)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ result = storeAtts(parser, enc, s, &name, &bindings);
+ if (result)
+ return result;
+ poolFinish(&tempPool);
+ if (startElementHandler) {
+ startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+ noElmHandlers = XML_FALSE;
+ }
+ if (endElementHandler) {
+ if (startElementHandler)
+ *eventPP = *eventEndPP;
+ endElementHandler(handlerArg, name.str);
+ noElmHandlers = XML_FALSE;
+ }
+ if (noElmHandlers && defaultHandler)
+ reportDefault(parser, enc, s, next);
+ poolClear(&tempPool);
+ while (bindings) {
+ BINDING *b = bindings;
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+ }
+ if (tagLevel == 0)
+ return epilogProcessor(parser, next, end, nextPtr);
+ break;
+ case XML_TOK_END_TAG:
+ if (tagLevel == startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ else {
+ int len;
+ const char *rawName;
+ TAG *tag = tagStack;
+ tagStack = tag->parent;
+ tag->parent = freeTagList;
+ freeTagList = tag;
+ rawName = s + enc->minBytesPerChar*2;
+ len = XmlNameLength(enc, rawName);
+ if (len != tag->rawNameLength
+ || memcmp(tag->rawName, rawName, len) != 0) {
+ *eventPP = rawName;
+ return XML_ERROR_TAG_MISMATCH;
+ }
+ --tagLevel;
+ if (endElementHandler) {
+ const XML_Char *localPart;
+ const XML_Char *prefix;
+ XML_Char *uri;
+ localPart = tag->name.localPart;
+ if (ns && localPart) {
+ /* localPart and prefix may have been overwritten in
+ tag->name.str, since this points to the binding->uri
+ buffer which gets re-used; so we have to add them again
+ */
+ uri = (XML_Char *)tag->name.str + tag->name.uriLen;
+ /* don't need to check for space - already done in storeAtts() */
+ while (*localPart) *uri++ = *localPart++;
+ prefix = (XML_Char *)tag->name.prefix;
+ if (ns_triplets && prefix) {
+ *uri++ = namespaceSeparator;
+ while (*prefix) *uri++ = *prefix++;
+ }
+ *uri = XML_T('\0');
+ }
+ endElementHandler(handlerArg, tag->name.str);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ while (tag->bindings) {
+ BINDING *b = tag->bindings;
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ tag->bindings = tag->bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+ if (tagLevel == 0)
+ return epilogProcessor(parser, next, end, nextPtr);
+ }
+ break;
+ case XML_TOK_CHAR_REF:
+ {
+ int n = XmlCharRefNumber(enc, s);
+ if (n < 0)
+ return XML_ERROR_BAD_CHAR_REF;
+ if (characterDataHandler) {
+ XML_Char buf[XML_ENCODE_MAX];
+ characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ }
+ break;
+ case XML_TOK_XML_DECL:
+ return XML_ERROR_MISPLACED_XML_PI;
+ case XML_TOK_DATA_NEWLINE:
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_CDATA_SECT_OPEN:
+ {
+ enum XML_Error result;
+ if (startCdataSectionHandler)
+ startCdataSectionHandler(handlerArg);
+#if 0
+ /* Suppose you doing a transformation on a document that involves
+ changing only the character data. You set up a defaultHandler
+ and a characterDataHandler. The defaultHandler simply copies
+ characters through. The characterDataHandler does the
+ transformation and writes the characters out escaping them as
+ necessary. This case will fail to work if we leave out the
+ following two lines (because & and < inside CDATA sections will
+ be incorrectly escaped).
+
+ However, now we have a start/endCdataSectionHandler, so it seems
+ easier to let the user deal with this.
+ */
+ else if (characterDataHandler)
+ characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (!next) {
+ processor = cdataSectionProcessor;
+ return result;
+ }
+ }
+ break;
+ case XML_TOK_TRAILING_RSQB:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ characterDataHandler(handlerArg, dataBuf,
+ (int)(dataPtr - (ICHAR *)dataBuf));
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (int)((XML_Char *)end - (XML_Char *)s));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, end);
+ /* We are at the end of the final buffer, should we check for
+ XML_SUSPENDED, XML_FINISHED?
+ */
+ if (startTagLevel == 0) {
+ *eventPP = end;
+ return XML_ERROR_NO_ELEMENTS;
+ }
+ if (tagLevel != startTagLevel) {
+ *eventPP = end;
+ return XML_ERROR_ASYNC_ENTITY;
+ }
+ *nextPtr = end;
+ return XML_ERROR_NONE;
+ case XML_TOK_DATA_CHARS:
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = s;
+ characterDataHandler(handlerArg, dataBuf,
+ (int)(dataPtr - (ICHAR *)dataBuf));
+ if (s == next)
+ break;
+ *eventPP = s;
+ }
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (int)((XML_Char *)next - (XML_Char *)s));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ default:
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ *eventPP = s = next;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default: ;
+ }
+ }
+ /* not reached */
+}
+
+/* Precondition: all arguments must be non-NULL;
+ Purpose:
+ - normalize attributes
+ - check attributes for well-formedness
+ - generate namespace aware attribute names (URI, prefix)
+ - build list of attributes for startElementHandler
+ - default attributes
+ - process namespace declarations (check and report them)
+ - generate namespace aware element name (URI, prefix)
+*/
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *enc,
+ const char *attStr, TAG_NAME *tagNamePtr,
+ BINDING **bindingsPtr)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ ELEMENT_TYPE *elementType;
+ int nDefaultAtts;
+ const XML_Char **appAtts; /* the attribute list for the application */
+ int attIndex = 0;
+ int prefixLen;
+ int i;
+ int n;
+ XML_Char *uri;
+ int nPrefixes = 0;
+ BINDING *binding;
+ const XML_Char *localPart;
+
+ /* lookup the element type name */
+ elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
+ if (!elementType) {
+ const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
+ sizeof(ELEMENT_TYPE));
+ if (!elementType)
+ return XML_ERROR_NO_MEMORY;
+ if (ns && !setElementTypePrefix(parser, elementType))
+ return XML_ERROR_NO_MEMORY;
+ }
+ nDefaultAtts = elementType->nDefaultAtts;
+
+ /* get the attributes from the tokenizer */
+ n = XmlGetAttributes(enc, attStr, attsSize, atts);
+ if (n + nDefaultAtts > attsSize) {
+ int oldAttsSize = attsSize;
+ ATTRIBUTE *temp;
+ attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+ temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ atts = temp;
+ if (n > oldAttsSize)
+ XmlGetAttributes(enc, attStr, n, atts);
+ }
+
+ appAtts = (const XML_Char **)atts;
+ for (i = 0; i < n; i++) {
+ /* add the name and value to the attribute list */
+ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+ atts[i].name
+ + XmlNameLength(enc, atts[i].name));
+ if (!attId)
+ return XML_ERROR_NO_MEMORY;
+ /* Detect duplicate attributes by their QNames. This does not work when
+ namespace processing is turned on and different prefixes for the same
+ namespace are used. For this case we have a check further down.
+ */
+ if ((attId->name)[-1]) {
+ if (enc == encoding)
+ eventPtr = atts[i].name;
+ return XML_ERROR_DUPLICATE_ATTRIBUTE;
+ }
+ (attId->name)[-1] = 1;
+ appAtts[attIndex++] = attId->name;
+ if (!atts[i].normalized) {
+ enum XML_Error result;
+ XML_Bool isCdata = XML_TRUE;
+
+ /* figure out whether declared as other than CDATA */
+ if (attId->maybeTokenized) {
+ int j;
+ for (j = 0; j < nDefaultAtts; j++) {
+ if (attId == elementType->defaultAtts[j].id) {
+ isCdata = elementType->defaultAtts[j].isCdata;
+ break;
+ }
+ }
+ }
+
+ /* normalize the attribute value */
+ result = storeAttributeValue(parser, enc, isCdata,
+ atts[i].valuePtr, atts[i].valueEnd,
+ &tempPool);
+ if (result)
+ return result;
+ appAtts[attIndex] = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ }
+ else {
+ /* the value did not need normalizing */
+ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
+ atts[i].valueEnd);
+ if (appAtts[attIndex] == 0)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ }
+ /* handle prefixed attribute names */
+ if (attId->prefix) {
+ if (attId->xmlns) {
+ /* deal with namespace declarations here */
+ enum XML_Error result = addBinding(parser, attId->prefix, attId,
+ appAtts[attIndex], bindingsPtr);
+ if (result)
+ return result;
+ --attIndex;
+ }
+ else {
+ /* deal with other prefixed names later */
+ attIndex++;
+ nPrefixes++;
+ (attId->name)[-1] = 2;
+ }
+ }
+ else
+ attIndex++;
+ }
+
+ /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
+ nSpecifiedAtts = attIndex;
+ if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+ for (i = 0; i < attIndex; i += 2)
+ if (appAtts[i] == elementType->idAtt->name) {
+ idAttIndex = i;
+ break;
+ }
+ }
+ else
+ idAttIndex = -1;
+
+ /* do attribute defaulting */
+ for (i = 0; i < nDefaultAtts; i++) {
+ const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
+ if (!(da->id->name)[-1] && da->value) {
+ if (da->id->prefix) {
+ if (da->id->xmlns) {
+ enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
+ da->value, bindingsPtr);
+ if (result)
+ return result;
+ }
+ else {
+ (da->id->name)[-1] = 2;
+ nPrefixes++;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+ }
+ }
+ else {
+ (da->id->name)[-1] = 1;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+ }
+ }
+ }
+ appAtts[attIndex] = 0;
+
+ /* expand prefixed attribute names, check for duplicates,
+ and clear flags that say whether attributes were specified */
+ i = 0;
+ if (nPrefixes) {
+ int j; /* hash table index */
+ unsigned long version = nsAttsVersion;
+ int nsAttsSize = (int)1 << nsAttsPower;
+ /* size of hash table must be at least 2 * (# of prefixed attributes) */
+ if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
+ NS_ATT *temp;
+ /* hash table size must also be a power of 2 and >= 8 */
+ while (nPrefixes >> nsAttsPower++);
+ if (nsAttsPower < 3)
+ nsAttsPower = 3;
+ nsAttsSize = (int)1 << nsAttsPower;
+ temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
+ if (!temp)
+ return XML_ERROR_NO_MEMORY;
+ nsAtts = temp;
+ version = 0; /* force re-initialization of nsAtts hash table */
+ }
+ /* using a version flag saves us from initializing nsAtts every time */
+ if (!version) { /* initialize version flags when version wraps around */
+ version = INIT_ATTS_VERSION;
+ for (j = nsAttsSize; j != 0; )
+ nsAtts[--j].version = version;
+ }
+ nsAttsVersion = --version;
+
+ /* expand prefixed names and check for duplicates */
+ for (; i < attIndex; i += 2) {
+ const XML_Char *s = appAtts[i];
+ if (s[-1] == 2) { /* prefixed */
+ ATTRIBUTE_ID *id;
+ const BINDING *b;
+ unsigned long uriHash = 0;
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
+ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
+ if (!id)
+ return XML_ERROR_NO_MEMORY;
+ b = id->prefix->binding;
+ if (!b)
+ return XML_ERROR_UNBOUND_PREFIX;
+
+ /* as we expand the name we also calculate its hash value */
+ for (j = 0; j < b->uriLen; j++) {
+ const XML_Char c = b->uri[j];
+ if (!poolAppendChar(&tempPool, c))
+ return XML_ERROR_NO_MEMORY;
+ uriHash = CHAR_HASH(uriHash, c);
+ }
+ while (*s++ != XML_T(':'))
+ ;
+ do { /* copies null terminator */
+ const XML_Char c = *s;
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ uriHash = CHAR_HASH(uriHash, c);
+ } while (*s++);
+
+ { /* Check hash table for duplicate of expanded name (uriName).
+ Derived from code in lookup(HASH_TABLE *table, ...).
+ */
+ unsigned char step = 0;
+ unsigned long mask = nsAttsSize - 1;
+ j = uriHash & mask; /* index into hash table */
+ while (nsAtts[j].version == version) {
+ /* for speed we compare stored hash values first */
+ if (uriHash == nsAtts[j].hash) {
+ const XML_Char *s1 = poolStart(&tempPool);
+ const XML_Char *s2 = nsAtts[j].uriName;
+ /* s1 is null terminated, but not s2 */
+ for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+ if (*s1 == 0)
+ return XML_ERROR_DUPLICATE_ATTRIBUTE;
+ }
+ if (!step)
+ step = PROBE_STEP(uriHash, mask, nsAttsPower);
+ j < step ? (j += nsAttsSize - step) : (j -= step);
+ }
+ }
+
+ if (ns_triplets) { /* append namespace separator and prefix */
+ tempPool.ptr[-1] = namespaceSeparator;
+ s = b->prefix->name;
+ do {
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ } while (*s++);
+ }
+
+ /* store expanded name in attribute list */
+ s = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ appAtts[i] = s;
+
+ /* fill empty slot with new version, uriName and hash value */
+ nsAtts[j].version = version;
+ nsAtts[j].hash = uriHash;
+ nsAtts[j].uriName = s;
+
+ if (!--nPrefixes) {
+ i += 2;
+ break;
+ }
+ }
+ else /* not prefixed */
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
+ }
+ }
+ /* clear flags for the remaining attributes */
+ for (; i < attIndex; i += 2)
+ ((XML_Char *)(appAtts[i]))[-1] = 0;
+ for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+ binding->attId->name[-1] = 0;
+
+ if (!ns)
+ return XML_ERROR_NONE;
+
+ /* expand the element type name */
+ if (elementType->prefix) {
+ binding = elementType->prefix->binding;
+ if (!binding)
+ return XML_ERROR_UNBOUND_PREFIX;
+ localPart = tagNamePtr->str;
+ while (*localPart++ != XML_T(':'))
+ ;
+ }
+ else if (dtd->defaultPrefix.binding) {
+ binding = dtd->defaultPrefix.binding;
+ localPart = tagNamePtr->str;
+ }
+ else
+ return XML_ERROR_NONE;
+ prefixLen = 0;
+ if (ns_triplets && binding->prefix->name) {
+ for (; binding->prefix->name[prefixLen++];)
+ ; /* prefixLen includes null terminator */
+ }
+ tagNamePtr->localPart = localPart;
+ tagNamePtr->uriLen = binding->uriLen;
+ tagNamePtr->prefix = binding->prefix->name;
+ tagNamePtr->prefixLen = prefixLen;
+ for (i = 0; localPart[i++];)
+ ; /* i includes null terminator */
+ n = i + binding->uriLen + prefixLen;
+ if (n > binding->uriAlloc) {
+ TAG *p;
+ uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+ if (!uri)
+ return XML_ERROR_NO_MEMORY;
+ binding->uriAlloc = n + EXPAND_SPARE;
+ memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+ for (p = tagStack; p; p = p->parent)
+ if (p->name.str == binding->uri)
+ p->name.str = uri;
+ FREE(binding->uri);
+ binding->uri = uri;
+ }
+ /* if namespaceSeparator != '\0' then uri includes it already */
+ uri = binding->uri + binding->uriLen;
+ memcpy(uri, localPart, i * sizeof(XML_Char));
+ /* we always have a namespace separator between localPart and prefix */
+ if (prefixLen) {
+ uri += i - 1;
+ *uri = namespaceSeparator; /* replace null terminator */
+ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
+ }
+ tagNamePtr->str = binding->uri;
+ return XML_ERROR_NONE;
+}
+
+/* addBinding() overwrites the value of prefix->binding without checking.
+ Therefore one must keep track of the old value outside of addBinding().
+*/
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+ const XML_Char *uri, BINDING **bindingsPtr)
+{
+ static const XML_Char xmlNamespace[] = {
+ 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+ 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+ };
+ static const int xmlLen =
+ (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
+ static const XML_Char xmlnsNamespace[] = {
+ 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+ };
+ static const int xmlnsLen =
+ (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
+
+ XML_Bool mustBeXML = XML_FALSE;
+ XML_Bool isXML = XML_TRUE;
+ XML_Bool isXMLNS = XML_TRUE;
+
+ BINDING *b;
+ int len;
+
+ /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
+ if (*uri == XML_T('\0') && prefix->name)
+ return XML_ERROR_UNDECLARING_PREFIX;
+
+ if (prefix->name
+ && prefix->name[0] == XML_T('x')
+ && prefix->name[1] == XML_T('m')
+ && prefix->name[2] == XML_T('l')) {
+
+ /* Not allowed to bind xmlns */
+ if (prefix->name[3] == XML_T('n')
+ && prefix->name[4] == XML_T('s')
+ && prefix->name[5] == XML_T('\0'))
+ return XML_ERROR_RESERVED_PREFIX_XMLNS;
+
+ if (prefix->name[3] == XML_T('\0'))
+ mustBeXML = XML_TRUE;
+ }
+
+ for (len = 0; uri[len]; len++) {
+ if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
+ isXML = XML_FALSE;
+
+ if (!mustBeXML && isXMLNS
+ && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
+ isXMLNS = XML_FALSE;
+ }
+ isXML = isXML && len == xmlLen;
+ isXMLNS = isXMLNS && len == xmlnsLen;
+
+ if (mustBeXML != isXML)
+ return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
+ : XML_ERROR_RESERVED_NAMESPACE_URI;
+
+ if (isXMLNS)
+ return XML_ERROR_RESERVED_NAMESPACE_URI;
+
+ if (namespaceSeparator)
+ len++;
+ if (freeBindingList) {
+ b = freeBindingList;
+ if (len > b->uriAlloc) {
+ XML_Char *temp = (XML_Char *)REALLOC(b->uri,
+ sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ b->uri = temp;
+ b->uriAlloc = len + EXPAND_SPARE;
+ }
+ freeBindingList = b->nextTagBinding;
+ }
+ else {
+ b = (BINDING *)MALLOC(sizeof(BINDING));
+ if (!b)
+ return XML_ERROR_NO_MEMORY;
+ b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (!b->uri) {
+ FREE(b);
+ return XML_ERROR_NO_MEMORY;
+ }
+ b->uriAlloc = len + EXPAND_SPARE;
+ }
+ b->uriLen = len;
+ memcpy(b->uri, uri, len * sizeof(XML_Char));
+ if (namespaceSeparator)
+ b->uri[len - 1] = namespaceSeparator;
+ b->prefix = prefix;
+ b->attId = attId;
+ b->prevPrefixBinding = prefix->binding;
+ /* NULL binding when default namespace undeclared */
+ if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
+ prefix->binding = NULL;
+ else
+ prefix->binding = b;
+ b->nextTagBinding = *bindingsPtr;
+ *bindingsPtr = b;
+ /* if attId == NULL then we are not starting a namespace scope */
+ if (attId && startNamespaceDeclHandler)
+ startNamespaceDeclHandler(handlerArg, prefix->name,
+ prefix->binding ? uri : 0);
+ return XML_ERROR_NONE;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+ the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+cdataSectionProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doCdataSection(parser, encoding, &start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result != XML_ERROR_NONE)
+ return result;
+ if (start) {
+ if (parentParser) { /* we are parsing an external entity */
+ processor = externalEntityContentProcessor;
+ return externalEntityContentProcessor(parser, start, end, endPtr);
+ }
+ else {
+ processor = contentProcessor;
+ return contentProcessor(parser, start, end, endPtr);
+ }
+ }
+ return result;
+}
+
+/* startPtr gets set to non-null if the section is closed, and to null if
+ the section is not yet closed.
+*/
+static enum XML_Error
+doCdataSection(XML_Parser parser,
+ const ENCODING *enc,
+ const char **startPtr,
+ const char *end,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+ const char *s = *startPtr;
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ *eventPP = s;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ *startPtr = NULL;
+
+ for (;;) {
+ const char *next;
+ int tok = XmlCdataSectionTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_CDATA_SECT_CLOSE:
+ if (endCdataSectionHandler)
+ endCdataSectionHandler(handlerArg);
+#if 0
+ /* see comment under XML_TOK_CDATA_SECT_OPEN */
+ else if (characterDataHandler)
+ characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ *startPtr = next;
+ *nextPtr = next;
+ if (ps_parsing == XML_FINISHED)
+ return XML_ERROR_ABORTED;
+ else
+ return XML_ERROR_NONE;
+ case XML_TOK_DATA_NEWLINE:
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_DATA_CHARS:
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = next;
+ characterDataHandler(handlerArg, dataBuf,
+ (int)(dataPtr - (ICHAR *)dataBuf));
+ if (s == next)
+ break;
+ *eventPP = s;
+ }
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (int)((XML_Char *)next - (XML_Char *)s));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_PARTIAL:
+ case XML_TOK_NONE:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_CDATA_SECTION;
+ default:
+ *eventPP = next;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+
+ *eventPP = s = next;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default: ;
+ }
+ }
+ /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+ the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+ignoreSectionProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result != XML_ERROR_NONE)
+ return result;
+ if (start) {
+ processor = prologProcessor;
+ return prologProcessor(parser, start, end, endPtr);
+ }
+ return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null
+ if the section is not yet closed.
+*/
+static enum XML_Error
+doIgnoreSection(XML_Parser parser,
+ const ENCODING *enc,
+ const char **startPtr,
+ const char *end,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+ const char *next;
+ int tok;
+ const char *s = *startPtr;
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ *eventPP = s;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ *startPtr = NULL;
+ tok = XmlIgnoreSectionTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_IGNORE_SECT:
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ *startPtr = next;
+ *nextPtr = next;
+ if (ps_parsing == XML_FINISHED)
+ return XML_ERROR_ABORTED;
+ else
+ return XML_ERROR_NONE;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_PARTIAL:
+ case XML_TOK_NONE:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+ default:
+ *eventPP = next;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+ const char *s;
+#ifdef XML_UNICODE
+ char encodingBuf[128];
+ if (!protocolEncodingName)
+ s = NULL;
+ else {
+ int i;
+ for (i = 0; protocolEncodingName[i]; i++) {
+ if (i == sizeof(encodingBuf) - 1
+ || (protocolEncodingName[i] & ~0x7f) != 0) {
+ encodingBuf[0] = '\0';
+ break;
+ }
+ encodingBuf[i] = (char)protocolEncodingName[i];
+ }
+ encodingBuf[i] = '\0';
+ s = encodingBuf;
+ }
+#else
+ s = protocolEncodingName;
+#endif
+ if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+ return XML_ERROR_NONE;
+ return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+ const char *s, const char *next)
+{
+ const char *encodingName = NULL;
+ const XML_Char *storedEncName = NULL;
+ const ENCODING *newEncoding = NULL;
+ const char *version = NULL;
+ const char *versionend;
+ const XML_Char *storedversion = NULL;
+ int standalone = -1;
+ if (!(ns
+ ? XmlParseXmlDeclNS
+ : XmlParseXmlDecl)(isGeneralTextEntity,
+ encoding,
+ s,
+ next,
+ &eventPtr,
+ &version,
+ &versionend,
+ &encodingName,
+ &newEncoding,
+ &standalone)) {
+ if (isGeneralTextEntity)
+ return XML_ERROR_TEXT_DECL;
+ else
+ return XML_ERROR_XML_DECL;
+ }
+ if (!isGeneralTextEntity && standalone == 1) {
+ _dtd->standalone = XML_TRUE;
+#ifdef XML_DTD
+ if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+ }
+ if (xmlDeclHandler) {
+ if (encodingName != NULL) {
+ storedEncName = poolStoreString(&temp2Pool,
+ encoding,
+ encodingName,
+ encodingName
+ + XmlNameLength(encoding, encodingName));
+ if (!storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&temp2Pool);
+ }
+ if (version) {
+ storedversion = poolStoreString(&temp2Pool,
+ encoding,
+ version,
+ versionend - encoding->minBytesPerChar);
+ if (!storedversion)
+ return XML_ERROR_NO_MEMORY;
+ }
+ xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, encoding, s, next);
+ if (protocolEncodingName == NULL) {
+ if (newEncoding) {
+ if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+ eventPtr = encodingName;
+ return XML_ERROR_INCORRECT_ENCODING;
+ }
+ encoding = newEncoding;
+ }
+ else if (encodingName) {
+ enum XML_Error result;
+ if (!storedEncName) {
+ storedEncName = poolStoreString(
+ &temp2Pool, encoding, encodingName,
+ encodingName + XmlNameLength(encoding, encodingName));
+ if (!storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ }
+ result = handleUnknownEncoding(parser, storedEncName);
+ poolClear(&temp2Pool);
+ if (result == XML_ERROR_UNKNOWN_ENCODING)
+ eventPtr = encodingName;
+ return result;
+ }
+ }
+
+ if (storedEncName || storedversion)
+ poolClear(&temp2Pool);
+
+ return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+ if (unknownEncodingHandler) {
+ XML_Encoding info;
+ int i;
+ for (i = 0; i < 256; i++)
+ info.map[i] = -1;
+ info.convert = NULL;
+ info.data = NULL;
+ info.release = NULL;
+ if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
+ &info)) {
+ ENCODING *enc;
+ unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
+ if (!unknownEncodingMem) {
+ if (info.release)
+ info.release(info.data);
+ return XML_ERROR_NO_MEMORY;
+ }
+ enc = (ns
+ ? XmlInitUnknownEncodingNS
+ : XmlInitUnknownEncoding)(unknownEncodingMem,
+ info.map,
+ info.convert,
+ info.data);
+ if (enc) {
+ unknownEncodingData = info.data;
+ unknownEncodingRelease = info.release;
+ encoding = enc;
+ return XML_ERROR_NONE;
+ }
+ }
+ if (info.release != NULL)
+ info.release(info.data);
+ }
+ return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error PTRCALL
+prologInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+ processor = prologProcessor;
+ return prologProcessor(parser, s, end, nextPtr);
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error PTRCALL
+externalParEntInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+
+ /* we know now that XML_Parse(Buffer) has been called,
+ so we consider the external parameter entity read */
+ _dtd->paramEntityRead = XML_TRUE;
+
+ if (prologState.inEntityValue) {
+ processor = entityValueInitProcessor;
+ return entityValueInitProcessor(parser, s, end, nextPtr);
+ }
+ else {
+ processor = externalParEntProcessor;
+ return externalParEntProcessor(parser, s, end, nextPtr);
+ }
+}
+
+static enum XML_Error PTRCALL
+entityValueInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ int tok;
+ const char *start = s;
+ const char *next = start;
+ eventPtr = start;
+
+ for (;;) {
+ tok = XmlPrologTok(encoding, start, end, &next);
+ eventEndPtr = next;
+ if (tok <= 0) {
+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE: /* start == end */
+ default:
+ break;
+ }
+ /* found end of entity value - can store it now */
+ return storeEntityValue(parser, encoding, s, end);
+ }
+ else if (tok == XML_TOK_XML_DECL) {
+ enum XML_Error result;
+ result = processXmlDecl(parser, 0, start, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ *nextPtr = next;
+ }
+ /* stop scanning for text declaration - we found one */
+ processor = entityValueProcessor;
+ return entityValueProcessor(parser, next, end, nextPtr);
+ }
+ /* If we are at the end of the buffer, this would cause XmlPrologTok to
+ return XML_TOK_NONE on the next call, which would then cause the
+ function to exit with *nextPtr set to s - that is what we want for other
+ tokens, but not for the BOM - we would rather like to skip it;
+ then, when this routine is entered the next time, XmlPrologTok will
+ return XML_TOK_INVALID, since the BOM is still in the buffer
+ */
+ else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ }
+ start = next;
+ eventPtr = start;
+ }
+}
+
+static enum XML_Error PTRCALL
+externalParEntProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *next = s;
+ int tok;
+
+ tok = XmlPrologTok(encoding, s, end, &next);
+ if (tok <= 0) {
+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE: /* start == end */
+ default:
+ break;
+ }
+ }
+ /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
+ However, when parsing an external subset, doProlog will not accept a BOM
+ as valid, and report a syntax error, so we have to skip the BOM
+ */
+ else if (tok == XML_TOK_BOM) {
+ s = next;
+ tok = XmlPrologTok(encoding, s, end, &next);
+ }
+
+ processor = prologProcessor;
+ return doProlog(parser, encoding, s, end, tok, next,
+ nextPtr, (XML_Bool)!ps_finalBuffer);
+}
+
+static enum XML_Error PTRCALL
+entityValueProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *start = s;
+ const char *next = s;
+ const ENCODING *enc = encoding;
+ int tok;
+
+ for (;;) {
+ tok = XmlPrologTok(enc, start, end, &next);
+ if (tok <= 0) {
+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE: /* start == end */
+ default:
+ break;
+ }
+ /* found end of entity value - can store it now */
+ return storeEntityValue(parser, enc, s, end);
+ }
+ start = next;
+ }
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error PTRCALL
+prologProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *next = s;
+ int tok = XmlPrologTok(encoding, s, end, &next);
+ return doProlog(parser, encoding, s, end, tok, next,
+ nextPtr, (XML_Bool)!ps_finalBuffer);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+ const ENCODING *enc,
+ const char *s,
+ const char *end,
+ int tok,
+ const char *next,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+#ifdef XML_DTD
+ static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+ static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
+ static const XML_Char atypeID[] = { 'I', 'D', '\0' };
+ static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
+ static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
+ static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
+ static const XML_Char atypeENTITIES[] =
+ { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
+ static const XML_Char atypeNMTOKEN[] = {
+ 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
+ static const XML_Char atypeNMTOKENS[] = {
+ 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
+ static const XML_Char notationPrefix[] = {
+ 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
+ static const XML_Char enumValueSep[] = { '|', '\0' };
+ static const XML_Char enumValueStart[] = { '(', '\0' };
+
+ /* save one level of indirection */
+ DTD * const dtd = _dtd;
+
+ const char **eventPP;
+ const char **eventEndPP;
+ enum XML_Content_Quant quant;
+
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+
+ for (;;) {
+ int role;
+ XML_Bool handleDefault = XML_TRUE;
+ *eventPP = s;
+ *eventEndPP = next;
+ if (tok <= 0) {
+ if (haveMore && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE:
+#ifdef XML_DTD
+ /* for internal PE NOT referenced between declarations */
+ if (enc != encoding && !openInternalEntities->betweenDecl) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ /* WFC: PE Between Declarations - must check that PE contains
+ complete markup, not only for external PEs, but also for
+ internal PEs if the reference occurs between declarations.
+ */
+ if (isParamEntity || enc != encoding) {
+ if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+ == XML_ROLE_ERROR)
+ return XML_ERROR_INCOMPLETE_PE;
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+#endif /* XML_DTD */
+ return XML_ERROR_NO_ELEMENTS;
+ default:
+ tok = -tok;
+ next = end;
+ break;
+ }
+ }
+ role = XmlTokenRole(&prologState, tok, s, next, enc);
+ switch (role) {
+ case XML_ROLE_XML_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 0, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = encoding;
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_NAME:
+ if (startDoctypeDeclHandler) {
+ doctypeName = poolStoreString(&tempPool, enc, s, next);
+ if (!doctypeName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ doctypePubid = NULL;
+ handleDefault = XML_FALSE;
+ }
+ doctypeSysid = NULL; /* always initialize to NULL */
+ break;
+ case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
+ if (startDoctypeDeclHandler) {
+ startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+ doctypePubid, 1);
+ doctypeName = NULL;
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ break;
+#ifdef XML_DTD
+ case XML_ROLE_TEXT_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 1, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = encoding;
+ handleDefault = XML_FALSE;
+ }
+ break;
+#endif /* XML_DTD */
+ case XML_ROLE_DOCTYPE_PUBLIC_ID:
+#ifdef XML_DTD
+ useForeignDTD = XML_FALSE;
+ declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (startDoctypeDeclHandler) {
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_PUBLICID;
+ doctypePubid = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!doctypePubid)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId((XML_Char *)doctypePubid);
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ goto alreadyChecked;
+ }
+ /* fall through */
+ case XML_ROLE_ENTITY_PUBLIC_ID:
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_PUBLICID;
+ alreadyChecked:
+ if (dtd->keepProcessing && declEntity) {
+ XML_Char *tem = poolStoreString(&dtd->pool,
+ enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!tem)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId(tem);
+ declEntity->publicId = tem;
+ poolFinish(&dtd->pool);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_CLOSE:
+ if (doctypeName) {
+ startDoctypeDeclHandler(handlerArg, doctypeName,
+ doctypeSysid, doctypePubid, 0);
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ /* doctypeSysid will be non-NULL in the case of a previous
+ XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
+ was not set, indicating an external subset
+ */
+#ifdef XML_DTD
+ if (doctypeSysid || useForeignDTD) {
+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (paramEntityParsing && externalEntityRefHandler) {
+ ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!entity)
+ return XML_ERROR_NO_MEMORY;
+ if (useForeignDTD)
+ entity->base = curBase;
+ dtd->paramEntityRead = XML_FALSE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ if (dtd->paramEntityRead) {
+ if (!dtd->standalone &&
+ notStandaloneHandler &&
+ !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ }
+ /* if we didn't read the foreign DTD then this means that there
+ is no external subset and we must reset dtd->hasParamEntityRefs
+ */
+ else if (!doctypeSysid)
+ dtd->hasParamEntityRefs = hadParamEntityRefs;
+ /* end of DTD - no need to update dtd->keepProcessing */
+ }
+ useForeignDTD = XML_FALSE;
+ }
+#endif /* XML_DTD */
+ if (endDoctypeDeclHandler) {
+ endDoctypeDeclHandler(handlerArg);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_INSTANCE_START:
+#ifdef XML_DTD
+ /* if there is no DOCTYPE declaration then now is the
+ last chance to read the foreign DTD
+ */
+ if (useForeignDTD) {
+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (paramEntityParsing && externalEntityRefHandler) {
+ ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!entity)
+ return XML_ERROR_NO_MEMORY;
+ entity->base = curBase;
+ dtd->paramEntityRead = XML_FALSE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ if (dtd->paramEntityRead) {
+ if (!dtd->standalone &&
+ notStandaloneHandler &&
+ !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ }
+ /* if we didn't read the foreign DTD then this means that there
+ is no external subset and we must reset dtd->hasParamEntityRefs
+ */
+ else
+ dtd->hasParamEntityRefs = hadParamEntityRefs;
+ /* end of DTD - no need to update dtd->keepProcessing */
+ }
+ }
+#endif /* XML_DTD */
+ processor = contentProcessor;
+ return contentProcessor(parser, s, end, nextPtr);
+ case XML_ROLE_ATTLIST_ELEMENT_NAME:
+ declElementType = getElementType(parser, enc, s, next);
+ if (!declElementType)
+ return XML_ERROR_NO_MEMORY;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_NAME:
+ declAttributeId = getAttributeId(parser, enc, s, next);
+ if (!declAttributeId)
+ return XML_ERROR_NO_MEMORY;
+ declAttributeIsCdata = XML_FALSE;
+ declAttributeType = NULL;
+ declAttributeIsId = XML_FALSE;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+ declAttributeIsCdata = XML_TRUE;
+ declAttributeType = atypeCDATA;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_ID:
+ declAttributeIsId = XML_TRUE;
+ declAttributeType = atypeID;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
+ declAttributeType = atypeIDREF;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
+ declAttributeType = atypeIDREFS;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
+ declAttributeType = atypeENTITY;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
+ declAttributeType = atypeENTITIES;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
+ declAttributeType = atypeNMTOKEN;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
+ declAttributeType = atypeNMTOKENS;
+ checkAttListDeclHandler:
+ if (dtd->keepProcessing && attlistDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
+ case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
+ if (dtd->keepProcessing && attlistDeclHandler) {
+ const XML_Char *prefix;
+ if (declAttributeType) {
+ prefix = enumValueSep;
+ }
+ else {
+ prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+ ? notationPrefix
+ : enumValueStart);
+ }
+ if (!poolAppendString(&tempPool, prefix))
+ return XML_ERROR_NO_MEMORY;
+ if (!poolAppend(&tempPool, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+ case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+ if (dtd->keepProcessing) {
+ if (!defineAttribute(declElementType, declAttributeId,
+ declAttributeIsCdata, declAttributeIsId,
+ 0, parser))
+ return XML_ERROR_NO_MEMORY;
+ if (attlistDeclHandler && declAttributeType) {
+ if (*declAttributeType == XML_T('(')
+ || (*declAttributeType == XML_T('N')
+ && declAttributeType[1] == XML_T('O'))) {
+ /* Enumerated or Notation type */
+ if (!poolAppendChar(&tempPool, XML_T(')'))
+ || !poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ poolFinish(&tempPool);
+ }
+ *eventEndPP = s;
+ attlistDeclHandler(handlerArg, declElementType->name,
+ declAttributeId->name, declAttributeType,
+ 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ }
+ break;
+ case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+ case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+ if (dtd->keepProcessing) {
+ const XML_Char *attVal;
+ enum XML_Error result =
+ storeAttributeValue(parser, enc, declAttributeIsCdata,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar,
+ &dtd->pool);
+ if (result)
+ return result;
+ attVal = poolStart(&dtd->pool);
+ poolFinish(&dtd->pool);
+ /* ID attributes aren't allowed to have a default */
+ if (!defineAttribute(declElementType, declAttributeId,
+ declAttributeIsCdata, XML_FALSE, attVal, parser))
+ return XML_ERROR_NO_MEMORY;
+ if (attlistDeclHandler && declAttributeType) {
+ if (*declAttributeType == XML_T('(')
+ || (*declAttributeType == XML_T('N')
+ && declAttributeType[1] == XML_T('O'))) {
+ /* Enumerated or Notation type */
+ if (!poolAppendChar(&tempPool, XML_T(')'))
+ || !poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ poolFinish(&tempPool);
+ }
+ *eventEndPP = s;
+ attlistDeclHandler(handlerArg, declElementType->name,
+ declAttributeId->name, declAttributeType,
+ attVal,
+ role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ }
+ break;
+ case XML_ROLE_ENTITY_VALUE:
+ if (dtd->keepProcessing) {
+ enum XML_Error result = storeEntityValue(parser, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (declEntity) {
+ declEntity->textPtr = poolStart(&dtd->entityValuePool);
+ declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
+ poolFinish(&dtd->entityValuePool);
+ if (entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->is_param,
+ declEntity->textPtr,
+ declEntity->textLen,
+ curBase, 0, 0, 0);
+ handleDefault = XML_FALSE;
+ }
+ }
+ else
+ poolDiscard(&dtd->entityValuePool);
+ if (result != XML_ERROR_NONE)
+ return result;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_SYSTEM_ID:
+#ifdef XML_DTD
+ useForeignDTD = XML_FALSE;
+#endif /* XML_DTD */
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (startDoctypeDeclHandler) {
+ doctypeSysid = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (doctypeSysid == NULL)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+#ifdef XML_DTD
+ else
+ /* use externalSubsetName to make doctypeSysid non-NULL
+ for the case where no startDoctypeDeclHandler is set */
+ doctypeSysid = externalSubsetName;
+#endif /* XML_DTD */
+ if (!dtd->standalone
+#ifdef XML_DTD
+ && !paramEntityParsing
+#endif /* XML_DTD */
+ && notStandaloneHandler
+ && !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+#ifndef XML_DTD
+ break;
+#else /* XML_DTD */
+ if (!declEntity) {
+ declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ declEntity->publicId = NULL;
+ }
+ /* fall through */
+#endif /* XML_DTD */
+ case XML_ROLE_ENTITY_SYSTEM_ID:
+ if (dtd->keepProcessing && declEntity) {
+ declEntity->systemId = poolStoreString(&dtd->pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!declEntity->systemId)
+ return XML_ERROR_NO_MEMORY;
+ declEntity->base = curBase;
+ poolFinish(&dtd->pool);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_ENTITY_COMPLETE:
+ if (dtd->keepProcessing && declEntity && entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->is_param,
+ 0,0,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ 0);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_ENTITY_NOTATION_NAME:
+ if (dtd->keepProcessing && declEntity) {
+ declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
+ if (!declEntity->notation)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&dtd->pool);
+ if (unparsedEntityDeclHandler) {
+ *eventEndPP = s;
+ unparsedEntityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ declEntity->notation);
+ handleDefault = XML_FALSE;
+ }
+ else if (entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ 0,0,0,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ declEntity->notation);
+ handleDefault = XML_FALSE;
+ }
+ }
+ break;
+ case XML_ROLE_GENERAL_ENTITY_NAME:
+ {
+ if (XmlPredefinedEntityName(enc, s, next)) {
+ declEntity = NULL;
+ break;
+ }
+ if (dtd->keepProcessing) {
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (declEntity->name != name) {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+ else {
+ poolFinish(&dtd->pool);
+ declEntity->publicId = NULL;
+ declEntity->is_param = XML_FALSE;
+ /* if we have a parent parser or are reading an internal parameter
+ entity, then the entity declaration is not considered "internal"
+ */
+ declEntity->is_internal = !(parentParser || openInternalEntities);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ }
+ else {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+ }
+ break;
+ case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+ if (dtd->keepProcessing) {
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+ name, sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (declEntity->name != name) {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+ else {
+ poolFinish(&dtd->pool);
+ declEntity->publicId = NULL;
+ declEntity->is_param = XML_TRUE;
+ /* if we have a parent parser or are reading an internal parameter
+ entity, then the entity declaration is not considered "internal"
+ */
+ declEntity->is_internal = !(parentParser || openInternalEntities);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ }
+ else {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+#else /* not XML_DTD */
+ declEntity = NULL;
+#endif /* XML_DTD */
+ break;
+ case XML_ROLE_NOTATION_NAME:
+ declNotationPublicId = NULL;
+ declNotationName = NULL;
+ if (notationDeclHandler) {
+ declNotationName = poolStoreString(&tempPool, enc, s, next);
+ if (!declNotationName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_NOTATION_PUBLIC_ID:
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_PUBLICID;
+ if (declNotationName) { /* means notationDeclHandler != NULL */
+ XML_Char *tem = poolStoreString(&tempPool,
+ enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!tem)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId(tem);
+ declNotationPublicId = tem;
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_NOTATION_SYSTEM_ID:
+ if (declNotationName && notationDeclHandler) {
+ const XML_Char *systemId
+ = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!systemId)
+ return XML_ERROR_NO_MEMORY;
+ *eventEndPP = s;
+ notationDeclHandler(handlerArg,
+ declNotationName,
+ curBase,
+ systemId,
+ declNotationPublicId);
+ handleDefault = XML_FALSE;
+ }
+ poolClear(&tempPool);
+ break;
+ case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+ if (declNotationPublicId && notationDeclHandler) {
+ *eventEndPP = s;
+ notationDeclHandler(handlerArg,
+ declNotationName,
+ curBase,
+ 0,
+ declNotationPublicId);
+ handleDefault = XML_FALSE;
+ }
+ poolClear(&tempPool);
+ break;
+ case XML_ROLE_ERROR:
+ switch (tok) {
+ case XML_TOK_PARAM_ENTITY_REF:
+ /* PE references in internal subset are
+ not allowed within declarations. */
+ return XML_ERROR_PARAM_ENTITY_REF;
+ case XML_TOK_XML_DECL:
+ return XML_ERROR_MISPLACED_XML_PI;
+ default:
+ return XML_ERROR_SYNTAX;
+ }
+#ifdef XML_DTD
+ case XML_ROLE_IGNORE_SECT:
+ {
+ enum XML_Error result;
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ handleDefault = XML_FALSE;
+ result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (!next) {
+ processor = ignoreSectionProcessor;
+ return result;
+ }
+ }
+ break;
+#endif /* XML_DTD */
+ case XML_ROLE_GROUP_OPEN:
+ if (prologState.level >= groupSize) {
+ if (groupSize) {
+ char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ groupConnector = temp;
+ if (dtd->scaffIndex) {
+ int *temp = (int *)REALLOC(dtd->scaffIndex,
+ groupSize * sizeof(int));
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffIndex = temp;
+ }
+ }
+ else {
+ groupConnector = (char *)MALLOC(groupSize = 32);
+ if (!groupConnector)
+ return XML_ERROR_NO_MEMORY;
+ }
+ }
+ groupConnector[prologState.level] = 0;
+ if (dtd->in_eldecl) {
+ int myindex = nextScaffoldPart(parser);
+ if (myindex < 0)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffIndex[dtd->scaffLevel] = myindex;
+ dtd->scaffLevel++;
+ dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_GROUP_SEQUENCE:
+ if (groupConnector[prologState.level] == '|')
+ return XML_ERROR_SYNTAX;
+ groupConnector[prologState.level] = ',';
+ if (dtd->in_eldecl && elementDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_GROUP_CHOICE:
+ if (groupConnector[prologState.level] == ',')
+ return XML_ERROR_SYNTAX;
+ if (dtd->in_eldecl
+ && !groupConnector[prologState.level]
+ && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+ != XML_CTYPE_MIXED)
+ ) {
+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+ = XML_CTYPE_CHOICE;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ groupConnector[prologState.level] = '|';
+ break;
+ case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+ case XML_ROLE_INNER_PARAM_ENTITY_REF:
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (!paramEntityParsing)
+ dtd->keepProcessing = dtd->standalone;
+ else {
+ const XML_Char *name;
+ ENTITY *entity;
+ name = poolStoreString(&dtd->pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+ poolDiscard(&dtd->pool);
+ /* first, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal,
+ otherwise call the skipped entity handler
+ */
+ if (prologState.documentEntity &&
+ (dtd->standalone
+ ? !openInternalEntities
+ : !dtd->hasParamEntityRefs)) {
+ if (!entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (!entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ }
+ else if (!entity) {
+ dtd->keepProcessing = dtd->standalone;
+ /* cannot report skipped entities in declarations */
+ if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
+ skippedEntityHandler(handlerArg, name, 1);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->textPtr) {
+ enum XML_Error result;
+ XML_Bool betweenDecl =
+ (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
+ result = processInternalEntity(parser, entity, betweenDecl);
+ if (result != XML_ERROR_NONE)
+ return result;
+ handleDefault = XML_FALSE;
+ break;
+ }
+ if (externalEntityRefHandler) {
+ dtd->paramEntityRead = XML_FALSE;
+ entity->open = XML_TRUE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId)) {
+ entity->open = XML_FALSE;
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ }
+ entity->open = XML_FALSE;
+ handleDefault = XML_FALSE;
+ if (!dtd->paramEntityRead) {
+ dtd->keepProcessing = dtd->standalone;
+ break;
+ }
+ }
+ else {
+ dtd->keepProcessing = dtd->standalone;
+ break;
+ }
+ }
+#endif /* XML_DTD */
+ if (!dtd->standalone &&
+ notStandaloneHandler &&
+ !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ break;
+
+ /* Element declaration stuff */
+
+ case XML_ROLE_ELEMENT_NAME:
+ if (elementDeclHandler) {
+ declElementType = getElementType(parser, enc, s, next);
+ if (!declElementType)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffLevel = 0;
+ dtd->scaffCount = 0;
+ dtd->in_eldecl = XML_TRUE;
+ handleDefault = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_ANY:
+ case XML_ROLE_CONTENT_EMPTY:
+ if (dtd->in_eldecl) {
+ if (elementDeclHandler) {
+ XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
+ if (!content)
+ return XML_ERROR_NO_MEMORY;
+ content->quant = XML_CQUANT_NONE;
+ content->name = NULL;
+ content->numchildren = 0;
+ content->children = NULL;
+ content->type = ((role == XML_ROLE_CONTENT_ANY) ?
+ XML_CTYPE_ANY :
+ XML_CTYPE_EMPTY);
+ *eventEndPP = s;
+ elementDeclHandler(handlerArg, declElementType->name, content);
+ handleDefault = XML_FALSE;
+ }
+ dtd->in_eldecl = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_PCDATA:
+ if (dtd->in_eldecl) {
+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+ = XML_CTYPE_MIXED;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_ELEMENT:
+ quant = XML_CQUANT_NONE;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_OPT:
+ quant = XML_CQUANT_OPT;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_REP:
+ quant = XML_CQUANT_REP;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_PLUS:
+ quant = XML_CQUANT_PLUS;
+ elementContent:
+ if (dtd->in_eldecl) {
+ ELEMENT_TYPE *el;
+ const XML_Char *name;
+ int nameLen;
+ const char *nxt = (quant == XML_CQUANT_NONE
+ ? next
+ : next - enc->minBytesPerChar);
+ int myindex = nextScaffoldPart(parser);
+ if (myindex < 0)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffold[myindex].type = XML_CTYPE_NAME;
+ dtd->scaffold[myindex].quant = quant;
+ el = getElementType(parser, enc, s, nxt);
+ if (!el)
+ return XML_ERROR_NO_MEMORY;
+ name = el->name;
+ dtd->scaffold[myindex].name = name;
+ nameLen = 0;
+ for (; name[nameLen++]; );
+ dtd->contentStringLen += nameLen;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_GROUP_CLOSE:
+ quant = XML_CQUANT_NONE;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_OPT:
+ quant = XML_CQUANT_OPT;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_REP:
+ quant = XML_CQUANT_REP;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_PLUS:
+ quant = XML_CQUANT_PLUS;
+ closeGroup:
+ if (dtd->in_eldecl) {
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ dtd->scaffLevel--;
+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
+ if (dtd->scaffLevel == 0) {
+ if (!handleDefault) {
+ XML_Content *model = build_model(parser);
+ if (!model)
+ return XML_ERROR_NO_MEMORY;
+ *eventEndPP = s;
+ elementDeclHandler(handlerArg, declElementType->name, model);
+ }
+ dtd->in_eldecl = XML_FALSE;
+ dtd->contentStringLen = 0;
+ }
+ }
+ break;
+ /* End element declaration stuff */
+
+ case XML_ROLE_PI:
+ if (!reportProcessingInstruction(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_COMMENT:
+ if (!reportComment(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_NONE:
+ switch (tok) {
+ case XML_TOK_BOM:
+ handleDefault = XML_FALSE;
+ break;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_NONE:
+ if (startDoctypeDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ENTITY_NONE:
+ if (dtd->keepProcessing && entityDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_NOTATION_NONE:
+ if (notationDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ATTLIST_NONE:
+ if (dtd->keepProcessing && attlistDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ELEMENT_NONE:
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ } /* end of big switch */
+
+ if (handleDefault && defaultHandler)
+ reportDefault(parser, enc, s, next);
+
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ s = next;
+ tok = XmlPrologTok(enc, s, end, &next);
+ }
+ }
+ /* not reached */
+}
+
+static enum XML_Error PTRCALL
+epilogProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ processor = epilogProcessor;
+ eventPtr = s;
+ for (;;) {
+ const char *next = NULL;
+ int tok = XmlPrologTok(encoding, s, end, &next);
+ eventEndPtr = next;
+ switch (tok) {
+ /* report partial linebreak - it might be the last token */
+ case -XML_TOK_PROLOG_S:
+ if (defaultHandler) {
+ reportDefault(parser, encoding, s, next);
+ if (ps_parsing == XML_FINISHED)
+ return XML_ERROR_ABORTED;
+ }
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_TOK_NONE:
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ case XML_TOK_PROLOG_S:
+ if (defaultHandler)
+ reportDefault(parser, encoding, s, next);
+ break;
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, encoding, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, encoding, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_INVALID:
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (!ps_finalBuffer) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (!ps_finalBuffer) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ default:
+ return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+ }
+ eventPtr = s = next;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default: ;
+ }
+ }
+}
+
+static enum XML_Error
+processInternalEntity(XML_Parser parser, ENTITY *entity,
+ XML_Bool betweenDecl)
+{
+ const char *textStart, *textEnd;
+ const char *next;
+ enum XML_Error result;
+ OPEN_INTERNAL_ENTITY *openEntity;
+
+ if (freeInternalEntities) {
+ openEntity = freeInternalEntities;
+ freeInternalEntities = openEntity->next;
+ }
+ else {
+ openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
+ if (!openEntity)
+ return XML_ERROR_NO_MEMORY;
+ }
+ entity->open = XML_TRUE;
+ entity->processed = 0;
+ openEntity->next = openInternalEntities;
+ openInternalEntities = openEntity;
+ openEntity->entity = entity;
+ openEntity->startTagLevel = tagLevel;
+ openEntity->betweenDecl = betweenDecl;
+ openEntity->internalEventPtr = NULL;
+ openEntity->internalEventEndPtr = NULL;
+ textStart = (char *)entity->textPtr;
+ textEnd = (char *)(entity->textPtr + entity->textLen);
+
+#ifdef XML_DTD
+ if (entity->is_param) {
+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
+ next, &next, XML_FALSE);
+ }
+ else
+#endif /* XML_DTD */
+ result = doContent(parser, tagLevel, internalEncoding, textStart,
+ textEnd, &next, XML_FALSE);
+
+ if (result == XML_ERROR_NONE) {
+ if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+ entity->processed = (int)(next - textStart);
+ processor = internalEntityProcessor;
+ }
+ else {
+ entity->open = XML_FALSE;
+ openInternalEntities = openEntity->next;
+ /* put openEntity back in list of free instances */
+ openEntity->next = freeInternalEntities;
+ freeInternalEntities = openEntity;
+ }
+ }
+ return result;
+}
+
+static enum XML_Error PTRCALL
+internalEntityProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ ENTITY *entity;
+ const char *textStart, *textEnd;
+ const char *next;
+ enum XML_Error result;
+ OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
+ if (!openEntity)
+ return XML_ERROR_UNEXPECTED_STATE;
+
+ entity = openEntity->entity;
+ textStart = ((char *)entity->textPtr) + entity->processed;
+ textEnd = (char *)(entity->textPtr + entity->textLen);
+
+#ifdef XML_DTD
+ if (entity->is_param) {
+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
+ next, &next, XML_FALSE);
+ }
+ else
+#endif /* XML_DTD */
+ result = doContent(parser, openEntity->startTagLevel, internalEncoding,
+ textStart, textEnd, &next, XML_FALSE);
+
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+ entity->processed = (int)(next - (char *)entity->textPtr);
+ return result;
+ }
+ else {
+ entity->open = XML_FALSE;
+ openInternalEntities = openEntity->next;
+ /* put openEntity back in list of free instances */
+ openEntity->next = freeInternalEntities;
+ freeInternalEntities = openEntity;
+ }
+
+#ifdef XML_DTD
+ if (entity->is_param) {
+ int tok;
+ processor = prologProcessor;
+ tok = XmlPrologTok(encoding, s, end, &next);
+ return doProlog(parser, encoding, s, end, tok, next, nextPtr,
+ (XML_Bool)!ps_finalBuffer);
+ }
+ else
+#endif /* XML_DTD */
+ {
+ processor = contentProcessor;
+ /* see externalEntityContentProcessor vs contentProcessor */
+ return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
+ nextPtr, (XML_Bool)!ps_finalBuffer);
+ }
+}
+
+static enum XML_Error PTRCALL
+errorProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+ const char *ptr, const char *end,
+ STRING_POOL *pool)
+{
+ enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
+ end, pool);
+ if (result)
+ return result;
+ if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+ poolChop(pool);
+ if (!poolAppendChar(pool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+ const char *ptr, const char *end,
+ STRING_POOL *pool)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ for (;;) {
+ const char *next;
+ int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+ switch (tok) {
+ case XML_TOK_NONE:
+ return XML_ERROR_NONE;
+ case XML_TOK_INVALID:
+ if (enc == encoding)
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_CHAR_REF:
+ {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, ptr);
+ if (n < 0) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ if (!isCdata
+ && n == 0x20 /* space */
+ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ n = XmlEncode(n, (ICHAR *)buf);
+ if (!n) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ for (i = 0; i < n; i++) {
+ if (!poolAppendChar(pool, buf[i]))
+ return XML_ERROR_NO_MEMORY;
+ }
+ }
+ break;
+ case XML_TOK_DATA_CHARS:
+ if (!poolAppend(pool, enc, ptr, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_TRAILING_CR:
+ next = ptr + enc->minBytesPerChar;
+ /* fall through */
+ case XML_TOK_ATTRIBUTE_VALUE_S:
+ case XML_TOK_DATA_NEWLINE:
+ if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ if (!poolAppendChar(pool, 0x20))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_ENTITY_REF:
+ {
+ const XML_Char *name;
+ ENTITY *entity;
+ char checkEntityDecl;
+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (ch) {
+ if (!poolAppendChar(pool, ch))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ }
+ name = poolStoreString(&temp2Pool, enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+ poolDiscard(&temp2Pool);
+ /* First, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal.
+ */
+ if (pool == &dtd->pool) /* are we called from prolog? */
+ checkEntityDecl =
+#ifdef XML_DTD
+ prologState.documentEntity &&
+#endif /* XML_DTD */
+ (dtd->standalone
+ ? !openInternalEntities
+ : !dtd->hasParamEntityRefs);
+ else /* if (pool == &tempPool): we are called from content */
+ checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
+ if (checkEntityDecl) {
+ if (!entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (!entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ }
+ else if (!entity) {
+ /* Cannot report skipped entity here - see comments on
+ skippedEntityHandler.
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, name, 0);
+ */
+ /* Cannot call the default handler because this would be
+ out of sync with the call to the startElementHandler.
+ if ((pool == &tempPool) && defaultHandler)
+ reportDefault(parser, enc, ptr, next);
+ */
+ break;
+ }
+ if (entity->open) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ }
+ if (entity->notation) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BINARY_ENTITY_REF;
+ }
+ if (!entity->textPtr) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+ }
+ else {
+ enum XML_Error result;
+ const XML_Char *textEnd = entity->textPtr + entity->textLen;
+ entity->open = XML_TRUE;
+ result = appendAttributeValue(parser, internalEncoding, isCdata,
+ (char *)entity->textPtr,
+ (char *)textEnd, pool);
+ entity->open = XML_FALSE;
+ if (result)
+ return result;
+ }
+ }
+ break;
+ default:
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ ptr = next;
+ }
+ /* not reached */
+}
+
+static enum XML_Error
+storeEntityValue(XML_Parser parser,
+ const ENCODING *enc,
+ const char *entityTextPtr,
+ const char *entityTextEnd)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ STRING_POOL *pool = &(dtd->entityValuePool);
+ enum XML_Error result = XML_ERROR_NONE;
+#ifdef XML_DTD
+ int oldInEntityValue = prologState.inEntityValue;
+ prologState.inEntityValue = 1;
+#endif /* XML_DTD */
+ /* never return Null for the value argument in EntityDeclHandler,
+ since this would indicate an external entity; therefore we
+ have to make sure that entityValuePool.start is not null */
+ if (!pool->blocks) {
+ if (!poolGrow(pool))
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ for (;;) {
+ const char *next;
+ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+ switch (tok) {
+ case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+ if (isParamEntity || enc != encoding) {
+ const XML_Char *name;
+ ENTITY *entity;
+ name = poolStoreString(&tempPool, enc,
+ entityTextPtr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+ poolDiscard(&tempPool);
+ if (!entity) {
+ /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
+ /* cannot report skipped entity here - see comments on
+ skippedEntityHandler
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, name, 0);
+ */
+ dtd->keepProcessing = dtd->standalone;
+ goto endEntityValue;
+ }
+ if (entity->open) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_RECURSIVE_ENTITY_REF;
+ goto endEntityValue;
+ }
+ if (entity->systemId) {
+ if (externalEntityRefHandler) {
+ dtd->paramEntityRead = XML_FALSE;
+ entity->open = XML_TRUE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId)) {
+ entity->open = XML_FALSE;
+ result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ goto endEntityValue;
+ }
+ entity->open = XML_FALSE;
+ if (!dtd->paramEntityRead)
+ dtd->keepProcessing = dtd->standalone;
+ }
+ else
+ dtd->keepProcessing = dtd->standalone;
+ }
+ else {
+ entity->open = XML_TRUE;
+ result = storeEntityValue(parser,
+ internalEncoding,
+ (char *)entity->textPtr,
+ (char *)(entity->textPtr
+ + entity->textLen));
+ entity->open = XML_FALSE;
+ if (result)
+ goto endEntityValue;
+ }
+ break;
+ }
+#endif /* XML_DTD */
+ /* In the internal subset, PE references are not legal
+ within markup declarations, e.g entity values in this case. */
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_PARAM_ENTITY_REF;
+ goto endEntityValue;
+ case XML_TOK_NONE:
+ result = XML_ERROR_NONE;
+ goto endEntityValue;
+ case XML_TOK_ENTITY_REF:
+ case XML_TOK_DATA_CHARS:
+ if (!poolAppend(pool, enc, entityTextPtr, next)) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ break;
+ case XML_TOK_TRAILING_CR:
+ next = entityTextPtr + enc->minBytesPerChar;
+ /* fall through */
+ case XML_TOK_DATA_NEWLINE:
+ if (pool->end == pool->ptr && !poolGrow(pool)) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ *(pool->ptr)++ = 0xA;
+ break;
+ case XML_TOK_CHAR_REF:
+ {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, entityTextPtr);
+ if (n < 0) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_BAD_CHAR_REF;
+ goto endEntityValue;
+ }
+ n = XmlEncode(n, (ICHAR *)buf);
+ if (!n) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_BAD_CHAR_REF;
+ goto endEntityValue;
+ }
+ for (i = 0; i < n; i++) {
+ if (pool->end == pool->ptr && !poolGrow(pool)) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ *(pool->ptr)++ = buf[i];
+ }
+ }
+ break;
+ case XML_TOK_PARTIAL:
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_INVALID_TOKEN;
+ goto endEntityValue;
+ case XML_TOK_INVALID:
+ if (enc == encoding)
+ eventPtr = next;
+ result = XML_ERROR_INVALID_TOKEN;
+ goto endEntityValue;
+ default:
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_UNEXPECTED_STATE;
+ goto endEntityValue;
+ }
+ entityTextPtr = next;
+ }
+endEntityValue:
+#ifdef XML_DTD
+ prologState.inEntityValue = oldInEntityValue;
+#endif /* XML_DTD */
+ return result;
+}
+
+static void FASTCALL
+normalizeLines(XML_Char *s)
+{
+ XML_Char *p;
+ for (;; s++) {
+ if (*s == XML_T('\0'))
+ return;
+ if (*s == 0xD)
+ break;
+ }
+ p = s;
+ do {
+ if (*s == 0xD) {
+ *p++ = 0xA;
+ if (*++s == 0xA)
+ s++;
+ }
+ else
+ *p++ = *s++;
+ } while (*s);
+ *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end)
+{
+ const XML_Char *target;
+ XML_Char *data;
+ const char *tem;
+ if (!processingInstructionHandler) {
+ if (defaultHandler)
+ reportDefault(parser, enc, start, end);
+ return 1;
+ }
+ start += enc->minBytesPerChar * 2;
+ tem = start + XmlNameLength(enc, start);
+ target = poolStoreString(&tempPool, enc, start, tem);
+ if (!target)
+ return 0;
+ poolFinish(&tempPool);
+ data = poolStoreString(&tempPool, enc,
+ XmlSkipS(enc, tem),
+ end - enc->minBytesPerChar*2);
+ if (!data)
+ return 0;
+ normalizeLines(data);
+ processingInstructionHandler(handlerArg, target, data);
+ poolClear(&tempPool);
+ return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end)
+{
+ XML_Char *data;
+ if (!commentHandler) {
+ if (defaultHandler)
+ reportDefault(parser, enc, start, end);
+ return 1;
+ }
+ data = poolStoreString(&tempPool,
+ enc,
+ start + enc->minBytesPerChar * 4,
+ end - enc->minBytesPerChar * 3);
+ if (!data)
+ return 0;
+ normalizeLines(data);
+ commentHandler(handlerArg, data);
+ poolClear(&tempPool);
+ return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc,
+ const char *s, const char *end)
+{
+ if (MUST_CONVERT(enc, s)) {
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ do {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = s;
+ defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
+ *eventPP = s;
+ } while (s != end);
+ }
+ else
+ defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
+ XML_Bool isId, const XML_Char *value, XML_Parser parser)
+{
+ DEFAULT_ATTRIBUTE *att;
+ if (value || isId) {
+ /* The handling of default attributes gets messed up if we have
+ a default which duplicates a non-default. */
+ int i;
+ for (i = 0; i < type->nDefaultAtts; i++)
+ if (attId == type->defaultAtts[i].id)
+ return 1;
+ if (isId && !type->idAtt && !attId->xmlns)
+ type->idAtt = attId;
+ }
+ if (type->nDefaultAtts == type->allocDefaultAtts) {
+ if (type->allocDefaultAtts == 0) {
+ type->allocDefaultAtts = 8;
+ type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
+ * sizeof(DEFAULT_ATTRIBUTE));
+ if (!type->defaultAtts)
+ return 0;
+ }
+ else {
+ DEFAULT_ATTRIBUTE *temp;
+ int count = type->allocDefaultAtts * 2;
+ temp = (DEFAULT_ATTRIBUTE *)
+ REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+ if (temp == NULL)
+ return 0;
+ type->allocDefaultAtts = count;
+ type->defaultAtts = temp;
+ }
+ }
+ att = type->defaultAtts + type->nDefaultAtts;
+ att->id = attId;
+ att->value = value;
+ att->isCdata = isCdata;
+ if (!isCdata)
+ attId->maybeTokenized = XML_TRUE;
+ type->nDefaultAtts += 1;
+ return 1;
+}
+
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ const XML_Char *name;
+ for (name = elementType->name; *name; name++) {
+ if (*name == XML_T(':')) {
+ PREFIX *prefix;
+ const XML_Char *s;
+ for (s = elementType->name; s != name; s++) {
+ if (!poolAppendChar(&dtd->pool, *s))
+ return 0;
+ }
+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ return 0;
+ prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+ sizeof(PREFIX));
+ if (!prefix)
+ return 0;
+ if (prefix->name == poolStart(&dtd->pool))
+ poolFinish(&dtd->pool);
+ else
+ poolDiscard(&dtd->pool);
+ elementType->prefix = prefix;
+
+ }
+ }
+ return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ ATTRIBUTE_ID *id;
+ const XML_Char *name;
+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ return NULL;
+ name = poolStoreString(&dtd->pool, enc, start, end);
+ if (!name)
+ return NULL;
+ /* skip quotation mark - its storage will be re-used (like in name[-1]) */
+ ++name;
+ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
+ if (!id)
+ return NULL;
+ if (id->name != name)
+ poolDiscard(&dtd->pool);
+ else {
+ poolFinish(&dtd->pool);
+ if (!ns)
+ ;
+ else if (name[0] == XML_T('x')
+ && name[1] == XML_T('m')
+ && name[2] == XML_T('l')
+ && name[3] == XML_T('n')
+ && name[4] == XML_T('s')
+ && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+ if (name[5] == XML_T('\0'))
+ id->prefix = &dtd->defaultPrefix;
+ else
+ id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
+ id->xmlns = XML_TRUE;
+ }
+ else {
+ int i;
+ for (i = 0; name[i]; i++) {
+ /* attributes without prefix are *not* in the default namespace */
+ if (name[i] == XML_T(':')) {
+ int j;
+ for (j = 0; j < i; j++) {
+ if (!poolAppendChar(&dtd->pool, name[j]))
+ return NULL;
+ }
+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ return NULL;
+ id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+ sizeof(PREFIX));
+ if (!id->prefix)
+ return NULL;
+ if (id->prefix->name == poolStart(&dtd->pool))
+ poolFinish(&dtd->pool);
+ else
+ poolDiscard(&dtd->pool);
+ break;
+ }
+ }
+ }
+ }
+ return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static const XML_Char *
+getContext(XML_Parser parser)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ HASH_TABLE_ITER iter;
+ XML_Bool needSep = XML_FALSE;
+
+ if (dtd->defaultPrefix.binding) {
+ int i;
+ int len;
+ if (!poolAppendChar(&tempPool, XML_T('=')))
+ return NULL;
+ len = dtd->defaultPrefix.binding->uriLen;
+ if (namespaceSeparator)
+ len--;
+ for (i = 0; i < len; i++)
+ if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
+ return NULL;
+ needSep = XML_TRUE;
+ }
+
+ hashTableIterInit(&iter, &(dtd->prefixes));
+ for (;;) {
+ int i;
+ int len;
+ const XML_Char *s;
+ PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+ if (!prefix)
+ break;
+ if (!prefix->binding)
+ continue;
+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ return NULL;
+ for (s = prefix->name; *s; s++)
+ if (!poolAppendChar(&tempPool, *s))
+ return NULL;
+ if (!poolAppendChar(&tempPool, XML_T('=')))
+ return NULL;
+ len = prefix->binding->uriLen;
+ if (namespaceSeparator)
+ len--;
+ for (i = 0; i < len; i++)
+ if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+ return NULL;
+ needSep = XML_TRUE;
+ }
+
+
+ hashTableIterInit(&iter, &(dtd->generalEntities));
+ for (;;) {
+ const XML_Char *s;
+ ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (!e->open)
+ continue;
+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ return NULL;
+ for (s = e->name; *s; s++)
+ if (!poolAppendChar(&tempPool, *s))
+ return 0;
+ needSep = XML_TRUE;
+ }
+
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return NULL;
+ return tempPool.start;
+}
+
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ const XML_Char *s = context;
+
+ while (*context != XML_T('\0')) {
+ if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+ ENTITY *e;
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_FALSE;
+ e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
+ if (e)
+ e->open = XML_TRUE;
+ if (*s != XML_T('\0'))
+ s++;
+ context = s;
+ poolDiscard(&tempPool);
+ }
+ else if (*s == XML_T('=')) {
+ PREFIX *prefix;
+ if (poolLength(&tempPool) == 0)
+ prefix = &dtd->defaultPrefix;
+ else {
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_FALSE;
+ prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
+ sizeof(PREFIX));
+ if (!prefix)
+ return XML_FALSE;
+ if (prefix->name == poolStart(&tempPool)) {
+ prefix->name = poolCopyString(&dtd->pool, prefix->name);
+ if (!prefix->name)
+ return XML_FALSE;
+ }
+ poolDiscard(&tempPool);
+ }
+ for (context = s + 1;
+ *context != CONTEXT_SEP && *context != XML_T('\0');
+ context++)
+ if (!poolAppendChar(&tempPool, *context))
+ return XML_FALSE;
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_FALSE;
+ if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
+ &inheritedBindings) != XML_ERROR_NONE)
+ return XML_FALSE;
+ poolDiscard(&tempPool);
+ if (*context != XML_T('\0'))
+ ++context;
+ s = context;
+ }
+ else {
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_FALSE;
+ s++;
+ }
+ }
+ return XML_TRUE;
+}
+
+static void FASTCALL
+normalizePublicId(XML_Char *publicId)
+{
+ XML_Char *p = publicId;
+ XML_Char *s;
+ for (s = publicId; *s; s++) {
+ switch (*s) {
+ case 0x20:
+ case 0xD:
+ case 0xA:
+ if (p != publicId && p[-1] != 0x20)
+ *p++ = 0x20;
+ break;
+ default:
+ *p++ = *s;
+ }
+ }
+ if (p != publicId && p[-1] == 0x20)
+ --p;
+ *p = XML_T('\0');
+}
+
+static DTD *
+dtdCreate(const XML_Memory_Handling_Suite *ms)
+{
+ DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
+ if (p == NULL)
+ return p;
+ poolInit(&(p->pool), ms);
+ poolInit(&(p->entityValuePool), ms);
+ hashTableInit(&(p->generalEntities), ms);
+ hashTableInit(&(p->elementTypes), ms);
+ hashTableInit(&(p->attributeIds), ms);
+ hashTableInit(&(p->prefixes), ms);
+#ifdef XML_DTD
+ p->paramEntityRead = XML_FALSE;
+ hashTableInit(&(p->paramEntities), ms);
+#endif /* XML_DTD */
+ p->defaultPrefix.name = NULL;
+ p->defaultPrefix.binding = NULL;
+
+ p->in_eldecl = XML_FALSE;
+ p->scaffIndex = NULL;
+ p->scaffold = NULL;
+ p->scaffLevel = 0;
+ p->scaffSize = 0;
+ p->scaffCount = 0;
+ p->contentStringLen = 0;
+
+ p->keepProcessing = XML_TRUE;
+ p->hasParamEntityRefs = XML_FALSE;
+ p->standalone = XML_FALSE;
+ return p;
+}
+
+static void
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
+{
+ HASH_TABLE_ITER iter;
+ hashTableIterInit(&iter, &(p->elementTypes));
+ for (;;) {
+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (e->allocDefaultAtts != 0)
+ ms->free_fcn(e->defaultAtts);
+ }
+ hashTableClear(&(p->generalEntities));
+#ifdef XML_DTD
+ p->paramEntityRead = XML_FALSE;
+ hashTableClear(&(p->paramEntities));
+#endif /* XML_DTD */
+ hashTableClear(&(p->elementTypes));
+ hashTableClear(&(p->attributeIds));
+ hashTableClear(&(p->prefixes));
+ poolClear(&(p->pool));
+ poolClear(&(p->entityValuePool));
+ p->defaultPrefix.name = NULL;
+ p->defaultPrefix.binding = NULL;
+
+ p->in_eldecl = XML_FALSE;
+
+ ms->free_fcn(p->scaffIndex);
+ p->scaffIndex = NULL;
+ ms->free_fcn(p->scaffold);
+ p->scaffold = NULL;
+
+ p->scaffLevel = 0;
+ p->scaffSize = 0;
+ p->scaffCount = 0;
+ p->contentStringLen = 0;
+
+ p->keepProcessing = XML_TRUE;
+ p->hasParamEntityRefs = XML_FALSE;
+ p->standalone = XML_FALSE;
+}
+
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
+{
+ HASH_TABLE_ITER iter;
+ hashTableIterInit(&iter, &(p->elementTypes));
+ for (;;) {
+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (e->allocDefaultAtts != 0)
+ ms->free_fcn(e->defaultAtts);
+ }
+ hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+ hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+ hashTableDestroy(&(p->elementTypes));
+ hashTableDestroy(&(p->attributeIds));
+ hashTableDestroy(&(p->prefixes));
+ poolDestroy(&(p->pool));
+ poolDestroy(&(p->entityValuePool));
+ if (isDocEntity) {
+ ms->free_fcn(p->scaffIndex);
+ ms->free_fcn(p->scaffold);
+ }
+ ms->free_fcn(p);
+}
+
+/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
+ The new DTD has already been initialized.
+*/
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
+{
+ HASH_TABLE_ITER iter;
+
+ /* Copy the prefix table. */
+
+ hashTableIterInit(&iter, &(oldDtd->prefixes));
+ for (;;) {
+ const XML_Char *name;
+ const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+ if (!oldP)
+ break;
+ name = poolCopyString(&(newDtd->pool), oldP->name);
+ if (!name)
+ return 0;
+ if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+ return 0;
+ }
+
+ hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+ /* Copy the attribute id table. */
+
+ for (;;) {
+ ATTRIBUTE_ID *newA;
+ const XML_Char *name;
+ const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+ if (!oldA)
+ break;
+ /* Remember to allocate the scratch byte before the name. */
+ if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+ return 0;
+ name = poolCopyString(&(newDtd->pool), oldA->name);
+ if (!name)
+ return 0;
+ ++name;
+ newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
+ sizeof(ATTRIBUTE_ID));
+ if (!newA)
+ return 0;
+ newA->maybeTokenized = oldA->maybeTokenized;
+ if (oldA->prefix) {
+ newA->xmlns = oldA->xmlns;
+ if (oldA->prefix == &oldDtd->defaultPrefix)
+ newA->prefix = &newDtd->defaultPrefix;
+ else
+ newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+ oldA->prefix->name, 0);
+ }
+ }
+
+ /* Copy the element type table. */
+
+ hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+ for (;;) {
+ int i;
+ ELEMENT_TYPE *newE;
+ const XML_Char *name;
+ const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!oldE)
+ break;
+ name = poolCopyString(&(newDtd->pool), oldE->name);
+ if (!name)
+ return 0;
+ newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
+ sizeof(ELEMENT_TYPE));
+ if (!newE)
+ return 0;
+ if (oldE->nDefaultAtts) {
+ newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
+ ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ if (!newE->defaultAtts) {
+ ms->free_fcn(newE);
+ return 0;
+ }
+ }
+ if (oldE->idAtt)
+ newE->idAtt = (ATTRIBUTE_ID *)
+ lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+ newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+ if (oldE->prefix)
+ newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+ oldE->prefix->name, 0);
+ for (i = 0; i < newE->nDefaultAtts; i++) {
+ newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
+ lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+ newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+ if (oldE->defaultAtts[i].value) {
+ newE->defaultAtts[i].value
+ = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+ if (!newE->defaultAtts[i].value)
+ return 0;
+ }
+ else
+ newE->defaultAtts[i].value = NULL;
+ }
+ }
+
+ /* Copy the entity tables. */
+ if (!copyEntityTable(&(newDtd->generalEntities),
+ &(newDtd->pool),
+ &(oldDtd->generalEntities)))
+ return 0;
+
+#ifdef XML_DTD
+ if (!copyEntityTable(&(newDtd->paramEntities),
+ &(newDtd->pool),
+ &(oldDtd->paramEntities)))
+ return 0;
+ newDtd->paramEntityRead = oldDtd->paramEntityRead;
+#endif /* XML_DTD */
+
+ newDtd->keepProcessing = oldDtd->keepProcessing;
+ newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
+ newDtd->standalone = oldDtd->standalone;
+
+ /* Don't want deep copying for scaffolding */
+ newDtd->in_eldecl = oldDtd->in_eldecl;
+ newDtd->scaffold = oldDtd->scaffold;
+ newDtd->contentStringLen = oldDtd->contentStringLen;
+ newDtd->scaffSize = oldDtd->scaffSize;
+ newDtd->scaffLevel = oldDtd->scaffLevel;
+ newDtd->scaffIndex = oldDtd->scaffIndex;
+
+ return 1;
+} /* End dtdCopy */
+
+static int
+copyEntityTable(HASH_TABLE *newTable,
+ STRING_POOL *newPool,
+ const HASH_TABLE *oldTable)
+{
+ HASH_TABLE_ITER iter;
+ const XML_Char *cachedOldBase = NULL;
+ const XML_Char *cachedNewBase = NULL;
+
+ hashTableIterInit(&iter, oldTable);
+
+ for (;;) {
+ ENTITY *newE;
+ const XML_Char *name;
+ const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+ if (!oldE)
+ break;
+ name = poolCopyString(newPool, oldE->name);
+ if (!name)
+ return 0;
+ newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+ if (!newE)
+ return 0;
+ if (oldE->systemId) {
+ const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+ if (!tem)
+ return 0;
+ newE->systemId = tem;
+ if (oldE->base) {
+ if (oldE->base == cachedOldBase)
+ newE->base = cachedNewBase;
+ else {
+ cachedOldBase = oldE->base;
+ tem = poolCopyString(newPool, cachedOldBase);
+ if (!tem)
+ return 0;
+ cachedNewBase = newE->base = tem;
+ }
+ }
+ if (oldE->publicId) {
+ tem = poolCopyString(newPool, oldE->publicId);
+ if (!tem)
+ return 0;
+ newE->publicId = tem;
+ }
+ }
+ else {
+ const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
+ oldE->textLen);
+ if (!tem)
+ return 0;
+ newE->textPtr = tem;
+ newE->textLen = oldE->textLen;
+ }
+ if (oldE->notation) {
+ const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+ if (!tem)
+ return 0;
+ newE->notation = tem;
+ }
+ newE->is_param = oldE->is_param;
+ newE->is_internal = oldE->is_internal;
+ }
+ return 1;
+}
+
+#define INIT_POWER 6
+
+static XML_Bool FASTCALL
+keyeq(KEY s1, KEY s2)
+{
+ for (; *s1 == *s2; s1++, s2++)
+ if (*s1 == 0)
+ return XML_TRUE;
+ return XML_FALSE;
+}
+
+static unsigned long FASTCALL
+hash(KEY s)
+{
+ unsigned long h = 0;
+ while (*s)
+ h = CHAR_HASH(h, *s++);
+ return h;
+}
+
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+ size_t i;
+ if (table->size == 0) {
+ size_t tsize;
+ if (!createSize)
+ return NULL;
+ table->power = INIT_POWER;
+ /* table->size is a power of 2 */
+ table->size = (size_t)1 << INIT_POWER;
+ tsize = table->size * sizeof(NAMED *);
+ table->v = (NAMED **)table->mem->malloc_fcn(tsize);
+ if (!table->v) {
+ table->size = 0;
+ return NULL;
+ }
+ memset(table->v, 0, tsize);
+ i = hash(name) & ((unsigned long)table->size - 1);
+ }
+ else {
+ unsigned long h = hash(name);
+ unsigned long mask = (unsigned long)table->size - 1;
+ unsigned char step = 0;
+ i = h & mask;
+ while (table->v[i]) {
+ if (keyeq(name, table->v[i]->name))
+ return table->v[i];
+ if (!step)
+ step = PROBE_STEP(h, mask, table->power);
+ i < step ? (i += table->size - step) : (i -= step);
+ }
+ if (!createSize)
+ return NULL;
+
+ /* check for overflow (table is half full) */
+ if (table->used >> (table->power - 1)) {
+ unsigned char newPower = table->power + 1;
+ size_t newSize = (size_t)1 << newPower;
+ unsigned long newMask = (unsigned long)newSize - 1;
+ size_t tsize = newSize * sizeof(NAMED *);
+ NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
+ if (!newV)
+ return NULL;
+ memset(newV, 0, tsize);
+ for (i = 0; i < table->size; i++)
+ if (table->v[i]) {
+ unsigned long newHash = hash(table->v[i]->name);
+ size_t j = newHash & newMask;
+ step = 0;
+ while (newV[j]) {
+ if (!step)
+ step = PROBE_STEP(newHash, newMask, newPower);
+ j < step ? (j += newSize - step) : (j -= step);
+ }
+ newV[j] = table->v[i];
+ }
+ table->mem->free_fcn(table->v);
+ table->v = newV;
+ table->power = newPower;
+ table->size = newSize;
+ i = h & newMask;
+ step = 0;
+ while (table->v[i]) {
+ if (!step)
+ step = PROBE_STEP(h, newMask, newPower);
+ i < step ? (i += newSize - step) : (i -= step);
+ }
+ }
+ }
+ table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
+ if (!table->v[i])
+ return NULL;
+ memset(table->v[i], 0, createSize);
+ table->v[i]->name = name;
+ (table->used)++;
+ return table->v[i];
+}
+
+static void FASTCALL
+hashTableClear(HASH_TABLE *table)
+{
+ size_t i;
+ for (i = 0; i < table->size; i++) {
+ table->mem->free_fcn(table->v[i]);
+ table->v[i] = NULL;
+ }
+ table->used = 0;
+}
+
+static void FASTCALL
+hashTableDestroy(HASH_TABLE *table)
+{
+ size_t i;
+ for (i = 0; i < table->size; i++)
+ table->mem->free_fcn(table->v[i]);
+ table->mem->free_fcn(table->v);
+}
+
+static void FASTCALL
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
+{
+ p->power = 0;
+ p->size = 0;
+ p->used = 0;
+ p->v = NULL;
+ p->mem = ms;
+}
+
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+ iter->p = table->v;
+ iter->end = iter->p + table->size;
+}
+
+static NAMED * FASTCALL
+hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+ while (iter->p != iter->end) {
+ NAMED *tem = *(iter->p)++;
+ if (tem)
+ return tem;
+ }
+ return NULL;
+}
+
+static void FASTCALL
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
+{
+ pool->blocks = NULL;
+ pool->freeBlocks = NULL;
+ pool->start = NULL;
+ pool->ptr = NULL;
+ pool->end = NULL;
+ pool->mem = ms;
+}
+
+static void FASTCALL
+poolClear(STRING_POOL *pool)
+{
+ if (!pool->freeBlocks)
+ pool->freeBlocks = pool->blocks;
+ else {
+ BLOCK *p = pool->blocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ p->next = pool->freeBlocks;
+ pool->freeBlocks = p;
+ p = tem;
+ }
+ }
+ pool->blocks = NULL;
+ pool->start = NULL;
+ pool->ptr = NULL;
+ pool->end = NULL;
+}
+
+static void FASTCALL
+poolDestroy(STRING_POOL *pool)
+{
+ BLOCK *p = pool->blocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ pool->mem->free_fcn(p);
+ p = tem;
+ }
+ p = pool->freeBlocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ pool->mem->free_fcn(p);
+ p = tem;
+ }
+}
+
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end)
+{
+ if (!pool->ptr && !poolGrow(pool))
+ return NULL;
+ for (;;) {
+ XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if (ptr == end)
+ break;
+ if (!poolGrow(pool))
+ return NULL;
+ }
+ return pool->start;
+}
+
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+ do {
+ if (!poolAppendChar(pool, *s))
+ return NULL;
+ } while (*s++);
+ s = pool->start;
+ poolFinish(pool);
+ return s;
+}
+
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+ if (!pool->ptr && !poolGrow(pool))
+ return NULL;
+ for (; n > 0; --n, s++) {
+ if (!poolAppendChar(pool, *s))
+ return NULL;
+ }
+ s = pool->start;
+ poolFinish(pool);
+ return s;
+}
+
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s)
+{
+ while (*s) {
+ if (!poolAppendChar(pool, *s))
+ return NULL;
+ s++;
+ }
+ return pool->start;
+}
+
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end)
+{
+ if (!poolAppend(pool, enc, ptr, end))
+ return NULL;
+ if (pool->ptr == pool->end && !poolGrow(pool))
+ return NULL;
+ *(pool->ptr)++ = 0;
+ return pool->start;
+}
+
+static XML_Bool FASTCALL
+poolGrow(STRING_POOL *pool)
+{
+ if (pool->freeBlocks) {
+ if (pool->start == 0) {
+ pool->blocks = pool->freeBlocks;
+ pool->freeBlocks = pool->freeBlocks->next;
+ pool->blocks->next = NULL;
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + pool->blocks->size;
+ pool->ptr = pool->start;
+ return XML_TRUE;
+ }
+ if (pool->end - pool->start < pool->freeBlocks->size) {
+ BLOCK *tem = pool->freeBlocks->next;
+ pool->freeBlocks->next = pool->blocks;
+ pool->blocks = pool->freeBlocks;
+ pool->freeBlocks = tem;
+ memcpy(pool->blocks->s, pool->start,
+ (pool->end - pool->start) * sizeof(XML_Char));
+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + pool->blocks->size;
+ return XML_TRUE;
+ }
+ }
+ if (pool->blocks && pool->start == pool->blocks->s) {
+ int blockSize = (int)(pool->end - pool->start)*2;
+ pool->blocks = (BLOCK *)
+ pool->mem->realloc_fcn(pool->blocks,
+ (offsetof(BLOCK, s)
+ + blockSize * sizeof(XML_Char)));
+ if (pool->blocks == NULL)
+ return XML_FALSE;
+ pool->blocks->size = blockSize;
+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + blockSize;
+ }
+ else {
+ BLOCK *tem;
+ int blockSize = (int)(pool->end - pool->start);
+ if (blockSize < INIT_BLOCK_SIZE)
+ blockSize = INIT_BLOCK_SIZE;
+ else
+ blockSize *= 2;
+ tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
+ + blockSize * sizeof(XML_Char));
+ if (!tem)
+ return XML_FALSE;
+ tem->size = blockSize;
+ tem->next = pool->blocks;
+ pool->blocks = tem;
+ if (pool->ptr != pool->start)
+ memcpy(tem->s, pool->start,
+ (pool->ptr - pool->start) * sizeof(XML_Char));
+ pool->ptr = tem->s + (pool->ptr - pool->start);
+ pool->start = tem->s;
+ pool->end = tem->s + blockSize;
+ }
+ return XML_TRUE;
+}
+
+static int FASTCALL
+nextScaffoldPart(XML_Parser parser)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ CONTENT_SCAFFOLD * me;
+ int next;
+
+ if (!dtd->scaffIndex) {
+ dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
+ if (!dtd->scaffIndex)
+ return -1;
+ dtd->scaffIndex[0] = 0;
+ }
+
+ if (dtd->scaffCount >= dtd->scaffSize) {
+ CONTENT_SCAFFOLD *temp;
+ if (dtd->scaffold) {
+ temp = (CONTENT_SCAFFOLD *)
+ REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+ if (temp == NULL)
+ return -1;
+ dtd->scaffSize *= 2;
+ }
+ else {
+ temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
+ * sizeof(CONTENT_SCAFFOLD));
+ if (temp == NULL)
+ return -1;
+ dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
+ }
+ dtd->scaffold = temp;
+ }
+ next = dtd->scaffCount++;
+ me = &dtd->scaffold[next];
+ if (dtd->scaffLevel) {
+ CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
+ if (parent->lastchild) {
+ dtd->scaffold[parent->lastchild].nextsib = next;
+ }
+ if (!parent->childcnt)
+ parent->firstchild = next;
+ parent->lastchild = next;
+ parent->childcnt++;
+ }
+ me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
+ return next;
+}
+
+static void
+build_node(XML_Parser parser,
+ int src_node,
+ XML_Content *dest,
+ XML_Content **contpos,
+ XML_Char **strpos)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ dest->type = dtd->scaffold[src_node].type;
+ dest->quant = dtd->scaffold[src_node].quant;
+ if (dest->type == XML_CTYPE_NAME) {
+ const XML_Char *src;
+ dest->name = *strpos;
+ src = dtd->scaffold[src_node].name;
+ for (;;) {
+ *(*strpos)++ = *src;
+ if (!*src)
+ break;
+ src++;
+ }
+ dest->numchildren = 0;
+ dest->children = NULL;
+ }
+ else {
+ unsigned int i;
+ int cn;
+ dest->numchildren = dtd->scaffold[src_node].childcnt;
+ dest->children = *contpos;
+ *contpos += dest->numchildren;
+ for (i = 0, cn = dtd->scaffold[src_node].firstchild;
+ i < dest->numchildren;
+ i++, cn = dtd->scaffold[cn].nextsib) {
+ build_node(parser, cn, &(dest->children[i]), contpos, strpos);
+ }
+ dest->name = NULL;
+ }
+}
+
+static XML_Content *
+build_model (XML_Parser parser)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ XML_Content *ret;
+ XML_Content *cpos;
+ XML_Char * str;
+ int allocsize = (dtd->scaffCount * sizeof(XML_Content)
+ + (dtd->contentStringLen * sizeof(XML_Char)));
+
+ ret = (XML_Content *)MALLOC(allocsize);
+ if (!ret)
+ return NULL;
+
+ str = (XML_Char *) (&ret[dtd->scaffCount]);
+ cpos = &ret[1];
+
+ build_node(parser, 0, ret, &cpos, &str);
+ return ret;
+}
+
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
+ ELEMENT_TYPE *ret;
+
+ if (!name)
+ return NULL;
+ ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
+ if (!ret)
+ return NULL;
+ if (ret->name != name)
+ poolDiscard(&dtd->pool);
+ else {
+ poolFinish(&dtd->pool);
+ if (!setElementTypePrefix(parser, ret))
+ return NULL;
+ }
+ return ret;
+}
diff --git a/sys/src/cmd/python/Modules/expat/xmlrole.c b/sys/src/cmd/python/Modules/expat/xmlrole.c
new file mode 100644
index 000000000..15d4d8ff6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmlrole.c
@@ -0,0 +1,1330 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+
+#include "expat_external.h"
+#include "internal.h"
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = {
+ ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = {
+ ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = {
+ ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = {
+ ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = {
+ ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = {
+ ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = {
+ ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
+ '\0' };
+static const char KW_ENTITY[] = {
+ ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = {
+ ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = {
+ ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = {
+ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = {
+ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_IGNORE[] = {
+ ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IMPLIED[] = {
+ ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_INCLUDE[] = {
+ ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_NDATA[] = {
+ ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = {
+ ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = {
+ ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
+ '\0' };
+static const char KW_NOTATION[] =
+ { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
+ '\0' };
+static const char KW_PCDATA[] = {
+ ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = {
+ ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = {
+ ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
+ '\0' };
+static const char KW_SYSTEM[] = {
+ ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+ ((state)->handler = ((state)->documentEntity \
+ ? internalSubset \
+ : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc);
+
+static PROLOG_HANDLER
+ prolog0, prolog1, prolog2,
+ doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+ internalSubset,
+ entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+ entity7, entity8, entity9, entity10,
+ notation0, notation1, notation2, notation3, notation4,
+ attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+ attlist7, attlist8, attlist9,
+ element0, element1, element2, element3, element4, element5, element6,
+ element7,
+#ifdef XML_DTD
+ externalSubset0, externalSubset1,
+ condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+ declClose,
+ error;
+
+static int FASTCALL common(PROLOG_STATE *state, int tok);
+
+static int PTRCALL
+prolog0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ state->handler = prolog1;
+ return XML_ROLE_NONE;
+ case XML_TOK_XML_DECL:
+ state->handler = prolog1;
+ return XML_ROLE_XML_DECL;
+ case XML_TOK_PI:
+ state->handler = prolog1;
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ state->handler = prolog1;
+ return XML_ROLE_COMMENT;
+ case XML_TOK_BOM:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (!XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_DOCTYPE))
+ break;
+ state->handler = doctype0;
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+prolog1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PI:
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ return XML_ROLE_COMMENT;
+ case XML_TOK_BOM:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (!XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_DOCTYPE))
+ break;
+ state->handler = doctype0;
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+prolog2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PI:
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ return XML_ROLE_COMMENT;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = doctype1;
+ return XML_ROLE_DOCTYPE_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = internalSubset;
+ return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = doctype3;
+ return XML_ROLE_DOCTYPE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = doctype2;
+ return XML_ROLE_DOCTYPE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = doctype3;
+ return XML_ROLE_DOCTYPE_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = doctype4;
+ return XML_ROLE_DOCTYPE_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = internalSubset;
+ return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+internalSubset(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ENTITY)) {
+ state->handler = entity0;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ATTLIST)) {
+ state->handler = attlist0;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ELEMENT)) {
+ state->handler = element0;
+ return XML_ROLE_ELEMENT_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_NOTATION)) {
+ state->handler = notation0;
+ return XML_ROLE_NOTATION_NONE;
+ }
+ break;
+ case XML_TOK_PI:
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ return XML_ROLE_COMMENT;
+ case XML_TOK_PARAM_ENTITY_REF:
+ return XML_ROLE_PARAM_ENTITY_REF;
+ case XML_TOK_CLOSE_BRACKET:
+ state->handler = doctype5;
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_NONE:
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+externalSubset0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ state->handler = externalSubset1;
+ if (tok == XML_TOK_XML_DECL)
+ return XML_ROLE_TEXT_DECL;
+ return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static int PTRCALL
+externalSubset1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_COND_SECT_OPEN:
+ state->handler = condSect0;
+ return XML_ROLE_NONE;
+ case XML_TOK_COND_SECT_CLOSE:
+ if (state->includeLevel == 0)
+ break;
+ state->includeLevel -= 1;
+ return XML_ROLE_NONE;
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_BRACKET:
+ break;
+ case XML_TOK_NONE:
+ if (state->includeLevel)
+ break;
+ return XML_ROLE_NONE;
+ default:
+ return internalSubset(state, tok, ptr, end, enc);
+ }
+ return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+entity0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_PERCENT:
+ state->handler = entity1;
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ state->handler = entity2;
+ return XML_ROLE_GENERAL_ENTITY_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ state->handler = entity7;
+ return XML_ROLE_PARAM_ENTITY_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = entity4;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = entity3;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ENTITY_NONE;
+ return XML_ROLE_ENTITY_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity4;
+ return XML_ROLE_ENTITY_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity5;
+ return XML_ROLE_ENTITY_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ENTITY_COMPLETE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+ state->handler = entity6;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ENTITY_NONE;
+ return XML_ROLE_ENTITY_NOTATION_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = entity9;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = entity8;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ENTITY_NONE;
+ return XML_ROLE_ENTITY_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity8(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity9;
+ return XML_ROLE_ENTITY_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity9(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity10;
+ return XML_ROLE_ENTITY_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity10(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ENTITY_COMPLETE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_NAME:
+ state->handler = notation1;
+ return XML_ROLE_NOTATION_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = notation3;
+ return XML_ROLE_NOTATION_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = notation2;
+ return XML_ROLE_NOTATION_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = notation4;
+ return XML_ROLE_NOTATION_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_NOTATION_NONE;
+ return XML_ROLE_NOTATION_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_NOTATION_NONE;
+ return XML_ROLE_NOTATION_SYSTEM_ID;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist1;
+ return XML_ROLE_ATTLIST_ELEMENT_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist2;
+ return XML_ROLE_ATTRIBUTE_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ {
+ static const char * const types[] = {
+ KW_CDATA,
+ KW_ID,
+ KW_IDREF,
+ KW_IDREFS,
+ KW_ENTITY,
+ KW_ENTITIES,
+ KW_NMTOKEN,
+ KW_NMTOKENS,
+ };
+ int i;
+ for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+ if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+ state->handler = attlist8;
+ return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+ }
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+ state->handler = attlist5;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = attlist3;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NMTOKEN:
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist4;
+ return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = attlist8;
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_OR:
+ state->handler = attlist3;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = attlist6;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ state->handler = attlist7;
+ return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = attlist8;
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_OR:
+ state->handler = attlist6;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+/* default value */
+static int PTRCALL
+attlist8(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_POUND_NAME:
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_IMPLIED)) {
+ state->handler = attlist1;
+ return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_REQUIRED)) {
+ state->handler = attlist1;
+ return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_FIXED)) {
+ state->handler = attlist9;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = attlist1;
+ return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist9(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = attlist1;
+ return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element1;
+ return XML_ROLE_ELEMENT_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_CONTENT_EMPTY;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_CONTENT_ANY;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = element2;
+ state->level = 1;
+ return XML_ROLE_GROUP_OPEN;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_POUND_NAME:
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_PCDATA)) {
+ state->handler = element3;
+ return XML_ROLE_CONTENT_PCDATA;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->level = 2;
+ state->handler = element6;
+ return XML_ROLE_GROUP_OPEN;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT;
+ case XML_TOK_NAME_QUESTION:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_OPT;
+ case XML_TOK_NAME_ASTERISK:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_REP;
+ case XML_TOK_NAME_PLUS:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_PLUS;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_GROUP_CLOSE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_OR:
+ state->handler = element4;
+ return XML_ROLE_ELEMENT_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element5;
+ return XML_ROLE_CONTENT_ELEMENT;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_OR:
+ state->handler = element4;
+ return XML_ROLE_ELEMENT_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_OPEN_PAREN:
+ state->level += 1;
+ return XML_ROLE_GROUP_OPEN;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT;
+ case XML_TOK_NAME_QUESTION:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_OPT;
+ case XML_TOK_NAME_ASTERISK:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_REP;
+ case XML_TOK_NAME_PLUS:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_PLUS;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_CLOSE_PAREN_QUESTION:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE_OPT;
+ case XML_TOK_CLOSE_PAREN_PLUS:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE_PLUS;
+ case XML_TOK_COMMA:
+ state->handler = element6;
+ return XML_ROLE_GROUP_SEQUENCE;
+ case XML_TOK_OR:
+ state->handler = element6;
+ return XML_ROLE_GROUP_CHOICE;
+ }
+ return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+condSect0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+ state->handler = condSect1;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+ state->handler = condSect2;
+ return XML_ROLE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+condSect1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = externalSubset1;
+ state->includeLevel += 1;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+condSect2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = externalSubset1;
+ return XML_ROLE_IGNORE_SECT;
+ }
+ return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+declClose(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return state->role_none;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return state->role_none;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+error(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ return XML_ROLE_NONE;
+}
+
+static int FASTCALL
+common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+ if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+ return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+ state->handler = error;
+ return XML_ROLE_ERROR;
+}
+
+void
+XmlPrologStateInit(PROLOG_STATE *state)
+{
+ state->handler = prolog0;
+#ifdef XML_DTD
+ state->documentEntity = 1;
+ state->includeLevel = 0;
+ state->inEntityValue = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void
+XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+ state->handler = externalSubset0;
+ state->documentEntity = 0;
+ state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */
diff --git a/sys/src/cmd/python/Modules/expat/xmlrole.h b/sys/src/cmd/python/Modules/expat/xmlrole.h
new file mode 100644
index 000000000..4dd9f06f9
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmlrole.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#ifdef __VMS
+/* 0 1 2 3 0 1 2 3
+ 1234567890123456789012345678901 1234567890123456789012345678901 */
+#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
+#endif
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ XML_ROLE_ERROR = -1,
+ XML_ROLE_NONE = 0,
+ XML_ROLE_XML_DECL,
+ XML_ROLE_INSTANCE_START,
+ XML_ROLE_DOCTYPE_NONE,
+ XML_ROLE_DOCTYPE_NAME,
+ XML_ROLE_DOCTYPE_SYSTEM_ID,
+ XML_ROLE_DOCTYPE_PUBLIC_ID,
+ XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
+ XML_ROLE_DOCTYPE_CLOSE,
+ XML_ROLE_GENERAL_ENTITY_NAME,
+ XML_ROLE_PARAM_ENTITY_NAME,
+ XML_ROLE_ENTITY_NONE,
+ XML_ROLE_ENTITY_VALUE,
+ XML_ROLE_ENTITY_SYSTEM_ID,
+ XML_ROLE_ENTITY_PUBLIC_ID,
+ XML_ROLE_ENTITY_COMPLETE,
+ XML_ROLE_ENTITY_NOTATION_NAME,
+ XML_ROLE_NOTATION_NONE,
+ XML_ROLE_NOTATION_NAME,
+ XML_ROLE_NOTATION_SYSTEM_ID,
+ XML_ROLE_NOTATION_NO_SYSTEM_ID,
+ XML_ROLE_NOTATION_PUBLIC_ID,
+ XML_ROLE_ATTRIBUTE_NAME,
+ XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+ XML_ROLE_ATTRIBUTE_TYPE_ID,
+ XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+ XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+ XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+ XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+ XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+ XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+ XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+ XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+ XML_ROLE_ATTLIST_NONE,
+ XML_ROLE_ATTLIST_ELEMENT_NAME,
+ XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+ XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+ XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+ XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+ XML_ROLE_ELEMENT_NONE,
+ XML_ROLE_ELEMENT_NAME,
+ XML_ROLE_CONTENT_ANY,
+ XML_ROLE_CONTENT_EMPTY,
+ XML_ROLE_CONTENT_PCDATA,
+ XML_ROLE_GROUP_OPEN,
+ XML_ROLE_GROUP_CLOSE,
+ XML_ROLE_GROUP_CLOSE_REP,
+ XML_ROLE_GROUP_CLOSE_OPT,
+ XML_ROLE_GROUP_CLOSE_PLUS,
+ XML_ROLE_GROUP_CHOICE,
+ XML_ROLE_GROUP_SEQUENCE,
+ XML_ROLE_CONTENT_ELEMENT,
+ XML_ROLE_CONTENT_ELEMENT_REP,
+ XML_ROLE_CONTENT_ELEMENT_OPT,
+ XML_ROLE_CONTENT_ELEMENT_PLUS,
+ XML_ROLE_PI,
+ XML_ROLE_COMMENT,
+#ifdef XML_DTD
+ XML_ROLE_TEXT_DECL,
+ XML_ROLE_IGNORE_SECT,
+ XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+ XML_ROLE_PARAM_ENTITY_REF
+};
+
+typedef struct prolog_state {
+ int (PTRCALL *handler) (struct prolog_state *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc);
+ unsigned level;
+ int role_none;
+#ifdef XML_DTD
+ unsigned includeLevel;
+ int documentEntity;
+ int inEntityValue;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */
diff --git a/sys/src/cmd/python/Modules/expat/xmltok.c b/sys/src/cmd/python/Modules/expat/xmltok.c
new file mode 100644
index 000000000..db92247da
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmltok.c
@@ -0,0 +1,1639 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+
+#include "expat_external.h"
+#include "internal.h"
+#include "xmltok.h"
+#include "nametab.h"
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+ { PREFIX(prologTok), PREFIX(contentTok), \
+ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+ PREFIX(sameName), \
+ PREFIX(nameMatchesAscii), \
+ PREFIX(nameLength), \
+ PREFIX(skipS), \
+ PREFIX(getAtts), \
+ PREFIX(charRefNumber), \
+ PREFIX(predefinedEntityName), \
+ PREFIX(updatePosition), \
+ PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits between
+ the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
+ pages, 3 bits to add to that index and 5 bits to generate the mask.
+*/
+#define UTF8_GET_NAMING2(pages, byte) \
+ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+ + ((((byte)[0]) & 3) << 1) \
+ + ((((byte)[1]) >> 5) & 1)] \
+ & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits between
+ the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
+ into pages, 3 bits to add to that index and 5 bits to generate the
+ mask.
+*/
+#define UTF8_GET_NAMING3(pages, byte) \
+ (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+ + ((((byte)[1]) >> 2) & 0xF)] \
+ << 3) \
+ + ((((byte)[1]) & 3) << 1) \
+ + ((((byte)[2]) >> 5) & 1)] \
+ & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+ ((n) == 2 \
+ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+ : ((n) == 3 \
+ ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+ : 0))
+
+/* Detection of invalid UTF-8 sequences is based on Table 3.1B
+ of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
+ with the additional restriction of not allowing the Unicode
+ code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
+ Implementation details:
+ (A & 0x80) == 0 means A < 0x80
+ and
+ (A & 0xC0) == 0xC0 means A > 0xBF
+*/
+
+#define UTF8_INVALID2(p) \
+ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
+
+#define UTF8_INVALID3(p) \
+ (((p)[2] & 0x80) == 0 \
+ || \
+ ((*p) == 0xEF && (p)[1] == 0xBF \
+ ? \
+ (p)[2] > 0xBD \
+ : \
+ ((p)[2] & 0xC0) == 0xC0) \
+ || \
+ ((*p) == 0xE0 \
+ ? \
+ (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+ : \
+ ((p)[1] & 0x80) == 0 \
+ || \
+ ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
+
+#define UTF8_INVALID4(p) \
+ (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
+ || \
+ ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
+ || \
+ ((*p) == 0xF0 \
+ ? \
+ (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
+ : \
+ ((p)[1] & 0x80) == 0 \
+ || \
+ ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
+
+static int PTRFASTCALL
+isNever(const ENCODING *enc, const char *p)
+{
+ return 0;
+}
+
+static int PTRFASTCALL
+utf8_isName2(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isName3(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static int PTRFASTCALL
+utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+static int PTRFASTCALL
+utf8_isInvalid2(const ENCODING *enc, const char *p)
+{
+ return UTF8_INVALID2((const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+ return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+ return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+ ENCODING enc;
+ unsigned char type[256];
+#ifdef XML_MIN_SIZE
+ int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
+ int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
+ int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+ int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
+};
+
+#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc))
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+static int FASTCALL checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static int PTRFASTCALL
+sb_byteType(const ENCODING *enc, const char *p)
+{
+ return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
+static int PTRFASTCALL
+sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
+static int PTRCALL
+sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
+ UTF8_cval1 = 0x00,
+ UTF8_cval2 = 0xc0,
+ UTF8_cval3 = 0xe0,
+ UTF8_cval4 = 0xf0
+};
+
+static void PTRCALL
+utf8_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ char *to;
+ const char *from;
+ if (fromLim - *fromP > toLim - *toP) {
+ /* Avoid copying partial characters. */
+ for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+ if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+ break;
+ }
+ for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+ *to = *from;
+ *fromP = from;
+ *toP = to;
+}
+
+static void PTRCALL
+utf8_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ unsigned short *to = *toP;
+ const char *from = *fromP;
+ while (from != fromLim && to != toLim) {
+ switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+ case BT_LEAD2:
+ *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
+ from += 2;
+ break;
+ case BT_LEAD3:
+ *to++ = (unsigned short)(((from[0] & 0xf) << 12)
+ | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
+ from += 3;
+ break;
+ case BT_LEAD4:
+ {
+ unsigned long n;
+ if (to + 1 == toLim)
+ goto after;
+ n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
+ | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+ n -= 0x10000;
+ to[0] = (unsigned short)((n >> 10) | 0xD800);
+ to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+ to += 2;
+ from += 4;
+ }
+ break;
+ default:
+ *to++ = *from++;
+ break;
+ }
+ }
+after:
+ *fromP = from;
+ *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#include "asciitab.h"
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#include "iasciitab.h"
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static void PTRCALL
+latin1_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ for (;;) {
+ unsigned char c;
+ if (*fromP == fromLim)
+ break;
+ c = (unsigned char)**fromP;
+ if (c & 0x80) {
+ if (toLim - *toP < 2)
+ break;
+ *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
+ *(*toP)++ = (char)((c & 0x3f) | 0x80);
+ (*fromP)++;
+ }
+ else {
+ if (*toP == toLim)
+ break;
+ *(*toP)++ = *(*fromP)++;
+ }
+ }
+}
+
+static void PTRCALL
+latin1_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ while (*fromP != fromLim && *toP != toLim)
+ *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+ { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+ { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+static void PTRCALL
+ascii_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ while (*fromP != fromLim && *toP != toLim)
+ *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+ { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+ {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+ { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+static int PTRFASTCALL
+unicode_byte_type(char hi, char lo)
+{
+ switch ((unsigned char)hi) {
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ return BT_LEAD4;
+ case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ return BT_TRAIL;
+ case 0xFF:
+ switch ((unsigned char)lo) {
+ case 0xFF:
+ case 0xFE:
+ return BT_NONXML;
+ }
+ break;
+ }
+ return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static void PTRCALL \
+E ## toUtf8(const ENCODING *enc, \
+ const char **fromP, const char *fromLim, \
+ char **toP, const char *toLim) \
+{ \
+ const char *from; \
+ for (from = *fromP; from != fromLim; from += 2) { \
+ int plane; \
+ unsigned char lo2; \
+ unsigned char lo = GET_LO(from); \
+ unsigned char hi = GET_HI(from); \
+ switch (hi) { \
+ case 0: \
+ if (lo < 0x80) { \
+ if (*toP == toLim) { \
+ *fromP = from; \
+ return; \
+ } \
+ *(*toP)++ = lo; \
+ break; \
+ } \
+ /* fall through */ \
+ case 0x1: case 0x2: case 0x3: \
+ case 0x4: case 0x5: case 0x6: case 0x7: \
+ if (toLim - *toP < 2) { \
+ *fromP = from; \
+ return; \
+ } \
+ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ default: \
+ if (toLim - *toP < 3) { \
+ *fromP = from; \
+ return; \
+ } \
+ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+ if (toLim - *toP < 4) { \
+ *fromP = from; \
+ return; \
+ } \
+ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+ from += 2; \
+ lo2 = GET_LO(from); \
+ *(*toP)++ = (((lo & 0x3) << 4) \
+ | ((GET_HI(from) & 0x3) << 2) \
+ | (lo2 >> 6) \
+ | 0x80); \
+ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+ break; \
+ } \
+ } \
+ *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static void PTRCALL \
+E ## toUtf16(const ENCODING *enc, \
+ const char **fromP, const char *fromLim, \
+ unsigned short **toP, const unsigned short *toLim) \
+{ \
+ /* Avoid copying first half only of surrogate */ \
+ if (fromLim - *fromP > ((toLim - *toP) << 1) \
+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+ fromLim -= 2; \
+ for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+ (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+ (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+ : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static int PTRFASTCALL
+little2_byteType(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static int PTRFASTCALL
+little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static int PTRCALL
+little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static int PTRFASTCALL
+little2_isNameMin(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static int PTRFASTCALL
+little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 1234
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 1234
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#if BYTEORDER != 4321
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = {
+ { VTABLE, 2, 0, 1 },
+ {
+#include "iasciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = {
+ { VTABLE, 2, 0, 1 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+ : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static int PTRFASTCALL
+big2_byteType(const ENCODING *enc, const char *p)
+{
+ return BIG2_BYTE_TYPE(enc, p);
+}
+
+static int PTRFASTCALL
+big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static int PTRCALL
+big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static int PTRFASTCALL
+big2_isNameMin(const ENCODING *enc, const char *p)
+{
+ return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static int PTRFASTCALL
+big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+ return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 4321
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 4321
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#if BYTEORDER != 1234
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+ { VTABLE, 2, 0, 1 },
+ {
+#include "iasciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+ { VTABLE, 2, 0, 1 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static int FASTCALL
+streqci(const char *s1, const char *s2)
+{
+ for (;;) {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (ASCII_a <= c1 && c1 <= ASCII_z)
+ c1 += ASCII_A - ASCII_a;
+ if (ASCII_a <= c2 && c2 <= ASCII_z)
+ c2 += ASCII_A - ASCII_a;
+ if (c1 != c2)
+ return 0;
+ if (!c1)
+ break;
+ }
+ return 1;
+}
+
+static void PTRCALL
+initUpdatePosition(const ENCODING *enc, const char *ptr,
+ const char *end, POSITION *pos)
+{
+ normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static int
+toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+ char buf[1];
+ char *p = buf;
+ XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+ if (p == buf)
+ return -1;
+ else
+ return buf[0];
+}
+
+static int FASTCALL
+isSpace(int c)
+{
+ switch (c) {
+ case 0x20:
+ case 0xD:
+ case 0xA:
+ case 0x9:
+ return 1;
+ }
+ return 0;
+}
+
+/* Return 1 if there's just optional white space or there's an S
+ followed by name=val.
+*/
+static int
+parsePseudoAttribute(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **namePtr,
+ const char **nameEndPtr,
+ const char **valPtr,
+ const char **nextTokPtr)
+{
+ int c;
+ char open;
+ if (ptr == end) {
+ *namePtr = NULL;
+ return 1;
+ }
+ if (!isSpace(toAscii(enc, ptr, end))) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ do {
+ ptr += enc->minBytesPerChar;
+ } while (isSpace(toAscii(enc, ptr, end)));
+ if (ptr == end) {
+ *namePtr = NULL;
+ return 1;
+ }
+ *namePtr = ptr;
+ for (;;) {
+ c = toAscii(enc, ptr, end);
+ if (c == -1) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ if (c == ASCII_EQUALS) {
+ *nameEndPtr = ptr;
+ break;
+ }
+ if (isSpace(c)) {
+ *nameEndPtr = ptr;
+ do {
+ ptr += enc->minBytesPerChar;
+ } while (isSpace(c = toAscii(enc, ptr, end)));
+ if (c != ASCII_EQUALS) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ break;
+ }
+ ptr += enc->minBytesPerChar;
+ }
+ if (ptr == *namePtr) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ ptr += enc->minBytesPerChar;
+ c = toAscii(enc, ptr, end);
+ while (isSpace(c)) {
+ ptr += enc->minBytesPerChar;
+ c = toAscii(enc, ptr, end);
+ }
+ if (c != ASCII_QUOT && c != ASCII_APOS) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ open = (char)c;
+ ptr += enc->minBytesPerChar;
+ *valPtr = ptr;
+ for (;; ptr += enc->minBytesPerChar) {
+ c = toAscii(enc, ptr, end);
+ if (c == open)
+ break;
+ if (!(ASCII_a <= c && c <= ASCII_z)
+ && !(ASCII_A <= c && c <= ASCII_Z)
+ && !(ASCII_0 <= c && c <= ASCII_9)
+ && c != ASCII_PERIOD
+ && c != ASCII_MINUS
+ && c != ASCII_UNDERSCORE) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ }
+ *nextTokPtr = ptr + enc->minBytesPerChar;
+ return 1;
+}
+
+static const char KW_version[] = {
+ ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+ ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+ ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
+ ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+ ASCII_y, ASCII_e, ASCII_s, '\0'
+};
+
+static const char KW_no[] = {
+ ASCII_n, ASCII_o, '\0'
+};
+
+static int
+doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+ const char *,
+ const char *),
+ int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingName,
+ const ENCODING **encoding,
+ int *standalone)
+{
+ const char *val = NULL;
+ const char *name = NULL;
+ const char *nameEnd = NULL;
+ ptr += 5 * enc->minBytesPerChar;
+ end -= 2 * enc->minBytesPerChar;
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
+ || !name) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+ if (!isGeneralTextEntity) {
+ *badPtr = name;
+ return 0;
+ }
+ }
+ else {
+ if (versionPtr)
+ *versionPtr = val;
+ if (versionEndPtr)
+ *versionEndPtr = ptr;
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!name) {
+ if (isGeneralTextEntity) {
+ /* a TextDecl must have an EncodingDecl */
+ *badPtr = ptr;
+ return 0;
+ }
+ return 1;
+ }
+ }
+ if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+ int c = toAscii(enc, val, end);
+ if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+ *badPtr = val;
+ return 0;
+ }
+ if (encodingName)
+ *encodingName = val;
+ if (encoding)
+ *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!name)
+ return 1;
+ }
+ if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
+ || isGeneralTextEntity) {
+ *badPtr = name;
+ return 0;
+ }
+ if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+ if (standalone)
+ *standalone = 1;
+ }
+ else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+ if (standalone)
+ *standalone = 0;
+ }
+ else {
+ *badPtr = val;
+ return 0;
+ }
+ while (isSpace(toAscii(enc, ptr, end)))
+ ptr += enc->minBytesPerChar;
+ if (ptr != end) {
+ *badPtr = ptr;
+ return 0;
+ }
+ return 1;
+}
+
+static int FASTCALL
+checkCharRefNumber(int result)
+{
+ switch (result >> 8) {
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ return -1;
+ case 0:
+ if (latin1_encoding.type[result] == BT_NONXML)
+ return -1;
+ break;
+ case 0xFF:
+ if (result == 0xFFFE || result == 0xFFFF)
+ return -1;
+ break;
+ }
+ return result;
+}
+
+int FASTCALL
+XmlUtf8Encode(int c, char *buf)
+{
+ enum {
+ /* minN is minimum legal resulting value for N byte sequence */
+ min2 = 0x80,
+ min3 = 0x800,
+ min4 = 0x10000
+ };
+
+ if (c < 0)
+ return 0;
+ if (c < min2) {
+ buf[0] = (char)(c | UTF8_cval1);
+ return 1;
+ }
+ if (c < min3) {
+ buf[0] = (char)((c >> 6) | UTF8_cval2);
+ buf[1] = (char)((c & 0x3f) | 0x80);
+ return 2;
+ }
+ if (c < min4) {
+ buf[0] = (char)((c >> 12) | UTF8_cval3);
+ buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
+ buf[2] = (char)((c & 0x3f) | 0x80);
+ return 3;
+ }
+ if (c < 0x110000) {
+ buf[0] = (char)((c >> 18) | UTF8_cval4);
+ buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
+ buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
+ buf[3] = (char)((c & 0x3f) | 0x80);
+ return 4;
+ }
+ return 0;
+}
+
+int FASTCALL
+XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+ if (charNum < 0)
+ return 0;
+ if (charNum < 0x10000) {
+ buf[0] = (unsigned short)charNum;
+ return 1;
+ }
+ if (charNum < 0x110000) {
+ charNum -= 0x10000;
+ buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
+ buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
+ return 2;
+ }
+ return 0;
+}
+
+struct unknown_encoding {
+ struct normal_encoding normal;
+ CONVERTER convert;
+ void *userData;
+ unsigned short utf16[256];
+ char utf8[256][4];
+};
+
+#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc))
+
+int
+XmlSizeOfUnknownEncoding(void)
+{
+ return sizeof(struct unknown_encoding);
+}
+
+static int PTRFASTCALL
+unknown_isName(const ENCODING *enc, const char *p)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ int c = uenc->convert(uenc->userData, p);
+ if (c & ~0xFFFF)
+ return 0;
+ return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static int PTRFASTCALL
+unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ int c = uenc->convert(uenc->userData, p);
+ if (c & ~0xFFFF)
+ return 0;
+ return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static int PTRFASTCALL
+unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ int c = uenc->convert(uenc->userData, p);
+ return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static void PTRCALL
+unknown_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ char buf[XML_UTF8_ENCODE_MAX];
+ for (;;) {
+ const char *utf8;
+ int n;
+ if (*fromP == fromLim)
+ break;
+ utf8 = uenc->utf8[(unsigned char)**fromP];
+ n = *utf8++;
+ if (n == 0) {
+ int c = uenc->convert(uenc->userData, *fromP);
+ n = XmlUtf8Encode(c, buf);
+ if (n > toLim - *toP)
+ break;
+ utf8 = buf;
+ *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+ - (BT_LEAD2 - 2));
+ }
+ else {
+ if (n > toLim - *toP)
+ break;
+ (*fromP)++;
+ }
+ do {
+ *(*toP)++ = *utf8++;
+ } while (--n != 0);
+ }
+}
+
+static void PTRCALL
+unknown_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ while (*fromP != fromLim && *toP != toLim) {
+ unsigned short c = uenc->utf16[(unsigned char)**fromP];
+ if (c == 0) {
+ c = (unsigned short)
+ uenc->convert(uenc->userData, *fromP);
+ *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+ - (BT_LEAD2 - 2));
+ }
+ else
+ (*fromP)++;
+ *(*toP)++ = c;
+ }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData)
+{
+ int i;
+ struct unknown_encoding *e = (struct unknown_encoding *)mem;
+ for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+ ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+ for (i = 0; i < 128; i++)
+ if (latin1_encoding.type[i] != BT_OTHER
+ && latin1_encoding.type[i] != BT_NONXML
+ && table[i] != i)
+ return 0;
+ for (i = 0; i < 256; i++) {
+ int c = table[i];
+ if (c == -1) {
+ e->normal.type[i] = BT_MALFORM;
+ /* This shouldn't really get used. */
+ e->utf16[i] = 0xFFFF;
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = 0;
+ }
+ else if (c < 0) {
+ if (c < -4)
+ return 0;
+ e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
+ e->utf8[i][0] = 0;
+ e->utf16[i] = 0;
+ }
+ else if (c < 0x80) {
+ if (latin1_encoding.type[c] != BT_OTHER
+ && latin1_encoding.type[c] != BT_NONXML
+ && c != i)
+ return 0;
+ e->normal.type[i] = latin1_encoding.type[c];
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = (char)c;
+ e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
+ }
+ else if (checkCharRefNumber(c) < 0) {
+ e->normal.type[i] = BT_NONXML;
+ /* This shouldn't really get used. */
+ e->utf16[i] = 0xFFFF;
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = 0;
+ }
+ else {
+ if (c > 0xFFFF)
+ return 0;
+ if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+ e->normal.type[i] = BT_NMSTRT;
+ else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+ e->normal.type[i] = BT_NAME;
+ else
+ e->normal.type[i] = BT_OTHER;
+ e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+ e->utf16[i] = (unsigned short)c;
+ }
+ }
+ e->userData = userData;
+ e->convert = convert;
+ if (convert) {
+ e->normal.isName2 = unknown_isName;
+ e->normal.isName3 = unknown_isName;
+ e->normal.isName4 = unknown_isName;
+ e->normal.isNmstrt2 = unknown_isNmstrt;
+ e->normal.isNmstrt3 = unknown_isNmstrt;
+ e->normal.isNmstrt4 = unknown_isNmstrt;
+ e->normal.isInvalid2 = unknown_isInvalid;
+ e->normal.isInvalid3 = unknown_isInvalid;
+ e->normal.isInvalid4 = unknown_isInvalid;
+ }
+ e->normal.enc.utf8Convert = unknown_toUtf8;
+ e->normal.enc.utf16Convert = unknown_toUtf16;
+ return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+ UNKNOWN_ENC = -1,
+ ISO_8859_1_ENC = 0,
+ US_ASCII_ENC,
+ UTF_8_ENC,
+ UTF_16_ENC,
+ UTF_16BE_ENC,
+ UTF_16LE_ENC,
+ /* must match encodingNames up to here */
+ NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+ ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
+ ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+ ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
+ '\0'
+};
+static const char KW_UTF_8[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
+ '\0'
+};
+static const char KW_UTF_16LE[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
+ '\0'
+};
+
+static int FASTCALL
+getEncodingIndex(const char *name)
+{
+ static const char * const encodingNames[] = {
+ KW_ISO_8859_1,
+ KW_US_ASCII,
+ KW_UTF_8,
+ KW_UTF_16,
+ KW_UTF_16BE,
+ KW_UTF_16LE,
+ };
+ int i;
+ if (name == NULL)
+ return NO_ENC;
+ for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+ if (streqci(name, encodingNames[i]))
+ return i;
+ return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding
+ specified at initialization in the isUtf16 member.
+*/
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding. encodingTable maps from
+ encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
+ the external (protocol) specified encoding; state is
+ XML_CONTENT_STATE if we're parsing an external text entity, and
+ XML_PROLOG_STATE otherwise.
+*/
+
+
+static int
+initScan(const ENCODING * const *encodingTable,
+ const INIT_ENCODING *enc,
+ int state,
+ const char *ptr,
+ const char *end,
+ const char **nextTokPtr)
+{
+ const ENCODING **encPtr;
+
+ if (ptr == end)
+ return XML_TOK_NONE;
+ encPtr = enc->encPtr;
+ if (ptr + 1 == end) {
+ /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+ /* a well-formed document entity must have more than one byte */
+ if (state != XML_CONTENT_STATE)
+ return XML_TOK_PARTIAL;
+#endif
+ /* so we're parsing an external text entity... */
+ /* if UTF-16 was externally specified, then we need at least 2 bytes */
+ switch (INIT_ENC_INDEX(enc)) {
+ case UTF_16_ENC:
+ case UTF_16LE_ENC:
+ case UTF_16BE_ENC:
+ return XML_TOK_PARTIAL;
+ }
+ switch ((unsigned char)*ptr) {
+ case 0xFE:
+ case 0xFF:
+ case 0xEF: /* possibly first byte of UTF-8 BOM */
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ /* fall through */
+ case 0x00:
+ case 0x3C:
+ return XML_TOK_PARTIAL;
+ }
+ }
+ else {
+ switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+ case 0xFEFF:
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ *nextTokPtr = ptr + 2;
+ *encPtr = encodingTable[UTF_16BE_ENC];
+ return XML_TOK_BOM;
+ /* 00 3C is handled in the default case */
+ case 0x3C00:
+ if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+ || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+ && state == XML_CONTENT_STATE)
+ break;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ case 0xFFFE:
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ *nextTokPtr = ptr + 2;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XML_TOK_BOM;
+ case 0xEFBB:
+ /* Maybe a UTF-8 BOM (EF BB BF) */
+ /* If there's an explicitly specified (external) encoding
+ of ISO-8859-1 or some flavour of UTF-16
+ and this is an external text entity,
+ don't look for the BOM,
+ because it might be a legal data.
+ */
+ if (state == XML_CONTENT_STATE) {
+ int e = INIT_ENC_INDEX(enc);
+ if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
+ || e == UTF_16LE_ENC || e == UTF_16_ENC)
+ break;
+ }
+ if (ptr + 2 == end)
+ return XML_TOK_PARTIAL;
+ if ((unsigned char)ptr[2] == 0xBF) {
+ *nextTokPtr = ptr + 3;
+ *encPtr = encodingTable[UTF_8_ENC];
+ return XML_TOK_BOM;
+ }
+ break;
+ default:
+ if (ptr[0] == '\0') {
+ /* 0 isn't a legal data character. Furthermore a document
+ entity can only start with ASCII characters. So the only
+ way this can fail to be big-endian UTF-16 if it it's an
+ external parsed general entity that's labelled as
+ UTF-16LE.
+ */
+ if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+ break;
+ *encPtr = encodingTable[UTF_16BE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ }
+ else if (ptr[1] == '\0') {
+ /* We could recover here in the case:
+ - parsing an external entity
+ - second byte is 0
+ - no externally specified encoding
+ - no encoding declaration
+ by assuming UTF-16LE. But we don't, because this would mean when
+ presented just with a single byte, we couldn't reliably determine
+ whether we needed further bytes.
+ */
+ if (state == XML_CONTENT_STATE)
+ break;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ }
+ break;
+ }
+ }
+ *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData)
+{
+ ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+ if (enc)
+ ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+ return enc;
+}
+
+#endif /* XML_NS */
diff --git a/sys/src/cmd/python/Modules/expat/xmltok.h b/sys/src/cmd/python/Modules/expat/xmltok.h
new file mode 100644
index 000000000..ca867aa6b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmltok.h
@@ -0,0 +1,316 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
+ start of illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and
+ XmlContentTok.
+*/
+#define XML_TOK_NONE -4 /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
+ might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+ returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
+*/
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10 /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and
+ XmlContentTok.
+*/
+#define XML_TOK_PI 11 /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14 /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok for a
+ name with a colon.
+*/
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+ /* first line and first column are 0 not 1 */
+ XML_Size lineNumber;
+ XML_Size columnNumber;
+} POSITION;
+
+typedef struct {
+ const char *name;
+ const char *valuePtr;
+ const char *valueEnd;
+ char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+typedef int (PTRCALL *SCANNER)(const ENCODING *,
+ const char *,
+ const char *,
+ const char **);
+
+struct encoding {
+ SCANNER scanners[XML_N_STATES];
+ SCANNER literalScanners[XML_N_LITERAL_TYPES];
+ int (PTRCALL *sameName)(const ENCODING *,
+ const char *,
+ const char *);
+ int (PTRCALL *nameMatchesAscii)(const ENCODING *,
+ const char *,
+ const char *,
+ const char *);
+ int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+ const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
+ int (PTRCALL *getAtts)(const ENCODING *enc,
+ const char *ptr,
+ int attsMax,
+ ATTRIBUTE *atts);
+ int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+ int (PTRCALL *predefinedEntityName)(const ENCODING *,
+ const char *,
+ const char *);
+ void (PTRCALL *updatePosition)(const ENCODING *,
+ const char *ptr,
+ const char *end,
+ POSITION *);
+ int (PTRCALL *isPublicId)(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr);
+ void (PTRCALL *utf8Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ char **toP,
+ const char *toLim);
+ void (PTRCALL *utf16Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ unsigned short **toP,
+ const unsigned short *toLim);
+ int minBytesPerChar;
+ char isUtf8;
+ char isUtf16;
+};
+
+/* Scan the string starting at ptr until the end of the next complete
+ token, but do not scan past eptr. Return an integer giving the
+ type of token.
+
+ Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+ Return XML_TOK_PARTIAL when the string does not contain a complete
+ token; nextTokPtr will not be set.
+
+ Return XML_TOK_INVALID when the string does not start a valid
+ token; nextTokPtr will be set to point to the character which made
+ the token invalid.
+
+ Otherwise the string starts with a valid token; nextTokPtr will be
+ set to point to the character following the end of that token.
+
+ Each data character counts as a single token, but adjacent data
+ characters may be returned together. Similarly for characters in
+ the prolog outside literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on the content
+ of a literal that has already been returned by XmlTok.
+*/
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+ (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+ (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+ (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+ (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+ (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+ (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+ (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+ ENCODING initEnc;
+ const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int XmlParseXmlDecl(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingNamePtr,
+ const ENCODING **namedEncodingPtr,
+ int *standalonePtr);
+
+int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncoding(void);
+const ENCODING *XmlGetUtf16InternalEncoding(void);
+int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
+int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
+int XmlSizeOfUnknownEncoding(void);
+
+
+typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData);
+
+int XmlParseXmlDeclNS(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingNamePtr,
+ const ENCODING **namedEncodingPtr,
+ int *standalonePtr);
+
+int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING *XmlGetUtf16InternalEncodingNS(void);
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */
diff --git a/sys/src/cmd/python/Modules/expat/xmltok_impl.c b/sys/src/cmd/python/Modules/expat/xmltok_impl.c
new file mode 100644
index 000000000..0ee57abb1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmltok_impl.c
@@ -0,0 +1,1779 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#endif
+
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_INVALID_CHAR(enc, ptr, n)) { \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+ case BT_NONXML: \
+ case BT_MALFORM: \
+ case BT_TRAIL: \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (!IS_NAME_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ case BT_DIGIT: \
+ case BT_NAME: \
+ case BT_MINUS: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static int PTRCALL
+PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr != end) {
+ if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_MINUS:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COMMENT;
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static int PTRCALL
+PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_MINUS:
+ return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LSQB:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COND_SECT_OPEN;
+ case BT_NMSTRT:
+ case BT_HEX:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_PERCNT:
+ if (ptr + MINBPC(enc) == end)
+ return XML_TOK_PARTIAL;
+ /* don't allow <!ENTITY% foo "whatever"> */
+ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+ case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* fall through */
+ case BT_S: case BT_CR: case BT_LF:
+ *nextTokPtr = ptr;
+ return XML_TOK_DECL_OPEN;
+ case BT_NMSTRT:
+ case BT_HEX:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+ const char *end, int *tokPtr)
+{
+ int upper = 0;
+ *tokPtr = XML_TOK_PI;
+ if (end - ptr != MINBPC(enc)*3)
+ return 1;
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_x:
+ break;
+ case ASCII_X:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ ptr += MINBPC(enc);
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_m:
+ break;
+ case ASCII_M:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ ptr += MINBPC(enc);
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_l:
+ break;
+ case ASCII_L:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ if (upper)
+ return 0;
+ *tokPtr = XML_TOK_XML_DECL;
+ return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static int PTRCALL
+PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ int tok;
+ const char *target = ptr;
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_QUEST:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return tok;
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+ case BT_QUEST:
+ if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return tok;
+ }
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
+ ASCII_T, ASCII_A, ASCII_LSQB };
+ int i;
+ /* CDATA[ */
+ if (end - ptr < 6 * MINBPC(enc))
+ return XML_TOK_PARTIAL;
+ for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+ if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static int PTRCALL
+PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ break;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr -= MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CDATA_SECT_CLOSE;
+ case BT_CR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ case BT_LF:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ INVALID_CASES(ptr, nextTokPtr)
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONXML:
+ case BT_MALFORM:
+ case BT_TRAIL:
+ case BT_CR:
+ case BT_LF:
+ case BT_RSQB:
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static int PTRCALL
+PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_CR: case BT_LF:
+ break;
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_END_TAG;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+#ifdef XML_NS
+ case BT_COLON:
+ /* no need to check qname syntax here,
+ since end-tag must match exactly */
+ ptr += MINBPC(enc);
+ break;
+#endif
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_END_TAG;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static int PTRCALL
+PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ break;
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CHAR_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static int PTRCALL
+PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr != end) {
+ if (CHAR_MATCHES(enc, ptr, ASCII_x))
+ return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ break;
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CHAR_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static int PTRCALL
+PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_NUM:
+ return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_ENTITY_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static int PTRCALL
+PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+#ifdef XML_NS
+ int hadColon = 0;
+#endif
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+ case BT_COLON:
+ if (hadColon) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ hadColon = 1;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+#endif
+ case BT_S: case BT_CR: case BT_LF:
+ for (;;) {
+ int t;
+
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ t = BYTE_TYPE(enc, ptr);
+ if (t == BT_EQUALS)
+ break;
+ switch (t) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ /* fall through */
+ case BT_EQUALS:
+ {
+ int open;
+#ifdef XML_NS
+ hadColon = 0;
+#endif
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ open = BYTE_TYPE(enc, ptr);
+ if (open == BT_QUOT || open == BT_APOS)
+ break;
+ switch (open) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ ptr += MINBPC(enc);
+ /* in attribute value */
+ for (;;) {
+ int t;
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ t = BYTE_TYPE(enc, ptr);
+ if (t == open)
+ break;
+ switch (t) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_AMP:
+ {
+ int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+ if (tok <= 0) {
+ if (tok == XML_TOK_INVALID)
+ *nextTokPtr = ptr;
+ return tok;
+ }
+ break;
+ }
+ case BT_LT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ break;
+ case BT_SOL:
+ goto sol;
+ case BT_GT:
+ goto gt;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* ptr points to closing quote */
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ continue;
+ case BT_GT:
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_WITH_ATTS;
+ case BT_SOL:
+ sol:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+ }
+ break;
+ }
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static int PTRCALL
+PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+#ifdef XML_NS
+ int hadColon;
+#endif
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_EXCL:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_MINUS:
+ return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LSQB:
+ return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
+ end, nextTokPtr);
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_SOL:
+ return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+#ifdef XML_NS
+ hadColon = 0;
+#endif
+ /* we have a start-tag */
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+ case BT_COLON:
+ if (hadColon) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ hadColon = 1;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+#endif
+ case BT_S: case BT_CR: case BT_LF:
+ {
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT:
+ goto gt;
+ case BT_SOL:
+ goto sol;
+ case BT_S: case BT_CR: case BT_LF:
+ ptr += MINBPC(enc);
+ continue;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+ }
+ return XML_TOK_PARTIAL;
+ }
+ case BT_GT:
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_NO_ATTS;
+ case BT_SOL:
+ sol:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_LT:
+ return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_AMP:
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_CR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ case BT_LF:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_RSQB;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ break;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_RSQB;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr -= MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ INVALID_CASES(ptr, nextTokPtr)
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_RSQB:
+ if (ptr + MINBPC(enc) != end) {
+ if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ if (ptr + 2*MINBPC(enc) != end) {
+ if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + 2*MINBPC(enc);
+ return XML_TOK_INVALID;
+ }
+ }
+ /* fall through */
+ case BT_AMP:
+ case BT_LT:
+ case BT_NONXML:
+ case BT_MALFORM:
+ case BT_TRAIL:
+ case BT_CR:
+ case BT_LF:
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static int PTRCALL
+PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return -XML_TOK_PERCENT;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+ *nextTokPtr = ptr;
+ return XML_TOK_PERCENT;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_PARAM_ENTITY_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_CR: case BT_LF: case BT_S:
+ case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+ *nextTokPtr = ptr;
+ return XML_TOK_POUND_NAME;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return -XML_TOK_POUND_NAME;
+}
+
+static int PTRCALL
+PREFIX(scanLit)(int open, const ENCODING *enc,
+ const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ while (ptr != end) {
+ int t = BYTE_TYPE(enc, ptr);
+ switch (t) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_QUOT:
+ case BT_APOS:
+ ptr += MINBPC(enc);
+ if (t != open)
+ break;
+ if (ptr == end)
+ return -XML_TOK_LITERAL;
+ *nextTokPtr = ptr;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_CR: case BT_LF:
+ case BT_GT: case BT_PERCNT: case BT_LSQB:
+ return XML_TOK_LITERAL;
+ default:
+ return XML_TOK_INVALID;
+ }
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ int tok;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_QUOT:
+ return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_APOS:
+ return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LT:
+ {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_EXCL:
+ return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_NMSTRT:
+ case BT_HEX:
+ case BT_NONASCII:
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ *nextTokPtr = ptr - MINBPC(enc);
+ return XML_TOK_INSTANCE_START;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ case BT_CR:
+ if (ptr + MINBPC(enc) == end) {
+ *nextTokPtr = end;
+ /* indicate that this might be part of a CR/LF pair */
+ return -XML_TOK_PROLOG_S;
+ }
+ /* fall through */
+ case BT_S: case BT_LF:
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ break;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_LF:
+ break;
+ case BT_CR:
+ /* don't split CR/LF pair */
+ if (ptr + MINBPC(enc) != end)
+ break;
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_PROLOG_S;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_PROLOG_S;
+ case BT_PERCNT:
+ return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_COMMA:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COMMA;
+ case BT_LSQB:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OPEN_BRACKET;
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return -XML_TOK_CLOSE_BRACKET;
+ if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+ if (ptr + MINBPC(enc) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+ *nextTokPtr = ptr + 2*MINBPC(enc);
+ return XML_TOK_COND_SECT_CLOSE;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_CLOSE_BRACKET;
+ case BT_LPAR:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OPEN_PAREN;
+ case BT_RPAR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return -XML_TOK_CLOSE_PAREN;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_AST:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_ASTERISK;
+ case BT_QUEST:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_QUESTION;
+ case BT_PLUS:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_PLUS;
+ case BT_CR: case BT_LF: case BT_S:
+ case BT_GT: case BT_COMMA: case BT_VERBAR:
+ case BT_RPAR:
+ *nextTokPtr = ptr;
+ return XML_TOK_CLOSE_PAREN;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_VERBAR:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OR;
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DECL_CLOSE;
+ case BT_NUM:
+ return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NAME; \
+ break; \
+ } \
+ if (IS_NAME_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NMTOKEN; \
+ break; \
+ } \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NMSTRT:
+ case BT_HEX:
+ tok = XML_TOK_NAME;
+ ptr += MINBPC(enc);
+ break;
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ tok = XML_TOK_NMTOKEN;
+ ptr += MINBPC(enc);
+ break;
+ case BT_NONASCII:
+ if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+ ptr += MINBPC(enc);
+ tok = XML_TOK_NAME;
+ break;
+ }
+ if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+ ptr += MINBPC(enc);
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT: case BT_RPAR: case BT_COMMA:
+ case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+ case BT_S: case BT_CR: case BT_LF:
+ *nextTokPtr = ptr;
+ return tok;
+#ifdef XML_NS
+ case BT_COLON:
+ ptr += MINBPC(enc);
+ switch (tok) {
+ case XML_TOK_NAME:
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ tok = XML_TOK_PREFIXED_NAME;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ break;
+ case XML_TOK_PREFIXED_NAME:
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ break;
+#endif
+ case BT_PLUS:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_PLUS;
+ case BT_AST:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_ASTERISK;
+ case BT_QUEST:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_QUESTION;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return -tok;
+}
+
+static int PTRCALL
+PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ const char *start;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ start = ptr;
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_AMP:
+ if (ptr == start)
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_LT:
+ /* this is for inside entity references */
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_LF:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_CR:
+ if (ptr == start) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_S:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_ATTRIBUTE_VALUE_S;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+static int PTRCALL
+PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ const char *start;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ start = ptr;
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_AMP:
+ if (ptr == start)
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_PERCNT:
+ if (ptr == start) {
+ int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
+ end, nextTokPtr);
+ return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_LF:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_CR:
+ if (ptr == start) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ int level = 0;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ end = ptr + n;
+ }
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_LT:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+ ++level;
+ ptr += MINBPC(enc);
+ }
+ }
+ break;
+ case BT_RSQB:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr += MINBPC(enc);
+ if (level == 0) {
+ *nextTokPtr = ptr;
+ return XML_TOK_IGNORE_SECT;
+ }
+ --level;
+ }
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **badPtr)
+{
+ ptr += MINBPC(enc);
+ end -= MINBPC(enc);
+ for (; ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ case BT_MINUS:
+ case BT_APOS:
+ case BT_LPAR:
+ case BT_RPAR:
+ case BT_PLUS:
+ case BT_COMMA:
+ case BT_SOL:
+ case BT_EQUALS:
+ case BT_QUEST:
+ case BT_CR:
+ case BT_LF:
+ case BT_SEMI:
+ case BT_EXCL:
+ case BT_AST:
+ case BT_PERCNT:
+ case BT_NUM:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ break;
+ case BT_S:
+ if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ break;
+ case BT_NAME:
+ case BT_NMSTRT:
+ if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+ break;
+ default:
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case 0x24: /* $ */
+ case 0x40: /* @ */
+ break;
+ default:
+ *badPtr = ptr;
+ return 0;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty
+ element tag. Returns the number of attributes. Pointers to the
+ first attsMax attributes are stored in atts.
+*/
+
+static int PTRCALL
+PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+ int attsMax, ATTRIBUTE *atts)
+{
+ enum { other, inName, inValue } state = inName;
+ int nAtts = 0;
+ int open = 0; /* defined when state == inValue;
+ initialization just to shut up compilers */
+
+ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+ if (state == other) { \
+ if (nAtts < attsMax) { \
+ atts[nAtts].name = ptr; \
+ atts[nAtts].normalized = 1; \
+ } \
+ state = inName; \
+ }
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONASCII:
+ case BT_NMSTRT:
+ case BT_HEX:
+ START_NAME
+ break;
+#undef START_NAME
+ case BT_QUOT:
+ if (state != inValue) {
+ if (nAtts < attsMax)
+ atts[nAtts].valuePtr = ptr + MINBPC(enc);
+ state = inValue;
+ open = BT_QUOT;
+ }
+ else if (open == BT_QUOT) {
+ state = other;
+ if (nAtts < attsMax)
+ atts[nAtts].valueEnd = ptr;
+ nAtts++;
+ }
+ break;
+ case BT_APOS:
+ if (state != inValue) {
+ if (nAtts < attsMax)
+ atts[nAtts].valuePtr = ptr + MINBPC(enc);
+ state = inValue;
+ open = BT_APOS;
+ }
+ else if (open == BT_APOS) {
+ state = other;
+ if (nAtts < attsMax)
+ atts[nAtts].valueEnd = ptr;
+ nAtts++;
+ }
+ break;
+ case BT_AMP:
+ if (nAtts < attsMax)
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_S:
+ if (state == inName)
+ state = other;
+ else if (state == inValue
+ && nAtts < attsMax
+ && atts[nAtts].normalized
+ && (ptr == atts[nAtts].valuePtr
+ || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+ || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+ || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_CR: case BT_LF:
+ /* This case ensures that the first attribute name is counted
+ Apart from that we could just change state on the quote. */
+ if (state == inName)
+ state = other;
+ else if (state == inValue && nAtts < attsMax)
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_GT:
+ case BT_SOL:
+ if (state != inValue)
+ return nAtts;
+ break;
+ default:
+ break;
+ }
+ }
+ /* not reached */
+}
+
+static int PTRFASTCALL
+PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+ int result = 0;
+ /* skip &# */
+ ptr += 2*MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+ for (ptr += MINBPC(enc);
+ !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
+ ptr += MINBPC(enc)) {
+ int c = BYTE_TO_ASCII(enc, ptr);
+ switch (c) {
+ case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+ case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+ result <<= 4;
+ result |= (c - ASCII_0);
+ break;
+ case ASCII_A: case ASCII_B: case ASCII_C:
+ case ASCII_D: case ASCII_E: case ASCII_F:
+ result <<= 4;
+ result += 10 + (c - ASCII_A);
+ break;
+ case ASCII_a: case ASCII_b: case ASCII_c:
+ case ASCII_d: case ASCII_e: case ASCII_f:
+ result <<= 4;
+ result += 10 + (c - ASCII_a);
+ break;
+ }
+ if (result >= 0x110000)
+ return -1;
+ }
+ }
+ else {
+ for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+ int c = BYTE_TO_ASCII(enc, ptr);
+ result *= 10;
+ result += (c - ASCII_0);
+ if (result >= 0x110000)
+ return -1;
+ }
+ }
+ return checkCharRefNumber(result);
+}
+
+static int PTRCALL
+PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+ const char *end)
+{
+ switch ((end - ptr)/MINBPC(enc)) {
+ case 2:
+ if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_l:
+ return ASCII_LT;
+ case ASCII_g:
+ return ASCII_GT;
+ }
+ }
+ break;
+ case 3:
+ if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_p))
+ return ASCII_AMP;
+ }
+ }
+ break;
+ case 4:
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_q:
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_t))
+ return ASCII_QUOT;
+ }
+ }
+ break;
+ case ASCII_a:
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_s))
+ return ASCII_APOS;
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static int PTRCALL
+PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (*ptr1++ != *ptr2++) \
+ return 0;
+ LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+ /* fall through */
+ if (*ptr1++ != *ptr2++)
+ return 0;
+ break;
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 1) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 2) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 3) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ }
+ }
+ }
+ break;
+ default:
+ if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+ return 1;
+ switch (BYTE_TYPE(enc, ptr2)) {
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+ }
+ /* not reached */
+}
+
+static int PTRCALL
+PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+ const char *end1, const char *ptr2)
+{
+ for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+ if (ptr1 == end1)
+ return 0;
+ if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+ return 0;
+ }
+ return ptr1 == end1;
+}
+
+static int PTRFASTCALL
+PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+ const char *start = ptr;
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ return (int)(ptr - start);
+ }
+ }
+}
+
+static const char * PTRFASTCALL
+PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_LF:
+ case BT_CR:
+ case BT_S:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ return ptr;
+ }
+ }
+}
+
+static void PTRCALL
+PREFIX(updatePosition)(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ POSITION *pos)
+{
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_LF:
+ pos->columnNumber = (XML_Size)-1;
+ pos->lineNumber++;
+ ptr += MINBPC(enc);
+ break;
+ case BT_CR:
+ pos->lineNumber++;
+ ptr += MINBPC(enc);
+ if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ pos->columnNumber = (XML_Size)-1;
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ pos->columnNumber++;
+ }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
+
diff --git a/sys/src/cmd/python/Modules/expat/xmltok_impl.h b/sys/src/cmd/python/Modules/expat/xmltok_impl.h
new file mode 100644
index 000000000..da0ea60a6
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmltok_impl.h
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+enum {
+ BT_NONXML,
+ BT_MALFORM,
+ BT_LT,
+ BT_AMP,
+ BT_RSQB,
+ BT_LEAD2,
+ BT_LEAD3,
+ BT_LEAD4,
+ BT_TRAIL,
+ BT_CR,
+ BT_LF,
+ BT_GT,
+ BT_QUOT,
+ BT_APOS,
+ BT_EQUALS,
+ BT_QUEST,
+ BT_EXCL,
+ BT_SOL,
+ BT_SEMI,
+ BT_NUM,
+ BT_LSQB,
+ BT_S,
+ BT_NMSTRT,
+ BT_COLON,
+ BT_HEX,
+ BT_DIGIT,
+ BT_NAME,
+ BT_MINUS,
+ BT_OTHER, /* known not to be a name or name start character */
+ BT_NONASCII, /* might be a name or name start character */
+ BT_PERCNT,
+ BT_LPAR,
+ BT_RPAR,
+ BT_AST,
+ BT_PLUS,
+ BT_COMMA,
+ BT_VERBAR
+};
+
+#include <stddef.h>
diff --git a/sys/src/cmd/python/Modules/expat/xmltok_ns.c b/sys/src/cmd/python/Modules/expat/xmltok_ns.c
new file mode 100644
index 000000000..d2f893836
--- /dev/null
+++ b/sys/src/cmd/python/Modules/expat/xmltok_ns.c
@@ -0,0 +1,106 @@
+const ENCODING *
+NS(XmlGetUtf8InternalEncoding)(void)
+{
+ return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *
+NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if BYTEORDER == 1234
+ return &ns(internal_little2_encoding).enc;
+#elif BYTEORDER == 4321
+ return &ns(internal_big2_encoding).enc;
+#else
+ const short n = 1;
+ return (*(const char *)&n
+ ? &ns(internal_little2_encoding).enc
+ : &ns(internal_big2_encoding).enc);
+#endif
+}
+
+static const ENCODING * const NS(encodings)[] = {
+ &ns(latin1_encoding).enc,
+ &ns(ascii_encoding).enc,
+ &ns(utf8_encoding).enc,
+ &ns(big2_encoding).enc,
+ &ns(big2_encoding).enc,
+ &ns(little2_encoding).enc,
+ &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static int PTRCALL
+NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+ XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static int PTRCALL
+NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+ XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int
+NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
+ const char *name)
+{
+ int i = getEncodingIndex(name);
+ if (i == UNKNOWN_ENC)
+ return 0;
+ SET_INIT_ENC_INDEX(p, i);
+ p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+ p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+ p->initEnc.updatePosition = initUpdatePosition;
+ p->encPtr = encPtr;
+ *encPtr = &(p->initEnc);
+ return 1;
+}
+
+static const ENCODING *
+NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+ char buf[ENCODING_MAX];
+ char *p = buf;
+ int i;
+ XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+ if (ptr != end)
+ return 0;
+ *p = 0;
+ if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+ return enc;
+ i = getEncodingIndex(buf);
+ if (i == UNKNOWN_ENC)
+ return 0;
+ return NS(encodings)[i];
+}
+
+int
+NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingName,
+ const ENCODING **encoding,
+ int *standalone)
+{
+ return doParseXmlDecl(NS(findEncoding),
+ isGeneralTextEntity,
+ enc,
+ ptr,
+ end,
+ badPtr,
+ versionPtr,
+ versionEndPtr,
+ encodingName,
+ encoding,
+ standalone);
+}
diff --git a/sys/src/cmd/python/Modules/fcntlmodule.c b/sys/src/cmd/python/Modules/fcntlmodule.c
new file mode 100644
index 000000000..5198baa5e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/fcntlmodule.c
@@ -0,0 +1,607 @@
+
+/* fcntl module */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+
+static int
+conv_descriptor(PyObject *object, int *target)
+{
+ int fd = PyObject_AsFileDescriptor(object);
+
+ if (fd < 0)
+ return 0;
+ *target = fd;
+ return 1;
+}
+
+
+/* fcntl(fd, opt, [arg]) */
+
+static PyObject *
+fcntl_fcntl(PyObject *self, PyObject *args)
+{
+ int fd;
+ int code;
+ int arg;
+ int ret;
+ char *str;
+ Py_ssize_t len;
+ char buf[1024];
+
+ if (PyArg_ParseTuple(args, "O&is#:fcntl",
+ conv_descriptor, &fd, &code, &str, &len)) {
+ if (len > sizeof buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "fcntl string arg too long");
+ return NULL;
+ }
+ memcpy(buf, str, len);
+ Py_BEGIN_ALLOW_THREADS
+ ret = fcntl(fd, code, buf);
+ Py_END_ALLOW_THREADS
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyString_FromStringAndSize(buf, len);
+ }
+
+ PyErr_Clear();
+ arg = 0;
+ if (!PyArg_ParseTuple(args,
+ "O&i|i;fcntl requires a file or file descriptor,"
+ " an integer and optionally a third integer or a string",
+ conv_descriptor, &fd, &code, &arg)) {
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ ret = fcntl(fd, code, arg);
+ Py_END_ALLOW_THREADS
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyInt_FromLong((long)ret);
+}
+
+PyDoc_STRVAR(fcntl_doc,
+"fcntl(fd, opt, [arg])\n\
+\n\
+Perform the requested operation on file descriptor fd. The operation\n\
+is defined by op and is operating system dependent. These constants are\n\
+available from the fcntl module. The argument arg is optional, and\n\
+defaults to 0; it may be an int or a string. If arg is given as a string,\n\
+the return value of fcntl is a string of that length, containing the\n\
+resulting value put in the arg buffer by the operating system.The length\n\
+of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
+is an integer or if none is specified, the result value is an integer\n\
+corresponding to the return value of the fcntl call in the C code.");
+
+
+/* ioctl(fd, opt, [arg]) */
+
+static PyObject *
+fcntl_ioctl(PyObject *self, PyObject *args)
+{
+#define IOCTL_BUFSZ 1024
+ int fd;
+ /* In PyArg_ParseTuple below, use the unsigned int 'I' format for
+ the signed int 'code' variable, because Python turns 0x8000000
+ into a large positive number (PyLong, or PyInt on 64-bit
+ platforms,) whereas C expects it to be a negative int */
+ int code;
+ int arg;
+ int ret;
+ char *str;
+ Py_ssize_t len;
+ int mutate_arg = 1;
+ char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
+
+ if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
+ conv_descriptor, &fd, &code,
+ &str, &len, &mutate_arg)) {
+ char *arg;
+
+ if (mutate_arg) {
+ if (len <= IOCTL_BUFSZ) {
+ memcpy(buf, str, len);
+ buf[len] = '\0';
+ arg = buf;
+ }
+ else {
+ arg = str;
+ }
+ }
+ else {
+ if (len > IOCTL_BUFSZ) {
+ PyErr_SetString(PyExc_ValueError,
+ "ioctl string arg too long");
+ return NULL;
+ }
+ else {
+ memcpy(buf, str, len);
+ buf[len] = '\0';
+ arg = buf;
+ }
+ }
+ if (buf == arg) {
+ Py_BEGIN_ALLOW_THREADS /* think array.resize() */
+ ret = ioctl(fd, code, arg);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ ret = ioctl(fd, code, arg);
+ }
+ if (mutate_arg && (len < IOCTL_BUFSZ)) {
+ memcpy(str, buf, len);
+ }
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ if (mutate_arg) {
+ return PyInt_FromLong(ret);
+ }
+ else {
+ return PyString_FromStringAndSize(buf, len);
+ }
+ }
+
+ PyErr_Clear();
+ if (PyArg_ParseTuple(args, "O&Is#:ioctl",
+ conv_descriptor, &fd, &code, &str, &len)) {
+ if (len > IOCTL_BUFSZ) {
+ PyErr_SetString(PyExc_ValueError,
+ "ioctl string arg too long");
+ return NULL;
+ }
+ memcpy(buf, str, len);
+ buf[len] = '\0';
+ Py_BEGIN_ALLOW_THREADS
+ ret = ioctl(fd, code, buf);
+ Py_END_ALLOW_THREADS
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyString_FromStringAndSize(buf, len);
+ }
+
+ PyErr_Clear();
+ arg = 0;
+ if (!PyArg_ParseTuple(args,
+ "O&I|i;ioctl requires a file or file descriptor,"
+ " an integer and optionally an integer or buffer argument",
+ conv_descriptor, &fd, &code, &arg)) {
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+#ifdef __VMS
+ ret = ioctl(fd, code, (void *)arg);
+#else
+ ret = ioctl(fd, code,
+#ifdef PLAN9APE
+ (void *)
+#endif
+ arg);
+#endif
+ Py_END_ALLOW_THREADS
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyInt_FromLong((long)ret);
+#undef IOCTL_BUFSZ
+}
+
+PyDoc_STRVAR(ioctl_doc,
+"ioctl(fd, opt[, arg[, mutate_flag]])\n\
+\n\
+Perform the requested operation on file descriptor fd. The operation is\n\
+defined by opt and is operating system dependent. Typically these codes are\n\
+retrieved from the fcntl or termios library modules.\n\
+\n\
+The argument arg is optional, and defaults to 0; it may be an int or a\n\
+buffer containing character data (most likely a string or an array). \n\
+\n\
+If the argument is a mutable buffer (such as an array) and if the\n\
+mutate_flag argument (which is only allowed in this case) is true then the\n\
+buffer is (in effect) passed to the operating system and changes made by\n\
+the OS will be reflected in the contents of the buffer after the call has\n\
+returned. The return value is the integer returned by the ioctl system\n\
+call.\n\
+\n\
+If the argument is a mutable buffer and the mutable_flag argument is not\n\
+passed or is false, the behavior is as if a string had been passed. This\n\
+behavior will change in future releases of Python.\n\
+\n\
+If the argument is an immutable buffer (most likely a string) then a copy\n\
+of the buffer is passed to the operating system and the return value is a\n\
+string of the same length containing whatever the operating system put in\n\
+the buffer. The length of the arg buffer in this case is not allowed to\n\
+exceed 1024 bytes.\n\
+\n\
+If the arg given is an integer or if none is specified, the result value is\n\
+an integer corresponding to the return value of the ioctl call in the C\n\
+code.");
+
+
+/* flock(fd, operation) */
+
+static PyObject *
+fcntl_flock(PyObject *self, PyObject *args)
+{
+ int fd;
+ int code;
+ int ret;
+
+ if (!PyArg_ParseTuple(args, "O&i:flock",
+ conv_descriptor, &fd, &code))
+ return NULL;
+
+#ifdef HAVE_FLOCK
+ Py_BEGIN_ALLOW_THREADS
+ ret = flock(fd, code);
+ Py_END_ALLOW_THREADS
+#else
+
+#ifndef LOCK_SH
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* don't block when locking */
+#define LOCK_UN 8 /* unlock */
+#endif
+ {
+ struct flock l;
+ if (code == LOCK_UN)
+ l.l_type = F_UNLCK;
+ else if (code & LOCK_SH)
+ l.l_type = F_RDLCK;
+ else if (code & LOCK_EX)
+ l.l_type = F_WRLCK;
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "unrecognized flock argument");
+ return NULL;
+ }
+ l.l_whence = l.l_start = l.l_len = 0;
+ Py_BEGIN_ALLOW_THREADS
+ ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
+ Py_END_ALLOW_THREADS
+ }
+#endif /* HAVE_FLOCK */
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(flock_doc,
+"flock(fd, operation)\n\
+\n\
+Perform the lock operation op on file descriptor fd. See the Unix \n\
+manual page for flock(3) for details. (On some systems, this function is\n\
+emulated using fcntl().)");
+
+
+/* lockf(fd, operation) */
+static PyObject *
+fcntl_lockf(PyObject *self, PyObject *args)
+{
+ int fd, code, ret, whence = 0;
+ PyObject *lenobj = NULL, *startobj = NULL;
+
+ if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
+ conv_descriptor, &fd, &code,
+ &lenobj, &startobj, &whence))
+ return NULL;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ PyErr_SetString(PyExc_NotImplementedError,
+ "lockf not supported on OS/2 (EMX)");
+ return NULL;
+#else
+#ifndef LOCK_SH
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* don't block when locking */
+#define LOCK_UN 8 /* unlock */
+#endif /* LOCK_SH */
+ {
+ struct flock l;
+ if (code == LOCK_UN)
+ l.l_type = F_UNLCK;
+ else if (code & LOCK_SH)
+ l.l_type = F_RDLCK;
+ else if (code & LOCK_EX)
+ l.l_type = F_WRLCK;
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "unrecognized lockf argument");
+ return NULL;
+ }
+ l.l_start = l.l_len = 0;
+ if (startobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ l.l_start = PyInt_AsLong(startobj);
+#else
+ l.l_start = PyLong_Check(startobj) ?
+ PyLong_AsLongLong(startobj) :
+ PyInt_AsLong(startobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+ }
+ if (lenobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ l.l_len = PyInt_AsLong(lenobj);
+#else
+ l.l_len = PyLong_Check(lenobj) ?
+ PyLong_AsLongLong(lenobj) :
+ PyInt_AsLong(lenobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+ }
+ l.l_whence = whence;
+ Py_BEGIN_ALLOW_THREADS
+ ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
+ Py_END_ALLOW_THREADS
+ }
+ if (ret < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
+}
+
+PyDoc_STRVAR(lockf_doc,
+"lockf (fd, operation, length=0, start=0, whence=0)\n\
+\n\
+This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
+file descriptor of the file to lock or unlock, and operation is one of the\n\
+following values:\n\
+\n\
+ LOCK_UN - unlock\n\
+ LOCK_SH - acquire a shared lock\n\
+ LOCK_EX - acquire an exclusive lock\n\
+\n\
+When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
+LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
+lock cannot be acquired, an IOError will be raised and the exception will\n\
+have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
+system -- for portability, check for either value).\n\
+\n\
+length is the number of bytes to lock, with the default meaning to lock to\n\
+EOF. start is the byte offset, relative to whence, to that the lock\n\
+starts. whence is as with fileobj.seek(), specifically:\n\
+\n\
+ 0 - relative to the start of the file (SEEK_SET)\n\
+ 1 - relative to the current buffer position (SEEK_CUR)\n\
+ 2 - relative to the end of the file (SEEK_END)");
+
+/* List of functions */
+
+static PyMethodDef fcntl_methods[] = {
+ {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
+ {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
+ {"flock", fcntl_flock, METH_VARARGS, flock_doc},
+ {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module performs file control and I/O control on file \n\
+descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
+routines. File descriptors can be obtained with the fileno() method of\n\
+a file or socket object.");
+
+/* Module initialisation */
+
+static int
+ins(PyObject* d, char* symbol, long value)
+{
+ PyObject* v = PyInt_FromLong(value);
+ if (!v || PyDict_SetItemString(d, symbol, v) < 0)
+ return -1;
+
+ Py_DECREF(v);
+ return 0;
+}
+
+#define INS(x) if (ins(d, #x, (long)x)) return -1
+
+static int
+all_ins(PyObject* d)
+{
+ if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
+ if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
+ if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
+ if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
+/* GNU extensions, as of glibc 2.2.4 */
+#ifdef LOCK_MAND
+ if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
+#endif
+#ifdef LOCK_READ
+ if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
+#endif
+#ifdef LOCK_WRITE
+ if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
+#endif
+#ifdef LOCK_RW
+ if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
+#endif
+
+#ifdef F_DUPFD
+ if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
+#endif
+#ifdef F_GETFD
+ if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
+#endif
+#ifdef F_SETFD
+ if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
+#endif
+#ifdef F_GETFL
+ if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
+#endif
+#ifdef F_SETFL
+ if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
+#endif
+#ifdef F_GETLK
+ if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
+#endif
+#ifdef F_SETLK
+ if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
+#endif
+#ifdef F_SETLKW
+ if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
+#endif
+#ifdef F_GETOWN
+ if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
+#endif
+#ifdef F_SETOWN
+ if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
+#endif
+#ifdef F_GETSIG
+ if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
+#endif
+#ifdef F_SETSIG
+ if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
+#endif
+#ifdef F_RDLCK
+ if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
+#endif
+#ifdef F_WRLCK
+ if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
+#endif
+#ifdef F_UNLCK
+ if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
+#endif
+/* LFS constants */
+#ifdef F_GETLK64
+ if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
+#endif
+#ifdef F_SETLK64
+ if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
+#endif
+#ifdef F_SETLKW64
+ if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
+#endif
+/* GNU extensions, as of glibc 2.2.4. */
+#ifdef F_SETLEASE
+ if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
+#endif
+#ifdef F_GETLEASE
+ if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
+#endif
+#ifdef F_NOTIFY
+ if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
+#endif
+/* Old BSD flock(). */
+#ifdef F_EXLCK
+ if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
+#endif
+#ifdef F_SHLCK
+ if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
+#endif
+
+/* For F_{GET|SET}FL */
+#ifdef FD_CLOEXEC
+ if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
+#endif
+
+/* For F_NOTIFY */
+#ifdef DN_ACCESS
+ if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
+#endif
+#ifdef DN_MODIFY
+ if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
+#endif
+#ifdef DN_CREATE
+ if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
+#endif
+#ifdef DN_DELETE
+ if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
+#endif
+#ifdef DN_RENAME
+ if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
+#endif
+#ifdef DN_ATTRIB
+ if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
+#endif
+#ifdef DN_MULTISHOT
+ if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
+#endif
+
+#ifdef HAVE_STROPTS_H
+ /* Unix 98 guarantees that these are in stropts.h. */
+ INS(I_PUSH);
+ INS(I_POP);
+ INS(I_LOOK);
+ INS(I_FLUSH);
+ INS(I_FLUSHBAND);
+ INS(I_SETSIG);
+ INS(I_GETSIG);
+ INS(I_FIND);
+ INS(I_PEEK);
+ INS(I_SRDOPT);
+ INS(I_GRDOPT);
+ INS(I_NREAD);
+ INS(I_FDINSERT);
+ INS(I_STR);
+ INS(I_SWROPT);
+#ifdef I_GWROPT
+ /* despite the comment above, old-ish glibcs miss a couple... */
+ INS(I_GWROPT);
+#endif
+ INS(I_SENDFD);
+ INS(I_RECVFD);
+ INS(I_LIST);
+ INS(I_ATMARK);
+ INS(I_CKBAND);
+ INS(I_GETBAND);
+ INS(I_CANPUT);
+ INS(I_SETCLTIME);
+#ifdef I_GETCLTIME
+ INS(I_GETCLTIME);
+#endif
+ INS(I_LINK);
+ INS(I_UNLINK);
+ INS(I_PLINK);
+ INS(I_PUNLINK);
+#endif
+
+ return 0;
+}
+
+PyMODINIT_FUNC
+initfcntl(void)
+{
+ PyObject *m, *d;
+
+ /* Create the module and add the functions and documentation */
+ m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ all_ins(d);
+}
diff --git a/sys/src/cmd/python/Modules/flmodule.c b/sys/src/cmd/python/Modules/flmodule.c
new file mode 100644
index 000000000..e507c9fb5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/flmodule.c
@@ -0,0 +1,2139 @@
+/* FL module -- interface to Mark Overmars' FORMS Library. */
+
+/* This code works with FORMS version 2.2 (if you defined
+ OBSOLETE_FORMS_CALLS), and 2.3.
+ FORMS can be ftp'ed from ftp.cs.ruu.nl (131.211.80.17), directory
+ /pub/SGI/FORMS. */
+
+/* A half-hearted attempt has been made to allow programs using this
+ * module to exploit parallelism (through the threads module). No provisions
+ * have been made for multiple threads to use this module at the same time,
+ * though. So, a program with a forms thread and a non-forms thread will work
+ * fine but a program with two threads using forms will probably crash (unless
+ * the program takes precaution to ensure that only one thread can be in
+ * this module at any time). This will have to be fixed some time.
+ * (A fix will probably also have to synchronize with the gl module).
+ */
+
+#include "Python.h"
+#include "forms.h"
+#include "structmember.h"
+
+/* Generic Forms Objects */
+
+typedef struct {
+ PyObject_HEAD
+ FL_OBJECT *ob_generic;
+ PyMethodDef *ob_methods;
+ PyObject *ob_callback;
+ PyObject *ob_callback_arg;
+} genericobject;
+
+static PyTypeObject GenericObjecttype;
+
+#define is_genericobject(g) ((g)->ob_type == &GenericObjecttype)
+
+/* List of all objects (XXX this should be a hash table on address...) */
+
+static PyObject *allgenerics = NULL;
+static int nfreeslots = 0;
+
+/* Add an object to the list of known objects */
+
+static void
+knowgeneric(genericobject *g)
+{
+ int i, n;
+ /* Create the list if it doesn't already exist */
+ if (allgenerics == NULL) {
+ allgenerics = PyList_New(0);
+ if (allgenerics == NULL) {
+ PyErr_Clear();
+ return; /* Too bad, live without allgenerics... */
+ }
+ }
+ if (nfreeslots > 0) {
+ /* Search the list for reusable slots (NULL items) */
+ /* XXX This can be made faster! */
+ n = PyList_Size(allgenerics);
+ for (i = 0; i < n; i++) {
+ if (PyList_GetItem(allgenerics, i) == NULL) {
+ Py_INCREF(g);
+ PyList_SetItem(allgenerics, i, (PyObject *)g);
+ nfreeslots--;
+ return;
+ }
+ }
+ /* Strange... no free slots found... */
+ nfreeslots = 0;
+ }
+ /* No free entries, append new item to the end */
+ PyList_Append(allgenerics, (PyObject *)g);
+}
+
+/* Find an object in the list of known objects */
+
+static genericobject *
+findgeneric(FL_OBJECT *generic)
+{
+ int i, n;
+ genericobject *g;
+
+ if (allgenerics == NULL)
+ return NULL; /* No objects known yet */
+ n = PyList_Size(allgenerics);
+ for (i = 0; i < n; i++) {
+ g = (genericobject *)PyList_GetItem(allgenerics, i);
+ if (g != NULL && g->ob_generic == generic)
+ return g;
+ }
+ return NULL; /* Unknown object */
+}
+
+/* Remove an object from the list of known objects */
+
+static void
+forgetgeneric(genericobject *g)
+{
+ int i, n;
+
+ Py_XDECREF(g->ob_callback);
+ g->ob_callback = NULL;
+ Py_XDECREF(g->ob_callback_arg);
+ g->ob_callback_arg = NULL;
+ if (allgenerics == NULL)
+ return; /* No objects known yet */
+ n = PyList_Size(allgenerics);
+ for (i = 0; i < n; i++) {
+ if (g == (genericobject *)PyList_GetItem(allgenerics, i)) {
+ PyList_SetItem(allgenerics, i, (PyObject *)NULL);
+ nfreeslots++;
+ break;
+ }
+ }
+}
+
+/* Called when a form is about to be freed --
+ remove all the objects that we know about from it. */
+
+static void
+releaseobjects(FL_FORM *form)
+{
+ int i, n;
+ genericobject *g;
+
+ if (allgenerics == NULL)
+ return; /* No objects known yet */
+ n = PyList_Size(allgenerics);
+ for (i = 0; i < n; i++) {
+ g = (genericobject *)PyList_GetItem(allgenerics, i);
+ if (g != NULL && g->ob_generic->form == form) {
+ fl_delete_object(g->ob_generic);
+ /* The object is now unreachable for
+ do_forms and check_forms, so
+ delete it from the list of known objects */
+ Py_XDECREF(g->ob_callback);
+ g->ob_callback = NULL;
+ Py_XDECREF(g->ob_callback_arg);
+ g->ob_callback_arg = NULL;
+ PyList_SetItem(allgenerics, i, (PyObject *)NULL);
+ nfreeslots++;
+ }
+ }
+}
+
+
+/* Methods of generic objects */
+
+static PyObject *
+generic_set_call_back(genericobject *g, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0) {
+ Py_XDECREF(g->ob_callback);
+ Py_XDECREF(g->ob_callback_arg);
+ g->ob_callback = NULL;
+ g->ob_callback_arg = NULL;
+ }
+ else {
+ PyObject *a, *b;
+ if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b)
+ return NULL;
+ Py_XDECREF(g->ob_callback);
+ Py_XDECREF(g->ob_callback_arg);
+ g->ob_callback = a;
+ Py_INCREF(g->ob_callback);
+ g->ob_callback_arg = b;
+ Py_INCREF(g->ob_callback_arg);
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+generic_call(genericobject *g, void (*func)(FL_OBJECT *))
+{
+ (*func)(g->ob_generic);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+generic_delete_object(genericobject *g)
+{
+ PyObject *res;
+ res = generic_call(g, fl_delete_object);
+ if (res != NULL)
+ forgetgeneric(g);
+ return res;
+}
+
+static PyObject *
+generic_show_object(genericobject *g)
+{
+ return generic_call(g, fl_show_object);
+}
+
+static PyObject *
+generic_hide_object(genericobject *g)
+{
+ return generic_call(g, fl_hide_object);
+}
+
+static PyObject *
+generic_redraw_object(genericobject *g)
+{
+ return generic_call(g, fl_redraw_object);
+}
+
+#ifdef OBSOLETE_FORMS_CALLS
+
+ /* (un)freeze_object() are obsolete in FORMS 2.2 and unsupported
+ in 2.3. Since there's no foolproof way to tell which version we're
+ using, we omit them unconditionally. */
+
+static PyObject *
+generic_freeze_object(genericobject *g)
+{
+ return generic_call(g, fl_freeze_object);
+}
+
+static PyObject *
+generic_unfreeze_object(genericobject *g)
+{
+ return generic_call(g, fl_unfreeze_object);
+}
+
+#endif /* OBSOLETE_FORMS_CALLS */
+
+static PyObject *
+generic_activate_object(genericobject *g)
+{
+ return generic_call(g, fl_activate_object);
+}
+
+static PyObject *
+generic_deactivate_object(genericobject *g)
+{
+ return generic_call(g, fl_deactivate_object);
+}
+
+static PyObject *
+generic_set_object_shortcut(genericobject *g, PyObject *args)
+{
+ char *str;
+ if (!PyArg_ParseTuple(args, "s:set_object_shortcut", &str))
+ return NULL;
+ fl_set_object_shortcut(g->ob_generic, str);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef generic_methods[] = {
+ {"set_call_back", (PyCFunction)generic_set_call_back, METH_VARARGS},
+ {"delete_object", (PyCFunction)generic_delete_object, METH_NOARGS},
+ {"show_object", (PyCFunction)generic_show_object, METH_NOARGS},
+ {"hide_object", (PyCFunction)generic_hide_object, METH_NOARGS},
+ {"redraw_object", (PyCFunction)generic_redraw_object, METH_NOARGS},
+#ifdef OBSOLETE_FORMS_CALLS
+ {"freeze_object", (PyCFunction)generic_freeze_object, METH_NOARGS},
+ {"unfreeze_object", (PyCFunction)generic_unfreeze_object, METH_NOARGS},
+#endif
+ {"activate_object", (PyCFunction)generic_activate_object, METH_NOARGS},
+ {"deactivate_object", (PyCFunction)generic_deactivate_object, METH_NOARGS},
+ {"set_object_shortcut", (PyCFunction)generic_set_object_shortcut, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+generic_dealloc(genericobject *g)
+{
+ fl_free_object(g->ob_generic);
+ Py_XDECREF(g->ob_callback);
+ Py_XDECREF(g->ob_callback_arg);
+ PyObject_Del(g);
+}
+
+#define OFF(x) offsetof(FL_OBJECT, x)
+
+static struct memberlist generic_memberlist[] = {
+ {"objclass", T_INT, OFF(objclass), RO},
+ {"type", T_INT, OFF(type), RO},
+ {"boxtype", T_INT, OFF(boxtype)},
+ {"x", T_FLOAT, OFF(x)},
+ {"y", T_FLOAT, OFF(y)},
+ {"w", T_FLOAT, OFF(w)},
+ {"h", T_FLOAT, OFF(h)},
+ {"col1", T_INT, OFF(col1)},
+ {"col2", T_INT, OFF(col2)},
+ {"align", T_INT, OFF(align)},
+ {"lcol", T_INT, OFF(lcol)},
+ {"lsize", T_FLOAT, OFF(lsize)},
+ /* "label" is treated specially! */
+ {"lstyle", T_INT, OFF(lstyle)},
+ {"pushed", T_INT, OFF(pushed), RO},
+ {"focus", T_INT, OFF(focus), RO},
+ {"belowmouse", T_INT, OFF(belowmouse),RO},
+/* {"frozen", T_INT, OFF(frozen), RO}, */
+ {"active", T_INT, OFF(active)},
+ {"input", T_INT, OFF(input)},
+ {"visible", T_INT, OFF(visible), RO},
+ {"radio", T_INT, OFF(radio)},
+ {"automatic", T_INT, OFF(automatic)},
+ {NULL} /* Sentinel */
+};
+
+#undef OFF
+
+static PyObject *
+generic_getattr(genericobject *g, char *name)
+{
+ PyObject *meth;
+
+ /* XXX Ought to special-case name "__methods__" */
+ if (g-> ob_methods) {
+ meth = Py_FindMethod(g->ob_methods, (PyObject *)g, name);
+ if (meth != NULL) return meth;
+ PyErr_Clear();
+ }
+
+ meth = Py_FindMethod(generic_methods, (PyObject *)g, name);
+ if (meth != NULL)
+ return meth;
+ PyErr_Clear();
+
+ /* "label" is an exception, getmember only works for char pointers,
+ not for char arrays */
+ if (strcmp(name, "label") == 0)
+ return PyString_FromString(g->ob_generic->label);
+
+ return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);
+}
+
+static int
+generic_setattr(genericobject *g, char *name, PyObject *v)
+{
+ int ret;
+
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete forms object attributes");
+ return -1;
+ }
+
+ /* "label" is an exception: setmember doesn't set strings;
+ and FORMS wants you to call a function to set the label */
+ if (strcmp(name, "label") == 0) {
+ if (!PyString_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "label attr must be string");
+ return -1;
+ }
+ fl_set_object_label(g->ob_generic, PyString_AsString(v));
+ return 0;
+ }
+
+ ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v);
+
+ /* Rather than calling all the various set_object_* functions,
+ we call fl_redraw_object here. This is sometimes redundant
+ but I doubt that's a big problem */
+ if (ret == 0)
+ fl_redraw_object(g->ob_generic);
+
+ return ret;
+}
+
+static PyObject *
+generic_repr(genericobject *g)
+{
+ char buf[100];
+ PyOS_snprintf(buf, sizeof(buf), "<FORMS_object at %p, objclass=%d>",
+ g, g->ob_generic->objclass);
+ return PyString_FromString(buf);
+}
+
+static PyTypeObject GenericObjecttype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "fl.FORMS_object", /*tp_name*/
+ sizeof(genericobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)generic_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)generic_getattr, /*tp_getattr*/
+ (setattrfunc)generic_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc)generic_repr, /*tp_repr*/
+};
+
+static PyObject *
+newgenericobject(FL_OBJECT *generic, PyMethodDef *methods)
+{
+ genericobject *g;
+ g = PyObject_New(genericobject, &GenericObjecttype);
+ if (g == NULL)
+ return NULL;
+ g-> ob_generic = generic;
+ g->ob_methods = methods;
+ g->ob_callback = NULL;
+ g->ob_callback_arg = NULL;
+ knowgeneric(g);
+ return (PyObject *)g;
+}
+
+/**********************************************************************/
+/* Some common calling sequences */
+
+/* void func (object, float) */
+static PyObject *
+call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args)
+{
+ float parameter;
+
+ if (!PyArg_Parse(args, "f", &parameter)) return NULL;
+
+ (*func) (obj, parameter);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void func (object, float) */
+static PyObject *
+call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args)
+{
+ float par1, par2;
+
+ if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL;
+
+ (*func) (obj, par1, par2);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void func (object, int) */
+static PyObject *
+call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
+{
+ int parameter;
+
+ if (!PyArg_Parse(args, "i", &parameter)) return NULL;
+
+ (*func) (obj, parameter);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void func (object, char) */
+static PyObject *
+call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
+{
+ char *a;
+
+ if (!PyArg_Parse(args, "s", &a)) return NULL;
+
+ (*func) (obj, a[0]);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void func (object, string) */
+static PyObject *
+call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args)
+{
+ char *a;
+
+ if (!PyArg_Parse(args, "s", &a)) return NULL;
+
+ (*func) (obj, a);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* void func (object, int, string) */
+static PyObject *
+call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args)
+{
+ char *b;
+ int a;
+
+ if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;
+
+ (*func) (obj, a, b);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef UNUSED
+/* void func (object, int, int) */
+static PyObject *
+call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args)
+{
+ int par1, par2;
+
+ if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
+
+ (*func) (obj, par1, par2);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+/* int func (object) */
+static PyObject *
+call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj)
+{
+ int retval;
+
+ retval = (*func) (obj);
+
+ return PyInt_FromLong ((long) retval);
+}
+
+/* char * func (object) */
+static PyObject *
+call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj)
+{
+ char *str;
+
+ str = (*func) (obj);
+
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString (str);
+}
+
+/* int func (object) */
+static PyObject *
+call_forms_Rf (float (*func)(FL_OBJECT *), FL_OBJECT *obj)
+{
+ float retval;
+
+ retval = (*func) (obj);
+
+ return PyFloat_FromDouble (retval);
+}
+
+static PyObject *
+call_forms_OUTfOUTf (void (*func)(FL_OBJECT *, float *, float *), FL_OBJECT *obj)
+{
+ float f1, f2;
+
+ (*func) (obj, &f1, &f2);
+
+ return Py_BuildValue("(ff)", f1, f2);
+}
+
+#ifdef UNUSED
+static PyObject *
+call_forms_OUTf (void (*func)(FL_OBJECT *, float *), FL_OBJECT *obj)
+{
+ float f;
+
+ (*func) (obj, &f);
+
+ return PyFloat_FromDouble (f);
+}
+#endif
+
+/**********************************************************************/
+/* Class : browser */
+
+static PyObject *
+set_browser_topline(genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
+}
+
+static PyObject *
+clear_browser(genericobject *g)
+{
+ return generic_call (g, fl_clear_browser);
+}
+
+static PyObject *
+add_browser_line (genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+addto_browser (genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
+}
+
+static PyObject *
+insert_browser_line (genericobject *g, PyObject *args)
+{
+ return call_forms_INiINstr (fl_insert_browser_line,
+ g-> ob_generic, args);
+}
+
+static PyObject *
+delete_browser_line (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+replace_browser_line (genericobject *g, PyObject *args)
+{
+ return call_forms_INiINstr (fl_replace_browser_line,
+ g-> ob_generic, args);
+}
+
+static PyObject *
+get_browser_line(genericobject *g, PyObject *args)
+{
+ int i;
+ char *str;
+
+ if (!PyArg_Parse(args, "i", &i))
+ return NULL;
+
+ str = fl_get_browser_line (g->ob_generic, i);
+
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString (str);
+}
+
+static PyObject *
+load_browser (genericobject *g, PyObject *args)
+{
+ /* XXX strictly speaking this is wrong since fl_load_browser
+ XXX returns int, not void */
+ return call_forms_INstr (fl_load_browser, g-> ob_generic, args);
+}
+
+static PyObject *
+get_browser_maxline(genericobject *g)
+{
+ return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic);
+}
+
+static PyObject *
+select_browser_line (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+deselect_browser_line (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
+}
+
+static PyObject *
+deselect_browser (genericobject *g)
+{
+ return generic_call (g, fl_deselect_browser);
+}
+
+static PyObject *
+isselected_browser_line (genericobject *g, PyObject *args)
+{
+ int i, j;
+
+ if (!PyArg_Parse(args, "i", &i))
+ return NULL;
+
+ j = fl_isselected_browser_line (g->ob_generic, i);
+
+ return PyInt_FromLong (j);
+}
+
+static PyObject *
+get_browser (genericobject *g)
+{
+ return call_forms_Ri (fl_get_browser, g-> ob_generic);
+}
+
+static PyObject *
+set_browser_fontsize (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
+}
+
+static PyObject *
+set_browser_fontstyle (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
+}
+
+static PyObject *
+set_browser_specialkey (genericobject *g, PyObject *args)
+{
+ return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
+}
+
+static PyMethodDef browser_methods[] = {
+ {"set_browser_topline", (PyCFunction)set_browser_topline,
+ METH_OLDARGS},
+ {"clear_browser", (PyCFunction)clear_browser,
+ METH_NOARGS},
+ {"add_browser_line", (PyCFunction)add_browser_line,
+ METH_OLDARGS},
+ {"addto_browser", (PyCFunction)addto_browser,
+ METH_OLDARGS},
+ {"insert_browser_line", (PyCFunction)insert_browser_line,
+ METH_OLDARGS},
+ {"delete_browser_line", (PyCFunction)delete_browser_line,
+ METH_OLDARGS},
+ {"replace_browser_line", (PyCFunction)replace_browser_line,
+ METH_OLDARGS},
+ {"get_browser_line", (PyCFunction)get_browser_line,
+ METH_OLDARGS},
+ {"load_browser", (PyCFunction)load_browser,
+ METH_OLDARGS},
+ {"get_browser_maxline", (PyCFunction)get_browser_maxline,
+ METH_NOARGS,}
+ {"select_browser_line", (PyCFunction)select_browser_line,
+ METH_OLDARGS},
+ {"deselect_browser_line", (PyCFunction)deselect_browser_line,
+ METH_OLDARGS},
+ {"deselect_browser", (PyCFunction)deselect_browser,
+ METH_NOARGS,}
+ {"isselected_browser_line", (PyCFunction)isselected_browser_line,
+ METH_OLDARGS},
+ {"get_browser", (PyCFunction)get_browser,
+ METH_NOARGS,}
+ {"set_browser_fontsize", (PyCFunction)set_browser_fontsize,
+ METH_OLDARGS},
+ {"set_browser_fontstyle", (PyCFunction)set_browser_fontstyle,
+ METH_OLDARGS},
+ {"set_browser_specialkey", (PyCFunction)set_browser_specialkey,
+ METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Class: button */
+
+static PyObject *
+set_button(genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_button, g-> ob_generic, args);
+}
+
+static PyObject *
+get_button(genericobject *g)
+{
+ return call_forms_Ri (fl_get_button, g-> ob_generic);
+}
+
+static PyObject *
+get_button_numb(genericobject *g)
+{
+ return call_forms_Ri (fl_get_button_numb, g-> ob_generic);
+}
+
+static PyObject *
+set_button_shortcut(genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
+}
+
+static PyMethodDef button_methods[] = {
+ {"set_button", (PyCFunction)set_button, METH_OLDARGS},
+ {"get_button", (PyCFunction)get_button, METH_NOARGS},
+ {"get_button_numb", (PyCFunction)get_button_numb, METH_NOARGS},
+ {"set_button_shortcut", (PyCFunction)set_button_shortcut, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Class: choice */
+
+static PyObject *
+set_choice(genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+get_choice(genericobject *g)
+{
+ return call_forms_Ri (fl_get_choice, g-> ob_generic);
+}
+
+static PyObject *
+clear_choice (genericobject *g)
+{
+ return generic_call (g, fl_clear_choice);
+}
+
+static PyObject *
+addto_choice (genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+replace_choice (genericobject *g, PyObject *args)
+{
+ return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+delete_choice (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
+}
+
+static PyObject *
+get_choice_text (genericobject *g)
+{
+ return call_forms_Rstr (fl_get_choice_text, g-> ob_generic);
+}
+
+static PyObject *
+set_choice_fontsize (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
+}
+
+static PyObject *
+set_choice_fontstyle (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
+}
+
+static PyMethodDef choice_methods[] = {
+ {"set_choice", (PyCFunction)set_choice, METH_OLDARGS},
+ {"get_choice", (PyCFunction)get_choice, METH_NOARGS},
+ {"clear_choice", (PyCFunction)clear_choice, METH_NOARGS},
+ {"addto_choice", (PyCFunction)addto_choice, METH_OLDARGS},
+ {"replace_choice", (PyCFunction)replace_choice, METH_OLDARGS},
+ {"delete_choice", (PyCFunction)delete_choice, METH_OLDARGS},
+ {"get_choice_text", (PyCFunction)get_choice_text, METH_NOARGS},
+ {"set_choice_fontsize", (PyCFunction)set_choice_fontsize, METH_OLDARGS},
+ {"set_choice_fontstyle",(PyCFunction)set_choice_fontstyle, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Class : Clock */
+
+static PyObject *
+get_clock(genericobject *g)
+{
+ int i0, i1, i2;
+
+ fl_get_clock (g->ob_generic, &i0, &i1, &i2);
+
+ return Py_BuildValue("(iii)", i0, i1, i2);
+}
+
+static PyMethodDef clock_methods[] = {
+ {"get_clock", (PyCFunction)get_clock, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* CLass : Counters */
+
+static PyObject *
+get_counter_value(genericobject *g)
+{
+ return call_forms_Rf (fl_get_counter_value, g-> ob_generic);
+}
+
+static PyObject *
+set_counter_value (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_precision (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_bounds (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_step (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
+}
+
+static PyObject *
+set_counter_return (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
+}
+
+static PyMethodDef counter_methods[] = {
+ {"set_counter_value", (PyCFunction)set_counter_value,
+ METH_OLDARGS},
+ {"get_counter_value", (PyCFunction)get_counter_value,
+ METH_NOARGS},
+ {"set_counter_bounds", (PyCFunction)set_counter_bounds,
+ METH_OLDARGS},
+ {"set_counter_step", (PyCFunction)set_counter_step,
+ METH_OLDARGS},
+ {"set_counter_precision", (PyCFunction)set_counter_precision,
+ METH_OLDARGS},
+ {"set_counter_return", (PyCFunction)set_counter_return,
+ METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Class: Dials */
+
+static PyObject *
+get_dial_value(genericobject *g)
+{
+ return call_forms_Rf (fl_get_dial_value, g-> ob_generic);
+}
+
+static PyObject *
+set_dial_value (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
+}
+
+static PyObject *
+set_dial_bounds (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
+}
+
+static PyObject *
+get_dial_bounds (genericobject *g)
+{
+ return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic);
+}
+
+static PyObject *
+set_dial_step (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
+}
+
+static PyMethodDef dial_methods[] = {
+ {"set_dial_value", (PyCFunction)set_dial_value, METH_OLDARGS},
+ {"get_dial_value", (PyCFunction)get_dial_value, METH_NOARGS},
+ {"set_dial_bounds", (PyCFunction)set_dial_bounds, METH_OLDARGS},
+ {"get_dial_bounds", (PyCFunction)get_dial_bounds, METH_NOARGS},
+ {"set_dial_step", (PyCFunction)set_dial_step, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Class : Input */
+
+static PyObject *
+set_input (genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_set_input, g-> ob_generic, args);
+}
+
+static PyObject *
+get_input (genericobject *g)
+{
+ return call_forms_Rstr (fl_get_input, g-> ob_generic);
+}
+
+static PyObject *
+set_input_color (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
+}
+
+static PyObject *
+set_input_return (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
+}
+
+static PyMethodDef input_methods[] = {
+ {"set_input", (PyCFunction)set_input, METH_OLDARGS},
+ {"get_input", (PyCFunction)get_input, METH_NOARGS},
+ {"set_input_color", (PyCFunction)set_input_color, METH_OLDARGS},
+ {"set_input_return", (PyCFunction)set_input_return, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Class : Menu */
+
+static PyObject *
+set_menu (genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
+}
+
+static PyObject *
+get_menu (genericobject *g)
+{
+ /* XXX strictly speaking this is wrong since fl_get_menu
+ XXX returns long, not int */
+ return call_forms_Ri (fl_get_menu, g-> ob_generic);
+}
+
+static PyObject *
+get_menu_text (genericobject *g)
+{
+ return call_forms_Rstr (fl_get_menu_text, g-> ob_generic);
+}
+
+static PyObject *
+addto_menu (genericobject *g, PyObject *args)
+{
+ return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
+}
+
+static PyMethodDef menu_methods[] = {
+ {"set_menu", (PyCFunction)set_menu, METH_OLDARGS},
+ {"get_menu", (PyCFunction)get_menu, METH_NOARGS},
+ {"get_menu_text", (PyCFunction)get_menu_text, METH_NOARGS},
+ {"addto_menu", (PyCFunction)addto_menu, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Class: Sliders */
+
+static PyObject *
+get_slider_value(genericobject *g)
+{
+ return call_forms_Rf (fl_get_slider_value, g-> ob_generic);
+}
+
+static PyObject *
+set_slider_value (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_bounds (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
+}
+
+static PyObject *
+get_slider_bounds (genericobject *g)
+{
+ return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic);
+}
+
+static PyObject *
+set_slider_return (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_size (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_precision (genericobject *g, PyObject *args)
+{
+ return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
+}
+
+static PyObject *
+set_slider_step (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
+}
+
+
+static PyMethodDef slider_methods[] = {
+ {"set_slider_value", (PyCFunction)set_slider_value, METH_OLDARGS},
+ {"get_slider_value", (PyCFunction)get_slider_value, METH_NOARGS},
+ {"set_slider_bounds", (PyCFunction)set_slider_bounds, METH_OLDARGS},
+ {"get_slider_bounds", (PyCFunction)get_slider_bounds, METH_NOARGS},
+ {"set_slider_return", (PyCFunction)set_slider_return, METH_OLDARGS},
+ {"set_slider_size", (PyCFunction)set_slider_size, METH_OLDARGS},
+ {"set_slider_precision",(PyCFunction)set_slider_precision, METH_OLDARGS},
+ {"set_slider_step", (PyCFunction)set_slider_step, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+set_positioner_xvalue (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
+}
+
+static PyObject *
+set_positioner_xbounds (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_positioner_xbounds,
+ g-> ob_generic, args);
+}
+
+static PyObject *
+set_positioner_yvalue (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
+}
+
+static PyObject *
+set_positioner_ybounds (genericobject *g, PyObject *args)
+{
+ return call_forms_INfINf (fl_set_positioner_ybounds,
+ g-> ob_generic, args);
+}
+
+static PyObject *
+get_positioner_xvalue (genericobject *g)
+{
+ return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic);
+}
+
+static PyObject *
+get_positioner_xbounds (genericobject *g)
+{
+ return call_forms_OUTfOUTf (fl_get_positioner_xbounds, g-> ob_generic);
+}
+
+static PyObject *
+get_positioner_yvalue (genericobject *g)
+{
+ return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic);
+}
+
+static PyObject *
+get_positioner_ybounds (genericobject *g)
+{
+ return call_forms_OUTfOUTf (fl_get_positioner_ybounds, g-> ob_generic);
+}
+
+static PyMethodDef positioner_methods[] = {
+ {"set_positioner_xvalue", (PyCFunction)set_positioner_xvalue,
+ METH_OLDARGS},
+ {"set_positioner_yvalue", (PyCFunction)set_positioner_yvalue,
+ METH_OLDARGS},
+ {"set_positioner_xbounds", (PyCFunction)set_positioner_xbounds,
+ METH_OLDARGS},
+ {"set_positioner_ybounds", (PyCFunction)set_positioner_ybounds,
+ METH_OLDARGS},
+ {"get_positioner_xvalue", (PyCFunction)get_positioner_xvalue,
+ METH_NOARGS},
+ {"get_positioner_yvalue", (PyCFunction)get_positioner_yvalue,
+ METH_NOARGS},
+ {"get_positioner_xbounds", (PyCFunction)get_positioner_xbounds,
+ METH_NOARGS},
+ {"get_positioner_ybounds", (PyCFunction)get_positioner_ybounds,
+ METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Class timer */
+
+static PyObject *
+set_timer (genericobject *g, PyObject *args)
+{
+ return call_forms_INf (fl_set_timer, g-> ob_generic, args);
+}
+
+static PyObject *
+get_timer (genericobject *g)
+{
+ return call_forms_Rf (fl_get_timer, g-> ob_generic);
+}
+
+static PyMethodDef timer_methods[] = {
+ {"set_timer", (PyCFunction)set_timer, METH_OLDARGS},
+ {"get_timer", (PyCFunction)get_timer, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Form objects */
+
+typedef struct {
+ PyObject_HEAD
+ FL_FORM *ob_form;
+} formobject;
+
+static PyTypeObject Formtype;
+
+#define is_formobject(v) ((v)->ob_type == &Formtype)
+
+static PyObject *
+form_show_form(formobject *f, PyObject *args)
+{
+ int place, border;
+ char *name;
+ if (!PyArg_Parse(args, "(iis)", &place, &border, &name))
+ return NULL;
+ fl_show_form(f->ob_form, place, border, name);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+form_call(void (*func)(FL_FORM *), FL_FORM *f)
+{
+ (*func)(f);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+form_call_INiINi(void (*func)(FL_FORM *, int, int), FL_FORM *f, PyObject *args)
+{
+ int a, b;
+
+ if (!PyArg_Parse(args, "(ii)", &a, &b)) return NULL;
+
+ (*func)(f, a, b);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+form_call_INfINf(void (*func)(FL_FORM *, float, float), FL_FORM *f, PyObject *args)
+{
+ float a, b;
+
+ if (!PyArg_Parse(args, "(ff)", &a, &b)) return NULL;
+
+ (*func)(f, a, b);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+form_hide_form(formobject *f)
+{
+ return form_call(fl_hide_form, f-> ob_form);
+}
+
+static PyObject *
+form_redraw_form(formobject *f)
+{
+ return form_call(fl_redraw_form, f-> ob_form);
+}
+
+static PyObject *
+form_set_form_position(formobject *f, PyObject *args)
+{
+ return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
+}
+
+static PyObject *
+form_set_form_size(formobject *f, PyObject *args)
+{
+ return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
+}
+
+static PyObject *
+form_scale_form(formobject *f, PyObject *args)
+{
+ return form_call_INfINf(fl_scale_form, f-> ob_form, args);
+}
+
+static PyObject *
+generic_add_object(formobject *f, PyObject *args, FL_OBJECT *(*func)(int, float, float, float, float, char*), PyMethodDef *internal_methods)
+{
+ int type;
+ float x, y, w, h;
+ char *name;
+ FL_OBJECT *obj;
+
+ if (!PyArg_Parse(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
+ return NULL;
+
+ fl_addto_form (f-> ob_form);
+
+ obj = (*func) (type, x, y, w, h, name);
+
+ fl_end_form();
+
+ if (obj == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ return newgenericobject (obj, internal_methods);
+}
+
+static PyObject *
+form_add_button(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_button, button_methods);
+}
+
+static PyObject *
+form_add_lightbutton(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_lightbutton, button_methods);
+}
+
+static PyObject *
+form_add_roundbutton(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_roundbutton, button_methods);
+}
+
+static PyObject *
+form_add_menu (formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_menu, menu_methods);
+}
+
+static PyObject *
+form_add_slider(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_slider, slider_methods);
+}
+
+static PyObject *
+form_add_valslider(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_valslider, slider_methods);
+}
+
+static PyObject *
+form_add_dial(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_dial, dial_methods);
+}
+
+static PyObject *
+form_add_counter(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_counter, counter_methods);
+}
+
+static PyObject *
+form_add_clock(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_clock, clock_methods);
+}
+
+static PyObject *
+form_add_box(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_box,
+ (PyMethodDef *)NULL);
+}
+
+static PyObject *
+form_add_choice(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_choice, choice_methods);
+}
+
+static PyObject *
+form_add_browser(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_browser, browser_methods);
+}
+
+static PyObject *
+form_add_positioner(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_positioner,
+ positioner_methods);
+}
+
+static PyObject *
+form_add_input(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_input, input_methods);
+}
+
+static PyObject *
+form_add_text(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_text,
+ (PyMethodDef *)NULL);
+}
+
+static PyObject *
+form_add_timer(formobject *f, PyObject *args)
+{
+ return generic_add_object(f, args, fl_add_timer, timer_methods);
+}
+
+static PyObject *
+form_freeze_form(formobject *f)
+{
+ return form_call(fl_freeze_form, f-> ob_form);
+}
+
+static PyObject *
+form_unfreeze_form(formobject *f)
+{
+ return form_call(fl_unfreeze_form, f-> ob_form);
+}
+
+static PyObject *
+form_activate_form(formobject *f)
+{
+ return form_call(fl_activate_form, f-> ob_form);
+}
+
+static PyObject *
+form_deactivate_form(formobject *f)
+{
+ return form_call(fl_deactivate_form, f-> ob_form);
+}
+
+static PyObject *
+form_bgn_group(formobject *f, PyObject *args)
+{
+ FL_OBJECT *obj;
+
+ fl_addto_form(f-> ob_form);
+ obj = fl_bgn_group();
+ fl_end_form();
+
+ if (obj == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ return newgenericobject (obj, (PyMethodDef *) NULL);
+}
+
+static PyObject *
+form_end_group(formobject *f, PyObject *args)
+{
+ fl_addto_form(f-> ob_form);
+ fl_end_group();
+ fl_end_form();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_find_first_or_last(FL_OBJECT *(*func)(FL_FORM *, int, float, float), formobject *f, PyObject *args)
+{
+ int type;
+ float mx, my;
+ FL_OBJECT *generic;
+ genericobject *g;
+
+ if (!PyArg_Parse(args, "(iff)", &type, &mx, &my)) return NULL;
+
+ generic = (*func) (f-> ob_form, type, mx, my);
+
+ if (generic == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ g = findgeneric(generic);
+ if (g == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "forms_find_{first|last} returns unknown object");
+ return NULL;
+ }
+ Py_INCREF(g);
+ return (PyObject *) g;
+}
+
+static PyObject *
+form_find_first(formobject *f, PyObject *args)
+{
+ return forms_find_first_or_last(fl_find_first, f, args);
+}
+
+static PyObject *
+form_find_last(formobject *f, PyObject *args)
+{
+ return forms_find_first_or_last(fl_find_last, f, args);
+}
+
+static PyObject *
+form_set_object_focus(formobject *f, PyObject *args)
+{
+ genericobject *g;
+ if (args == NULL || !is_genericobject(args)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ g = (genericobject *)args;
+ fl_set_object_focus(f->ob_form, g->ob_generic);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef form_methods[] = {
+/* adm */
+ {"show_form", (PyCFunction)form_show_form, METH_OLDARGS},
+ {"hide_form", (PyCFunction)form_hide_form, METH_NOARGS},
+ {"redraw_form", (PyCFunction)form_redraw_form, METH_NOARGS},
+ {"set_form_position", (PyCFunction)form_set_form_position, METH_OLDARGS},
+ {"set_form_size", (PyCFunction)form_set_form_size, METH_OLDARGS},
+ {"scale_form", (PyCFunction)form_scale_form, METH_OLDARGS},
+ {"freeze_form", (PyCFunction)form_freeze_form, METH_NOARGS},
+ {"unfreeze_form", (PyCFunction)form_unfreeze_form, METH_NOARGS},
+ {"activate_form", (PyCFunction)form_activate_form, METH_NOARGS},
+ {"deactivate_form", (PyCFunction)form_deactivate_form, METH_NOARGS},
+ {"bgn_group", (PyCFunction)form_bgn_group, METH_OLDARGS},
+ {"end_group", (PyCFunction)form_end_group, METH_OLDARGS},
+ {"find_first", (PyCFunction)form_find_first, METH_OLDARGS},
+ {"find_last", (PyCFunction)form_find_last, METH_OLDARGS},
+ {"set_object_focus", (PyCFunction)form_set_object_focus, METH_OLDARGS},
+
+/* basic objects */
+ {"add_button", (PyCFunction)form_add_button, METH_OLDARGS},
+/* {"add_bitmap", (method)form_add_bitmap, METH_OLDARGS}, */
+ {"add_lightbutton", (PyCFunction)form_add_lightbutton, METH_OLDARGS},
+ {"add_roundbutton", (PyCFunction)form_add_roundbutton, METH_OLDARGS},
+ {"add_menu", (PyCFunction)form_add_menu, METH_OLDARGS},
+ {"add_slider", (PyCFunction)form_add_slider, METH_OLDARGS},
+ {"add_positioner", (PyCFunction)form_add_positioner, METH_OLDARGS},
+ {"add_valslider", (PyCFunction)form_add_valslider, METH_OLDARGS},
+ {"add_dial", (PyCFunction)form_add_dial, METH_OLDARGS},
+ {"add_counter", (PyCFunction)form_add_counter, METH_OLDARGS},
+ {"add_box", (PyCFunction)form_add_box, METH_OLDARGS},
+ {"add_clock", (PyCFunction)form_add_clock, METH_OLDARGS},
+ {"add_choice", (PyCFunction)form_add_choice, METH_OLDARGS},
+ {"add_browser", (PyCFunction)form_add_browser, METH_OLDARGS},
+ {"add_input", (PyCFunction)form_add_input, METH_OLDARGS},
+ {"add_timer", (PyCFunction)form_add_timer, METH_OLDARGS},
+ {"add_text", (PyCFunction)form_add_text, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+form_dealloc(formobject *f)
+{
+ releaseobjects(f->ob_form);
+ if (f->ob_form->visible)
+ fl_hide_form(f->ob_form);
+ fl_free_form(f->ob_form);
+ PyObject_Del(f);
+}
+
+#define OFF(x) offsetof(FL_FORM, x)
+
+static struct memberlist form_memberlist[] = {
+ {"window", T_LONG, OFF(window), RO},
+ {"w", T_FLOAT, OFF(w)},
+ {"h", T_FLOAT, OFF(h)},
+ {"x", T_FLOAT, OFF(x), RO},
+ {"y", T_FLOAT, OFF(y), RO},
+ {"deactivated", T_INT, OFF(deactivated)},
+ {"visible", T_INT, OFF(visible), RO},
+ {"frozen", T_INT, OFF(frozen), RO},
+ {"doublebuf", T_INT, OFF(doublebuf)},
+ {NULL} /* Sentinel */
+};
+
+#undef OFF
+
+static PyObject *
+form_getattr(formobject *f, char *name)
+{
+ PyObject *meth;
+
+ meth = Py_FindMethod(form_methods, (PyObject *)f, name);
+ if (meth != NULL)
+ return meth;
+ PyErr_Clear();
+ return PyMember_Get((char *)f->ob_form, form_memberlist, name);
+}
+
+static int
+form_setattr(formobject *f, char *name, PyObject *v)
+{
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete form attributes");
+ return -1;
+ }
+
+ return PyMember_Set((char *)f->ob_form, form_memberlist, name, v);
+}
+
+static PyObject *
+form_repr(formobject *f)
+{
+ char buf[100];
+ PyOS_snprintf(buf, sizeof(buf), "<FORMS_form at %p, window=%ld>",
+ f, f->ob_form->window);
+ return PyString_FromString(buf);
+}
+
+static PyTypeObject Formtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "fl.FORMS_form", /*tp_name*/
+ sizeof(formobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)form_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)form_getattr, /*tp_getattr*/
+ (setattrfunc)form_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc)form_repr, /*tp_repr*/
+};
+
+static PyObject *
+newformobject(FL_FORM *form)
+{
+ formobject *f;
+ f = PyObject_New(formobject, &Formtype);
+ if (f == NULL)
+ return NULL;
+ f->ob_form = form;
+ return (PyObject *)f;
+}
+
+
+/* The "fl" module */
+
+static PyObject *
+forms_make_form(PyObject *dummy, PyObject *args)
+{
+ int type;
+ float w, h;
+ FL_FORM *form;
+ if (!PyArg_Parse(args, "(iff)", &type, &w, &h))
+ return NULL;
+ form = fl_bgn_form(type, w, h);
+ if (form == NULL) {
+ /* XXX Actually, cannot happen! */
+ PyErr_NoMemory();
+ return NULL;
+ }
+ fl_end_form();
+ return newformobject(form);
+}
+
+static PyObject *
+forms_activate_all_forms(PyObject *f, PyObject *args)
+{
+ fl_activate_all_forms();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_deactivate_all_forms(PyObject *f, PyObject *args)
+{
+ fl_deactivate_all_forms();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *my_event_callback = NULL;
+
+static PyObject *
+forms_set_event_call_back(PyObject *dummy, PyObject *args)
+{
+ if (args == Py_None)
+ args = NULL;
+ my_event_callback = args;
+ Py_XINCREF(args);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_do_or_check_forms(PyObject *dummy, FL_OBJECT *(*func)(void))
+{
+ FL_OBJECT *generic;
+ genericobject *g;
+ PyObject *arg, *res;
+
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ generic = (*func)();
+ Py_END_ALLOW_THREADS
+ if (generic == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (generic == FL_EVENT) {
+ int dev;
+ short val;
+ if (my_event_callback == NULL)
+ return PyInt_FromLong(-1L);
+ dev = fl_qread(&val);
+ arg = Py_BuildValue("(ih)", dev, val);
+ if (arg == NULL)
+ return NULL;
+ res = PyEval_CallObject(my_event_callback, arg);
+ Py_XDECREF(res);
+ Py_DECREF(arg);
+ if (res == NULL)
+ return NULL; /* Callback raised exception */
+ continue;
+ }
+ g = findgeneric(generic);
+ if (g == NULL) {
+ /* Object not known to us (some dialogs cause this) */
+ continue; /* Ignore it */
+ }
+ if (g->ob_callback == NULL) {
+ Py_INCREF(g);
+ return ((PyObject *) g);
+ }
+ arg = PyTuple_Pack(2, (PyObject *)g, g->ob_callback_arg);
+ if (arg == NULL)
+ return NULL;
+ res = PyEval_CallObject(g->ob_callback, arg);
+ Py_XDECREF(res);
+ Py_DECREF(arg);
+ if (res == NULL)
+ return NULL; /* Callback raised exception */
+ }
+}
+
+static PyObject *
+forms_do_forms(PyObject *dummy)
+{
+ return forms_do_or_check_forms(dummy, fl_do_forms);
+}
+
+static PyObject *
+forms_check_forms(PyObject *dummy)
+{
+ return forms_do_or_check_forms(dummy, fl_check_forms);
+}
+
+static PyObject *
+forms_do_only_forms(PyObject *dummy)
+{
+ return forms_do_or_check_forms(dummy, fl_do_only_forms);
+}
+
+static PyObject *
+forms_check_only_forms(PyObject *dummy)
+{
+ return forms_do_or_check_forms(dummy, fl_check_only_forms);
+}
+
+#ifdef UNUSED
+static PyObject *
+fl_call(void (*func)(void))
+{
+ (*func)();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+static PyObject *
+forms_set_graphics_mode(PyObject *dummy, PyObject *args)
+{
+ int rgbmode, doublebuf;
+
+ if (!PyArg_Parse(args, "(ii)", &rgbmode, &doublebuf))
+ return NULL;
+ fl_set_graphics_mode(rgbmode,doublebuf);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_get_rgbmode(PyObject *dummy, PyObject *args)
+{
+ extern int fl_rgbmode;
+
+ if (args != NULL) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyInt_FromLong((long)fl_rgbmode);
+}
+
+static PyObject *
+forms_show_errors(PyObject *dummy, PyObject *args)
+{
+ int show;
+ if (!PyArg_Parse(args, "i", &show))
+ return NULL;
+ fl_show_errors(show);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_set_font_name(PyObject *dummy, PyObject *args)
+{
+ int numb;
+ char *name;
+ if (!PyArg_Parse(args, "(is)", &numb, &name))
+ return NULL;
+ fl_set_font_name(numb, name);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+static PyObject *
+forms_qdevice(PyObject *self, PyObject *args)
+{
+ short arg1;
+ if (!PyArg_Parse(args, "h", &arg1))
+ return NULL;
+ fl_qdevice(arg1);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_unqdevice(PyObject *self, PyObject *args)
+{
+ short arg1;
+ if (!PyArg_Parse(args, "h", &arg1))
+ return NULL;
+ fl_unqdevice(arg1);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_isqueued(PyObject *self, PyObject *args)
+{
+ long retval;
+ short arg1;
+ if (!PyArg_Parse(args, "h", &arg1))
+ return NULL;
+ retval = fl_isqueued(arg1);
+
+ return PyInt_FromLong(retval);
+}
+
+static PyObject *
+forms_qtest(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = fl_qtest();
+ return PyInt_FromLong(retval);
+}
+
+
+static PyObject *
+forms_qread(PyObject *self, PyObject *args)
+{
+ int dev;
+ short val;
+ Py_BEGIN_ALLOW_THREADS
+ dev = fl_qread(&val);
+ Py_END_ALLOW_THREADS
+ return Py_BuildValue("(ih)", dev, val);
+}
+
+static PyObject *
+forms_qreset(PyObject *self)
+{
+ fl_qreset();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_qenter(PyObject *self, PyObject *args)
+{
+ short arg1, arg2;
+ if (!PyArg_Parse(args, "(hh)", &arg1, &arg2))
+ return NULL;
+ fl_qenter(arg1, arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_color(PyObject *self, PyObject *args)
+{
+ int arg;
+
+ if (!PyArg_Parse(args, "i", &arg)) return NULL;
+
+ fl_color((short) arg);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_mapcolor(PyObject *self, PyObject *args)
+{
+ int arg0, arg1, arg2, arg3;
+
+ if (!PyArg_Parse(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
+ return NULL;
+
+ fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_getmcolor(PyObject *self, PyObject *args)
+{
+ int arg;
+ short r, g, b;
+
+ if (!PyArg_Parse(args, "i", &arg)) return NULL;
+
+ fl_getmcolor(arg, &r, &g, &b);
+
+ return Py_BuildValue("(hhh)", r, g, b);
+}
+
+static PyObject *
+forms_get_mouse(PyObject *self)
+{
+ float x, y;
+
+ fl_get_mouse(&x, &y);
+
+ return Py_BuildValue("(ff)", x, y);
+}
+
+static PyObject *
+forms_tie(PyObject *self, PyObject *args)
+{
+ short arg1, arg2, arg3;
+ if (!PyArg_Parse(args, "(hhh)", &arg1, &arg2, &arg3))
+ return NULL;
+ fl_tie(arg1, arg2, arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_show_message(PyObject *f, PyObject *args)
+{
+ char *a, *b, *c;
+
+ if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ fl_show_message(a, b, c);
+ Py_END_ALLOW_THREADS
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+forms_show_choice(PyObject *f, PyObject *args)
+{
+ char *m1, *m2, *m3, *b1, *b2, *b3;
+ int nb;
+ char *format;
+ long rv;
+
+ if (args == NULL || !PyTuple_Check(args)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ nb = PyTuple_Size(args) - 3;
+ if (nb <= 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "need at least one button label");
+ return NULL;
+ }
+ if (PyInt_Check(PyTuple_GetItem(args, 3))) {
+ PyErr_SetString(PyExc_TypeError,
+ "'number-of-buttons' argument not needed");
+ return NULL;
+ }
+ switch (nb) {
+ case 1: format = "(ssss)"; break;
+ case 2: format = "(sssss)"; break;
+ case 3: format = "(ssssss)"; break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "too many button labels");
+ return NULL;
+ }
+
+ if (!PyArg_Parse(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ rv = fl_show_choice(m1, m2, m3, nb, b1, b2, b3);
+ Py_END_ALLOW_THREADS
+ return PyInt_FromLong(rv);
+}
+
+static PyObject *
+forms_show_question(PyObject *f, PyObject *args)
+{
+ int ret;
+ char *a, *b, *c;
+
+ if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = fl_show_question(a, b, c);
+ Py_END_ALLOW_THREADS
+
+ return PyInt_FromLong((long) ret);
+}
+
+static PyObject *
+forms_show_input(PyObject *f, PyObject *args)
+{
+ char *str;
+ char *a, *b;
+
+ if (!PyArg_Parse(args, "(ss)", &a, &b)) return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ str = fl_show_input(a, b);
+ Py_END_ALLOW_THREADS
+
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(str);
+}
+
+static PyObject *
+forms_file_selector(PyObject *f, PyObject *args)
+{
+ char *str;
+ char *a, *b, *c, *d;
+
+ if (!PyArg_Parse(args, "(ssss)", &a, &b, &c, &d)) return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ str = fl_show_file_selector(a, b, c, d);
+ Py_END_ALLOW_THREADS
+
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(str);
+}
+
+
+static PyObject *
+forms_file_selector_func(PyObject *args, char *(*func)(void))
+{
+ char *str;
+
+ str = (*func) ();
+
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(str);
+}
+
+static PyObject *
+forms_get_directory(PyObject *f, PyObject *args)
+{
+ return forms_file_selector_func(args, fl_get_directory);
+}
+
+static PyObject *
+forms_get_pattern(PyObject *f, PyObject *args)
+{
+ return forms_file_selector_func(args, fl_get_pattern);
+}
+
+static PyObject *
+forms_get_filename(PyObject *f, PyObject *args)
+{
+ return forms_file_selector_func(args, fl_get_filename);
+}
+
+static PyMethodDef forms_methods[] = {
+/* adm */
+ {"make_form", forms_make_form, METH_OLDARGS},
+ {"activate_all_forms", forms_activate_all_forms, METH_OLDARGS},
+ {"deactivate_all_forms",forms_deactivate_all_forms, METH_OLDARGS},
+/* gl support wrappers */
+ {"qdevice", forms_qdevice, METH_OLDARGS},
+ {"unqdevice", forms_unqdevice, METH_OLDARGS},
+ {"isqueued", forms_isqueued, METH_OLDARGS},
+ {"qtest", forms_qtest, METH_OLDARGS},
+ {"qread", forms_qread, METH_OLDARGS},
+/* {"blkqread", forms_blkqread, METH_OLDARGS}, */
+ {"qreset", forms_qreset, METH_NOARGS},
+ {"qenter", forms_qenter, METH_OLDARGS},
+ {"get_mouse", forms_get_mouse, METH_NOARGS},
+ {"tie", forms_tie, METH_OLDARGS},
+/* {"new_events", forms_new_events, METH_OLDARGS}, */
+ {"color", forms_color, METH_OLDARGS},
+ {"mapcolor", forms_mapcolor, METH_OLDARGS},
+ {"getmcolor", forms_getmcolor, METH_OLDARGS},
+/* interaction */
+ {"do_forms", forms_do_forms, METH_NOARGS},
+ {"do_only_forms", forms_do_only_forms, METH_NOARGS},
+ {"check_forms", forms_check_forms, METH_NOARGS},
+ {"check_only_forms", forms_check_only_forms, METH_NOARGS},
+ {"set_event_call_back", forms_set_event_call_back, METH_OLDARGS},
+/* goodies */
+ {"show_message", forms_show_message, METH_OLDARGS},
+ {"show_question", forms_show_question, METH_OLDARGS},
+ {"show_choice", forms_show_choice, METH_OLDARGS},
+ {"show_input", forms_show_input, METH_OLDARGS},
+ {"show_file_selector", forms_file_selector, METH_OLDARGS},
+ {"file_selector", forms_file_selector, METH_OLDARGS}, /* BW compat */
+ {"get_directory", forms_get_directory, METH_OLDARGS},
+ {"get_pattern", forms_get_pattern, METH_OLDARGS},
+ {"get_filename", forms_get_filename, METH_OLDARGS},
+ {"set_graphics_mode", forms_set_graphics_mode, METH_OLDARGS},
+ {"get_rgbmode", forms_get_rgbmode, METH_OLDARGS},
+ {"show_errors", forms_show_errors, METH_OLDARGS},
+ {"set_font_name", forms_set_font_name, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+initfl(void)
+{
+ Py_InitModule("fl", forms_methods);
+ if (m == NULL)
+ return;
+ foreground();
+ fl_init();
+}
+
+
+
diff --git a/sys/src/cmd/python/Modules/fmmodule.c b/sys/src/cmd/python/Modules/fmmodule.c
new file mode 100644
index 000000000..1f7edb687
--- /dev/null
+++ b/sys/src/cmd/python/Modules/fmmodule.c
@@ -0,0 +1,264 @@
+
+/* Font Manager module */
+
+#include "Python.h"
+
+#include <gl.h>
+#include <device.h>
+#include <fmclient.h>
+
+
+/* Font Handle object implementation */
+
+typedef struct {
+ PyObject_HEAD
+ fmfonthandle fh_fh;
+} fhobject;
+
+static PyTypeObject Fhtype;
+
+#define is_fhobject(v) ((v)->ob_type == &Fhtype)
+
+static PyObject *
+newfhobject(fmfonthandle fh)
+{
+ fhobject *fhp;
+ if (fh == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "error creating new font handle");
+ return NULL;
+ }
+ fhp = PyObject_New(fhobject, &Fhtype);
+ if (fhp == NULL)
+ return NULL;
+ fhp->fh_fh = fh;
+ return (PyObject *)fhp;
+}
+
+/* Font Handle methods */
+
+static PyObject *
+fh_scalefont(fhobject *self, PyObject *args)
+{
+ double size;
+ if (!PyArg_ParseTuple(args, "d", &size))
+ return NULL;
+ return newfhobject(fmscalefont(self->fh_fh, size));
+}
+
+/* XXX fmmakefont */
+
+static PyObject *
+fh_setfont(fhobject *self)
+{
+ fmsetfont(self->fh_fh);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+fh_getfontname(fhobject *self)
+{
+ char fontname[256];
+ int len;
+ len = fmgetfontname(self->fh_fh, sizeof fontname, fontname);
+ if (len < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontname");
+ return NULL;
+ }
+ return PyString_FromStringAndSize(fontname, len);
+}
+
+static PyObject *
+fh_getcomment(fhobject *self)
+{
+ char comment[256];
+ int len;
+ len = fmgetcomment(self->fh_fh, sizeof comment, comment);
+ if (len < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "error in fmgetcomment");
+ return NULL;
+ }
+ return PyString_FromStringAndSize(comment, len);
+}
+
+static PyObject *
+fh_getfontinfo(fhobject *self)
+{
+ fmfontinfo info;
+ if (fmgetfontinfo(self->fh_fh, &info) < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontinfo");
+ return NULL;
+ }
+ return Py_BuildValue("(llllllll)",
+ info.printermatched,
+ info.fixed_width,
+ info.xorig,
+ info.yorig,
+ info.xsize,
+ info.ysize,
+ info.height,
+ info.nglyphs);
+}
+
+#if 0
+static PyObject *
+fh_getwholemetrics(fhobject *self, PyObject *args)
+{
+}
+#endif
+
+static PyObject *
+fh_getstrwidth(fhobject *self, PyObject *args)
+{
+ char *str;
+ if (!PyArg_ParseTuple(args, "s", &str))
+ return NULL;
+ return PyInt_FromLong(fmgetstrwidth(self->fh_fh, str));
+}
+
+static PyMethodDef fh_methods[] = {
+ {"scalefont", (PyCFunction)fh_scalefont, METH_VARARGS},
+ {"setfont", (PyCFunction)fh_setfont, METH_NOARGS},
+ {"getfontname", (PyCFunction)fh_getfontname, METH_NOARGS},
+ {"getcomment", (PyCFunction)fh_getcomment, METH_NOARGS},
+ {"getfontinfo", (PyCFunction)fh_getfontinfo, METH_NOARGS},
+#if 0
+ {"getwholemetrics", (PyCFunction)fh_getwholemetrics, METH_VARARGS},
+#endif
+ {"getstrwidth", (PyCFunction)fh_getstrwidth, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+fh_getattr(fhobject *fhp, char *name)
+{
+ return Py_FindMethod(fh_methods, (PyObject *)fhp, name);
+}
+
+static void
+fh_dealloc(fhobject *fhp)
+{
+ fmfreefont(fhp->fh_fh);
+ PyObject_Del(fhp);
+}
+
+static PyTypeObject Fhtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "fm.font handle", /*tp_name*/
+ sizeof(fhobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)fh_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)fh_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+
+/* Font Manager functions */
+
+static PyObject *
+fm_init(PyObject *self)
+{
+ fminit();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+fm_findfont(PyObject *self, PyObject *args)
+{
+ char *str;
+ if (!PyArg_ParseTuple(args, "s", &str))
+ return NULL;
+ return newfhobject(fmfindfont(str));
+}
+
+static PyObject *
+fm_prstr(PyObject *self, PyObject *args)
+{
+ char *str;
+ if (!PyArg_ParseTuple(args, "s", &str))
+ return NULL;
+ fmprstr(str);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* XXX This uses a global variable as temporary! Not re-entrant! */
+
+static PyObject *fontlist;
+
+static void
+clientproc(char *fontname)
+{
+ int err;
+ PyObject *v;
+ if (fontlist == NULL)
+ return;
+ v = PyString_FromString(fontname);
+ if (v == NULL)
+ err = -1;
+ else {
+ err = PyList_Append(fontlist, v);
+ Py_DECREF(v);
+ }
+ if (err != 0) {
+ Py_DECREF(fontlist);
+ fontlist = NULL;
+ }
+}
+
+static PyObject *
+fm_enumerate(PyObject *self)
+{
+ PyObject *res;
+ fontlist = PyList_New(0);
+ if (fontlist == NULL)
+ return NULL;
+ fmenumerate(clientproc);
+ res = fontlist;
+ fontlist = NULL;
+ return res;
+}
+
+static PyObject *
+fm_setpath(PyObject *self, PyObject *args)
+{
+ char *str;
+ if (!PyArg_ParseTuple(args, "s", &str))
+ return NULL;
+ fmsetpath(str);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+fm_fontpath(PyObject *self)
+{
+ return PyString_FromString(fmfontpath());
+}
+
+static PyMethodDef fm_methods[] = {
+ {"init", fm_init, METH_NOARGS},
+ {"findfont", fm_findfont, METH_VARARGS},
+ {"enumerate", fm_enumerate, METH_NOARGS},
+ {"prstr", fm_prstr, METH_VARARGS},
+ {"setpath", fm_setpath, METH_VARARGS},
+ {"fontpath", fm_fontpath, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+void
+initfm(void)
+{
+ Py_InitModule("fm", fm_methods);
+ if (m == NULL)
+ return;
+ fminit();
+}
diff --git a/sys/src/cmd/python/Modules/fpectlmodule.c b/sys/src/cmd/python/Modules/fpectlmodule.c
new file mode 100644
index 000000000..74354bac5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/fpectlmodule.c
@@ -0,0 +1,303 @@
+/*
+ ---------------------------------------------------------------------
+ / Copyright (c) 1996. \
+ | The Regents of the University of California. |
+ | All rights reserved. |
+ | |
+ | Permission to use, copy, modify, and distribute this software for |
+ | any purpose without fee is hereby granted, provided that this en- |
+ | tire notice is included in all copies of any software which is or |
+ | includes a copy or modification of this software and in all |
+ | copies of the supporting documentation for such software. |
+ | |
+ | This work was produced at the University of California, Lawrence |
+ | Livermore National Laboratory under contract no. W-7405-ENG-48 |
+ | between the U.S. Department of Energy and The Regents of the |
+ | University of California for the operation of UC LLNL. |
+ | |
+ | DISCLAIMER |
+ | |
+ | This software was prepared as an account of work sponsored by an |
+ | agency of the United States Government. Neither the United States |
+ | Government nor the University of California nor any of their em- |
+ | ployees, makes any warranty, express or implied, or assumes any |
+ | liability or responsibility for the accuracy, completeness, or |
+ | usefulness of any information, apparatus, product, or process |
+ | disclosed, or represents that its use would not infringe |
+ | privately-owned rights. Reference herein to any specific commer- |
+ | cial products, process, or service by trade name, trademark, |
+ | manufacturer, or otherwise, does not necessarily constitute or |
+ | imply its endorsement, recommendation, or favoring by the United |
+ | States Government or the University of California. The views and |
+ | opinions of authors expressed herein do not necessarily state or |
+ | reflect those of the United States Government or the University |
+ | of California, and shall not be used for advertising or product |
+ \ endorsement purposes. /
+ ---------------------------------------------------------------------
+*/
+
+/*
+ Floating point exception control module.
+
+ This Python module provides bare-bones control over floating point
+ units from several hardware manufacturers. Specifically, it allows
+ the user to turn on the generation of SIGFPE whenever any of the
+ three serious IEEE 754 exceptions (Division by Zero, Overflow,
+ Invalid Operation) occurs. We currently ignore Underflow and
+ Inexact Result exceptions, although those could certainly be added
+ if desired.
+
+ The module also establishes a signal handler for SIGFPE during
+ initialization. This builds on code found in the Python
+ distribution at Include/pyfpe.h and Python/pyfpe.c. If those files
+ are not in your Python distribution, find them in a patch at
+ ftp://icf.llnl.gov/pub/python/busby/patches.961108.tgz.
+
+ This module is only useful to you if it happens to include code
+ specific for your hardware and software environment. If you can
+ contribute OS-specific code for new platforms, or corrections for
+ the code provided, it will be greatly appreciated.
+
+ ** Version 1.0: September 20, 1996. Lee Busby, LLNL.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Python.h"
+#include <signal.h>
+
+#if defined(__FreeBSD__)
+# include <ieeefp.h>
+#elif defined(__VMS)
+#define __NEW_STARLET
+#include <starlet.h>
+#include <ieeedef.h>
+#endif
+
+#ifndef WANT_SIGFPE_HANDLER
+/* Define locally if they are not defined in Python. This gives only
+ * the limited control to induce a core dump in case of an exception.
+ */
+#include <setjmp.h>
+static jmp_buf PyFPE_jbuf;
+static int PyFPE_counter = 0;
+#endif
+
+typedef void Sigfunc(int);
+static Sigfunc sigfpe_handler;
+static void fpe_reset(Sigfunc *);
+
+static PyObject *fpe_error;
+PyMODINIT_FUNC initfpectl(void);
+static PyObject *turnon_sigfpe (PyObject *self,PyObject *args);
+static PyObject *turnoff_sigfpe (PyObject *self,PyObject *args);
+
+static PyMethodDef fpectl_methods[] = {
+ {"turnon_sigfpe", (PyCFunction) turnon_sigfpe, METH_VARARGS},
+ {"turnoff_sigfpe", (PyCFunction) turnoff_sigfpe, METH_VARARGS},
+ {0,0}
+};
+
+static PyObject *turnon_sigfpe(PyObject *self,PyObject *args)
+{
+ /* Do any architecture-specific one-time only initialization here. */
+
+ fpe_reset(sigfpe_handler);
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static void fpe_reset(Sigfunc *handler)
+{
+ /* Reset the exception handling machinery, and reset the signal
+ * handler for SIGFPE to the given handler.
+ */
+
+/*-- IRIX -----------------------------------------------------------------*/
+#if defined(sgi)
+ /* See man page on handle_sigfpes -- must link with -lfpe
+ * My usage doesn't follow the man page exactly. Maybe somebody
+ * else can explain handle_sigfpes to me....
+ * cc -c -I/usr/local/python/include fpectlmodule.c
+ * ld -shared -o fpectlmodule.so fpectlmodule.o -lfpe
+ */
+#include <sigfpe.h>
+ typedef void user_routine (unsigned[5], int[2]);
+ typedef void abort_routine (unsigned long);
+ handle_sigfpes(_OFF, 0,
+ (user_routine *)0,
+ _TURN_OFF_HANDLER_ON_ERROR,
+ NULL);
+ handle_sigfpes(_ON, _EN_OVERFL | _EN_DIVZERO | _EN_INVALID,
+ (user_routine *)0,
+ _ABORT_ON_ERROR,
+ NULL);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- SunOS and Solaris ----------------------------------------------------*/
+#elif defined(sun)
+ /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
+ man pages (SunOS or Solaris)
+ cc -c -I/usr/local/python/include fpectlmodule.c
+ ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
+ */
+#include <math.h>
+#ifndef _SUNMATH_H
+ extern void nonstandard_arithmetic(void);
+ extern int ieee_flags(const char*, const char*, const char*, char **);
+ extern long ieee_handler(const char*, const char*, sigfpe_handler_type);
+#endif
+
+ char *mode="exception", *in="all", *out;
+ (void) nonstandard_arithmetic();
+ (void) ieee_flags("clearall",mode,in,&out);
+ (void) ieee_handler("set","common",(sigfpe_handler_type)handler);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- HPUX -----------------------------------------------------------------*/
+#elif defined(__hppa) || defined(hppa)
+ /* References: fpsetmask man page */
+ /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
+ /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
+#include <math.h>
+ fpsetdefaults();
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- IBM AIX --------------------------------------------------------------*/
+#elif defined(__AIX) || defined(_AIX)
+ /* References: fp_trap, fp_enable man pages */
+#include <fptrap.h>
+ fp_trap(FP_TRAP_SYNC);
+ fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- DEC ALPHA OSF --------------------------------------------------------*/
+#elif defined(__alpha) && defined(__osf__)
+ /* References: exception_intro, ieee man pages */
+ /* cc -c -I/usr/local/python/include fpectlmodule.c */
+ /* ld -shared -o fpectlmodule.so fpectlmodule.o */
+#include <machine/fpu.h>
+ unsigned long fp_control =
+ IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
+ ieee_set_fp_control(fp_control);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- DEC ALPHA LINUX ------------------------------------------------------*/
+#elif defined(__alpha) && defined(linux)
+#include <asm/fpu.h>
+ unsigned long fp_control =
+ IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
+ ieee_set_fp_control(fp_control);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- DEC ALPHA VMS --------------------------------------------------------*/
+#elif defined(__ALPHA) && defined(__VMS)
+ IEEE clrmsk;
+ IEEE setmsk;
+ clrmsk.ieee$q_flags =
+ IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE |
+ IEEE$M_MAP_UMZ;
+ setmsk.ieee$q_flags =
+ IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE |
+ IEEE$M_TRAP_ENABLE_OVF;
+ sys$ieee_set_fp_control(&clrmsk, &setmsk, 0);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- HP IA64 VMS --------------------------------------------------------*/
+#elif defined(__ia64) && defined(__VMS)
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- Cray Unicos ----------------------------------------------------------*/
+#elif defined(cray)
+ /* UNICOS delivers SIGFPE by default, but no matherr */
+#ifdef HAS_LIBMSET
+ libmset(-1);
+#endif
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- FreeBSD ----------------------------------------------------------------*/
+#elif defined(__FreeBSD__)
+ fpresetsticky(fpgetsticky());
+ fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- Linux ----------------------------------------------------------------*/
+#elif defined(linux)
+#ifdef __GLIBC__
+#include <fpu_control.h>
+#else
+#include <i386/fpu_control.h>
+#endif
+#ifdef _FPU_SETCW
+ {
+ fpu_control_t cw = 0x1372;
+ _FPU_SETCW(cw);
+ }
+#else
+ __setfpucw(0x1372);
+#endif
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- Microsoft Windows, NT ------------------------------------------------*/
+#elif defined(_MSC_VER)
+ /* Reference: Visual C++ Books Online 4.2,
+ Run-Time Library Reference, _control87, _controlfp */
+#include <float.h>
+ unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
+ (void)_controlfp(0, cw);
+ PyOS_setsig(SIGFPE, handler);
+
+/*-- Give Up --------------------------------------------------------------*/
+#else
+ fputs("Operation not implemented\n", stderr);
+#endif
+
+}
+
+static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
+{
+#ifdef __FreeBSD__
+ fpresetsticky(fpgetsticky());
+ fpsetmask(0);
+#elif defined(__VMS)
+ IEEE clrmsk;
+ clrmsk.ieee$q_flags =
+ IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE |
+ IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV |
+ IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF |
+ IEEE$M_INHERIT;
+ sys$ieee_set_fp_control(&clrmsk, 0, 0);
+#else
+ fputs("Operation not implemented\n", stderr);
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static void sigfpe_handler(int signo)
+{
+ fpe_reset(sigfpe_handler);
+ if(PyFPE_counter) {
+ longjmp(PyFPE_jbuf, 1);
+ } else {
+ Py_FatalError("Unprotected floating point exception");
+ }
+}
+
+PyMODINIT_FUNC initfpectl(void)
+{
+ PyObject *m, *d;
+ m = Py_InitModule("fpectl", fpectl_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ fpe_error = PyErr_NewException("fpectl.error", NULL, NULL);
+ if (fpe_error != NULL)
+ PyDict_SetItemString(d, "error", fpe_error);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/src/cmd/python/Modules/fpetestmodule.c b/sys/src/cmd/python/Modules/fpetestmodule.c
new file mode 100644
index 000000000..22e95dbae
--- /dev/null
+++ b/sys/src/cmd/python/Modules/fpetestmodule.c
@@ -0,0 +1,186 @@
+/*
+ ---------------------------------------------------------------------
+ / Copyright (c) 1996. \
+ | The Regents of the University of California. |
+ | All rights reserved. |
+ | |
+ | Permission to use, copy, modify, and distribute this software for |
+ | any purpose without fee is hereby granted, provided that this en- |
+ | tire notice is included in all copies of any software which is or |
+ | includes a copy or modification of this software and in all |
+ | copies of the supporting documentation for such software. |
+ | |
+ | This work was produced at the University of California, Lawrence |
+ | Livermore National Laboratory under contract no. W-7405-ENG-48 |
+ | between the U.S. Department of Energy and The Regents of the |
+ | University of California for the operation of UC LLNL. |
+ | |
+ | DISCLAIMER |
+ | |
+ | This software was prepared as an account of work sponsored by an |
+ | agency of the United States Government. Neither the United States |
+ | Government nor the University of California nor any of their em- |
+ | ployees, makes any warranty, express or implied, or assumes any |
+ | liability or responsibility for the accuracy, completeness, or |
+ | usefulness of any information, apparatus, product, or process |
+ | disclosed, or represents that its use would not infringe |
+ | privately-owned rights. Reference herein to any specific commer- |
+ | cial products, process, or service by trade name, trademark, |
+ | manufacturer, or otherwise, does not necessarily constitute or |
+ | imply its endorsement, recommendation, or favoring by the United |
+ | States Government or the University of California. The views and |
+ | opinions of authors expressed herein do not necessarily state or |
+ | reflect those of the United States Government or the University |
+ | of California, and shall not be used for advertising or product |
+ \ endorsement purposes. /
+ ---------------------------------------------------------------------
+*/
+
+/*
+ Floating point exception test module.
+
+ */
+
+#include "Python.h"
+
+static PyObject *fpe_error;
+PyMODINIT_FUNC initfpetest(void);
+static PyObject *test(PyObject *self,PyObject *args);
+static double db0(double);
+static double overflow(double);
+static double nest1(int, double);
+static double nest2(int, double);
+static double nest3(double);
+static void printerr(double);
+
+static PyMethodDef fpetest_methods[] = {
+ {"test", (PyCFunction) test, METH_VARARGS},
+ {0,0}
+};
+
+static PyObject *test(PyObject *self,PyObject *args)
+{
+ double r;
+
+ fprintf(stderr,"overflow");
+ r = overflow(1.e160);
+ printerr(r);
+
+ fprintf(stderr,"\ndiv by 0");
+ r = db0(0.0);
+ printerr(r);
+
+ fprintf(stderr,"\nnested outer");
+ r = nest1(0, 0.0);
+ printerr(r);
+
+ fprintf(stderr,"\nnested inner");
+ r = nest1(1, 1.0);
+ printerr(r);
+
+ fprintf(stderr,"\ntrailing outer");
+ r = nest1(2, 2.0);
+ printerr(r);
+
+ fprintf(stderr,"\nnested prior");
+ r = nest2(0, 0.0);
+ printerr(r);
+
+ fprintf(stderr,"\nnested interior");
+ r = nest2(1, 1.0);
+ printerr(r);
+
+ fprintf(stderr,"\nnested trailing");
+ r = nest2(2, 2.0);
+ printerr(r);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static void printerr(double r)
+{
+ if(r == 3.1416){
+ fprintf(stderr,"\tPASS\n");
+ PyErr_Print();
+ }else{
+ fprintf(stderr,"\tFAIL\n");
+ }
+ PyErr_Clear();
+}
+
+static double nest1(int i, double x)
+{
+ double a = 1.0;
+
+ PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416)
+ if(i == 0){
+ a = 1./x;
+ }else if(i == 1){
+ /* This (following) message is never seen. */
+ PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416)
+ a = 1./(1. - x);
+ PyFPE_END_PROTECT(a)
+ }else if(i == 2){
+ a = 1./(2. - x);
+ }
+ PyFPE_END_PROTECT(a)
+
+ return a;
+}
+
+static double nest2(int i, double x)
+{
+ double a = 1.0;
+ PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416)
+ if(i == 0){
+ a = 1./x;
+ }else if(i == 1){
+ a = nest3(x);
+ }else if(i == 2){
+ a = 1./(2. - x);
+ }
+ PyFPE_END_PROTECT(a)
+ return a;
+}
+
+static double nest3(double x)
+{
+ double result;
+ /* This (following) message is never seen. */
+ PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416)
+ result = 1./(1. - x);
+ PyFPE_END_PROTECT(result)
+ return result;
+}
+
+static double db0(double x)
+{
+ double a;
+ PyFPE_START_PROTECT("Division by zero", return 3.1416)
+ a = 1./x;
+ PyFPE_END_PROTECT(a)
+ return a;
+}
+
+static double overflow(double b)
+{
+ double a;
+ PyFPE_START_PROTECT("Overflow", return 3.1416)
+ a = b*b;
+ PyFPE_END_PROTECT(a)
+ return a;
+}
+
+PyMODINIT_FUNC initfpetest(void)
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule("fpetest", fpetest_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
+ if (fpe_error != NULL)
+ PyDict_SetItemString(d, "error", fpe_error);
+}
diff --git a/sys/src/cmd/python/Modules/gc_weakref.txt b/sys/src/cmd/python/Modules/gc_weakref.txt
new file mode 100644
index 000000000..d7be6c3ab
--- /dev/null
+++ b/sys/src/cmd/python/Modules/gc_weakref.txt
@@ -0,0 +1,219 @@
+Intro
+=====
+
+The basic rule for dealing with weakref callbacks (and __del__ methods too,
+for that matter) during cyclic gc:
+
+ Once gc has computed the set of unreachable objects, no Python-level
+ code can be allowed to access an unreachable object.
+
+If that can happen, then the Python code can resurrect unreachable objects
+too, and gc can't detect that without starting over. Since gc eventually
+runs tp_clear on all unreachable objects, if an unreachable object is
+resurrected then tp_clear will eventually be called on it (or may already
+have been called before resurrection). At best (and this has been an
+historically common bug), tp_clear empties an instance's __dict__, and
+"impossible" AttributeErrors result. At worst, tp_clear leaves behind an
+insane object at the C level, and segfaults result (historically, most
+often by setting a new-style class's mro pointer to NULL, after which
+attribute lookups performed by the class can segfault).
+
+OTOH, it's OK to run Python-level code that can't access unreachable
+objects, and sometimes that's necessary. The chief example is the callback
+attached to a reachable weakref W to an unreachable object O. Since O is
+going away, and W is still alive, the callback must be invoked. Because W
+is still alive, everything reachable from its callback is also reachable,
+so it's also safe to invoke the callback (although that's trickier than it
+sounds, since other reachable weakrefs to other unreachable objects may
+still exist, and be accessible to the callback -- there are lots of painful
+details like this covered in the rest of this file).
+
+Python 2.4/2.3.5
+================
+
+The "Before 2.3.3" section below turned out to be wrong in some ways, but
+I'm leaving it as-is because it's more right than wrong, and serves as a
+wonderful example of how painful analysis can miss not only the forest for
+the trees, but also miss the trees for the aphids sucking the trees
+dry <wink>.
+
+The primary thing it missed is that when a weakref to a piece of cyclic
+trash (CT) exists, then any call to any Python code whatsoever can end up
+materializing a strong reference to that weakref's CT referent, and so
+possibly resurrect an insane object (one for which cyclic gc has called-- or
+will call before it's done --tp_clear()). It's not even necessarily that a
+weakref callback or __del__ method does something nasty on purpose: as
+soon as we execute Python code, threads other than the gc thread can run
+too, and they can do ordinary things with weakrefs that end up resurrecting
+CT while gc is running.
+
+ http://www.python.org/sf/1055820
+
+shows how innocent it can be, and also how nasty. Variants of the three
+focussed test cases attached to that bug report are now part of Python's
+standard Lib/test/test_gc.py.
+
+Jim Fulton gave the best nutshell summary of the new (in 2.4 and 2.3.5)
+approach:
+
+ Clearing cyclic trash can call Python code. If there are weakrefs to
+ any of the cyclic trash, then those weakrefs can be used to resurrect
+ the objects. Therefore, *before* clearing cyclic trash, we need to
+ remove any weakrefs. If any of the weakrefs being removed have
+ callbacks, then we need to save the callbacks and call them *after* all
+ of the weakrefs have been cleared.
+
+Alas, doing just that much doesn't work, because it overlooks what turned
+out to be the much subtler problems that were fixed earlier, and described
+below. We do clear all weakrefs to CT now before breaking cycles, but not
+all callbacks encountered can be run later. That's explained in horrid
+detail below.
+
+Older text follows, with a some later comments in [] brackets:
+
+Before 2.3.3
+============
+
+Before 2.3.3, Python's cyclic gc didn't pay any attention to weakrefs.
+Segfaults in Zope3 resulted.
+
+weakrefs in Python are designed to, at worst, let *other* objects learn
+that a given object has died, via a callback function. The weakly
+referenced object itself is not passed to the callback, and the presumption
+is that the weakly referenced object is unreachable trash at the time the
+callback is invoked.
+
+That's usually true, but not always. Suppose a weakly referenced object
+becomes part of a clump of cyclic trash. When enough cycles are broken by
+cyclic gc that the object is reclaimed, the callback is invoked. If it's
+possible for the callback to get at objects in the cycle(s), then it may be
+possible for those objects to access (via strong references in the cycle)
+the weakly referenced object being torn down, or other objects in the cycle
+that have already suffered a tp_clear() call. There's no guarantee that an
+object is in a sane state after tp_clear(). Bad things (including
+segfaults) can happen right then, during the callback's execution, or can
+happen at any later time if the callback manages to resurrect an insane
+object.
+
+[That missed that, in addition, a weakref to CT can exist outside CT, and
+ any callback into Python can use such a non-CT weakref to resurrect its CT
+ referent. The same bad kinds of things can happen then.]
+
+Note that if it's possible for the callback to get at objects in the trash
+cycles, it must also be the case that the callback itself is part of the
+trash cycles. Else the callback would have acted as an external root to
+the current collection, and nothing reachable from it would be in cyclic
+trash either.
+
+[Except that a non-CT callback can also use a non-CT weakref to get at
+ CT objects.]
+
+More, if the callback itself is in cyclic trash, then the weakref to which
+the callback is attached must also be trash, and for the same kind of
+reason: if the weakref acted as an external root, then the callback could
+not have been cyclic trash.
+
+So a problem here requires that a weakref, that weakref's callback, and the
+weakly referenced object, all be in cyclic trash at the same time. This
+isn't easy to stumble into by accident while Python is running, and, indeed,
+it took quite a while to dream up failing test cases. Zope3 saw segfaults
+during shutdown, during the second call of gc in Py_Finalize, after most
+modules had been torn down. That creates many trash cycles (esp. those
+involving new-style classes), making the problem much more likely. Once you
+know what's required to provoke the problem, though, it's easy to create
+tests that segfault before shutdown.
+
+In 2.3.3, before breaking cycles, we first clear all the weakrefs with
+callbacks in cyclic trash. Since the weakrefs *are* trash, and there's no
+defined-- or even predictable --order in which tp_clear() gets called on
+cyclic trash, it's defensible to first clear weakrefs with callbacks. It's
+a feature of Python's weakrefs too that when a weakref goes away, the
+callback (if any) associated with it is thrown away too, unexecuted.
+
+[In 2.4/2.3.5, we first clear all weakrefs to CT objects, whether or not
+ those weakrefs are themselves CT, and whether or not they have callbacks.
+ The callbacks (if any) on non-CT weakrefs (if any) are invoked later,
+ after all weakrefs-to-CT have been cleared. The callbacks (if any) on CT
+ weakrefs (if any) are never invoked, for the excruciating reasons
+ explained here.]
+
+Just that much is almost enough to prevent problems, by throwing away
+*almost* all the weakref callbacks that could get triggered by gc. The
+problem remaining is that clearing a weakref with a callback decrefs the
+callback object, and the callback object may *itself* be weakly referenced,
+via another weakref with another callback. So the process of clearing
+weakrefs can trigger callbacks attached to other weakrefs, and those
+latter weakrefs may or may not be part of cyclic trash.
+
+So, to prevent any Python code from running while gc is invoking tp_clear()
+on all the objects in cyclic trash,
+
+[That was always wrong: we can't stop Python code from running when gc
+ is breaking cycles. If an object with a __del__ method is not itself in
+ a cycle, but is reachable only from CT, then breaking cycles will, as a
+ matter of course, drop the refcount on that object to 0, and its __del__
+ will run right then. What we can and must stop is running any Python
+ code that could access CT.]
+ it's not quite enough just to invoke
+tp_clear() on weakrefs with callbacks first. Instead the weakref module
+grew a new private function (_PyWeakref_ClearRef) that does only part of
+tp_clear(): it removes the weakref from the weakly-referenced object's list
+of weakrefs, but does not decref the callback object. So calling
+_PyWeakref_ClearRef(wr) ensures that wr's callback object will never
+trigger, and (unlike weakref's tp_clear()) also prevents any callback
+associated *with* wr's callback object from triggering.
+
+[Although we may trigger such callbacks later, as explained below.]
+
+Then we can call tp_clear on all the cyclic objects and never trigger
+Python code.
+
+[As above, not so: it means never trigger Python code that can access CT.]
+
+After we do that, the callback objects still need to be decref'ed. Callbacks
+(if any) *on* the callback objects that were also part of cyclic trash won't
+get invoked, because we cleared all trash weakrefs with callbacks at the
+start. Callbacks on the callback objects that were not part of cyclic trash
+acted as external roots to everything reachable from them, so nothing
+reachable from them was part of cyclic trash, so gc didn't do any damage to
+objects reachable from them, and it's safe to call them at the end of gc.
+
+[That's so. In addition, now we also invoke (if any) the callbacks on
+ non-CT weakrefs to CT objects, during the same pass that decrefs the
+ callback objects.]
+
+An alternative would have been to treat objects with callbacks like objects
+with __del__ methods, refusing to collect them, appending them to gc.garbage
+instead. That would have been much easier. Jim Fulton gave a strong
+argument against that (on Python-Dev):
+
+ There's a big difference between __del__ and weakref callbacks.
+ The __del__ method is "internal" to a design. When you design a
+ class with a del method, you know you have to avoid including the
+ class in cycles.
+
+ Now, suppose you have a design that makes has no __del__ methods but
+ that does use cyclic data structures. You reason about the design,
+ run tests, and convince yourself you don't have a leak.
+
+ Now, suppose some external code creates a weakref to one of your
+ objects. All of a sudden, you start leaking. You can look at your
+ code all you want and you won't find a reason for the leak.
+
+IOW, a class designer can out-think __del__ problems, but has no control
+over who creates weakrefs to his classes or class instances. The class
+user has little chance either of predicting when the weakrefs he creates
+may end up in cycles.
+
+Callbacks on weakref callbacks are executed in an arbitrary order, and
+that's not good (a primary reason not to collect cycles with objects with
+__del__ methods is to avoid running finalizers in an arbitrary order).
+However, a weakref callback on a weakref callback has got to be rare.
+It's possible to do such a thing, so gc has to be robust against it, but
+I doubt anyone has done it outside the test case I wrote for it.
+
+[The callbacks (if any) on non-CT weakrefs to CT objects are also executed
+ in an arbitrary order now. But they were before too, depending on the
+ vagaries of when tp_clear() happened to break enough cycles to trigger
+ them. People simply shouldn't try to use __del__ or weakref callbacks to
+ do fancy stuff.]
diff --git a/sys/src/cmd/python/Modules/gcmodule.c b/sys/src/cmd/python/Modules/gcmodule.c
new file mode 100644
index 000000000..6c5011cab
--- /dev/null
+++ b/sys/src/cmd/python/Modules/gcmodule.c
@@ -0,0 +1,1390 @@
+/*
+
+ Reference Cycle Garbage Collection
+ ==================================
+
+ Neil Schemenauer <nas@arctrix.com>
+
+ Based on a post on the python-dev list. Ideas from Guido van Rossum,
+ Eric Tiedemann, and various others.
+
+ http://www.arctrix.com/nas/python/gc/
+ http://www.python.org/pipermail/python-dev/2000-March/003869.html
+ http://www.python.org/pipermail/python-dev/2000-March/004010.html
+ http://www.python.org/pipermail/python-dev/2000-March/004022.html
+
+ For a highlevel view of the collection process, read the collect
+ function.
+
+*/
+
+#include "Python.h"
+
+/* Get an object's GC head */
+#define AS_GC(o) ((PyGC_Head *)(o)-1)
+
+/* Get the object given the GC head */
+#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
+
+/*** Global GC state ***/
+
+struct gc_generation {
+ PyGC_Head head;
+ int threshold; /* collection threshold */
+ int count; /* count of allocations or collections of younger
+ generations */
+};
+
+#define NUM_GENERATIONS 3
+#define GEN_HEAD(n) (&generations[n].head)
+
+/* linked lists of container objects */
+static struct gc_generation generations[NUM_GENERATIONS] = {
+ /* PyGC_Head, threshold, count */
+ {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700, 0},
+ {{{GEN_HEAD(1), GEN_HEAD(1), 0}}, 10, 0},
+ {{{GEN_HEAD(2), GEN_HEAD(2), 0}}, 10, 0},
+};
+
+PyGC_Head *_PyGC_generation0 = GEN_HEAD(0);
+
+static int enabled = 1; /* automatic collection enabled? */
+
+/* true if we are currently running the collector */
+static int collecting = 0;
+
+/* list of uncollectable objects */
+static PyObject *garbage = NULL;
+
+/* Python string to use if unhandled exception occurs */
+static PyObject *gc_str = NULL;
+
+/* Python string used to look for __del__ attribute. */
+static PyObject *delstr = NULL;
+
+/* set for debugging information */
+#define DEBUG_STATS (1<<0) /* print collection statistics */
+#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
+#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
+#define DEBUG_INSTANCES (1<<3) /* print instances */
+#define DEBUG_OBJECTS (1<<4) /* print other objects */
+#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
+#define DEBUG_LEAK DEBUG_COLLECTABLE | \
+ DEBUG_UNCOLLECTABLE | \
+ DEBUG_INSTANCES | \
+ DEBUG_OBJECTS | \
+ DEBUG_SAVEALL
+static int debug;
+static PyObject *tmod = NULL;
+
+/*--------------------------------------------------------------------------
+gc_refs values.
+
+Between collections, every gc'ed object has one of two gc_refs values:
+
+GC_UNTRACKED
+ The initial state; objects returned by PyObject_GC_Malloc are in this
+ state. The object doesn't live in any generation list, and its
+ tp_traverse slot must not be called.
+
+GC_REACHABLE
+ The object lives in some generation list, and its tp_traverse is safe to
+ call. An object transitions to GC_REACHABLE when PyObject_GC_Track
+ is called.
+
+During a collection, gc_refs can temporarily take on other states:
+
+>= 0
+ At the start of a collection, update_refs() copies the true refcount
+ to gc_refs, for each object in the generation being collected.
+ subtract_refs() then adjusts gc_refs so that it equals the number of
+ times an object is referenced directly from outside the generation
+ being collected.
+ gc_refs remains >= 0 throughout these steps.
+
+GC_TENTATIVELY_UNREACHABLE
+ move_unreachable() then moves objects not reachable (whether directly or
+ indirectly) from outside the generation into an "unreachable" set.
+ Objects that are found to be reachable have gc_refs set to GC_REACHABLE
+ again. Objects that are found to be unreachable have gc_refs set to
+ GC_TENTATIVELY_UNREACHABLE. It's "tentatively" because the pass doing
+ this can't be sure until it ends, and GC_TENTATIVELY_UNREACHABLE may
+ transition back to GC_REACHABLE.
+
+ Only objects with GC_TENTATIVELY_UNREACHABLE still set are candidates
+ for collection. If it's decided not to collect such an object (e.g.,
+ it has a __del__ method), its gc_refs is restored to GC_REACHABLE again.
+----------------------------------------------------------------------------
+*/
+#define GC_UNTRACKED _PyGC_REFS_UNTRACKED
+#define GC_REACHABLE _PyGC_REFS_REACHABLE
+#define GC_TENTATIVELY_UNREACHABLE _PyGC_REFS_TENTATIVELY_UNREACHABLE
+
+#define IS_TRACKED(o) ((AS_GC(o))->gc.gc_refs != GC_UNTRACKED)
+#define IS_REACHABLE(o) ((AS_GC(o))->gc.gc_refs == GC_REACHABLE)
+#define IS_TENTATIVELY_UNREACHABLE(o) ( \
+ (AS_GC(o))->gc.gc_refs == GC_TENTATIVELY_UNREACHABLE)
+
+/*** list functions ***/
+
+static void
+gc_list_init(PyGC_Head *list)
+{
+ list->gc.gc_prev = list;
+ list->gc.gc_next = list;
+}
+
+static int
+gc_list_is_empty(PyGC_Head *list)
+{
+ return (list->gc.gc_next == list);
+}
+
+#if 0
+/* This became unused after gc_list_move() was introduced. */
+/* Append `node` to `list`. */
+static void
+gc_list_append(PyGC_Head *node, PyGC_Head *list)
+{
+ node->gc.gc_next = list;
+ node->gc.gc_prev = list->gc.gc_prev;
+ node->gc.gc_prev->gc.gc_next = node;
+ list->gc.gc_prev = node;
+}
+#endif
+
+/* Remove `node` from the gc list it's currently in. */
+static void
+gc_list_remove(PyGC_Head *node)
+{
+ node->gc.gc_prev->gc.gc_next = node->gc.gc_next;
+ node->gc.gc_next->gc.gc_prev = node->gc.gc_prev;
+ node->gc.gc_next = NULL; /* object is not currently tracked */
+}
+
+/* Move `node` from the gc list it's currently in (which is not explicitly
+ * named here) to the end of `list`. This is semantically the same as
+ * gc_list_remove(node) followed by gc_list_append(node, list).
+ */
+static void
+gc_list_move(PyGC_Head *node, PyGC_Head *list)
+{
+ PyGC_Head *new_prev;
+ PyGC_Head *current_prev = node->gc.gc_prev;
+ PyGC_Head *current_next = node->gc.gc_next;
+ /* Unlink from current list. */
+ current_prev->gc.gc_next = current_next;
+ current_next->gc.gc_prev = current_prev;
+ /* Relink at end of new list. */
+ new_prev = node->gc.gc_prev = list->gc.gc_prev;
+ new_prev->gc.gc_next = list->gc.gc_prev = node;
+ node->gc.gc_next = list;
+}
+
+/* append list `from` onto list `to`; `from` becomes an empty list */
+static void
+gc_list_merge(PyGC_Head *from, PyGC_Head *to)
+{
+ PyGC_Head *tail;
+ assert(from != to);
+ if (!gc_list_is_empty(from)) {
+ tail = to->gc.gc_prev;
+ tail->gc.gc_next = from->gc.gc_next;
+ tail->gc.gc_next->gc.gc_prev = tail;
+ to->gc.gc_prev = from->gc.gc_prev;
+ to->gc.gc_prev->gc.gc_next = to;
+ }
+ gc_list_init(from);
+}
+
+static Py_ssize_t
+gc_list_size(PyGC_Head *list)
+{
+ PyGC_Head *gc;
+ Py_ssize_t n = 0;
+ for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
+ n++;
+ }
+ return n;
+}
+
+/* Append objects in a GC list to a Python list.
+ * Return 0 if all OK, < 0 if error (out of memory for list).
+ */
+static int
+append_objects(PyObject *py_list, PyGC_Head *gc_list)
+{
+ PyGC_Head *gc;
+ for (gc = gc_list->gc.gc_next; gc != gc_list; gc = gc->gc.gc_next) {
+ PyObject *op = FROM_GC(gc);
+ if (op != py_list) {
+ if (PyList_Append(py_list, op)) {
+ return -1; /* exception */
+ }
+ }
+ }
+ return 0;
+}
+
+/*** end of list stuff ***/
+
+
+/* Set all gc_refs = ob_refcnt. After this, gc_refs is > 0 for all objects
+ * in containers, and is GC_REACHABLE for all tracked gc objects not in
+ * containers.
+ */
+static void
+update_refs(PyGC_Head *containers)
+{
+ PyGC_Head *gc = containers->gc.gc_next;
+ for (; gc != containers; gc = gc->gc.gc_next) {
+ assert(gc->gc.gc_refs == GC_REACHABLE);
+ gc->gc.gc_refs = FROM_GC(gc)->ob_refcnt;
+ /* Python's cyclic gc should never see an incoming refcount
+ * of 0: if something decref'ed to 0, it should have been
+ * deallocated immediately at that time.
+ * Possible cause (if the assert triggers): a tp_dealloc
+ * routine left a gc-aware object tracked during its teardown
+ * phase, and did something-- or allowed something to happen --
+ * that called back into Python. gc can trigger then, and may
+ * see the still-tracked dying object. Before this assert
+ * was added, such mistakes went on to allow gc to try to
+ * delete the object again. In a debug build, that caused
+ * a mysterious segfault, when _Py_ForgetReference tried
+ * to remove the object from the doubly-linked list of all
+ * objects a second time. In a release build, an actual
+ * double deallocation occurred, which leads to corruption
+ * of the allocator's internal bookkeeping pointers. That's
+ * so serious that maybe this should be a release-build
+ * check instead of an assert?
+ */
+ assert(gc->gc.gc_refs != 0);
+ }
+}
+
+/* A traversal callback for subtract_refs. */
+static int
+visit_decref(PyObject *op, void *data)
+{
+ assert(op != NULL);
+ if (PyObject_IS_GC(op)) {
+ PyGC_Head *gc = AS_GC(op);
+ /* We're only interested in gc_refs for objects in the
+ * generation being collected, which can be recognized
+ * because only they have positive gc_refs.
+ */
+ assert(gc->gc.gc_refs != 0); /* else refcount was too small */
+ if (gc->gc.gc_refs > 0)
+ gc->gc.gc_refs--;
+ }
+ return 0;
+}
+
+/* Subtract internal references from gc_refs. After this, gc_refs is >= 0
+ * for all objects in containers, and is GC_REACHABLE for all tracked gc
+ * objects not in containers. The ones with gc_refs > 0 are directly
+ * reachable from outside containers, and so can't be collected.
+ */
+static void
+subtract_refs(PyGC_Head *containers)
+{
+ traverseproc traverse;
+ PyGC_Head *gc = containers->gc.gc_next;
+ for (; gc != containers; gc=gc->gc.gc_next) {
+ traverse = FROM_GC(gc)->ob_type->tp_traverse;
+ (void) traverse(FROM_GC(gc),
+ (visitproc)visit_decref,
+ NULL);
+ }
+}
+
+/* A traversal callback for move_unreachable. */
+static int
+visit_reachable(PyObject *op, PyGC_Head *reachable)
+{
+ if (PyObject_IS_GC(op)) {
+ PyGC_Head *gc = AS_GC(op);
+ const Py_ssize_t gc_refs = gc->gc.gc_refs;
+
+ if (gc_refs == 0) {
+ /* This is in move_unreachable's 'young' list, but
+ * the traversal hasn't yet gotten to it. All
+ * we need to do is tell move_unreachable that it's
+ * reachable.
+ */
+ gc->gc.gc_refs = 1;
+ }
+ else if (gc_refs == GC_TENTATIVELY_UNREACHABLE) {
+ /* This had gc_refs = 0 when move_unreachable got
+ * to it, but turns out it's reachable after all.
+ * Move it back to move_unreachable's 'young' list,
+ * and move_unreachable will eventually get to it
+ * again.
+ */
+ gc_list_move(gc, reachable);
+ gc->gc.gc_refs = 1;
+ }
+ /* Else there's nothing to do.
+ * If gc_refs > 0, it must be in move_unreachable's 'young'
+ * list, and move_unreachable will eventually get to it.
+ * If gc_refs == GC_REACHABLE, it's either in some other
+ * generation so we don't care about it, or move_unreachable
+ * already dealt with it.
+ * If gc_refs == GC_UNTRACKED, it must be ignored.
+ */
+ else {
+ assert(gc_refs > 0
+ || gc_refs == GC_REACHABLE
+ || gc_refs == GC_UNTRACKED);
+ }
+ }
+ return 0;
+}
+
+/* Move the unreachable objects from young to unreachable. After this,
+ * all objects in young have gc_refs = GC_REACHABLE, and all objects in
+ * unreachable have gc_refs = GC_TENTATIVELY_UNREACHABLE. All tracked
+ * gc objects not in young or unreachable still have gc_refs = GC_REACHABLE.
+ * All objects in young after this are directly or indirectly reachable
+ * from outside the original young; and all objects in unreachable are
+ * not.
+ */
+static void
+move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
+{
+ PyGC_Head *gc = young->gc.gc_next;
+
+ /* Invariants: all objects "to the left" of us in young have gc_refs
+ * = GC_REACHABLE, and are indeed reachable (directly or indirectly)
+ * from outside the young list as it was at entry. All other objects
+ * from the original young "to the left" of us are in unreachable now,
+ * and have gc_refs = GC_TENTATIVELY_UNREACHABLE. All objects to the
+ * left of us in 'young' now have been scanned, and no objects here
+ * or to the right have been scanned yet.
+ */
+
+ while (gc != young) {
+ PyGC_Head *next;
+
+ if (gc->gc.gc_refs) {
+ /* gc is definitely reachable from outside the
+ * original 'young'. Mark it as such, and traverse
+ * its pointers to find any other objects that may
+ * be directly reachable from it. Note that the
+ * call to tp_traverse may append objects to young,
+ * so we have to wait until it returns to determine
+ * the next object to visit.
+ */
+ PyObject *op = FROM_GC(gc);
+ traverseproc traverse = op->ob_type->tp_traverse;
+ assert(gc->gc.gc_refs > 0);
+ gc->gc.gc_refs = GC_REACHABLE;
+ (void) traverse(op,
+ (visitproc)visit_reachable,
+ (void *)young);
+ next = gc->gc.gc_next;
+ }
+ else {
+ /* This *may* be unreachable. To make progress,
+ * assume it is. gc isn't directly reachable from
+ * any object we've already traversed, but may be
+ * reachable from an object we haven't gotten to yet.
+ * visit_reachable will eventually move gc back into
+ * young if that's so, and we'll see it again.
+ */
+ next = gc->gc.gc_next;
+ gc_list_move(gc, unreachable);
+ gc->gc.gc_refs = GC_TENTATIVELY_UNREACHABLE;
+ }
+ gc = next;
+ }
+}
+
+/* Return true if object has a finalization method.
+ * CAUTION: An instance of an old-style class has to be checked for a
+ *__del__ method, and earlier versions of this used to call PyObject_HasAttr,
+ * which in turn could call the class's __getattr__ hook (if any). That
+ * could invoke arbitrary Python code, mutating the object graph in arbitrary
+ * ways, and that was the source of some excruciatingly subtle bugs.
+ */
+static int
+has_finalizer(PyObject *op)
+{
+ if (PyInstance_Check(op)) {
+ assert(delstr != NULL);
+ return _PyInstance_Lookup(op, delstr) != NULL;
+ }
+ else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
+ return op->ob_type->tp_del != NULL;
+ else if (PyGen_CheckExact(op))
+ return PyGen_NeedsFinalizing((PyGenObject *)op);
+ else
+ return 0;
+}
+
+/* Move the objects in unreachable with __del__ methods into `finalizers`.
+ * Objects moved into `finalizers` have gc_refs set to GC_REACHABLE; the
+ * objects remaining in unreachable are left at GC_TENTATIVELY_UNREACHABLE.
+ */
+static void
+move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
+{
+ PyGC_Head *gc;
+ PyGC_Head *next;
+
+ /* March over unreachable. Move objects with finalizers into
+ * `finalizers`.
+ */
+ for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) {
+ PyObject *op = FROM_GC(gc);
+
+ assert(IS_TENTATIVELY_UNREACHABLE(op));
+ next = gc->gc.gc_next;
+
+ if (has_finalizer(op)) {
+ gc_list_move(gc, finalizers);
+ gc->gc.gc_refs = GC_REACHABLE;
+ }
+ }
+}
+
+/* A traversal callback for move_finalizer_reachable. */
+static int
+visit_move(PyObject *op, PyGC_Head *tolist)
+{
+ if (PyObject_IS_GC(op)) {
+ if (IS_TENTATIVELY_UNREACHABLE(op)) {
+ PyGC_Head *gc = AS_GC(op);
+ gc_list_move(gc, tolist);
+ gc->gc.gc_refs = GC_REACHABLE;
+ }
+ }
+ return 0;
+}
+
+/* Move objects that are reachable from finalizers, from the unreachable set
+ * into finalizers set.
+ */
+static void
+move_finalizer_reachable(PyGC_Head *finalizers)
+{
+ traverseproc traverse;
+ PyGC_Head *gc = finalizers->gc.gc_next;
+ for (; gc != finalizers; gc = gc->gc.gc_next) {
+ /* Note that the finalizers list may grow during this. */
+ traverse = FROM_GC(gc)->ob_type->tp_traverse;
+ (void) traverse(FROM_GC(gc),
+ (visitproc)visit_move,
+ (void *)finalizers);
+ }
+}
+
+/* Clear all weakrefs to unreachable objects, and if such a weakref has a
+ * callback, invoke it if necessary. Note that it's possible for such
+ * weakrefs to be outside the unreachable set -- indeed, those are precisely
+ * the weakrefs whose callbacks must be invoked. See gc_weakref.txt for
+ * overview & some details. Some weakrefs with callbacks may be reclaimed
+ * directly by this routine; the number reclaimed is the return value. Other
+ * weakrefs with callbacks may be moved into the `old` generation. Objects
+ * moved into `old` have gc_refs set to GC_REACHABLE; the objects remaining in
+ * unreachable are left at GC_TENTATIVELY_UNREACHABLE. When this returns,
+ * no object in `unreachable` is weakly referenced anymore.
+ */
+static int
+handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
+{
+ PyGC_Head *gc;
+ PyObject *op; /* generally FROM_GC(gc) */
+ PyWeakReference *wr; /* generally a cast of op */
+ PyGC_Head wrcb_to_call; /* weakrefs with callbacks to call */
+ PyGC_Head *next;
+ int num_freed = 0;
+
+ gc_list_init(&wrcb_to_call);
+
+ /* Clear all weakrefs to the objects in unreachable. If such a weakref
+ * also has a callback, move it into `wrcb_to_call` if the callback
+ * needs to be invoked. Note that we cannot invoke any callbacks until
+ * all weakrefs to unreachable objects are cleared, lest the callback
+ * resurrect an unreachable object via a still-active weakref. We
+ * make another pass over wrcb_to_call, invoking callbacks, after this
+ * pass completes.
+ */
+ for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) {
+ PyWeakReference **wrlist;
+
+ op = FROM_GC(gc);
+ assert(IS_TENTATIVELY_UNREACHABLE(op));
+ next = gc->gc.gc_next;
+
+ if (! PyType_SUPPORTS_WEAKREFS(op->ob_type))
+ continue;
+
+ /* It supports weakrefs. Does it have any? */
+ wrlist = (PyWeakReference **)
+ PyObject_GET_WEAKREFS_LISTPTR(op);
+
+ /* `op` may have some weakrefs. March over the list, clear
+ * all the weakrefs, and move the weakrefs with callbacks
+ * that must be called into wrcb_to_call.
+ */
+ for (wr = *wrlist; wr != NULL; wr = *wrlist) {
+ PyGC_Head *wrasgc; /* AS_GC(wr) */
+
+ /* _PyWeakref_ClearRef clears the weakref but leaves
+ * the callback pointer intact. Obscure: it also
+ * changes *wrlist.
+ */
+ assert(wr->wr_object == op);
+ _PyWeakref_ClearRef(wr);
+ assert(wr->wr_object == Py_None);
+ if (wr->wr_callback == NULL)
+ continue; /* no callback */
+
+ /* Headache time. `op` is going away, and is weakly referenced by
+ * `wr`, which has a callback. Should the callback be invoked? If wr
+ * is also trash, no:
+ *
+ * 1. There's no need to call it. The object and the weakref are
+ * both going away, so it's legitimate to pretend the weakref is
+ * going away first. The user has to ensure a weakref outlives its
+ * referent if they want a guarantee that the wr callback will get
+ * invoked.
+ *
+ * 2. It may be catastrophic to call it. If the callback is also in
+ * cyclic trash (CT), then although the CT is unreachable from
+ * outside the current generation, CT may be reachable from the
+ * callback. Then the callback could resurrect insane objects.
+ *
+ * Since the callback is never needed and may be unsafe in this case,
+ * wr is simply left in the unreachable set. Note that because we
+ * already called _PyWeakref_ClearRef(wr), its callback will never
+ * trigger.
+ *
+ * OTOH, if wr isn't part of CT, we should invoke the callback: the
+ * weakref outlived the trash. Note that since wr isn't CT in this
+ * case, its callback can't be CT either -- wr acted as an external
+ * root to this generation, and therefore its callback did too. So
+ * nothing in CT is reachable from the callback either, so it's hard
+ * to imagine how calling it later could create a problem for us. wr
+ * is moved to wrcb_to_call in this case.
+ */
+ if (IS_TENTATIVELY_UNREACHABLE(wr))
+ continue;
+ assert(IS_REACHABLE(wr));
+
+ /* Create a new reference so that wr can't go away
+ * before we can process it again.
+ */
+ Py_INCREF(wr);
+
+ /* Move wr to wrcb_to_call, for the next pass. */
+ wrasgc = AS_GC(wr);
+ assert(wrasgc != next); /* wrasgc is reachable, but
+ next isn't, so they can't
+ be the same */
+ gc_list_move(wrasgc, &wrcb_to_call);
+ }
+ }
+
+ /* Invoke the callbacks we decided to honor. It's safe to invoke them
+ * because they can't reference unreachable objects.
+ */
+ while (! gc_list_is_empty(&wrcb_to_call)) {
+ PyObject *temp;
+ PyObject *callback;
+
+ gc = wrcb_to_call.gc.gc_next;
+ op = FROM_GC(gc);
+ assert(IS_REACHABLE(op));
+ assert(PyWeakref_Check(op));
+ wr = (PyWeakReference *)op;
+ callback = wr->wr_callback;
+ assert(callback != NULL);
+
+ /* copy-paste of weakrefobject.c's handle_callback() */
+ temp = PyObject_CallFunctionObjArgs(callback, wr, NULL);
+ if (temp == NULL)
+ PyErr_WriteUnraisable(callback);
+ else
+ Py_DECREF(temp);
+
+ /* Give up the reference we created in the first pass. When
+ * op's refcount hits 0 (which it may or may not do right now),
+ * op's tp_dealloc will decref op->wr_callback too. Note
+ * that the refcount probably will hit 0 now, and because this
+ * weakref was reachable to begin with, gc didn't already
+ * add it to its count of freed objects. Example: a reachable
+ * weak value dict maps some key to this reachable weakref.
+ * The callback removes this key->weakref mapping from the
+ * dict, leaving no other references to the weakref (excepting
+ * ours).
+ */
+ Py_DECREF(op);
+ if (wrcb_to_call.gc.gc_next == gc) {
+ /* object is still alive -- move it */
+ gc_list_move(gc, old);
+ }
+ else
+ ++num_freed;
+ }
+
+ return num_freed;
+}
+
+static void
+debug_instance(char *msg, PyInstanceObject *inst)
+{
+ char *cname;
+ /* simple version of instance_repr */
+ PyObject *classname = inst->in_class->cl_name;
+ if (classname != NULL && PyString_Check(classname))
+ cname = PyString_AsString(classname);
+ else
+ cname = "?";
+ PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
+ msg, cname, inst);
+}
+
+static void
+debug_cycle(char *msg, PyObject *op)
+{
+ if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
+ debug_instance(msg, (PyInstanceObject *)op);
+ }
+ else if (debug & DEBUG_OBJECTS) {
+ PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
+ msg, op->ob_type->tp_name, op);
+ }
+}
+
+/* Handle uncollectable garbage (cycles with finalizers, and stuff reachable
+ * only from such cycles).
+ * If DEBUG_SAVEALL, all objects in finalizers are appended to the module
+ * garbage list (a Python list), else only the objects in finalizers with
+ * __del__ methods are appended to garbage. All objects in finalizers are
+ * merged into the old list regardless.
+ * Returns 0 if all OK, <0 on error (out of memory to grow the garbage list).
+ * The finalizers list is made empty on a successful return.
+ */
+static int
+handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
+{
+ PyGC_Head *gc = finalizers->gc.gc_next;
+
+ if (garbage == NULL) {
+ garbage = PyList_New(0);
+ if (garbage == NULL)
+ Py_FatalError("gc couldn't create gc.garbage list");
+ }
+ for (; gc != finalizers; gc = gc->gc.gc_next) {
+ PyObject *op = FROM_GC(gc);
+
+ if ((debug & DEBUG_SAVEALL) || has_finalizer(op)) {
+ if (PyList_Append(garbage, op) < 0)
+ return -1;
+ }
+ }
+
+ gc_list_merge(finalizers, old);
+ return 0;
+}
+
+/* Break reference cycles by clearing the containers involved. This is
+ * tricky business as the lists can be changing and we don't know which
+ * objects may be freed. It is possible I screwed something up here.
+ */
+static void
+delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
+{
+ inquiry clear;
+
+ while (!gc_list_is_empty(collectable)) {
+ PyGC_Head *gc = collectable->gc.gc_next;
+ PyObject *op = FROM_GC(gc);
+
+ assert(IS_TENTATIVELY_UNREACHABLE(op));
+ if (debug & DEBUG_SAVEALL) {
+ PyList_Append(garbage, op);
+ }
+ else {
+ if ((clear = op->ob_type->tp_clear) != NULL) {
+ Py_INCREF(op);
+ clear(op);
+ Py_DECREF(op);
+ }
+ }
+ if (collectable->gc.gc_next == gc) {
+ /* object is still alive, move it, it may die later */
+ gc_list_move(gc, old);
+ gc->gc.gc_refs = GC_REACHABLE;
+ }
+ }
+}
+
+/* This is the main function. Read this to understand how the
+ * collection process works. */
+static Py_ssize_t
+collect(int generation)
+{
+ int i;
+ Py_ssize_t m = 0; /* # objects collected */
+ Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */
+ PyGC_Head *young; /* the generation we are examining */
+ PyGC_Head *old; /* next older generation */
+ PyGC_Head unreachable; /* non-problematic unreachable trash */
+ PyGC_Head finalizers; /* objects with, & reachable from, __del__ */
+ PyGC_Head *gc;
+ double t1 = 0.0;
+
+ if (delstr == NULL) {
+ delstr = PyString_InternFromString("__del__");
+ if (delstr == NULL)
+ Py_FatalError("gc couldn't allocate \"__del__\"");
+ }
+
+ if (debug & DEBUG_STATS) {
+ if (tmod != NULL) {
+ PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
+ if (f == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ t1 = PyFloat_AsDouble(f);
+ Py_DECREF(f);
+ }
+ }
+ PySys_WriteStderr("gc: collecting generation %d...\n",
+ generation);
+ PySys_WriteStderr("gc: objects in each generation:");
+ for (i = 0; i < NUM_GENERATIONS; i++)
+ PySys_WriteStderr(" %" PY_FORMAT_SIZE_T "d",
+ gc_list_size(GEN_HEAD(i)));
+ PySys_WriteStderr("\n");
+ }
+
+ /* update collection and allocation counters */
+ if (generation+1 < NUM_GENERATIONS)
+ generations[generation+1].count += 1;
+ for (i = 0; i <= generation; i++)
+ generations[i].count = 0;
+
+ /* merge younger generations with one we are currently collecting */
+ for (i = 0; i < generation; i++) {
+ gc_list_merge(GEN_HEAD(i), GEN_HEAD(generation));
+ }
+
+ /* handy references */
+ young = GEN_HEAD(generation);
+ if (generation < NUM_GENERATIONS-1)
+ old = GEN_HEAD(generation+1);
+ else
+ old = young;
+
+ /* Using ob_refcnt and gc_refs, calculate which objects in the
+ * container set are reachable from outside the set (i.e., have a
+ * refcount greater than 0 when all the references within the
+ * set are taken into account).
+ */
+ update_refs(young);
+ subtract_refs(young);
+
+ /* Leave everything reachable from outside young in young, and move
+ * everything else (in young) to unreachable.
+ * NOTE: This used to move the reachable objects into a reachable
+ * set instead. But most things usually turn out to be reachable,
+ * so it's more efficient to move the unreachable things.
+ */
+ gc_list_init(&unreachable);
+ move_unreachable(young, &unreachable);
+
+ /* Move reachable objects to next generation. */
+ if (young != old)
+ gc_list_merge(young, old);
+
+ /* All objects in unreachable are trash, but objects reachable from
+ * finalizers can't safely be deleted. Python programmers should take
+ * care not to create such things. For Python, finalizers means
+ * instance objects with __del__ methods. Weakrefs with callbacks
+ * can also call arbitrary Python code but they will be dealt with by
+ * handle_weakrefs().
+ */
+ gc_list_init(&finalizers);
+ move_finalizers(&unreachable, &finalizers);
+ /* finalizers contains the unreachable objects with a finalizer;
+ * unreachable objects reachable *from* those are also uncollectable,
+ * and we move those into the finalizers list too.
+ */
+ move_finalizer_reachable(&finalizers);
+
+ /* Collect statistics on collectable objects found and print
+ * debugging information.
+ */
+ for (gc = unreachable.gc.gc_next; gc != &unreachable;
+ gc = gc->gc.gc_next) {
+ m++;
+ if (debug & DEBUG_COLLECTABLE) {
+ debug_cycle("collectable", FROM_GC(gc));
+ }
+ if (tmod != NULL && (debug & DEBUG_STATS)) {
+ PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
+ if (f == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ t1 = PyFloat_AsDouble(f)-t1;
+ Py_DECREF(f);
+ PySys_WriteStderr("gc: %.4fs elapsed.\n", t1);
+ }
+ }
+ }
+
+ /* Clear weakrefs and invoke callbacks as necessary. */
+ m += handle_weakrefs(&unreachable, old);
+
+ /* Call tp_clear on objects in the unreachable set. This will cause
+ * the reference cycles to be broken. It may also cause some objects
+ * in finalizers to be freed.
+ */
+ delete_garbage(&unreachable, old);
+
+ /* Collect statistics on uncollectable objects found and print
+ * debugging information. */
+ for (gc = finalizers.gc.gc_next;
+ gc != &finalizers;
+ gc = gc->gc.gc_next) {
+ n++;
+ if (debug & DEBUG_UNCOLLECTABLE)
+ debug_cycle("uncollectable", FROM_GC(gc));
+ }
+ if (debug & DEBUG_STATS) {
+ if (m == 0 && n == 0)
+ PySys_WriteStderr("gc: done.\n");
+ else
+ PySys_WriteStderr(
+ "gc: done, "
+ "%" PY_FORMAT_SIZE_T "d unreachable, "
+ "%" PY_FORMAT_SIZE_T "d uncollectable.\n",
+ n+m, n);
+ }
+
+ /* Append instances in the uncollectable set to a Python
+ * reachable list of garbage. The programmer has to deal with
+ * this if they insist on creating this type of structure.
+ */
+ (void)handle_finalizers(&finalizers, old);
+
+ if (PyErr_Occurred()) {
+ if (gc_str == NULL)
+ gc_str = PyString_FromString("garbage collection");
+ PyErr_WriteUnraisable(gc_str);
+ Py_FatalError("unexpected exception during garbage collection");
+ }
+ return n+m;
+}
+
+static Py_ssize_t
+collect_generations(void)
+{
+ int i;
+ Py_ssize_t n = 0;
+
+ /* Find the oldest generation (higest numbered) where the count
+ * exceeds the threshold. Objects in the that generation and
+ * generations younger than it will be collected. */
+ for (i = NUM_GENERATIONS-1; i >= 0; i--) {
+ if (generations[i].count > generations[i].threshold) {
+ n = collect(i);
+ break;
+ }
+ }
+ return n;
+}
+
+PyDoc_STRVAR(gc_enable__doc__,
+"enable() -> None\n"
+"\n"
+"Enable automatic garbage collection.\n");
+
+static PyObject *
+gc_enable(PyObject *self, PyObject *noargs)
+{
+ enabled = 1;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(gc_disable__doc__,
+"disable() -> None\n"
+"\n"
+"Disable automatic garbage collection.\n");
+
+static PyObject *
+gc_disable(PyObject *self, PyObject *noargs)
+{
+ enabled = 0;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(gc_isenabled__doc__,
+"isenabled() -> status\n"
+"\n"
+"Returns true if automatic garbage collection is enabled.\n");
+
+static PyObject *
+gc_isenabled(PyObject *self, PyObject *noargs)
+{
+ return PyBool_FromLong((long)enabled);
+}
+
+PyDoc_STRVAR(gc_collect__doc__,
+"collect([generation]) -> n\n"
+"\n"
+"With no arguments, run a full collection. The optional argument\n"
+"may be an integer specifying which generation to collect. A ValueError\n"
+"is raised if the generation number is invalid.\n\n"
+"The number of unreachable objects is returned.\n");
+
+static PyObject *
+gc_collect(PyObject *self, PyObject *args, PyObject *kws)
+{
+ static char *keywords[] = {"generation", NULL};
+ int genarg = NUM_GENERATIONS - 1;
+ Py_ssize_t n;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kws, "|i", keywords, &genarg))
+ return NULL;
+
+ else if (genarg < 0 || genarg >= NUM_GENERATIONS) {
+ PyErr_SetString(PyExc_ValueError, "invalid generation");
+ return NULL;
+ }
+
+ if (collecting)
+ n = 0; /* already collecting, don't do anything */
+ else {
+ collecting = 1;
+ n = collect(genarg);
+ collecting = 0;
+ }
+
+ return PyInt_FromSsize_t(n);
+}
+
+PyDoc_STRVAR(gc_set_debug__doc__,
+"set_debug(flags) -> None\n"
+"\n"
+"Set the garbage collection debugging flags. Debugging information is\n"
+"written to sys.stderr.\n"
+"\n"
+"flags is an integer and can have the following bits turned on:\n"
+"\n"
+" DEBUG_STATS - Print statistics during collection.\n"
+" DEBUG_COLLECTABLE - Print collectable objects found.\n"
+" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n"
+" DEBUG_INSTANCES - Print instance objects.\n"
+" DEBUG_OBJECTS - Print objects other than instances.\n"
+" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
+" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n");
+
+static PyObject *
+gc_set_debug(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, "i:set_debug", &debug))
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(gc_get_debug__doc__,
+"get_debug() -> flags\n"
+"\n"
+"Get the garbage collection debugging flags.\n");
+
+static PyObject *
+gc_get_debug(PyObject *self, PyObject *noargs)
+{
+ return Py_BuildValue("i", debug);
+}
+
+PyDoc_STRVAR(gc_set_thresh__doc__,
+"set_threshold(threshold0, [threshold1, threshold2]) -> None\n"
+"\n"
+"Sets the collection thresholds. Setting threshold0 to zero disables\n"
+"collection.\n");
+
+static PyObject *
+gc_set_thresh(PyObject *self, PyObject *args)
+{
+ int i;
+ if (!PyArg_ParseTuple(args, "i|ii:set_threshold",
+ &generations[0].threshold,
+ &generations[1].threshold,
+ &generations[2].threshold))
+ return NULL;
+ for (i = 2; i < NUM_GENERATIONS; i++) {
+ /* generations higher than 2 get the same threshold */
+ generations[i].threshold = generations[2].threshold;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(gc_get_thresh__doc__,
+"get_threshold() -> (threshold0, threshold1, threshold2)\n"
+"\n"
+"Return the current collection thresholds\n");
+
+static PyObject *
+gc_get_thresh(PyObject *self, PyObject *noargs)
+{
+ return Py_BuildValue("(iii)",
+ generations[0].threshold,
+ generations[1].threshold,
+ generations[2].threshold);
+}
+
+PyDoc_STRVAR(gc_get_count__doc__,
+"get_count() -> (count0, count1, count2)\n"
+"\n"
+"Return the current collection counts\n");
+
+static PyObject *
+gc_get_count(PyObject *self, PyObject *noargs)
+{
+ return Py_BuildValue("(iii)",
+ generations[0].count,
+ generations[1].count,
+ generations[2].count);
+}
+
+static int
+referrersvisit(PyObject* obj, PyObject *objs)
+{
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(objs); i++)
+ if (PyTuple_GET_ITEM(objs, i) == obj)
+ return 1;
+ return 0;
+}
+
+static int
+gc_referrers_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist)
+{
+ PyGC_Head *gc;
+ PyObject *obj;
+ traverseproc traverse;
+ for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
+ obj = FROM_GC(gc);
+ traverse = obj->ob_type->tp_traverse;
+ if (obj == objs || obj == resultlist)
+ continue;
+ if (traverse(obj, (visitproc)referrersvisit, objs)) {
+ if (PyList_Append(resultlist, obj) < 0)
+ return 0; /* error */
+ }
+ }
+ return 1; /* no error */
+}
+
+PyDoc_STRVAR(gc_get_referrers__doc__,
+"get_referrers(*objs) -> list\n\
+Return the list of objects that directly refer to any of objs.");
+
+static PyObject *
+gc_get_referrers(PyObject *self, PyObject *args)
+{
+ int i;
+ PyObject *result = PyList_New(0);
+ if (!result) return NULL;
+
+ for (i = 0; i < NUM_GENERATIONS; i++) {
+ if (!(gc_referrers_for(args, GEN_HEAD(i), result))) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+/* Append obj to list; return true if error (out of memory), false if OK. */
+static int
+referentsvisit(PyObject *obj, PyObject *list)
+{
+ return PyList_Append(list, obj) < 0;
+}
+
+PyDoc_STRVAR(gc_get_referents__doc__,
+"get_referents(*objs) -> list\n\
+Return the list of objects that are directly referred to by objs.");
+
+static PyObject *
+gc_get_referents(PyObject *self, PyObject *args)
+{
+ Py_ssize_t i;
+ PyObject *result = PyList_New(0);
+
+ if (result == NULL)
+ return NULL;
+
+ for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
+ traverseproc traverse;
+ PyObject *obj = PyTuple_GET_ITEM(args, i);
+
+ if (! PyObject_IS_GC(obj))
+ continue;
+ traverse = obj->ob_type->tp_traverse;
+ if (! traverse)
+ continue;
+ if (traverse(obj, (visitproc)referentsvisit, result)) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+PyDoc_STRVAR(gc_get_objects__doc__,
+"get_objects() -> [...]\n"
+"\n"
+"Return a list of objects tracked by the collector (excluding the list\n"
+"returned).\n");
+
+static PyObject *
+gc_get_objects(PyObject *self, PyObject *noargs)
+{
+ int i;
+ PyObject* result;
+
+ result = PyList_New(0);
+ if (result == NULL)
+ return NULL;
+ for (i = 0; i < NUM_GENERATIONS; i++) {
+ if (append_objects(result, GEN_HEAD(i))) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+
+PyDoc_STRVAR(gc__doc__,
+"This module provides access to the garbage collector for reference cycles.\n"
+"\n"
+"enable() -- Enable automatic garbage collection.\n"
+"disable() -- Disable automatic garbage collection.\n"
+"isenabled() -- Returns true if automatic collection is enabled.\n"
+"collect() -- Do a full collection right now.\n"
+"get_count() -- Return the current collection counts.\n"
+"set_debug() -- Set debugging flags.\n"
+"get_debug() -- Get debugging flags.\n"
+"set_threshold() -- Set the collection thresholds.\n"
+"get_threshold() -- Return the current the collection thresholds.\n"
+"get_objects() -- Return a list of all objects tracked by the collector.\n"
+"get_referrers() -- Return the list of objects that refer to an object.\n"
+"get_referents() -- Return the list of objects that an object refers to.\n");
+
+static PyMethodDef GcMethods[] = {
+ {"enable", gc_enable, METH_NOARGS, gc_enable__doc__},
+ {"disable", gc_disable, METH_NOARGS, gc_disable__doc__},
+ {"isenabled", gc_isenabled, METH_NOARGS, gc_isenabled__doc__},
+ {"set_debug", gc_set_debug, METH_VARARGS, gc_set_debug__doc__},
+ {"get_debug", gc_get_debug, METH_NOARGS, gc_get_debug__doc__},
+ {"get_count", gc_get_count, METH_NOARGS, gc_get_count__doc__},
+ {"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__},
+ {"get_threshold", gc_get_thresh, METH_NOARGS, gc_get_thresh__doc__},
+ {"collect", (PyCFunction)gc_collect,
+ METH_VARARGS | METH_KEYWORDS, gc_collect__doc__},
+ {"get_objects", gc_get_objects,METH_NOARGS, gc_get_objects__doc__},
+ {"get_referrers", gc_get_referrers, METH_VARARGS,
+ gc_get_referrers__doc__},
+ {"get_referents", gc_get_referents, METH_VARARGS,
+ gc_get_referents__doc__},
+ {NULL, NULL} /* Sentinel */
+};
+
+PyMODINIT_FUNC
+initgc(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule4("gc",
+ GcMethods,
+ gc__doc__,
+ NULL,
+ PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ if (garbage == NULL) {
+ garbage = PyList_New(0);
+ if (garbage == NULL)
+ return;
+ }
+ Py_INCREF(garbage);
+ if (PyModule_AddObject(m, "garbage", garbage) < 0)
+ return;
+
+ /* Importing can't be done in collect() because collect()
+ * can be called via PyGC_Collect() in Py_Finalize().
+ * This wouldn't be a problem, except that <initialized> is
+ * reset to 0 before calling collect which trips up
+ * the import and triggers an assertion.
+ */
+ if (tmod == NULL) {
+ tmod = PyImport_ImportModule("time");
+ if (tmod == NULL)
+ PyErr_Clear();
+ }
+
+#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return
+ ADD_INT(DEBUG_STATS);
+ ADD_INT(DEBUG_COLLECTABLE);
+ ADD_INT(DEBUG_UNCOLLECTABLE);
+ ADD_INT(DEBUG_INSTANCES);
+ ADD_INT(DEBUG_OBJECTS);
+ ADD_INT(DEBUG_SAVEALL);
+ ADD_INT(DEBUG_LEAK);
+#undef ADD_INT
+}
+
+/* API to invoke gc.collect() from C */
+Py_ssize_t
+PyGC_Collect(void)
+{
+ Py_ssize_t n;
+
+ if (collecting)
+ n = 0; /* already collecting, don't do anything */
+ else {
+ collecting = 1;
+ n = collect(NUM_GENERATIONS - 1);
+ collecting = 0;
+ }
+
+ return n;
+}
+
+/* for debugging */
+void
+_PyGC_Dump(PyGC_Head *g)
+{
+ _PyObject_Dump(FROM_GC(g));
+}
+
+/* extension modules might be compiled with GC support so these
+ functions must always be available */
+
+#undef PyObject_GC_Track
+#undef PyObject_GC_UnTrack
+#undef PyObject_GC_Del
+#undef _PyObject_GC_Malloc
+
+void
+PyObject_GC_Track(void *op)
+{
+ _PyObject_GC_TRACK(op);
+}
+
+/* for binary compatibility with 2.2 */
+void
+_PyObject_GC_Track(PyObject *op)
+{
+ PyObject_GC_Track(op);
+}
+
+void
+PyObject_GC_UnTrack(void *op)
+{
+ /* Obscure: the Py_TRASHCAN mechanism requires that we be able to
+ * call PyObject_GC_UnTrack twice on an object.
+ */
+ if (IS_TRACKED(op))
+ _PyObject_GC_UNTRACK(op);
+}
+
+/* for binary compatibility with 2.2 */
+void
+_PyObject_GC_UnTrack(PyObject *op)
+{
+ PyObject_GC_UnTrack(op);
+}
+
+PyObject *
+_PyObject_GC_Malloc(size_t basicsize)
+{
+ PyObject *op;
+ PyGC_Head *g = (PyGC_Head *)PyObject_MALLOC(
+ sizeof(PyGC_Head) + basicsize);
+ if (g == NULL)
+ return PyErr_NoMemory();
+ g->gc.gc_refs = GC_UNTRACKED;
+ generations[0].count++; /* number of allocated GC objects */
+ if (generations[0].count > generations[0].threshold &&
+ enabled &&
+ generations[0].threshold &&
+ !collecting &&
+ !PyErr_Occurred()) {
+ collecting = 1;
+ collect_generations();
+ collecting = 0;
+ }
+ op = FROM_GC(g);
+ return op;
+}
+
+PyObject *
+_PyObject_GC_New(PyTypeObject *tp)
+{
+ PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp));
+ if (op != NULL)
+ op = PyObject_INIT(op, tp);
+ return op;
+}
+
+PyVarObject *
+_PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
+{
+ const size_t size = _PyObject_VAR_SIZE(tp, nitems);
+ PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(size);
+ if (op != NULL)
+ op = PyObject_INIT_VAR(op, tp, nitems);
+ return op;
+}
+
+PyVarObject *
+_PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems)
+{
+ const size_t basicsize = _PyObject_VAR_SIZE(op->ob_type, nitems);
+ PyGC_Head *g = AS_GC(op);
+ g = (PyGC_Head *)PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize);
+ if (g == NULL)
+ return (PyVarObject *)PyErr_NoMemory();
+ op = (PyVarObject *) FROM_GC(g);
+ op->ob_size = nitems;
+ return op;
+}
+
+void
+PyObject_GC_Del(void *op)
+{
+ PyGC_Head *g = AS_GC(op);
+ if (IS_TRACKED(op))
+ gc_list_remove(g);
+ if (generations[0].count > 0) {
+ generations[0].count--;
+ }
+ PyObject_FREE(g);
+}
+
+/* for binary compatibility with 2.2 */
+#undef _PyObject_GC_Del
+void
+_PyObject_GC_Del(PyObject *op)
+{
+ PyObject_GC_Del(op);
+}
diff --git a/sys/src/cmd/python/Modules/gdbmmodule.c b/sys/src/cmd/python/Modules/gdbmmodule.c
new file mode 100644
index 000000000..cfc6abc37
--- /dev/null
+++ b/sys/src/cmd/python/Modules/gdbmmodule.c
@@ -0,0 +1,515 @@
+
+/* DBM module using dictionary interface */
+/* Author: Anthony Baxter, after dbmmodule.c */
+/* Doc strings: Mitch Chapman */
+
+
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "gdbm.h"
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include "gdbmerrno.h"
+extern const char * gdbm_strerror(gdbm_error);
+#endif
+
+PyDoc_STRVAR(gdbmmodule__doc__,
+"This module provides an interface to the GNU DBM (GDBM) library.\n\
+\n\
+This module is quite similar to the dbm module, but uses GDBM instead to\n\
+provide some additional functionality. Please note that the file formats\n\
+created by GDBM and dbm are incompatible. \n\
+\n\
+GDBM objects behave like mappings (dictionaries), except that keys and\n\
+values are always strings. Printing a GDBM object doesn't print the\n\
+keys and values, and the items() and values() methods are not\n\
+supported.");
+
+typedef struct {
+ PyObject_HEAD
+ int di_size; /* -1 means recompute */
+ GDBM_FILE di_dbm;
+} dbmobject;
+
+static PyTypeObject Dbmtype;
+
+#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
+#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
+ { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
+ return NULL; }
+
+
+
+static PyObject *DbmError;
+
+PyDoc_STRVAR(gdbm_object__doc__,
+"This object represents a GDBM database.\n\
+GDBM objects behave like mappings (dictionaries), except that keys and\n\
+values are always strings. Printing a GDBM object doesn't print the\n\
+keys and values, and the items() and values() methods are not\n\
+supported.\n\
+\n\
+GDBM objects also support additional operations such as firstkey,\n\
+nextkey, reorganize, and sync.");
+
+static PyObject *
+newdbmobject(char *file, int flags, int mode)
+{
+ dbmobject *dp;
+
+ dp = PyObject_New(dbmobject, &Dbmtype);
+ if (dp == NULL)
+ return NULL;
+ dp->di_size = -1;
+ errno = 0;
+ if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) {
+ if (errno != 0)
+ PyErr_SetFromErrno(DbmError);
+ else
+ PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
+ Py_DECREF(dp);
+ return NULL;
+ }
+ return (PyObject *)dp;
+}
+
+/* Methods */
+
+static void
+dbm_dealloc(register dbmobject *dp)
+{
+ if (dp->di_dbm)
+ gdbm_close(dp->di_dbm);
+ PyObject_Del(dp);
+}
+
+static Py_ssize_t
+dbm_length(dbmobject *dp)
+{
+ if (dp->di_dbm == NULL) {
+ PyErr_SetString(DbmError, "GDBM object has already been closed");
+ return -1;
+ }
+ if (dp->di_size < 0) {
+ datum key,okey;
+ int size;
+ okey.dsize=0;
+ okey.dptr=NULL;
+
+ size = 0;
+ for (key=gdbm_firstkey(dp->di_dbm); key.dptr;
+ key = gdbm_nextkey(dp->di_dbm,okey)) {
+ size++;
+ if(okey.dsize) free(okey.dptr);
+ okey=key;
+ }
+ dp->di_size = size;
+ }
+ return dp->di_size;
+}
+
+static PyObject *
+dbm_subscript(dbmobject *dp, register PyObject *key)
+{
+ PyObject *v;
+ datum drec, krec;
+
+ if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
+ return NULL;
+
+ if (dp->di_dbm == NULL) {
+ PyErr_SetString(DbmError,
+ "GDBM object has already been closed");
+ return NULL;
+ }
+ drec = gdbm_fetch(dp->di_dbm, krec);
+ if (drec.dptr == 0) {
+ PyErr_SetString(PyExc_KeyError,
+ PyString_AS_STRING((PyStringObject *)key));
+ return NULL;
+ }
+ v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
+ free(drec.dptr);
+ return v;
+}
+
+static int
+dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
+{
+ datum krec, drec;
+
+ if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
+ PyErr_SetString(PyExc_TypeError,
+ "gdbm mappings have string indices only");
+ return -1;
+ }
+ if (dp->di_dbm == NULL) {
+ PyErr_SetString(DbmError,
+ "GDBM object has already been closed");
+ return -1;
+ }
+ dp->di_size = -1;
+ if (w == NULL) {
+ if (gdbm_delete(dp->di_dbm, krec) < 0) {
+ PyErr_SetString(PyExc_KeyError,
+ PyString_AS_STRING((PyStringObject *)v));
+ return -1;
+ }
+ }
+ else {
+ if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) {
+ PyErr_SetString(PyExc_TypeError,
+ "gdbm mappings have string elements only");
+ return -1;
+ }
+ errno = 0;
+ if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) {
+ if (errno != 0)
+ PyErr_SetFromErrno(DbmError);
+ else
+ PyErr_SetString(DbmError,
+ gdbm_strerror(gdbm_errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static PyMappingMethods dbm_as_mapping = {
+ (lenfunc)dbm_length, /*mp_length*/
+ (binaryfunc)dbm_subscript, /*mp_subscript*/
+ (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
+};
+
+PyDoc_STRVAR(dbm_close__doc__,
+"close() -> None\n\
+Closes the database.");
+
+static PyObject *
+dbm_close(register dbmobject *dp, PyObject *unused)
+{
+ if (dp->di_dbm)
+ gdbm_close(dp->di_dbm);
+ dp->di_dbm = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(dbm_keys__doc__,
+"keys() -> list_of_keys\n\
+Get a list of all keys in the database.");
+
+static PyObject *
+dbm_keys(register dbmobject *dp, PyObject *unused)
+{
+ register PyObject *v, *item;
+ datum key, nextkey;
+ int err;
+
+ if (dp == NULL || !is_dbmobject(dp)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ check_dbmobject_open(dp);
+
+ v = PyList_New(0);
+ if (v == NULL)
+ return NULL;
+
+ key = gdbm_firstkey(dp->di_dbm);
+ while (key.dptr) {
+ item = PyString_FromStringAndSize(key.dptr, key.dsize);
+ if (item == NULL) {
+ free(key.dptr);
+ Py_DECREF(v);
+ return NULL;
+ }
+ err = PyList_Append(v, item);
+ Py_DECREF(item);
+ if (err != 0) {
+ free(key.dptr);
+ Py_DECREF(v);
+ return NULL;
+ }
+ nextkey = gdbm_nextkey(dp->di_dbm, key);
+ free(key.dptr);
+ key = nextkey;
+ }
+ return v;
+}
+
+PyDoc_STRVAR(dbm_has_key__doc__,
+"has_key(key) -> boolean\n\
+Find out whether or not the database contains a given key.");
+
+static PyObject *
+dbm_has_key(register dbmobject *dp, PyObject *args)
+{
+ datum key;
+
+ if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &key.dsize))
+ return NULL;
+ check_dbmobject_open(dp);
+ return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
+}
+
+PyDoc_STRVAR(dbm_firstkey__doc__,
+"firstkey() -> key\n\
+It's possible to loop over every key in the database using this method\n\
+and the nextkey() method. The traversal is ordered by GDBM's internal\n\
+hash values, and won't be sorted by the key values. This method\n\
+returns the starting key.");
+
+static PyObject *
+dbm_firstkey(register dbmobject *dp, PyObject *unused)
+{
+ register PyObject *v;
+ datum key;
+
+ check_dbmobject_open(dp);
+ key = gdbm_firstkey(dp->di_dbm);
+ if (key.dptr) {
+ v = PyString_FromStringAndSize(key.dptr, key.dsize);
+ free(key.dptr);
+ return v;
+ }
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyDoc_STRVAR(dbm_nextkey__doc__,
+"nextkey(key) -> next_key\n\
+Returns the key that follows key in the traversal.\n\
+The following code prints every key in the database db, without having\n\
+to create a list in memory that contains them all:\n\
+\n\
+ k = db.firstkey()\n\
+ while k != None:\n\
+ print k\n\
+ k = db.nextkey(k)");
+
+static PyObject *
+dbm_nextkey(register dbmobject *dp, PyObject *args)
+{
+ register PyObject *v;
+ datum key, nextkey;
+
+ if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize))
+ return NULL;
+ check_dbmobject_open(dp);
+ nextkey = gdbm_nextkey(dp->di_dbm, key);
+ if (nextkey.dptr) {
+ v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
+ free(nextkey.dptr);
+ return v;
+ }
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyDoc_STRVAR(dbm_reorganize__doc__,
+"reorganize() -> None\n\
+If you have carried out a lot of deletions and would like to shrink\n\
+the space used by the GDBM file, this routine will reorganize the\n\
+database. GDBM will not shorten the length of a database file except\n\
+by using this reorganization; otherwise, deleted file space will be\n\
+kept and reused as new (key,value) pairs are added.");
+
+static PyObject *
+dbm_reorganize(register dbmobject *dp, PyObject *unused)
+{
+ check_dbmobject_open(dp);
+ errno = 0;
+ if (gdbm_reorganize(dp->di_dbm) < 0) {
+ if (errno != 0)
+ PyErr_SetFromErrno(DbmError);
+ else
+ PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(dbm_sync__doc__,
+"sync() -> None\n\
+When the database has been opened in fast mode, this method forces\n\
+any unwritten data to be written to the disk.");
+
+static PyObject *
+dbm_sync(register dbmobject *dp, PyObject *unused)
+{
+ check_dbmobject_open(dp);
+ gdbm_sync(dp->di_dbm);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef dbm_methods[] = {
+ {"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__},
+ {"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__},
+ {"has_key", (PyCFunction)dbm_has_key, METH_VARARGS, dbm_has_key__doc__},
+ {"firstkey", (PyCFunction)dbm_firstkey,METH_NOARGS, dbm_firstkey__doc__},
+ {"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
+ {"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__},
+ {"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+dbm_getattr(dbmobject *dp, char *name)
+{
+ return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
+}
+
+static PyTypeObject Dbmtype = {
+ PyObject_HEAD_INIT(0)
+ 0,
+ "gdbm.gdbm",
+ sizeof(dbmobject),
+ 0,
+ (destructor)dbm_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)dbm_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &dbm_as_mapping, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ 0, /*tp_xxx4*/
+ gdbm_object__doc__, /*tp_doc*/
+};
+
+/* ----------------------------------------------------------------- */
+
+PyDoc_STRVAR(dbmopen__doc__,
+"open(filename, [flags, [mode]]) -> dbm_object\n\
+Open a dbm database and return a dbm object. The filename argument is\n\
+the name of the database file.\n\
+\n\
+The optional flags argument can be 'r' (to open an existing database\n\
+for reading only -- default), 'w' (to open an existing database for\n\
+reading and writing), 'c' (which creates the database if it doesn't\n\
+exist), or 'n' (which always creates a new empty database).\n\
+\n\
+Some versions of gdbm support additional flags which must be\n\
+appended to one of the flags described above. The module constant\n\
+'open_flags' is a string of valid additional flags. The 'f' flag\n\
+opens the database in fast mode; altered data will not automatically\n\
+be written to the disk after every change. This results in faster\n\
+writes to the database, but may result in an inconsistent database\n\
+if the program crashes while the database is still open. Use the\n\
+sync() method to force any unwritten data to be written to the disk.\n\
+The 's' flag causes all database operations to be synchronized to\n\
+disk. The 'u' flag disables locking of the database file.\n\
+\n\
+The optional mode argument is the Unix mode of the file, used only\n\
+when the database has to be created. It defaults to octal 0666. ");
+
+static PyObject *
+dbmopen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *flags = "r";
+ int iflags;
+ int mode = 0666;
+
+ if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode))
+ return NULL;
+ switch (flags[0]) {
+ case 'r':
+ iflags = GDBM_READER;
+ break;
+ case 'w':
+ iflags = GDBM_WRITER;
+ break;
+ case 'c':
+ iflags = GDBM_WRCREAT;
+ break;
+ case 'n':
+ iflags = GDBM_NEWDB;
+ break;
+ default:
+ PyErr_SetString(DbmError,
+ "First flag must be one of 'r', 'w', 'c' or 'n'");
+ return NULL;
+ }
+ for (flags++; *flags != '\0'; flags++) {
+ char buf[40];
+ switch (*flags) {
+#ifdef GDBM_FAST
+ case 'f':
+ iflags |= GDBM_FAST;
+ break;
+#endif
+#ifdef GDBM_SYNC
+ case 's':
+ iflags |= GDBM_SYNC;
+ break;
+#endif
+#ifdef GDBM_NOLOCK
+ case 'u':
+ iflags |= GDBM_NOLOCK;
+ break;
+#endif
+ default:
+ PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.",
+ *flags);
+ PyErr_SetString(DbmError, buf);
+ return NULL;
+ }
+ }
+
+ return newdbmobject(name, iflags, mode);
+}
+
+static char dbmmodule_open_flags[] = "rwcn"
+#ifdef GDBM_FAST
+ "f"
+#endif
+#ifdef GDBM_SYNC
+ "s"
+#endif
+#ifdef GDBM_NOLOCK
+ "u"
+#endif
+ ;
+
+static PyMethodDef dbmmodule_methods[] = {
+ { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__},
+ { 0, 0 },
+};
+
+PyMODINIT_FUNC
+initgdbm(void) {
+ PyObject *m, *d, *s;
+
+ Dbmtype.ob_type = &PyType_Type;
+ m = Py_InitModule4("gdbm", dbmmodule_methods,
+ gdbmmodule__doc__, (PyObject *)NULL,
+ PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
+ if (DbmError != NULL) {
+ PyDict_SetItemString(d, "error", DbmError);
+ s = PyString_FromString(dbmmodule_open_flags);
+ PyDict_SetItemString(d, "open_flags", s);
+ Py_DECREF(s);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/getaddrinfo.c b/sys/src/cmd/python/Modules/getaddrinfo.c
new file mode 100644
index 000000000..4d19c3424
--- /dev/null
+++ b/sys/src/cmd/python/Modules/getaddrinfo.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
+ *
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked.
+ * - Return values. There are nonstandard return values defined and used
+ * in the source code. This is because RFC2133 is silent about which error
+ * code must be returned for which situation.
+ * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
+ */
+
+#if 0
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "addrinfo.h"
+#endif
+
+#if defined(__KAME__) && defined(ENABLE_IPV6)
+# define FAITH
+#endif
+
+#define SUCCESS 0
+#define GAI_ANY 0
+#define YES 1
+#define NO 0
+
+#ifdef FAITH
+static int translate = NO;
+static struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT;
+#endif
+
+static const char in_addrany[] = { 0, 0, 0, 0 };
+static const char in6_addrany[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static const char in_loopback[] = { 127, 0, 0, 1 };
+static const char in6_loopback[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+};
+
+struct sockinet {
+ u_char si_len;
+ u_char si_family;
+ u_short si_port;
+};
+
+static struct gai_afd {
+ int a_af;
+ int a_addrlen;
+ int a_socklen;
+ int a_off;
+ const char *a_addrany;
+ const char *a_loopback;
+} gai_afdl [] = {
+#ifdef ENABLE_IPV6
+#define N_INET6 0
+ {PF_INET6, sizeof(struct in6_addr),
+ sizeof(struct sockaddr_in6),
+ offsetof(struct sockaddr_in6, sin6_addr),
+ in6_addrany, in6_loopback},
+#define N_INET 1
+#else
+#define N_INET 0
+#endif
+ {PF_INET, sizeof(struct in_addr),
+ sizeof(struct sockaddr_in),
+ offsetof(struct sockaddr_in, sin_addr),
+ in_addrany, in_loopback},
+ {0, 0, 0, 0, NULL, NULL},
+};
+
+#ifdef ENABLE_IPV6
+#define PTON_MAX 16
+#else
+#define PTON_MAX 4
+#endif
+
+#ifndef IN_MULTICAST
+#define IN_MULTICAST(i) (((i) & 0xf0000000U) == 0xe0000000U)
+#endif
+
+#ifndef IN_EXPERIMENTAL
+#define IN_EXPERIMENTAL(i) (((i) & 0xe0000000U) == 0xe0000000U)
+#endif
+
+#ifndef IN_LOOPBACKNET
+#define IN_LOOPBACKNET 127
+#endif
+
+static int get_name Py_PROTO((const char *, struct gai_afd *,
+ struct addrinfo **, char *, struct addrinfo *,
+ int));
+static int get_addr Py_PROTO((const char *, int, struct addrinfo **,
+ struct addrinfo *, int));
+static int str_isnumber Py_PROTO((const char *));
+
+static char *ai_errlist[] = {
+ "success.",
+ "address family for hostname not supported.", /* EAI_ADDRFAMILY */
+ "temporary failure in name resolution.", /* EAI_AGAIN */
+ "invalid value for ai_flags.", /* EAI_BADFLAGS */
+ "non-recoverable failure in name resolution.", /* EAI_FAIL */
+ "ai_family not supported.", /* EAI_FAMILY */
+ "memory allocation failure.", /* EAI_MEMORY */
+ "no address associated with hostname.", /* EAI_NODATA */
+ "hostname nor servname provided, or not known.",/* EAI_NONAME */
+ "servname not supported for ai_socktype.", /* EAI_SERVICE */
+ "ai_socktype not supported.", /* EAI_SOCKTYPE */
+ "system error returned in errno.", /* EAI_SYSTEM */
+ "invalid value for hints.", /* EAI_BADHINTS */
+ "resolved protocol is unknown.", /* EAI_PROTOCOL */
+ "unknown error.", /* EAI_MAX */
+};
+
+#define GET_CANONNAME(ai, str) \
+if (pai->ai_flags & AI_CANONNAME) {\
+ if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
+ strcpy((ai)->ai_canonname, (str));\
+ } else {\
+ error = EAI_MEMORY;\
+ goto free;\
+ }\
+}
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+#define GET_AI(ai, gai_afd, addr, port) {\
+ char *p;\
+ if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
+ ((gai_afd)->a_socklen)))\
+ == NULL) goto free;\
+ memcpy(ai, pai, sizeof(struct addrinfo));\
+ (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
+ memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
+ (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\
+ (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
+ ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
+ p = (char *)((ai)->ai_addr);\
+ memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
+}
+#else
+#define GET_AI(ai, gai_afd, addr, port) {\
+ char *p;\
+ if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
+ ((gai_afd)->a_socklen)))\
+ == NULL) goto free;\
+ memcpy(ai, pai, sizeof(struct addrinfo));\
+ (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
+ memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
+ (ai)->ai_addrlen = (gai_afd)->a_socklen;\
+ (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
+ ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
+ p = (char *)((ai)->ai_addr);\
+ memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
+}
+#endif
+
+#define ERR(err) { error = (err); goto bad; }
+
+char *
+gai_strerror(int ecode)
+{
+ if (ecode < 0 || ecode > EAI_MAX)
+ ecode = EAI_MAX;
+ return ai_errlist[ecode];
+}
+
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+ struct addrinfo *next;
+
+ do {
+ next = ai->ai_next;
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ /* no need to free(ai->ai_addr) */
+ free(ai);
+ } while ((ai = next) != NULL);
+}
+
+static int
+str_isnumber(const char *p)
+{
+ unsigned char *q = (unsigned char *)p;
+ while (*q) {
+ if (! isdigit(*q))
+ return NO;
+ q++;
+ }
+ return YES;
+}
+
+int
+getaddrinfo(const char*hostname, const char*servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct addrinfo sentinel;
+ struct addrinfo *top = NULL;
+ struct addrinfo *cur;
+ int i, error = 0;
+ char pton[PTON_MAX];
+ struct addrinfo ai;
+ struct addrinfo *pai;
+ u_short port;
+
+#ifdef FAITH
+ static int firsttime = 1;
+
+ if (firsttime) {
+ /* translator hack */
+ {
+ char *q = getenv("GAI");
+ if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
+ translate = YES;
+ }
+ firsttime = 0;
+ }
+#endif
+
+ /* initialize file static vars */
+ sentinel.ai_next = NULL;
+ cur = &sentinel;
+ pai = &ai;
+ pai->ai_flags = 0;
+ pai->ai_family = PF_UNSPEC;
+ pai->ai_socktype = GAI_ANY;
+ pai->ai_protocol = GAI_ANY;
+ pai->ai_addrlen = 0;
+ pai->ai_canonname = NULL;
+ pai->ai_addr = NULL;
+ pai->ai_next = NULL;
+ port = GAI_ANY;
+
+ if (hostname == NULL && servname == NULL)
+ return EAI_NONAME;
+ if (hints) {
+ /* error check for hints */
+ if (hints->ai_addrlen || hints->ai_canonname ||
+ hints->ai_addr || hints->ai_next)
+ ERR(EAI_BADHINTS); /* xxx */
+ if (hints->ai_flags & ~AI_MASK)
+ ERR(EAI_BADFLAGS);
+ switch (hints->ai_family) {
+ case PF_UNSPEC:
+ case PF_INET:
+#ifdef ENABLE_IPV6
+ case PF_INET6:
+#endif
+ break;
+ default:
+ ERR(EAI_FAMILY);
+ }
+ memcpy(pai, hints, sizeof(*pai));
+ switch (pai->ai_socktype) {
+ case GAI_ANY:
+ switch (pai->ai_protocol) {
+ case GAI_ANY:
+ break;
+ case IPPROTO_UDP:
+ pai->ai_socktype = SOCK_DGRAM;
+ break;
+ case IPPROTO_TCP:
+ pai->ai_socktype = SOCK_STREAM;
+ break;
+ default:
+ pai->ai_socktype = SOCK_RAW;
+ break;
+ }
+ break;
+ case SOCK_RAW:
+ break;
+ case SOCK_DGRAM:
+ if (pai->ai_protocol != IPPROTO_UDP &&
+ pai->ai_protocol != GAI_ANY)
+ ERR(EAI_BADHINTS); /*xxx*/
+ pai->ai_protocol = IPPROTO_UDP;
+ break;
+ case SOCK_STREAM:
+ if (pai->ai_protocol != IPPROTO_TCP &&
+ pai->ai_protocol != GAI_ANY)
+ ERR(EAI_BADHINTS); /*xxx*/
+ pai->ai_protocol = IPPROTO_TCP;
+ break;
+ default:
+ ERR(EAI_SOCKTYPE);
+ /* unreachable */
+ }
+ }
+
+ /*
+ * service port
+ */
+ if (servname) {
+ if (str_isnumber(servname)) {
+ if (pai->ai_socktype == GAI_ANY) {
+ /* caller accept *GAI_ANY* socktype */
+ pai->ai_socktype = SOCK_DGRAM;
+ pai->ai_protocol = IPPROTO_UDP;
+ }
+ port = htons((u_short)atoi(servname));
+ } else {
+ struct servent *sp;
+ char *proto;
+
+ proto = NULL;
+ switch (pai->ai_socktype) {
+ case GAI_ANY:
+ proto = NULL;
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ default:
+ fprintf(stderr, "panic!\n");
+ break;
+ }
+ if ((sp = getservbyname(servname, proto)) == NULL)
+ ERR(EAI_SERVICE);
+ port = sp->s_port;
+ if (pai->ai_socktype == GAI_ANY) {
+ if (strcmp(sp->s_proto, "udp") == 0) {
+ pai->ai_socktype = SOCK_DGRAM;
+ pai->ai_protocol = IPPROTO_UDP;
+ } else if (strcmp(sp->s_proto, "tcp") == 0) {
+ pai->ai_socktype = SOCK_STREAM;
+ pai->ai_protocol = IPPROTO_TCP;
+ } else
+ ERR(EAI_PROTOCOL); /*xxx*/
+ }
+ }
+ }
+
+ /*
+ * hostname == NULL.
+ * passive socket -> anyaddr (0.0.0.0 or ::)
+ * non-passive socket -> localhost (127.0.0.1 or ::1)
+ */
+ if (hostname == NULL) {
+ struct gai_afd *gai_afd;
+
+ for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) {
+ if (!(pai->ai_family == PF_UNSPEC
+ || pai->ai_family == gai_afd->a_af)) {
+ continue;
+ }
+
+ if (pai->ai_flags & AI_PASSIVE) {
+ GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port);
+ /* xxx meaningless?
+ * GET_CANONNAME(cur->ai_next, "anyaddr");
+ */
+ } else {
+ GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback,
+ port);
+ /* xxx meaningless?
+ * GET_CANONNAME(cur->ai_next, "localhost");
+ */
+ }
+ cur = cur->ai_next;
+ }
+ top = sentinel.ai_next;
+ if (top)
+ goto good;
+ else
+ ERR(EAI_FAMILY);
+ }
+
+ /* hostname as numeric name */
+ for (i = 0; gai_afdl[i].a_af; i++) {
+ if (inet_pton(gai_afdl[i].a_af, hostname, pton)) {
+ u_long v4a;
+#ifdef ENABLE_IPV6
+ u_char pfx;
+#endif
+
+ switch (gai_afdl[i].a_af) {
+ case AF_INET:
+ v4a = ((struct in_addr *)pton)->s_addr;
+ v4a = ntohl(v4a);
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ pai->ai_flags &= ~AI_CANONNAME;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ pai->ai_flags &= ~AI_CANONNAME;
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ pfx = ((struct in6_addr *)pton)->s6_addr8[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ pai->ai_flags &= ~AI_CANONNAME;
+ break;
+#endif
+ }
+
+ if (pai->ai_family == gai_afdl[i].a_af ||
+ pai->ai_family == PF_UNSPEC) {
+ if (! (pai->ai_flags & AI_CANONNAME)) {
+ GET_AI(top, &gai_afdl[i], pton, port);
+ goto good;
+ }
+ /*
+ * if AI_CANONNAME and if reverse lookup
+ * fail, return ai anyway to pacify
+ * calling application.
+ *
+ * XXX getaddrinfo() is a name->address
+ * translation function, and it looks strange
+ * that we do addr->name translation here.
+ */
+ get_name(pton, &gai_afdl[i], &top, pton, pai, port);
+ goto good;
+ } else
+ ERR(EAI_FAMILY); /*xxx*/
+ }
+ }
+
+ if (pai->ai_flags & AI_NUMERICHOST)
+ ERR(EAI_NONAME);
+
+ /* hostname as alphabetical name */
+ error = get_addr(hostname, pai->ai_family, &top, pai, port);
+ if (error == 0) {
+ if (top) {
+ good:
+ *res = top;
+ return SUCCESS;
+ } else
+ error = EAI_FAIL;
+ }
+ free:
+ if (top)
+ freeaddrinfo(top);
+ bad:
+ *res = NULL;
+ return error;
+}
+
+static int
+get_name(addr, gai_afd, res, numaddr, pai, port0)
+ const char *addr;
+ struct gai_afd *gai_afd;
+ struct addrinfo **res;
+ char *numaddr;
+ struct addrinfo *pai;
+ int port0;
+{
+ u_short port = port0 & 0xffff;
+ struct hostent *hp;
+ struct addrinfo *cur;
+ int error = 0;
+#ifdef ENABLE_IPV6
+ int h_error;
+#endif
+
+#ifdef ENABLE_IPV6
+ hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error);
+#else
+ hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET);
+#endif
+ if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+ GET_AI(cur, gai_afd, hp->h_addr_list[0], port);
+ GET_CANONNAME(cur, hp->h_name);
+ } else
+ GET_AI(cur, gai_afd, numaddr, port);
+
+#ifdef ENABLE_IPV6
+ if (hp)
+ freehostent(hp);
+#endif
+ *res = cur;
+ return SUCCESS;
+ free:
+ if (cur)
+ freeaddrinfo(cur);
+#ifdef ENABLE_IPV6
+ if (hp)
+ freehostent(hp);
+#endif
+ /* bad: */
+ *res = NULL;
+ return error;
+}
+
+static int
+get_addr(hostname, af, res, pai, port0)
+ const char *hostname;
+ int af;
+ struct addrinfo **res;
+ struct addrinfo *pai;
+ int port0;
+{
+ u_short port = port0 & 0xffff;
+ struct addrinfo sentinel;
+ struct hostent *hp;
+ struct addrinfo *top, *cur;
+ struct gai_afd *gai_afd;
+ int i, error = 0, h_error;
+ char *ap;
+
+ top = NULL;
+ sentinel.ai_next = NULL;
+ cur = &sentinel;
+#ifdef ENABLE_IPV6
+ if (af == AF_UNSPEC) {
+ hp = getipnodebyname(hostname, AF_INET6,
+ AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
+ } else
+ hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
+#else
+ hp = gethostbyname(hostname);
+ h_error = h_errno;
+#endif
+ if (hp == NULL) {
+ switch (h_error) {
+ case HOST_NOT_FOUND:
+ case NO_DATA:
+ error = EAI_NODATA;
+ break;
+ case TRY_AGAIN:
+ error = EAI_AGAIN;
+ break;
+ case NO_RECOVERY:
+ default:
+ error = EAI_FAIL;
+ break;
+ }
+ goto free;
+ }
+
+ if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
+ (hp->h_addr_list[0] == NULL)) {
+ error = EAI_FAIL;
+ goto free;
+ }
+
+ for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
+ switch (af) {
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ gai_afd = &gai_afdl[N_INET6];
+ break;
+#endif
+#ifndef ENABLE_IPV6
+ default: /* AF_UNSPEC */
+#endif
+ case AF_INET:
+ gai_afd = &gai_afdl[N_INET];
+ break;
+#ifdef ENABLE_IPV6
+ default: /* AF_UNSPEC */
+ if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
+ ap += sizeof(struct in6_addr) -
+ sizeof(struct in_addr);
+ gai_afd = &gai_afdl[N_INET];
+ } else
+ gai_afd = &gai_afdl[N_INET6];
+ break;
+#endif
+ }
+#ifdef FAITH
+ if (translate && gai_afd->a_af == AF_INET) {
+ struct in6_addr *in6;
+
+ GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port);
+ in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
+ memcpy(&in6->s6_addr32[0], &faith_prefix,
+ sizeof(struct in6_addr) - sizeof(struct in_addr));
+ memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
+ } else
+#endif /* FAITH */
+ GET_AI(cur->ai_next, gai_afd, ap, port);
+ if (cur == &sentinel) {
+ top = cur->ai_next;
+ GET_CANONNAME(top, hp->h_name);
+ }
+ cur = cur->ai_next;
+ }
+#ifdef ENABLE_IPV6
+ freehostent(hp);
+#endif
+ *res = top;
+ return SUCCESS;
+ free:
+ if (top)
+ freeaddrinfo(top);
+#ifdef ENABLE_IPV6
+ if (hp)
+ freehostent(hp);
+#endif
+/* bad: */
+ *res = NULL;
+ return error;
+}
diff --git a/sys/src/cmd/python/Modules/getbuildinfo.c b/sys/src/cmd/python/Modules/getbuildinfo.c
new file mode 100644
index 000000000..a017dab06
--- /dev/null
+++ b/sys/src/cmd/python/Modules/getbuildinfo.c
@@ -0,0 +1,48 @@
+#include "Python.h"
+
+#ifndef DONT_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifndef DATE
+#ifdef __DATE__
+#define DATE __DATE__
+#else
+#define DATE "xx/xx/xx"
+#endif
+#endif
+
+#ifndef TIME
+#ifdef __TIME__
+#define TIME __TIME__
+#else
+#define TIME "xx:xx:xx"
+#endif
+#endif
+
+#ifdef SUBWCREV
+#define SVNVERSION "$WCRANGE$$WCMODS?M:$"
+#endif
+
+const char *
+Py_GetBuildInfo(void)
+{
+ static char buildinfo[50];
+ const char *revision = Py_SubversionRevision();
+ const char *sep = *revision ? ":" : "";
+ const char *branch = Py_SubversionShortBranch();
+ PyOS_snprintf(buildinfo, sizeof(buildinfo),
+ "%s%s%s, %.20s, %.9s", branch, sep, revision,
+ DATE, TIME);
+ return buildinfo;
+}
+
+const char *
+_Py_svnversion(void)
+{
+#ifdef SVNVERSION
+ return SVNVERSION;
+#else
+ return "exported";
+#endif
+}
diff --git a/sys/src/cmd/python/Modules/getnameinfo.c b/sys/src/cmd/python/Modules/getnameinfo.c
new file mode 100644
index 000000000..d3c0ac537
--- /dev/null
+++ b/sys/src/cmd/python/Modules/getnameinfo.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Issues to be discussed:
+ * - Thread safe-ness must be checked
+ * - Return values. There seems to be no standard for return value (RFC2133)
+ * but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+ */
+
+#if 0
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "addrinfo.h"
+#endif
+
+#define SUCCESS 0
+#define YES 1
+#define NO 0
+
+static struct gni_afd {
+ int a_af;
+ int a_addrlen;
+ int a_socklen;
+ int a_off;
+} gni_afdl [] = {
+#ifdef ENABLE_IPV6
+ {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
+ offsetof(struct sockaddr_in6, sin6_addr)},
+#endif
+ {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
+ offsetof(struct sockaddr_in, sin_addr)},
+ {0, 0, 0},
+};
+
+struct gni_sockinet {
+ u_char si_len;
+ u_char si_family;
+ u_short si_port;
+};
+
+#define ENI_NOSOCKET 0
+#define ENI_NOSERVNAME 1
+#define ENI_NOHOSTNAME 2
+#define ENI_MEMORY 3
+#define ENI_SYSTEM 4
+#define ENI_FAMILY 5
+#define ENI_SALEN 6
+
+/* forward declaration to make gcc happy */
+int getnameinfo Py_PROTO((const struct sockaddr *, size_t, char *, size_t,
+ char *, size_t, int));
+
+int
+getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+ const struct sockaddr *sa;
+ size_t salen;
+ char *host;
+ size_t hostlen;
+ char *serv;
+ size_t servlen;
+ int flags;
+{
+ struct gni_afd *gni_afd;
+ struct servent *sp;
+ struct hostent *hp;
+ u_short port;
+ int family, len, i;
+ char *addr, *p;
+ u_long v4a;
+#ifdef ENABLE_IPV6
+ u_char pfx;
+#endif
+ int h_error;
+ char numserv[512];
+ char numaddr[512];
+
+ if (sa == NULL)
+ return ENI_NOSOCKET;
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+ len = sa->sa_len;
+ if (len != salen) return ENI_SALEN;
+#else
+ len = salen;
+#endif
+
+ family = sa->sa_family;
+ for (i = 0; gni_afdl[i].a_af; i++)
+ if (gni_afdl[i].a_af == family) {
+ gni_afd = &gni_afdl[i];
+ goto found;
+ }
+ return ENI_FAMILY;
+
+ found:
+ if (len != gni_afd->a_socklen) return ENI_SALEN;
+
+ port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */
+ addr = (char *)sa + gni_afd->a_off;
+
+ if (serv == NULL || servlen == 0) {
+ /* what we should do? */
+ } else if (flags & NI_NUMERICSERV) {
+ sprintf(numserv, "%d", ntohs(port));
+ if (strlen(numserv) > servlen)
+ return ENI_MEMORY;
+ strcpy(serv, numserv);
+ } else {
+ sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
+ if (sp) {
+ if (strlen(sp->s_name) > servlen)
+ return ENI_MEMORY;
+ strcpy(serv, sp->s_name);
+ } else
+ return ENI_NOSERVNAME;
+ }
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ flags |= NI_NUMERICHOST;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ flags |= NI_NUMERICHOST;
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ flags |= NI_NUMERICHOST;
+ break;
+#endif
+ }
+ if (host == NULL || hostlen == 0) {
+ /* what should we do? */
+ } else if (flags & NI_NUMERICHOST) {
+ if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ return ENI_SYSTEM;
+ if (strlen(numaddr) > hostlen)
+ return ENI_MEMORY;
+ strcpy(host, numaddr);
+ } else {
+#ifdef ENABLE_IPV6
+ hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error);
+#else
+ hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af);
+ h_error = h_errno;
+#endif
+
+ if (hp) {
+ if (flags & NI_NOFQDN) {
+ p = strchr(hp->h_name, '.');
+ if (p) *p = '\0';
+ }
+ if (strlen(hp->h_name) > hostlen) {
+#ifdef ENABLE_IPV6
+ freehostent(hp);
+#endif
+ return ENI_MEMORY;
+ }
+ strcpy(host, hp->h_name);
+#ifdef ENABLE_IPV6
+ freehostent(hp);
+#endif
+ } else {
+ if (flags & NI_NAMEREQD)
+ return ENI_NOHOSTNAME;
+ if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ return ENI_NOHOSTNAME;
+ if (strlen(numaddr) > hostlen)
+ return ENI_MEMORY;
+ strcpy(host, numaddr);
+ }
+ }
+ return SUCCESS;
+}
diff --git a/sys/src/cmd/python/Modules/getpath.c b/sys/src/cmd/python/Modules/getpath.c
new file mode 100644
index 000000000..78bfaf976
--- /dev/null
+++ b/sys/src/cmd/python/Modules/getpath.c
@@ -0,0 +1,694 @@
+/* Return the initial module search path. */
+
+#include "Python.h"
+#include "osdefs.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
+/* Search in some common locations for the associated Python libraries.
+ *
+ * Two directories must be found, the platform independent directory
+ * (prefix), containing the common .py and .pyc files, and the platform
+ * dependent directory (exec_prefix), containing the shared library
+ * modules. Note that prefix and exec_prefix can be the same directory,
+ * but for some installations, they are different.
+ *
+ * Py_GetPath() carries out separate searches for prefix and exec_prefix.
+ * Each search tries a number of different locations until a ``landmark''
+ * file or directory is found. If no prefix or exec_prefix is found, a
+ * warning message is issued and the preprocessor defined PREFIX and
+ * EXEC_PREFIX are used (even though they will not work); python carries on
+ * as best as is possible, but most imports will fail.
+ *
+ * Before any searches are done, the location of the executable is
+ * determined. If argv[0] has one or more slashs in it, it is used
+ * unchanged. Otherwise, it must have been invoked from the shell's path,
+ * so we search $PATH for the named executable and use that. If the
+ * executable was not found on $PATH (or there was no $PATH environment
+ * variable), the original argv[0] string is used.
+ *
+ * Next, the executable location is examined to see if it is a symbolic
+ * link. If so, the link is chased (correctly interpreting a relative
+ * pathname if one is found) and the directory of the link target is used.
+ *
+ * Finally, argv0_path is set to the directory containing the executable
+ * (i.e. the last component is stripped).
+ *
+ * With argv0_path in hand, we perform a number of steps. The same steps
+ * are performed for prefix and for exec_prefix, but with a different
+ * landmark.
+ *
+ * Step 1. Are we running python out of the build directory? This is
+ * checked by looking for a different kind of landmark relative to
+ * argv0_path. For prefix, the landmark's path is derived from the VPATH
+ * preprocessor variable (taking into account that its value is almost, but
+ * not quite, what we need). For exec_prefix, the landmark is
+ * Modules/Setup. If the landmark is found, we're done.
+ *
+ * For the remaining steps, the prefix landmark will always be
+ * lib/python$VERSION/os.py and the exec_prefix will always be
+ * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
+ * number as supplied by the Makefile. Note that this means that no more
+ * build directory checking is performed; if the first step did not find
+ * the landmarks, the assumption is that python is running from an
+ * installed setup.
+ *
+ * Step 2. See if the $PYTHONHOME environment variable points to the
+ * installed location of the Python libraries. If $PYTHONHOME is set, then
+ * it points to prefix and exec_prefix. $PYTHONHOME can be a single
+ * directory, which is used for both, or the prefix and exec_prefix
+ * directories separated by a colon.
+ *
+ * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
+ * backtracking up the path until it is exhausted. This is the most common
+ * step to succeed. Note that if prefix and exec_prefix are different,
+ * exec_prefix is more likely to be found; however if exec_prefix is a
+ * subdirectory of prefix, both will be found.
+ *
+ * Step 4. Search the directories pointed to by the preprocessor variables
+ * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be
+ * passed in as options to the configure script.
+ *
+ * That's it!
+ *
+ * Well, almost. Once we have determined prefix and exec_prefix, the
+ * preprocessor variable PYTHONPATH is used to construct a path. Each
+ * relative path on PYTHONPATH is prefixed with prefix. Then the directory
+ * containing the shared library modules is appended. The environment
+ * variable $PYTHONPATH is inserted in front of it all. Finally, the
+ * prefix and exec_prefix globals are tweaked so they reflect the values
+ * expected by other code, by stripping the "lib/python$VERSION/..." stuff
+ * off. If either points to the build directory, the globals are reset to
+ * the corresponding preprocessor variables (so sys.prefix will reflect the
+ * installation location, even though sys.path points into the build
+ * directory). This seems to make more sense given that currently the only
+ * known use of sys.prefix and sys.exec_prefix is for the ILU installation
+ * process to find the installed Python tree.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifndef VERSION
+#define VERSION "2.1"
+#endif
+
+#ifndef VPATH
+#define VPATH "."
+#endif
+
+#ifndef PREFIX
+# ifdef __VMS
+# define PREFIX ""
+# else
+# define PREFIX "/usr/local"
+# endif
+#endif
+
+#ifndef EXEC_PREFIX
+#define EXEC_PREFIX PREFIX
+#endif
+
+#ifndef PYTHONPATH
+#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
+ EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
+#endif
+
+#ifndef LANDMARK
+#define LANDMARK "os.py"
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char exec_prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+static char lib_python[] = "lib/python" VERSION;
+
+static void
+reduce(char *dir)
+{
+ size_t i = strlen(dir);
+ while (i > 0 && dir[i] != SEP)
+ --i;
+ dir[i] = '\0';
+}
+
+
+static int
+isfile(char *filename) /* Is file, not directory */
+{
+ struct stat buf;
+ if (stat(filename, &buf) != 0)
+ return 0;
+ if (!S_ISREG(buf.st_mode))
+ return 0;
+ return 1;
+}
+
+
+static int
+ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
+{
+ if (isfile(filename))
+ return 1;
+
+ /* Check for the compiled version of prefix. */
+ if (strlen(filename) < MAXPATHLEN) {
+ strcat(filename, Py_OptimizeFlag ? "o" : "c");
+ if (isfile(filename))
+ return 1;
+ }
+ return 0;
+}
+
+
+static int
+isxfile(char *filename) /* Is executable file */
+{
+ struct stat buf;
+ if (stat(filename, &buf) != 0)
+ return 0;
+ if (!S_ISREG(buf.st_mode))
+ return 0;
+ if ((buf.st_mode & 0111) == 0)
+ return 0;
+ return 1;
+}
+
+
+static int
+isdir(char *filename) /* Is directory */
+{
+ struct stat buf;
+ if (stat(filename, &buf) != 0)
+ return 0;
+ if (!S_ISDIR(buf.st_mode))
+ return 0;
+ return 1;
+}
+
+
+/* Add a path component, by appending stuff to buffer.
+ buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
+ NUL-terminated string with no more than MAXPATHLEN characters (not counting
+ the trailing NUL). It's a fatal error if it contains a string longer than
+ that (callers must be careful!). If these requirements are met, it's
+ guaranteed that buffer will still be a NUL-terminated string with no more
+ than MAXPATHLEN characters at exit. If stuff is too long, only as much of
+ stuff as fits will be appended.
+*/
+static void
+joinpath(char *buffer, char *stuff)
+{
+ size_t n, k;
+ if (stuff[0] == SEP)
+ n = 0;
+ else {
+ n = strlen(buffer);
+ if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
+ buffer[n++] = SEP;
+ }
+ if (n > MAXPATHLEN)
+ Py_FatalError("buffer overflow in getpath.c's joinpath()");
+ k = strlen(stuff);
+ if (n + k > MAXPATHLEN)
+ k = MAXPATHLEN - n;
+ strncpy(buffer+n, stuff, k);
+ buffer[n+k] = '\0';
+}
+
+/* copy_absolute requires that path be allocated at least
+ MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
+static void
+copy_absolute(char *path, char *p)
+{
+ if (p[0] == SEP)
+ strcpy(path, p);
+ else {
+ getcwd(path, MAXPATHLEN);
+ if (p[0] == '.' && p[1] == SEP)
+ p += 2;
+ joinpath(path, p);
+ }
+}
+
+/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
+static void
+absolutize(char *path)
+{
+ char buffer[MAXPATHLEN + 1];
+
+ if (path[0] == SEP)
+ return;
+ copy_absolute(buffer, path);
+ strcpy(path, buffer);
+}
+
+/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
+ bytes long.
+*/
+static int
+search_for_prefix(char *argv0_path, char *home)
+{
+ size_t n;
+ char *vpath;
+
+ /* If PYTHONHOME is set, we believe it unconditionally */
+ if (home) {
+ char *delim;
+ strncpy(prefix, home, MAXPATHLEN);
+ delim = strchr(prefix, DELIM);
+ if (delim)
+ *delim = '\0';
+ joinpath(prefix, lib_python);
+ joinpath(prefix, LANDMARK);
+ return 1;
+ }
+
+ /* Check to see if argv[0] is in the build directory */
+ strcpy(prefix, argv0_path);
+ joinpath(prefix, "Modules/Setup");
+ if (isfile(prefix)) {
+ /* Check VPATH to see if argv0_path is in the build directory. */
+ vpath = VPATH;
+ strcpy(prefix, argv0_path);
+ joinpath(prefix, vpath);
+ joinpath(prefix, "Lib");
+ joinpath(prefix, LANDMARK);
+ if (ismodule(prefix))
+ return -1;
+ }
+
+ /* Search from argv0_path, until root is found */
+ copy_absolute(prefix, argv0_path);
+ do {
+ n = strlen(prefix);
+ joinpath(prefix, lib_python);
+ joinpath(prefix, LANDMARK);
+ if (ismodule(prefix))
+ return 1;
+ prefix[n] = '\0';
+ reduce(prefix);
+ } while (prefix[0]);
+
+ /* Look at configure's PREFIX */
+ strncpy(prefix, PREFIX, MAXPATHLEN);
+ joinpath(prefix, lib_python);
+ joinpath(prefix, LANDMARK);
+ if (ismodule(prefix))
+ return 1;
+
+ /* Fail */
+ return 0;
+}
+
+
+/* search_for_exec_prefix requires that argv0_path be no more than
+ MAXPATHLEN bytes long.
+*/
+static int
+search_for_exec_prefix(char *argv0_path, char *home)
+{
+ size_t n;
+
+ /* If PYTHONHOME is set, we believe it unconditionally */
+ if (home) {
+ char *delim;
+ delim = strchr(home, DELIM);
+ if (delim)
+ strncpy(exec_prefix, delim+1, MAXPATHLEN);
+ else
+ strncpy(exec_prefix, home, MAXPATHLEN);
+ joinpath(exec_prefix, lib_python);
+ joinpath(exec_prefix, "lib-dynload");
+ return 1;
+ }
+
+ /* Check to see if argv[0] is in the build directory */
+ strcpy(exec_prefix, argv0_path);
+ joinpath(exec_prefix, "Modules/Setup");
+ if (isfile(exec_prefix)) {
+ reduce(exec_prefix);
+ return -1;
+ }
+
+ /* Search from argv0_path, until root is found */
+ copy_absolute(exec_prefix, argv0_path);
+ do {
+ n = strlen(exec_prefix);
+ joinpath(exec_prefix, lib_python);
+ joinpath(exec_prefix, "lib-dynload");
+ if (isdir(exec_prefix))
+ return 1;
+ exec_prefix[n] = '\0';
+ reduce(exec_prefix);
+ } while (exec_prefix[0]);
+
+ /* Look at configure's EXEC_PREFIX */
+ strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
+ joinpath(exec_prefix, lib_python);
+ joinpath(exec_prefix, "lib-dynload");
+ if (isdir(exec_prefix))
+ return 1;
+
+ /* Fail */
+ return 0;
+}
+
+
+static void
+calculate_path(void)
+{
+ extern char *Py_GetProgramName(void);
+
+ static char delimiter[2] = {DELIM, '\0'};
+ static char separator[2] = {SEP, '\0'};
+ char *pythonpath = PYTHONPATH;
+ char *rtpypath = Py_GETENV("PYTHONPATH");
+ char *home = Py_GetPythonHome();
+ char *path = getenv("PATH");
+ char *prog = Py_GetProgramName();
+ char argv0_path[MAXPATHLEN+1];
+ char zip_path[MAXPATHLEN+1];
+ int pfound, efound; /* 1 if found; -1 if found build directory */
+ char *buf;
+ size_t bufsz;
+ size_t prefixsz;
+ char *defpath = pythonpath;
+#ifdef WITH_NEXT_FRAMEWORK
+ NSModule pythonModule;
+#endif
+#ifdef __APPLE__
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ uint32_t nsexeclength = MAXPATHLEN;
+#else
+ unsigned long nsexeclength = MAXPATHLEN;
+#endif
+#endif
+
+ /* If there is no slash in the argv0 path, then we have to
+ * assume python is on the user's $PATH, since there's no
+ * other way to find a directory to start the search from. If
+ * $PATH isn't exported, you lose.
+ */
+ if (strchr(prog, SEP))
+ strncpy(progpath, prog, MAXPATHLEN);
+#ifdef __APPLE__
+ /* On Mac OS X, if a script uses an interpreter of the form
+ * "#!/opt/python2.3/bin/python", the kernel only passes "python"
+ * as argv[0], which falls through to the $PATH search below.
+ * If /opt/python2.3/bin isn't in your path, or is near the end,
+ * this algorithm may incorrectly find /usr/bin/python. To work
+ * around this, we can use _NSGetExecutablePath to get a better
+ * hint of what the intended interpreter was, although this
+ * will fail if a relative path was used. but in that case,
+ * absolutize() should help us out below
+ */
+ else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
+ ;
+#endif /* __APPLE__ */
+ else if (path) {
+ while (1) {
+ char *delim = strchr(path, DELIM);
+
+ if (delim) {
+ size_t len = delim - path;
+ if (len > MAXPATHLEN)
+ len = MAXPATHLEN;
+ strncpy(progpath, path, len);
+ *(progpath + len) = '\0';
+ }
+ else
+ strncpy(progpath, path, MAXPATHLEN);
+
+ joinpath(progpath, prog);
+ if (isxfile(progpath))
+ break;
+
+ if (!delim) {
+ progpath[0] = '\0';
+ break;
+ }
+ path = delim + 1;
+ }
+ }
+ else
+ progpath[0] = '\0';
+ if (progpath[0] != SEP)
+ absolutize(progpath);
+ strncpy(argv0_path, progpath, MAXPATHLEN);
+ argv0_path[MAXPATHLEN] = '\0';
+
+#ifdef WITH_NEXT_FRAMEWORK
+ /* On Mac OS X we have a special case if we're running from a framework.
+ ** This is because the python home should be set relative to the library,
+ ** which is in the framework, not relative to the executable, which may
+ ** be outside of the framework. Except when we're in the build directory...
+ */
+ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
+ /* Use dylib functions to find out where the framework was loaded from */
+ buf = (char *)NSLibraryNameForModule(pythonModule);
+ if (buf != NULL) {
+ /* We're in a framework. */
+ /* See if we might be in the build directory. The framework in the
+ ** build directory is incomplete, it only has the .dylib and a few
+ ** needed symlinks, it doesn't have the Lib directories and such.
+ ** If we're running with the framework from the build directory we must
+ ** be running the interpreter in the build directory, so we use the
+ ** build-directory-specific logic to find Lib and such.
+ */
+ strncpy(argv0_path, buf, MAXPATHLEN);
+ reduce(argv0_path);
+ joinpath(argv0_path, lib_python);
+ joinpath(argv0_path, LANDMARK);
+ if (!ismodule(argv0_path)) {
+ /* We are in the build directory so use the name of the
+ executable - we know that the absolute path is passed */
+ strncpy(argv0_path, prog, MAXPATHLEN);
+ }
+ else {
+ /* Use the location of the library as the progpath */
+ strncpy(argv0_path, buf, MAXPATHLEN);
+ }
+ }
+#endif
+
+#if HAVE_READLINK
+ {
+ char tmpbuffer[MAXPATHLEN+1];
+ int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
+ while (linklen != -1) {
+ /* It's not null terminated! */
+ tmpbuffer[linklen] = '\0';
+ if (tmpbuffer[0] == SEP)
+ /* tmpbuffer should never be longer than MAXPATHLEN,
+ but extra check does not hurt */
+ strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
+ else {
+ /* Interpret relative to progpath */
+ reduce(argv0_path);
+ joinpath(argv0_path, tmpbuffer);
+ }
+ linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
+ }
+ }
+#endif /* HAVE_READLINK */
+
+ reduce(argv0_path);
+ /* At this point, argv0_path is guaranteed to be less than
+ MAXPATHLEN bytes long.
+ */
+
+ if (!(pfound = search_for_prefix(argv0_path, home))) {
+ if (!Py_FrozenFlag)
+ fprintf(stderr,
+ "Could not find platform independent libraries <prefix>\n");
+ strncpy(prefix, PREFIX, MAXPATHLEN);
+ joinpath(prefix, lib_python);
+ }
+ else
+ reduce(prefix);
+
+ strncpy(zip_path, prefix, MAXPATHLEN);
+ zip_path[MAXPATHLEN] = '\0';
+ if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
+ reduce(zip_path);
+ reduce(zip_path);
+ }
+ else
+ strncpy(zip_path, PREFIX, MAXPATHLEN);
+ joinpath(zip_path, "lib/python00.zip");
+ bufsz = strlen(zip_path); /* Replace "00" with version */
+ zip_path[bufsz - 6] = VERSION[0];
+ zip_path[bufsz - 5] = VERSION[2];
+
+ if (!(efound = search_for_exec_prefix(argv0_path, home))) {
+ if (!Py_FrozenFlag)
+ fprintf(stderr,
+ "Could not find platform dependent libraries <exec_prefix>\n");
+ strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
+ joinpath(exec_prefix, "lib/lib-dynload");
+ }
+ /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
+
+ if ((!pfound || !efound) && !Py_FrozenFlag)
+ fprintf(stderr,
+ "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
+
+ /* Calculate size of return buffer.
+ */
+ bufsz = 0;
+
+ if (rtpypath)
+ bufsz += strlen(rtpypath) + 1;
+
+ prefixsz = strlen(prefix) + 1;
+
+ while (1) {
+ char *delim = strchr(defpath, DELIM);
+
+ if (defpath[0] != SEP)
+ /* Paths are relative to prefix */
+ bufsz += prefixsz;
+
+ if (delim)
+ bufsz += delim - defpath + 1;
+ else {
+ bufsz += strlen(defpath) + 1;
+ break;
+ }
+ defpath = delim + 1;
+ }
+
+ bufsz += strlen(zip_path) + 1;
+ bufsz += strlen(exec_prefix) + 1;
+
+ /* This is the only malloc call in this file */
+ buf = (char *)PyMem_Malloc(bufsz);
+
+ if (buf == NULL) {
+ /* We can't exit, so print a warning and limp along */
+ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
+ fprintf(stderr, "Using default static PYTHONPATH.\n");
+ module_search_path = PYTHONPATH;
+ }
+ else {
+ /* Run-time value of $PYTHONPATH goes first */
+ if (rtpypath) {
+ strcpy(buf, rtpypath);
+ strcat(buf, delimiter);
+ }
+ else
+ buf[0] = '\0';
+
+ /* Next is the default zip path */
+ strcat(buf, zip_path);
+ strcat(buf, delimiter);
+
+ /* Next goes merge of compile-time $PYTHONPATH with
+ * dynamically located prefix.
+ */
+ defpath = pythonpath;
+ while (1) {
+ char *delim = strchr(defpath, DELIM);
+
+ if (defpath[0] != SEP) {
+ strcat(buf, prefix);
+ strcat(buf, separator);
+ }
+
+ if (delim) {
+ size_t len = delim - defpath + 1;
+ size_t end = strlen(buf) + len;
+ strncat(buf, defpath, len);
+ *(buf + end) = '\0';
+ }
+ else {
+ strcat(buf, defpath);
+ break;
+ }
+ defpath = delim + 1;
+ }
+ strcat(buf, delimiter);
+
+ /* Finally, on goes the directory for dynamic-load modules */
+ strcat(buf, exec_prefix);
+
+ /* And publish the results */
+ module_search_path = buf;
+ }
+
+ /* Reduce prefix and exec_prefix to their essence,
+ * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
+ * If we're loading relative to the build directory,
+ * return the compiled-in defaults instead.
+ */
+ if (pfound > 0) {
+ reduce(prefix);
+ reduce(prefix);
+ /* The prefix is the root directory, but reduce() chopped
+ * off the "/". */
+ if (!prefix[0])
+ strcpy(prefix, separator);
+ }
+ else
+ strncpy(prefix, PREFIX, MAXPATHLEN);
+
+ if (efound > 0) {
+ reduce(exec_prefix);
+ reduce(exec_prefix);
+ reduce(exec_prefix);
+ if (!exec_prefix[0])
+ strcpy(exec_prefix, separator);
+ }
+ else
+ strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return exec_prefix;
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return progpath;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/sys/src/cmd/python/Modules/glmodule.c b/sys/src/cmd/python/Modules/glmodule.c
new file mode 100644
index 000000000..659070472
--- /dev/null
+++ b/sys/src/cmd/python/Modules/glmodule.c
@@ -0,0 +1,7628 @@
+
+/*
+Input used to generate the Python module "glmodule.c".
+The stub generator is a Python script called "cgen.py".
+
+Each definition must be contained on one line:
+
+<returntype> <name> <type> <arg> <type> <arg>
+
+<returntype> can be: void, short, long (XXX maybe others?)
+
+<type> can be: char, string, short, float, long, or double
+ string indicates a null terminated string;
+ if <type> is char and <arg> begins with a *, the * is stripped
+ and <type> is changed into string
+
+<arg> has the form <mode> or <mode>[<subscript>]
+ where <mode> can be
+ s: arg is sent
+ r: arg is received (arg is a pointer)
+ and <subscript> can be (N and I are numbers):
+ N
+ argI
+ retval
+ N*argI
+ N*I
+ N*retval
+ In the case where the subscript consists of two parts
+ separated by *, the first part is the width of the matrix, and
+ the second part is the length of the matrix. This order is
+ opposite from the order used in C to declare a two-dimensional
+ matrix.
+*/
+
+/*
+ * An attempt has been made to make this module switch threads on qread
+ * calls. It is far from safe, though.
+ */
+
+#include <gl.h>
+#include <device.h>
+
+#ifdef __sgi
+extern int devport();
+extern int textwritemask();
+extern int pagewritemask();
+extern int gewrite();
+extern int gettp();
+#endif
+
+#include "Python.h"
+#include "cgensupport.h"
+
+/*
+Some stubs are too complicated for the stub generator.
+We can include manually written versions of them here.
+A line starting with '%' gives the name of the function so the stub
+generator can include it in the table of functions.
+*/
+
+
+static PyObject *
+gl_qread(PyObject *self, PyObject *args)
+{
+ long retval;
+ short arg1 ;
+ Py_BEGIN_ALLOW_THREADS
+ retval = qread( & arg1 );
+ Py_END_ALLOW_THREADS
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewlongobject(retval));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg1));
+ return v;
+ }
+}
+
+
+/*
+varray -- an array of v.. calls.
+The argument is an array (maybe list or tuple) of points.
+Each point must be a tuple or list of coordinates (x, y, z).
+The points may be 2- or 3-dimensional but must all have the
+same dimension. Float and int values may be mixed however.
+The points are always converted to 3D double precision points
+by assuming z=0.0 if necessary (as indicated in the man page),
+and for each point v3d() is called.
+*/
+
+
+static PyObject *
+gl_varray(PyObject *self, PyObject *args)
+{
+ PyObject *v, *w=NULL;
+ int i, n, width;
+ double vec[3];
+ PyObject * (*getitem)(PyObject *, int);
+
+ if (!PyArg_GetObject(args, 1, 0, &v))
+ return NULL;
+
+ if (PyList_Check(v)) {
+ n = PyList_Size(v);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(v)) {
+ n = PyTuple_Size(v);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ if (n == 0) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (n > 0)
+ w = (*getitem)(v, 0);
+
+ width = 0;
+ if (w == NULL) {
+ }
+ else if (PyList_Check(w)) {
+ width = PyList_Size(w);
+ }
+ else if (PyTuple_Check(w)) {
+ width = PyTuple_Size(w);
+ }
+
+ switch (width) {
+ case 2:
+ vec[2] = 0.0;
+ /* Fall through */
+ case 3:
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ w = (*getitem)(v, i);
+ if (!PyArg_GetDoubleArray(w, 1, 0, width, vec))
+ return NULL;
+ v3d(vec);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+vnarray, nvarray -- an array of n3f and v3f calls.
+The argument is an array (list or tuple) of pairs of points and normals.
+Each pair is a tuple (NOT a list) of a point and a normal for that point.
+Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
+Three coordinates must be given. Float and int values may be mixed.
+For each pair, n3f() is called for the normal, and then v3f() is called
+for the vector.
+
+vnarray and nvarray differ only in the order of the vector and normal in
+the pair: vnarray expects (v, n) while nvarray expects (n, v).
+*/
+
+static PyObject *gen_nvarray(); /* Forward */
+
+
+static PyObject *
+gl_nvarray(PyObject *self, PyObject *args)
+{
+ return gen_nvarray(args, 0);
+}
+
+
+static PyObject *
+gl_vnarray(PyObject *self, PyObject *args)
+{
+ return gen_nvarray(args, 1);
+}
+
+/* Generic, internal version of {nv,nv}array: inorm indicates the
+ argument order, 0: normal first, 1: vector first. */
+
+static PyObject *
+gen_nvarray(PyObject *args, int inorm)
+{
+ PyObject *v, *w, *wnorm, *wvec;
+ int i, n;
+ float norm[3], vec[3];
+ PyObject * (*getitem)(PyObject *, int);
+
+ if (!PyArg_GetObject(args, 1, 0, &v))
+ return NULL;
+
+ if (PyList_Check(v)) {
+ n = PyList_Size(v);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(v)) {
+ n = PyTuple_Size(v);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ w = (*getitem)(v, i);
+ if (!PyTuple_Check(w) || PyTuple_Size(w) != 2) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ wnorm = PyTuple_GetItem(w, inorm);
+ wvec = PyTuple_GetItem(w, 1 - inorm);
+ if (!PyArg_GetFloatArray(wnorm, 1, 0, 3, norm) ||
+ !PyArg_GetFloatArray(wvec, 1, 0, 3, vec))
+ return NULL;
+ n3f(norm);
+ v3f(vec);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* nurbssurface(s_knots[], t_knots[], ctl[][], s_order, t_order, type).
+ The dimensions of ctl[] are computed as follows:
+ [len(s_knots) - s_order], [len(t_knots) - t_order]
+*/
+
+
+static PyObject *
+gl_nurbssurface(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ double * arg2 ;
+ long arg3 ;
+ double * arg4 ;
+ double *arg5 ;
+ long arg6 ;
+ long arg7 ;
+ long arg8 ;
+ long ncoords;
+ long s_byte_stride, t_byte_stride;
+ long s_nctl, t_nctl;
+ long s, t;
+ PyObject *v, *w, *pt;
+ double *pnext;
+ if (!PyArg_GetLongArraySize(args, 6, 0, &arg1))
+ return NULL;
+ if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ if (!PyArg_GetDoubleArray(args, 6, 0, arg1 , arg2))
+ return NULL;
+ if (!PyArg_GetLongArraySize(args, 6, 1, &arg3))
+ return NULL;
+ if ((arg4 = PyMem_NEW(double, arg3 )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ if (!PyArg_GetDoubleArray(args, 6, 1, arg3 , arg4))
+ return NULL;
+ if (!PyArg_GetLong(args, 6, 3, &arg6))
+ return NULL;
+ if (!PyArg_GetLong(args, 6, 4, &arg7))
+ return NULL;
+ if (!PyArg_GetLong(args, 6, 5, &arg8))
+ return NULL;
+ if (arg8 == N_XYZ)
+ ncoords = 3;
+ else if (arg8 == N_XYZW)
+ ncoords = 4;
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ s_nctl = arg1 - arg6;
+ t_nctl = arg3 - arg7;
+ if (!PyArg_GetObject(args, 6, 2, &v))
+ return NULL;
+ if (!PyList_Check(v) || PyList_Size(v) != s_nctl) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ((arg5 = PyMem_NEW(double, s_nctl*t_nctl*ncoords )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ pnext = arg5;
+ for (s = 0; s < s_nctl; s++) {
+ w = PyList_GetItem(v, s);
+ if (w == NULL || !PyList_Check(w) ||
+ PyList_Size(w) != t_nctl) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ for (t = 0; t < t_nctl; t++) {
+ pt = PyList_GetItem(w, t);
+ if (!PyArg_GetDoubleArray(pt, 1, 0, ncoords, pnext))
+ return NULL;
+ pnext += ncoords;
+ }
+ }
+ s_byte_stride = sizeof(double) * ncoords;
+ t_byte_stride = s_byte_stride * s_nctl;
+ nurbssurface( arg1 , arg2 , arg3 , arg4 ,
+ s_byte_stride , t_byte_stride , arg5 , arg6 , arg7 , arg8 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg4);
+ PyMem_DEL(arg5);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* nurbscurve(knots, ctlpoints, order, type).
+ The length of ctlpoints is len(knots)-order. */
+
+
+static PyObject *
+gl_nurbscurve(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ double * arg2 ;
+ long arg3 ;
+ double * arg4 ;
+ long arg5 ;
+ long arg6 ;
+ int ncoords, npoints;
+ int i;
+ PyObject *v;
+ double *pnext;
+ if (!PyArg_GetLongArraySize(args, 4, 0, &arg1))
+ return NULL;
+ if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ if (!PyArg_GetDoubleArray(args, 4, 0, arg1 , arg2))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 2, &arg5))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 3, &arg6))
+ return NULL;
+ if (arg6 == N_ST)
+ ncoords = 2;
+ else if (arg6 == N_STW)
+ ncoords = 3;
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ npoints = arg1 - arg5;
+ if (!PyArg_GetObject(args, 4, 1, &v))
+ return NULL;
+ if (!PyList_Check(v) || PyList_Size(v) != npoints) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ((arg4 = PyMem_NEW(double, npoints*ncoords )) == NULL) {
+ return PyErr_NoMemory();
+ }
+ pnext = arg4;
+ for (i = 0; i < npoints; i++) {
+ if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+ return NULL;
+ pnext += ncoords;
+ }
+ arg3 = (sizeof(double)) * ncoords;
+ nurbscurve( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg4);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* pwlcurve(points, type).
+ Points is a list of points. Type must be N_ST. */
+
+
+static PyObject *
+gl_pwlcurve(PyObject *self, PyObject *args)
+{
+ PyObject *v;
+ long type;
+ double *data, *pnext;
+ long npoints, ncoords;
+ int i;
+ if (!PyArg_GetObject(args, 2, 0, &v))
+ return NULL;
+ if (!PyArg_GetLong(args, 2, 1, &type))
+ return NULL;
+ if (!PyList_Check(v)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ npoints = PyList_Size(v);
+ if (type == N_ST)
+ ncoords = 2;
+ else {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ((data = PyMem_NEW(double, npoints*ncoords)) == NULL) {
+ return PyErr_NoMemory();
+ }
+ pnext = data;
+ for (i = 0; i < npoints; i++) {
+ if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
+ return NULL;
+ pnext += ncoords;
+ }
+ pwlcurve(npoints, data, sizeof(double)*ncoords, type);
+ PyMem_DEL(data);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* Picking and Selecting */
+
+static short *pickbuffer = NULL;
+static long pickbuffersize;
+
+static PyObject *
+pick_select(PyObject *args, void (*func)())
+{
+ if (!PyArg_GetLong(args, 1, 0, &pickbuffersize))
+ return NULL;
+ if (pickbuffer != NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "pick/gselect: already picking/selecting");
+ return NULL;
+ }
+ if ((pickbuffer = PyMem_NEW(short, pickbuffersize)) == NULL) {
+ return PyErr_NoMemory();
+ }
+ (*func)(pickbuffer, pickbuffersize);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+endpick_select(long (*func)())
+{
+ PyObject *v, *w;
+ int i, nhits, n;
+ if (pickbuffer == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "endpick/endselect: not in pick/select mode");
+ return NULL;
+ }
+ nhits = (*func)(pickbuffer);
+ if (nhits < 0) {
+ nhits = -nhits; /* How to report buffer overflow otherwise? */
+ }
+ /* Scan the buffer to see how many integers */
+ n = 0;
+ for (; nhits > 0; nhits--) {
+ n += 1 + pickbuffer[n];
+ }
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ /* XXX Could do it nicer and interpret the data structure here,
+ returning a list of lists. But this can be done in Python... */
+ for (i = 0; i < n; i++) {
+ w = PyInt_FromLong((long)pickbuffer[i]);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(v, i, w);
+ }
+ PyMem_DEL(pickbuffer);
+ pickbuffer = NULL;
+ return v;
+}
+
+extern void pick(), gselect();
+extern long endpick(), endselect();
+
+static PyObject *gl_pick(PyObject *self, PyObject *args)
+{
+ return pick_select(args, pick);
+}
+
+static PyObject *gl_endpick(PyObject *self)
+{
+ return endpick_select(endpick);
+}
+
+static PyObject *gl_gselect(PyObject *self, PyObject *args)
+{
+ return pick_select(args, gselect);
+}
+
+static PyObject *gl_endselect(PyObject *self)
+{
+ return endpick_select(endselect);
+}
+
+
+/* XXX The generator botches this one. Here's a quick hack to fix it. */
+
+/* XXX The generator botches this one. Here's a quick hack to fix it. */
+
+
+static PyObject *
+gl_getmatrix(PyObject *self, PyObject *args)
+{
+ Matrix arg1;
+ PyObject *v, *w;
+ int i, j;
+ getmatrix( arg1 );
+ v = PyList_New(16);
+ if (v == NULL) {
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
+ w = mknewfloatobject(arg1[i][j]);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(v, i*4+j, w);
+ }
+ return v;
+}
+
+/* Here's an alternate version that returns a 4x4 matrix instead of
+ a vector. Unfortunately it is incompatible with loadmatrix and
+ multmatrix... */
+
+
+static PyObject *
+gl_altgetmatrix(PyObject *self, PyObject *args)
+{
+ Matrix arg1;
+ PyObject *v, *w;
+ int i, j;
+ getmatrix( arg1 );
+ v = PyList_New(4);
+ if (v == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < 4; i++) {
+ w = PyList_New(4);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(v, i, w);
+ }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ w = mknewfloatobject(arg1[i][j]);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SetItem(PyList_GetItem(v, i), j, w);
+ }
+ }
+ return v;
+}
+
+
+static PyObject *
+gl_lrectwrite(PyObject *self, PyObject *args)
+{
+ short x1 ;
+ short y1 ;
+ short x2 ;
+ short y2 ;
+ string parray ;
+ PyObject *s;
+#if 0
+ int pixcount;
+#endif
+ if (!PyArg_GetShort(args, 5, 0, &x1))
+ return NULL;
+ if (!PyArg_GetShort(args, 5, 1, &y1))
+ return NULL;
+ if (!PyArg_GetShort(args, 5, 2, &x2))
+ return NULL;
+ if (!PyArg_GetShort(args, 5, 3, &y2))
+ return NULL;
+ if (!PyArg_GetString(args, 5, 4, &parray))
+ return NULL;
+ if (!PyArg_GetObject(args, 5, 4, &s))
+ return NULL;
+#if 0
+/* Don't check this, it breaks experiments with pixmode(PM_SIZE, ...) */
+ pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+ if (!PyString_Check(s) || PyString_Size(s) != pixcount*sizeof(long)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "string arg to lrectwrite has wrong size");
+ return NULL;
+ }
+#endif
+ lrectwrite( x1 , y1 , x2 , y2 , (unsigned long *) parray );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+static PyObject *
+gl_lrectread(PyObject *self, PyObject *args)
+{
+ short x1 ;
+ short y1 ;
+ short x2 ;
+ short y2 ;
+ PyObject *parray;
+ int pixcount;
+ if (!PyArg_GetShort(args, 4, 0, &x1))
+ return NULL;
+ if (!PyArg_GetShort(args, 4, 1, &y1))
+ return NULL;
+ if (!PyArg_GetShort(args, 4, 2, &x2))
+ return NULL;
+ if (!PyArg_GetShort(args, 4, 3, &y2))
+ return NULL;
+ pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
+ parray = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+ if (parray == NULL)
+ return NULL; /* No memory */
+ lrectread(x1, y1, x2, y2, (unsigned long *) PyString_AsString(parray));
+ return parray;
+}
+
+
+static PyObject *
+gl_readdisplay(PyObject *self, PyObject *args)
+{
+ short x1, y1, x2, y2;
+ unsigned long *parray, hints;
+ long size, size_ret;
+ PyObject *rv;
+
+ if ( !PyArg_Parse(args, "hhhhl", &x1, &y1, &x2, &y2, &hints) )
+ return 0;
+ size = (long)(x2+1-x1) * (long)(y2+1-y1);
+ rv = PyString_FromStringAndSize((char *)NULL, size*sizeof(long));
+ if ( rv == NULL )
+ return NULL;
+ parray = (unsigned long *)PyString_AsString(rv);
+ size_ret = readdisplay(x1, y1, x2, y2, parray, hints);
+ if ( size_ret != size ) {
+ printf("gl_readdisplay: got %ld pixels, expected %ld\n",
+ size_ret, size);
+ PyErr_SetString(PyExc_RuntimeError, "readdisplay returned unexpected length");
+ return NULL;
+ }
+ return rv;
+}
+
+/* Desperately needed, here are tools to compress and decompress
+ the data manipulated by lrectread/lrectwrite.
+
+ gl.packrect(width, height, packfactor, bigdata) --> smalldata
+ makes 'bigdata' 4*(packfactor**2) times smaller by:
+ - turning it into B/W (a factor 4)
+ - replacing squares of size pacfactor by one
+ representative
+
+ gl.unpackrect(width, height, packfactor, smalldata) --> bigdata
+ is the inverse; the numeric arguments must be *the same*.
+
+ Both work best if width and height are multiples of packfactor
+ (in fact unpackrect will leave garbage bytes).
+*/
+
+
+static PyObject *
+gl_packrect(PyObject *self, PyObject *args)
+{
+ long width, height, packfactor;
+ char *s;
+ PyObject *unpacked, *packed;
+ int pixcount, packedcount, x, y, r, g, b;
+ unsigned long pixel;
+ unsigned char *p;
+ unsigned long *parray;
+ if (!PyArg_GetLong(args, 4, 0, &width))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 1, &height))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 2, &packfactor))
+ return NULL;
+ if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+ return NULL;
+ if (!PyArg_GetObject(args, 4, 3, &unpacked))
+ return NULL;
+ if (width <= 0 || height <= 0 || packfactor <= 0) {
+ PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+ return NULL;
+ }
+ pixcount = width*height;
+ packedcount = ((width+packfactor-1)/packfactor) *
+ ((height+packfactor-1)/packfactor);
+ if (PyString_Size(unpacked) != pixcount*sizeof(long)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "string arg to packrect has wrong size");
+ return NULL;
+ }
+ packed = PyString_FromStringAndSize((char *)NULL, packedcount);
+ if (packed == NULL)
+ return NULL;
+ parray = (unsigned long *) PyString_AsString(unpacked);
+ p = (unsigned char *) PyString_AsString(packed);
+ for (y = 0; y < height; y += packfactor, parray += packfactor*width) {
+ for (x = 0; x < width; x += packfactor) {
+ pixel = parray[x];
+ r = pixel & 0xff;
+ g = (pixel >> 8) & 0xff;
+ b = (pixel >> 16) & 0xff;
+ *p++ = (30*r+59*g+11*b) / 100;
+ }
+ }
+ return packed;
+}
+
+
+static unsigned long unpacktab[256];
+static int unpacktab_inited = 0;
+
+static PyObject *
+gl_unpackrect(PyObject *self, PyObject *args)
+{
+ long width, height, packfactor;
+ char *s;
+ PyObject *unpacked, *packed;
+ int pixcount, packedcount;
+ register unsigned char *p;
+ register unsigned long *parray;
+ if (!unpacktab_inited) {
+ register int white;
+ for (white = 256; --white >= 0; )
+ unpacktab[white] = white * 0x010101L;
+ unpacktab_inited++;
+ }
+ if (!PyArg_GetLong(args, 4, 0, &width))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 1, &height))
+ return NULL;
+ if (!PyArg_GetLong(args, 4, 2, &packfactor))
+ return NULL;
+ if (!PyArg_GetString(args, 4, 3, &s)) /* For type checking only */
+ return NULL;
+ if (!PyArg_GetObject(args, 4, 3, &packed))
+ return NULL;
+ if (width <= 0 || height <= 0 || packfactor <= 0) {
+ PyErr_SetString(PyExc_RuntimeError, "packrect args must be > 0");
+ return NULL;
+ }
+ pixcount = width*height;
+ packedcount = ((width+packfactor-1)/packfactor) *
+ ((height+packfactor-1)/packfactor);
+ if (PyString_Size(packed) != packedcount) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "string arg to unpackrect has wrong size");
+ return NULL;
+ }
+ unpacked = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
+ if (unpacked == NULL)
+ return NULL;
+ parray = (unsigned long *) PyString_AsString(unpacked);
+ p = (unsigned char *) PyString_AsString(packed);
+ if (packfactor == 1 && width*height > 0) {
+ /* Just expand bytes to longs */
+ register int x = width * height;
+ do {
+ *parray++ = unpacktab[*p++];
+ } while (--x >= 0);
+ }
+ else {
+ register int y;
+ for (y = 0; y < height-packfactor+1;
+ y += packfactor, parray += packfactor*width) {
+ register int x;
+ for (x = 0; x < width-packfactor+1; x += packfactor) {
+ register unsigned long pixel = unpacktab[*p++];
+ register int i;
+ for (i = packfactor*width; (i-=width) >= 0;) {
+ register int j;
+ for (j = packfactor; --j >= 0; )
+ parray[i+x+j] = pixel;
+ }
+ }
+ }
+ }
+ return unpacked;
+}
+
+static PyObject *
+gl_gversion(PyObject *self, PyObject *args)
+{
+ char buf[20];
+ gversion(buf);
+ return PyString_FromString(buf);
+}
+
+
+/* void clear - Manual because of clash with termcap */
+static PyObject *
+gl_clear(PyObject *self, PyObject *args)
+{
+ __GLclear( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* End of manually written stubs */
+
+
+/* long getshade */
+
+static PyObject *
+gl_getshade(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getshade( );
+ return mknewlongobject(retval);
+}
+
+/* void devport short s long s */
+
+static PyObject *
+gl_devport(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ long arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ devport( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rdr2i long s long s */
+
+static PyObject *
+gl_rdr2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ rdr2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rectfs short s short s short s short s */
+
+static PyObject *
+gl_rectfs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ rectfs( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rects short s short s short s short s */
+
+static PyObject *
+gl_rects(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ rects( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rmv2i long s long s */
+
+static PyObject *
+gl_rmv2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ rmv2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void noport */
+
+static PyObject *
+gl_noport(PyObject *self, PyObject *args)
+{
+ noport( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void popviewport */
+
+static PyObject *
+gl_popviewport(PyObject *self, PyObject *args)
+{
+ popviewport( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void clearhitcode */
+
+static PyObject *
+gl_clearhitcode(PyObject *self, PyObject *args)
+{
+ clearhitcode( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void closeobj */
+
+static PyObject *
+gl_closeobj(PyObject *self, PyObject *args)
+{
+ closeobj( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cursoff */
+
+static PyObject *
+gl_cursoff(PyObject *self, PyObject *args)
+{
+ cursoff( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void curson */
+
+static PyObject *
+gl_curson(PyObject *self, PyObject *args)
+{
+ curson( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void doublebuffer */
+
+static PyObject *
+gl_doublebuffer(PyObject *self, PyObject *args)
+{
+ doublebuffer( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void finish */
+
+static PyObject *
+gl_finish(PyObject *self, PyObject *args)
+{
+ finish( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gconfig */
+
+static PyObject *
+gl_gconfig(PyObject *self, PyObject *args)
+{
+ gconfig( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void ginit */
+
+static PyObject *
+gl_ginit(PyObject *self, PyObject *args)
+{
+ ginit( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void greset */
+
+static PyObject *
+gl_greset(PyObject *self, PyObject *args)
+{
+ greset( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void multimap */
+
+static PyObject *
+gl_multimap(PyObject *self, PyObject *args)
+{
+ multimap( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void onemap */
+
+static PyObject *
+gl_onemap(PyObject *self, PyObject *args)
+{
+ onemap( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void popattributes */
+
+static PyObject *
+gl_popattributes(PyObject *self, PyObject *args)
+{
+ popattributes( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void popmatrix */
+
+static PyObject *
+gl_popmatrix(PyObject *self, PyObject *args)
+{
+ popmatrix( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pushattributes */
+
+static PyObject *
+gl_pushattributes(PyObject *self, PyObject *args)
+{
+ pushattributes( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pushmatrix */
+
+static PyObject *
+gl_pushmatrix(PyObject *self, PyObject *args)
+{
+ pushmatrix( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pushviewport */
+
+static PyObject *
+gl_pushviewport(PyObject *self, PyObject *args)
+{
+ pushviewport( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void qreset */
+
+static PyObject *
+gl_qreset(PyObject *self, PyObject *args)
+{
+ qreset( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void RGBmode */
+
+static PyObject *
+gl_RGBmode(PyObject *self, PyObject *args)
+{
+ RGBmode( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void singlebuffer */
+
+static PyObject *
+gl_singlebuffer(PyObject *self, PyObject *args)
+{
+ singlebuffer( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void swapbuffers */
+
+static PyObject *
+gl_swapbuffers(PyObject *self, PyObject *args)
+{
+ swapbuffers( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gsync */
+
+static PyObject *
+gl_gsync(PyObject *self, PyObject *args)
+{
+ gsync( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gflush */
+
+static PyObject *
+gl_gflush(PyObject *self, PyObject *args)
+{
+ gflush( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void tpon */
+
+static PyObject *
+gl_tpon(PyObject *self, PyObject *args)
+{
+ tpon( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void tpoff */
+
+static PyObject *
+gl_tpoff(PyObject *self, PyObject *args)
+{
+ tpoff( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void clkon */
+
+static PyObject *
+gl_clkon(PyObject *self, PyObject *args)
+{
+ clkon( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void clkoff */
+
+static PyObject *
+gl_clkoff(PyObject *self, PyObject *args)
+{
+ clkoff( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void ringbell */
+
+static PyObject *
+gl_ringbell(PyObject *self, PyObject *args)
+{
+ ringbell( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gbegin */
+
+static PyObject *
+gl_gbegin(PyObject *self, PyObject *args)
+{
+ gbegin( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void textinit */
+
+static PyObject *
+gl_textinit(PyObject *self, PyObject *args)
+{
+ textinit( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void initnames */
+
+static PyObject *
+gl_initnames(PyObject *self, PyObject *args)
+{
+ initnames( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pclos */
+
+static PyObject *
+gl_pclos(PyObject *self, PyObject *args)
+{
+ pclos( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void popname */
+
+static PyObject *
+gl_popname(PyObject *self, PyObject *args)
+{
+ popname( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void spclos */
+
+static PyObject *
+gl_spclos(PyObject *self, PyObject *args)
+{
+ spclos( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void zclear */
+
+static PyObject *
+gl_zclear(PyObject *self, PyObject *args)
+{
+ zclear( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void screenspace */
+
+static PyObject *
+gl_screenspace(PyObject *self, PyObject *args)
+{
+ screenspace( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void reshapeviewport */
+
+static PyObject *
+gl_reshapeviewport(PyObject *self, PyObject *args)
+{
+ reshapeviewport( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void winpush */
+
+static PyObject *
+gl_winpush(PyObject *self, PyObject *args)
+{
+ winpush( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void winpop */
+
+static PyObject *
+gl_winpop(PyObject *self, PyObject *args)
+{
+ winpop( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void foreground */
+
+static PyObject *
+gl_foreground(PyObject *self, PyObject *args)
+{
+ foreground( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endfullscrn */
+
+static PyObject *
+gl_endfullscrn(PyObject *self, PyObject *args)
+{
+ endfullscrn( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endpupmode */
+
+static PyObject *
+gl_endpupmode(PyObject *self, PyObject *args)
+{
+ endpupmode( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void fullscrn */
+
+static PyObject *
+gl_fullscrn(PyObject *self, PyObject *args)
+{
+ fullscrn( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pupmode */
+
+static PyObject *
+gl_pupmode(PyObject *self, PyObject *args)
+{
+ pupmode( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void winconstraints */
+
+static PyObject *
+gl_winconstraints(PyObject *self, PyObject *args)
+{
+ winconstraints( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pagecolor short s */
+
+static PyObject *
+gl_pagecolor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ pagecolor( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void textcolor short s */
+
+static PyObject *
+gl_textcolor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ textcolor( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void color short s */
+
+static PyObject *
+gl_color(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ color( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void curveit short s */
+
+static PyObject *
+gl_curveit(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ curveit( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void font short s */
+
+static PyObject *
+gl_font(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ font( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void linewidth short s */
+
+static PyObject *
+gl_linewidth(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ linewidth( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setlinestyle short s */
+
+static PyObject *
+gl_setlinestyle(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ setlinestyle( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setmap short s */
+
+static PyObject *
+gl_setmap(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ setmap( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void swapinterval short s */
+
+static PyObject *
+gl_swapinterval(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ swapinterval( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void writemask short s */
+
+static PyObject *
+gl_writemask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ writemask( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void textwritemask short s */
+
+static PyObject *
+gl_textwritemask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ textwritemask( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void qdevice short s */
+
+static PyObject *
+gl_qdevice(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ qdevice( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void unqdevice short s */
+
+static PyObject *
+gl_unqdevice(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ unqdevice( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void curvebasis short s */
+
+static PyObject *
+gl_curvebasis(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ curvebasis( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void curveprecision short s */
+
+static PyObject *
+gl_curveprecision(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ curveprecision( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void loadname short s */
+
+static PyObject *
+gl_loadname(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ loadname( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void passthrough short s */
+
+static PyObject *
+gl_passthrough(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ passthrough( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pushname short s */
+
+static PyObject *
+gl_pushname(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ pushname( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setmonitor short s */
+
+static PyObject *
+gl_setmonitor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ setmonitor( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setshade short s */
+
+static PyObject *
+gl_setshade(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ setshade( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setpattern short s */
+
+static PyObject *
+gl_setpattern(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ setpattern( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pagewritemask short s */
+
+static PyObject *
+gl_pagewritemask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ pagewritemask( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void callobj long s */
+
+static PyObject *
+gl_callobj(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ callobj( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void delobj long s */
+
+static PyObject *
+gl_delobj(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ delobj( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void editobj long s */
+
+static PyObject *
+gl_editobj(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ editobj( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void makeobj long s */
+
+static PyObject *
+gl_makeobj(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ makeobj( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void maketag long s */
+
+static PyObject *
+gl_maketag(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ maketag( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void chunksize long s */
+
+static PyObject *
+gl_chunksize(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ chunksize( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void compactify long s */
+
+static PyObject *
+gl_compactify(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ compactify( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void deltag long s */
+
+static PyObject *
+gl_deltag(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ deltag( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lsrepeat long s */
+
+static PyObject *
+gl_lsrepeat(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ lsrepeat( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void objinsert long s */
+
+static PyObject *
+gl_objinsert(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ objinsert( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void objreplace long s */
+
+static PyObject *
+gl_objreplace(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ objreplace( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void winclose long s */
+
+static PyObject *
+gl_winclose(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ winclose( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void blanktime long s */
+
+static PyObject *
+gl_blanktime(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ blanktime( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void freepup long s */
+
+static PyObject *
+gl_freepup(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ freepup( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void backbuffer long s */
+
+static PyObject *
+gl_backbuffer(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ backbuffer( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void frontbuffer long s */
+
+static PyObject *
+gl_frontbuffer(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ frontbuffer( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lsbackup long s */
+
+static PyObject *
+gl_lsbackup(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ lsbackup( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void resetls long s */
+
+static PyObject *
+gl_resetls(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ resetls( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lampon long s */
+
+static PyObject *
+gl_lampon(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ lampon( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lampoff long s */
+
+static PyObject *
+gl_lampoff(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ lampoff( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setbell long s */
+
+static PyObject *
+gl_setbell(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ setbell( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void blankscreen long s */
+
+static PyObject *
+gl_blankscreen(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ blankscreen( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void depthcue long s */
+
+static PyObject *
+gl_depthcue(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ depthcue( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void zbuffer long s */
+
+static PyObject *
+gl_zbuffer(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ zbuffer( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void backface long s */
+
+static PyObject *
+gl_backface(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ backface( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cmov2i long s long s */
+
+static PyObject *
+gl_cmov2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ cmov2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void draw2i long s long s */
+
+static PyObject *
+gl_draw2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ draw2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void move2i long s long s */
+
+static PyObject *
+gl_move2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ move2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pnt2i long s long s */
+
+static PyObject *
+gl_pnt2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ pnt2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void patchbasis long s long s */
+
+static PyObject *
+gl_patchbasis(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ patchbasis( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void patchprecision long s long s */
+
+static PyObject *
+gl_patchprecision(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ patchprecision( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pdr2i long s long s */
+
+static PyObject *
+gl_pdr2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ pdr2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pmv2i long s long s */
+
+static PyObject *
+gl_pmv2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ pmv2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpdr2i long s long s */
+
+static PyObject *
+gl_rpdr2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ rpdr2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpmv2i long s long s */
+
+static PyObject *
+gl_rpmv2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ rpmv2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt2i long s long s */
+
+static PyObject *
+gl_xfpt2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ xfpt2i( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void objdelete long s long s */
+
+static PyObject *
+gl_objdelete(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ objdelete( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void patchcurves long s long s */
+
+static PyObject *
+gl_patchcurves(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ patchcurves( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void minsize long s long s */
+
+static PyObject *
+gl_minsize(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ minsize( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void maxsize long s long s */
+
+static PyObject *
+gl_maxsize(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ maxsize( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void keepaspect long s long s */
+
+static PyObject *
+gl_keepaspect(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ keepaspect( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void prefsize long s long s */
+
+static PyObject *
+gl_prefsize(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ prefsize( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void stepunit long s long s */
+
+static PyObject *
+gl_stepunit(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ stepunit( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void fudge long s long s */
+
+static PyObject *
+gl_fudge(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ fudge( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void winmove long s long s */
+
+static PyObject *
+gl_winmove(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ winmove( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void attachcursor short s short s */
+
+static PyObject *
+gl_attachcursor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ attachcursor( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void deflinestyle short s short s */
+
+static PyObject *
+gl_deflinestyle(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ deflinestyle( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void noise short s short s */
+
+static PyObject *
+gl_noise(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ noise( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void picksize short s short s */
+
+static PyObject *
+gl_picksize(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ picksize( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void qenter short s short s */
+
+static PyObject *
+gl_qenter(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ qenter( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setdepth short s short s */
+
+static PyObject *
+gl_setdepth(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ setdepth( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cmov2s short s short s */
+
+static PyObject *
+gl_cmov2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ cmov2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void draw2s short s short s */
+
+static PyObject *
+gl_draw2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ draw2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void move2s short s short s */
+
+static PyObject *
+gl_move2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ move2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pdr2s short s short s */
+
+static PyObject *
+gl_pdr2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ pdr2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pmv2s short s short s */
+
+static PyObject *
+gl_pmv2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ pmv2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pnt2s short s short s */
+
+static PyObject *
+gl_pnt2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ pnt2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rdr2s short s short s */
+
+static PyObject *
+gl_rdr2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ rdr2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rmv2s short s short s */
+
+static PyObject *
+gl_rmv2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ rmv2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpdr2s short s short s */
+
+static PyObject *
+gl_rpdr2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ rpdr2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpmv2s short s short s */
+
+static PyObject *
+gl_rpmv2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ rpmv2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt2s short s short s */
+
+static PyObject *
+gl_xfpt2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ xfpt2s( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cmov2 float s float s */
+
+static PyObject *
+gl_cmov2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ cmov2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void draw2 float s float s */
+
+static PyObject *
+gl_draw2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ draw2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void move2 float s float s */
+
+static PyObject *
+gl_move2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ move2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pnt2 float s float s */
+
+static PyObject *
+gl_pnt2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ pnt2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pdr2 float s float s */
+
+static PyObject *
+gl_pdr2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ pdr2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pmv2 float s float s */
+
+static PyObject *
+gl_pmv2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ pmv2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rdr2 float s float s */
+
+static PyObject *
+gl_rdr2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ rdr2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rmv2 float s float s */
+
+static PyObject *
+gl_rmv2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ rmv2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpdr2 float s float s */
+
+static PyObject *
+gl_rpdr2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ rpdr2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpmv2 float s float s */
+
+static PyObject *
+gl_rpmv2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ rpmv2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt2 float s float s */
+
+static PyObject *
+gl_xfpt2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ xfpt2( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void loadmatrix float s[4*4] */
+
+static PyObject *
+gl_loadmatrix(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] [ 4 ] ;
+ if (!getifloatarray(args, 1, 0, 4 * 4 , (float *) arg1))
+ return NULL;
+ loadmatrix( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void multmatrix float s[4*4] */
+
+static PyObject *
+gl_multmatrix(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] [ 4 ] ;
+ if (!getifloatarray(args, 1, 0, 4 * 4 , (float *) arg1))
+ return NULL;
+ multmatrix( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void crv float s[3*4] */
+
+static PyObject *
+gl_crv(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] [ 3 ] ;
+ if (!getifloatarray(args, 1, 0, 3 * 4 , (float *) arg1))
+ return NULL;
+ crv( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rcrv float s[4*4] */
+
+static PyObject *
+gl_rcrv(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] [ 4 ] ;
+ if (!getifloatarray(args, 1, 0, 4 * 4 , (float *) arg1))
+ return NULL;
+ rcrv( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void addtopup long s char *s long s */
+
+static PyObject *
+gl_addtopup(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ string arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getistringarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ addtopup( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void charstr char *s */
+
+static PyObject *
+gl_charstr(PyObject *self, PyObject *args)
+{
+ string arg1 ;
+ if (!getistringarg(args, 1, 0, &arg1))
+ return NULL;
+ charstr( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void getport char *s */
+
+static PyObject *
+gl_getport(PyObject *self, PyObject *args)
+{
+ string arg1 ;
+ if (!getistringarg(args, 1, 0, &arg1))
+ return NULL;
+ getport( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long strwidth char *s */
+
+static PyObject *
+gl_strwidth(PyObject *self, PyObject *args)
+{
+ long retval;
+ string arg1 ;
+ if (!getistringarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = strwidth( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* long winopen char *s */
+
+static PyObject *
+gl_winopen(PyObject *self, PyObject *args)
+{
+ long retval;
+ string arg1 ;
+ if (!getistringarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = winopen( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void wintitle char *s */
+
+static PyObject *
+gl_wintitle(PyObject *self, PyObject *args)
+{
+ string arg1 ;
+ if (!getistringarg(args, 1, 0, &arg1))
+ return NULL;
+ wintitle( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polf long s float s[3*arg1] */
+
+static PyObject *
+gl_polf(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 1, 0, 3 * arg1 , (float *) arg2))
+ return NULL;
+ polf( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polf2 long s float s[2*arg1] */
+
+static PyObject *
+gl_polf2(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 2 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (float(*)[2]) PyMem_NEW(float , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 1, 0, 2 * arg1 , (float *) arg2))
+ return NULL;
+ polf2( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void poly long s float s[3*arg1] */
+
+static PyObject *
+gl_poly(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 1, 0, 3 * arg1 , (float *) arg2))
+ return NULL;
+ poly( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void poly2 long s float s[2*arg1] */
+
+static PyObject *
+gl_poly2(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 2 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (float(*)[2]) PyMem_NEW(float , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 1, 0, 2 * arg1 , (float *) arg2))
+ return NULL;
+ poly2( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void crvn long s float s[3*arg1] */
+
+static PyObject *
+gl_crvn(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 1, 0, 3 * arg1 , (float *) arg2))
+ return NULL;
+ crvn( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rcrvn long s float s[4*arg1] */
+
+static PyObject *
+gl_rcrvn(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 4 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 4;
+ if ((arg2 = (float(*)[4]) PyMem_NEW(float , 4 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 1, 0, 4 * arg1 , (float *) arg2))
+ return NULL;
+ rcrvn( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polf2i long s long s[2*arg1] */
+
+static PyObject *
+gl_polf2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long (* arg2) [ 2 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (long(*)[2]) PyMem_NEW(long , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getilongarray(args, 1, 0, 2 * arg1 , (long *) arg2))
+ return NULL;
+ polf2i( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polfi long s long s[3*arg1] */
+
+static PyObject *
+gl_polfi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (long(*)[3]) PyMem_NEW(long , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getilongarray(args, 1, 0, 3 * arg1 , (long *) arg2))
+ return NULL;
+ polfi( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void poly2i long s long s[2*arg1] */
+
+static PyObject *
+gl_poly2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long (* arg2) [ 2 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (long(*)[2]) PyMem_NEW(long , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getilongarray(args, 1, 0, 2 * arg1 , (long *) arg2))
+ return NULL;
+ poly2i( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polyi long s long s[3*arg1] */
+
+static PyObject *
+gl_polyi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (long(*)[3]) PyMem_NEW(long , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getilongarray(args, 1, 0, 3 * arg1 , (long *) arg2))
+ return NULL;
+ polyi( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polf2s long s short s[2*arg1] */
+
+static PyObject *
+gl_polf2s(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short (* arg2) [ 2 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (short(*)[2]) PyMem_NEW(short , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 1, 0, 2 * arg1 , (short *) arg2))
+ return NULL;
+ polf2s( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polfs long s short s[3*arg1] */
+
+static PyObject *
+gl_polfs(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (short(*)[3]) PyMem_NEW(short , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 1, 0, 3 * arg1 , (short *) arg2))
+ return NULL;
+ polfs( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polys long s short s[3*arg1] */
+
+static PyObject *
+gl_polys(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short (* arg2) [ 3 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (short(*)[3]) PyMem_NEW(short , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 1, 0, 3 * arg1 , (short *) arg2))
+ return NULL;
+ polys( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void poly2s long s short s[2*arg1] */
+
+static PyObject *
+gl_poly2s(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short (* arg2) [ 2 ] ;
+ if (!getilongarraysize(args, 1, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (short(*)[2]) PyMem_NEW(short , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 1, 0, 2 * arg1 , (short *) arg2))
+ return NULL;
+ poly2s( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void defcursor short s u_short s[128] */
+
+static PyObject *
+gl_defcursor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ unsigned short arg2 [ 128 ] ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarray(args, 2, 1, 128 , (short *) arg2))
+ return NULL;
+ defcursor( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void writepixels short s u_short s[arg1] */
+
+static PyObject *
+gl_writepixels(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ unsigned short * arg2 ;
+ if (!getishortarraysize(args, 1, 0, &arg1))
+ return NULL;
+ if ((arg2 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 1, 0, arg1 , (short *) arg2))
+ return NULL;
+ writepixels( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void defbasis long s float s[4*4] */
+
+static PyObject *
+gl_defbasis(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float arg2 [ 4 ] [ 4 ] ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarray(args, 2, 1, 4 * 4 , (float *) arg2))
+ return NULL;
+ defbasis( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gewrite short s short s[arg1] */
+
+static PyObject *
+gl_gewrite(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short * arg2 ;
+ if (!getishortarraysize(args, 1, 0, &arg1))
+ return NULL;
+ if ((arg2 = PyMem_NEW(short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 1, 0, arg1 , arg2))
+ return NULL;
+ gewrite( arg1 , arg2 );
+ PyMem_DEL(arg2);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rotate short s char s */
+
+static PyObject *
+gl_rotate(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ char arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getichararg(args, 2, 1, &arg2))
+ return NULL;
+ rotate( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rot float s char s */
+
+static PyObject *
+gl_rot(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ char arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getichararg(args, 2, 1, &arg2))
+ return NULL;
+ rot( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void circfi long s long s long s */
+
+static PyObject *
+gl_circfi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ circfi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void circi long s long s long s */
+
+static PyObject *
+gl_circi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ circi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cmovi long s long s long s */
+
+static PyObject *
+gl_cmovi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ cmovi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void drawi long s long s long s */
+
+static PyObject *
+gl_drawi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ drawi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void movei long s long s long s */
+
+static PyObject *
+gl_movei(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ movei( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pnti long s long s long s */
+
+static PyObject *
+gl_pnti(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ pnti( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void newtag long s long s long s */
+
+static PyObject *
+gl_newtag(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ newtag( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pdri long s long s long s */
+
+static PyObject *
+gl_pdri(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ pdri( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pmvi long s long s long s */
+
+static PyObject *
+gl_pmvi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ pmvi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rdri long s long s long s */
+
+static PyObject *
+gl_rdri(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ rdri( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rmvi long s long s long s */
+
+static PyObject *
+gl_rmvi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ rmvi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpdri long s long s long s */
+
+static PyObject *
+gl_rpdri(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ rpdri( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpmvi long s long s long s */
+
+static PyObject *
+gl_rpmvi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ rpmvi( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpti long s long s long s */
+
+static PyObject *
+gl_xfpti(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ xfpti( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void circ float s float s float s */
+
+static PyObject *
+gl_circ(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ circ( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void circf float s float s float s */
+
+static PyObject *
+gl_circf(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ circf( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cmov float s float s float s */
+
+static PyObject *
+gl_cmov(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ cmov( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void draw float s float s float s */
+
+static PyObject *
+gl_draw(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ draw( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void move float s float s float s */
+
+static PyObject *
+gl_move(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ move( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pnt float s float s float s */
+
+static PyObject *
+gl_pnt(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ pnt( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void scale float s float s float s */
+
+static PyObject *
+gl_scale(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ scale( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void translate float s float s float s */
+
+static PyObject *
+gl_translate(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ translate( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pdr float s float s float s */
+
+static PyObject *
+gl_pdr(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ pdr( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pmv float s float s float s */
+
+static PyObject *
+gl_pmv(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ pmv( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rdr float s float s float s */
+
+static PyObject *
+gl_rdr(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ rdr( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rmv float s float s float s */
+
+static PyObject *
+gl_rmv(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ rmv( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpdr float s float s float s */
+
+static PyObject *
+gl_rpdr(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ rpdr( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpmv float s float s float s */
+
+static PyObject *
+gl_rpmv(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ rpmv( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt float s float s float s */
+
+static PyObject *
+gl_xfpt(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ if (!getifloatarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 3, 2, &arg3))
+ return NULL;
+ xfpt( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void RGBcolor short s short s short s */
+
+static PyObject *
+gl_RGBcolor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ RGBcolor( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void RGBwritemask short s short s short s */
+
+static PyObject *
+gl_RGBwritemask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ RGBwritemask( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setcursor short s short s short s */
+
+static PyObject *
+gl_setcursor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ setcursor( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void tie short s short s short s */
+
+static PyObject *
+gl_tie(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ tie( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void circfs short s short s short s */
+
+static PyObject *
+gl_circfs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ circfs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void circs short s short s short s */
+
+static PyObject *
+gl_circs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ circs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cmovs short s short s short s */
+
+static PyObject *
+gl_cmovs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ cmovs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void draws short s short s short s */
+
+static PyObject *
+gl_draws(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ draws( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void moves short s short s short s */
+
+static PyObject *
+gl_moves(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ moves( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pdrs short s short s short s */
+
+static PyObject *
+gl_pdrs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ pdrs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pmvs short s short s short s */
+
+static PyObject *
+gl_pmvs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ pmvs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pnts short s short s short s */
+
+static PyObject *
+gl_pnts(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ pnts( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rdrs short s short s short s */
+
+static PyObject *
+gl_rdrs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ rdrs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rmvs short s short s short s */
+
+static PyObject *
+gl_rmvs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ rmvs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpdrs short s short s short s */
+
+static PyObject *
+gl_rpdrs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ rpdrs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpmvs short s short s short s */
+
+static PyObject *
+gl_rpmvs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ rpmvs( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpts short s short s short s */
+
+static PyObject *
+gl_xfpts(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ xfpts( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void curorigin short s short s short s */
+
+static PyObject *
+gl_curorigin(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ curorigin( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cyclemap short s short s short s */
+
+static PyObject *
+gl_cyclemap(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ if (!getishortarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ cyclemap( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void patch float s[4*4] float s[4*4] float s[4*4] */
+
+static PyObject *
+gl_patch(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] [ 4 ] ;
+ float arg2 [ 4 ] [ 4 ] ;
+ float arg3 [ 4 ] [ 4 ] ;
+ if (!getifloatarray(args, 3, 0, 4 * 4 , (float *) arg1))
+ return NULL;
+ if (!getifloatarray(args, 3, 1, 4 * 4 , (float *) arg2))
+ return NULL;
+ if (!getifloatarray(args, 3, 2, 4 * 4 , (float *) arg3))
+ return NULL;
+ patch( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void splf long s float s[3*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 3 ] ;
+ unsigned short * arg3 ;
+ if (!getilongarraysize(args, 2, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (float(*)[3]) PyMem_NEW(float , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 2, 0, 3 * arg1 , (float *) arg2))
+ return NULL;
+ if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+ return NULL;
+ splf( arg1 , arg2 , arg3 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void splf2 long s float s[2*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf2(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float (* arg2) [ 2 ] ;
+ unsigned short * arg3 ;
+ if (!getilongarraysize(args, 2, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (float(*)[2]) PyMem_NEW(float , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 2, 0, 2 * arg1 , (float *) arg2))
+ return NULL;
+ if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+ return NULL;
+ splf2( arg1 , arg2 , arg3 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void splfi long s long s[3*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splfi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long (* arg2) [ 3 ] ;
+ unsigned short * arg3 ;
+ if (!getilongarraysize(args, 2, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (long(*)[3]) PyMem_NEW(long , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getilongarray(args, 2, 0, 3 * arg1 , (long *) arg2))
+ return NULL;
+ if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+ return NULL;
+ splfi( arg1 , arg2 , arg3 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void splf2i long s long s[2*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf2i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long (* arg2) [ 2 ] ;
+ unsigned short * arg3 ;
+ if (!getilongarraysize(args, 2, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (long(*)[2]) PyMem_NEW(long , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getilongarray(args, 2, 0, 2 * arg1 , (long *) arg2))
+ return NULL;
+ if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+ return NULL;
+ splf2i( arg1 , arg2 , arg3 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void splfs long s short s[3*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splfs(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short (* arg2) [ 3 ] ;
+ unsigned short * arg3 ;
+ if (!getilongarraysize(args, 2, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 3;
+ if ((arg2 = (short(*)[3]) PyMem_NEW(short , 3 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 0, 3 * arg1 , (short *) arg2))
+ return NULL;
+ if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+ return NULL;
+ splfs( arg1 , arg2 , arg3 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void splf2s long s short s[2*arg1] u_short s[arg1] */
+
+static PyObject *
+gl_splf2s(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short (* arg2) [ 2 ] ;
+ unsigned short * arg3 ;
+ if (!getilongarraysize(args, 2, 0, &arg1))
+ return NULL;
+ arg1 = arg1 / 2;
+ if ((arg2 = (short(*)[2]) PyMem_NEW(short , 2 * arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 0, 2 * arg1 , (short *) arg2))
+ return NULL;
+ if ((arg3 = PyMem_NEW(unsigned short , arg1 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getishortarray(args, 2, 1, arg1 , (short *) arg3))
+ return NULL;
+ splf2s( arg1 , arg2 , arg3 );
+ PyMem_DEL(arg2);
+ PyMem_DEL(arg3);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rpatch float s[4*4] float s[4*4] float s[4*4] float s[4*4] */
+
+static PyObject *
+gl_rpatch(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] [ 4 ] ;
+ float arg2 [ 4 ] [ 4 ] ;
+ float arg3 [ 4 ] [ 4 ] ;
+ float arg4 [ 4 ] [ 4 ] ;
+ if (!getifloatarray(args, 4, 0, 4 * 4 , (float *) arg1))
+ return NULL;
+ if (!getifloatarray(args, 4, 1, 4 * 4 , (float *) arg2))
+ return NULL;
+ if (!getifloatarray(args, 4, 2, 4 * 4 , (float *) arg3))
+ return NULL;
+ if (!getifloatarray(args, 4, 3, 4 * 4 , (float *) arg4))
+ return NULL;
+ rpatch( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void ortho2 float s float s float s float s */
+
+static PyObject *
+gl_ortho2(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ ortho2( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rect float s float s float s float s */
+
+static PyObject *
+gl_rect(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ rect( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rectf float s float s float s float s */
+
+static PyObject *
+gl_rectf(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ rectf( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt4 float s float s float s float s */
+
+static PyObject *
+gl_xfpt4(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ xfpt4( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void textport short s short s short s short s */
+
+static PyObject *
+gl_textport(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ textport( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void mapcolor short s short s short s short s */
+
+static PyObject *
+gl_mapcolor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ mapcolor( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void scrmask short s short s short s short s */
+
+static PyObject *
+gl_scrmask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ scrmask( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setvaluator short s short s short s short s */
+
+static PyObject *
+gl_setvaluator(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ setvaluator( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void viewport short s short s short s short s */
+
+static PyObject *
+gl_viewport(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ viewport( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void shaderange short s short s short s short s */
+
+static PyObject *
+gl_shaderange(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ shaderange( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt4s short s short s short s short s */
+
+static PyObject *
+gl_xfpt4s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ xfpt4s( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rectfi long s long s long s long s */
+
+static PyObject *
+gl_rectfi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ rectfi( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void recti long s long s long s long s */
+
+static PyObject *
+gl_recti(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ recti( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void xfpt4i long s long s long s long s */
+
+static PyObject *
+gl_xfpt4i(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ xfpt4i( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void prefposition long s long s long s long s */
+
+static PyObject *
+gl_prefposition(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ prefposition( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void arc float s float s float s short s short s */
+
+static PyObject *
+gl_arc(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getifloatarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ arc( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void arcf float s float s float s short s short s */
+
+static PyObject *
+gl_arcf(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getifloatarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ arcf( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void arcfi long s long s long s short s short s */
+
+static PyObject *
+gl_arcfi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getilongarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ arcfi( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void arci long s long s long s short s short s */
+
+static PyObject *
+gl_arci(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getilongarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ arci( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bbox2 short s short s float s float s float s float s */
+
+static PyObject *
+gl_bbox2(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ float arg3 ;
+ float arg4 ;
+ float arg5 ;
+ float arg6 ;
+ if (!getishortarg(args, 6, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 6, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 6, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 6, 3, &arg4))
+ return NULL;
+ if (!getifloatarg(args, 6, 4, &arg5))
+ return NULL;
+ if (!getifloatarg(args, 6, 5, &arg6))
+ return NULL;
+ bbox2( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bbox2i short s short s long s long s long s long s */
+
+static PyObject *
+gl_bbox2i(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ long arg3 ;
+ long arg4 ;
+ long arg5 ;
+ long arg6 ;
+ if (!getishortarg(args, 6, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 6, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 6, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 6, 3, &arg4))
+ return NULL;
+ if (!getilongarg(args, 6, 4, &arg5))
+ return NULL;
+ if (!getilongarg(args, 6, 5, &arg6))
+ return NULL;
+ bbox2i( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bbox2s short s short s short s short s short s short s */
+
+static PyObject *
+gl_bbox2s(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ short arg6 ;
+ if (!getishortarg(args, 6, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 6, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 6, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 6, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 6, 4, &arg5))
+ return NULL;
+ if (!getishortarg(args, 6, 5, &arg6))
+ return NULL;
+ bbox2s( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void blink short s short s short s short s short s */
+
+static PyObject *
+gl_blink(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getishortarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ blink( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void ortho float s float s float s float s float s float s */
+
+static PyObject *
+gl_ortho(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ float arg5 ;
+ float arg6 ;
+ if (!getifloatarg(args, 6, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 6, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 6, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 6, 3, &arg4))
+ return NULL;
+ if (!getifloatarg(args, 6, 4, &arg5))
+ return NULL;
+ if (!getifloatarg(args, 6, 5, &arg6))
+ return NULL;
+ ortho( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void window float s float s float s float s float s float s */
+
+static PyObject *
+gl_window(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ float arg5 ;
+ float arg6 ;
+ if (!getifloatarg(args, 6, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 6, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 6, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 6, 3, &arg4))
+ return NULL;
+ if (!getifloatarg(args, 6, 4, &arg5))
+ return NULL;
+ if (!getifloatarg(args, 6, 5, &arg6))
+ return NULL;
+ window( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lookat float s float s float s float s float s float s short s */
+
+static PyObject *
+gl_lookat(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ float arg5 ;
+ float arg6 ;
+ short arg7 ;
+ if (!getifloatarg(args, 7, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 7, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 7, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 7, 3, &arg4))
+ return NULL;
+ if (!getifloatarg(args, 7, 4, &arg5))
+ return NULL;
+ if (!getifloatarg(args, 7, 5, &arg6))
+ return NULL;
+ if (!getishortarg(args, 7, 6, &arg7))
+ return NULL;
+ lookat( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void perspective short s float s float s float s */
+
+static PyObject *
+gl_perspective(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ perspective( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void polarview float s short s short s short s */
+
+static PyObject *
+gl_polarview(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ polarview( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void arcfs short s short s short s short s short s */
+
+static PyObject *
+gl_arcfs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getishortarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ arcfs( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void arcs short s short s short s short s short s */
+
+static PyObject *
+gl_arcs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ if (!getishortarg(args, 5, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 5, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 5, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 5, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 5, 4, &arg5))
+ return NULL;
+ arcs( arg1 , arg2 , arg3 , arg4 , arg5 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rectcopy short s short s short s short s short s short s */
+
+static PyObject *
+gl_rectcopy(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ short arg6 ;
+ if (!getishortarg(args, 6, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 6, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 6, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 6, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 6, 4, &arg5))
+ return NULL;
+ if (!getishortarg(args, 6, 5, &arg6))
+ return NULL;
+ rectcopy( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void RGBcursor short s short s short s short s short s short s short s */
+
+static PyObject *
+gl_RGBcursor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ short arg6 ;
+ short arg7 ;
+ if (!getishortarg(args, 7, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 7, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 7, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 7, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 7, 4, &arg5))
+ return NULL;
+ if (!getishortarg(args, 7, 5, &arg6))
+ return NULL;
+ if (!getishortarg(args, 7, 6, &arg7))
+ return NULL;
+ RGBcursor( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long getbutton short s */
+
+static PyObject *
+gl_getbutton(PyObject *self, PyObject *args)
+{
+ long retval;
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = getbutton( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* long getcmmode */
+
+static PyObject *
+gl_getcmmode(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getcmmode( );
+ return mknewlongobject(retval);
+}
+
+/* long getlsbackup */
+
+static PyObject *
+gl_getlsbackup(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getlsbackup( );
+ return mknewlongobject(retval);
+}
+
+/* long getresetls */
+
+static PyObject *
+gl_getresetls(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getresetls( );
+ return mknewlongobject(retval);
+}
+
+/* long getdcm */
+
+static PyObject *
+gl_getdcm(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getdcm( );
+ return mknewlongobject(retval);
+}
+
+/* long getzbuffer */
+
+static PyObject *
+gl_getzbuffer(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getzbuffer( );
+ return mknewlongobject(retval);
+}
+
+/* long ismex */
+
+static PyObject *
+gl_ismex(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = ismex( );
+ return mknewlongobject(retval);
+}
+
+/* long isobj long s */
+
+static PyObject *
+gl_isobj(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = isobj( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* long isqueued short s */
+
+static PyObject *
+gl_isqueued(PyObject *self, PyObject *args)
+{
+ long retval;
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = isqueued( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* long istag long s */
+
+static PyObject *
+gl_istag(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = istag( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* long genobj */
+
+static PyObject *
+gl_genobj(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = genobj( );
+ return mknewlongobject(retval);
+}
+
+/* long gentag */
+
+static PyObject *
+gl_gentag(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = gentag( );
+ return mknewlongobject(retval);
+}
+
+/* long getbuffer */
+
+static PyObject *
+gl_getbuffer(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getbuffer( );
+ return mknewlongobject(retval);
+}
+
+/* long getcolor */
+
+static PyObject *
+gl_getcolor(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getcolor( );
+ return mknewlongobject(retval);
+}
+
+/* long getdisplaymode */
+
+static PyObject *
+gl_getdisplaymode(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getdisplaymode( );
+ return mknewlongobject(retval);
+}
+
+/* long getfont */
+
+static PyObject *
+gl_getfont(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getfont( );
+ return mknewlongobject(retval);
+}
+
+/* long getheight */
+
+static PyObject *
+gl_getheight(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getheight( );
+ return mknewlongobject(retval);
+}
+
+/* long gethitcode */
+
+static PyObject *
+gl_gethitcode(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = gethitcode( );
+ return mknewlongobject(retval);
+}
+
+/* long getlstyle */
+
+static PyObject *
+gl_getlstyle(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getlstyle( );
+ return mknewlongobject(retval);
+}
+
+/* long getlwidth */
+
+static PyObject *
+gl_getlwidth(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getlwidth( );
+ return mknewlongobject(retval);
+}
+
+/* long getmap */
+
+static PyObject *
+gl_getmap(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getmap( );
+ return mknewlongobject(retval);
+}
+
+/* long getplanes */
+
+static PyObject *
+gl_getplanes(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getplanes( );
+ return mknewlongobject(retval);
+}
+
+/* long getwritemask */
+
+static PyObject *
+gl_getwritemask(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getwritemask( );
+ return mknewlongobject(retval);
+}
+
+/* long qtest */
+
+static PyObject *
+gl_qtest(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = qtest( );
+ return mknewlongobject(retval);
+}
+
+/* long getlsrepeat */
+
+static PyObject *
+gl_getlsrepeat(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getlsrepeat( );
+ return mknewlongobject(retval);
+}
+
+/* long getmonitor */
+
+static PyObject *
+gl_getmonitor(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getmonitor( );
+ return mknewlongobject(retval);
+}
+
+/* long getopenobj */
+
+static PyObject *
+gl_getopenobj(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getopenobj( );
+ return mknewlongobject(retval);
+}
+
+/* long getpattern */
+
+static PyObject *
+gl_getpattern(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getpattern( );
+ return mknewlongobject(retval);
+}
+
+/* long winget */
+
+static PyObject *
+gl_winget(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = winget( );
+ return mknewlongobject(retval);
+}
+
+/* long winattach */
+
+static PyObject *
+gl_winattach(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = winattach( );
+ return mknewlongobject(retval);
+}
+
+/* long getothermonitor */
+
+static PyObject *
+gl_getothermonitor(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getothermonitor( );
+ return mknewlongobject(retval);
+}
+
+/* long newpup */
+
+static PyObject *
+gl_newpup(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = newpup( );
+ return mknewlongobject(retval);
+}
+
+/* long getvaluator short s */
+
+static PyObject *
+gl_getvaluator(PyObject *self, PyObject *args)
+{
+ long retval;
+ short arg1 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = getvaluator( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void winset long s */
+
+static PyObject *
+gl_winset(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ winset( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long dopup long s */
+
+static PyObject *
+gl_dopup(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = dopup( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void getdepth short r short r */
+
+static PyObject *
+gl_getdepth(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ getdepth( & arg1 , & arg2 );
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ return v;
+ }
+}
+
+/* void getcpos short r short r */
+
+static PyObject *
+gl_getcpos(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ getcpos( & arg1 , & arg2 );
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ return v;
+ }
+}
+
+/* void getsize long r long r */
+
+static PyObject *
+gl_getsize(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ getsize( & arg1 , & arg2 );
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewlongobject(arg1));
+ PyTuple_SetItem(v, 1, mknewlongobject(arg2));
+ return v;
+ }
+}
+
+/* void getorigin long r long r */
+
+static PyObject *
+gl_getorigin(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ getorigin( & arg1 , & arg2 );
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewlongobject(arg1));
+ PyTuple_SetItem(v, 1, mknewlongobject(arg2));
+ return v;
+ }
+}
+
+/* void getviewport short r short r short r short r */
+
+static PyObject *
+gl_getviewport(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ getviewport( & arg1 , & arg2 , & arg3 , & arg4 );
+ { PyObject *v = PyTuple_New( 4 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+ PyTuple_SetItem(v, 3, mknewshortobject(arg4));
+ return v;
+ }
+}
+
+/* void gettp short r short r short r short r */
+
+static PyObject *
+gl_gettp(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ gettp( & arg1 , & arg2 , & arg3 , & arg4 );
+ { PyObject *v = PyTuple_New( 4 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+ PyTuple_SetItem(v, 3, mknewshortobject(arg4));
+ return v;
+ }
+}
+
+/* void getgpos float r float r float r float r */
+
+static PyObject *
+gl_getgpos(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ getgpos( & arg1 , & arg2 , & arg3 , & arg4 );
+ { PyObject *v = PyTuple_New( 4 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewfloatobject(arg1));
+ PyTuple_SetItem(v, 1, mknewfloatobject(arg2));
+ PyTuple_SetItem(v, 2, mknewfloatobject(arg3));
+ PyTuple_SetItem(v, 3, mknewfloatobject(arg4));
+ return v;
+ }
+}
+
+/* void winposition long s long s long s long s */
+
+static PyObject *
+gl_winposition(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ winposition( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gRGBcolor short r short r short r */
+
+static PyObject *
+gl_gRGBcolor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ gRGBcolor( & arg1 , & arg2 , & arg3 );
+ { PyObject *v = PyTuple_New( 3 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+ return v;
+ }
+}
+
+/* void gRGBmask short r short r short r */
+
+static PyObject *
+gl_gRGBmask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ gRGBmask( & arg1 , & arg2 , & arg3 );
+ { PyObject *v = PyTuple_New( 3 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+ return v;
+ }
+}
+
+/* void getscrmask short r short r short r short r */
+
+static PyObject *
+gl_getscrmask(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ getscrmask( & arg1 , & arg2 , & arg3 , & arg4 );
+ { PyObject *v = PyTuple_New( 4 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg2));
+ PyTuple_SetItem(v, 2, mknewshortobject(arg3));
+ PyTuple_SetItem(v, 3, mknewshortobject(arg4));
+ return v;
+ }
+}
+
+/* void getmcolor short s short r short r short r */
+
+static PyObject *
+gl_getmcolor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 1, 0, &arg1))
+ return NULL;
+ getmcolor( arg1 , & arg2 , & arg3 , & arg4 );
+ { PyObject *v = PyTuple_New( 3 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg2));
+ PyTuple_SetItem(v, 1, mknewshortobject(arg3));
+ PyTuple_SetItem(v, 2, mknewshortobject(arg4));
+ return v;
+ }
+}
+
+/* void mapw long s short s short s float r float r float r float r float r float r */
+
+static PyObject *
+gl_mapw(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short arg2 ;
+ short arg3 ;
+ float arg4 ;
+ float arg5 ;
+ float arg6 ;
+ float arg7 ;
+ float arg8 ;
+ float arg9 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ mapw( arg1 , arg2 , arg3 , & arg4 , & arg5 , & arg6 , & arg7 , & arg8 , & arg9 );
+ { PyObject *v = PyTuple_New( 6 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewfloatobject(arg4));
+ PyTuple_SetItem(v, 1, mknewfloatobject(arg5));
+ PyTuple_SetItem(v, 2, mknewfloatobject(arg6));
+ PyTuple_SetItem(v, 3, mknewfloatobject(arg7));
+ PyTuple_SetItem(v, 4, mknewfloatobject(arg8));
+ PyTuple_SetItem(v, 5, mknewfloatobject(arg9));
+ return v;
+ }
+}
+
+/* void mapw2 long s short s short s float r float r */
+
+static PyObject *
+gl_mapw2(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ short arg2 ;
+ short arg3 ;
+ float arg4 ;
+ float arg5 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 3, 2, &arg3))
+ return NULL;
+ mapw2( arg1 , arg2 , arg3 , & arg4 , & arg5 );
+ { PyObject *v = PyTuple_New( 2 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewfloatobject(arg4));
+ PyTuple_SetItem(v, 1, mknewfloatobject(arg5));
+ return v;
+ }
+}
+
+/* void getcursor short r u_short r u_short r long r */
+
+static PyObject *
+gl_getcursor(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ unsigned short arg2 ;
+ unsigned short arg3 ;
+ long arg4 ;
+ getcursor( & arg1 , & arg2 , & arg3 , & arg4 );
+ { PyObject *v = PyTuple_New( 4 );
+ if (v == NULL) return NULL;
+ PyTuple_SetItem(v, 0, mknewshortobject(arg1));
+ PyTuple_SetItem(v, 1, mknewshortobject((short) arg2));
+ PyTuple_SetItem(v, 2, mknewshortobject((short) arg3));
+ PyTuple_SetItem(v, 3, mknewlongobject(arg4));
+ return v;
+ }
+}
+
+/* void cmode */
+
+static PyObject *
+gl_cmode(PyObject *self, PyObject *args)
+{
+ cmode( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void concave long s */
+
+static PyObject *
+gl_concave(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ concave( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void curstype long s */
+
+static PyObject *
+gl_curstype(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ curstype( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void drawmode long s */
+
+static PyObject *
+gl_drawmode(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ drawmode( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void gammaramp short s[256] short s[256] short s[256] */
+
+static PyObject *
+gl_gammaramp(PyObject *self, PyObject *args)
+{
+ short arg1 [ 256 ] ;
+ short arg2 [ 256 ] ;
+ short arg3 [ 256 ] ;
+ if (!getishortarray(args, 3, 0, 256 , arg1))
+ return NULL;
+ if (!getishortarray(args, 3, 1, 256 , arg2))
+ return NULL;
+ if (!getishortarray(args, 3, 2, 256 , arg3))
+ return NULL;
+ gammaramp( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long getbackface */
+
+static PyObject *
+gl_getbackface(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getbackface( );
+ return mknewlongobject(retval);
+}
+
+/* long getdescender */
+
+static PyObject *
+gl_getdescender(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getdescender( );
+ return mknewlongobject(retval);
+}
+
+/* long getdrawmode */
+
+static PyObject *
+gl_getdrawmode(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getdrawmode( );
+ return mknewlongobject(retval);
+}
+
+/* long getmmode */
+
+static PyObject *
+gl_getmmode(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getmmode( );
+ return mknewlongobject(retval);
+}
+
+/* long getsm */
+
+static PyObject *
+gl_getsm(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = getsm( );
+ return mknewlongobject(retval);
+}
+
+/* long getvideo long s */
+
+static PyObject *
+gl_getvideo(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = getvideo( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void imakebackground */
+
+static PyObject *
+gl_imakebackground(PyObject *self, PyObject *args)
+{
+ imakebackground( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lmbind short s short s */
+
+static PyObject *
+gl_lmbind(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ if (!getishortarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 2, 1, &arg2))
+ return NULL;
+ lmbind( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lmdef long s long s long s float s[arg3] */
+
+static PyObject *
+gl_lmdef(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ float * arg4 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarraysize(args, 3, 2, &arg3))
+ return NULL;
+ if ((arg4 = PyMem_NEW(float , arg3 )) == NULL)
+ return PyErr_NoMemory();
+ if (!getifloatarray(args, 3, 2, arg3 , arg4))
+ return NULL;
+ lmdef( arg1 , arg2 , arg3 , arg4 );
+ PyMem_DEL(arg4);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void mmode long s */
+
+static PyObject *
+gl_mmode(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ mmode( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void normal float s[3] */
+
+static PyObject *
+gl_normal(PyObject *self, PyObject *args)
+{
+ float arg1 [ 3 ] ;
+ if (!getifloatarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ normal( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void overlay long s */
+
+static PyObject *
+gl_overlay(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ overlay( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void RGBrange short s short s short s short s short s short s short s short s */
+
+static PyObject *
+gl_RGBrange(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ short arg6 ;
+ short arg7 ;
+ short arg8 ;
+ if (!getishortarg(args, 8, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 8, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 8, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 8, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 8, 4, &arg5))
+ return NULL;
+ if (!getishortarg(args, 8, 5, &arg6))
+ return NULL;
+ if (!getishortarg(args, 8, 6, &arg7))
+ return NULL;
+ if (!getishortarg(args, 8, 7, &arg8))
+ return NULL;
+ RGBrange( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setvideo long s long s */
+
+static PyObject *
+gl_setvideo(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ setvideo( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void shademodel long s */
+
+static PyObject *
+gl_shademodel(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ shademodel( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void underlay long s */
+
+static PyObject *
+gl_underlay(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ underlay( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgnclosedline */
+
+static PyObject *
+gl_bgnclosedline(PyObject *self, PyObject *args)
+{
+ bgnclosedline( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgnline */
+
+static PyObject *
+gl_bgnline(PyObject *self, PyObject *args)
+{
+ bgnline( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgnpoint */
+
+static PyObject *
+gl_bgnpoint(PyObject *self, PyObject *args)
+{
+ bgnpoint( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgnpolygon */
+
+static PyObject *
+gl_bgnpolygon(PyObject *self, PyObject *args)
+{
+ bgnpolygon( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgnsurface */
+
+static PyObject *
+gl_bgnsurface(PyObject *self, PyObject *args)
+{
+ bgnsurface( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgntmesh */
+
+static PyObject *
+gl_bgntmesh(PyObject *self, PyObject *args)
+{
+ bgntmesh( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void bgntrim */
+
+static PyObject *
+gl_bgntrim(PyObject *self, PyObject *args)
+{
+ bgntrim( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endclosedline */
+
+static PyObject *
+gl_endclosedline(PyObject *self, PyObject *args)
+{
+ endclosedline( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endline */
+
+static PyObject *
+gl_endline(PyObject *self, PyObject *args)
+{
+ endline( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endpoint */
+
+static PyObject *
+gl_endpoint(PyObject *self, PyObject *args)
+{
+ endpoint( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endpolygon */
+
+static PyObject *
+gl_endpolygon(PyObject *self, PyObject *args)
+{
+ endpolygon( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endsurface */
+
+static PyObject *
+gl_endsurface(PyObject *self, PyObject *args)
+{
+ endsurface( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endtmesh */
+
+static PyObject *
+gl_endtmesh(PyObject *self, PyObject *args)
+{
+ endtmesh( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void endtrim */
+
+static PyObject *
+gl_endtrim(PyObject *self, PyObject *args)
+{
+ endtrim( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void blendfunction long s long s */
+
+static PyObject *
+gl_blendfunction(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ blendfunction( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void c3f float s[3] */
+
+static PyObject *
+gl_c3f(PyObject *self, PyObject *args)
+{
+ float arg1 [ 3 ] ;
+ if (!getifloatarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ c3f( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void c3i long s[3] */
+
+static PyObject *
+gl_c3i(PyObject *self, PyObject *args)
+{
+ long arg1 [ 3 ] ;
+ if (!getilongarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ c3i( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void c3s short s[3] */
+
+static PyObject *
+gl_c3s(PyObject *self, PyObject *args)
+{
+ short arg1 [ 3 ] ;
+ if (!getishortarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ c3s( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void c4f float s[4] */
+
+static PyObject *
+gl_c4f(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] ;
+ if (!getifloatarray(args, 1, 0, 4 , arg1))
+ return NULL;
+ c4f( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void c4i long s[4] */
+
+static PyObject *
+gl_c4i(PyObject *self, PyObject *args)
+{
+ long arg1 [ 4 ] ;
+ if (!getilongarray(args, 1, 0, 4 , arg1))
+ return NULL;
+ c4i( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void c4s short s[4] */
+
+static PyObject *
+gl_c4s(PyObject *self, PyObject *args)
+{
+ short arg1 [ 4 ] ;
+ if (!getishortarray(args, 1, 0, 4 , arg1))
+ return NULL;
+ c4s( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void colorf float s */
+
+static PyObject *
+gl_colorf(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ if (!getifloatarg(args, 1, 0, &arg1))
+ return NULL;
+ colorf( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void cpack long s */
+
+static PyObject *
+gl_cpack(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ cpack( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void czclear long s long s */
+
+static PyObject *
+gl_czclear(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ czclear( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void dglclose long s */
+
+static PyObject *
+gl_dglclose(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ dglclose( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long dglopen char *s long s */
+
+static PyObject *
+gl_dglopen(PyObject *self, PyObject *args)
+{
+ long retval;
+ string arg1 ;
+ long arg2 ;
+ if (!getistringarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ retval = dglopen( arg1 , arg2 );
+ return mknewlongobject(retval);
+}
+
+/* long getgdesc long s */
+
+static PyObject *
+gl_getgdesc(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = getgdesc( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void getnurbsproperty long s float r */
+
+static PyObject *
+gl_getnurbsproperty(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float arg2 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ getnurbsproperty( arg1 , & arg2 );
+ return mknewfloatobject(arg2);
+}
+
+/* void glcompat long s long s */
+
+static PyObject *
+gl_glcompat(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ glcompat( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void iconsize long s long s */
+
+static PyObject *
+gl_iconsize(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ iconsize( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void icontitle char *s */
+
+static PyObject *
+gl_icontitle(PyObject *self, PyObject *args)
+{
+ string arg1 ;
+ if (!getistringarg(args, 1, 0, &arg1))
+ return NULL;
+ icontitle( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lRGBrange short s short s short s short s short s short s long s long s */
+
+static PyObject *
+gl_lRGBrange(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ short arg5 ;
+ short arg6 ;
+ long arg7 ;
+ long arg8 ;
+ if (!getishortarg(args, 8, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 8, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 8, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 8, 3, &arg4))
+ return NULL;
+ if (!getishortarg(args, 8, 4, &arg5))
+ return NULL;
+ if (!getishortarg(args, 8, 5, &arg6))
+ return NULL;
+ if (!getilongarg(args, 8, 6, &arg7))
+ return NULL;
+ if (!getilongarg(args, 8, 7, &arg8))
+ return NULL;
+ lRGBrange( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void linesmooth long s */
+
+static PyObject *
+gl_linesmooth(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ linesmooth( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lmcolor long s */
+
+static PyObject *
+gl_lmcolor(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ lmcolor( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void logicop long s */
+
+static PyObject *
+gl_logicop(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ logicop( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lsetdepth long s long s */
+
+static PyObject *
+gl_lsetdepth(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ lsetdepth( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void lshaderange short s short s long s long s */
+
+static PyObject *
+gl_lshaderange(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ lshaderange( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void n3f float s[3] */
+
+static PyObject *
+gl_n3f(PyObject *self, PyObject *args)
+{
+ float arg1 [ 3 ] ;
+ if (!getifloatarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ n3f( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void noborder */
+
+static PyObject *
+gl_noborder(PyObject *self, PyObject *args)
+{
+ noborder( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pntsmooth long s */
+
+static PyObject *
+gl_pntsmooth(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ pntsmooth( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void readsource long s */
+
+static PyObject *
+gl_readsource(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ readsource( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void rectzoom float s float s */
+
+static PyObject *
+gl_rectzoom(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ if (!getifloatarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ rectzoom( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void sbox float s float s float s float s */
+
+static PyObject *
+gl_sbox(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ sbox( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void sboxi long s long s long s long s */
+
+static PyObject *
+gl_sboxi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ sboxi( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void sboxs short s short s short s short s */
+
+static PyObject *
+gl_sboxs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ sboxs( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void sboxf float s float s float s float s */
+
+static PyObject *
+gl_sboxf(PyObject *self, PyObject *args)
+{
+ float arg1 ;
+ float arg2 ;
+ float arg3 ;
+ float arg4 ;
+ if (!getifloatarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getifloatarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getifloatarg(args, 4, 3, &arg4))
+ return NULL;
+ sboxf( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void sboxfi long s long s long s long s */
+
+static PyObject *
+gl_sboxfi(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ long arg4 ;
+ if (!getilongarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getilongarg(args, 4, 3, &arg4))
+ return NULL;
+ sboxfi( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void sboxfs short s short s short s short s */
+
+static PyObject *
+gl_sboxfs(PyObject *self, PyObject *args)
+{
+ short arg1 ;
+ short arg2 ;
+ short arg3 ;
+ short arg4 ;
+ if (!getishortarg(args, 4, 0, &arg1))
+ return NULL;
+ if (!getishortarg(args, 4, 1, &arg2))
+ return NULL;
+ if (!getishortarg(args, 4, 2, &arg3))
+ return NULL;
+ if (!getishortarg(args, 4, 3, &arg4))
+ return NULL;
+ sboxfs( arg1 , arg2 , arg3 , arg4 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setnurbsproperty long s float s */
+
+static PyObject *
+gl_setnurbsproperty(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ float arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getifloatarg(args, 2, 1, &arg2))
+ return NULL;
+ setnurbsproperty( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void setpup long s long s long s */
+
+static PyObject *
+gl_setpup(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ long arg3 ;
+ if (!getilongarg(args, 3, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 3, 1, &arg2))
+ return NULL;
+ if (!getilongarg(args, 3, 2, &arg3))
+ return NULL;
+ setpup( arg1 , arg2 , arg3 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void smoothline long s */
+
+static PyObject *
+gl_smoothline(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ smoothline( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void subpixel long s */
+
+static PyObject *
+gl_subpixel(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ subpixel( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void swaptmesh */
+
+static PyObject *
+gl_swaptmesh(PyObject *self, PyObject *args)
+{
+ swaptmesh( );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long swinopen long s */
+
+static PyObject *
+gl_swinopen(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = swinopen( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void v2f float s[2] */
+
+static PyObject *
+gl_v2f(PyObject *self, PyObject *args)
+{
+ float arg1 [ 2 ] ;
+ if (!getifloatarray(args, 1, 0, 2 , arg1))
+ return NULL;
+ v2f( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v2i long s[2] */
+
+static PyObject *
+gl_v2i(PyObject *self, PyObject *args)
+{
+ long arg1 [ 2 ] ;
+ if (!getilongarray(args, 1, 0, 2 , arg1))
+ return NULL;
+ v2i( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v2s short s[2] */
+
+static PyObject *
+gl_v2s(PyObject *self, PyObject *args)
+{
+ short arg1 [ 2 ] ;
+ if (!getishortarray(args, 1, 0, 2 , arg1))
+ return NULL;
+ v2s( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v3f float s[3] */
+
+static PyObject *
+gl_v3f(PyObject *self, PyObject *args)
+{
+ float arg1 [ 3 ] ;
+ if (!getifloatarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ v3f( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v3i long s[3] */
+
+static PyObject *
+gl_v3i(PyObject *self, PyObject *args)
+{
+ long arg1 [ 3 ] ;
+ if (!getilongarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ v3i( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v3s short s[3] */
+
+static PyObject *
+gl_v3s(PyObject *self, PyObject *args)
+{
+ short arg1 [ 3 ] ;
+ if (!getishortarray(args, 1, 0, 3 , arg1))
+ return NULL;
+ v3s( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v4f float s[4] */
+
+static PyObject *
+gl_v4f(PyObject *self, PyObject *args)
+{
+ float arg1 [ 4 ] ;
+ if (!getifloatarray(args, 1, 0, 4 , arg1))
+ return NULL;
+ v4f( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v4i long s[4] */
+
+static PyObject *
+gl_v4i(PyObject *self, PyObject *args)
+{
+ long arg1 [ 4 ] ;
+ if (!getilongarray(args, 1, 0, 4 , arg1))
+ return NULL;
+ v4i( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v4s short s[4] */
+
+static PyObject *
+gl_v4s(PyObject *self, PyObject *args)
+{
+ short arg1 [ 4 ] ;
+ if (!getishortarray(args, 1, 0, 4 , arg1))
+ return NULL;
+ v4s( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void videocmd long s */
+
+static PyObject *
+gl_videocmd(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ videocmd( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long windepth long s */
+
+static PyObject *
+gl_windepth(PyObject *self, PyObject *args)
+{
+ long retval;
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ retval = windepth( arg1 );
+ return mknewlongobject(retval);
+}
+
+/* void wmpack long s */
+
+static PyObject *
+gl_wmpack(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ wmpack( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void zdraw long s */
+
+static PyObject *
+gl_zdraw(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ zdraw( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void zfunction long s */
+
+static PyObject *
+gl_zfunction(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ zfunction( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void zsource long s */
+
+static PyObject *
+gl_zsource(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ zsource( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void zwritemask long s */
+
+static PyObject *
+gl_zwritemask(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ zwritemask( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v2d double s[2] */
+
+static PyObject *
+gl_v2d(PyObject *self, PyObject *args)
+{
+ double arg1 [ 2 ] ;
+ if (!getidoublearray(args, 1, 0, 2 , arg1))
+ return NULL;
+ v2d( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v3d double s[3] */
+
+static PyObject *
+gl_v3d(PyObject *self, PyObject *args)
+{
+ double arg1 [ 3 ] ;
+ if (!getidoublearray(args, 1, 0, 3 , arg1))
+ return NULL;
+ v3d( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void v4d double s[4] */
+
+static PyObject *
+gl_v4d(PyObject *self, PyObject *args)
+{
+ double arg1 [ 4 ] ;
+ if (!getidoublearray(args, 1, 0, 4 , arg1))
+ return NULL;
+ v4d( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* void pixmode long s long s */
+
+static PyObject *
+gl_pixmode(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ long arg2 ;
+ if (!getilongarg(args, 2, 0, &arg1))
+ return NULL;
+ if (!getilongarg(args, 2, 1, &arg2))
+ return NULL;
+ pixmode( arg1 , arg2 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* long qgetfd */
+
+static PyObject *
+gl_qgetfd(PyObject *self, PyObject *args)
+{
+ long retval;
+ retval = qgetfd( );
+ return mknewlongobject(retval);
+}
+
+/* void dither long s */
+
+static PyObject *
+gl_dither(PyObject *self, PyObject *args)
+{
+ long arg1 ;
+ if (!getilongarg(args, 1, 0, &arg1))
+ return NULL;
+ dither( arg1 );
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static struct PyMethodDef gl_methods[] = {
+ {"qread", gl_qread, METH_OLDARGS},
+ {"varray", gl_varray, METH_OLDARGS},
+ {"nvarray", gl_nvarray, METH_OLDARGS},
+ {"vnarray", gl_vnarray, METH_OLDARGS},
+ {"nurbssurface", gl_nurbssurface, METH_OLDARGS},
+ {"nurbscurve", gl_nurbscurve, METH_OLDARGS},
+ {"pwlcurve", gl_pwlcurve, METH_OLDARGS},
+ {"pick", gl_pick, METH_OLDARGS},
+ {"endpick", gl_endpick, METH_NOARGS},
+ {"gselect", gl_gselect, METH_OLDARGS},
+ {"endselect", gl_endselect, METH_NOARGS},
+ {"getmatrix", gl_getmatrix, METH_OLDARGS},
+ {"altgetmatrix", gl_altgetmatrix, METH_OLDARGS},
+ {"lrectwrite", gl_lrectwrite, METH_OLDARGS},
+ {"lrectread", gl_lrectread, METH_OLDARGS},
+ {"readdisplay", gl_readdisplay, METH_OLDARGS},
+ {"packrect", gl_packrect, METH_OLDARGS},
+ {"unpackrect", gl_unpackrect, METH_OLDARGS},
+ {"gversion", gl_gversion, METH_OLDARGS},
+ {"clear", gl_clear, METH_OLDARGS},
+ {"getshade", gl_getshade, METH_OLDARGS},
+ {"devport", gl_devport, METH_OLDARGS},
+ {"rdr2i", gl_rdr2i, METH_OLDARGS},
+ {"rectfs", gl_rectfs, METH_OLDARGS},
+ {"rects", gl_rects, METH_OLDARGS},
+ {"rmv2i", gl_rmv2i, METH_OLDARGS},
+ {"noport", gl_noport, METH_OLDARGS},
+ {"popviewport", gl_popviewport, METH_OLDARGS},
+ {"clearhitcode", gl_clearhitcode, METH_OLDARGS},
+ {"closeobj", gl_closeobj, METH_OLDARGS},
+ {"cursoff", gl_cursoff, METH_OLDARGS},
+ {"curson", gl_curson, METH_OLDARGS},
+ {"doublebuffer", gl_doublebuffer, METH_OLDARGS},
+ {"finish", gl_finish, METH_OLDARGS},
+ {"gconfig", gl_gconfig, METH_OLDARGS},
+ {"ginit", gl_ginit, METH_OLDARGS},
+ {"greset", gl_greset, METH_OLDARGS},
+ {"multimap", gl_multimap, METH_OLDARGS},
+ {"onemap", gl_onemap, METH_OLDARGS},
+ {"popattributes", gl_popattributes, METH_OLDARGS},
+ {"popmatrix", gl_popmatrix, METH_OLDARGS},
+ {"pushattributes", gl_pushattributes,METH_OLDARGS},
+ {"pushmatrix", gl_pushmatrix, METH_OLDARGS},
+ {"pushviewport", gl_pushviewport, METH_OLDARGS},
+ {"qreset", gl_qreset, METH_OLDARGS},
+ {"RGBmode", gl_RGBmode, METH_OLDARGS},
+ {"singlebuffer", gl_singlebuffer, METH_OLDARGS},
+ {"swapbuffers", gl_swapbuffers, METH_OLDARGS},
+ {"gsync", gl_gsync, METH_OLDARGS},
+ {"gflush", gl_gflush, METH_OLDARGS},
+ {"tpon", gl_tpon, METH_OLDARGS},
+ {"tpoff", gl_tpoff, METH_OLDARGS},
+ {"clkon", gl_clkon, METH_OLDARGS},
+ {"clkoff", gl_clkoff, METH_OLDARGS},
+ {"ringbell", gl_ringbell, METH_OLDARGS},
+ {"gbegin", gl_gbegin, METH_OLDARGS},
+ {"textinit", gl_textinit, METH_OLDARGS},
+ {"initnames", gl_initnames, METH_OLDARGS},
+ {"pclos", gl_pclos, METH_OLDARGS},
+ {"popname", gl_popname, METH_OLDARGS},
+ {"spclos", gl_spclos, METH_OLDARGS},
+ {"zclear", gl_zclear, METH_OLDARGS},
+ {"screenspace", gl_screenspace, METH_OLDARGS},
+ {"reshapeviewport", gl_reshapeviewport, METH_OLDARGS},
+ {"winpush", gl_winpush, METH_OLDARGS},
+ {"winpop", gl_winpop, METH_OLDARGS},
+ {"foreground", gl_foreground, METH_OLDARGS},
+ {"endfullscrn", gl_endfullscrn, METH_OLDARGS},
+ {"endpupmode", gl_endpupmode, METH_OLDARGS},
+ {"fullscrn", gl_fullscrn, METH_OLDARGS},
+ {"pupmode", gl_pupmode, METH_OLDARGS},
+ {"winconstraints", gl_winconstraints, METH_OLDARGS},
+ {"pagecolor", gl_pagecolor, METH_OLDARGS},
+ {"textcolor", gl_textcolor, METH_OLDARGS},
+ {"color", gl_color, METH_OLDARGS},
+ {"curveit", gl_curveit, METH_OLDARGS},
+ {"font", gl_font, METH_OLDARGS},
+ {"linewidth", gl_linewidth, METH_OLDARGS},
+ {"setlinestyle", gl_setlinestyle, METH_OLDARGS},
+ {"setmap", gl_setmap, METH_OLDARGS},
+ {"swapinterval", gl_swapinterval, METH_OLDARGS},
+ {"writemask", gl_writemask, METH_OLDARGS},
+ {"textwritemask", gl_textwritemask, METH_OLDARGS},
+ {"qdevice", gl_qdevice, METH_OLDARGS},
+ {"unqdevice", gl_unqdevice, METH_OLDARGS},
+ {"curvebasis", gl_curvebasis, METH_OLDARGS},
+ {"curveprecision", gl_curveprecision,METH_OLDARGS},
+ {"loadname", gl_loadname, METH_OLDARGS},
+ {"passthrough", gl_passthrough, METH_OLDARGS},
+ {"pushname", gl_pushname, METH_OLDARGS},
+ {"setmonitor", gl_setmonitor, METH_OLDARGS},
+ {"setshade", gl_setshade, METH_OLDARGS},
+ {"setpattern", gl_setpattern, METH_OLDARGS},
+ {"pagewritemask", gl_pagewritemask, METH_OLDARGS},
+ {"callobj", gl_callobj, METH_OLDARGS},
+ {"delobj", gl_delobj, METH_OLDARGS},
+ {"editobj", gl_editobj, METH_OLDARGS},
+ {"makeobj", gl_makeobj, METH_OLDARGS},
+ {"maketag", gl_maketag, METH_OLDARGS},
+ {"chunksize", gl_chunksize, METH_OLDARGS},
+ {"compactify", gl_compactify, METH_OLDARGS},
+ {"deltag", gl_deltag, METH_OLDARGS},
+ {"lsrepeat", gl_lsrepeat, METH_OLDARGS},
+ {"objinsert", gl_objinsert, METH_OLDARGS},
+ {"objreplace", gl_objreplace, METH_OLDARGS},
+ {"winclose", gl_winclose, METH_OLDARGS},
+ {"blanktime", gl_blanktime, METH_OLDARGS},
+ {"freepup", gl_freepup, METH_OLDARGS},
+ {"backbuffer", gl_backbuffer, METH_OLDARGS},
+ {"frontbuffer", gl_frontbuffer, METH_OLDARGS},
+ {"lsbackup", gl_lsbackup, METH_OLDARGS},
+ {"resetls", gl_resetls, METH_OLDARGS},
+ {"lampon", gl_lampon, METH_OLDARGS},
+ {"lampoff", gl_lampoff, METH_OLDARGS},
+ {"setbell", gl_setbell, METH_OLDARGS},
+ {"blankscreen", gl_blankscreen, METH_OLDARGS},
+ {"depthcue", gl_depthcue, METH_OLDARGS},
+ {"zbuffer", gl_zbuffer, METH_OLDARGS},
+ {"backface", gl_backface, METH_OLDARGS},
+ {"cmov2i", gl_cmov2i, METH_OLDARGS},
+ {"draw2i", gl_draw2i, METH_OLDARGS},
+ {"move2i", gl_move2i, METH_OLDARGS},
+ {"pnt2i", gl_pnt2i, METH_OLDARGS},
+ {"patchbasis", gl_patchbasis, METH_OLDARGS},
+ {"patchprecision", gl_patchprecision, METH_OLDARGS},
+ {"pdr2i", gl_pdr2i, METH_OLDARGS},
+ {"pmv2i", gl_pmv2i, METH_OLDARGS},
+ {"rpdr2i", gl_rpdr2i, METH_OLDARGS},
+ {"rpmv2i", gl_rpmv2i, METH_OLDARGS},
+ {"xfpt2i", gl_xfpt2i, METH_OLDARGS},
+ {"objdelete", gl_objdelete, METH_OLDARGS},
+ {"patchcurves", gl_patchcurves, METH_OLDARGS},
+ {"minsize", gl_minsize, METH_OLDARGS},
+ {"maxsize", gl_maxsize, METH_OLDARGS},
+ {"keepaspect", gl_keepaspect, METH_OLDARGS},
+ {"prefsize", gl_prefsize, METH_OLDARGS},
+ {"stepunit", gl_stepunit, METH_OLDARGS},
+ {"fudge", gl_fudge, METH_OLDARGS},
+ {"winmove", gl_winmove, METH_OLDARGS},
+ {"attachcursor", gl_attachcursor, METH_OLDARGS},
+ {"deflinestyle", gl_deflinestyle, METH_OLDARGS},
+ {"noise", gl_noise, METH_OLDARGS},
+ {"picksize", gl_picksize, METH_OLDARGS},
+ {"qenter", gl_qenter, METH_OLDARGS},
+ {"setdepth", gl_setdepth, METH_OLDARGS},
+ {"cmov2s", gl_cmov2s, METH_OLDARGS},
+ {"draw2s", gl_draw2s, METH_OLDARGS},
+ {"move2s", gl_move2s, METH_OLDARGS},
+ {"pdr2s", gl_pdr2s, METH_OLDARGS},
+ {"pmv2s", gl_pmv2s, METH_OLDARGS},
+ {"pnt2s", gl_pnt2s, METH_OLDARGS},
+ {"rdr2s", gl_rdr2s, METH_OLDARGS},
+ {"rmv2s", gl_rmv2s, METH_OLDARGS},
+ {"rpdr2s", gl_rpdr2s, METH_OLDARGS},
+ {"rpmv2s", gl_rpmv2s, METH_OLDARGS},
+ {"xfpt2s", gl_xfpt2s, METH_OLDARGS},
+ {"cmov2", gl_cmov2, METH_OLDARGS},
+ {"draw2", gl_draw2, METH_OLDARGS},
+ {"move2", gl_move2, METH_OLDARGS},
+ {"pnt2", gl_pnt2, METH_OLDARGS},
+ {"pdr2", gl_pdr2, METH_OLDARGS},
+ {"pmv2", gl_pmv2, METH_OLDARGS},
+ {"rdr2", gl_rdr2, METH_OLDARGS},
+ {"rmv2", gl_rmv2, METH_OLDARGS},
+ {"rpdr2", gl_rpdr2, METH_OLDARGS},
+ {"rpmv2", gl_rpmv2, METH_OLDARGS},
+ {"xfpt2", gl_xfpt2, METH_OLDARGS},
+ {"loadmatrix", gl_loadmatrix, METH_OLDARGS},
+ {"multmatrix", gl_multmatrix, METH_OLDARGS},
+ {"crv", gl_crv, METH_OLDARGS},
+ {"rcrv", gl_rcrv, METH_OLDARGS},
+ {"addtopup", gl_addtopup, METH_OLDARGS},
+ {"charstr", gl_charstr, METH_OLDARGS},
+ {"getport", gl_getport, METH_OLDARGS},
+ {"strwidth", gl_strwidth, METH_OLDARGS},
+ {"winopen", gl_winopen, METH_OLDARGS},
+ {"wintitle", gl_wintitle, METH_OLDARGS},
+ {"polf", gl_polf, METH_OLDARGS},
+ {"polf2", gl_polf2, METH_OLDARGS},
+ {"poly", gl_poly, METH_OLDARGS},
+ {"poly2", gl_poly2, METH_OLDARGS},
+ {"crvn", gl_crvn, METH_OLDARGS},
+ {"rcrvn", gl_rcrvn, METH_OLDARGS},
+ {"polf2i", gl_polf2i, METH_OLDARGS},
+ {"polfi", gl_polfi, METH_OLDARGS},
+ {"poly2i", gl_poly2i, METH_OLDARGS},
+ {"polyi", gl_polyi, METH_OLDARGS},
+ {"polf2s", gl_polf2s, METH_OLDARGS},
+ {"polfs", gl_polfs, METH_OLDARGS},
+ {"polys", gl_polys, METH_OLDARGS},
+ {"poly2s", gl_poly2s, METH_OLDARGS},
+ {"defcursor", gl_defcursor, METH_OLDARGS},
+ {"writepixels", gl_writepixels, METH_OLDARGS},
+ {"defbasis", gl_defbasis, METH_OLDARGS},
+ {"gewrite", gl_gewrite, METH_OLDARGS},
+ {"rotate", gl_rotate, METH_OLDARGS},
+ {"rot", gl_rot, METH_OLDARGS},
+ {"circfi", gl_circfi, METH_OLDARGS},
+ {"circi", gl_circi, METH_OLDARGS},
+ {"cmovi", gl_cmovi, METH_OLDARGS},
+ {"drawi", gl_drawi, METH_OLDARGS},
+ {"movei", gl_movei, METH_OLDARGS},
+ {"pnti", gl_pnti, METH_OLDARGS},
+ {"newtag", gl_newtag, METH_OLDARGS},
+ {"pdri", gl_pdri, METH_OLDARGS},
+ {"pmvi", gl_pmvi, METH_OLDARGS},
+ {"rdri", gl_rdri, METH_OLDARGS},
+ {"rmvi", gl_rmvi, METH_OLDARGS},
+ {"rpdri", gl_rpdri, METH_OLDARGS},
+ {"rpmvi", gl_rpmvi, METH_OLDARGS},
+ {"xfpti", gl_xfpti, METH_OLDARGS},
+ {"circ", gl_circ, METH_OLDARGS},
+ {"circf", gl_circf, METH_OLDARGS},
+ {"cmov", gl_cmov, METH_OLDARGS},
+ {"draw", gl_draw, METH_OLDARGS},
+ {"move", gl_move, METH_OLDARGS},
+ {"pnt", gl_pnt, METH_OLDARGS},
+ {"scale", gl_scale, METH_OLDARGS},
+ {"translate", gl_translate, METH_OLDARGS},
+ {"pdr", gl_pdr, METH_OLDARGS},
+ {"pmv", gl_pmv, METH_OLDARGS},
+ {"rdr", gl_rdr, METH_OLDARGS},
+ {"rmv", gl_rmv, METH_OLDARGS},
+ {"rpdr", gl_rpdr, METH_OLDARGS},
+ {"rpmv", gl_rpmv, METH_OLDARGS},
+ {"xfpt", gl_xfpt, METH_OLDARGS},
+ {"RGBcolor", gl_RGBcolor, METH_OLDARGS},
+ {"RGBwritemask", gl_RGBwritemask, METH_OLDARGS},
+ {"setcursor", gl_setcursor, METH_OLDARGS},
+ {"tie", gl_tie, METH_OLDARGS},
+ {"circfs", gl_circfs, METH_OLDARGS},
+ {"circs", gl_circs, METH_OLDARGS},
+ {"cmovs", gl_cmovs, METH_OLDARGS},
+ {"draws", gl_draws, METH_OLDARGS},
+ {"moves", gl_moves, METH_OLDARGS},
+ {"pdrs", gl_pdrs, METH_OLDARGS},
+ {"pmvs", gl_pmvs, METH_OLDARGS},
+ {"pnts", gl_pnts, METH_OLDARGS},
+ {"rdrs", gl_rdrs, METH_OLDARGS},
+ {"rmvs", gl_rmvs, METH_OLDARGS},
+ {"rpdrs", gl_rpdrs, METH_OLDARGS},
+ {"rpmvs", gl_rpmvs, METH_OLDARGS},
+ {"xfpts", gl_xfpts, METH_OLDARGS},
+ {"curorigin", gl_curorigin, METH_OLDARGS},
+ {"cyclemap", gl_cyclemap, METH_OLDARGS},
+ {"patch", gl_patch, METH_OLDARGS},
+ {"splf", gl_splf, METH_OLDARGS},
+ {"splf2", gl_splf2, METH_OLDARGS},
+ {"splfi", gl_splfi, METH_OLDARGS},
+ {"splf2i", gl_splf2i, METH_OLDARGS},
+ {"splfs", gl_splfs, METH_OLDARGS},
+ {"splf2s", gl_splf2s, METH_OLDARGS},
+ {"rpatch", gl_rpatch, METH_OLDARGS},
+ {"ortho2", gl_ortho2, METH_OLDARGS},
+ {"rect", gl_rect, METH_OLDARGS},
+ {"rectf", gl_rectf, METH_OLDARGS},
+ {"xfpt4", gl_xfpt4, METH_OLDARGS},
+ {"textport", gl_textport, METH_OLDARGS},
+ {"mapcolor", gl_mapcolor, METH_OLDARGS},
+ {"scrmask", gl_scrmask, METH_OLDARGS},
+ {"setvaluator", gl_setvaluator, METH_OLDARGS},
+ {"viewport", gl_viewport, METH_OLDARGS},
+ {"shaderange", gl_shaderange, METH_OLDARGS},
+ {"xfpt4s", gl_xfpt4s, METH_OLDARGS},
+ {"rectfi", gl_rectfi, METH_OLDARGS},
+ {"recti", gl_recti, METH_OLDARGS},
+ {"xfpt4i", gl_xfpt4i, METH_OLDARGS},
+ {"prefposition", gl_prefposition, METH_OLDARGS},
+ {"arc", gl_arc, METH_OLDARGS},
+ {"arcf", gl_arcf, METH_OLDARGS},
+ {"arcfi", gl_arcfi, METH_OLDARGS},
+ {"arci", gl_arci, METH_OLDARGS},
+ {"bbox2", gl_bbox2, METH_OLDARGS},
+ {"bbox2i", gl_bbox2i, METH_OLDARGS},
+ {"bbox2s", gl_bbox2s, METH_OLDARGS},
+ {"blink", gl_blink, METH_OLDARGS},
+ {"ortho", gl_ortho, METH_OLDARGS},
+ {"window", gl_window, METH_OLDARGS},
+ {"lookat", gl_lookat, METH_OLDARGS},
+ {"perspective", gl_perspective, METH_OLDARGS},
+ {"polarview", gl_polarview, METH_OLDARGS},
+ {"arcfs", gl_arcfs, METH_OLDARGS},
+ {"arcs", gl_arcs, METH_OLDARGS},
+ {"rectcopy", gl_rectcopy, METH_OLDARGS},
+ {"RGBcursor", gl_RGBcursor, METH_OLDARGS},
+ {"getbutton", gl_getbutton, METH_OLDARGS},
+ {"getcmmode", gl_getcmmode, METH_OLDARGS},
+ {"getlsbackup", gl_getlsbackup, METH_OLDARGS},
+ {"getresetls", gl_getresetls, METH_OLDARGS},
+ {"getdcm", gl_getdcm, METH_OLDARGS},
+ {"getzbuffer", gl_getzbuffer, METH_OLDARGS},
+ {"ismex", gl_ismex, METH_OLDARGS},
+ {"isobj", gl_isobj, METH_OLDARGS},
+ {"isqueued", gl_isqueued, METH_OLDARGS},
+ {"istag", gl_istag, METH_OLDARGS},
+ {"genobj", gl_genobj, METH_OLDARGS},
+ {"gentag", gl_gentag, METH_OLDARGS},
+ {"getbuffer", gl_getbuffer, METH_OLDARGS},
+ {"getcolor", gl_getcolor, METH_OLDARGS},
+ {"getdisplaymode", gl_getdisplaymode, METH_OLDARGS},
+ {"getfont", gl_getfont, METH_OLDARGS},
+ {"getheight", gl_getheight, METH_OLDARGS},
+ {"gethitcode", gl_gethitcode, METH_OLDARGS},
+ {"getlstyle", gl_getlstyle, METH_OLDARGS},
+ {"getlwidth", gl_getlwidth, METH_OLDARGS},
+ {"getmap", gl_getmap, METH_OLDARGS},
+ {"getplanes", gl_getplanes, METH_OLDARGS},
+ {"getwritemask", gl_getwritemask, METH_OLDARGS},
+ {"qtest", gl_qtest, METH_OLDARGS},
+ {"getlsrepeat", gl_getlsrepeat, METH_OLDARGS},
+ {"getmonitor", gl_getmonitor, METH_OLDARGS},
+ {"getopenobj", gl_getopenobj, METH_OLDARGS},
+ {"getpattern", gl_getpattern, METH_OLDARGS},
+ {"winget", gl_winget, METH_OLDARGS},
+ {"winattach", gl_winattach, METH_OLDARGS},
+ {"getothermonitor", gl_getothermonitor, METH_OLDARGS},
+ {"newpup", gl_newpup, METH_OLDARGS},
+ {"getvaluator", gl_getvaluator, METH_OLDARGS},
+ {"winset", gl_winset, METH_OLDARGS},
+ {"dopup", gl_dopup, METH_OLDARGS},
+ {"getdepth", gl_getdepth, METH_OLDARGS},
+ {"getcpos", gl_getcpos, METH_OLDARGS},
+ {"getsize", gl_getsize, METH_OLDARGS},
+ {"getorigin", gl_getorigin, METH_OLDARGS},
+ {"getviewport", gl_getviewport, METH_OLDARGS},
+ {"gettp", gl_gettp, METH_OLDARGS},
+ {"getgpos", gl_getgpos, METH_OLDARGS},
+ {"winposition", gl_winposition, METH_OLDARGS},
+ {"gRGBcolor", gl_gRGBcolor, METH_OLDARGS},
+ {"gRGBmask", gl_gRGBmask, METH_OLDARGS},
+ {"getscrmask", gl_getscrmask, METH_OLDARGS},
+ {"getmcolor", gl_getmcolor, METH_OLDARGS},
+ {"mapw", gl_mapw, METH_OLDARGS},
+ {"mapw2", gl_mapw2, METH_OLDARGS},
+ {"getcursor", gl_getcursor, METH_OLDARGS},
+ {"cmode", gl_cmode, METH_OLDARGS},
+ {"concave", gl_concave, METH_OLDARGS},
+ {"curstype", gl_curstype, METH_OLDARGS},
+ {"drawmode", gl_drawmode, METH_OLDARGS},
+ {"gammaramp", gl_gammaramp, METH_OLDARGS},
+ {"getbackface", gl_getbackface, METH_OLDARGS},
+ {"getdescender", gl_getdescender, METH_OLDARGS},
+ {"getdrawmode", gl_getdrawmode, METH_OLDARGS},
+ {"getmmode", gl_getmmode, METH_OLDARGS},
+ {"getsm", gl_getsm, METH_OLDARGS},
+ {"getvideo", gl_getvideo, METH_OLDARGS},
+ {"imakebackground", gl_imakebackground, METH_OLDARGS},
+ {"lmbind", gl_lmbind, METH_OLDARGS},
+ {"lmdef", gl_lmdef, METH_OLDARGS},
+ {"mmode", gl_mmode, METH_OLDARGS},
+ {"normal", gl_normal, METH_OLDARGS},
+ {"overlay", gl_overlay, METH_OLDARGS},
+ {"RGBrange", gl_RGBrange, METH_OLDARGS},
+ {"setvideo", gl_setvideo, METH_OLDARGS},
+ {"shademodel", gl_shademodel, METH_OLDARGS},
+ {"underlay", gl_underlay, METH_OLDARGS},
+ {"bgnclosedline", gl_bgnclosedline, METH_OLDARGS},
+ {"bgnline", gl_bgnline, METH_OLDARGS},
+ {"bgnpoint", gl_bgnpoint, METH_OLDARGS},
+ {"bgnpolygon", gl_bgnpolygon, METH_OLDARGS},
+ {"bgnsurface", gl_bgnsurface, METH_OLDARGS},
+ {"bgntmesh", gl_bgntmesh, METH_OLDARGS},
+ {"bgntrim", gl_bgntrim, METH_OLDARGS},
+ {"endclosedline", gl_endclosedline, METH_OLDARGS},
+ {"endline", gl_endline, METH_OLDARGS},
+ {"endpoint", gl_endpoint, METH_OLDARGS},
+ {"endpolygon", gl_endpolygon, METH_OLDARGS},
+ {"endsurface", gl_endsurface, METH_OLDARGS},
+ {"endtmesh", gl_endtmesh, METH_OLDARGS},
+ {"endtrim", gl_endtrim, METH_OLDARGS},
+ {"blendfunction", gl_blendfunction, METH_OLDARGS},
+ {"c3f", gl_c3f, METH_OLDARGS},
+ {"c3i", gl_c3i, METH_OLDARGS},
+ {"c3s", gl_c3s, METH_OLDARGS},
+ {"c4f", gl_c4f, METH_OLDARGS},
+ {"c4i", gl_c4i, METH_OLDARGS},
+ {"c4s", gl_c4s, METH_OLDARGS},
+ {"colorf", gl_colorf, METH_OLDARGS},
+ {"cpack", gl_cpack, METH_OLDARGS},
+ {"czclear", gl_czclear, METH_OLDARGS},
+ {"dglclose", gl_dglclose, METH_OLDARGS},
+ {"dglopen", gl_dglopen, METH_OLDARGS},
+ {"getgdesc", gl_getgdesc, METH_OLDARGS},
+ {"getnurbsproperty", gl_getnurbsproperty, METH_OLDARGS},
+ {"glcompat", gl_glcompat, METH_OLDARGS},
+ {"iconsize", gl_iconsize, METH_OLDARGS},
+ {"icontitle", gl_icontitle, METH_OLDARGS},
+ {"lRGBrange", gl_lRGBrange, METH_OLDARGS},
+ {"linesmooth", gl_linesmooth, METH_OLDARGS},
+ {"lmcolor", gl_lmcolor, METH_OLDARGS},
+ {"logicop", gl_logicop, METH_OLDARGS},
+ {"lsetdepth", gl_lsetdepth, METH_OLDARGS},
+ {"lshaderange", gl_lshaderange, METH_OLDARGS},
+ {"n3f", gl_n3f, METH_OLDARGS},
+ {"noborder", gl_noborder, METH_OLDARGS},
+ {"pntsmooth", gl_pntsmooth, METH_OLDARGS},
+ {"readsource", gl_readsource, METH_OLDARGS},
+ {"rectzoom", gl_rectzoom, METH_OLDARGS},
+ {"sbox", gl_sbox, METH_OLDARGS},
+ {"sboxi", gl_sboxi, METH_OLDARGS},
+ {"sboxs", gl_sboxs, METH_OLDARGS},
+ {"sboxf", gl_sboxf, METH_OLDARGS},
+ {"sboxfi", gl_sboxfi, METH_OLDARGS},
+ {"sboxfs", gl_sboxfs, METH_OLDARGS},
+ {"setnurbsproperty", gl_setnurbsproperty, METH_OLDARGS},
+ {"setpup", gl_setpup, METH_OLDARGS},
+ {"smoothline", gl_smoothline, METH_OLDARGS},
+ {"subpixel", gl_subpixel, METH_OLDARGS},
+ {"swaptmesh", gl_swaptmesh, METH_OLDARGS},
+ {"swinopen", gl_swinopen, METH_OLDARGS},
+ {"v2f", gl_v2f, METH_OLDARGS},
+ {"v2i", gl_v2i, METH_OLDARGS},
+ {"v2s", gl_v2s, METH_OLDARGS},
+ {"v3f", gl_v3f, METH_OLDARGS},
+ {"v3i", gl_v3i, METH_OLDARGS},
+ {"v3s", gl_v3s, METH_OLDARGS},
+ {"v4f", gl_v4f, METH_OLDARGS},
+ {"v4i", gl_v4i, METH_OLDARGS},
+ {"v4s", gl_v4s, METH_OLDARGS},
+ {"videocmd", gl_videocmd, METH_OLDARGS},
+ {"windepth", gl_windepth, METH_OLDARGS},
+ {"wmpack", gl_wmpack, METH_OLDARGS},
+ {"zdraw", gl_zdraw, METH_OLDARGS},
+ {"zfunction", gl_zfunction, METH_OLDARGS},
+ {"zsource", gl_zsource, METH_OLDARGS},
+ {"zwritemask", gl_zwritemask, METH_OLDARGS},
+ {"v2d", gl_v2d, METH_OLDARGS},
+ {"v3d", gl_v3d, METH_OLDARGS},
+ {"v4d", gl_v4d, METH_OLDARGS},
+ {"pixmode", gl_pixmode, METH_OLDARGS},
+ {"qgetfd", gl_qgetfd, METH_OLDARGS},
+ {"dither", gl_dither, METH_OLDARGS},
+ {NULL, NULL} /* Sentinel */
+};
+
+void
+initgl(void)
+{
+ (void) Py_InitModule("gl", gl_methods);
+}
diff --git a/sys/src/cmd/python/Modules/grpmodule.c b/sys/src/cmd/python/Modules/grpmodule.c
new file mode 100644
index 000000000..f371b2a78
--- /dev/null
+++ b/sys/src/cmd/python/Modules/grpmodule.c
@@ -0,0 +1,194 @@
+
+/* UNIX group file access module */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <sys/types.h>
+#include <grp.h>
+
+static PyStructSequence_Field struct_group_type_fields[] = {
+ {"gr_name", "group name"},
+ {"gr_passwd", "password"},
+ {"gr_gid", "group id"},
+ {"gr_mem", "group memebers"},
+ {0}
+};
+
+PyDoc_STRVAR(struct_group__doc__,
+"grp.struct_group: Results from getgr*() routines.\n\n\
+This object may be accessed either as a tuple of\n\
+ (gr_name,gr_passwd,gr_gid,gr_mem)\n\
+or via the object attributes as named in the above tuple.\n");
+
+static PyStructSequence_Desc struct_group_type_desc = {
+ "grp.struct_group",
+ struct_group__doc__,
+ struct_group_type_fields,
+ 4,
+};
+
+
+static int initialized;
+static PyTypeObject StructGrpType;
+
+static PyObject *
+mkgrent(struct group *p)
+{
+ int setIndex = 0;
+ PyObject *v = PyStructSequence_New(&StructGrpType), *w;
+ char **member;
+
+ if (v == NULL)
+ return NULL;
+
+ if ((w = PyList_New(0)) == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ for (member = p->gr_mem; *member != NULL; member++) {
+ PyObject *x = PyString_FromString(*member);
+ if (x == NULL || PyList_Append(w, x) != 0) {
+ Py_XDECREF(x);
+ Py_DECREF(w);
+ Py_DECREF(v);
+ return NULL;
+ }
+ Py_DECREF(x);
+ }
+
+#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
+ SET(setIndex++, PyString_FromString(p->gr_name));
+#if defined(__VMS) || defined(PLAN9APE)
+ SET(setIndex++, Py_None);
+ Py_INCREF(Py_None);
+#else
+ if (p->gr_passwd)
+ SET(setIndex++, PyString_FromString(p->gr_passwd));
+ else {
+ SET(setIndex++, Py_None);
+ Py_INCREF(Py_None);
+ }
+#endif
+ SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
+ SET(setIndex++, w);
+#undef SET
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return NULL;
+ }
+
+ return v;
+}
+
+static PyObject *
+grp_getgrgid(PyObject *self, PyObject *pyo_id)
+{
+ PyObject *py_int_id;
+ unsigned int gid;
+ struct group *p;
+
+ py_int_id = PyNumber_Int(pyo_id);
+ if (!py_int_id)
+ return NULL;
+ gid = PyInt_AS_LONG(py_int_id);
+ Py_DECREF(py_int_id);
+
+ if ((p = getgrgid(gid)) == NULL) {
+ PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
+ return NULL;
+ }
+ return mkgrent(p);
+}
+
+static PyObject *
+grp_getgrnam(PyObject *self, PyObject *pyo_name)
+{
+ PyObject *py_str_name;
+ char *name;
+ struct group *p;
+
+ py_str_name = PyObject_Str(pyo_name);
+ if (!py_str_name)
+ return NULL;
+ name = PyString_AS_STRING(py_str_name);
+
+ if ((p = getgrnam(name)) == NULL) {
+ PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
+ Py_DECREF(py_str_name);
+ return NULL;
+ }
+
+ Py_DECREF(py_str_name);
+ return mkgrent(p);
+}
+
+static PyObject *
+grp_getgrall(PyObject *self, PyObject *ignore)
+{
+ PyObject *d;
+ struct group *p;
+
+ if ((d = PyList_New(0)) == NULL)
+ return NULL;
+ setgrent();
+ while ((p = getgrent()) != NULL) {
+ PyObject *v = mkgrent(p);
+ if (v == NULL || PyList_Append(d, v) != 0) {
+ Py_XDECREF(v);
+ Py_DECREF(d);
+ return NULL;
+ }
+ Py_DECREF(v);
+ }
+ endgrent();
+ return d;
+}
+
+static PyMethodDef grp_methods[] = {
+ {"getgrgid", grp_getgrgid, METH_O,
+ "getgrgid(id) -> tuple\n\
+Return the group database entry for the given numeric group ID. If\n\
+id is not valid, raise KeyError."},
+ {"getgrnam", grp_getgrnam, METH_O,
+ "getgrnam(name) -> tuple\n\
+Return the group database entry for the given group name. If\n\
+name is not valid, raise KeyError."},
+ {"getgrall", grp_getgrall, METH_NOARGS,
+ "getgrall() -> list of tuples\n\
+Return a list of all available group entries, in arbitrary order."},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(grp__doc__,
+"Access to the Unix group database.\n\
+\n\
+Group entries are reported as 4-tuples containing the following fields\n\
+from the group database, in order:\n\
+\n\
+ name - name of the group\n\
+ passwd - group password (encrypted); often empty\n\
+ gid - numeric ID of the group\n\
+ mem - list of members\n\
+\n\
+The gid is an integer, name and password are strings. (Note that most\n\
+users are not explicitly listed as members of the groups they are in\n\
+according to the password database. Check both databases to get\n\
+complete membership information.)");
+
+
+PyMODINIT_FUNC
+initgrp(void)
+{
+ PyObject *m, *d;
+ m = Py_InitModule3("grp", grp_methods, grp__doc__);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ if (!initialized)
+ PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
+ PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
+ initialized = 1;
+}
diff --git a/sys/src/cmd/python/Modules/imageop.c b/sys/src/cmd/python/Modules/imageop.c
new file mode 100644
index 000000000..92f805a83
--- /dev/null
+++ b/sys/src/cmd/python/Modules/imageop.c
@@ -0,0 +1,785 @@
+
+/* imageopmodule - Various operations on pictures */
+
+#ifdef sun
+#define signed
+#endif
+
+#include "Python.h"
+
+#if SIZEOF_INT == 4
+typedef int Py_Int32;
+typedef unsigned int Py_UInt32;
+#else
+#if SIZEOF_LONG == 4
+typedef long Py_Int32;
+typedef unsigned long Py_UInt32;
+#else
+#error "No 4-byte integral type"
+#endif
+#endif
+
+#define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
+#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
+#define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x)))
+
+static PyObject *ImageopError;
+static PyObject *ImageopDict;
+
+/* If this function returns true (the default if anything goes wrong), we're
+ behaving in a backward-compatible way with respect to how multi-byte pixels
+ are stored in the strings. The code in this module was originally written
+ for an SGI which is a big-endian system, and so the old code assumed that
+ 4-byte integers hold the R, G, and B values in a particular order.
+ However, on little-endian systems the order is reversed, and so not
+ actually compatible with what gl.lrectwrite and imgfile expect.
+ (gl.lrectwrite and imgfile are also SGI-specific, however, it is
+ conceivable that the data handled here comes from or goes to an SGI or that
+ it is otherwise used in the expectation that the byte order in the strings
+ is as specified.)
+
+ The function returns the value of the module variable
+ "backward_compatible", or 1 if the variable does not exist or is not an
+ int.
+ */
+
+static int
+imageop_backward_compatible(void)
+{
+ static PyObject *bcos;
+ PyObject *bco;
+ long rc;
+
+ if (ImageopDict == NULL) /* "cannot happen" */
+ return 1;
+ if (bcos == NULL) {
+ /* cache string object for future use */
+ bcos = PyString_FromString("backward_compatible");
+ if (bcos == NULL)
+ return 1;
+ }
+ bco = PyDict_GetItem(ImageopDict, bcos);
+ if (bco == NULL)
+ return 1;
+ if (!PyInt_Check(bco))
+ return 1;
+ rc = PyInt_AsLong(bco);
+ if (PyErr_Occurred()) {
+ /* not an integer, or too large, or something */
+ PyErr_Clear();
+ rc = 1;
+ }
+ return rc != 0; /* convert to values 0, 1 */
+}
+
+static PyObject *
+imageop_crop(PyObject *self, PyObject *args)
+{
+ char *cp, *ncp;
+ short *nsp;
+ Py_Int32 *nlp;
+ int len, size, x, y, newx1, newx2, newy1, newy2;
+ int ix, iy, xstep, ystep;
+ PyObject *rv;
+
+ if ( !PyArg_ParseTuple(args, "s#iiiiiii", &cp, &len, &size, &x, &y,
+ &newx1, &newy1, &newx2, &newy2) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ if ( len != size*x*y ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+ xstep = (newx1 < newx2)? 1 : -1;
+ ystep = (newy1 < newy2)? 1 : -1;
+
+ rv = PyString_FromStringAndSize(NULL,
+ (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
+ if ( rv == 0 )
+ return 0;
+ ncp = (char *)PyString_AsString(rv);
+ nsp = (short *)ncp;
+ nlp = (Py_Int32 *)ncp;
+ newy2 += ystep;
+ newx2 += xstep;
+ for( iy = newy1; iy != newy2; iy+=ystep ) {
+ for ( ix = newx1; ix != newx2; ix+=xstep ) {
+ if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
+ if ( size == 1 )
+ *ncp++ = 0;
+ else
+ *nlp++ = 0;
+ } else {
+ if ( size == 1 )
+ *ncp++ = *CHARP(cp, x, ix, iy);
+ else if ( size == 2 )
+ *nsp++ = *SHORTP(cp, x, ix, iy);
+ else
+ *nlp++ = *LONGP(cp, x, ix, iy);
+ }
+ }
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_scale(PyObject *self, PyObject *args)
+{
+ char *cp, *ncp;
+ short *nsp;
+ Py_Int32 *nlp;
+ int len, size, x, y, newx, newy;
+ int ix, iy;
+ int oix, oiy;
+ PyObject *rv;
+
+ if ( !PyArg_ParseTuple(args, "s#iiiii",
+ &cp, &len, &size, &x, &y, &newx, &newy) )
+ return 0;
+
+ if ( size != 1 && size != 2 && size != 4 ) {
+ PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ if ( len != size*x*y ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, newx*newy*size);
+ if ( rv == 0 )
+ return 0;
+ ncp = (char *)PyString_AsString(rv);
+ nsp = (short *)ncp;
+ nlp = (Py_Int32 *)ncp;
+ for( iy = 0; iy < newy; iy++ ) {
+ for ( ix = 0; ix < newx; ix++ ) {
+ oix = ix * x / newx;
+ oiy = iy * y / newy;
+ if ( size == 1 )
+ *ncp++ = *CHARP(cp, x, oix, oiy);
+ else if ( size == 2 )
+ *nsp++ = *SHORTP(cp, x, oix, oiy);
+ else
+ *nlp++ = *LONGP(cp, x, oix, oiy);
+ }
+ }
+ return rv;
+}
+
+/* Note: this routine can use a bit of optimizing */
+
+static PyObject *
+imageop_tovideo(PyObject *self, PyObject *args)
+{
+ int maxx, maxy, x, y, len;
+ int i;
+ unsigned char *cp, *ncp;
+ int width;
+ PyObject *rv;
+
+
+ if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &width, &maxx, &maxy) )
+ return 0;
+
+ if ( width != 1 && width != 4 ) {
+ PyErr_SetString(ImageopError, "Size should be 1 or 4");
+ return 0;
+ }
+ if ( maxx*maxy*width != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, len);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ if ( width == 1 ) {
+ memcpy(ncp, cp, maxx); /* Copy first line */
+ ncp += maxx;
+ for (y=1; y<maxy; y++) { /* Interpolate other lines */
+ for(x=0; x<maxx; x++) {
+ i = y*maxx + x;
+ *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
+ }
+ }
+ } else {
+ memcpy(ncp, cp, maxx*4); /* Copy first line */
+ ncp += maxx*4;
+ for (y=1; y<maxy; y++) { /* Interpolate other lines */
+ for(x=0; x<maxx; x++) {
+ i = (y*maxx + x)*4 + 1;
+ *ncp++ = 0; /* Skip alfa comp */
+ *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
+ i++;
+ *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
+ i++;
+ *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
+ }
+ }
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_grey2mono(PyObject *self, PyObject *args)
+{
+ int tres, x, y, len;
+ unsigned char *cp, *ncp;
+ unsigned char ovalue;
+ PyObject *rv;
+ int i, bit;
+
+
+ if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &x, &y, &tres) )
+ return 0;
+
+ if ( x*y != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, (len+7)/8);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ bit = 0x80;
+ ovalue = 0;
+ for ( i=0; i < len; i++ ) {
+ if ( (int)cp[i] > tres )
+ ovalue |= bit;
+ bit >>= 1;
+ if ( bit == 0 ) {
+ *ncp++ = ovalue;
+ bit = 0x80;
+ ovalue = 0;
+ }
+ }
+ if ( bit != 0x80 )
+ *ncp++ = ovalue;
+ return rv;
+}
+
+static PyObject *
+imageop_grey2grey4(PyObject *self, PyObject *args)
+{
+ int x, y, len;
+ unsigned char *cp, *ncp;
+ unsigned char ovalue;
+ PyObject *rv;
+ int i;
+ int pos;
+
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ if ( x*y != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, (len+1)/2);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+ pos = 0;
+ ovalue = 0;
+ for ( i=0; i < len; i++ ) {
+ ovalue |= ((int)cp[i] & 0xf0) >> pos;
+ pos += 4;
+ if ( pos == 8 ) {
+ *ncp++ = ovalue;
+ ovalue = 0;
+ pos = 0;
+ }
+ }
+ if ( pos != 0 )
+ *ncp++ = ovalue;
+ return rv;
+}
+
+static PyObject *
+imageop_grey2grey2(PyObject *self, PyObject *args)
+{
+ int x, y, len;
+ unsigned char *cp, *ncp;
+ unsigned char ovalue;
+ PyObject *rv;
+ int i;
+ int pos;
+
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ if ( x*y != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, (len+3)/4);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+ pos = 0;
+ ovalue = 0;
+ for ( i=0; i < len; i++ ) {
+ ovalue |= ((int)cp[i] & 0xc0) >> pos;
+ pos += 2;
+ if ( pos == 8 ) {
+ *ncp++ = ovalue;
+ ovalue = 0;
+ pos = 0;
+ }
+ }
+ if ( pos != 0 )
+ *ncp++ = ovalue;
+ return rv;
+}
+
+static PyObject *
+imageop_dither2mono(PyObject *self, PyObject *args)
+{
+ int sum, x, y, len;
+ unsigned char *cp, *ncp;
+ unsigned char ovalue;
+ PyObject *rv;
+ int i, bit;
+
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ if ( x*y != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, (len+7)/8);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ bit = 0x80;
+ ovalue = 0;
+ sum = 0;
+ for ( i=0; i < len; i++ ) {
+ sum += cp[i];
+ if ( sum >= 256 ) {
+ sum -= 256;
+ ovalue |= bit;
+ }
+ bit >>= 1;
+ if ( bit == 0 ) {
+ *ncp++ = ovalue;
+ bit = 0x80;
+ ovalue = 0;
+ }
+ }
+ if ( bit != 0x80 )
+ *ncp++ = ovalue;
+ return rv;
+}
+
+static PyObject *
+imageop_dither2grey2(PyObject *self, PyObject *args)
+{
+ int x, y, len;
+ unsigned char *cp, *ncp;
+ unsigned char ovalue;
+ PyObject *rv;
+ int i;
+ int pos;
+ int sum = 0, nvalue;
+
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ if ( x*y != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, (len+3)/4);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+ pos = 1;
+ ovalue = 0;
+ for ( i=0; i < len; i++ ) {
+ sum += cp[i];
+ nvalue = sum & 0x180;
+ sum -= nvalue;
+ ovalue |= nvalue >> pos;
+ pos += 2;
+ if ( pos == 9 ) {
+ *ncp++ = ovalue;
+ ovalue = 0;
+ pos = 1;
+ }
+ }
+ if ( pos != 0 )
+ *ncp++ = ovalue;
+ return rv;
+}
+
+static PyObject *
+imageop_mono2grey(PyObject *self, PyObject *args)
+{
+ int v0, v1, x, y, len, nlen;
+ unsigned char *cp, *ncp;
+ PyObject *rv;
+ int i, bit;
+
+ if ( !PyArg_ParseTuple(args, "s#iiii", &cp, &len, &x, &y, &v0, &v1) )
+ return 0;
+
+ nlen = x*y;
+ if ( (nlen+7)/8 != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ bit = 0x80;
+ for ( i=0; i < nlen; i++ ) {
+ if ( *cp & bit )
+ *ncp++ = v1;
+ else
+ *ncp++ = v0;
+ bit >>= 1;
+ if ( bit == 0 ) {
+ bit = 0x80;
+ cp++;
+ }
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_grey22grey(PyObject *self, PyObject *args)
+{
+ int x, y, len, nlen;
+ unsigned char *cp, *ncp;
+ PyObject *rv;
+ int i, pos, value = 0, nvalue;
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ nlen = x*y;
+ if ( (nlen+3)/4 != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ pos = 0;
+ for ( i=0; i < nlen; i++ ) {
+ if ( pos == 0 ) {
+ value = *cp++;
+ pos = 8;
+ }
+ pos -= 2;
+ nvalue = (value >> pos) & 0x03;
+ *ncp++ = nvalue | (nvalue << 2) |
+ (nvalue << 4) | (nvalue << 6);
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_grey42grey(PyObject *self, PyObject *args)
+{
+ int x, y, len, nlen;
+ unsigned char *cp, *ncp;
+ PyObject *rv;
+ int i, pos, value = 0, nvalue;
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ nlen = x*y;
+ if ( (nlen+1)/2 != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ pos = 0;
+ for ( i=0; i < nlen; i++ ) {
+ if ( pos == 0 ) {
+ value = *cp++;
+ pos = 8;
+ }
+ pos -= 4;
+ nvalue = (value >> pos) & 0x0f;
+ *ncp++ = nvalue | (nvalue << 4);
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_rgb2rgb8(PyObject *self, PyObject *args)
+{
+ int x, y, len, nlen;
+ unsigned char *cp;
+ unsigned char *ncp;
+ PyObject *rv;
+ int i, r, g, b;
+ int backward_compatible = imageop_backward_compatible();
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ nlen = x*y;
+ if ( nlen*4 != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < nlen; i++ ) {
+ /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
+ if (backward_compatible) {
+ Py_UInt32 value = * (Py_UInt32 *) cp;
+ cp += 4;
+ r = (int) ((value & 0xff) / 255. * 7. + .5);
+ g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
+ b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
+ } else {
+ cp++; /* skip alpha channel */
+ b = (int) (*cp++ / 255. * 3. + .5);
+ g = (int) (*cp++ / 255. * 7. + .5);
+ r = (int) (*cp++ / 255. * 7. + .5);
+ }
+ *ncp++ = (unsigned char)((r<<5) | (b<<3) | g);
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_rgb82rgb(PyObject *self, PyObject *args)
+{
+ int x, y, len, nlen;
+ unsigned char *cp;
+ unsigned char *ncp;
+ PyObject *rv;
+ int i, r, g, b;
+ unsigned char value;
+ int backward_compatible = imageop_backward_compatible();
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ nlen = x*y;
+ if ( nlen != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen*4);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < nlen; i++ ) {
+ /* Bits in source: RRRBBGGG
+ ** Red and Green are multiplied by 36.5, Blue by 85
+ */
+ value = *cp++;
+ r = (value >> 5) & 7;
+ g = (value ) & 7;
+ b = (value >> 3) & 3;
+ r = (r<<5) | (r<<3) | (r>>1);
+ g = (g<<5) | (g<<3) | (g>>1);
+ b = (b<<6) | (b<<4) | (b<<2) | b;
+ if (backward_compatible) {
+ Py_UInt32 nvalue = r | (g<<8) | (b<<16);
+ * (Py_UInt32 *) ncp = nvalue;
+ ncp += 4;
+ } else {
+ *ncp++ = 0;
+ *ncp++ = b;
+ *ncp++ = g;
+ *ncp++ = r;
+ }
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_rgb2grey(PyObject *self, PyObject *args)
+{
+ int x, y, len, nlen;
+ unsigned char *cp;
+ unsigned char *ncp;
+ PyObject *rv;
+ int i, r, g, b;
+ int nvalue;
+ int backward_compatible = imageop_backward_compatible();
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ nlen = x*y;
+ if ( nlen*4 != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < nlen; i++ ) {
+ if (backward_compatible) {
+ Py_UInt32 value = * (Py_UInt32 *) cp;
+ cp += 4;
+ r = (int) ((value & 0xff) / 255. * 7. + .5);
+ g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
+ b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
+ } else {
+ cp++; /* skip alpha channel */
+ b = *cp++;
+ g = *cp++;
+ r = *cp++;
+ }
+ nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
+ if ( nvalue > 255 ) nvalue = 255;
+ *ncp++ = (unsigned char)nvalue;
+ }
+ return rv;
+}
+
+static PyObject *
+imageop_grey2rgb(PyObject *self, PyObject *args)
+{
+ int x, y, len, nlen;
+ unsigned char *cp;
+ unsigned char *ncp;
+ PyObject *rv;
+ int i;
+ unsigned char value;
+ int backward_compatible = imageop_backward_compatible();
+
+ if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
+ return 0;
+
+ nlen = x*y;
+ if ( nlen != len ) {
+ PyErr_SetString(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = PyString_FromStringAndSize(NULL, nlen*4);
+ if ( rv == 0 )
+ return 0;
+ ncp = (unsigned char *)PyString_AsString(rv);
+
+ for ( i=0; i < nlen; i++ ) {
+ value = *cp++;
+ if (backward_compatible) {
+ * (Py_UInt32 *) ncp = (Py_UInt32) value | ((Py_UInt32) value << 8 ) | ((Py_UInt32) value << 16);
+ ncp += 4;
+ } else {
+ *ncp++ = 0;
+ *ncp++ = value;
+ *ncp++ = value;
+ *ncp++ = value;
+ }
+ }
+ return rv;
+}
+
+/*
+static object *
+imageop_mul(object *self, object *args)
+{
+ char *cp, *ncp;
+ int len, size, x, y;
+ object *rv;
+ int i;
+
+ if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
+ return 0;
+
+ if ( size != 1 && size != 4 ) {
+ err_setstr(ImageopError, "Size should be 1 or 4");
+ return 0;
+ }
+ if ( len != size*x*y ) {
+ err_setstr(ImageopError, "String has incorrect length");
+ return 0;
+ }
+
+ rv = newsizedstringobject(NULL, XXXX);
+ if ( rv == 0 )
+ return 0;
+ ncp = (char *)getstringvalue(rv);
+
+
+ for ( i=0; i < len; i += size ) {
+ }
+ return rv;
+}
+*/
+
+static PyMethodDef imageop_methods[] = {
+ { "crop", imageop_crop, METH_VARARGS },
+ { "scale", imageop_scale, METH_VARARGS },
+ { "grey2mono", imageop_grey2mono, METH_VARARGS },
+ { "grey2grey2", imageop_grey2grey2, METH_VARARGS },
+ { "grey2grey4", imageop_grey2grey4, METH_VARARGS },
+ { "dither2mono", imageop_dither2mono, METH_VARARGS },
+ { "dither2grey2", imageop_dither2grey2, METH_VARARGS },
+ { "mono2grey", imageop_mono2grey, METH_VARARGS },
+ { "grey22grey", imageop_grey22grey, METH_VARARGS },
+ { "grey42grey", imageop_grey42grey, METH_VARARGS },
+ { "tovideo", imageop_tovideo, METH_VARARGS },
+ { "rgb2rgb8", imageop_rgb2rgb8, METH_VARARGS },
+ { "rgb82rgb", imageop_rgb82rgb, METH_VARARGS },
+ { "rgb2grey", imageop_rgb2grey, METH_VARARGS },
+ { "grey2rgb", imageop_grey2rgb, METH_VARARGS },
+ { 0, 0 }
+};
+
+
+PyMODINIT_FUNC
+initimageop(void)
+{
+ PyObject *m;
+ m = Py_InitModule("imageop", imageop_methods);
+ if (m == NULL)
+ return;
+ ImageopDict = PyModule_GetDict(m);
+ ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
+ if (ImageopError != NULL)
+ PyDict_SetItemString(ImageopDict, "error", ImageopError);
+}
diff --git a/sys/src/cmd/python/Modules/imgfile.c b/sys/src/cmd/python/Modules/imgfile.c
new file mode 100644
index 000000000..bb85a78d5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/imgfile.c
@@ -0,0 +1,504 @@
+
+/* IMGFILE module - Interface to sgi libimage */
+
+/* XXX This module should be done better at some point. It should return
+** an object of image file class, and have routines to manipulate these
+** image files in a neater way (so you can get rgb images off a greyscale
+** file, for instance, or do a straight display without having to get the
+** image bits into python, etc).
+**
+** Warning: this module is very non-reentrant (esp. the readscaled stuff)
+*/
+
+#include "Python.h"
+
+#include <gl/image.h>
+
+#include "/usr/people/4Dgifts/iristools/include/izoom.h"
+
+/* Bunch of missing extern decls; keep gcc -Wall happy... */
+extern void i_seterror();
+extern void iclose();
+extern void filterzoom();
+extern void putrow();
+extern void getrow();
+
+static PyObject * ImgfileError; /* Exception we raise for various trouble */
+
+static int top_to_bottom; /* True if we want top-to-bottom images */
+
+/* The image library does not always call the error hander :-(,
+ therefore we have a global variable indicating that it was called.
+ It is cleared by imgfile_open(). */
+
+static int error_called;
+
+
+/* The error handler */
+
+static void
+imgfile_error(char *str)
+{
+ PyErr_SetString(ImgfileError, str);
+ error_called = 1;
+ return; /* To imglib, which will return a failure indicator */
+}
+
+
+/* Open an image file and return a pointer to it.
+ Make sure we raise an exception if we fail. */
+
+static IMAGE *
+imgfile_open(char *fname)
+{
+ IMAGE *image;
+ i_seterror(imgfile_error);
+ error_called = 0;
+ errno = 0;
+ if ( (image = iopen(fname, "r")) == NULL ) {
+ /* Error may already be set by imgfile_error */
+ if ( !error_called ) {
+ if (errno)
+ PyErr_SetFromErrno(ImgfileError);
+ else
+ PyErr_SetString(ImgfileError,
+ "Can't open image file");
+ }
+ return NULL;
+ }
+ return image;
+}
+
+static PyObject *
+imgfile_ttob(PyObject *self, PyObject *args)
+{
+ int newval;
+ PyObject *rv;
+
+ if (!PyArg_ParseTuple(args, "i:ttob", &newval))
+ return NULL;
+ rv = PyInt_FromLong(top_to_bottom);
+ top_to_bottom = newval;
+ return rv;
+}
+
+static PyObject *
+imgfile_read(PyObject *self, PyObject *args)
+{
+ char *fname;
+ PyObject *rv;
+ int xsize, ysize, zsize;
+ char *cdatap;
+ long *idatap;
+ static short rs[8192], gs[8192], bs[8192];
+ int x, y;
+ IMAGE *image;
+ int yfirst, ylast, ystep;
+
+ if ( !PyArg_ParseTuple(args, "s:read", &fname) )
+ return NULL;
+
+ if ( (image = imgfile_open(fname)) == NULL )
+ return NULL;
+
+ if ( image->colormap != CM_NORMAL ) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can only handle CM_NORMAL images");
+ return NULL;
+ }
+ if ( BPP(image->type) != 1 ) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can't handle imgfiles with bpp!=1");
+ return NULL;
+ }
+ xsize = image->xsize;
+ ysize = image->ysize;
+ zsize = image->zsize;
+ if ( zsize != 1 && zsize != 3) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can only handle 1 or 3 byte pixels");
+ return NULL;
+ }
+ if ( xsize > 8192 ) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can't handle image with > 8192 columns");
+ return NULL;
+ }
+
+ if ( zsize == 3 ) zsize = 4;
+ rv = PyString_FromStringAndSize((char *)NULL, xsize*ysize*zsize);
+ if ( rv == NULL ) {
+ iclose(image);
+ return NULL;
+ }
+ cdatap = PyString_AsString(rv);
+ idatap = (long *)cdatap;
+
+ if (top_to_bottom) {
+ yfirst = ysize-1;
+ ylast = -1;
+ ystep = -1;
+ } else {
+ yfirst = 0;
+ ylast = ysize;
+ ystep = 1;
+ }
+ for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
+ if ( zsize == 1 ) {
+ getrow(image, rs, y, 0);
+ for(x=0; x<xsize; x++ )
+ *cdatap++ = rs[x];
+ } else {
+ getrow(image, rs, y, 0);
+ getrow(image, gs, y, 1);
+ getrow(image, bs, y, 2);
+ for(x=0; x<xsize; x++ )
+ *idatap++ = (rs[x] & 0xff) |
+ ((gs[x] & 0xff)<<8) |
+ ((bs[x] & 0xff)<<16);
+ }
+ }
+ iclose(image);
+ if ( error_called ) {
+ Py_DECREF(rv);
+ return NULL;
+ }
+ return rv;
+}
+
+static IMAGE *glob_image;
+static long *glob_datap;
+static int glob_width, glob_z, glob_ysize;
+
+static void
+xs_get(short *buf, int y)
+{
+ if (top_to_bottom)
+ getrow(glob_image, buf, (glob_ysize-1-y), glob_z);
+ else
+ getrow(glob_image, buf, y, glob_z);
+}
+
+static void
+xs_put_c(short *buf, int y)
+{
+ char *datap = (char *)glob_datap + y*glob_width;
+ int width = glob_width;
+
+ while ( width-- )
+ *datap++ = (*buf++) & 0xff;
+}
+
+static void
+xs_put_0(short *buf, int y)
+{
+ long *datap = glob_datap + y*glob_width;
+ int width = glob_width;
+
+ while ( width-- )
+ *datap++ = (*buf++) & 0xff;
+}
+static void
+xs_put_12(short *buf, int y)
+{
+ long *datap = glob_datap + y*glob_width;
+ int width = glob_width;
+
+ while ( width-- )
+ *datap++ |= ((*buf++) & 0xff) << (glob_z*8);
+}
+
+static void
+xscale(IMAGE *image, int xsize, int ysize, int zsize,
+ long *datap, int xnew, int ynew, int fmode, double blur)
+{
+ glob_image = image;
+ glob_datap = datap;
+ glob_width = xnew;
+ glob_ysize = ysize;
+ if ( zsize == 1 ) {
+ glob_z = 0;
+ filterzoom(xs_get, xs_put_c, xsize, ysize,
+ xnew, ynew, fmode, blur);
+ } else {
+ glob_z = 0;
+ filterzoom(xs_get, xs_put_0, xsize, ysize,
+ xnew, ynew, fmode, blur);
+ glob_z = 1;
+ filterzoom(xs_get, xs_put_12, xsize, ysize,
+ xnew, ynew, fmode, blur);
+ glob_z = 2;
+ filterzoom(xs_get, xs_put_12, xsize, ysize,
+ xnew, ynew, fmode, blur);
+ }
+}
+
+
+static PyObject *
+imgfile_readscaled(PyObject *self, PyObject *args)
+{
+ char *fname;
+ PyObject *rv;
+ int xsize, ysize, zsize;
+ char *cdatap;
+ long *idatap;
+ static short rs[8192], gs[8192], bs[8192];
+ int x, y;
+ int xwtd, ywtd, xorig, yorig;
+ float xfac, yfac;
+ IMAGE *image;
+ char *filter;
+ double blur = 1.0;
+ int extended;
+ int fmode = 0;
+ int yfirst, ylast, ystep;
+
+ /*
+ ** Parse args. Funny, since arg 4 and 5 are optional
+ ** (filter name and blur factor). Also, 4 or 5 arguments indicates
+ ** extended scale algorithm in stead of simple-minded pixel drop/dup.
+ */
+ extended = PyTuple_Size(args) >= 4;
+ if ( !PyArg_ParseTuple(args, "sii|sd",
+ &fname, &xwtd, &ywtd, &filter, &blur) )
+ return NULL;
+
+ /*
+ ** Check parameters, open file and check type, rows, etc.
+ */
+ if ( extended ) {
+ if ( strcmp(filter, "impulse") == 0 )
+ fmode = IMPULSE;
+ else if ( strcmp( filter, "box") == 0 )
+ fmode = BOX;
+ else if ( strcmp( filter, "triangle") == 0 )
+ fmode = TRIANGLE;
+ else if ( strcmp( filter, "quadratic") == 0 )
+ fmode = QUADRATIC;
+ else if ( strcmp( filter, "gaussian") == 0 )
+ fmode = GAUSSIAN;
+ else {
+ PyErr_SetString(ImgfileError, "Unknown filter type");
+ return NULL;
+ }
+ }
+
+ if ( (image = imgfile_open(fname)) == NULL )
+ return NULL;
+
+ if ( image->colormap != CM_NORMAL ) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can only handle CM_NORMAL images");
+ return NULL;
+ }
+ if ( BPP(image->type) != 1 ) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can't handle imgfiles with bpp!=1");
+ return NULL;
+ }
+ xsize = image->xsize;
+ ysize = image->ysize;
+ zsize = image->zsize;
+ if ( zsize != 1 && zsize != 3) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can only handle 1 or 3 byte pixels");
+ return NULL;
+ }
+ if ( xsize > 8192 ) {
+ iclose(image);
+ PyErr_SetString(ImgfileError,
+ "Can't handle image with > 8192 columns");
+ return NULL;
+ }
+
+ if ( zsize == 3 ) zsize = 4;
+ rv = PyString_FromStringAndSize(NULL, xwtd*ywtd*zsize);
+ if ( rv == NULL ) {
+ iclose(image);
+ return NULL;
+ }
+ PyFPE_START_PROTECT("readscaled", return 0)
+ xfac = (float)xsize/(float)xwtd;
+ yfac = (float)ysize/(float)ywtd;
+ PyFPE_END_PROTECT(yfac)
+ cdatap = PyString_AsString(rv);
+ idatap = (long *)cdatap;
+
+ if ( extended ) {
+ xscale(image, xsize, ysize, zsize,
+ idatap, xwtd, ywtd, fmode, blur);
+ } else {
+ if (top_to_bottom) {
+ yfirst = ywtd-1;
+ ylast = -1;
+ ystep = -1;
+ } else {
+ yfirst = 0;
+ ylast = ywtd;
+ ystep = 1;
+ }
+ for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
+ yorig = (int)(y*yfac);
+ if ( zsize == 1 ) {
+ getrow(image, rs, yorig, 0);
+ for(x=0; x<xwtd; x++ ) {
+ *cdatap++ = rs[(int)(x*xfac)];
+ }
+ } else {
+ getrow(image, rs, yorig, 0);
+ getrow(image, gs, yorig, 1);
+ getrow(image, bs, yorig, 2);
+ for(x=0; x<xwtd; x++ ) {
+ xorig = (int)(x*xfac);
+ *idatap++ = (rs[xorig] & 0xff) |
+ ((gs[xorig] & 0xff)<<8) |
+ ((bs[xorig] & 0xff)<<16);
+ }
+ }
+ }
+ }
+ iclose(image);
+ if ( error_called ) {
+ Py_DECREF(rv);
+ return NULL;
+ }
+ return rv;
+}
+
+static PyObject *
+imgfile_getsizes(PyObject *self, PyObject *args)
+{
+ char *fname;
+ PyObject *rv;
+ IMAGE *image;
+
+ if ( !PyArg_ParseTuple(args, "s:getsizes", &fname) )
+ return NULL;
+
+ if ( (image = imgfile_open(fname)) == NULL )
+ return NULL;
+ rv = Py_BuildValue("(iii)", image->xsize, image->ysize, image->zsize);
+ iclose(image);
+ return rv;
+}
+
+static PyObject *
+imgfile_write(PyObject *self, PyObject *args)
+{
+ IMAGE *image;
+ char *fname;
+ int xsize, ysize, zsize, len;
+ char *cdatap;
+ long *idatap;
+ short rs[8192], gs[8192], bs[8192];
+ short r, g, b;
+ long rgb;
+ int x, y;
+ int yfirst, ylast, ystep;
+
+
+ if ( !PyArg_ParseTuple(args, "ss#iii:write",
+ &fname, &cdatap, &len, &xsize, &ysize, &zsize) )
+ return NULL;
+
+ if ( zsize != 1 && zsize != 3 ) {
+ PyErr_SetString(ImgfileError,
+ "Can only handle 1 or 3 byte pixels");
+ return NULL;
+ }
+ if ( len != xsize * ysize * (zsize == 1 ? 1 : 4) ) {
+ PyErr_SetString(ImgfileError, "Data does not match sizes");
+ return NULL;
+ }
+ if ( xsize > 8192 ) {
+ PyErr_SetString(ImgfileError,
+ "Can't handle image with > 8192 columns");
+ return NULL;
+ }
+
+ error_called = 0;
+ errno = 0;
+ image =iopen(fname, "w", RLE(1), 3, xsize, ysize, zsize);
+ if ( image == 0 ) {
+ if ( ! error_called ) {
+ if (errno)
+ PyErr_SetFromErrno(ImgfileError);
+ else
+ PyErr_SetString(ImgfileError,
+ "Can't create image file");
+ }
+ return NULL;
+ }
+
+ idatap = (long *)cdatap;
+
+ if (top_to_bottom) {
+ yfirst = ysize-1;
+ ylast = -1;
+ ystep = -1;
+ } else {
+ yfirst = 0;
+ ylast = ysize;
+ ystep = 1;
+ }
+ for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
+ if ( zsize == 1 ) {
+ for( x=0; x<xsize; x++ )
+ rs[x] = *cdatap++;
+ putrow(image, rs, y, 0);
+ } else {
+ for( x=0; x<xsize; x++ ) {
+ rgb = *idatap++;
+ r = rgb & 0xff;
+ g = (rgb >> 8 ) & 0xff;
+ b = (rgb >> 16 ) & 0xff;
+ rs[x] = r;
+ gs[x] = g;
+ bs[x] = b;
+ }
+ putrow(image, rs, y, 0);
+ putrow(image, gs, y, 1);
+ putrow(image, bs, y, 2);
+ }
+ }
+ iclose(image);
+ if ( error_called )
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+
+static PyMethodDef imgfile_methods[] = {
+ { "getsizes", imgfile_getsizes, METH_VARARGS },
+ { "read", imgfile_read, METH_VARARGS },
+ { "readscaled", imgfile_readscaled, METH_VARARGS},
+ { "write", imgfile_write, METH_VARARGS },
+ { "ttob", imgfile_ttob, METH_VARARGS },
+ { NULL, NULL } /* Sentinel */
+};
+
+
+void
+initimgfile(void)
+{
+ PyObject *m, *d;
+ m = Py_InitModule("imgfile", imgfile_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ ImgfileError = PyErr_NewException("imgfile.error", NULL, NULL);
+ if (ImgfileError != NULL)
+ PyDict_SetItemString(d, "error", ImgfileError);
+}
+
+
+
diff --git a/sys/src/cmd/python/Modules/itertoolsmodule.c b/sys/src/cmd/python/Modules/itertoolsmodule.c
new file mode 100644
index 000000000..70f787f78
--- /dev/null
+++ b/sys/src/cmd/python/Modules/itertoolsmodule.c
@@ -0,0 +1,2550 @@
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Itertools module written and maintained
+ by Raymond D. Hettinger <python@rcn.com>
+ Copyright (c) 2003 Python Software Foundation.
+ All rights reserved.
+*/
+
+
+/* groupby object ***********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *it;
+ PyObject *keyfunc;
+ PyObject *tgtkey;
+ PyObject *currkey;
+ PyObject *currvalue;
+} groupbyobject;
+
+static PyTypeObject groupby_type;
+static PyObject *_grouper_create(groupbyobject *, PyObject *);
+
+static PyObject *
+groupby_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ static char *kwargs[] = {"iterable", "key", NULL};
+ groupbyobject *gbo;
+ PyObject *it, *keyfunc = Py_None;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:groupby", kwargs,
+ &it, &keyfunc))
+ return NULL;
+
+ gbo = (groupbyobject *)type->tp_alloc(type, 0);
+ if (gbo == NULL)
+ return NULL;
+ gbo->tgtkey = NULL;
+ gbo->currkey = NULL;
+ gbo->currvalue = NULL;
+ gbo->keyfunc = keyfunc;
+ Py_INCREF(keyfunc);
+ gbo->it = PyObject_GetIter(it);
+ if (gbo->it == NULL) {
+ Py_DECREF(gbo);
+ return NULL;
+ }
+ return (PyObject *)gbo;
+}
+
+static void
+groupby_dealloc(groupbyobject *gbo)
+{
+ PyObject_GC_UnTrack(gbo);
+ Py_XDECREF(gbo->it);
+ Py_XDECREF(gbo->keyfunc);
+ Py_XDECREF(gbo->tgtkey);
+ Py_XDECREF(gbo->currkey);
+ Py_XDECREF(gbo->currvalue);
+ gbo->ob_type->tp_free(gbo);
+}
+
+static int
+groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
+{
+ Py_VISIT(gbo->it);
+ Py_VISIT(gbo->keyfunc);
+ Py_VISIT(gbo->tgtkey);
+ Py_VISIT(gbo->currkey);
+ Py_VISIT(gbo->currvalue);
+ return 0;
+}
+
+static PyObject *
+groupby_next(groupbyobject *gbo)
+{
+ PyObject *newvalue, *newkey, *r, *grouper, *tmp;
+
+ /* skip to next iteration group */
+ for (;;) {
+ if (gbo->currkey == NULL)
+ /* pass */;
+ else if (gbo->tgtkey == NULL)
+ break;
+ else {
+ int rcmp;
+
+ rcmp = PyObject_RichCompareBool(gbo->tgtkey,
+ gbo->currkey, Py_EQ);
+ if (rcmp == -1)
+ return NULL;
+ else if (rcmp == 0)
+ break;
+ }
+
+ newvalue = PyIter_Next(gbo->it);
+ if (newvalue == NULL)
+ return NULL;
+
+ if (gbo->keyfunc == Py_None) {
+ newkey = newvalue;
+ Py_INCREF(newvalue);
+ } else {
+ newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
+ newvalue, NULL);
+ if (newkey == NULL) {
+ Py_DECREF(newvalue);
+ return NULL;
+ }
+ }
+
+ tmp = gbo->currkey;
+ gbo->currkey = newkey;
+ Py_XDECREF(tmp);
+
+ tmp = gbo->currvalue;
+ gbo->currvalue = newvalue;
+ Py_XDECREF(tmp);
+ }
+
+ Py_INCREF(gbo->currkey);
+ tmp = gbo->tgtkey;
+ gbo->tgtkey = gbo->currkey;
+ Py_XDECREF(tmp);
+
+ grouper = _grouper_create(gbo, gbo->tgtkey);
+ if (grouper == NULL)
+ return NULL;
+
+ r = PyTuple_Pack(2, gbo->currkey, grouper);
+ Py_DECREF(grouper);
+ return r;
+}
+
+PyDoc_STRVAR(groupby_doc,
+"groupby(iterable[, keyfunc]) -> create an iterator which returns\n\
+(key, sub-iterator) grouped by each value of key(value).\n");
+
+static PyTypeObject groupby_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.groupby", /* tp_name */
+ sizeof(groupbyobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)groupby_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ groupby_doc, /* tp_doc */
+ (traverseproc)groupby_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)groupby_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ groupby_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* _grouper object (internal) ************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *parent;
+ PyObject *tgtkey;
+} _grouperobject;
+
+static PyTypeObject _grouper_type;
+
+static PyObject *
+_grouper_create(groupbyobject *parent, PyObject *tgtkey)
+{
+ _grouperobject *igo;
+
+ igo = PyObject_New(_grouperobject, &_grouper_type);
+ if (igo == NULL)
+ return NULL;
+ igo->parent = (PyObject *)parent;
+ Py_INCREF(parent);
+ igo->tgtkey = tgtkey;
+ Py_INCREF(tgtkey);
+
+ return (PyObject *)igo;
+}
+
+static void
+_grouper_dealloc(_grouperobject *igo)
+{
+ Py_DECREF(igo->parent);
+ Py_DECREF(igo->tgtkey);
+ PyObject_Del(igo);
+}
+
+static PyObject *
+_grouper_next(_grouperobject *igo)
+{
+ groupbyobject *gbo = (groupbyobject *)igo->parent;
+ PyObject *newvalue, *newkey, *r;
+ int rcmp;
+
+ if (gbo->currvalue == NULL) {
+ newvalue = PyIter_Next(gbo->it);
+ if (newvalue == NULL)
+ return NULL;
+
+ if (gbo->keyfunc == Py_None) {
+ newkey = newvalue;
+ Py_INCREF(newvalue);
+ } else {
+ newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
+ newvalue, NULL);
+ if (newkey == NULL) {
+ Py_DECREF(newvalue);
+ return NULL;
+ }
+ }
+
+ assert(gbo->currkey == NULL);
+ gbo->currkey = newkey;
+ gbo->currvalue = newvalue;
+ }
+
+ assert(gbo->currkey != NULL);
+ rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ);
+ if (rcmp <= 0)
+ /* got any error or current group is end */
+ return NULL;
+
+ r = gbo->currvalue;
+ gbo->currvalue = NULL;
+ Py_CLEAR(gbo->currkey);
+
+ return r;
+}
+
+static PyTypeObject _grouper_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools._grouper", /* tp_name */
+ sizeof(_grouperobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)_grouper_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)_grouper_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+
+
+/* tee object and with supporting function and objects ***************/
+
+/* The teedataobject pre-allocates space for LINKCELLS number of objects.
+ To help the object fit neatly inside cache lines (space for 16 to 32
+ pointers), the value should be a multiple of 16 minus space for
+ the other structure members including PyHEAD overhead. The larger the
+ value, the less memory overhead per object and the less time spent
+ allocating/deallocating new links. The smaller the number, the less
+ wasted space and the more rapid freeing of older data.
+*/
+#define LINKCELLS 57
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *it;
+ int numread;
+ PyObject *nextlink;
+ PyObject *(values[LINKCELLS]);
+} teedataobject;
+
+typedef struct {
+ PyObject_HEAD
+ teedataobject *dataobj;
+ int index;
+ PyObject *weakreflist;
+} teeobject;
+
+static PyTypeObject teedataobject_type;
+
+static PyObject *
+teedataobject_new(PyObject *it)
+{
+ teedataobject *tdo;
+
+ tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
+ if (tdo == NULL)
+ return NULL;
+
+ tdo->numread = 0;
+ tdo->nextlink = NULL;
+ Py_INCREF(it);
+ tdo->it = it;
+ PyObject_GC_Track(tdo);
+ return (PyObject *)tdo;
+}
+
+static PyObject *
+teedataobject_jumplink(teedataobject *tdo)
+{
+ if (tdo->nextlink == NULL)
+ tdo->nextlink = teedataobject_new(tdo->it);
+ Py_XINCREF(tdo->nextlink);
+ return tdo->nextlink;
+}
+
+static PyObject *
+teedataobject_getitem(teedataobject *tdo, int i)
+{
+ PyObject *value;
+
+ assert(i < LINKCELLS);
+ if (i < tdo->numread)
+ value = tdo->values[i];
+ else {
+ /* this is the lead iterator, so fetch more data */
+ assert(i == tdo->numread);
+ value = PyIter_Next(tdo->it);
+ if (value == NULL)
+ return NULL;
+ tdo->numread++;
+ tdo->values[i] = value;
+ }
+ Py_INCREF(value);
+ return value;
+}
+
+static int
+teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
+{
+ int i;
+ Py_VISIT(tdo->it);
+ for (i = 0; i < tdo->numread; i++)
+ Py_VISIT(tdo->values[i]);
+ Py_VISIT(tdo->nextlink);
+ return 0;
+}
+
+static int
+teedataobject_clear(teedataobject *tdo)
+{
+ int i;
+ Py_CLEAR(tdo->it);
+ for (i=0 ; i<tdo->numread ; i++)
+ Py_CLEAR(tdo->values[i]);
+ Py_CLEAR(tdo->nextlink);
+ return 0;
+}
+
+static void
+teedataobject_dealloc(teedataobject *tdo)
+{
+ PyObject_GC_UnTrack(tdo);
+ teedataobject_clear(tdo);
+ PyObject_GC_Del(tdo);
+}
+
+PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
+
+static PyTypeObject teedataobject_type = {
+ PyObject_HEAD_INIT(0) /* Must fill in type value later */
+ 0, /* ob_size */
+ "itertools.tee_dataobject", /* tp_name */
+ sizeof(teedataobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)teedataobject_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ teedataobject_doc, /* tp_doc */
+ (traverseproc)teedataobject_traverse, /* tp_traverse */
+ (inquiry)teedataobject_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+static PyTypeObject tee_type;
+
+static PyObject *
+tee_next(teeobject *to)
+{
+ PyObject *value, *link;
+
+ if (to->index >= LINKCELLS) {
+ link = teedataobject_jumplink(to->dataobj);
+ Py_DECREF(to->dataobj);
+ to->dataobj = (teedataobject *)link;
+ to->index = 0;
+ }
+ value = teedataobject_getitem(to->dataobj, to->index);
+ if (value == NULL)
+ return NULL;
+ to->index++;
+ return value;
+}
+
+static int
+tee_traverse(teeobject *to, visitproc visit, void *arg)
+{
+ Py_VISIT((PyObject *)to->dataobj);
+ return 0;
+}
+
+static PyObject *
+tee_copy(teeobject *to)
+{
+ teeobject *newto;
+
+ newto = PyObject_GC_New(teeobject, &tee_type);
+ if (newto == NULL)
+ return NULL;
+ Py_INCREF(to->dataobj);
+ newto->dataobj = to->dataobj;
+ newto->index = to->index;
+ newto->weakreflist = NULL;
+ PyObject_GC_Track(newto);
+ return (PyObject *)newto;
+}
+
+PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
+
+static PyObject *
+tee_fromiterable(PyObject *iterable)
+{
+ teeobject *to;
+ PyObject *it = NULL;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+ if (PyObject_TypeCheck(it, &tee_type)) {
+ to = (teeobject *)tee_copy((teeobject *)it);
+ goto done;
+ }
+
+ to = PyObject_GC_New(teeobject, &tee_type);
+ if (to == NULL)
+ goto done;
+ to->dataobj = (teedataobject *)teedataobject_new(it);
+ if (!to->dataobj) {
+ PyObject_GC_Del(to);
+ to = NULL;
+ goto done;
+ }
+
+ to->index = 0;
+ to->weakreflist = NULL;
+ PyObject_GC_Track(to);
+done:
+ Py_XDECREF(it);
+ return (PyObject *)to;
+}
+
+static PyObject *
+tee_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *iterable;
+
+ if (!PyArg_UnpackTuple(args, "tee", 1, 1, &iterable))
+ return NULL;
+ return tee_fromiterable(iterable);
+}
+
+static int
+tee_clear(teeobject *to)
+{
+ if (to->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) to);
+ Py_CLEAR(to->dataobj);
+ return 0;
+}
+
+static void
+tee_dealloc(teeobject *to)
+{
+ PyObject_GC_UnTrack(to);
+ tee_clear(to);
+ PyObject_GC_Del(to);
+}
+
+PyDoc_STRVAR(teeobject_doc,
+"Iterator wrapped to make it copyable");
+
+static PyMethodDef tee_methods[] = {
+ {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject tee_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.tee", /* tp_name */
+ sizeof(teeobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)tee_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ teeobject_doc, /* tp_doc */
+ (traverseproc)tee_traverse, /* tp_traverse */
+ (inquiry)tee_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)tee_next, /* tp_iternext */
+ tee_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ tee_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+static PyObject *
+tee(PyObject *self, PyObject *args)
+{
+ Py_ssize_t i, n=2;
+ PyObject *it, *iterable, *copyable, *result;
+
+ if (!PyArg_ParseTuple(args, "O|n", &iterable, &n))
+ return NULL;
+ if (n < 0) {
+ PyErr_SetString(PyExc_ValueError, "n must be >= 0");
+ return NULL;
+ }
+ result = PyTuple_New(n);
+ if (result == NULL)
+ return NULL;
+ if (n == 0)
+ return result;
+ it = PyObject_GetIter(iterable);
+ if (it == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (!PyObject_HasAttrString(it, "__copy__")) {
+ copyable = tee_fromiterable(it);
+ Py_DECREF(it);
+ if (copyable == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ } else
+ copyable = it;
+ PyTuple_SET_ITEM(result, 0, copyable);
+ for (i=1 ; i<n ; i++) {
+ copyable = PyObject_CallMethod(copyable, "__copy__", NULL);
+ if (copyable == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, copyable);
+ }
+ return result;
+}
+
+PyDoc_STRVAR(tee_doc,
+"tee(iterable, n=2) --> tuple of n independent iterators.");
+
+
+/* cycle object **********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *it;
+ PyObject *saved;
+ int firstpass;
+} cycleobject;
+
+static PyTypeObject cycle_type;
+
+static PyObject *
+cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *it;
+ PyObject *iterable;
+ PyObject *saved;
+ cycleobject *lz;
+
+ if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+
+ saved = PyList_New(0);
+ if (saved == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+
+ /* create cycleobject structure */
+ lz = (cycleobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ Py_DECREF(saved);
+ return NULL;
+ }
+ lz->it = it;
+ lz->saved = saved;
+ lz->firstpass = 0;
+
+ return (PyObject *)lz;
+}
+
+static void
+cycle_dealloc(cycleobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->saved);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->saved);
+ return 0;
+}
+
+static PyObject *
+cycle_next(cycleobject *lz)
+{
+ PyObject *item;
+ PyObject *it;
+ PyObject *tmp;
+
+ while (1) {
+ item = PyIter_Next(lz->it);
+ if (item != NULL) {
+ if (!lz->firstpass)
+ PyList_Append(lz->saved, item);
+ return item;
+ }
+ if (PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ if (PyList_Size(lz->saved) == 0)
+ return NULL;
+ it = PyObject_GetIter(lz->saved);
+ if (it == NULL)
+ return NULL;
+ tmp = lz->it;
+ lz->it = it;
+ lz->firstpass = 1;
+ Py_DECREF(tmp);
+ }
+}
+
+PyDoc_STRVAR(cycle_doc,
+"cycle(iterable) --> cycle object\n\
+\n\
+Return elements from the iterable until it is exhausted.\n\
+Then repeat the sequence indefinitely.");
+
+static PyTypeObject cycle_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.cycle", /* tp_name */
+ sizeof(cycleobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)cycle_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ cycle_doc, /* tp_doc */
+ (traverseproc)cycle_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)cycle_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ cycle_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* dropwhile object **********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+ long start;
+} dropwhileobject;
+
+static PyTypeObject dropwhile_type;
+
+static PyObject *
+dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq;
+ PyObject *it;
+ dropwhileobject *lz;
+
+ if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create dropwhileobject structure */
+ lz = (dropwhileobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+ lz->start = 0;
+
+ return (PyObject *)lz;
+}
+
+static void
+dropwhile_dealloc(dropwhileobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+dropwhile_next(dropwhileobject *lz)
+{
+ PyObject *item, *good;
+ PyObject *it = lz->it;
+ long ok;
+ PyObject *(*iternext)(PyObject *);
+
+ assert(PyIter_Check(it));
+ iternext = *it->ob_type->tp_iternext;
+ for (;;) {
+ item = iternext(it);
+ if (item == NULL)
+ return NULL;
+ if (lz->start == 1)
+ return item;
+
+ good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
+ if (good == NULL) {
+ Py_DECREF(item);
+ return NULL;
+ }
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
+ if (!ok) {
+ lz->start = 1;
+ return item;
+ }
+ Py_DECREF(item);
+ }
+}
+
+PyDoc_STRVAR(dropwhile_doc,
+"dropwhile(predicate, iterable) --> dropwhile object\n\
+\n\
+Drop items from the iterable while predicate(item) is true.\n\
+Afterwards, return every element until the iterable is exhausted.");
+
+static PyTypeObject dropwhile_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.dropwhile", /* tp_name */
+ sizeof(dropwhileobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dropwhile_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ dropwhile_doc, /* tp_doc */
+ (traverseproc)dropwhile_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)dropwhile_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ dropwhile_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* takewhile object **********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+ long stop;
+} takewhileobject;
+
+static PyTypeObject takewhile_type;
+
+static PyObject *
+takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq;
+ PyObject *it;
+ takewhileobject *lz;
+
+ if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create takewhileobject structure */
+ lz = (takewhileobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+ lz->stop = 0;
+
+ return (PyObject *)lz;
+}
+
+static void
+takewhile_dealloc(takewhileobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+takewhile_next(takewhileobject *lz)
+{
+ PyObject *item, *good;
+ PyObject *it = lz->it;
+ long ok;
+
+ if (lz->stop == 1)
+ return NULL;
+
+ assert(PyIter_Check(it));
+ item = (*it->ob_type->tp_iternext)(it);
+ if (item == NULL)
+ return NULL;
+
+ good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
+ if (good == NULL) {
+ Py_DECREF(item);
+ return NULL;
+ }
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
+ if (ok)
+ return item;
+ Py_DECREF(item);
+ lz->stop = 1;
+ return NULL;
+}
+
+PyDoc_STRVAR(takewhile_doc,
+"takewhile(predicate, iterable) --> takewhile object\n\
+\n\
+Return successive entries from an iterable as long as the \n\
+predicate evaluates to true for each entry.");
+
+static PyTypeObject takewhile_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.takewhile", /* tp_name */
+ sizeof(takewhileobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)takewhile_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ takewhile_doc, /* tp_doc */
+ (traverseproc)takewhile_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)takewhile_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ takewhile_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* islice object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *it;
+ Py_ssize_t next;
+ Py_ssize_t stop;
+ Py_ssize_t step;
+ Py_ssize_t cnt;
+} isliceobject;
+
+static PyTypeObject islice_type;
+
+static PyObject *
+islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *seq;
+ Py_ssize_t start=0, stop=-1, step=1;
+ PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
+ Py_ssize_t numargs;
+ isliceobject *lz;
+
+ if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
+ return NULL;
+
+ numargs = PyTuple_Size(args);
+ if (numargs == 2) {
+ if (a1 != Py_None) {
+ stop = PyInt_AsSsize_t(a1);
+ if (stop == -1) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ PyErr_SetString(PyExc_ValueError,
+ "Stop argument for islice() must be a non-negative integer or None.");
+ return NULL;
+ }
+ }
+ } else {
+ if (a1 != Py_None)
+ start = PyInt_AsSsize_t(a1);
+ if (start == -1 && PyErr_Occurred())
+ PyErr_Clear();
+ if (a2 != Py_None) {
+ stop = PyInt_AsSsize_t(a2);
+ if (stop == -1) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ PyErr_SetString(PyExc_ValueError,
+ "Stop argument for islice() must be a non-negative integer or None.");
+ return NULL;
+ }
+ }
+ }
+ if (start<0 || stop<-1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Indices for islice() must be non-negative integers or None.");
+ return NULL;
+ }
+
+ if (a3 != NULL) {
+ if (a3 != Py_None)
+ step = PyInt_AsSsize_t(a3);
+ if (step == -1 && PyErr_Occurred())
+ PyErr_Clear();
+ }
+ if (step<1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Step for islice() must be a positive integer or None.");
+ return NULL;
+ }
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create isliceobject structure */
+ lz = (isliceobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ lz->it = it;
+ lz->next = start;
+ lz->stop = stop;
+ lz->step = step;
+ lz->cnt = 0L;
+
+ return (PyObject *)lz;
+}
+
+static void
+islice_dealloc(isliceobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+islice_traverse(isliceobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ return 0;
+}
+
+static PyObject *
+islice_next(isliceobject *lz)
+{
+ PyObject *item;
+ PyObject *it = lz->it;
+ Py_ssize_t oldnext;
+ PyObject *(*iternext)(PyObject *);
+
+ assert(PyIter_Check(it));
+ iternext = *it->ob_type->tp_iternext;
+ while (lz->cnt < lz->next) {
+ item = iternext(it);
+ if (item == NULL)
+ return NULL;
+ Py_DECREF(item);
+ lz->cnt++;
+ }
+ if (lz->stop != -1 && lz->cnt >= lz->stop)
+ return NULL;
+ assert(PyIter_Check(it));
+ item = iternext(it);
+ if (item == NULL)
+ return NULL;
+ lz->cnt++;
+ oldnext = lz->next;
+ lz->next += lz->step;
+ if (lz->next < oldnext) /* Check for overflow */
+ lz->next = lz->stop;
+ return item;
+}
+
+PyDoc_STRVAR(islice_doc,
+"islice(iterable, [start,] stop [, step]) --> islice object\n\
+\n\
+Return an iterator whose next() method returns selected values from an\n\
+iterable. If start is specified, will skip all preceding elements;\n\
+otherwise, start defaults to zero. Step defaults to one. If\n\
+specified as another value, step determines how many values are \n\
+skipped between successive calls. Works like a slice() on a list\n\
+but returns an iterator.");
+
+static PyTypeObject islice_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.islice", /* tp_name */
+ sizeof(isliceobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)islice_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ islice_doc, /* tp_doc */
+ (traverseproc)islice_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)islice_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ islice_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* starmap object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+} starmapobject;
+
+static PyTypeObject starmap_type;
+
+static PyObject *
+starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq;
+ PyObject *it;
+ starmapobject *lz;
+
+ if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create starmapobject structure */
+ lz = (starmapobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+
+ return (PyObject *)lz;
+}
+
+static void
+starmap_dealloc(starmapobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+starmap_next(starmapobject *lz)
+{
+ PyObject *args;
+ PyObject *result;
+ PyObject *it = lz->it;
+
+ assert(PyIter_Check(it));
+ args = (*it->ob_type->tp_iternext)(it);
+ if (args == NULL)
+ return NULL;
+ if (!PyTuple_CheckExact(args)) {
+ Py_DECREF(args);
+ PyErr_SetString(PyExc_TypeError,
+ "iterator must return a tuple");
+ return NULL;
+ }
+ result = PyObject_Call(lz->func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+
+PyDoc_STRVAR(starmap_doc,
+"starmap(function, sequence) --> starmap object\n\
+\n\
+Return an iterator whose values are returned from the function evaluated\n\
+with a argument tuple taken from the given sequence.");
+
+static PyTypeObject starmap_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.starmap", /* tp_name */
+ sizeof(starmapobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)starmap_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ starmap_doc, /* tp_doc */
+ (traverseproc)starmap_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)starmap_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ starmap_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* imap object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *iters;
+ PyObject *func;
+} imapobject;
+
+static PyTypeObject imap_type;
+
+static PyObject *
+imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *it, *iters, *func;
+ imapobject *lz;
+ Py_ssize_t numargs, i;
+
+ if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds))
+ return NULL;
+
+ numargs = PyTuple_Size(args);
+ if (numargs < 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "imap() must have at least two arguments.");
+ return NULL;
+ }
+
+ iters = PyTuple_New(numargs-1);
+ if (iters == NULL)
+ return NULL;
+
+ for (i=1 ; i<numargs ; i++) {
+ /* Get iterator. */
+ it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
+ if (it == NULL) {
+ Py_DECREF(iters);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(iters, i-1, it);
+ }
+
+ /* create imapobject structure */
+ lz = (imapobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(iters);
+ return NULL;
+ }
+ lz->iters = iters;
+ func = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(func);
+ lz->func = func;
+
+ return (PyObject *)lz;
+}
+
+static void
+imap_dealloc(imapobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->iters);
+ Py_XDECREF(lz->func);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+imap_traverse(imapobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->iters);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+/*
+imap() is an iterator version of __builtins__.map() except that it does
+not have the None fill-in feature. That was intentionally left out for
+the following reasons:
+
+ 1) Itertools are designed to be easily combined and chained together.
+ Having all tools stop with the shortest input is a unifying principle
+ that makes it easier to combine finite iterators (supplying data) with
+ infinite iterators like count() and repeat() (for supplying sequential
+ or constant arguments to a function).
+
+ 2) In typical use cases for combining itertools, having one finite data
+ supplier run out before another is likely to be an error condition which
+ should not pass silently by automatically supplying None.
+
+ 3) The use cases for automatic None fill-in are rare -- not many functions
+ do something useful when a parameter suddenly switches type and becomes
+ None.
+
+ 4) If a need does arise, it can be met by __builtins__.map() or by
+ writing: chain(iterable, repeat(None)).
+
+ 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
+*/
+
+static PyObject *
+imap_next(imapobject *lz)
+{
+ PyObject *val;
+ PyObject *argtuple;
+ PyObject *result;
+ Py_ssize_t numargs, i;
+
+ numargs = PyTuple_Size(lz->iters);
+ argtuple = PyTuple_New(numargs);
+ if (argtuple == NULL)
+ return NULL;
+
+ for (i=0 ; i<numargs ; i++) {
+ val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
+ if (val == NULL) {
+ Py_DECREF(argtuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(argtuple, i, val);
+ }
+ if (lz->func == Py_None)
+ return argtuple;
+ result = PyObject_Call(lz->func, argtuple, NULL);
+ Py_DECREF(argtuple);
+ return result;
+}
+
+PyDoc_STRVAR(imap_doc,
+"imap(func, *iterables) --> imap object\n\
+\n\
+Make an iterator that computes the function using arguments from\n\
+each of the iterables. Like map() except that it returns\n\
+an iterator instead of a list and that it stops when the shortest\n\
+iterable is exhausted instead of filling in None for shorter\n\
+iterables.");
+
+static PyTypeObject imap_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.imap", /* tp_name */
+ sizeof(imapobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)imap_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ imap_doc, /* tp_doc */
+ (traverseproc)imap_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)imap_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ imap_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* chain object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t tuplesize;
+ Py_ssize_t iternum; /* which iterator is active */
+ PyObject *ittuple; /* tuple of iterators */
+} chainobject;
+
+static PyTypeObject chain_type;
+
+static PyObject *
+chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ chainobject *lz;
+ Py_ssize_t tuplesize = PySequence_Length(args);
+ Py_ssize_t i;
+ PyObject *ittuple;
+
+ if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))
+ return NULL;
+
+ /* obtain iterators */
+ assert(PyTuple_Check(args));
+ ittuple = PyTuple_New(tuplesize);
+ if (ittuple == NULL)
+ return NULL;
+ for (i=0; i < tuplesize; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ PyObject *it = PyObject_GetIter(item);
+ if (it == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError,
+ "chain argument #%zd must support iteration",
+ i+1);
+ Py_DECREF(ittuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(ittuple, i, it);
+ }
+
+ /* create chainobject structure */
+ lz = (chainobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(ittuple);
+ return NULL;
+ }
+
+ lz->ittuple = ittuple;
+ lz->iternum = 0;
+ lz->tuplesize = tuplesize;
+
+ return (PyObject *)lz;
+}
+
+static void
+chain_dealloc(chainobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->ittuple);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+chain_traverse(chainobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->ittuple);
+ return 0;
+}
+
+static PyObject *
+chain_next(chainobject *lz)
+{
+ PyObject *it;
+ PyObject *item;
+
+ while (lz->iternum < lz->tuplesize) {
+ it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
+ item = PyIter_Next(it);
+ if (item != NULL)
+ return item;
+ if (PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ lz->iternum++;
+ }
+ return NULL;
+}
+
+PyDoc_STRVAR(chain_doc,
+"chain(*iterables) --> chain object\n\
+\n\
+Return a chain object whose .next() method returns elements from the\n\
+first iterable until it is exhausted, then elements from the next\n\
+iterable, until all of the iterables are exhausted.");
+
+static PyTypeObject chain_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.chain", /* tp_name */
+ sizeof(chainobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)chain_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ chain_doc, /* tp_doc */
+ (traverseproc)chain_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)chain_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ chain_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* ifilter object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+} ifilterobject;
+
+static PyTypeObject ifilter_type;
+
+static PyObject *
+ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq;
+ PyObject *it;
+ ifilterobject *lz;
+
+ if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create ifilterobject structure */
+ lz = (ifilterobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+
+ return (PyObject *)lz;
+}
+
+static void
+ifilter_dealloc(ifilterobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+ifilter_next(ifilterobject *lz)
+{
+ PyObject *item;
+ PyObject *it = lz->it;
+ long ok;
+ PyObject *(*iternext)(PyObject *);
+
+ assert(PyIter_Check(it));
+ iternext = *it->ob_type->tp_iternext;
+ for (;;) {
+ item = iternext(it);
+ if (item == NULL)
+ return NULL;
+
+ if (lz->func == Py_None) {
+ ok = PyObject_IsTrue(item);
+ } else {
+ PyObject *good;
+ good = PyObject_CallFunctionObjArgs(lz->func,
+ item, NULL);
+ if (good == NULL) {
+ Py_DECREF(item);
+ return NULL;
+ }
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
+ }
+ if (ok)
+ return item;
+ Py_DECREF(item);
+ }
+}
+
+PyDoc_STRVAR(ifilter_doc,
+"ifilter(function or None, sequence) --> ifilter object\n\
+\n\
+Return those items of sequence for which function(item) is true.\n\
+If function is None, return the items that are true.");
+
+static PyTypeObject ifilter_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.ifilter", /* tp_name */
+ sizeof(ifilterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)ifilter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ ifilter_doc, /* tp_doc */
+ (traverseproc)ifilter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)ifilter_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ifilter_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* ifilterfalse object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+} ifilterfalseobject;
+
+static PyTypeObject ifilterfalse_type;
+
+static PyObject *
+ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq;
+ PyObject *it;
+ ifilterfalseobject *lz;
+
+ if (type == &ifilterfalse_type &&
+ !_PyArg_NoKeywords("ifilterfalse()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create ifilterfalseobject structure */
+ lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+
+ return (PyObject *)lz;
+}
+
+static void
+ifilterfalse_dealloc(ifilterfalseobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->it);
+ Py_VISIT(lz->func);
+ return 0;
+}
+
+static PyObject *
+ifilterfalse_next(ifilterfalseobject *lz)
+{
+ PyObject *item;
+ PyObject *it = lz->it;
+ long ok;
+ PyObject *(*iternext)(PyObject *);
+
+ assert(PyIter_Check(it));
+ iternext = *it->ob_type->tp_iternext;
+ for (;;) {
+ item = iternext(it);
+ if (item == NULL)
+ return NULL;
+
+ if (lz->func == Py_None) {
+ ok = PyObject_IsTrue(item);
+ } else {
+ PyObject *good;
+ good = PyObject_CallFunctionObjArgs(lz->func,
+ item, NULL);
+ if (good == NULL) {
+ Py_DECREF(item);
+ return NULL;
+ }
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
+ }
+ if (!ok)
+ return item;
+ Py_DECREF(item);
+ }
+}
+
+PyDoc_STRVAR(ifilterfalse_doc,
+"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
+\n\
+Return those items of sequence for which function(item) is false.\n\
+If function is None, return the items that are false.");
+
+static PyTypeObject ifilterfalse_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.ifilterfalse", /* tp_name */
+ sizeof(ifilterfalseobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)ifilterfalse_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ ifilterfalse_doc, /* tp_doc */
+ (traverseproc)ifilterfalse_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)ifilterfalse_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ifilterfalse_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* count object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t cnt;
+} countobject;
+
+static PyTypeObject count_type;
+
+static PyObject *
+count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ countobject *lz;
+ Py_ssize_t cnt = 0;
+
+ if (type == &count_type && !_PyArg_NoKeywords("count()", kwds))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "|n:count", &cnt))
+ return NULL;
+
+ /* create countobject structure */
+ lz = (countobject *)PyObject_New(countobject, &count_type);
+ if (lz == NULL)
+ return NULL;
+ lz->cnt = cnt;
+
+ return (PyObject *)lz;
+}
+
+static PyObject *
+count_next(countobject *lz)
+{
+ if (lz->cnt == LONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot count beyond LONG_MAX");
+ return NULL;
+ }
+ return PyInt_FromSsize_t(lz->cnt++);
+}
+
+static PyObject *
+count_repr(countobject *lz)
+{
+ return PyString_FromFormat("count(%zd)", lz->cnt);
+}
+
+PyDoc_STRVAR(count_doc,
+"count([firstval]) --> count object\n\
+\n\
+Return a count object whose .next() method returns consecutive\n\
+integers starting from zero or, if specified, from firstval.");
+
+static PyTypeObject count_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.count", /* tp_name */
+ sizeof(countobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)PyObject_Del, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)count_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ count_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)count_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ count_new, /* tp_new */
+};
+
+
+/* izip object ************************************************************/
+
+#include "Python.h"
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t tuplesize;
+ PyObject *ittuple; /* tuple of iterators */
+ PyObject *result;
+} izipobject;
+
+static PyTypeObject izip_type;
+
+static PyObject *
+izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ izipobject *lz;
+ Py_ssize_t i;
+ PyObject *ittuple; /* tuple of iterators */
+ PyObject *result;
+ Py_ssize_t tuplesize = PySequence_Length(args);
+
+ if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds))
+ return NULL;
+
+ /* args must be a tuple */
+ assert(PyTuple_Check(args));
+
+ /* obtain iterators */
+ ittuple = PyTuple_New(tuplesize);
+ if (ittuple == NULL)
+ return NULL;
+ for (i=0; i < tuplesize; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ PyObject *it = PyObject_GetIter(item);
+ if (it == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError,
+ "izip argument #%zd must support iteration",
+ i+1);
+ Py_DECREF(ittuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(ittuple, i, it);
+ }
+
+ /* create a result holder */
+ result = PyTuple_New(tuplesize);
+ if (result == NULL) {
+ Py_DECREF(ittuple);
+ return NULL;
+ }
+ for (i=0 ; i < tuplesize ; i++) {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(result, i, Py_None);
+ }
+
+ /* create izipobject structure */
+ lz = (izipobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(ittuple);
+ Py_DECREF(result);
+ return NULL;
+ }
+ lz->ittuple = ittuple;
+ lz->tuplesize = tuplesize;
+ lz->result = result;
+
+ return (PyObject *)lz;
+}
+
+static void
+izip_dealloc(izipobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->ittuple);
+ Py_XDECREF(lz->result);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+izip_traverse(izipobject *lz, visitproc visit, void *arg)
+{
+ Py_VISIT(lz->ittuple);
+ Py_VISIT(lz->result);
+ return 0;
+}
+
+static PyObject *
+izip_next(izipobject *lz)
+{
+ Py_ssize_t i;
+ Py_ssize_t tuplesize = lz->tuplesize;
+ PyObject *result = lz->result;
+ PyObject *it;
+ PyObject *item;
+ PyObject *olditem;
+
+ if (tuplesize == 0)
+ return NULL;
+ if (result->ob_refcnt == 1) {
+ Py_INCREF(result);
+ for (i=0 ; i < tuplesize ; i++) {
+ it = PyTuple_GET_ITEM(lz->ittuple, i);
+ assert(PyIter_Check(it));
+ item = (*it->ob_type->tp_iternext)(it);
+ if (item == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ olditem = PyTuple_GET_ITEM(result, i);
+ PyTuple_SET_ITEM(result, i, item);
+ Py_DECREF(olditem);
+ }
+ } else {
+ result = PyTuple_New(tuplesize);
+ if (result == NULL)
+ return NULL;
+ for (i=0 ; i < tuplesize ; i++) {
+ it = PyTuple_GET_ITEM(lz->ittuple, i);
+ assert(PyIter_Check(it));
+ item = (*it->ob_type->tp_iternext)(it);
+ if (item == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, item);
+ }
+ }
+ return result;
+}
+
+PyDoc_STRVAR(izip_doc,
+"izip(iter1 [,iter2 [...]]) --> izip object\n\
+\n\
+Return a izip object whose .next() method returns a tuple where\n\
+the i-th element comes from the i-th iterable argument. The .next()\n\
+method continues until the shortest iterable in the argument sequence\n\
+is exhausted and then it raises StopIteration. Works like the zip()\n\
+function but consumes less memory by returning an iterator instead of\n\
+a list.");
+
+static PyTypeObject izip_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.izip", /* tp_name */
+ sizeof(izipobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)izip_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ izip_doc, /* tp_doc */
+ (traverseproc)izip_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)izip_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ izip_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* repeat object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *element;
+ Py_ssize_t cnt;
+} repeatobject;
+
+static PyTypeObject repeat_type;
+
+static PyObject *
+repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ repeatobject *ro;
+ PyObject *element;
+ Py_ssize_t cnt = -1;
+
+ if (type == &repeat_type && !_PyArg_NoKeywords("repeat()", kwds))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt))
+ return NULL;
+
+ if (PyTuple_Size(args) == 2 && cnt < 0)
+ cnt = 0;
+
+ ro = (repeatobject *)type->tp_alloc(type, 0);
+ if (ro == NULL)
+ return NULL;
+ Py_INCREF(element);
+ ro->element = element;
+ ro->cnt = cnt;
+ return (PyObject *)ro;
+}
+
+static void
+repeat_dealloc(repeatobject *ro)
+{
+ PyObject_GC_UnTrack(ro);
+ Py_XDECREF(ro->element);
+ ro->ob_type->tp_free(ro);
+}
+
+static int
+repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
+{
+ Py_VISIT(ro->element);
+ return 0;
+}
+
+static PyObject *
+repeat_next(repeatobject *ro)
+{
+ if (ro->cnt == 0)
+ return NULL;
+ if (ro->cnt > 0)
+ ro->cnt--;
+ Py_INCREF(ro->element);
+ return ro->element;
+}
+
+static PyObject *
+repeat_repr(repeatobject *ro)
+{
+ PyObject *result, *objrepr;
+
+ objrepr = PyObject_Repr(ro->element);
+ if (objrepr == NULL)
+ return NULL;
+
+ if (ro->cnt == -1)
+ result = PyString_FromFormat("repeat(%s)",
+ PyString_AS_STRING(objrepr));
+ else
+ result = PyString_FromFormat("repeat(%s, %zd)",
+ PyString_AS_STRING(objrepr), ro->cnt);
+ Py_DECREF(objrepr);
+ return result;
+}
+
+static PyObject *
+repeat_len(repeatobject *ro)
+{
+ if (ro->cnt == -1) {
+ PyErr_SetString(PyExc_TypeError, "len() of unsized object");
+ return NULL;
+ }
+ return PyInt_FromSize_t(ro->cnt);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef repeat_methods[] = {
+ {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(repeat_doc,
+"repeat(element [,times]) -> create an iterator which returns the element\n\
+for the specified number of times. If not specified, returns the element\n\
+endlessly.");
+
+static PyTypeObject repeat_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.repeat", /* tp_name */
+ sizeof(repeatobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)repeat_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)repeat_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ repeat_doc, /* tp_doc */
+ (traverseproc)repeat_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)repeat_next, /* tp_iternext */
+ repeat_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ repeat_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* module level code ********************************************************/
+
+PyDoc_STRVAR(module_doc,
+"Functional tools for creating and using iterators.\n\
+\n\
+Infinite iterators:\n\
+count([n]) --> n, n+1, n+2, ...\n\
+cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
+repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
+\n\
+Iterators terminating on the shortest input sequence:\n\
+izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
+ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
+ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
+islice(seq, [start,] stop [, step]) --> elements from\n\
+ seq[start:stop:step]\n\
+imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
+starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
+tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
+chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
+takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
+dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
+groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\
+");
+
+
+static PyMethodDef module_methods[] = {
+ {"tee", (PyCFunction)tee, METH_VARARGS, tee_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+inititertools(void)
+{
+ int i;
+ PyObject *m;
+ char *name;
+ PyTypeObject *typelist[] = {
+ &cycle_type,
+ &dropwhile_type,
+ &takewhile_type,
+ &islice_type,
+ &starmap_type,
+ &imap_type,
+ &chain_type,
+ &ifilter_type,
+ &ifilterfalse_type,
+ &count_type,
+ &izip_type,
+ &repeat_type,
+ &groupby_type,
+ NULL
+ };
+
+ teedataobject_type.ob_type = &PyType_Type;
+ m = Py_InitModule3("itertools", module_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ for (i=0 ; typelist[i] != NULL ; i++) {
+ if (PyType_Ready(typelist[i]) < 0)
+ return;
+ name = strchr(typelist[i]->tp_name, '.');
+ assert (name != NULL);
+ Py_INCREF(typelist[i]);
+ PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
+ }
+
+ if (PyType_Ready(&teedataobject_type) < 0)
+ return;
+ if (PyType_Ready(&tee_type) < 0)
+ return;
+ if (PyType_Ready(&_grouper_type) < 0)
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/ld_so_aix b/sys/src/cmd/python/Modules/ld_so_aix
new file mode 100755
index 000000000..76afa6e48
--- /dev/null
+++ b/sys/src/cmd/python/Modules/ld_so_aix
@@ -0,0 +1,187 @@
+#!/bin/sh
+#
+# ========================================================================
+# FILE: ld_so_aix
+# TYPE: executable, uses makexp_aix
+# SYSTEM: AIX
+#
+# DESCRIPTION: Creates a shareable .o from a set of pre-compiled
+# (unshared) .o files
+#
+# USAGE: ld_so_aix [CC] [arguments]
+#
+# ARGUMENTS: Same as for "ld". The following arguments are processed
+# or supplied by this script (those marked with an asterisk
+# can be overriden from command line):
+#
+# Argument Default value
+# (*) -o [OutputFileName] -o shr.o
+# (*) -e [EntryPointLabel] -e init[OutputBaseName]
+# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp
+# (*) -bI:[ImportFile] -bI:./python.exp
+# -bM:[ModuleType] -bM:SRE
+# -bhalt:[Number] -bhalt:4
+# -T[Number] -T512
+# -H[Number] -H512
+# -lm
+#
+# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...)
+# arguments will be automatically passed to "ld" according
+# to the CC command provided as a first argument to this
+# script. Usually, the same CC command was used to produce
+# the pre-compiled .o file(s).
+#
+# NOTES: 1. Since "ld_so_aix" was originally written for building
+# shared modules for the Python interpreter, the -e and
+# -bI default values match Python's conventions. In
+# Python, the entry point for a shared module is based
+# on the module's name (e.g., the "mathmodule" will
+# expect an entry point of "initmath").
+# 2. The script accepts multiple .o or .a input files and
+# creates a single (shared) output file. The export list
+# that is created is based on the output file's basename
+# with the suffix ".exp".
+# 3. The resulting shared object file is left in the
+# current directory.
+# 4. Uncommenting the "echo" lines gives detailed output
+# about the commands executed in the script.
+#
+#
+# HISTORY: Oct-1996 -- Support added for multiple .o files --
+# -- and optional arguments processing. --
+# Chris Myers (myers@tc.cornell.edu), Keith Kwok
+# (kkwok@tc.cornell.edu) and Vladimir Marangozov
+#
+# Aug-6-1996 -- Take care of the compiler specific --
+# -- args by leaving CC to invoke "ld". --
+# Vladimir Marangozov
+#
+# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld --
+# -- Use makexp_aix for the export list. --
+# Vladimir Marangozov (Vladimir.Marangozov@imag.fr)
+#
+# Manus Hand (mhand@csn.net) -- Initial code -- 6/24/96
+# ========================================================================
+#
+
+usage="Usage: ld_so_aix [CC command] [ld arguments]"
+if test ! -n "$*"; then
+ echo $usage; exit 2
+fi
+
+makexp=`dirname $0`/makexp_aix
+
+# Check for existence of compiler.
+CC=$1; shift
+whichcc=`which $CC`
+
+if test ! -x "$whichcc"; then
+ echo "ld_so_aix: Compiler '$CC' not found; exiting."
+ exit 2
+fi
+
+if test ! -n "$*"; then
+ echo $usage; exit 2
+fi
+
+# Default import file for Python
+# Can be overriden by providing a -bI: argument.
+impfile="./python.exp"
+
+# Parse arguments
+while test -n "$1"
+do
+ case "$1" in
+ -e | -Wl,-e)
+ if test -z "$2"; then
+ echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2
+ else
+ shift; entry=$1
+ fi
+ ;;
+ -e* | -Wl,-e*)
+ entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"`
+ ;;
+ -o)
+ if test -z "$2"; then
+ echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2
+ else
+ shift; objfile=$1
+ fi
+ ;;
+ -o*)
+ objfile=`echo $1 | sed "s/-o//"`
+ ;;
+ -bI:* | -Wl,-bI:*)
+ impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"`
+ ;;
+ -bE:* | -Wl,-bE:*)
+ expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"`
+ ;;
+ *.o | *.a)
+ objs="$objs $1"
+ args="$args $1"
+ ;;
+ -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm)
+ ;;
+ *)
+ args="$args $1"
+ ;;
+ esac
+ shift
+done
+
+
+if test -z "$objs"; then
+ echo "ld_so_aix: No input files; exiting."
+ exit 2
+elif test ! -r "$impfile"; then
+ echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting."
+ exit 2
+fi
+
+# If -o wasn't specified, assume "-o shr.o"
+if test -z "$objfile"; then
+ objfile=shr.o
+fi
+
+filename=`basename $objfile | sed "s/\.[^.]*$//"`
+
+# If -bE: wasn't specified, assume "-bE:$filename.exp"
+if test -z "$expfile"; then
+ expfile="$filename.exp"
+fi
+
+# Default entry symbol for Python modules = init[modulename]
+# Can be overriden by providing a -e argument.
+if test -z "$entry"; then
+ entry=init`echo $filename | sed "s/module.*//"`
+fi
+
+#echo "ld_so_aix: Debug info section"
+#echo " -> output file : $objfile"
+#echo " -> import file : $impfile"
+#echo " -> export file : $expfile"
+#echo " -> entry point : $entry"
+#echo " -> object files: $objs"
+#echo " -> CC arguments: $args"
+
+CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
+CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile"
+# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so
+# you may need to replace the second CCOPT line above with the following:
+# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile"
+
+CCARGS="$args"
+
+# Export list generation.
+#echo $makexp $expfile "$objfile" $objs
+$makexp $expfile "$objfile" $objs
+
+# Perform the link.
+#echo $CC $CCOPT $CCARGS
+$CC $CCOPT $CCARGS
+
+# Delete the module's export list file.
+# Comment this line if you need it.
+rm -f $expfile
diff --git a/sys/src/cmd/python/Modules/ld_so_beos b/sys/src/cmd/python/Modules/ld_so_beos
new file mode 100755
index 000000000..0b867fbde
--- /dev/null
+++ b/sys/src/cmd/python/Modules/ld_so_beos
@@ -0,0 +1,78 @@
+#! /bin/sh
+#
+# linkmodule for Python
+# Chris Herborth (chrish@qnx.com)
+#
+# This is covered by the same copyright/licensing terms as the rest of
+# Python.
+#
+# Shell script to build shared library versions of the modules; since
+# the change to the *ahem* "proper" import/export mechanism, this script
+# is much simpler. It handles PowerPC and x86, too.
+#
+# This is called by the Modules/Makefile as $(LDSHARED):
+#
+# $(LDSHARED) foomodule.o -o foomodule$(SO)
+#
+# Could also be called as:
+#
+# $(LDSHARED) readline.o -L/boot/home/config/lib -lreadline -ltermcap \
+# -o readline$(SO)
+#
+# so we need to preserve the arguments, sort of.
+
+# Make sure we got reasonable arguments.
+TARGET=""
+ARGS=""
+
+while [ "$#" != "0" ]; do
+ case "$1" in
+ -o) TARGET="$2"; shift; shift;;
+ *) ARGS="$ARGS $1"; shift;;
+ esac
+done
+
+if [ "$TARGET" = "" ] ; then
+ echo "Usage:"
+ echo
+ echo " $0 [args] -o foomodule.so [args] foomodule.o [args]"
+ echo
+ echo "Where:"
+ echo
+ echo " [args] normal compiler arguments"
+ exit 1
+fi
+
+# The shared libraries and glue objects we need to link against; these
+# libs are overkill for most of the standard modules, but it makes life
+# in this shell script easier.
+LIBS="-lbe -lnet -lroot"
+
+case $BE_HOST_CPU in
+ ppc)
+ # Boy, do we need a lot of crap...
+ GLUE_LOC=/boot/develop/lib/ppc
+ GLUE="${GLUE_LOC}/glue-noinit.a ${GLUE_LOC}/init_term_dyn.o"
+ case $(uname -r) in
+ 4.0*) CC="mwcc -xms -export pragma -nodup" ;;
+ *) CC="mwcc -shared -export pragma -nodup" ;;
+ esac
+ ;;
+
+ x86)
+ # We don't need as much crap here...
+ GLUE=""
+ CC="gcc -nostart -Wl,-soname=${TARGET}"
+ ;;
+
+ *)
+ # What the?!?
+ echo "$0 doesn't support $BE_HOST_CPU systems..."
+ echo "You're on your own... I'd be surprised if this works."
+ GLUE=""
+ CC="cc"
+ ;;
+esac
+
+# Now link that shared lib...
+$CC -o $TARGET $ARGS $GLUE $LIBS
diff --git a/sys/src/cmd/python/Modules/linuxaudiodev.c b/sys/src/cmd/python/Modules/linuxaudiodev.c
new file mode 100644
index 000000000..b435d768a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/linuxaudiodev.c
@@ -0,0 +1,502 @@
+/* Hey Emacs, this is -*-C-*-
+ ******************************************************************************
+ * linuxaudiodev.c -- Linux audio device for python.
+ *
+ * Author : Peter Bosch
+ * Created On : Thu Mar 2 21:10:33 2000
+ * Status : Unknown, Use with caution!
+ *
+ * Unless other notices are present in any part of this file
+ * explicitly claiming copyrights for other people and/or
+ * organizations, the contents of this file is fully copyright
+ * (C) 2000 Peter Bosch, all rights reserved.
+ ******************************************************************************
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#define O_RDONLY 00
+#define O_WRONLY 01
+#endif
+
+
+#include <sys/ioctl.h>
+#if defined(linux)
+#include <linux/soundcard.h>
+
+#ifndef HAVE_STDINT_H
+typedef unsigned long uint32_t;
+#endif
+
+#elif defined(__FreeBSD__)
+#include <machine/soundcard.h>
+
+#ifndef SNDCTL_DSP_CHANNELS
+#define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
+#endif
+
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ int x_fd; /* The open file */
+ int x_mode; /* file mode */
+ int x_icount; /* Input count */
+ int x_ocount; /* Output count */
+ uint32_t x_afmts; /* Audio formats supported by hardware*/
+} lad_t;
+
+/* XXX several format defined in soundcard.h are not supported,
+ including _NE (native endian) options and S32 options
+*/
+
+static struct {
+ int a_bps;
+ uint32_t a_fmt;
+ char *a_name;
+} audio_types[] = {
+ { 8, AFMT_MU_LAW, "logarithmic mu-law 8-bit audio" },
+ { 8, AFMT_A_LAW, "logarithmic A-law 8-bit audio" },
+ { 8, AFMT_U8, "linear unsigned 8-bit audio" },
+ { 8, AFMT_S8, "linear signed 8-bit audio" },
+ { 16, AFMT_U16_BE, "linear unsigned 16-bit big-endian audio" },
+ { 16, AFMT_U16_LE, "linear unsigned 16-bit little-endian audio" },
+ { 16, AFMT_S16_BE, "linear signed 16-bit big-endian audio" },
+ { 16, AFMT_S16_LE, "linear signed 16-bit little-endian audio" },
+ { 16, AFMT_S16_NE, "linear signed 16-bit native-endian audio" },
+};
+
+static int n_audio_types = sizeof(audio_types) / sizeof(audio_types[0]);
+
+static PyTypeObject Ladtype;
+
+static PyObject *LinuxAudioError;
+
+static lad_t *
+newladobject(PyObject *arg)
+{
+ lad_t *xp;
+ int fd, afmts, imode;
+ char *basedev = NULL;
+ char *mode = NULL;
+
+ /* Two ways to call linuxaudiodev.open():
+ open(device, mode) (for consistency with builtin open())
+ open(mode) (for backwards compatibility)
+ because the *first* argument is optional, parsing args is
+ a wee bit tricky. */
+ if (!PyArg_ParseTuple(arg, "s|s:open", &basedev, &mode))
+ return NULL;
+ if (mode == NULL) { /* only one arg supplied */
+ mode = basedev;
+ basedev = NULL;
+ }
+
+ if (strcmp(mode, "r") == 0)
+ imode = O_RDONLY;
+ else if (strcmp(mode, "w") == 0)
+ imode = O_WRONLY;
+ else {
+ PyErr_SetString(LinuxAudioError, "mode should be 'r' or 'w'");
+ return NULL;
+ }
+
+ /* Open the correct device. The base device name comes from the
+ * AUDIODEV environment variable first, then /dev/dsp. The
+ * control device tacks "ctl" onto the base device name.
+ *
+ * Note that the only difference between /dev/audio and /dev/dsp
+ * is that the former uses logarithmic mu-law encoding and the
+ * latter uses 8-bit unsigned encoding.
+ */
+
+ if (basedev == NULL) { /* called with one arg */
+ basedev = getenv("AUDIODEV");
+ if (basedev == NULL) /* $AUDIODEV not set */
+ basedev = "/dev/dsp";
+ }
+
+ if ((fd = open(basedev, imode)) == -1) {
+ PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
+ return NULL;
+ }
+ if (imode == O_WRONLY && ioctl(fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) {
+ PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
+ return NULL;
+ }
+ if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
+ PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
+ return NULL;
+ }
+ /* Create and initialize the object */
+ if ((xp = PyObject_New(lad_t, &Ladtype)) == NULL) {
+ close(fd);
+ return NULL;
+ }
+ xp->x_fd = fd;
+ xp->x_mode = imode;
+ xp->x_icount = xp->x_ocount = 0;
+ xp->x_afmts = afmts;
+ return xp;
+}
+
+static void
+lad_dealloc(lad_t *xp)
+{
+ /* if already closed, don't reclose it */
+ if (xp->x_fd != -1)
+ close(xp->x_fd);
+ PyObject_Del(xp);
+}
+
+static PyObject *
+lad_read(lad_t *self, PyObject *args)
+{
+ int size, count;
+ char *cp;
+ PyObject *rv;
+
+ if (!PyArg_ParseTuple(args, "i:read", &size))
+ return NULL;
+ rv = PyString_FromStringAndSize(NULL, size);
+ if (rv == NULL)
+ return NULL;
+ cp = PyString_AS_STRING(rv);
+ if ((count = read(self->x_fd, cp, size)) < 0) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ Py_DECREF(rv);
+ return NULL;
+ }
+ self->x_icount += count;
+ _PyString_Resize(&rv, count);
+ return rv;
+}
+
+static PyObject *
+lad_write(lad_t *self, PyObject *args)
+{
+ char *cp;
+ int rv, size;
+ fd_set write_set_fds;
+ struct timeval tv;
+ int select_retval;
+
+ if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
+ return NULL;
+
+ /* use select to wait for audio device to be available */
+ FD_ZERO(&write_set_fds);
+ FD_SET(self->x_fd, &write_set_fds);
+ tv.tv_sec = 4; /* timeout values */
+ tv.tv_usec = 0;
+
+ while (size > 0) {
+ select_retval = select(self->x_fd+1, NULL, &write_set_fds, NULL, &tv);
+ tv.tv_sec = 1; tv.tv_usec = 0; /* willing to wait this long next time*/
+ if (select_retval) {
+ if ((rv = write(self->x_fd, cp, size)) == -1) {
+ if (errno != EAGAIN) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ } else {
+ errno = 0; /* EAGAIN: buffer is full, try again */
+ }
+ } else {
+ self->x_ocount += rv;
+ size -= rv;
+ cp += rv;
+ }
+ } else {
+ /* printf("Not able to write to linux audio device within %ld seconds\n", tv.tv_sec); */
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+lad_close(lad_t *self, PyObject *unused)
+{
+ if (self->x_fd >= 0) {
+ close(self->x_fd);
+ self->x_fd = -1;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+lad_fileno(lad_t *self, PyObject *unused)
+{
+ return PyInt_FromLong(self->x_fd);
+}
+
+static PyObject *
+lad_setparameters(lad_t *self, PyObject *args)
+{
+ int rate, ssize, nchannels, n, fmt, emulate=0;
+
+ if (!PyArg_ParseTuple(args, "iiii|i:setparameters",
+ &rate, &ssize, &nchannels, &fmt, &emulate))
+ return NULL;
+
+ if (rate < 0) {
+ PyErr_Format(PyExc_ValueError, "expected rate >= 0, not %d",
+ rate);
+ return NULL;
+ }
+ if (ssize < 0) {
+ PyErr_Format(PyExc_ValueError, "expected sample size >= 0, not %d",
+ ssize);
+ return NULL;
+ }
+ if (nchannels != 1 && nchannels != 2) {
+ PyErr_Format(PyExc_ValueError, "nchannels must be 1 or 2, not %d",
+ nchannels);
+ return NULL;
+ }
+
+ for (n = 0; n < n_audio_types; n++)
+ if (fmt == audio_types[n].a_fmt)
+ break;
+ if (n == n_audio_types) {
+ PyErr_Format(PyExc_ValueError, "unknown audio encoding: %d", fmt);
+ return NULL;
+ }
+ if (audio_types[n].a_bps != ssize) {
+ PyErr_Format(PyExc_ValueError,
+ "for %s, expected sample size %d, not %d",
+ audio_types[n].a_name, audio_types[n].a_bps, ssize);
+ return NULL;
+ }
+
+ if (emulate == 0) {
+ if ((self->x_afmts & audio_types[n].a_fmt) == 0) {
+ PyErr_Format(PyExc_ValueError,
+ "%s format not supported by device",
+ audio_types[n].a_name);
+ return NULL;
+ }
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT,
+ &audio_types[n].a_fmt) == -1) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_SPEED, &rate) == -1) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int
+_ssize(lad_t *self, int *nchannels, int *ssize)
+{
+ int fmt;
+
+ fmt = 0;
+ if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
+ return -errno;
+
+ switch (fmt) {
+ case AFMT_MU_LAW:
+ case AFMT_A_LAW:
+ case AFMT_U8:
+ case AFMT_S8:
+ *ssize = sizeof(char);
+ break;
+ case AFMT_S16_LE:
+ case AFMT_S16_BE:
+ case AFMT_U16_LE:
+ case AFMT_U16_BE:
+ *ssize = sizeof(short);
+ break;
+ case AFMT_MPEG:
+ case AFMT_IMA_ADPCM:
+ default:
+ return -EOPNOTSUPP;
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
+ return -errno;
+ return 0;
+}
+
+
+/* bufsize returns the size of the hardware audio buffer in number
+ of samples */
+static PyObject *
+lad_bufsize(lad_t *self, PyObject *unused)
+{
+ audio_buf_info ai;
+ int nchannels=0, ssize=0;
+
+ if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
+}
+
+/* obufcount returns the number of samples that are available in the
+ hardware for playing */
+static PyObject *
+lad_obufcount(lad_t *self, PyObject *unused)
+{
+ audio_buf_info ai;
+ int nchannels=0, ssize=0;
+
+ if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) /
+ (ssize * nchannels));
+}
+
+/* obufcount returns the number of samples that can be played without
+ blocking */
+static PyObject *
+lad_obuffree(lad_t *self, PyObject *unused)
+{
+ audio_buf_info ai;
+ int nchannels=0, ssize=0;
+
+ if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ return PyInt_FromLong(ai.bytes / (ssize * nchannels));
+}
+
+/* Flush the device */
+static PyObject *
+lad_flush(lad_t *self, PyObject *unused)
+{
+ if (ioctl(self->x_fd, SNDCTL_DSP_SYNC, NULL) == -1) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+lad_getptr(lad_t *self, PyObject *unused)
+{
+ count_info info;
+ int req;
+
+ if (self->x_mode == O_RDONLY)
+ req = SNDCTL_DSP_GETIPTR;
+ else
+ req = SNDCTL_DSP_GETOPTR;
+ if (ioctl(self->x_fd, req, &info) == -1) {
+ PyErr_SetFromErrno(LinuxAudioError);
+ return NULL;
+ }
+ return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
+}
+
+static PyMethodDef lad_methods[] = {
+ { "read", (PyCFunction)lad_read, METH_VARARGS },
+ { "write", (PyCFunction)lad_write, METH_VARARGS },
+ { "setparameters", (PyCFunction)lad_setparameters, METH_VARARGS },
+ { "bufsize", (PyCFunction)lad_bufsize, METH_VARARGS },
+ { "obufcount", (PyCFunction)lad_obufcount, METH_NOARGS },
+ { "obuffree", (PyCFunction)lad_obuffree, METH_NOARGS },
+ { "flush", (PyCFunction)lad_flush, METH_NOARGS },
+ { "close", (PyCFunction)lad_close, METH_NOARGS },
+ { "fileno", (PyCFunction)lad_fileno, METH_NOARGS },
+ { "getptr", (PyCFunction)lad_getptr, METH_NOARGS },
+ { NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+lad_getattr(lad_t *xp, char *name)
+{
+ return Py_FindMethod(lad_methods, (PyObject *)xp, name);
+}
+
+static PyTypeObject Ladtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "linuxaudiodev.linux_audio_device", /*tp_name*/
+ sizeof(lad_t), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)lad_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)lad_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyObject *
+ladopen(PyObject *self, PyObject *args)
+{
+ return (PyObject *)newladobject(args);
+}
+
+static PyMethodDef linuxaudiodev_methods[] = {
+ { "open", ladopen, METH_VARARGS },
+ { 0, 0 },
+};
+
+void
+initlinuxaudiodev(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule("linuxaudiodev", linuxaudiodev_methods);
+ if (m == NULL)
+ return;
+
+ LinuxAudioError = PyErr_NewException("linuxaudiodev.error", NULL, NULL);
+ if (LinuxAudioError)
+ PyModule_AddObject(m, "error", LinuxAudioError);
+
+ if (PyModule_AddIntConstant(m, "AFMT_MU_LAW", (long)AFMT_MU_LAW) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_A_LAW", (long)AFMT_A_LAW) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_U8", (long)AFMT_U8) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_S8", (long)AFMT_S8) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_U16_BE", (long)AFMT_U16_BE) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_U16_LE", (long)AFMT_U16_LE) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_S16_BE", (long)AFMT_S16_BE) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_S16_LE", (long)AFMT_S16_LE) == -1)
+ return;
+ if (PyModule_AddIntConstant(m, "AFMT_S16_NE", (long)AFMT_S16_NE) == -1)
+ return;
+
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/main.c b/sys/src/cmd/python/Modules/main.c
new file mode 100644
index 000000000..83d567fed
--- /dev/null
+++ b/sys/src/cmd/python/Modules/main.c
@@ -0,0 +1,584 @@
+/* Python interpreter main program */
+
+#include "Python.h"
+#include "osdefs.h"
+#include "code.h" /* For CO_FUTURE_DIVISION */
+#include "import.h"
+
+#ifdef __VMS
+#include <unixlib.h>
+#endif
+
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#endif
+
+#if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)
+#define PYTHONHOMEHELP "<prefix>\\lib"
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define PYTHONHOMEHELP "<prefix>/Lib"
+#else
+#define PYTHONHOMEHELP "<prefix>/pythonX.X"
+#endif
+#endif
+
+#include "pygetopt.h"
+
+#define COPYRIGHT \
+ "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
+ "for more information."
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For Py_GetArgcArgv(); set by main() */
+static char **orig_argv;
+static int orig_argc;
+
+/* command line options */
+#define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX?"
+
+#ifndef RISCOS
+#define PROGRAM_OPTS BASE_OPTS
+#else /*RISCOS*/
+/* extra option saying that we are running under a special task window
+ frontend; especially my_readline will behave different */
+#define PROGRAM_OPTS BASE_OPTS "w"
+/* corresponding flag */
+extern int Py_RISCOSWimpFlag;
+#endif /*RISCOS*/
+
+/* Short usage message (with %s for argv0) */
+static char *usage_line =
+"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
+
+/* Long usage message, split into parts < 512 bytes */
+static char *usage_1 = "\
+Options and arguments (and corresponding environment variables):\n\
+-c cmd : program passed in as string (terminates option list)\n\
+-d : debug output from parser (also PYTHONDEBUG=x)\n\
+-E : ignore environment variables (such as PYTHONPATH)\n\
+-h : print this help message and exit (also --help)\n\
+-i : inspect interactively after running script, (also PYTHONINSPECT=x)\n\
+ and force prompts, even if stdin does not appear to be a terminal\n\
+";
+static char *usage_2 = "\
+-m mod : run library module as a script (terminates option list)\n\
+-O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\
+-OO : remove doc-strings in addition to the -O optimizations\n\
+-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
+-S : don't imply 'import site' on initialization\n\
+-t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
+-u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\
+";
+static char *usage_3 = "\
+ see man page for details on internal buffering relating to '-u'\n\
+-v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
+-V : print the Python version number and exit (also --version)\n\
+-W arg : warning control (arg is action:message:category:module:lineno)\n\
+-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
+file : program read from script file\n\
+- : program read from stdin (default; interactive mode if a tty)\n\
+";
+static char *usage_4 = "\
+arg ...: arguments passed to program in sys.argv[1:]\n\
+Other environment variables:\n\
+PYTHONSTARTUP: file executed on interactive startup (no default)\n\
+PYTHONPATH : '%c'-separated list of directories prefixed to the\n\
+ default module search path. The result is sys.path.\n\
+PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
+ The default module search path uses %s.\n\
+PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
+";
+
+
+static int
+usage(int exitcode, char* program)
+{
+ FILE *f = exitcode ? stderr : stdout;
+
+ fprintf(f, usage_line, program);
+ if (exitcode)
+ fprintf(f, "Try `python -h' for more information.\n");
+ else {
+ fprintf(f, usage_1);
+ fprintf(f, usage_2);
+ fprintf(f, usage_3);
+ fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP);
+ }
+#if defined(__VMS)
+ if (exitcode == 0) {
+ /* suppress 'error' message */
+ return 1;
+ }
+ else {
+ /* STS$M_INHIB_MSG + SS$_ABORT */
+ return 0x1000002c;
+ }
+#else
+ return exitcode;
+#endif
+ /*NOTREACHED*/
+}
+
+static void RunStartupFile(PyCompilerFlags *cf)
+{
+ char *startup = Py_GETENV("PYTHONSTARTUP");
+ if (startup != NULL && startup[0] != '\0') {
+ FILE *fp = fopen(startup, "r");
+ if (fp != NULL) {
+ (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
+ PyErr_Clear();
+ fclose(fp);
+ }
+ }
+}
+
+
+static int RunModule(char *module)
+{
+ PyObject *runpy, *runmodule, *runargs, *result;
+ runpy = PyImport_ImportModule("runpy");
+ if (runpy == NULL) {
+ fprintf(stderr, "Could not import runpy module\n");
+ return -1;
+ }
+ runmodule = PyObject_GetAttrString(runpy, "run_module");
+ if (runmodule == NULL) {
+ fprintf(stderr, "Could not access runpy.run_module\n");
+ Py_DECREF(runpy);
+ return -1;
+ }
+ runargs = Py_BuildValue("sOsO", module,
+ Py_None, "__main__", Py_True);
+ if (runargs == NULL) {
+ fprintf(stderr,
+ "Could not create arguments for runpy.run_module\n");
+ Py_DECREF(runpy);
+ Py_DECREF(runmodule);
+ return -1;
+ }
+ result = PyObject_Call(runmodule, runargs, NULL);
+ if (result == NULL) {
+ PyErr_Print();
+ }
+ Py_DECREF(runpy);
+ Py_DECREF(runmodule);
+ Py_DECREF(runargs);
+ if (result == NULL) {
+ return -1;
+ }
+ Py_DECREF(result);
+ return 0;
+}
+
+/* Wait until threading._shutdown completes, provided
+ the threading module was imported in the first place.
+ The shutdown routine will wait until all non-daemon
+ "threading" threads have completed. */
+#include "abstract.h"
+static void
+WaitForThreadShutdown()
+{
+#ifdef WITH_THREAD
+ PyObject *result;
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
+ "threading");
+ if (threading == NULL) {
+ /* threading not imported */
+ PyErr_Clear();
+ return;
+ }
+ result = PyObject_CallMethod(threading, "_shutdown", "");
+ if (result == NULL)
+ PyErr_WriteUnraisable(threading);
+ else
+ Py_DECREF(result);
+ Py_DECREF(threading);
+#endif
+}
+
+/* Main program */
+
+int
+Py_Main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ char *command = NULL;
+ char *filename = NULL;
+ char *module = NULL;
+ FILE *fp = stdin;
+ char *p;
+ int inspect = 0;
+ int unbuffered = 0;
+ int skipfirstline = 0;
+ int stdin_is_interactive = 0;
+ int help = 0;
+ int version = 0;
+ int saw_inspect_flag = 0;
+ int saw_unbuffered_flag = 0;
+ PyCompilerFlags cf;
+
+ cf.cf_flags = 0;
+
+ orig_argc = argc; /* For Py_GetArgcArgv() */
+ orig_argv = argv;
+
+#ifdef RISCOS
+ Py_RISCOSWimpFlag = 0;
+#endif
+
+ PySys_ResetWarnOptions();
+
+ while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
+ if (c == 'c') {
+ /* -c is the last option; following arguments
+ that look like options are left for the
+ command to interpret. */
+ command = (char *)malloc(strlen(_PyOS_optarg) + 2);
+ if (command == NULL)
+ Py_FatalError(
+ "not enough memory to copy -c argument");
+ strcpy(command, _PyOS_optarg);
+ strcat(command, "\n");
+ break;
+ }
+
+ if (c == 'm') {
+ /* -m is the last option; following arguments
+ that look like options are left for the
+ module to interpret. */
+ module = (char *)malloc(strlen(_PyOS_optarg) + 2);
+ if (module == NULL)
+ Py_FatalError(
+ "not enough memory to copy -m argument");
+ strcpy(module, _PyOS_optarg);
+ break;
+ }
+
+ switch (c) {
+
+ case 'd':
+ Py_DebugFlag++;
+ break;
+
+ case 'Q':
+ if (strcmp(_PyOS_optarg, "old") == 0) {
+ Py_DivisionWarningFlag = 0;
+ break;
+ }
+ if (strcmp(_PyOS_optarg, "warn") == 0) {
+ Py_DivisionWarningFlag = 1;
+ break;
+ }
+ if (strcmp(_PyOS_optarg, "warnall") == 0) {
+ Py_DivisionWarningFlag = 2;
+ break;
+ }
+ if (strcmp(_PyOS_optarg, "new") == 0) {
+ /* This only affects __main__ */
+ cf.cf_flags |= CO_FUTURE_DIVISION;
+ /* And this tells the eval loop to treat
+ BINARY_DIVIDE as BINARY_TRUE_DIVIDE */
+ _Py_QnewFlag = 1;
+ break;
+ }
+ fprintf(stderr,
+ "-Q option should be `-Qold', "
+ "`-Qwarn', `-Qwarnall', or `-Qnew' only\n");
+ return usage(2, argv[0]);
+ /* NOTREACHED */
+
+ case 'i':
+ inspect++;
+ saw_inspect_flag = 1;
+ Py_InteractiveFlag++;
+ break;
+
+ case 'O':
+ Py_OptimizeFlag++;
+ break;
+
+ case 'S':
+ Py_NoSiteFlag++;
+ break;
+
+ case 'E':
+ Py_IgnoreEnvironmentFlag++;
+ break;
+
+ case 't':
+ Py_TabcheckFlag++;
+ break;
+
+ case 'u':
+ unbuffered++;
+ saw_unbuffered_flag = 1;
+ break;
+
+ case 'v':
+ Py_VerboseFlag++;
+ break;
+
+#ifdef RISCOS
+ case 'w':
+ Py_RISCOSWimpFlag = 1;
+ break;
+#endif
+
+ case 'x':
+ skipfirstline = 1;
+ break;
+
+ case 'U':
+ Py_UnicodeFlag++;
+ break;
+ case 'h':
+ case '?':
+ help++;
+ break;
+ case 'V':
+ version++;
+ break;
+
+ case 'W':
+ PySys_AddWarnOption(_PyOS_optarg);
+ break;
+
+ /* This space reserved for other options */
+
+ default:
+ return usage(2, argv[0]);
+ /*NOTREACHED*/
+
+ }
+ }
+
+ if (help)
+ return usage(0, argv[0]);
+
+ if (version) {
+ fprintf(stderr, "Python %s\n", PY_VERSION);
+ return 0;
+ }
+
+ if (!saw_inspect_flag &&
+ (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+ inspect = 1;
+ if (!saw_unbuffered_flag &&
+ (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
+ unbuffered = 1;
+
+ if (command == NULL && module == NULL && _PyOS_optind < argc &&
+ strcmp(argv[_PyOS_optind], "-") != 0)
+ {
+#ifdef __VMS
+ filename = decc$translate_vms(argv[_PyOS_optind]);
+ if (filename == (char *)0 || filename == (char *)-1)
+ filename = argv[_PyOS_optind];
+
+#else
+ filename = argv[_PyOS_optind];
+#endif
+ if (filename != NULL) {
+ if ((fp = fopen(filename, "r")) == NULL) {
+#ifdef HAVE_STRERROR
+ fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
+ argv[0], filename, errno, strerror(errno));
+#else
+ fprintf(stderr, "%s: can't open file '%s': Errno %d\n",
+ argv[0], filename, errno);
+#endif
+ return 2;
+ }
+ else if (skipfirstline) {
+ int ch;
+ /* Push back first newline so line numbers
+ remain the same */
+ while ((ch = getc(fp)) != EOF) {
+ if (ch == '\n') {
+ (void)ungetc(ch, fp);
+ break;
+ }
+ }
+ }
+ {
+ /* XXX: does this work on Win/Win64? (see posix_fstat) */
+ struct stat sb;
+ if (fstat(fileno(fp), &sb) == 0 &&
+ S_ISDIR(sb.st_mode)) {
+ fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
+ return 1;
+ }
+ }
+ }
+ }
+
+ stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
+
+ if (unbuffered) {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ _setmode(fileno(stdin), O_BINARY);
+ _setmode(fileno(stdout), O_BINARY);
+#endif
+#ifdef HAVE_SETVBUF
+ setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+ setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !HAVE_SETVBUF */
+ setbuf(stdin, (char *)NULL);
+ setbuf(stdout, (char *)NULL);
+ setbuf(stderr, (char *)NULL);
+#endif /* !HAVE_SETVBUF */
+ }
+ else if (Py_InteractiveFlag) {
+#ifdef MS_WINDOWS
+ /* Doesn't have to have line-buffered -- use unbuffered */
+ /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !MS_WINDOWS */
+#ifdef HAVE_SETVBUF
+ setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
+ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+#endif /* HAVE_SETVBUF */
+#endif /* !MS_WINDOWS */
+ /* Leave stderr alone - it should be unbuffered anyway. */
+ }
+#ifdef __VMS
+ else {
+ setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
+ }
+#endif /* __VMS */
+
+#ifdef __APPLE__
+ /* On MacOS X, when the Python interpreter is embedded in an
+ application bundle, it gets executed by a bootstrapping script
+ that does os.execve() with an argv[0] that's different from the
+ actual Python executable. This is needed to keep the Finder happy,
+ or rather, to work around Apple's overly strict requirements of
+ the process name. However, we still need a usable sys.executable,
+ so the actual executable path is passed in an environment variable.
+ See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
+ script. */
+ if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')
+ Py_SetProgramName(p);
+ else
+ Py_SetProgramName(argv[0]);
+#else
+ Py_SetProgramName(argv[0]);
+#endif
+ Py_Initialize();
+
+ if (Py_VerboseFlag ||
+ (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {
+ fprintf(stderr, "Python %s on %s\n",
+ Py_GetVersion(), Py_GetPlatform());
+ if (!Py_NoSiteFlag)
+ fprintf(stderr, "%s\n", COPYRIGHT);
+ }
+
+ if (command != NULL) {
+ /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
+ _PyOS_optind--;
+ argv[_PyOS_optind] = "-c";
+ }
+
+ if (module != NULL) {
+ /* Backup _PyOS_optind and force sys.argv[0] = '-c'
+ so that PySys_SetArgv correctly sets sys.path[0] to ''*/
+ _PyOS_optind--;
+ argv[_PyOS_optind] = "-c";
+ }
+
+ PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
+
+ if ((inspect || (command == NULL && filename == NULL && module == NULL)) &&
+ isatty(fileno(stdin))) {
+ PyObject *v;
+ v = PyImport_ImportModule("readline");
+ if (v == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(v);
+ }
+
+ if (command) {
+ sts = PyRun_SimpleStringFlags(command, &cf) != 0;
+ free(command);
+ } else if (module) {
+ sts = RunModule(module);
+ free(module);
+ }
+ else {
+ if (filename == NULL && stdin_is_interactive) {
+ RunStartupFile(&cf);
+ }
+ /* XXX */
+ sts = PyRun_AnyFileExFlags(
+ fp,
+ filename == NULL ? "<stdin>" : filename,
+ filename != NULL, &cf) != 0;
+ }
+
+ /* Check this environment variable at the end, to give programs the
+ * opportunity to set it from Python.
+ */
+ if (!saw_inspect_flag &&
+ (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+ {
+ inspect = 1;
+ }
+
+ if (inspect && stdin_is_interactive &&
+ (filename != NULL || command != NULL || module != NULL))
+ /* XXX */
+ sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
+
+ WaitForThreadShutdown();
+
+ Py_Finalize();
+#ifdef RISCOS
+ if (Py_RISCOSWimpFlag)
+ fprintf(stderr, "\x0cq\x0c"); /* make frontend quit */
+#endif
+
+#ifdef __INSURE__
+ /* Insure++ is a memory analysis tool that aids in discovering
+ * memory leaks and other memory problems. On Python exit, the
+ * interned string dictionary is flagged as being in use at exit
+ * (which it is). Under normal circumstances, this is fine because
+ * the memory will be automatically reclaimed by the system. Under
+ * memory debugging, it's a huge source of useless noise, so we
+ * trade off slower shutdown for less distraction in the memory
+ * reports. -baw
+ */
+ _Py_ReleaseInternedStrings();
+#endif /* __INSURE__ */
+
+ return sts;
+}
+
+/* this is gonna seem *real weird*, but if you put some other code between
+ Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
+ while statement in Misc/gdbinit:ppystack */
+
+/* Make the *original* argc/argv available to other modules.
+ This is rare, but it is needed by the secureware extension. */
+
+void
+Py_GetArgcArgv(int *argc, char ***argv)
+{
+ *argc = orig_argc;
+ *argv = orig_argv;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/sys/src/cmd/python/Modules/makesetup b/sys/src/cmd/python/Modules/makesetup
new file mode 100755
index 000000000..bc1b1b915
--- /dev/null
+++ b/sys/src/cmd/python/Modules/makesetup
@@ -0,0 +1,297 @@
+#! /bin/sh
+
+# Convert templates into Makefile and config.c, based on the module
+# definitions found in the file Setup.
+#
+# Usage: makesetup [-s dir] [-c file] [-m file] [Setup] ... [-n [Setup] ...]
+#
+# Options:
+# -s directory: alternative source directory (default .)
+# -l directory: library source directory (default derived from $0)
+# -c file: alternative config.c template (default $libdir/config.c.in)
+# -c -: don't write config.c
+# -m file: alternative Makefile template (default ./Makefile.pre)
+# -m -: don't write Makefile
+#
+# Remaining arguments are one or more Setup files (default ./Setup).
+# Setup files after a -n option are used for their variables, modules
+# and libraries but not for their .o files.
+#
+# See Setup.dist for a description of the format of the Setup file.
+#
+# The following edits are made:
+#
+# Copying config.c.in to config.c:
+# - insert an identifying comment at the start
+# - for each <module> mentioned in Setup before *noconfig*:
+# + insert 'extern void init<module>(void);' before MARKER 1
+# + insert '{"<module>", initmodule},' before MARKER 2
+#
+# Copying Makefile.pre to Makefile:
+# - insert an identifying comment at the start
+# - replace _MODOBJS_ by the list of objects from Setup (except for
+# Setup files after a -n option)
+# - replace _MODLIBS_ by the list of libraries from Setup
+# - for each object file mentioned in Setup, append a rule
+# '<file>.o: <file>.c; <build commands>' to the end of the Makefile
+# - for each module mentioned in Setup, append a rule
+# which creates a shared library version to the end of the Makefile
+# - for each variable definition found in Setup, insert the definition
+# before the comment 'Definitions added by makesetup'
+
+# Loop over command line options
+usage='
+usage: makesetup [-s srcdir] [-l libdir] [-c config.c.in] [-m Makefile.pre]
+ [Setup] ... [-n [Setup] ...]'
+srcdir='.'
+libdir=''
+config=''
+makepre=''
+noobjects=''
+doconfig=yes
+while :
+do
+ case $1 in
+ -s) shift; srcdir=$1; shift;;
+ -l) shift; libdir=$1; shift;;
+ -c) shift; config=$1; shift;;
+ -m) shift; makepre=$1; shift;;
+ --) shift; break;;
+ -n) noobjects=yes;;
+ -*) echo "$usage" 1>&2; exit 2;;
+ *) break;;
+ esac
+done
+
+# Set default libdir and config if not set by command line
+# (Not all systems have dirname)
+case $libdir in
+'') case $0 in
+ */*) libdir=`echo $0 | sed 's,/[^/]*$,,'`;;
+ *) libdir=.;;
+ esac;;
+esac
+case $config in
+'') config=$libdir/config.c.in;;
+esac
+case $makepre in
+'') makepre=Makefile.pre;;
+esac
+
+# Newline for sed i and a commands
+NL='\
+'
+
+# Setup to link with extra libraries when makeing shared extensions.
+# Currently, only Cygwin needs this baggage.
+case `uname -s` in
+CYGWIN*) if test $libdir = .
+ then
+ ExtraLibDir=.
+ else
+ ExtraLibDir='$(LIBPL)'
+ fi
+ ExtraLibs="-L$ExtraLibDir -lpython\$(VERSION)";;
+esac
+
+# Main loop
+for i in ${*-Setup}
+do
+ case $i in
+ -n) echo '*noobjects*';;
+ *) echo '*doconfig*'; cat "$i";;
+ esac
+done |
+sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' |
+(
+ rulesf="@rules.$$"
+ trap 'rm -f $rulesf' 0 1 2 3
+ echo "
+# Rules appended by makedepend
+" >$rulesf
+ DEFS=
+ MODS=
+ SHAREDMODS=
+ OBJS=
+ LIBS=
+ LOCALLIBS=
+ BASELIBS=
+ while read line
+ do
+ # to handle backslashes for sh's that don't automatically
+ # continue a read when the last char is a backslash
+ while echo $line | grep '\\$' > /dev/null
+ do
+ read extraline
+ line=`echo $line| sed s/.$//`$extraline
+ done
+
+ # Output DEFS in reverse order so first definition overrides
+ case $line in
+ *=*) DEFS="$line$NL$DEFS"; continue;;
+ 'include '*) DEFS="$line$NL$DEFS"; continue;;
+ '*noobjects*')
+ case $noobjects in
+ yes) ;;
+ *) LOCALLIBS=$LIBS; LIBS=;;
+ esac
+ noobjects=yes;
+ continue;;
+ '*doconfig*') doconfig=yes; continue;;
+ '*static*') doconfig=yes; continue;;
+ '*noconfig*') doconfig=no; continue;;
+ '*shared*') doconfig=no; continue;;
+ esac
+ srcs=
+ cpps=
+ libs=
+ mods=
+ skip=
+ for arg in $line
+ do
+ case $skip in
+ libs) libs="$libs $arg"; skip=; continue;;
+ cpps) cpps="$cpps $arg"; skip=; continue;;
+ srcs) srcs="$srcs $arg"; skip=; continue;;
+ esac
+ case $arg in
+ -framework) libs="$libs $arg"; skip=libs;
+ # OSX/OSXS/Darwin framework link cmd
+ ;;
+ -[IDUCfF]*) cpps="$cpps $arg";;
+ -Xcompiler) skip=cpps;;
+ -Xlinker) libs="$libs $arg"; skip=libs;;
+ -rpath) libs="$libs $arg"; skip=libs;;
+ --rpath) libs="$libs $arg"; skip=libs;;
+ -[A-Zl]*) libs="$libs $arg";;
+ *.a) libs="$libs $arg";;
+ *.so) libs="$libs $arg";;
+ *.sl) libs="$libs $arg";;
+ /*.o) libs="$libs $arg";;
+ *.def) libs="$libs $arg";;
+ *.o) srcs="$srcs `basename $arg .o`.c";;
+ *.[cC]) srcs="$srcs $arg";;
+ *.m) srcs="$srcs $arg";; # Objective-C src
+ *.cc) srcs="$srcs $arg";;
+ *.c++) srcs="$srcs $arg";;
+ *.cxx) srcs="$srcs $arg";;
+ *.cpp) srcs="$srcs $arg";;
+ \$*) libs="$libs $arg"
+ cpps="$cpps $arg";;
+ *.*) echo 1>&2 "bad word $arg in $line"
+ exit 1;;
+ -u) skip=libs; libs="$libs -u";;
+ [a-zA-Z_]*) mods="$mods $arg";;
+ *) echo 1>&2 "bad word $arg in $line"
+ exit 1;;
+ esac
+ done
+ case $doconfig in
+ yes)
+ LIBS="$LIBS $libs"
+ MODS="$MODS $mods"
+ ;;
+ esac
+ case $noobjects in
+ yes) continue;;
+ esac
+ objs=''
+ for src in $srcs
+ do
+ case $src in
+ *.c) obj=`basename $src .c`.o; cc='$(CC)';;
+ *.cc) obj=`basename $src .cc`.o; cc='$(CXX)';;
+ *.c++) obj=`basename $src .c++`.o; cc='$(CXX)';;
+ *.C) obj=`basename $src .C`.o; cc='$(CXX)';;
+ *.cxx) obj=`basename $src .cxx`.o; cc='$(CXX)';;
+ *.cpp) obj=`basename $src .cpp`.o; cc='$(CXX)';;
+ *.m) obj=`basename $src .m`.o; cc='$(CC)';; # Obj-C
+ *) continue;;
+ esac
+ obj="$srcdir/$obj"
+ objs="$objs $obj"
+ case $src in
+ glmodule.c) ;;
+ /*) ;;
+ \$*) ;;
+ *) src='$(srcdir)/'"$srcdir/$src";;
+ esac
+ case $doconfig in
+ no) cc="$cc \$(CCSHARED) \$(CFLAGS) \$(CPPFLAGS)";;
+ *)
+ cc="$cc \$(PY_CFLAGS)";;
+ esac
+ rule="$obj: $src; $cc $cpps -c $src -o $obj"
+ echo "$rule" >>$rulesf
+ done
+ case $doconfig in
+ yes) OBJS="$OBJS $objs";;
+ esac
+ for mod in $mods
+ do
+ case $objs in
+ *$mod.o*) base=$mod;;
+ *) base=${mod}module;;
+ esac
+ file="$srcdir/$base\$(SO)"
+ case $doconfig in
+ no) SHAREDMODS="$SHAREDMODS $file";;
+ esac
+ rule="$file: $objs"
+ rule="$rule; \$(LDSHARED) $objs $libs $ExtraLibs -o $file"
+ echo "$rule" >>$rulesf
+ done
+ done
+
+ case $SHAREDMODS in
+ '') ;;
+ *) DEFS="SHAREDMODS=$SHAREDMODS$NL$DEFS";;
+ esac
+
+ case $noobjects in
+ yes) BASELIBS=$LIBS;;
+ *) LOCALLIBS=$LIBS;;
+ esac
+ LIBS='$(LOCALMODLIBS) $(BASEMODLIBS)'
+ DEFS="BASEMODLIBS=$BASELIBS$NL$DEFS"
+ DEFS="LOCALMODLIBS=$LOCALLIBS$NL$DEFS"
+
+ EXTDECLS=
+ INITBITS=
+ for mod in $MODS
+ do
+ EXTDECLS="${EXTDECLS}extern void init$mod(void);$NL"
+ INITBITS="${INITBITS} {\"$mod\", init$mod},$NL"
+ done
+
+
+ case $config in
+ -) ;;
+ *) sed -e "
+ 1i$NL/* Generated automatically from $config by makesetup. */
+ /MARKER 1/i$NL$EXTDECLS
+
+ /MARKER 2/i$NL$INITBITS
+
+ " $config >config.c
+ ;;
+ esac
+
+ case $makepre in
+ -) ;;
+ *) sedf="@sed.in.$$"
+ trap 'rm -f $sedf' 0 1 2 3
+ echo "1i\\" >$sedf
+ str="# Generated automatically from $makepre by makesetup."
+ echo "$str" >>$sedf
+ echo "s%_MODOBJS_%$OBJS%" >>$sedf
+ echo "s%_MODLIBS_%$LIBS%" >>$sedf
+ echo "/Definitions added by makesetup/a$NL$NL$DEFS" >>$sedf
+ sed -f $sedf $makepre >Makefile
+ cat $rulesf >>Makefile
+ rm -f $sedf
+ ;;
+ esac
+
+ rm -f $rulesf
+)
diff --git a/sys/src/cmd/python/Modules/makexp_aix b/sys/src/cmd/python/Modules/makexp_aix
new file mode 100755
index 000000000..cb349c287
--- /dev/null
+++ b/sys/src/cmd/python/Modules/makexp_aix
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# ===========================================================================
+# FILE: makexp_aix
+# TYPE: standalone executable
+# SYSTEM: AIX 3.2.5 and AIX 4
+#
+# DESCRIPTION: This script creates an export list of ALL global symbols
+# from a list of object or archive files.
+#
+# USAGE: makexp_aix <OutputFile> "<FirstLine>" <InputFile> ...
+#
+# where:
+# <OutputFile> is the target export list filename.
+# <FirstLine> is the path/file string to be appended
+# after the "#!" symbols in the first line of the
+# export file. Passing "" means deferred resolution.
+# <InputFile> is an object (.o) or an archive file (.a).
+#
+# HISTORY:
+# 3-Apr-1998 -- remove C++ entries of the form Class::method
+# Vladimir Marangozov
+#
+# 1-Jul-1996 -- added header information
+# Vladimir Marangozov
+#
+# 28-Jun-1996 -- initial code
+# Vladimir Marangozov (Vladimir.Marangozov@imag.fr)
+# ==========================================================================
+
+# Variables
+expFileName=$1
+toAppendStr=$2
+shift; shift;
+inputFiles=$*
+automsg="Generated automatically by makexp_aix"
+notemsg="NOTE: lists _all_ global symbols defined in the above file(s)."
+curwdir=`pwd`
+
+# Create the export file and setup the header info
+echo "#!"$toAppendStr > $expFileName
+echo "*" >> $expFileName
+echo "* $automsg (`date -u`)" >> $expFileName
+echo "*" >> $expFileName
+echo "* Base Directory: $curwdir" >> $expFileName
+echo "* Input File(s) : $inputFiles" >> $expFileName
+echo "*" >> $expFileName
+echo "* $notemsg" >> $expFileName
+echo "*" >> $expFileName
+
+# Extract the symbol list using 'nm' which produces quite
+# different output under AIX 4 than under AIX 3.2.5.
+# The following handles both versions by using a common flagset.
+# Here are some hidden tricks:
+# 1. Use /usr/ccs/bin/nm. Relevant to AIX 3.2.5 which has
+# another version under /usr/ucb/bin/nm.
+# 2. Use the -B flag to have a standard BSD representation
+# of the symbol list on both AIX 3.2.5 and AIX 4. The "-B"
+# flag is missing in the AIX 3.2.5 online usage help of 'nm'.
+# 3. Use the -x flag to have a hex representation of the symbol
+# values. This fills the leading whitespaces on AIX 4,
+# thus simplifying the sed statement.
+# 4. Eliminate all entries except those with either "B", "D"
+# or "T" key letters. We are interested only in the global
+# (extern) BSS, DATA and TEXT symbols. With the same statement
+# we eliminate object member lines relevant to AIX 4.
+# 5. Eliminate entries containing a dot. We can have a dot only
+# as a symbol prefix, but such symbols are undefined externs.
+# 6. Eliminate everything including the key letter, so that we're
+# left with just the symbol name.
+# 7. Eliminate all entries containing two colons, like Class::method
+#
+
+# Use -X32_64 if it appears to be implemented in this version of 'nm'.
+NM=/usr/ccs/bin/nm
+xopt=-X32_64
+$NM -e $xopt $1 >/dev/null 2>&1 || xopt=""
+
+$NM -Bex $xopt $inputFiles \
+| sed -e '/ [^BDT] /d' -e '/\./d' -e 's/.* [BDT] //' -e '/::/d' \
+| sort | uniq >> $expFileName
diff --git a/sys/src/cmd/python/Modules/mathmodule.c b/sys/src/cmd/python/Modules/mathmodule.c
new file mode 100644
index 000000000..e7fc6dd70
--- /dev/null
+++ b/sys/src/cmd/python/Modules/mathmodule.c
@@ -0,0 +1,376 @@
+/* Math module -- standard C math library functions, pi and e */
+
+#include "Python.h"
+#include "longintrepr.h" /* just for SHIFT */
+
+#ifndef _MSC_VER
+#ifndef __STDC__
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double modf (double, double *);
+#endif /* __STDC__ */
+#endif /* _MSC_VER */
+
+/* Call is_error when errno != 0, and where x is the result libm
+ * returned. is_error will usually set up an exception and return
+ * true (1), but may return false (0) without setting up an exception.
+ */
+static int
+is_error(double x)
+{
+ int result = 1; /* presumption of guilt */
+ assert(errno); /* non-zero errno is a precondition for calling */
+ if (errno == EDOM)
+ PyErr_SetString(PyExc_ValueError, "math domain error");
+
+ else if (errno == ERANGE) {
+ /* ANSI C generally requires libm functions to set ERANGE
+ * on overflow, but also generally *allows* them to set
+ * ERANGE on underflow too. There's no consistency about
+ * the latter across platforms.
+ * Alas, C99 never requires that errno be set.
+ * Here we suppress the underflow errors (libm functions
+ * should return a zero on underflow, and +- HUGE_VAL on
+ * overflow, so testing the result for zero suffices to
+ * distinguish the cases).
+ */
+ if (x)
+ PyErr_SetString(PyExc_OverflowError,
+ "math range error");
+ else
+ result = 0;
+ }
+ else
+ /* Unexpected math error */
+ PyErr_SetFromErrno(PyExc_ValueError);
+ return result;
+}
+
+static PyObject *
+math_1(PyObject *args, double (*func) (double), char *argsfmt)
+{
+ double x;
+ if (! PyArg_ParseTuple(args, argsfmt, &x))
+ return NULL;
+ errno = 0;
+ PyFPE_START_PROTECT("in math_1", return 0)
+ x = (*func)(x);
+ PyFPE_END_PROTECT(x)
+ Py_SET_ERRNO_ON_MATH_ERROR(x);
+ if (errno && is_error(x))
+ return NULL;
+ else
+ return PyFloat_FromDouble(x);
+}
+
+static PyObject *
+math_2(PyObject *args, double (*func) (double, double), char *argsfmt)
+{
+ double x, y;
+ if (! PyArg_ParseTuple(args, argsfmt, &x, &y))
+ return NULL;
+ errno = 0;
+ PyFPE_START_PROTECT("in math_2", return 0)
+ x = (*func)(x, y);
+ PyFPE_END_PROTECT(x)
+ Py_SET_ERRNO_ON_MATH_ERROR(x);
+ if (errno && is_error(x))
+ return NULL;
+ else
+ return PyFloat_FromDouble(x);
+}
+
+#define FUNC1(funcname, func, docstring) \
+ static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
+ return math_1(args, func, "d:" #funcname); \
+ }\
+ PyDoc_STRVAR(math_##funcname##_doc, docstring);
+
+#define FUNC2(funcname, func, docstring) \
+ static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
+ return math_2(args, func, "dd:" #funcname); \
+ }\
+ PyDoc_STRVAR(math_##funcname##_doc, docstring);
+
+FUNC1(acos, acos,
+ "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
+FUNC1(asin, asin,
+ "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
+FUNC1(atan, atan,
+ "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
+FUNC2(atan2, atan2,
+ "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
+ "Unlike atan(y/x), the signs of both x and y are considered.")
+FUNC1(ceil, ceil,
+ "ceil(x)\n\nReturn the ceiling of x as a float.\n"
+ "This is the smallest integral value >= x.")
+FUNC1(cos, cos,
+ "cos(x)\n\nReturn the cosine of x (measured in radians).")
+FUNC1(cosh, cosh,
+ "cosh(x)\n\nReturn the hyperbolic cosine of x.")
+FUNC1(exp, exp,
+ "exp(x)\n\nReturn e raised to the power of x.")
+FUNC1(fabs, fabs,
+ "fabs(x)\n\nReturn the absolute value of the float x.")
+FUNC1(floor, floor,
+ "floor(x)\n\nReturn the floor of x as a float.\n"
+ "This is the largest integral value <= x.")
+FUNC2(fmod, fmod,
+ "fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
+ " x % y may differ.")
+FUNC2(hypot, hypot,
+ "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
+FUNC2(pow, pow,
+ "pow(x,y)\n\nReturn x**y (x to the power of y).")
+FUNC1(sin, sin,
+ "sin(x)\n\nReturn the sine of x (measured in radians).")
+FUNC1(sinh, sinh,
+ "sinh(x)\n\nReturn the hyperbolic sine of x.")
+FUNC1(sqrt, sqrt,
+ "sqrt(x)\n\nReturn the square root of x.")
+FUNC1(tan, tan,
+ "tan(x)\n\nReturn the tangent of x (measured in radians).")
+FUNC1(tanh, tanh,
+ "tanh(x)\n\nReturn the hyperbolic tangent of x.")
+
+static PyObject *
+math_frexp(PyObject *self, PyObject *args)
+{
+ double x;
+ int i;
+ if (! PyArg_ParseTuple(args, "d:frexp", &x))
+ return NULL;
+ errno = 0;
+ x = frexp(x, &i);
+ Py_SET_ERRNO_ON_MATH_ERROR(x);
+ if (errno && is_error(x))
+ return NULL;
+ else
+ return Py_BuildValue("(di)", x, i);
+}
+
+PyDoc_STRVAR(math_frexp_doc,
+"frexp(x)\n"
+"\n"
+"Return the mantissa and exponent of x, as pair (m, e).\n"
+"m is a float and e is an int, such that x = m * 2.**e.\n"
+"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
+
+static PyObject *
+math_ldexp(PyObject *self, PyObject *args)
+{
+ double x;
+ int exp;
+ if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
+ return NULL;
+ errno = 0;
+ PyFPE_START_PROTECT("ldexp", return 0)
+ x = ldexp(x, exp);
+ PyFPE_END_PROTECT(x)
+ Py_SET_ERRNO_ON_MATH_ERROR(x);
+ if (errno && is_error(x))
+ return NULL;
+ else
+ return PyFloat_FromDouble(x);
+}
+
+PyDoc_STRVAR(math_ldexp_doc,
+"ldexp(x, i) -> x * (2**i)");
+
+static PyObject *
+math_modf(PyObject *self, PyObject *args)
+{
+ double x, y;
+ if (! PyArg_ParseTuple(args, "d:modf", &x))
+ return NULL;
+ errno = 0;
+ x = modf(x, &y);
+ Py_SET_ERRNO_ON_MATH_ERROR(x);
+ if (errno && is_error(x))
+ return NULL;
+ else
+ return Py_BuildValue("(dd)", x, y);
+}
+
+PyDoc_STRVAR(math_modf_doc,
+"modf(x)\n"
+"\n"
+"Return the fractional and integer parts of x. Both results carry the sign\n"
+"of x. The integer part is returned as a real.");
+
+/* A decent logarithm is easy to compute even for huge longs, but libm can't
+ do that by itself -- loghelper can. func is log or log10, and name is
+ "log" or "log10". Note that overflow isn't possible: a long can contain
+ no more than INT_MAX * SHIFT bits, so has value certainly less than
+ 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is
+ small enough to fit in an IEEE single. log and log10 are even smaller.
+*/
+
+static PyObject*
+loghelper(PyObject* args, double (*func)(double), char *format, PyObject *arg)
+{
+ /* If it is long, do it ourselves. */
+ if (PyLong_Check(arg)) {
+ double x;
+ int e;
+ x = _PyLong_AsScaledDouble(arg, &e);
+ if (x <= 0.0) {
+ PyErr_SetString(PyExc_ValueError,
+ "math domain error");
+ return NULL;
+ }
+ /* Value is ~= x * 2**(e*SHIFT), so the log ~=
+ log(x) + log(2) * e * SHIFT.
+ CAUTION: e*SHIFT may overflow using int arithmetic,
+ so force use of double. */
+ x = func(x) + (e * (double)SHIFT) * func(2.0);
+ return PyFloat_FromDouble(x);
+ }
+
+ /* Else let libm handle it by itself. */
+ return math_1(args, func, format);
+}
+
+static PyObject *
+math_log(PyObject *self, PyObject *args)
+{
+ PyObject *arg;
+ PyObject *base = NULL;
+ PyObject *num, *den;
+ PyObject *ans;
+ PyObject *newargs;
+
+ if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
+ return NULL;
+ if (base == NULL)
+ return loghelper(args, log, "d:log", arg);
+
+ newargs = PyTuple_Pack(1, arg);
+ if (newargs == NULL)
+ return NULL;
+ num = loghelper(newargs, log, "d:log", arg);
+ Py_DECREF(newargs);
+ if (num == NULL)
+ return NULL;
+
+ newargs = PyTuple_Pack(1, base);
+ if (newargs == NULL) {
+ Py_DECREF(num);
+ return NULL;
+ }
+ den = loghelper(newargs, log, "d:log", base);
+ Py_DECREF(newargs);
+ if (den == NULL) {
+ Py_DECREF(num);
+ return NULL;
+ }
+
+ ans = PyNumber_Divide(num, den);
+ Py_DECREF(num);
+ Py_DECREF(den);
+ return ans;
+}
+
+PyDoc_STRVAR(math_log_doc,
+"log(x[, base]) -> the logarithm of x to the given base.\n\
+If the base not specified, returns the natural logarithm (base e) of x.");
+
+static PyObject *
+math_log10(PyObject *self, PyObject *args)
+{
+ PyObject *arg;
+
+ if (!PyArg_UnpackTuple(args, "log10", 1, 1, &arg))
+ return NULL;
+ return loghelper(args, log10, "d:log10", arg);
+}
+
+PyDoc_STRVAR(math_log10_doc,
+"log10(x) -> the base 10 logarithm of x.");
+
+static const double degToRad = 3.141592653589793238462643383 / 180.0;
+
+static PyObject *
+math_degrees(PyObject *self, PyObject *args)
+{
+ double x;
+ if (! PyArg_ParseTuple(args, "d:degrees", &x))
+ return NULL;
+ return PyFloat_FromDouble(x / degToRad);
+}
+
+PyDoc_STRVAR(math_degrees_doc,
+"degrees(x) -> converts angle x from radians to degrees");
+
+static PyObject *
+math_radians(PyObject *self, PyObject *args)
+{
+ double x;
+ if (! PyArg_ParseTuple(args, "d:radians", &x))
+ return NULL;
+ return PyFloat_FromDouble(x * degToRad);
+}
+
+PyDoc_STRVAR(math_radians_doc,
+"radians(x) -> converts angle x from degrees to radians");
+
+static PyMethodDef math_methods[] = {
+ {"acos", math_acos, METH_VARARGS, math_acos_doc},
+ {"asin", math_asin, METH_VARARGS, math_asin_doc},
+ {"atan", math_atan, METH_VARARGS, math_atan_doc},
+ {"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
+ {"ceil", math_ceil, METH_VARARGS, math_ceil_doc},
+ {"cos", math_cos, METH_VARARGS, math_cos_doc},
+ {"cosh", math_cosh, METH_VARARGS, math_cosh_doc},
+ {"degrees", math_degrees, METH_VARARGS, math_degrees_doc},
+ {"exp", math_exp, METH_VARARGS, math_exp_doc},
+ {"fabs", math_fabs, METH_VARARGS, math_fabs_doc},
+ {"floor", math_floor, METH_VARARGS, math_floor_doc},
+ {"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
+ {"frexp", math_frexp, METH_VARARGS, math_frexp_doc},
+ {"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
+ {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
+ {"log", math_log, METH_VARARGS, math_log_doc},
+ {"log10", math_log10, METH_VARARGS, math_log10_doc},
+ {"modf", math_modf, METH_VARARGS, math_modf_doc},
+ {"pow", math_pow, METH_VARARGS, math_pow_doc},
+ {"radians", math_radians, METH_VARARGS, math_radians_doc},
+ {"sin", math_sin, METH_VARARGS, math_sin_doc},
+ {"sinh", math_sinh, METH_VARARGS, math_sinh_doc},
+ {"sqrt", math_sqrt, METH_VARARGS, math_sqrt_doc},
+ {"tan", math_tan, METH_VARARGS, math_tan_doc},
+ {"tanh", math_tanh, METH_VARARGS, math_tanh_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module is always available. It provides access to the\n"
+"mathematical functions defined by the C standard.");
+
+PyMODINIT_FUNC
+initmath(void)
+{
+ PyObject *m, *d, *v;
+
+ m = Py_InitModule3("math", math_methods, module_doc);
+ if (m == NULL)
+ goto finally;
+ d = PyModule_GetDict(m);
+
+ if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
+ goto finally;
+ if (PyDict_SetItemString(d, "pi", v) < 0)
+ goto finally;
+ Py_DECREF(v);
+
+ if (!(v = PyFloat_FromDouble(exp(1.0))))
+ goto finally;
+ if (PyDict_SetItemString(d, "e", v) < 0)
+ goto finally;
+ Py_DECREF(v);
+
+ finally:
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/md5.c b/sys/src/cmd/python/Modules/md5.c
new file mode 100644
index 000000000..c35d96c5e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/md5.c
@@ -0,0 +1,381 @@
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+#include "md5.h"
+#include <string.h>
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+# define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+ const md5_byte_t *p = data;
+ int left = nbytes;
+ int offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += nbytes >> 29;
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/sys/src/cmd/python/Modules/md5.h b/sys/src/cmd/python/Modules/md5.h
new file mode 100644
index 000000000..1718401f3
--- /dev/null
+++ b/sys/src/cmd/python/Modules/md5.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id: md5.h 43594 2006-04-03 16:27:50Z matthias.klose $ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.h is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Removed support for non-ANSI compilers; removed
+ references to Ghostscript; clarified derivation from RFC 1321;
+ now handles byte order either statically or dynamically.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+ added conditionalization for C++ compilation from Martin
+ Purschke <purschke@bnl.gov>.
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+# define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
diff --git a/sys/src/cmd/python/Modules/md5module.c b/sys/src/cmd/python/Modules/md5module.c
new file mode 100644
index 000000000..5e4f11632
--- /dev/null
+++ b/sys/src/cmd/python/Modules/md5module.c
@@ -0,0 +1,312 @@
+
+/* MD5 module */
+
+/* This module provides an interface to the RSA Data Security,
+ Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
+ It requires the files md5c.c and md5.h (which are slightly changed
+ from the versions in the RFC to avoid the "global.h" file.) */
+
+
+/* MD5 objects */
+
+#include "Python.h"
+#include "structmember.h"
+#include "md5.h"
+
+typedef struct {
+ PyObject_HEAD
+ md5_state_t md5; /* the context holder */
+} md5object;
+
+static PyTypeObject MD5type;
+
+#define is_md5object(v) ((v)->ob_type == &MD5type)
+
+static md5object *
+newmd5object(void)
+{
+ md5object *md5p;
+
+ md5p = PyObject_New(md5object, &MD5type);
+ if (md5p == NULL)
+ return NULL;
+
+ md5_init(&md5p->md5); /* actual initialisation */
+ return md5p;
+}
+
+
+/* MD5 methods */
+
+static void
+md5_dealloc(md5object *md5p)
+{
+ PyObject_Del(md5p);
+}
+
+
+/* MD5 methods-as-attributes */
+
+static PyObject *
+md5_update(md5object *self, PyObject *args)
+{
+ unsigned char *cp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+ return NULL;
+
+ md5_append(&self->md5, cp, len);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(update_doc,
+"update (arg)\n\
+\n\
+Update the md5 object with the string arg. Repeated calls are\n\
+equivalent to a single call with the concatenation of all the\n\
+arguments.");
+
+
+static PyObject *
+md5_digest(md5object *self)
+{
+ md5_state_t mdContext;
+ unsigned char aDigest[16];
+
+ /* make a temporary copy, and perform the final */
+ mdContext = self->md5;
+ md5_finish(&mdContext, aDigest);
+
+ return PyString_FromStringAndSize((char *)aDigest, 16);
+}
+
+PyDoc_STRVAR(digest_doc,
+"digest() -> string\n\
+\n\
+Return the digest of the strings passed to the update() method so\n\
+far. This is a 16-byte string which may contain non-ASCII characters,\n\
+including null bytes.");
+
+
+static PyObject *
+md5_hexdigest(md5object *self)
+{
+ md5_state_t mdContext;
+ unsigned char digest[16];
+ unsigned char hexdigest[32];
+ int i, j;
+
+ /* make a temporary copy, and perform the final */
+ mdContext = self->md5;
+ md5_finish(&mdContext, digest);
+
+ /* Make hex version of the digest */
+ for(i=j=0; i<16; i++) {
+ char c;
+ c = (digest[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hexdigest[j++] = c;
+ c = (digest[i] & 0xf);
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hexdigest[j++] = c;
+ }
+ return PyString_FromStringAndSize((char*)hexdigest, 32);
+}
+
+
+PyDoc_STRVAR(hexdigest_doc,
+"hexdigest() -> string\n\
+\n\
+Like digest(), but returns the digest as a string of hexadecimal digits.");
+
+
+static PyObject *
+md5_copy(md5object *self)
+{
+ md5object *md5p;
+
+ if ((md5p = newmd5object()) == NULL)
+ return NULL;
+
+ md5p->md5 = self->md5;
+
+ return (PyObject *)md5p;
+}
+
+PyDoc_STRVAR(copy_doc,
+"copy() -> md5 object\n\
+\n\
+Return a copy (``clone'') of the md5 object.");
+
+
+static PyMethodDef md5_methods[] = {
+ {"update", (PyCFunction)md5_update, METH_VARARGS, update_doc},
+ {"digest", (PyCFunction)md5_digest, METH_NOARGS, digest_doc},
+ {"hexdigest", (PyCFunction)md5_hexdigest, METH_NOARGS, hexdigest_doc},
+ {"copy", (PyCFunction)md5_copy, METH_NOARGS, copy_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+md5_get_block_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(64);
+}
+
+static PyObject *
+md5_get_digest_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(16);
+}
+
+static PyObject *
+md5_get_name(PyObject *self, void *closure)
+{
+ return PyString_FromStringAndSize("MD5", 3);
+}
+
+static PyGetSetDef md5_getseters[] = {
+ {"digest_size",
+ (getter)md5_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {"block_size",
+ (getter)md5_get_block_size, NULL,
+ NULL,
+ NULL},
+ {"name",
+ (getter)md5_get_name, NULL,
+ NULL,
+ NULL},
+ /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+ * the old sha module also supported 'digestsize'. ugh. */
+ {"digestsize",
+ (getter)md5_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module implements the interface to RSA's MD5 message digest\n\
+algorithm (see also Internet RFC 1321). Its use is quite\n\
+straightforward: use the new() to create an md5 object. You can now\n\
+feed this object with arbitrary strings using the update() method, and\n\
+at any point you can ask it for the digest (a strong kind of 128-bit\n\
+checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
+fed to it so far using the digest() method.\n\
+\n\
+Functions:\n\
+\n\
+new([arg]) -- return a new md5 object, initialized with arg if provided\n\
+md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
+\n\
+Special Objects:\n\
+\n\
+MD5Type -- type object for md5 objects");
+
+PyDoc_STRVAR(md5type_doc,
+"An md5 represents the object used to calculate the MD5 checksum of a\n\
+string of information.\n\
+\n\
+Methods:\n\
+\n\
+update() -- updates the current digest with an additional string\n\
+digest() -- return the current digest value\n\
+hexdigest() -- return the current digest as a string of hexadecimal digits\n\
+copy() -- return a copy of the current md5 object");
+
+static PyTypeObject MD5type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_md5.md5", /*tp_name*/
+ sizeof(md5object), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)md5_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ md5type_doc, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ md5_methods, /*tp_methods*/
+ 0, /*tp_members*/
+ md5_getseters, /*tp_getset*/
+};
+
+
+/* MD5 functions */
+
+static PyObject *
+MD5_new(PyObject *self, PyObject *args)
+{
+ md5object *md5p;
+ unsigned char *cp = NULL;
+ int len = 0;
+
+ if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
+ return NULL;
+
+ if ((md5p = newmd5object()) == NULL)
+ return NULL;
+
+ if (cp)
+ md5_append(&md5p->md5, cp, len);
+
+ return (PyObject *)md5p;
+}
+
+PyDoc_STRVAR(new_doc,
+"new([arg]) -> md5 object\n\
+\n\
+Return a new md5 object. If arg is present, the method call update(arg)\n\
+is made.");
+
+
+/* List of functions exported by this module */
+
+static PyMethodDef md5_functions[] = {
+ {"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+PyMODINIT_FUNC
+init_md5(void)
+{
+ PyObject *m, *d;
+
+ MD5type.ob_type = &PyType_Type;
+ if (PyType_Ready(&MD5type) < 0)
+ return;
+ m = Py_InitModule3("_md5", md5_functions, module_doc);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
+ PyModule_AddIntConstant(m, "digest_size", 16);
+ /* No need to check the error here, the caller will do that */
+}
diff --git a/sys/src/cmd/python/Modules/mkfile b/sys/src/cmd/python/Modules/mkfile
new file mode 100644
index 000000000..ff1bd7198
--- /dev/null
+++ b/sys/src/cmd/python/Modules/mkfile
@@ -0,0 +1,135 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libpython.a
+
+OFILES=\
+ _bisectmodule.$O\
+# _bsddb.$O\
+ _codecsmodule.$O\
+ _csv.$O\
+# _curses_panel.$O\
+# _cursesmodule.$O\
+ _elementtree.$O\
+ _functoolsmodule.$O\
+ _hashopenssl.$O\
+ _heapqmodule.$O\
+# _hotshot.$O\
+ _localemodule.$O\
+ _lsprof.$O\
+ _randommodule.$O\
+ _sre.$O\
+ _ssl.$O\
+ _struct.$O\
+ _testcapimodule.$O\
+# _tkinter.$O\
+ _typesmodule.$O\
+ _weakref.$O\
+# almodule.$O\
+ arraymodule.$O\
+ audioop.$O\
+ binascii.$O\
+# bsddbmodule.$O\
+ bz2module.$O\
+ cPickle.$O\
+ cStringIO.$O\
+# cdmodule.$O\
+ cgensupport.$O\
+# clmodule.$O\
+ cmathmodule.$O\
+ collectionsmodule.$O\
+# cryptmodule.$O\
+ datetimemodule.$O\
+# dbmmodule.$O\
+# dlmodule.$O\
+ errnomodule.$O\
+ fcntlmodule.$O\
+# flmodule.$O\
+# fmmodule.$O\
+ fpectlmodule.$O\
+ fpetestmodule.$O\
+ gcmodule.$O\
+# gdbmmodule.$O\
+ getbuildinfo.$O\
+# getpath.$O\
+# glmodule.$O\
+ grpmodule.$O\
+ imageop.$O\
+# imgfile.$O\
+ itertoolsmodule.$O\
+# linuxaudiodev.$O\
+ main.$O\
+ mathmodule.$O\
+ md5.$O\
+ md5module.$O\
+# mmapmodule.$O\
+# nismodule.$O\
+ operator.$O\
+# ossaudiodev.$O\
+ parsermodule.$O\
+ posixmodule.$O\
+ puremodule.$O\
+ pwdmodule.$O\
+ pyexpat.$O\
+# readline.$O\
+# resource.$O\
+ rgbimgmodule.$O\
+ rotatingtree.$O\
+ selectmodule.$O\
+# sgimodule.$O\
+ sha256module.$O\
+# sha512module.$O\
+ shamodule.$O\
+ signalmodule.$O\
+ socketmodule.$O\
+# spwdmodule.$O\
+ stropmodule.$O\
+# sunaudiodev.$O\
+# svmodule.$O\
+ symtablemodule.$O\
+# syslogmodule.$O\
+# termios.$O\
+ threadmodule.$O\
+ timemodule.$O\
+ timingmodule.$O\
+ unicodedata.$O\
+ xxmodule.$O\
+ xxsubtype.$O\
+ yuvconvert.$O\
+ zipimport.$O\
+ zlibmodule.$O\
+# expat \
+ xmlparse.$O\
+ xmlrole.$O\
+ xmltok.$O\
+# cjkcodecs \
+ _codecs_cn.$O\
+ _codecs_hk.$O\
+ _codecs_iso2022.$O\
+ _codecs_jp.$O\
+ _codecs_kr.$O\
+ _codecs_tw.$O\
+ multibytecodec.$O\
+
+
+</sys/src/cmd/mksyslib
+
+CFLAGS=-c -I. -I.. -I../Include -DT$objtype -DNDEBUG
+
+%.$O: expat/%.c
+ $CC $CFLAGS -DHAVE_EXPAT_CONFIG_H'=1' -DUSE_PYEXPAT_CAPI expat/$stem.c
+
+%.$O: cjkcodecs/%.c
+ $CC $CFLAGS cjkcodecs/$stem.c
+
+_elementtree.$O: _elementtree.c
+ $CC $CFLAGS -Iexpat _elementtree.c
+
+pyexpat.$O: pyexpat.c
+ $CC $CFLAGS -Iexpat pyexpat.c
+
+_hashopenssl.$O: _hashopenssl.c
+ $CC $CFLAGS -DPLAN9 _hashopenssl.c
+
+_ssl.$O: _ssl.c
+ $CC $CFLAGS -DPLAN9 _ssl.c
diff --git a/sys/src/cmd/python/Modules/mmapmodule.c b/sys/src/cmd/python/Modules/mmapmodule.c
new file mode 100644
index 000000000..9716e303d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/mmapmodule.c
@@ -0,0 +1,1186 @@
+/*
+ / Author: Sam Rushing <rushing@nightmare.com>
+ / Hacked for Unix by AMK
+ / $Id: mmapmodule.c 51474 2006-08-22 13:57:07Z neal.norwitz $
+
+ / mmapmodule.cpp -- map a view of a file into memory
+ /
+ / todo: need permission flags, perhaps a 'chsize' analog
+ / not all functions check range yet!!!
+ /
+ /
+ / This version of mmapmodule.c has been changed significantly
+ / from the original mmapfile.c on which it was based.
+ / The original version of mmapfile is maintained by Sam at
+ / ftp://squirl.nightmare.com/pub/python/python-ext.
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+
+#ifndef MS_WINDOWS
+#define UNIX
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+static int
+my_getpagesize(void)
+{
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ return si.dwPageSize;
+}
+#endif
+
+#ifdef UNIX
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+static int
+my_getpagesize(void)
+{
+ return sysconf(_SC_PAGESIZE);
+}
+#else
+#define my_getpagesize getpagesize
+#endif
+
+#endif /* UNIX */
+
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+/* Prefer MAP_ANONYMOUS since MAP_ANON is deprecated according to man page. */
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+static PyObject *mmap_module_error;
+
+typedef enum
+{
+ ACCESS_DEFAULT,
+ ACCESS_READ,
+ ACCESS_WRITE,
+ ACCESS_COPY
+} access_mode;
+
+typedef struct {
+ PyObject_HEAD
+ char * data;
+ size_t size;
+ size_t pos;
+
+#ifdef MS_WINDOWS
+ HANDLE map_handle;
+ HANDLE file_handle;
+ char * tagname;
+#endif
+
+#ifdef UNIX
+ int fd;
+#endif
+
+ access_mode access;
+} mmap_object;
+
+
+static void
+mmap_object_dealloc(mmap_object *m_obj)
+{
+#ifdef MS_WINDOWS
+ if (m_obj->data != NULL)
+ UnmapViewOfFile (m_obj->data);
+ if (m_obj->map_handle != INVALID_HANDLE_VALUE)
+ CloseHandle (m_obj->map_handle);
+ if (m_obj->file_handle != INVALID_HANDLE_VALUE)
+ CloseHandle (m_obj->file_handle);
+ if (m_obj->tagname)
+ PyMem_Free(m_obj->tagname);
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+ if (m_obj->fd >= 0)
+ (void) close(m_obj->fd);
+ if (m_obj->data!=NULL) {
+ msync(m_obj->data, m_obj->size, MS_SYNC);
+ munmap(m_obj->data, m_obj->size);
+ }
+#endif /* UNIX */
+
+ PyObject_Del(m_obj);
+}
+
+static PyObject *
+mmap_close_method(mmap_object *self, PyObject *unused)
+{
+#ifdef MS_WINDOWS
+ /* For each resource we maintain, we need to check
+ the value is valid, and if so, free the resource
+ and set the member value to an invalid value so
+ the dealloc does not attempt to resource clearing
+ again.
+ TODO - should we check for errors in the close operations???
+ */
+ if (self->data != NULL) {
+ UnmapViewOfFile(self->data);
+ self->data = NULL;
+ }
+ if (self->map_handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(self->map_handle);
+ self->map_handle = INVALID_HANDLE_VALUE;
+ }
+ if (self->file_handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(self->file_handle);
+ self->file_handle = INVALID_HANDLE_VALUE;
+ }
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+ (void) close(self->fd);
+ self->fd = -1;
+ if (self->data != NULL) {
+ munmap(self->data, self->size);
+ self->data = NULL;
+ }
+#endif
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef MS_WINDOWS
+#define CHECK_VALID(err) \
+do { \
+ if (self->map_handle == INVALID_HANDLE_VALUE) { \
+ PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \
+ return err; \
+ } \
+} while (0)
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+#define CHECK_VALID(err) \
+do { \
+ if (self->data == NULL) { \
+ PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \
+ return err; \
+ } \
+} while (0)
+#endif /* UNIX */
+
+static PyObject *
+mmap_read_byte_method(mmap_object *self,
+ PyObject *unused)
+{
+ CHECK_VALID(NULL);
+ if (self->pos < self->size) {
+ char value = self->data[self->pos];
+ self->pos += 1;
+ return Py_BuildValue("c", value);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "read byte out of range");
+ return NULL;
+ }
+}
+
+static PyObject *
+mmap_read_line_method(mmap_object *self,
+ PyObject *unused)
+{
+ char *start = self->data+self->pos;
+ char *eof = self->data+self->size;
+ char *eol;
+ PyObject *result;
+
+ CHECK_VALID(NULL);
+
+ eol = memchr(start, '\n', self->size - self->pos);
+ if (!eol)
+ eol = eof;
+ else
+ ++eol; /* we're interested in the position after the
+ newline. */
+ result = PyString_FromStringAndSize(start, (eol - start));
+ self->pos += (eol - start);
+ return result;
+}
+
+static PyObject *
+mmap_read_method(mmap_object *self,
+ PyObject *args)
+{
+ Py_ssize_t num_bytes;
+ PyObject *result;
+
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "n:read", &num_bytes))
+ return(NULL);
+
+ /* silently 'adjust' out-of-range requests */
+ if ((self->pos + num_bytes) > self->size) {
+ num_bytes -= (self->pos+num_bytes) - self->size;
+ }
+ result = Py_BuildValue("s#", self->data+self->pos, num_bytes);
+ self->pos += num_bytes;
+ return result;
+}
+
+static PyObject *
+mmap_find_method(mmap_object *self,
+ PyObject *args)
+{
+ Py_ssize_t start = self->pos;
+ char *needle;
+ Py_ssize_t len;
+
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "s#|n:find", &needle, &len, &start)) {
+ return NULL;
+ } else {
+ char *p;
+ char *e = self->data + self->size;
+
+ if (start < 0)
+ start += self->size;
+ if (start < 0)
+ start = 0;
+ else if ((size_t)start > self->size)
+ start = self->size;
+
+ for (p = self->data + start; p + len <= e; ++p) {
+ Py_ssize_t i;
+ for (i = 0; i < len && needle[i] == p[i]; ++i)
+ /* nothing */;
+ if (i == len) {
+ return PyInt_FromSsize_t(p - self->data);
+ }
+ }
+ return PyInt_FromLong(-1);
+ }
+}
+
+static int
+is_writeable(mmap_object *self)
+{
+ if (self->access != ACCESS_READ)
+ return 1;
+ PyErr_Format(PyExc_TypeError, "mmap can't modify a readonly memory map.");
+ return 0;
+}
+
+static int
+is_resizeable(mmap_object *self)
+{
+ if ((self->access == ACCESS_WRITE) || (self->access == ACCESS_DEFAULT))
+ return 1;
+ PyErr_Format(PyExc_TypeError,
+ "mmap can't resize a readonly or copy-on-write memory map.");
+ return 0;
+}
+
+
+static PyObject *
+mmap_write_method(mmap_object *self,
+ PyObject *args)
+{
+ Py_ssize_t length;
+ char *data;
+
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "s#:write", &data, &length))
+ return(NULL);
+
+ if (!is_writeable(self))
+ return NULL;
+
+ if ((self->pos + length) > self->size) {
+ PyErr_SetString(PyExc_ValueError, "data out of range");
+ return NULL;
+ }
+ memcpy(self->data+self->pos, data, length);
+ self->pos = self->pos+length;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+mmap_write_byte_method(mmap_object *self,
+ PyObject *args)
+{
+ char value;
+
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "c:write_byte", &value))
+ return(NULL);
+
+ if (!is_writeable(self))
+ return NULL;
+ *(self->data+self->pos) = value;
+ self->pos += 1;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+mmap_size_method(mmap_object *self,
+ PyObject *unused)
+{
+ CHECK_VALID(NULL);
+
+#ifdef MS_WINDOWS
+ if (self->file_handle != INVALID_HANDLE_VALUE) {
+ DWORD low,high;
+ PY_LONG_LONG size;
+ low = GetFileSize(self->file_handle, &high);
+ if (low == INVALID_FILE_SIZE) {
+ /* It might be that the function appears to have failed,
+ when indeed its size equals INVALID_FILE_SIZE */
+ DWORD error = GetLastError();
+ if (error != NO_ERROR)
+ return PyErr_SetFromWindowsErr(error);
+ }
+ if (!high && low < LONG_MAX)
+ return PyInt_FromLong((long)low);
+ size = (((PY_LONG_LONG)high)<<32) + low;
+ return PyLong_FromLongLong(size);
+ } else {
+ return PyInt_FromSsize_t(self->size);
+ }
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+ {
+ struct stat buf;
+ if (-1 == fstat(self->fd, &buf)) {
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+ return PyInt_FromSsize_t(buf.st_size);
+ }
+#endif /* UNIX */
+}
+
+/* This assumes that you want the entire file mapped,
+ / and when recreating the map will make the new file
+ / have the new size
+ /
+ / Is this really necessary? This could easily be done
+ / from python by just closing and re-opening with the
+ / new size?
+ */
+
+static PyObject *
+mmap_resize_method(mmap_object *self,
+ PyObject *args)
+{
+ Py_ssize_t new_size;
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "n:resize", &new_size) ||
+ !is_resizeable(self)) {
+ return NULL;
+#ifdef MS_WINDOWS
+ } else {
+ DWORD dwErrCode = 0;
+ DWORD newSizeLow, newSizeHigh;
+ /* First, unmap the file view */
+ UnmapViewOfFile(self->data);
+ /* Close the mapping object */
+ CloseHandle(self->map_handle);
+ /* Move to the desired EOF position */
+#if SIZEOF_SIZE_T > 4
+ newSizeHigh = (DWORD)(new_size >> 32);
+ newSizeLow = (DWORD)(new_size & 0xFFFFFFFF);
+#else
+ newSizeHigh = 0;
+ newSizeLow = (DWORD)new_size;
+#endif
+ SetFilePointer(self->file_handle,
+ newSizeLow, &newSizeHigh, FILE_BEGIN);
+ /* Change the size of the file */
+ SetEndOfFile(self->file_handle);
+ /* Create another mapping object and remap the file view */
+ self->map_handle = CreateFileMapping(
+ self->file_handle,
+ NULL,
+ PAGE_READWRITE,
+ newSizeHigh,
+ newSizeLow,
+ self->tagname);
+ if (self->map_handle != NULL) {
+ self->data = (char *) MapViewOfFile(self->map_handle,
+ FILE_MAP_WRITE,
+ 0,
+ 0,
+ 0);
+ if (self->data != NULL) {
+ self->size = new_size;
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {
+ dwErrCode = GetLastError();
+ }
+ } else {
+ dwErrCode = GetLastError();
+ }
+ PyErr_SetFromWindowsErr(dwErrCode);
+ return NULL;
+#endif /* MS_WINDOWS */
+
+#ifdef UNIX
+#ifndef HAVE_MREMAP
+ } else {
+ PyErr_SetString(PyExc_SystemError,
+ "mmap: resizing not available--no mremap()");
+ return NULL;
+#else
+ } else {
+ void *newmap;
+
+ if (ftruncate(self->fd, new_size) == -1) {
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+
+#ifdef MREMAP_MAYMOVE
+ newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
+#else
+ newmap = mremap(self->data, self->size, new_size, 0);
+#endif
+ if (newmap == (void *)-1)
+ {
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+ self->data = newmap;
+ self->size = new_size;
+ Py_INCREF(Py_None);
+ return Py_None;
+#endif /* HAVE_MREMAP */
+#endif /* UNIX */
+ }
+}
+
+static PyObject *
+mmap_tell_method(mmap_object *self, PyObject *unused)
+{
+ CHECK_VALID(NULL);
+ return PyInt_FromSize_t(self->pos);
+}
+
+static PyObject *
+mmap_flush_method(mmap_object *self, PyObject *args)
+{
+ Py_ssize_t offset = 0;
+ Py_ssize_t size = self->size;
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size))
+ return NULL;
+ if ((size_t)(offset + size) > self->size) {
+ PyErr_SetString(PyExc_ValueError, "flush values out of range");
+ return NULL;
+ } else {
+#ifdef MS_WINDOWS
+ return PyInt_FromLong((long)
+ FlushViewOfFile(self->data+offset, size));
+#endif /* MS_WINDOWS */
+#ifdef UNIX
+ /* XXX semantics of return value? */
+ /* XXX flags for msync? */
+ if (-1 == msync(self->data + offset, size,
+ MS_SYNC))
+ {
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+ return PyInt_FromLong(0);
+#endif /* UNIX */
+ }
+}
+
+static PyObject *
+mmap_seek_method(mmap_object *self, PyObject *args)
+{
+ Py_ssize_t dist;
+ int how=0;
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "n|i:seek", &dist, &how))
+ return NULL;
+ else {
+ size_t where;
+ switch (how) {
+ case 0: /* relative to start */
+ if (dist < 0)
+ goto onoutofrange;
+ where = dist;
+ break;
+ case 1: /* relative to current position */
+ if ((Py_ssize_t)self->pos + dist < 0)
+ goto onoutofrange;
+ where = self->pos + dist;
+ break;
+ case 2: /* relative to end */
+ if ((Py_ssize_t)self->size + dist < 0)
+ goto onoutofrange;
+ where = self->size + dist;
+ break;
+ default:
+ PyErr_SetString(PyExc_ValueError, "unknown seek type");
+ return NULL;
+ }
+ if (where > self->size)
+ goto onoutofrange;
+ self->pos = where;
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ onoutofrange:
+ PyErr_SetString(PyExc_ValueError, "seek out of range");
+ return NULL;
+}
+
+static PyObject *
+mmap_move_method(mmap_object *self, PyObject *args)
+{
+ unsigned long dest, src, count;
+ CHECK_VALID(NULL);
+ if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) ||
+ !is_writeable(self)) {
+ return NULL;
+ } else {
+ /* bounds check the values */
+ if (/* end of source after end of data?? */
+ ((src+count) > self->size)
+ /* dest will fit? */
+ || (dest+count > self->size)) {
+ PyErr_SetString(PyExc_ValueError,
+ "source or destination out of range");
+ return NULL;
+ } else {
+ memmove(self->data+dest, self->data+src, count);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+}
+
+static struct PyMethodDef mmap_object_methods[] = {
+ {"close", (PyCFunction) mmap_close_method, METH_NOARGS},
+ {"find", (PyCFunction) mmap_find_method, METH_VARARGS},
+ {"flush", (PyCFunction) mmap_flush_method, METH_VARARGS},
+ {"move", (PyCFunction) mmap_move_method, METH_VARARGS},
+ {"read", (PyCFunction) mmap_read_method, METH_VARARGS},
+ {"read_byte", (PyCFunction) mmap_read_byte_method, METH_NOARGS},
+ {"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS},
+ {"resize", (PyCFunction) mmap_resize_method, METH_VARARGS},
+ {"seek", (PyCFunction) mmap_seek_method, METH_VARARGS},
+ {"size", (PyCFunction) mmap_size_method, METH_NOARGS},
+ {"tell", (PyCFunction) mmap_tell_method, METH_NOARGS},
+ {"write", (PyCFunction) mmap_write_method, METH_VARARGS},
+ {"write_byte", (PyCFunction) mmap_write_byte_method, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Functions for treating an mmap'ed file as a buffer */
+
+static Py_ssize_t
+mmap_buffer_getreadbuf(mmap_object *self, Py_ssize_t index, const void **ptr)
+{
+ CHECK_VALID(-1);
+ if (index != 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "Accessing non-existent mmap segment");
+ return -1;
+ }
+ *ptr = self->data;
+ return self->size;
+}
+
+static Py_ssize_t
+mmap_buffer_getwritebuf(mmap_object *self, Py_ssize_t index, const void **ptr)
+{
+ CHECK_VALID(-1);
+ if (index != 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "Accessing non-existent mmap segment");
+ return -1;
+ }
+ if (!is_writeable(self))
+ return -1;
+ *ptr = self->data;
+ return self->size;
+}
+
+static Py_ssize_t
+mmap_buffer_getsegcount(mmap_object *self, Py_ssize_t *lenp)
+{
+ CHECK_VALID(-1);
+ if (lenp)
+ *lenp = self->size;
+ return 1;
+}
+
+static Py_ssize_t
+mmap_buffer_getcharbuffer(mmap_object *self, Py_ssize_t index, const void **ptr)
+{
+ if (index != 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ *ptr = (const char *)self->data;
+ return self->size;
+}
+
+static PyObject *
+mmap_object_getattr(mmap_object *self, char *name)
+{
+ return Py_FindMethod(mmap_object_methods, (PyObject *)self, name);
+}
+
+static Py_ssize_t
+mmap_length(mmap_object *self)
+{
+ CHECK_VALID(-1);
+ return self->size;
+}
+
+static PyObject *
+mmap_item(mmap_object *self, Py_ssize_t i)
+{
+ CHECK_VALID(NULL);
+ if (i < 0 || (size_t)i >= self->size) {
+ PyErr_SetString(PyExc_IndexError, "mmap index out of range");
+ return NULL;
+ }
+ return PyString_FromStringAndSize(self->data + i, 1);
+}
+
+static PyObject *
+mmap_slice(mmap_object *self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+ CHECK_VALID(NULL);
+ if (ilow < 0)
+ ilow = 0;
+ else if ((size_t)ilow > self->size)
+ ilow = self->size;
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if ((size_t)ihigh > self->size)
+ ihigh = self->size;
+
+ return PyString_FromStringAndSize(self->data + ilow, ihigh-ilow);
+}
+
+static PyObject *
+mmap_concat(mmap_object *self, PyObject *bb)
+{
+ CHECK_VALID(NULL);
+ PyErr_SetString(PyExc_SystemError,
+ "mmaps don't support concatenation");
+ return NULL;
+}
+
+static PyObject *
+mmap_repeat(mmap_object *self, Py_ssize_t n)
+{
+ CHECK_VALID(NULL);
+ PyErr_SetString(PyExc_SystemError,
+ "mmaps don't support repeat operation");
+ return NULL;
+}
+
+static int
+mmap_ass_slice(mmap_object *self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+ const char *buf;
+
+ CHECK_VALID(-1);
+ if (ilow < 0)
+ ilow = 0;
+ else if ((size_t)ilow > self->size)
+ ilow = self->size;
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if ((size_t)ihigh > self->size)
+ ihigh = self->size;
+
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "mmap object doesn't support slice deletion");
+ return -1;
+ }
+ if (! (PyString_Check(v)) ) {
+ PyErr_SetString(PyExc_IndexError,
+ "mmap slice assignment must be a string");
+ return -1;
+ }
+ if (PyString_Size(v) != (ihigh - ilow)) {
+ PyErr_SetString(PyExc_IndexError,
+ "mmap slice assignment is wrong size");
+ return -1;
+ }
+ if (!is_writeable(self))
+ return -1;
+ buf = PyString_AsString(v);
+ memcpy(self->data + ilow, buf, ihigh-ilow);
+ return 0;
+}
+
+static int
+mmap_ass_item(mmap_object *self, Py_ssize_t i, PyObject *v)
+{
+ const char *buf;
+
+ CHECK_VALID(-1);
+ if (i < 0 || (size_t)i >= self->size) {
+ PyErr_SetString(PyExc_IndexError, "mmap index out of range");
+ return -1;
+ }
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "mmap object doesn't support item deletion");
+ return -1;
+ }
+ if (! (PyString_Check(v) && PyString_Size(v)==1) ) {
+ PyErr_SetString(PyExc_IndexError,
+ "mmap assignment must be single-character string");
+ return -1;
+ }
+ if (!is_writeable(self))
+ return -1;
+ buf = PyString_AsString(v);
+ self->data[i] = buf[0];
+ return 0;
+}
+
+static PySequenceMethods mmap_as_sequence = {
+ (lenfunc)mmap_length, /*sq_length*/
+ (binaryfunc)mmap_concat, /*sq_concat*/
+ (ssizeargfunc)mmap_repeat, /*sq_repeat*/
+ (ssizeargfunc)mmap_item, /*sq_item*/
+ (ssizessizeargfunc)mmap_slice, /*sq_slice*/
+ (ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/
+ (ssizessizeobjargproc)mmap_ass_slice, /*sq_ass_slice*/
+};
+
+static PyBufferProcs mmap_as_buffer = {
+ (readbufferproc)mmap_buffer_getreadbuf,
+ (writebufferproc)mmap_buffer_getwritebuf,
+ (segcountproc)mmap_buffer_getsegcount,
+ (charbufferproc)mmap_buffer_getcharbuffer,
+};
+
+static PyTypeObject mmap_object_type = {
+ PyObject_HEAD_INIT(0) /* patched in module init */
+ 0, /* ob_size */
+ "mmap.mmap", /* tp_name */
+ sizeof(mmap_object), /* tp_size */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor) mmap_object_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) mmap_object_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &mmap_as_sequence, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &mmap_as_buffer, /*tp_as_buffer*/
+ Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/
+ 0, /*tp_doc*/
+};
+
+
+/* extract the map size from the given PyObject
+
+ Returns -1 on error, with an appropriate Python exception raised. On
+ success, the map size is returned. */
+static Py_ssize_t
+_GetMapSize(PyObject *o)
+{
+ if (PyIndex_Check(o)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
+ if (i==-1 && PyErr_Occurred())
+ return -1;
+ if (i < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "memory mapped size must be positive");
+ return -1;
+ }
+ return i;
+ }
+
+ PyErr_SetString(PyExc_TypeError, "map size must be an integral value");
+ return -1;
+}
+
+#ifdef UNIX
+static PyObject *
+new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+#ifdef HAVE_FSTAT
+ struct stat st;
+#endif
+ mmap_object *m_obj;
+ PyObject *map_size_obj = NULL;
+ Py_ssize_t map_size;
+ int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
+ int devzero = -1;
+ int access = (int)ACCESS_DEFAULT;
+ static char *keywords[] = {"fileno", "length",
+ "flags", "prot",
+ "access", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|iii", keywords,
+ &fd, &map_size_obj, &flags, &prot,
+ &access))
+ return NULL;
+ map_size = _GetMapSize(map_size_obj);
+ if (map_size < 0)
+ return NULL;
+
+ if ((access != (int)ACCESS_DEFAULT) &&
+ ((flags != MAP_SHARED) || (prot != (PROT_WRITE | PROT_READ))))
+ return PyErr_Format(PyExc_ValueError,
+ "mmap can't specify both access and flags, prot.");
+ switch ((access_mode)access) {
+ case ACCESS_READ:
+ flags = MAP_SHARED;
+ prot = PROT_READ;
+ break;
+ case ACCESS_WRITE:
+ flags = MAP_SHARED;
+ prot = PROT_READ | PROT_WRITE;
+ break;
+ case ACCESS_COPY:
+ flags = MAP_PRIVATE;
+ prot = PROT_READ | PROT_WRITE;
+ break;
+ case ACCESS_DEFAULT:
+ /* use the specified or default values of flags and prot */
+ break;
+ default:
+ return PyErr_Format(PyExc_ValueError,
+ "mmap invalid access parameter.");
+ }
+
+#ifdef HAVE_FSTAT
+# ifdef __VMS
+ /* on OpenVMS we must ensure that all bytes are written to the file */
+ fsync(fd);
+# endif
+ if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
+ if (map_size == 0) {
+ map_size = st.st_size;
+ } else if ((size_t)map_size > st.st_size) {
+ PyErr_SetString(PyExc_ValueError,
+ "mmap length is greater than file size");
+ return NULL;
+ }
+ }
+#endif
+ m_obj = PyObject_New(mmap_object, &mmap_object_type);
+ if (m_obj == NULL) {return NULL;}
+ m_obj->data = NULL;
+ m_obj->size = (size_t) map_size;
+ m_obj->pos = (size_t) 0;
+ if (fd == -1) {
+ m_obj->fd = -1;
+ /* Assume the caller wants to map anonymous memory.
+ This is the same behaviour as Windows. mmap.mmap(-1, size)
+ on both Windows and Unix map anonymous memory.
+ */
+#ifdef MAP_ANONYMOUS
+ /* BSD way to map anonymous memory */
+ flags |= MAP_ANONYMOUS;
+#else
+ /* SVR4 method to map anonymous memory is to open /dev/zero */
+ fd = devzero = open("/dev/zero", O_RDWR);
+ if (devzero == -1) {
+ Py_DECREF(m_obj);
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+#endif
+ } else {
+ m_obj->fd = dup(fd);
+ if (m_obj->fd == -1) {
+ Py_DECREF(m_obj);
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+ }
+
+ m_obj->data = mmap(NULL, map_size,
+ prot, flags,
+ fd, 0);
+
+ if (devzero != -1) {
+ close(devzero);
+ }
+
+ if (m_obj->data == (char *)-1) {
+ m_obj->data = NULL;
+ Py_DECREF(m_obj);
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+ m_obj->access = (access_mode)access;
+ return (PyObject *)m_obj;
+}
+#endif /* UNIX */
+
+#ifdef MS_WINDOWS
+static PyObject *
+new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ mmap_object *m_obj;
+ PyObject *map_size_obj = NULL;
+ Py_ssize_t map_size;
+ DWORD size_hi; /* upper 32 bits of m_obj->size */
+ DWORD size_lo; /* lower 32 bits of m_obj->size */
+ char *tagname = "";
+ DWORD dwErr = 0;
+ int fileno;
+ HANDLE fh = 0;
+ int access = (access_mode)ACCESS_DEFAULT;
+ DWORD flProtect, dwDesiredAccess;
+ static char *keywords[] = { "fileno", "length",
+ "tagname",
+ "access", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|zi", keywords,
+ &fileno, &map_size_obj,
+ &tagname, &access)) {
+ return NULL;
+ }
+
+ switch((access_mode)access) {
+ case ACCESS_READ:
+ flProtect = PAGE_READONLY;
+ dwDesiredAccess = FILE_MAP_READ;
+ break;
+ case ACCESS_DEFAULT: case ACCESS_WRITE:
+ flProtect = PAGE_READWRITE;
+ dwDesiredAccess = FILE_MAP_WRITE;
+ break;
+ case ACCESS_COPY:
+ flProtect = PAGE_WRITECOPY;
+ dwDesiredAccess = FILE_MAP_COPY;
+ break;
+ default:
+ return PyErr_Format(PyExc_ValueError,
+ "mmap invalid access parameter.");
+ }
+
+ map_size = _GetMapSize(map_size_obj);
+ if (map_size < 0)
+ return NULL;
+
+ /* assume -1 and 0 both mean invalid filedescriptor
+ to 'anonymously' map memory.
+ XXX: fileno == 0 is a valid fd, but was accepted prior to 2.5.
+ XXX: Should this code be added?
+ if (fileno == 0)
+ PyErr_Warn(PyExc_DeprecationWarning,
+ "don't use 0 for anonymous memory");
+ */
+ if (fileno != -1 && fileno != 0) {
+ fh = (HANDLE)_get_osfhandle(fileno);
+ if (fh==(HANDLE)-1) {
+ PyErr_SetFromErrno(mmap_module_error);
+ return NULL;
+ }
+ /* Win9x appears to need us seeked to zero */
+ lseek(fileno, 0, SEEK_SET);
+ }
+
+ m_obj = PyObject_New(mmap_object, &mmap_object_type);
+ if (m_obj == NULL)
+ return NULL;
+ /* Set every field to an invalid marker, so we can safely
+ destruct the object in the face of failure */
+ m_obj->data = NULL;
+ m_obj->file_handle = INVALID_HANDLE_VALUE;
+ m_obj->map_handle = INVALID_HANDLE_VALUE;
+ m_obj->tagname = NULL;
+
+ if (fh) {
+ /* It is necessary to duplicate the handle, so the
+ Python code can close it on us */
+ if (!DuplicateHandle(
+ GetCurrentProcess(), /* source process handle */
+ fh, /* handle to be duplicated */
+ GetCurrentProcess(), /* target proc handle */
+ (LPHANDLE)&m_obj->file_handle, /* result */
+ 0, /* access - ignored due to options value */
+ FALSE, /* inherited by child processes? */
+ DUPLICATE_SAME_ACCESS)) { /* options */
+ dwErr = GetLastError();
+ Py_DECREF(m_obj);
+ PyErr_SetFromWindowsErr(dwErr);
+ return NULL;
+ }
+ if (!map_size) {
+ DWORD low,high;
+ low = GetFileSize(fh, &high);
+ /* low might just happen to have the value INVALID_FILE_SIZE;
+ so we need to check the last error also. */
+ if (low == INVALID_FILE_SIZE &&
+ (dwErr = GetLastError()) != NO_ERROR) {
+ Py_DECREF(m_obj);
+ return PyErr_SetFromWindowsErr(dwErr);
+ }
+
+#if SIZEOF_SIZE_T > 4
+ m_obj->size = (((size_t)high)<<32) + low;
+#else
+ if (high)
+ /* File is too large to map completely */
+ m_obj->size = (size_t)-1;
+ else
+ m_obj->size = low;
+#endif
+ } else {
+ m_obj->size = map_size;
+ }
+ }
+ else {
+ m_obj->size = map_size;
+ }
+
+ /* set the initial position */
+ m_obj->pos = (size_t) 0;
+
+ /* set the tag name */
+ if (tagname != NULL && *tagname != '\0') {
+ m_obj->tagname = PyMem_Malloc(strlen(tagname)+1);
+ if (m_obj->tagname == NULL) {
+ PyErr_NoMemory();
+ Py_DECREF(m_obj);
+ return NULL;
+ }
+ strcpy(m_obj->tagname, tagname);
+ }
+ else
+ m_obj->tagname = NULL;
+
+ m_obj->access = (access_mode)access;
+ /* DWORD is a 4-byte int. If we're on a box where size_t consumes
+ * more than 4 bytes, we need to break it apart. Else (size_t
+ * consumes 4 bytes), C doesn't define what happens if we shift
+ * right by 32, so we need different code.
+ */
+#if SIZEOF_SIZE_T > 4
+ size_hi = (DWORD)(m_obj->size >> 32);
+ size_lo = (DWORD)(m_obj->size & 0xFFFFFFFF);
+#else
+ size_hi = 0;
+ size_lo = (DWORD)m_obj->size;
+#endif
+ m_obj->map_handle = CreateFileMapping(m_obj->file_handle,
+ NULL,
+ flProtect,
+ size_hi,
+ size_lo,
+ m_obj->tagname);
+ if (m_obj->map_handle != NULL) {
+ m_obj->data = (char *) MapViewOfFile(m_obj->map_handle,
+ dwDesiredAccess,
+ 0,
+ 0,
+ 0);
+ if (m_obj->data != NULL)
+ return (PyObject *)m_obj;
+ else
+ dwErr = GetLastError();
+ } else
+ dwErr = GetLastError();
+ Py_DECREF(m_obj);
+ PyErr_SetFromWindowsErr(dwErr);
+ return NULL;
+}
+#endif /* MS_WINDOWS */
+
+/* List of functions exported by this module */
+static struct PyMethodDef mmap_functions[] = {
+ {"mmap", (PyCFunction) new_mmap_object,
+ METH_VARARGS|METH_KEYWORDS},
+ {NULL, NULL} /* Sentinel */
+};
+
+static void
+setint(PyObject *d, const char *name, long value)
+{
+ PyObject *o = PyInt_FromLong(value);
+ if (o && PyDict_SetItemString(d, name, o) == 0) {
+ Py_DECREF(o);
+ }
+}
+
+PyMODINIT_FUNC
+ initmmap(void)
+{
+ PyObject *dict, *module;
+
+ /* Patch the object type */
+ mmap_object_type.ob_type = &PyType_Type;
+
+ module = Py_InitModule("mmap", mmap_functions);
+ if (module == NULL)
+ return;
+ dict = PyModule_GetDict(module);
+ if (!dict)
+ return;
+ mmap_module_error = PyExc_EnvironmentError;
+ PyDict_SetItemString(dict, "error", mmap_module_error);
+#ifdef PROT_EXEC
+ setint(dict, "PROT_EXEC", PROT_EXEC);
+#endif
+#ifdef PROT_READ
+ setint(dict, "PROT_READ", PROT_READ);
+#endif
+#ifdef PROT_WRITE
+ setint(dict, "PROT_WRITE", PROT_WRITE);
+#endif
+
+#ifdef MAP_SHARED
+ setint(dict, "MAP_SHARED", MAP_SHARED);
+#endif
+#ifdef MAP_PRIVATE
+ setint(dict, "MAP_PRIVATE", MAP_PRIVATE);
+#endif
+#ifdef MAP_DENYWRITE
+ setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE);
+#endif
+#ifdef MAP_EXECUTABLE
+ setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE);
+#endif
+#ifdef MAP_ANONYMOUS
+ setint(dict, "MAP_ANON", MAP_ANONYMOUS);
+ setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS);
+#endif
+
+ setint(dict, "PAGESIZE", (long)my_getpagesize());
+
+ setint(dict, "ACCESS_READ", ACCESS_READ);
+ setint(dict, "ACCESS_WRITE", ACCESS_WRITE);
+ setint(dict, "ACCESS_COPY", ACCESS_COPY);
+}
diff --git a/sys/src/cmd/python/Modules/nismodule.c b/sys/src/cmd/python/Modules/nismodule.c
new file mode 100644
index 000000000..0811430cf
--- /dev/null
+++ b/sys/src/cmd/python/Modules/nismodule.c
@@ -0,0 +1,444 @@
+/***********************************************************
+ Written by:
+ Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
+ B&O group,
+ Faculteit der Informatica,
+ Universiteit Twente,
+ Enschede,
+ the Netherlands.
+******************************************************************/
+
+/* NIS module implementation */
+
+#include "Python.h"
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+#ifdef __sgi
+/* This is missing from rpcsvc/ypclnt.h */
+extern int yp_get_default_domain(char **);
+#endif
+
+PyDoc_STRVAR(get_default_domain__doc__,
+"get_default_domain() -> str\n\
+Corresponds to the C library yp_get_default_domain() call, returning\n\
+the default NIS domain.\n");
+
+PyDoc_STRVAR(match__doc__,
+"match(key, map, domain = defaultdomain)\n\
+Corresponds to the C library yp_match() call, returning the value of\n\
+key in the given map. Optionally domain can be specified but it\n\
+defaults to the system default domain.\n");
+
+PyDoc_STRVAR(cat__doc__,
+"cat(map, domain = defaultdomain)\n\
+Returns the entire map as a dictionary. Optionally domain can be\n\
+specified but it defaults to the system default domain.\n");
+
+PyDoc_STRVAR(maps__doc__,
+"maps(domain = defaultdomain)\n\
+Returns an array of all available NIS maps within a domain. If domain\n\
+is not specified it defaults to the system default domain.\n");
+
+static PyObject *NisError;
+
+static PyObject *
+nis_error (int err)
+{
+ PyErr_SetString(NisError, yperr_string(err));
+ return NULL;
+}
+
+static struct nis_map {
+ char *alias;
+ char *map;
+ int fix;
+} aliases [] = {
+ {"passwd", "passwd.byname", 0},
+ {"group", "group.byname", 0},
+ {"networks", "networks.byaddr", 0},
+ {"hosts", "hosts.byname", 0},
+ {"protocols", "protocols.bynumber", 0},
+ {"services", "services.byname", 0},
+ {"aliases", "mail.aliases", 1}, /* created with 'makedbm -a' */
+ {"ethers", "ethers.byname", 0},
+ {0L, 0L, 0}
+};
+
+static char *
+nis_mapname (char *map, int *pfix)
+{
+ int i;
+
+ *pfix = 0;
+ for (i=0; aliases[i].alias != 0L; i++) {
+ if (!strcmp (aliases[i].alias, map)) {
+ *pfix = aliases[i].fix;
+ return aliases[i].map;
+ }
+ if (!strcmp (aliases[i].map, map)) {
+ *pfix = aliases[i].fix;
+ return aliases[i].map;
+ }
+ }
+
+ return map;
+}
+
+#ifdef __APPLE__
+typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *);
+#else
+typedef int (*foreachfunc)(int, char *, int, char *, int, char *);
+#endif
+
+struct ypcallback_data {
+ PyObject *dict;
+ int fix;
+};
+
+static int
+nis_foreach (int instatus, char *inkey, int inkeylen, char *inval,
+ int invallen, struct ypcallback_data *indata)
+{
+ if (instatus == YP_TRUE) {
+ PyObject *key;
+ PyObject *val;
+ int err;
+
+ if (indata->fix) {
+ if (inkeylen > 0 && inkey[inkeylen-1] == '\0')
+ inkeylen--;
+ if (invallen > 0 && inval[invallen-1] == '\0')
+ invallen--;
+ }
+ key = PyString_FromStringAndSize(inkey, inkeylen);
+ val = PyString_FromStringAndSize(inval, invallen);
+ if (key == NULL || val == NULL) {
+ /* XXX error -- don't know how to handle */
+ PyErr_Clear();
+ Py_XDECREF(key);
+ Py_XDECREF(val);
+ return 1;
+ }
+ err = PyDict_SetItem(indata->dict, key, val);
+ Py_DECREF(key);
+ Py_DECREF(val);
+ if (err != 0) {
+ PyErr_Clear();
+ return 1;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject *
+nis_get_default_domain (PyObject *self)
+{
+ char *domain;
+ int err;
+ PyObject *res;
+
+ if ((err = yp_get_default_domain(&domain)) != 0)
+ return nis_error(err);
+
+ res = PyString_FromStringAndSize (domain, strlen(domain));
+ return res;
+}
+
+static PyObject *
+nis_match (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ char *match;
+ char *domain = NULL;
+ int keylen, len;
+ char *key, *map;
+ int err;
+ PyObject *res;
+ int fix;
+ static char *kwlist[] = {"key", "map", "domain", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict,
+ "t#s|s:match", kwlist,
+ &key, &keylen, &map, &domain))
+ return NULL;
+ if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
+ return nis_error(err);
+ map = nis_mapname (map, &fix);
+ if (fix)
+ keylen++;
+ Py_BEGIN_ALLOW_THREADS
+ err = yp_match (domain, map, key, keylen, &match, &len);
+ Py_END_ALLOW_THREADS
+ if (fix)
+ len--;
+ if (err != 0)
+ return nis_error(err);
+ res = PyString_FromStringAndSize (match, len);
+ free (match);
+ return res;
+}
+
+static PyObject *
+nis_cat (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ char *domain = NULL;
+ char *map;
+ struct ypall_callback cb;
+ struct ypcallback_data data;
+ PyObject *dict;
+ int err;
+ static char *kwlist[] = {"map", "domain", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat",
+ kwlist, &map, &domain))
+ return NULL;
+ if (!domain && ((err = yp_get_default_domain(&domain)) != 0))
+ return nis_error(err);
+ dict = PyDict_New ();
+ if (dict == NULL)
+ return NULL;
+ cb.foreach = (foreachfunc)nis_foreach;
+ data.dict = dict;
+ map = nis_mapname (map, &data.fix);
+ cb.data = (char *)&data;
+ Py_BEGIN_ALLOW_THREADS
+ err = yp_all (domain, map, &cb);
+ Py_END_ALLOW_THREADS
+ if (err != 0) {
+ Py_DECREF(dict);
+ return nis_error(err);
+ }
+ return dict;
+}
+
+/* These should be u_long on Sun h/w but not on 64-bit h/w.
+ This is not portable to machines with 16-bit ints and no prototypes */
+#ifndef YPPROC_MAPLIST
+#define YPPROC_MAPLIST 11
+#endif
+#ifndef YPPROG
+#define YPPROG 100004
+#endif
+#ifndef YPVERS
+#define YPVERS 2
+#endif
+
+typedef char *domainname;
+typedef char *mapname;
+
+enum nisstat {
+ NIS_TRUE = 1,
+ NIS_NOMORE = 2,
+ NIS_FALSE = 0,
+ NIS_NOMAP = -1,
+ NIS_NODOM = -2,
+ NIS_NOKEY = -3,
+ NIS_BADOP = -4,
+ NIS_BADDB = -5,
+ NIS_YPERR = -6,
+ NIS_BADARGS = -7,
+ NIS_VERS = -8
+};
+typedef enum nisstat nisstat;
+
+struct nismaplist {
+ mapname map;
+ struct nismaplist *next;
+};
+typedef struct nismaplist nismaplist;
+
+struct nisresp_maplist {
+ nisstat stat;
+ nismaplist *maps;
+};
+typedef struct nisresp_maplist nisresp_maplist;
+
+static struct timeval TIMEOUT = { 25, 0 };
+
+static
+bool_t
+nis_xdr_domainname(XDR *xdrs, domainname *objp)
+{
+ if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_mapname(XDR *xdrs, mapname *objp)
+{
+ if (!xdr_string(xdrs, objp, YPMAXMAP)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp)
+{
+ if (!nis_xdr_mapname(xdrs, &objp->map)) {
+ return (FALSE);
+ }
+ if (!xdr_pointer(xdrs, (char **)&objp->next,
+ sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
+ {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+static
+bool_t
+nis_xdr_ypstat(XDR *xdrs, nisstat *objp)
+{
+ if (!xdr_enum(xdrs, (enum_t *)objp)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static
+bool_t
+nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp)
+{
+ if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
+ return (FALSE);
+ }
+ if (!xdr_pointer(xdrs, (char **)&objp->maps,
+ sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist))
+ {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static
+nisresp_maplist *
+nisproc_maplist_2(domainname *argp, CLIENT *clnt)
+{
+ static nisresp_maplist res;
+
+ memset(&res, 0, sizeof(res));
+ if (clnt_call(clnt, YPPROC_MAPLIST,
+ (xdrproc_t)nis_xdr_domainname, (caddr_t)argp,
+ (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res,
+ TIMEOUT) != RPC_SUCCESS)
+ {
+ return (NULL);
+ }
+ return (&res);
+}
+
+static
+nismaplist *
+nis_maplist (char *dom)
+{
+ nisresp_maplist *list;
+ CLIENT *cl;
+ char *server = NULL;
+ int mapi = 0;
+
+ while (!server && aliases[mapi].map != 0L) {
+ yp_master (dom, aliases[mapi].map, &server);
+ mapi++;
+ }
+ if (!server) {
+ PyErr_SetString(NisError, "No NIS master found for any map");
+ return NULL;
+ }
+ cl = clnt_create(server, YPPROG, YPVERS, "tcp");
+ if (cl == NULL) {
+ PyErr_SetString(NisError, clnt_spcreateerror(server));
+ goto finally;
+ }
+ list = nisproc_maplist_2 (&dom, cl);
+ clnt_destroy(cl);
+ if (list == NULL)
+ goto finally;
+ if (list->stat != NIS_TRUE)
+ goto finally;
+
+ free(server);
+ return list->maps;
+
+ finally:
+ free(server);
+ return NULL;
+}
+
+static PyObject *
+nis_maps (PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ char *domain = NULL;
+ nismaplist *maps;
+ PyObject *list;
+ int err;
+ static char *kwlist[] = {"domain", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict,
+ "|s:maps", kwlist, &domain))
+ return NULL;
+ if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) {
+ nis_error(err);
+ return NULL;
+ }
+
+ if ((maps = nis_maplist (domain)) == NULL)
+ return NULL;
+ if ((list = PyList_New(0)) == NULL)
+ return NULL;
+ for (maps = maps; maps; maps = maps->next) {
+ PyObject *str = PyString_FromString(maps->map);
+ if (!str || PyList_Append(list, str) < 0)
+ {
+ Py_DECREF(list);
+ list = NULL;
+ break;
+ }
+ Py_DECREF(str);
+ }
+ /* XXX Shouldn't we free the list of maps now? */
+ return list;
+}
+
+static PyMethodDef nis_methods[] = {
+ {"match", (PyCFunction)nis_match,
+ METH_VARARGS | METH_KEYWORDS,
+ match__doc__},
+ {"cat", (PyCFunction)nis_cat,
+ METH_VARARGS | METH_KEYWORDS,
+ cat__doc__},
+ {"maps", (PyCFunction)nis_maps,
+ METH_VARARGS | METH_KEYWORDS,
+ maps__doc__},
+ {"get_default_domain", (PyCFunction)nis_get_default_domain,
+ METH_NOARGS,
+ get_default_domain__doc__},
+ {NULL, NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(nis__doc__,
+"This module contains functions for accessing NIS maps.\n");
+
+void
+initnis (void)
+{
+ PyObject *m, *d;
+ m = Py_InitModule3("nis", nis_methods, nis__doc__);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ NisError = PyErr_NewException("nis.error", NULL, NULL);
+ if (NisError != NULL)
+ PyDict_SetItemString(d, "error", NisError);
+}
diff --git a/sys/src/cmd/python/Modules/operator.c b/sys/src/cmd/python/Modules/operator.c
new file mode 100644
index 000000000..0a7222a72
--- /dev/null
+++ b/sys/src/cmd/python/Modules/operator.c
@@ -0,0 +1,602 @@
+
+#include "Python.h"
+
+PyDoc_STRVAR(operator_doc,
+"Operator interface.\n\
+\n\
+This module exports a set of functions implemented in C corresponding\n\
+to the intrinsic operators of Python. For example, operator.add(x, y)\n\
+is equivalent to the expression x+y. The function names are those\n\
+used for special class methods; variants without leading and trailing\n\
+'__' are also provided for convenience.");
+
+#define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \
+ return AOP(a1); }
+
+#define spam2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ return AOP(a1,a2); }
+
+#define spamoi(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1; int a2; \
+ if(! PyArg_ParseTuple(a,"Oi:" #OP,&a1,&a2)) return NULL; \
+ return AOP(a1,a2); }
+
+#define spam2n(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ if(-1 == AOP(a1,a2)) return NULL; \
+ Py_INCREF(Py_None); \
+ return Py_None; }
+
+#define spam3n(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2, *a3; \
+ if(! PyArg_UnpackTuple(a,#OP,3,3,&a1,&a2,&a3)) return NULL; \
+ if(-1 == AOP(a1,a2,a3)) return NULL; \
+ Py_INCREF(Py_None); \
+ return Py_None; }
+
+#define spami(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \
+ long r; \
+ if(-1 == (r=AOP(a1))) return NULL; \
+ return PyBool_FromLong(r); }
+
+#define spami2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; long r; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ if(-1 == (r=AOP(a1,a2))) return NULL; \
+ return PyInt_FromLong(r); }
+
+#define spamn2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; Py_ssize_t r; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ if(-1 == (r=AOP(a1,a2))) return NULL; \
+ return PyInt_FromSsize_t(r); }
+
+#define spami2b(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; long r; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ if(-1 == (r=AOP(a1,a2))) return NULL; \
+ return PyBool_FromLong(r); }
+
+#define spamrc(OP,A) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ return PyObject_RichCompare(a1,a2,A); }
+
+spami(isCallable , PyCallable_Check)
+spami(isNumberType , PyNumber_Check)
+spami(truth , PyObject_IsTrue)
+spam2(op_add , PyNumber_Add)
+spam2(op_sub , PyNumber_Subtract)
+spam2(op_mul , PyNumber_Multiply)
+spam2(op_div , PyNumber_Divide)
+spam2(op_floordiv , PyNumber_FloorDivide)
+spam2(op_truediv , PyNumber_TrueDivide)
+spam2(op_mod , PyNumber_Remainder)
+spam1(op_neg , PyNumber_Negative)
+spam1(op_pos , PyNumber_Positive)
+spam1(op_abs , PyNumber_Absolute)
+spam1(op_inv , PyNumber_Invert)
+spam1(op_invert , PyNumber_Invert)
+spam2(op_lshift , PyNumber_Lshift)
+spam2(op_rshift , PyNumber_Rshift)
+spami(op_not_ , PyObject_Not)
+spam2(op_and_ , PyNumber_And)
+spam2(op_xor , PyNumber_Xor)
+spam2(op_or_ , PyNumber_Or)
+spam2(op_iadd , PyNumber_InPlaceAdd)
+spam2(op_isub , PyNumber_InPlaceSubtract)
+spam2(op_imul , PyNumber_InPlaceMultiply)
+spam2(op_idiv , PyNumber_InPlaceDivide)
+spam2(op_ifloordiv , PyNumber_InPlaceFloorDivide)
+spam2(op_itruediv , PyNumber_InPlaceTrueDivide)
+spam2(op_imod , PyNumber_InPlaceRemainder)
+spam2(op_ilshift , PyNumber_InPlaceLshift)
+spam2(op_irshift , PyNumber_InPlaceRshift)
+spam2(op_iand , PyNumber_InPlaceAnd)
+spam2(op_ixor , PyNumber_InPlaceXor)
+spam2(op_ior , PyNumber_InPlaceOr)
+spami(isSequenceType , PySequence_Check)
+spam2(op_concat , PySequence_Concat)
+spamoi(op_repeat , PySequence_Repeat)
+spam2(op_iconcat , PySequence_InPlaceConcat)
+spamoi(op_irepeat , PySequence_InPlaceRepeat)
+spami2b(op_contains , PySequence_Contains)
+spami2b(sequenceIncludes, PySequence_Contains)
+spamn2(indexOf , PySequence_Index)
+spamn2(countOf , PySequence_Count)
+spami(isMappingType , PyMapping_Check)
+spam2(op_getitem , PyObject_GetItem)
+spam2n(op_delitem , PyObject_DelItem)
+spam3n(op_setitem , PyObject_SetItem)
+spamrc(op_lt , Py_LT)
+spamrc(op_le , Py_LE)
+spamrc(op_eq , Py_EQ)
+spamrc(op_ne , Py_NE)
+spamrc(op_gt , Py_GT)
+spamrc(op_ge , Py_GE)
+
+static PyObject*
+op_pow(PyObject *s, PyObject *a)
+{
+ PyObject *a1, *a2;
+ if (PyArg_UnpackTuple(a,"pow", 2, 2, &a1, &a2))
+ return PyNumber_Power(a1, a2, Py_None);
+ return NULL;
+}
+
+static PyObject*
+op_ipow(PyObject *s, PyObject *a)
+{
+ PyObject *a1, *a2;
+ if (PyArg_UnpackTuple(a,"ipow", 2, 2, &a1, &a2))
+ return PyNumber_InPlacePower(a1, a2, Py_None);
+ return NULL;
+}
+
+static PyObject *
+op_index(PyObject *s, PyObject *a)
+{
+ return PyNumber_Index(a);
+}
+
+static PyObject*
+is_(PyObject *s, PyObject *a)
+{
+ PyObject *a1, *a2, *result = NULL;
+ if (PyArg_UnpackTuple(a,"is_", 2, 2, &a1, &a2)) {
+ result = (a1 == a2) ? Py_True : Py_False;
+ Py_INCREF(result);
+ }
+ return result;
+}
+
+static PyObject*
+is_not(PyObject *s, PyObject *a)
+{
+ PyObject *a1, *a2, *result = NULL;
+ if (PyArg_UnpackTuple(a,"is_not", 2, 2, &a1, &a2)) {
+ result = (a1 != a2) ? Py_True : Py_False;
+ Py_INCREF(result);
+ }
+ return result;
+}
+
+static PyObject*
+op_getslice(PyObject *s, PyObject *a)
+{
+ PyObject *a1;
+ Py_ssize_t a2, a3;
+
+ if (!PyArg_ParseTuple(a, "Onn:getslice", &a1, &a2, &a3))
+ return NULL;
+ return PySequence_GetSlice(a1, a2, a3);
+}
+
+static PyObject*
+op_setslice(PyObject *s, PyObject *a)
+{
+ PyObject *a1, *a4;
+ Py_ssize_t a2, a3;
+
+ if (!PyArg_ParseTuple(a, "OnnO:setslice", &a1, &a2, &a3, &a4))
+ return NULL;
+
+ if (-1 == PySequence_SetSlice(a1, a2, a3, a4))
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+op_delslice(PyObject *s, PyObject *a)
+{
+ PyObject *a1;
+ Py_ssize_t a2, a3;
+
+ if (!PyArg_ParseTuple(a, "Onn:delslice", &a1, &a2, &a3))
+ return NULL;
+
+ if (-1 == PySequence_DelSlice(a1, a2, a3))
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+#undef spam1
+#undef spam2
+#undef spam1o
+#undef spam1o
+#define spam1(OP,DOC) {#OP, OP, METH_VARARGS, PyDoc_STR(DOC)},
+#define spam2(OP,ALTOP,DOC) {#OP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, \
+ {#ALTOP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)},
+#define spam1o(OP,DOC) {#OP, OP, METH_O, PyDoc_STR(DOC)},
+#define spam2o(OP,ALTOP,DOC) {#OP, op_##OP, METH_O, PyDoc_STR(DOC)}, \
+ {#ALTOP, op_##OP, METH_O, PyDoc_STR(DOC)},
+
+static struct PyMethodDef operator_methods[] = {
+
+spam1o(isCallable,
+ "isCallable(a) -- Same as callable(a).")
+spam1o(isNumberType,
+ "isNumberType(a) -- Return True if a has a numeric type, False otherwise.")
+spam1o(isSequenceType,
+ "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.")
+spam1o(truth,
+ "truth(a) -- Return True if a is true, False otherwise.")
+spam2(contains,__contains__,
+ "contains(a, b) -- Same as b in a (note reversed operands).")
+spam1(sequenceIncludes,
+ "sequenceIncludes(a, b) -- Same as b in a (note reversed operands; deprecated).")
+spam1(indexOf,
+ "indexOf(a, b) -- Return the first index of b in a.")
+spam1(countOf,
+ "countOf(a, b) -- Return the number of times b occurs in a.")
+spam1o(isMappingType,
+ "isMappingType(a) -- Return True if a has a mapping type, False otherwise.")
+
+spam1(is_, "is_(a, b) -- Same as a is b.")
+spam1(is_not, "is_not(a, b) -- Same as a is not b.")
+spam2o(index, __index__, "index(a) -- Same as a.__index__()")
+spam2(add,__add__, "add(a, b) -- Same as a + b.")
+spam2(sub,__sub__, "sub(a, b) -- Same as a - b.")
+spam2(mul,__mul__, "mul(a, b) -- Same as a * b.")
+spam2(div,__div__, "div(a, b) -- Same as a / b when __future__.division is not in effect.")
+spam2(floordiv,__floordiv__, "floordiv(a, b) -- Same as a // b.")
+spam2(truediv,__truediv__, "truediv(a, b) -- Same as a / b when __future__.division is in effect.")
+spam2(mod,__mod__, "mod(a, b) -- Same as a % b.")
+spam2o(neg,__neg__, "neg(a) -- Same as -a.")
+spam2o(pos,__pos__, "pos(a) -- Same as +a.")
+spam2o(abs,__abs__, "abs(a) -- Same as abs(a).")
+spam2o(inv,__inv__, "inv(a) -- Same as ~a.")
+spam2o(invert,__invert__, "invert(a) -- Same as ~a.")
+spam2(lshift,__lshift__, "lshift(a, b) -- Same as a << b.")
+spam2(rshift,__rshift__, "rshift(a, b) -- Same as a >> b.")
+spam2o(not_,__not__, "not_(a) -- Same as not a.")
+spam2(and_,__and__, "and_(a, b) -- Same as a & b.")
+spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.")
+spam2(or_,__or__, "or_(a, b) -- Same as a | b.")
+spam2(iadd,__iadd__, "iadd(a, b) -- Same as a += b.")
+spam2(isub,__isub__, "isub(a, b) -- Same as a -= b.")
+spam2(imul,__imul__, "imul(a, b) -- Same as a *= b.")
+spam2(idiv,__idiv__, "idiv(a, b) -- Same as a /= b when __future__.division is not in effect.")
+spam2(ifloordiv,__ifloordiv__, "ifloordiv(a, b) -- Same as a //= b.")
+spam2(itruediv,__itruediv__, "itruediv(a, b) -- Same as a /= b when __future__.division is in effect.")
+spam2(imod,__imod__, "imod(a, b) -- Same as a %= b.")
+spam2(ilshift,__ilshift__, "ilshift(a, b) -- Same as a <<= b.")
+spam2(irshift,__irshift__, "irshift(a, b) -- Same as a >>= b.")
+spam2(iand,__iand__, "iand(a, b) -- Same as a &= b.")
+spam2(ixor,__ixor__, "ixor(a, b) -- Same as a ^= b.")
+spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.")
+spam2(concat,__concat__,
+ "concat(a, b) -- Same as a + b, for a and b sequences.")
+spam2(repeat,__repeat__,
+ "repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.")
+spam2(iconcat,__iconcat__,
+ "iconcat(a, b) -- Same as a += b, for a and b sequences.")
+spam2(irepeat,__irepeat__,
+ "irepeat(a, b) -- Same as a *= b, where a is a sequence, and b is an integer.")
+spam2(getitem,__getitem__,
+ "getitem(a, b) -- Same as a[b].")
+spam2(setitem,__setitem__,
+ "setitem(a, b, c) -- Same as a[b] = c.")
+spam2(delitem,__delitem__,
+ "delitem(a, b) -- Same as del a[b].")
+spam2(pow,__pow__, "pow(a, b) -- Same as a ** b.")
+spam2(ipow,__ipow__, "ipow(a, b) -- Same as a **= b.")
+spam2(getslice,__getslice__,
+ "getslice(a, b, c) -- Same as a[b:c].")
+spam2(setslice,__setslice__,
+"setslice(a, b, c, d) -- Same as a[b:c] = d.")
+spam2(delslice,__delslice__,
+"delslice(a, b, c) -- Same as del a[b:c].")
+spam2(lt,__lt__, "lt(a, b) -- Same as a<b.")
+spam2(le,__le__, "le(a, b) -- Same as a<=b.")
+spam2(eq,__eq__, "eq(a, b) -- Same as a==b.")
+spam2(ne,__ne__, "ne(a, b) -- Same as a!=b.")
+spam2(gt,__gt__, "gt(a, b) -- Same as a>b.")
+spam2(ge,__ge__, "ge(a, b) -- Same as a>=b.")
+
+ {NULL, NULL} /* sentinel */
+
+};
+
+/* itemgetter object **********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t nitems;
+ PyObject *item;
+} itemgetterobject;
+
+static PyTypeObject itemgetter_type;
+
+static PyObject *
+itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ itemgetterobject *ig;
+ PyObject *item;
+ Py_ssize_t nitems;
+
+ if (!_PyArg_NoKeywords("itemgetter()", kwds))
+ return NULL;
+
+ nitems = PyTuple_GET_SIZE(args);
+ if (nitems <= 1) {
+ if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
+ return NULL;
+ } else
+ item = args;
+
+ /* create itemgetterobject structure */
+ ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
+ if (ig == NULL)
+ return NULL;
+
+ Py_INCREF(item);
+ ig->item = item;
+ ig->nitems = nitems;
+
+ PyObject_GC_Track(ig);
+ return (PyObject *)ig;
+}
+
+static void
+itemgetter_dealloc(itemgetterobject *ig)
+{
+ PyObject_GC_UnTrack(ig);
+ Py_XDECREF(ig->item);
+ PyObject_GC_Del(ig);
+}
+
+static int
+itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
+{
+ Py_VISIT(ig->item);
+ return 0;
+}
+
+static PyObject *
+itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
+{
+ PyObject *obj, *result;
+ Py_ssize_t i, nitems=ig->nitems;
+
+ if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
+ return NULL;
+ if (nitems == 1)
+ return PyObject_GetItem(obj, ig->item);
+
+ assert(PyTuple_Check(ig->item));
+ assert(PyTuple_GET_SIZE(ig->item) == nitems);
+
+ result = PyTuple_New(nitems);
+ if (result == NULL)
+ return NULL;
+
+ for (i=0 ; i < nitems ; i++) {
+ PyObject *item, *val;
+ item = PyTuple_GET_ITEM(ig->item, i);
+ val = PyObject_GetItem(obj, item);
+ if (val == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, val);
+ }
+ return result;
+}
+
+PyDoc_STRVAR(itemgetter_doc,
+"itemgetter(item, ...) --> itemgetter object\n\
+\n\
+Return a callable object that fetches the given item(s) from its operand.\n\
+After, f=itemgetter(2), the call f(r) returns r[2].\n\
+After, g=itemgetter(2,5,3), the call g(r) returns (r[2], r[5], r[3])");
+
+static PyTypeObject itemgetter_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "operator.itemgetter", /* tp_name */
+ sizeof(itemgetterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)itemgetter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)itemgetter_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ itemgetter_doc, /* tp_doc */
+ (traverseproc)itemgetter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ itemgetter_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/* attrgetter object **********************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t nattrs;
+ PyObject *attr;
+} attrgetterobject;
+
+static PyTypeObject attrgetter_type;
+
+static PyObject *
+attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ attrgetterobject *ag;
+ PyObject *attr;
+ Py_ssize_t nattrs;
+
+ if (!_PyArg_NoKeywords("attrgetter()", kwds))
+ return NULL;
+
+ nattrs = PyTuple_GET_SIZE(args);
+ if (nattrs <= 1) {
+ if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
+ return NULL;
+ } else
+ attr = args;
+
+ /* create attrgetterobject structure */
+ ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
+ if (ag == NULL)
+ return NULL;
+
+ Py_INCREF(attr);
+ ag->attr = attr;
+ ag->nattrs = nattrs;
+
+ PyObject_GC_Track(ag);
+ return (PyObject *)ag;
+}
+
+static void
+attrgetter_dealloc(attrgetterobject *ag)
+{
+ PyObject_GC_UnTrack(ag);
+ Py_XDECREF(ag->attr);
+ PyObject_GC_Del(ag);
+}
+
+static int
+attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
+{
+ Py_VISIT(ag->attr);
+ return 0;
+}
+
+static PyObject *
+attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
+{
+ PyObject *obj, *result;
+ Py_ssize_t i, nattrs=ag->nattrs;
+
+ if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj))
+ return NULL;
+ if (ag->nattrs == 1)
+ return PyObject_GetAttr(obj, ag->attr);
+
+ assert(PyTuple_Check(ag->attr));
+ assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
+
+ result = PyTuple_New(nattrs);
+ if (result == NULL)
+ return NULL;
+
+ for (i=0 ; i < nattrs ; i++) {
+ PyObject *attr, *val;
+ attr = PyTuple_GET_ITEM(ag->attr, i);
+ val = PyObject_GetAttr(obj, attr);
+ if (val == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, val);
+ }
+ return result;
+}
+
+PyDoc_STRVAR(attrgetter_doc,
+"attrgetter(attr, ...) --> attrgetter object\n\
+\n\
+Return a callable object that fetches the given attribute(s) from its operand.\n\
+After, f=attrgetter('name'), the call f(r) returns r.name.\n\
+After, g=attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).");
+
+static PyTypeObject attrgetter_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "operator.attrgetter", /* tp_name */
+ sizeof(attrgetterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)attrgetter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)attrgetter_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ attrgetter_doc, /* tp_doc */
+ (traverseproc)attrgetter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ attrgetter_new, /* tp_new */
+ 0, /* tp_free */
+};
+/* Initialization function for the module (*must* be called initoperator) */
+
+PyMODINIT_FUNC
+initoperator(void)
+{
+ PyObject *m;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule4("operator", operator_methods, operator_doc,
+ (PyObject*)NULL, PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ if (PyType_Ready(&itemgetter_type) < 0)
+ return;
+ Py_INCREF(&itemgetter_type);
+ PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
+
+ if (PyType_Ready(&attrgetter_type) < 0)
+ return;
+ Py_INCREF(&attrgetter_type);
+ PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
+}
diff --git a/sys/src/cmd/python/Modules/ossaudiodev.c b/sys/src/cmd/python/Modules/ossaudiodev.c
new file mode 100644
index 000000000..dc14ded07
--- /dev/null
+++ b/sys/src/cmd/python/Modules/ossaudiodev.c
@@ -0,0 +1,1138 @@
+/*
+ * ossaudiodev -- Python interface to the OSS (Open Sound System) API.
+ * This is the standard audio API for Linux and some
+ * flavours of BSD [XXX which ones?]; it is also available
+ * for a wide range of commercial Unices.
+ *
+ * Originally written by Peter Bosch, March 2000, as linuxaudiodev.
+ *
+ * Renamed to ossaudiodev and rearranged/revised/hacked up
+ * by Greg Ward <gward@python.net>, November 2002.
+ * Mixer interface by Nicholas FitzRoy-Dale <wzdd@lardcave.net>, Dec 2002.
+ *
+ * (c) 2000 Peter Bosch. All Rights Reserved.
+ * (c) 2002 Gregory P. Ward. All Rights Reserved.
+ * (c) 2002 Python Software Foundation. All Rights Reserved.
+ *
+ * XXX need a license statement
+ *
+ * $Id: ossaudiodev.c 52137 2006-10-04 10:23:57Z armin.rigo $
+ */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#define O_RDONLY 00
+#define O_WRONLY 01
+#endif
+
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+
+#if defined(linux)
+
+#ifndef HAVE_STDINT_H
+typedef unsigned long uint32_t;
+#endif
+
+#elif defined(__FreeBSD__)
+
+# ifndef SNDCTL_DSP_CHANNELS
+# define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
+# endif
+
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ char *devicename; /* name of the device file */
+ int fd; /* file descriptor */
+ int mode; /* file mode (O_RDONLY, etc.) */
+ int icount; /* input count */
+ int ocount; /* output count */
+ uint32_t afmts; /* audio formats supported by hardware */
+} oss_audio_t;
+
+typedef struct {
+ PyObject_HEAD
+ int fd; /* The open mixer device */
+} oss_mixer_t;
+
+
+static PyTypeObject OSSAudioType;
+static PyTypeObject OSSMixerType;
+
+static PyObject *OSSAudioError;
+
+
+/* ----------------------------------------------------------------------
+ * DSP object initialization/deallocation
+ */
+
+static oss_audio_t *
+newossobject(PyObject *arg)
+{
+ oss_audio_t *self;
+ int fd, afmts, imode;
+ char *devicename = NULL;
+ char *mode = NULL;
+
+ /* Two ways to call open():
+ open(device, mode) (for consistency with builtin open())
+ open(mode) (for backwards compatibility)
+ because the *first* argument is optional, parsing args is
+ a wee bit tricky. */
+ if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode))
+ return NULL;
+ if (mode == NULL) { /* only one arg supplied */
+ mode = devicename;
+ devicename = NULL;
+ }
+
+ if (strcmp(mode, "r") == 0)
+ imode = O_RDONLY;
+ else if (strcmp(mode, "w") == 0)
+ imode = O_WRONLY;
+ else if (strcmp(mode, "rw") == 0)
+ imode = O_RDWR;
+ else {
+ PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'");
+ return NULL;
+ }
+
+ /* Open the correct device: either the 'device' argument,
+ or the AUDIODEV environment variable, or "/dev/dsp". */
+ if (devicename == NULL) { /* called with one arg */
+ devicename = getenv("AUDIODEV");
+ if (devicename == NULL) /* $AUDIODEV not set */
+ devicename = "/dev/dsp";
+ }
+
+ /* Open with O_NONBLOCK to avoid hanging on devices that only allow
+ one open at a time. This does *not* affect later I/O; OSS
+ provides a special ioctl() for non-blocking read/write, which is
+ exposed via oss_nonblock() below. */
+ if ((fd = open(devicename, imode|O_NONBLOCK)) == -1) {
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+ return NULL;
+ }
+
+ /* And (try to) put it back in blocking mode so we get the
+ expected write() semantics. */
+ if (fcntl(fd, F_SETFL, 0) == -1) {
+ close(fd);
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+ return NULL;
+ }
+
+ if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+ return NULL;
+ }
+ /* Create and initialize the object */
+ if ((self = PyObject_New(oss_audio_t, &OSSAudioType)) == NULL) {
+ close(fd);
+ return NULL;
+ }
+ self->devicename = devicename;
+ self->fd = fd;
+ self->mode = imode;
+ self->icount = self->ocount = 0;
+ self->afmts = afmts;
+ return self;
+}
+
+static void
+oss_dealloc(oss_audio_t *self)
+{
+ /* if already closed, don't reclose it */
+ if (self->fd != -1)
+ close(self->fd);
+ PyObject_Del(self);
+}
+
+
+/* ----------------------------------------------------------------------
+ * Mixer object initialization/deallocation
+ */
+
+static oss_mixer_t *
+newossmixerobject(PyObject *arg)
+{
+ char *devicename = NULL;
+ int fd;
+ oss_mixer_t *self;
+
+ if (!PyArg_ParseTuple(arg, "|s", &devicename)) {
+ return NULL;
+ }
+
+ if (devicename == NULL) {
+ devicename = getenv("MIXERDEV");
+ if (devicename == NULL) /* MIXERDEV not set */
+ devicename = "/dev/mixer";
+ }
+
+ if ((fd = open(devicename, O_RDWR)) == -1) {
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
+ return NULL;
+ }
+
+ if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) {
+ close(fd);
+ return NULL;
+ }
+
+ self->fd = fd;
+
+ return self;
+}
+
+static void
+oss_mixer_dealloc(oss_mixer_t *self)
+{
+ /* if already closed, don't reclose it */
+ if (self->fd != -1)
+ close(self->fd);
+ PyObject_Del(self);
+}
+
+
+/* Methods to wrap the OSS ioctls. The calling convention is pretty
+ simple:
+ nonblock() -> ioctl(fd, SNDCTL_DSP_NONBLOCK)
+ fmt = setfmt(fmt) -> ioctl(fd, SNDCTL_DSP_SETFMT, &fmt)
+ etc.
+*/
+
+
+/* ----------------------------------------------------------------------
+ * Helper functions
+ */
+
+/* _do_ioctl_1() is a private helper function used for the OSS ioctls --
+ SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that that are called from C
+ like this:
+ ioctl(fd, SNDCTL_DSP_cmd, &arg)
+
+ where arg is the value to set, and on return the driver sets arg to
+ the value that was actually set. Mapping this to Python is obvious:
+ arg = dsp.xxx(arg)
+*/
+static PyObject *
+_do_ioctl_1(int fd, PyObject *args, char *fname, int cmd)
+{
+ char argfmt[33] = "i:";
+ int arg;
+
+ assert(strlen(fname) <= 30);
+ strcat(argfmt, fname);
+ if (!PyArg_ParseTuple(args, argfmt, &arg))
+ return NULL;
+
+ if (ioctl(fd, cmd, &arg) == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ return PyInt_FromLong(arg);
+}
+
+
+/* _do_ioctl_1_internal() is a wrapper for ioctls that take no inputs
+ but return an output -- ie. we need to pass a pointer to a local C
+ variable so the driver can write its output there, but from Python
+ all we see is the return value. For example,
+ SOUND_MIXER_READ_DEVMASK returns a bitmask of available mixer
+ devices, but does not use the value of the parameter passed-in in any
+ way.
+*/
+static PyObject *
+_do_ioctl_1_internal(int fd, PyObject *args, char *fname, int cmd)
+{
+ char argfmt[32] = ":";
+ int arg = 0;
+
+ assert(strlen(fname) <= 30);
+ strcat(argfmt, fname);
+ if (!PyArg_ParseTuple(args, argfmt, &arg))
+ return NULL;
+
+ if (ioctl(fd, cmd, &arg) == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ return PyInt_FromLong(arg);
+}
+
+
+
+/* _do_ioctl_0() is a private helper for the no-argument ioctls:
+ SNDCTL_DSP_{SYNC,RESET,POST}. */
+static PyObject *
+_do_ioctl_0(int fd, PyObject *args, char *fname, int cmd)
+{
+ char argfmt[32] = ":";
+ int rv;
+
+ assert(strlen(fname) <= 30);
+ strcat(argfmt, fname);
+ if (!PyArg_ParseTuple(args, argfmt))
+ return NULL;
+
+ /* According to hannu@opensound.com, all three of the ioctls that
+ use this function can block, so release the GIL. This is
+ especially important for SYNC, which can block for several
+ seconds. */
+ Py_BEGIN_ALLOW_THREADS
+ rv = ioctl(fd, cmd, 0);
+ Py_END_ALLOW_THREADS
+
+ if (rv == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* ----------------------------------------------------------------------
+ * Methods of DSP objects (OSSAudioType)
+ */
+
+static PyObject *
+oss_nonblock(oss_audio_t *self, PyObject *unused)
+{
+ /* Hmmm: it doesn't appear to be possible to return to blocking
+ mode once we're in non-blocking mode! */
+ if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+oss_setfmt(oss_audio_t *self, PyObject *args)
+{
+ return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT);
+}
+
+static PyObject *
+oss_getfmts(oss_audio_t *self, PyObject *unused)
+{
+ int mask;
+ if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ return PyInt_FromLong(mask);
+}
+
+static PyObject *
+oss_channels(oss_audio_t *self, PyObject *args)
+{
+ return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS);
+}
+
+static PyObject *
+oss_speed(oss_audio_t *self, PyObject *args)
+{
+ return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED);
+}
+
+static PyObject *
+oss_sync(oss_audio_t *self, PyObject *args)
+{
+ return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC);
+}
+
+static PyObject *
+oss_reset(oss_audio_t *self, PyObject *args)
+{
+ return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET);
+}
+
+static PyObject *
+oss_post(oss_audio_t *self, PyObject *args)
+{
+ return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST);
+}
+
+
+/* Regular file methods: read(), write(), close(), etc. as well
+ as one convenience method, writeall(). */
+
+static PyObject *
+oss_read(oss_audio_t *self, PyObject *args)
+{
+ int size, count;
+ char *cp;
+ PyObject *rv;
+
+ if (!PyArg_ParseTuple(args, "i:read", &size))
+ return NULL;
+ rv = PyString_FromStringAndSize(NULL, size);
+ if (rv == NULL)
+ return NULL;
+ cp = PyString_AS_STRING(rv);
+
+ Py_BEGIN_ALLOW_THREADS
+ count = read(self->fd, cp, size);
+ Py_END_ALLOW_THREADS
+
+ if (count < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ Py_DECREF(rv);
+ return NULL;
+ }
+ self->icount += count;
+ _PyString_Resize(&rv, count);
+ return rv;
+}
+
+static PyObject *
+oss_write(oss_audio_t *self, PyObject *args)
+{
+ char *cp;
+ int rv, size;
+
+ if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) {
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ rv = write(self->fd, cp, size);
+ Py_END_ALLOW_THREADS
+
+ if (rv == -1) {
+ return PyErr_SetFromErrno(PyExc_IOError);
+ } else {
+ self->ocount += rv;
+ }
+ return PyInt_FromLong(rv);
+}
+
+static PyObject *
+oss_writeall(oss_audio_t *self, PyObject *args)
+{
+ char *cp;
+ int rv, size;
+ fd_set write_set_fds;
+ int select_rv;
+
+ /* NB. writeall() is only useful in non-blocking mode: according to
+ Guenter Geiger <geiger@xdv.org> on the linux-audio-dev list
+ (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that
+ write() in blocking mode consumes the whole buffer. In blocking
+ mode, the behaviour of write() and writeall() from Python is
+ indistinguishable. */
+
+ if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
+ return NULL;
+
+ /* use select to wait for audio device to be available */
+ FD_ZERO(&write_set_fds);
+ FD_SET(self->fd, &write_set_fds);
+
+ while (size > 0) {
+ Py_BEGIN_ALLOW_THREADS
+ select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL);
+ Py_END_ALLOW_THREADS
+ assert(select_rv != 0); /* no timeout, can't expire */
+ if (select_rv == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+
+ Py_BEGIN_ALLOW_THREADS
+ rv = write(self->fd, cp, size);
+ Py_END_ALLOW_THREADS
+ if (rv == -1) {
+ if (errno == EAGAIN) { /* buffer is full, try again */
+ errno = 0;
+ continue;
+ } else /* it's a real error */
+ return PyErr_SetFromErrno(PyExc_IOError);
+ } else { /* wrote rv bytes */
+ self->ocount += rv;
+ size -= rv;
+ cp += rv;
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+oss_close(oss_audio_t *self, PyObject *unused)
+{
+ if (self->fd >= 0) {
+ Py_BEGIN_ALLOW_THREADS
+ close(self->fd);
+ Py_END_ALLOW_THREADS
+ self->fd = -1;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+oss_fileno(oss_audio_t *self, PyObject *unused)
+{
+ return PyInt_FromLong(self->fd);
+}
+
+
+/* Convenience methods: these generally wrap a couple of ioctls into one
+ common task. */
+
+static PyObject *
+oss_setparameters(oss_audio_t *self, PyObject *args)
+{
+ int wanted_fmt, wanted_channels, wanted_rate, strict=0;
+ int fmt, channels, rate;
+ PyObject * rv; /* return tuple (fmt, channels, rate) */
+
+ if (!PyArg_ParseTuple(args, "iii|i:setparameters",
+ &wanted_fmt, &wanted_channels, &wanted_rate,
+ &strict))
+ return NULL;
+
+ fmt = wanted_fmt;
+ if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) == -1) {
+ return PyErr_SetFromErrno(PyExc_IOError);
+ }
+ if (strict && fmt != wanted_fmt) {
+ return PyErr_Format
+ (OSSAudioError,
+ "unable to set requested format (wanted %d, got %d)",
+ wanted_fmt, fmt);
+ }
+
+ channels = wanted_channels;
+ if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
+ return PyErr_SetFromErrno(PyExc_IOError);
+ }
+ if (strict && channels != wanted_channels) {
+ return PyErr_Format
+ (OSSAudioError,
+ "unable to set requested channels (wanted %d, got %d)",
+ wanted_channels, channels);
+ }
+
+ rate = wanted_rate;
+ if (ioctl(self->fd, SNDCTL_DSP_SPEED, &rate) == -1) {
+ return PyErr_SetFromErrno(PyExc_IOError);
+ }
+ if (strict && rate != wanted_rate) {
+ return PyErr_Format
+ (OSSAudioError,
+ "unable to set requested rate (wanted %d, got %d)",
+ wanted_rate, rate);
+ }
+
+ /* Construct the return value: a (fmt, channels, rate) tuple that
+ tells what the audio hardware was actually set to. */
+ rv = PyTuple_New(3);
+ if (rv == NULL)
+ return NULL;
+ PyTuple_SET_ITEM(rv, 0, PyInt_FromLong(fmt));
+ PyTuple_SET_ITEM(rv, 1, PyInt_FromLong(channels));
+ PyTuple_SET_ITEM(rv, 2, PyInt_FromLong(rate));
+ return rv;
+}
+
+static int
+_ssize(oss_audio_t *self, int *nchannels, int *ssize)
+{
+ int fmt;
+
+ fmt = 0;
+ if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
+ return -errno;
+
+ switch (fmt) {
+ case AFMT_MU_LAW:
+ case AFMT_A_LAW:
+ case AFMT_U8:
+ case AFMT_S8:
+ *ssize = 1; /* 8 bit formats: 1 byte */
+ break;
+ case AFMT_S16_LE:
+ case AFMT_S16_BE:
+ case AFMT_U16_LE:
+ case AFMT_U16_BE:
+ *ssize = 2; /* 16 bit formats: 2 byte */
+ break;
+ case AFMT_MPEG:
+ case AFMT_IMA_ADPCM:
+ default:
+ return -EOPNOTSUPP;
+ }
+ if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
+ return -errno;
+ return 0;
+}
+
+
+/* bufsize returns the size of the hardware audio buffer in number
+ of samples */
+static PyObject *
+oss_bufsize(oss_audio_t *self, PyObject *unused)
+{
+ audio_buf_info ai;
+ int nchannels=0, ssize=0;
+
+ if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
+}
+
+/* obufcount returns the number of samples that are available in the
+ hardware for playing */
+static PyObject *
+oss_obufcount(oss_audio_t *self, PyObject *unused)
+{
+ audio_buf_info ai;
+ int nchannels=0, ssize=0;
+
+ if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) /
+ (ssize * nchannels));
+}
+
+/* obufcount returns the number of samples that can be played without
+ blocking */
+static PyObject *
+oss_obuffree(oss_audio_t *self, PyObject *unused)
+{
+ audio_buf_info ai;
+ int nchannels=0, ssize=0;
+
+ if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyInt_FromLong(ai.bytes / (ssize * nchannels));
+}
+
+static PyObject *
+oss_getptr(oss_audio_t *self, PyObject *unused)
+{
+ count_info info;
+ int req;
+
+ if (self->mode == O_RDONLY)
+ req = SNDCTL_DSP_GETIPTR;
+ else
+ req = SNDCTL_DSP_GETOPTR;
+ if (ioctl(self->fd, req, &info) == -1) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
+}
+
+
+/* ----------------------------------------------------------------------
+ * Methods of mixer objects (OSSMixerType)
+ */
+
+static PyObject *
+oss_mixer_close(oss_mixer_t *self, PyObject *unused)
+{
+ if (self->fd >= 0) {
+ close(self->fd);
+ self->fd = -1;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+oss_mixer_fileno(oss_mixer_t *self, PyObject *unused)
+{
+ return PyInt_FromLong(self->fd);
+}
+
+/* Simple mixer interface methods */
+
+static PyObject *
+oss_mixer_controls(oss_mixer_t *self, PyObject *args)
+{
+ return _do_ioctl_1_internal(self->fd, args, "controls",
+ SOUND_MIXER_READ_DEVMASK);
+}
+
+static PyObject *
+oss_mixer_stereocontrols(oss_mixer_t *self, PyObject *args)
+{
+ return _do_ioctl_1_internal(self->fd, args, "stereocontrols",
+ SOUND_MIXER_READ_STEREODEVS);
+}
+
+static PyObject *
+oss_mixer_reccontrols(oss_mixer_t *self, PyObject *args)
+{
+ return _do_ioctl_1_internal(self->fd, args, "reccontrols",
+ SOUND_MIXER_READ_RECMASK);
+}
+
+static PyObject *
+oss_mixer_get(oss_mixer_t *self, PyObject *args)
+{
+ int channel, volume;
+
+ /* Can't use _do_ioctl_1 because of encoded arg thingy. */
+ if (!PyArg_ParseTuple(args, "i:get", &channel))
+ return NULL;
+
+ if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) {
+ PyErr_SetString(OSSAudioError, "Invalid mixer channel specified.");
+ return NULL;
+ }
+
+ if (ioctl(self->fd, MIXER_READ(channel), &volume) == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+
+ return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8);
+}
+
+static PyObject *
+oss_mixer_set(oss_mixer_t *self, PyObject *args)
+{
+ int channel, volume, leftVol, rightVol;
+
+ /* Can't use _do_ioctl_1 because of encoded arg thingy. */
+ if (!PyArg_ParseTuple(args, "i(ii):set", &channel, &leftVol, &rightVol))
+ return NULL;
+
+ if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) {
+ PyErr_SetString(OSSAudioError, "Invalid mixer channel specified.");
+ return NULL;
+ }
+
+ if (leftVol < 0 || rightVol < 0 || leftVol > 100 || rightVol > 100) {
+ PyErr_SetString(OSSAudioError, "Volumes must be between 0 and 100.");
+ return NULL;
+ }
+
+ volume = (rightVol << 8) | leftVol;
+
+ if (ioctl(self->fd, MIXER_WRITE(channel), &volume) == -1)
+ return PyErr_SetFromErrno(PyExc_IOError);
+
+ return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8);
+}
+
+static PyObject *
+oss_mixer_get_recsrc(oss_mixer_t *self, PyObject *args)
+{
+ return _do_ioctl_1_internal(self->fd, args, "get_recsrc",
+ SOUND_MIXER_READ_RECSRC);
+}
+
+static PyObject *
+oss_mixer_set_recsrc(oss_mixer_t *self, PyObject *args)
+{
+ return _do_ioctl_1(self->fd, args, "set_recsrc",
+ SOUND_MIXER_WRITE_RECSRC);
+}
+
+
+/* ----------------------------------------------------------------------
+ * Method tables and other bureaucracy
+ */
+
+static PyMethodDef oss_methods[] = {
+ /* Regular file methods */
+ { "read", (PyCFunction)oss_read, METH_VARARGS },
+ { "write", (PyCFunction)oss_write, METH_VARARGS },
+ { "writeall", (PyCFunction)oss_writeall, METH_VARARGS },
+ { "close", (PyCFunction)oss_close, METH_NOARGS },
+ { "fileno", (PyCFunction)oss_fileno, METH_NOARGS },
+
+ /* Simple ioctl wrappers */
+ { "nonblock", (PyCFunction)oss_nonblock, METH_NOARGS },
+ { "setfmt", (PyCFunction)oss_setfmt, METH_VARARGS },
+ { "getfmts", (PyCFunction)oss_getfmts, METH_NOARGS },
+ { "channels", (PyCFunction)oss_channels, METH_VARARGS },
+ { "speed", (PyCFunction)oss_speed, METH_VARARGS },
+ { "sync", (PyCFunction)oss_sync, METH_VARARGS },
+ { "reset", (PyCFunction)oss_reset, METH_VARARGS },
+ { "post", (PyCFunction)oss_post, METH_VARARGS },
+
+ /* Convenience methods -- wrap a couple of ioctls together */
+ { "setparameters", (PyCFunction)oss_setparameters, METH_VARARGS },
+ { "bufsize", (PyCFunction)oss_bufsize, METH_NOARGS },
+ { "obufcount", (PyCFunction)oss_obufcount, METH_NOARGS },
+ { "obuffree", (PyCFunction)oss_obuffree, METH_NOARGS },
+ { "getptr", (PyCFunction)oss_getptr, METH_NOARGS },
+
+ /* Aliases for backwards compatibility */
+ { "flush", (PyCFunction)oss_sync, METH_VARARGS },
+
+ { NULL, NULL} /* sentinel */
+};
+
+static PyMethodDef oss_mixer_methods[] = {
+ /* Regular file method - OSS mixers are ioctl-only interface */
+ { "close", (PyCFunction)oss_mixer_close, METH_NOARGS },
+ { "fileno", (PyCFunction)oss_mixer_fileno, METH_NOARGS },
+
+ /* Simple ioctl wrappers */
+ { "controls", (PyCFunction)oss_mixer_controls, METH_VARARGS },
+ { "stereocontrols", (PyCFunction)oss_mixer_stereocontrols, METH_VARARGS},
+ { "reccontrols", (PyCFunction)oss_mixer_reccontrols, METH_VARARGS},
+ { "get", (PyCFunction)oss_mixer_get, METH_VARARGS },
+ { "set", (PyCFunction)oss_mixer_set, METH_VARARGS },
+ { "get_recsrc", (PyCFunction)oss_mixer_get_recsrc, METH_VARARGS },
+ { "set_recsrc", (PyCFunction)oss_mixer_set_recsrc, METH_VARARGS },
+
+ { NULL, NULL}
+};
+
+static PyObject *
+oss_getattr(oss_audio_t *self, char *name)
+{
+ PyObject * rval = NULL;
+ if (strcmp(name, "closed") == 0) {
+ rval = (self->fd == -1) ? Py_True : Py_False;
+ Py_INCREF(rval);
+ }
+ else if (strcmp(name, "name") == 0) {
+ rval = PyString_FromString(self->devicename);
+ }
+ else if (strcmp(name, "mode") == 0) {
+ /* No need for a "default" in this switch: from newossobject(),
+ self->mode can only be one of these three values. */
+ switch(self->mode) {
+ case O_RDONLY:
+ rval = PyString_FromString("r");
+ break;
+ case O_RDWR:
+ rval = PyString_FromString("rw");
+ break;
+ case O_WRONLY:
+ rval = PyString_FromString("w");
+ break;
+ }
+ }
+ else {
+ rval = Py_FindMethod(oss_methods, (PyObject *)self, name);
+ }
+ return rval;
+}
+
+static PyObject *
+oss_mixer_getattr(oss_mixer_t *self, char *name)
+{
+ return Py_FindMethod(oss_mixer_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject OSSAudioType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "ossaudiodev.oss_audio_device", /*tp_name*/
+ sizeof(oss_audio_t), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)oss_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)oss_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyTypeObject OSSMixerType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "ossaudiodev.oss_mixer_device", /*tp_name*/
+ sizeof(oss_mixer_t), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)oss_mixer_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)oss_mixer_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+
+static PyObject *
+ossopen(PyObject *self, PyObject *args)
+{
+ return (PyObject *)newossobject(args);
+}
+
+static PyObject *
+ossopenmixer(PyObject *self, PyObject *args)
+{
+ return (PyObject *)newossmixerobject(args);
+}
+
+static PyMethodDef ossaudiodev_methods[] = {
+ { "open", ossopen, METH_VARARGS },
+ { "openmixer", ossopenmixer, METH_VARARGS },
+ { 0, 0 },
+};
+
+
+#define _EXPORT_INT(mod, name) \
+ if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return;
+
+
+static char *control_labels[] = SOUND_DEVICE_LABELS;
+static char *control_names[] = SOUND_DEVICE_NAMES;
+
+
+static int
+build_namelists (PyObject *module)
+{
+ PyObject *labels;
+ PyObject *names;
+ PyObject *s;
+ int num_controls;
+ int i;
+
+ num_controls = sizeof(control_labels) / sizeof(control_labels[0]);
+ assert(num_controls == sizeof(control_names) / sizeof(control_names[0]));
+
+ labels = PyList_New(num_controls);
+ names = PyList_New(num_controls);
+ if (labels == NULL || names == NULL)
+ goto error2;
+ for (i = 0; i < num_controls; i++) {
+ s = PyString_FromString(control_labels[i]);
+ if (s == NULL)
+ goto error2;
+ PyList_SET_ITEM(labels, i, s);
+
+ s = PyString_FromString(control_names[i]);
+ if (s == NULL)
+ goto error2;
+ PyList_SET_ITEM(names, i, s);
+ }
+
+ if (PyModule_AddObject(module, "control_labels", labels) == -1)
+ goto error2;
+ if (PyModule_AddObject(module, "control_names", names) == -1)
+ goto error1;
+
+ return 0;
+
+error2:
+ Py_XDECREF(labels);
+error1:
+ Py_XDECREF(names);
+ return -1;
+}
+
+
+void
+initossaudiodev(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule("ossaudiodev", ossaudiodev_methods);
+ if (m == NULL)
+ return;
+
+ OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError",
+ NULL, NULL);
+ if (OSSAudioError) {
+ /* Each call to PyModule_AddObject decrefs it; compensate: */
+ Py_INCREF(OSSAudioError);
+ Py_INCREF(OSSAudioError);
+ PyModule_AddObject(m, "error", OSSAudioError);
+ PyModule_AddObject(m, "OSSAudioError", OSSAudioError);
+ }
+
+ /* Build 'control_labels' and 'control_names' lists and add them
+ to the module. */
+ if (build_namelists(m) == -1) /* XXX what to do here? */
+ return;
+
+ /* Expose the audio format numbers -- essential! */
+ _EXPORT_INT(m, AFMT_QUERY);
+ _EXPORT_INT(m, AFMT_MU_LAW);
+ _EXPORT_INT(m, AFMT_A_LAW);
+ _EXPORT_INT(m, AFMT_IMA_ADPCM);
+ _EXPORT_INT(m, AFMT_U8);
+ _EXPORT_INT(m, AFMT_S16_LE);
+ _EXPORT_INT(m, AFMT_S16_BE);
+ _EXPORT_INT(m, AFMT_S8);
+ _EXPORT_INT(m, AFMT_U16_LE);
+ _EXPORT_INT(m, AFMT_U16_BE);
+ _EXPORT_INT(m, AFMT_MPEG);
+#ifdef AFMT_AC3
+ _EXPORT_INT(m, AFMT_AC3);
+#endif
+#ifdef AFMT_S16_NE
+ _EXPORT_INT(m, AFMT_S16_NE);
+#endif
+#ifdef AFMT_U16_NE
+ _EXPORT_INT(m, AFMT_U16_NE);
+#endif
+#ifdef AFMT_S32_LE
+ _EXPORT_INT(m, AFMT_S32_LE);
+#endif
+#ifdef AFMT_S32_BE
+ _EXPORT_INT(m, AFMT_S32_BE);
+#endif
+#ifdef AFMT_MPEG
+ _EXPORT_INT(m, AFMT_MPEG);
+#endif
+
+ /* Expose the sound mixer device numbers. */
+ _EXPORT_INT(m, SOUND_MIXER_NRDEVICES);
+ _EXPORT_INT(m, SOUND_MIXER_VOLUME);
+ _EXPORT_INT(m, SOUND_MIXER_BASS);
+ _EXPORT_INT(m, SOUND_MIXER_TREBLE);
+ _EXPORT_INT(m, SOUND_MIXER_SYNTH);
+ _EXPORT_INT(m, SOUND_MIXER_PCM);
+ _EXPORT_INT(m, SOUND_MIXER_SPEAKER);
+ _EXPORT_INT(m, SOUND_MIXER_LINE);
+ _EXPORT_INT(m, SOUND_MIXER_MIC);
+ _EXPORT_INT(m, SOUND_MIXER_CD);
+ _EXPORT_INT(m, SOUND_MIXER_IMIX);
+ _EXPORT_INT(m, SOUND_MIXER_ALTPCM);
+ _EXPORT_INT(m, SOUND_MIXER_RECLEV);
+ _EXPORT_INT(m, SOUND_MIXER_IGAIN);
+ _EXPORT_INT(m, SOUND_MIXER_OGAIN);
+ _EXPORT_INT(m, SOUND_MIXER_LINE1);
+ _EXPORT_INT(m, SOUND_MIXER_LINE2);
+ _EXPORT_INT(m, SOUND_MIXER_LINE3);
+#ifdef SOUND_MIXER_DIGITAL1
+ _EXPORT_INT(m, SOUND_MIXER_DIGITAL1);
+#endif
+#ifdef SOUND_MIXER_DIGITAL2
+ _EXPORT_INT(m, SOUND_MIXER_DIGITAL2);
+#endif
+#ifdef SOUND_MIXER_DIGITAL3
+ _EXPORT_INT(m, SOUND_MIXER_DIGITAL3);
+#endif
+#ifdef SOUND_MIXER_PHONEIN
+ _EXPORT_INT(m, SOUND_MIXER_PHONEIN);
+#endif
+#ifdef SOUND_MIXER_PHONEOUT
+ _EXPORT_INT(m, SOUND_MIXER_PHONEOUT);
+#endif
+#ifdef SOUND_MIXER_VIDEO
+ _EXPORT_INT(m, SOUND_MIXER_VIDEO);
+#endif
+#ifdef SOUND_MIXER_RADIO
+ _EXPORT_INT(m, SOUND_MIXER_RADIO);
+#endif
+#ifdef SOUND_MIXER_MONITOR
+ _EXPORT_INT(m, SOUND_MIXER_MONITOR);
+#endif
+
+ /* Expose all the ioctl numbers for masochists who like to do this
+ stuff directly. */
+ _EXPORT_INT(m, SNDCTL_COPR_HALT);
+ _EXPORT_INT(m, SNDCTL_COPR_LOAD);
+ _EXPORT_INT(m, SNDCTL_COPR_RCODE);
+ _EXPORT_INT(m, SNDCTL_COPR_RCVMSG);
+ _EXPORT_INT(m, SNDCTL_COPR_RDATA);
+ _EXPORT_INT(m, SNDCTL_COPR_RESET);
+ _EXPORT_INT(m, SNDCTL_COPR_RUN);
+ _EXPORT_INT(m, SNDCTL_COPR_SENDMSG);
+ _EXPORT_INT(m, SNDCTL_COPR_WCODE);
+ _EXPORT_INT(m, SNDCTL_COPR_WDATA);
+#ifdef SNDCTL_DSP_BIND_CHANNEL
+ _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL);
+#endif
+ _EXPORT_INT(m, SNDCTL_DSP_CHANNELS);
+ _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE);
+ _EXPORT_INT(m, SNDCTL_DSP_GETCAPS);
+#ifdef SNDCTL_DSP_GETCHANNELMASK
+ _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK);
+#endif
+ _EXPORT_INT(m, SNDCTL_DSP_GETFMTS);
+ _EXPORT_INT(m, SNDCTL_DSP_GETIPTR);
+ _EXPORT_INT(m, SNDCTL_DSP_GETISPACE);
+#ifdef SNDCTL_DSP_GETODELAY
+ _EXPORT_INT(m, SNDCTL_DSP_GETODELAY);
+#endif
+ _EXPORT_INT(m, SNDCTL_DSP_GETOPTR);
+ _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE);
+#ifdef SNDCTL_DSP_GETSPDIF
+ _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF);
+#endif
+ _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER);
+ _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF);
+ _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF);
+ _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK);
+ _EXPORT_INT(m, SNDCTL_DSP_POST);
+#ifdef SNDCTL_DSP_PROFILE
+ _EXPORT_INT(m, SNDCTL_DSP_PROFILE);
+#endif
+ _EXPORT_INT(m, SNDCTL_DSP_RESET);
+ _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE);
+ _EXPORT_INT(m, SNDCTL_DSP_SETDUPLEX);
+ _EXPORT_INT(m, SNDCTL_DSP_SETFMT);
+ _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT);
+#ifdef SNDCTL_DSP_SETSPDIF
+ _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF);
+#endif
+ _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO);
+ _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER);
+ _EXPORT_INT(m, SNDCTL_DSP_SPEED);
+ _EXPORT_INT(m, SNDCTL_DSP_STEREO);
+ _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE);
+ _EXPORT_INT(m, SNDCTL_DSP_SYNC);
+ _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE);
+ _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR);
+ _EXPORT_INT(m, SNDCTL_MIDI_INFO);
+ _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD);
+ _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE);
+ _EXPORT_INT(m, SNDCTL_MIDI_PRETIME);
+ _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE);
+ _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT);
+ _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT);
+#ifdef SNDCTL_SEQ_GETTIME
+ _EXPORT_INT(m, SNDCTL_SEQ_GETTIME);
+#endif
+ _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS);
+ _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS);
+ _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND);
+ _EXPORT_INT(m, SNDCTL_SEQ_PANIC);
+ _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE);
+ _EXPORT_INT(m, SNDCTL_SEQ_RESET);
+ _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES);
+ _EXPORT_INT(m, SNDCTL_SEQ_SYNC);
+ _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI);
+ _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD);
+#ifdef SNDCTL_SYNTH_CONTROL
+ _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL);
+#endif
+#ifdef SNDCTL_SYNTH_ID
+ _EXPORT_INT(m, SNDCTL_SYNTH_ID);
+#endif
+ _EXPORT_INT(m, SNDCTL_SYNTH_INFO);
+ _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL);
+#ifdef SNDCTL_SYNTH_REMOVESAMPLE
+ _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE);
+#endif
+ _EXPORT_INT(m, SNDCTL_TMR_CONTINUE);
+ _EXPORT_INT(m, SNDCTL_TMR_METRONOME);
+ _EXPORT_INT(m, SNDCTL_TMR_SELECT);
+ _EXPORT_INT(m, SNDCTL_TMR_SOURCE);
+ _EXPORT_INT(m, SNDCTL_TMR_START);
+ _EXPORT_INT(m, SNDCTL_TMR_STOP);
+ _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
+ _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
+}
diff --git a/sys/src/cmd/python/Modules/parsermodule.c b/sys/src/cmd/python/Modules/parsermodule.c
new file mode 100644
index 000000000..e33197e39
--- /dev/null
+++ b/sys/src/cmd/python/Modules/parsermodule.c
@@ -0,0 +1,3279 @@
+/* parsermodule.c
+ *
+ * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
+ * Institute and State University, Blacksburg, Virginia, USA.
+ * Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
+ * Amsterdam, The Netherlands. Copying is permitted under the terms
+ * associated with the main Python distribution, with the additional
+ * restriction that this additional notice be included and maintained
+ * on all distributed copies.
+ *
+ * This module serves to replace the original parser module written
+ * by Guido. The functionality is not matched precisely, but the
+ * original may be implemented on top of this. This is desirable
+ * since the source of the text to be parsed is now divorced from
+ * this interface.
+ *
+ * Unlike the prior interface, the ability to give a parse tree
+ * produced by Python code as a tuple to the compiler is enabled by
+ * this module. See the documentation for more details.
+ *
+ * I've added some annotations that help with the lint code-checking
+ * program, but they're not complete by a long shot. The real errors
+ * that lint detects are gone, but there are still warnings with
+ * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations
+ * look like "NOTE(...)".
+ */
+
+#include "Python.h" /* general Python API */
+#include "graminit.h" /* symbols defined in the grammar */
+#include "node.h" /* internal parser structure */
+#include "errcode.h" /* error codes for PyNode_*() */
+#include "token.h" /* token definitions */
+ /* ISTERMINAL() / ISNONTERMINAL() */
+#include "compile.h" /* PyNode_Compile() */
+
+#ifdef lint
+#include <note.h>
+#else
+#define NOTE(x)
+#endif
+
+/* String constants used to initialize module attributes.
+ *
+ */
+static char parser_copyright_string[] =
+"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
+University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
+Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
+Centrum, Amsterdam, The Netherlands.";
+
+
+PyDoc_STRVAR(parser_doc_string,
+"This is an interface to Python's internal parser.");
+
+static char parser_version_string[] = "0.5";
+
+
+typedef PyObject* (*SeqMaker) (Py_ssize_t length);
+typedef int (*SeqInserter) (PyObject* sequence,
+ Py_ssize_t index,
+ PyObject* element);
+
+/* The function below is copyrighted by Stichting Mathematisch Centrum. The
+ * original copyright statement is included below, and continues to apply
+ * in full to the function immediately following. All other material is
+ * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
+ * Institute and State University. Changes were made to comply with the
+ * new naming conventions. Added arguments to provide support for creating
+ * lists as well as tuples, and optionally including the line numbers.
+ */
+
+
+static PyObject*
+node2tuple(node *n, /* node to convert */
+ SeqMaker mkseq, /* create sequence */
+ SeqInserter addelem, /* func. to add elem. in seq. */
+ int lineno) /* include line numbers? */
+{
+ if (n == NULL) {
+ Py_INCREF(Py_None);
+ return (Py_None);
+ }
+ if (ISNONTERMINAL(TYPE(n))) {
+ int i;
+ PyObject *v;
+ PyObject *w;
+
+ v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl));
+ if (v == NULL)
+ return (v);
+ w = PyInt_FromLong(TYPE(n));
+ if (w == NULL) {
+ Py_DECREF(v);
+ return ((PyObject*) NULL);
+ }
+ (void) addelem(v, 0, w);
+ for (i = 0; i < NCH(n); i++) {
+ w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
+ if (w == NULL) {
+ Py_DECREF(v);
+ return ((PyObject*) NULL);
+ }
+ (void) addelem(v, i+1, w);
+ }
+
+ if (TYPE(n) == encoding_decl)
+ (void) addelem(v, i+1, PyString_FromString(STR(n)));
+ return (v);
+ }
+ else if (ISTERMINAL(TYPE(n))) {
+ PyObject *result = mkseq(2 + lineno);
+ if (result != NULL) {
+ (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
+ (void) addelem(result, 1, PyString_FromString(STR(n)));
+ if (lineno == 1)
+ (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
+ }
+ return (result);
+ }
+ else {
+ PyErr_SetString(PyExc_SystemError,
+ "unrecognized parse tree node type");
+ return ((PyObject*) NULL);
+ }
+}
+/*
+ * End of material copyrighted by Stichting Mathematisch Centrum.
+ */
+
+
+
+/* There are two types of intermediate objects we're interested in:
+ * 'eval' and 'exec' types. These constants can be used in the st_type
+ * field of the object type to identify which any given object represents.
+ * These should probably go in an external header to allow other extensions
+ * to use them, but then, we really should be using C++ too. ;-)
+ */
+
+#define PyST_EXPR 1
+#define PyST_SUITE 2
+
+
+/* These are the internal objects and definitions required to implement the
+ * ST type. Most of the internal names are more reminiscent of the 'old'
+ * naming style, but the code uses the new naming convention.
+ */
+
+static PyObject*
+parser_error = 0;
+
+
+typedef struct {
+ PyObject_HEAD /* standard object header */
+ node* st_node; /* the node* returned by the parser */
+ int st_type; /* EXPR or SUITE ? */
+} PyST_Object;
+
+
+static void parser_free(PyST_Object *st);
+static int parser_compare(PyST_Object *left, PyST_Object *right);
+static PyObject *parser_getattr(PyObject *self, char *name);
+
+
+static
+PyTypeObject PyST_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "parser.st", /* tp_name */
+ (int) sizeof(PyST_Object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)parser_free, /* tp_dealloc */
+ 0, /* tp_print */
+ parser_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)parser_compare, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+
+ /* Functions to access object as input/output buffer */
+ 0, /* tp_as_buffer */
+
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+
+ /* __doc__ */
+ "Intermediate representation of a Python parse tree."
+}; /* PyST_Type */
+
+
+static int
+parser_compare_nodes(node *left, node *right)
+{
+ int j;
+
+ if (TYPE(left) < TYPE(right))
+ return (-1);
+
+ if (TYPE(right) < TYPE(left))
+ return (1);
+
+ if (ISTERMINAL(TYPE(left)))
+ return (strcmp(STR(left), STR(right)));
+
+ if (NCH(left) < NCH(right))
+ return (-1);
+
+ if (NCH(right) < NCH(left))
+ return (1);
+
+ for (j = 0; j < NCH(left); ++j) {
+ int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
+
+ if (v != 0)
+ return (v);
+ }
+ return (0);
+}
+
+
+/* int parser_compare(PyST_Object* left, PyST_Object* right)
+ *
+ * Comparison function used by the Python operators ==, !=, <, >, <=, >=
+ * This really just wraps a call to parser_compare_nodes() with some easy
+ * checks and protection code.
+ *
+ */
+static int
+parser_compare(PyST_Object *left, PyST_Object *right)
+{
+ if (left == right)
+ return (0);
+
+ if ((left == 0) || (right == 0))
+ return (-1);
+
+ return (parser_compare_nodes(left->st_node, right->st_node));
+}
+
+
+/* parser_newstobject(node* st)
+ *
+ * Allocates a new Python object representing an ST. This is simply the
+ * 'wrapper' object that holds a node* and allows it to be passed around in
+ * Python code.
+ *
+ */
+static PyObject*
+parser_newstobject(node *st, int type)
+{
+ PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type);
+
+ if (o != 0) {
+ o->st_node = st;
+ o->st_type = type;
+ }
+ else {
+ PyNode_Free(st);
+ }
+ return ((PyObject*)o);
+}
+
+
+/* void parser_free(PyST_Object* st)
+ *
+ * This is called by a del statement that reduces the reference count to 0.
+ *
+ */
+static void
+parser_free(PyST_Object *st)
+{
+ PyNode_Free(st->st_node);
+ PyObject_Del(st);
+}
+
+
+/* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw)
+ *
+ * This provides conversion from a node* to a tuple object that can be
+ * returned to the Python-level caller. The ST object is not modified.
+ *
+ */
+static PyObject*
+parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ PyObject *line_option = 0;
+ PyObject *res = 0;
+ int ok;
+
+ static char *keywords[] = {"ast", "line_info", NULL};
+
+ if (self == NULL) {
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords,
+ &PyST_Type, &self, &line_option);
+ }
+ else
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
+ &line_option);
+ if (ok != 0) {
+ int lineno = 0;
+ if (line_option != NULL) {
+ lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
+ }
+ /*
+ * Convert ST into a tuple representation. Use Guido's function,
+ * since it's known to work already.
+ */
+ res = node2tuple(((PyST_Object*)self)->st_node,
+ PyTuple_New, PyTuple_SetItem, lineno);
+ }
+ return (res);
+}
+
+
+/* parser_st2list(PyObject* self, PyObject* args, PyObject* kw)
+ *
+ * This provides conversion from a node* to a list object that can be
+ * returned to the Python-level caller. The ST object is not modified.
+ *
+ */
+static PyObject*
+parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ PyObject *line_option = 0;
+ PyObject *res = 0;
+ int ok;
+
+ static char *keywords[] = {"ast", "line_info", NULL};
+
+ if (self == NULL)
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords,
+ &PyST_Type, &self, &line_option);
+ else
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
+ &line_option);
+ if (ok) {
+ int lineno = 0;
+ if (line_option != 0) {
+ lineno = PyObject_IsTrue(line_option) ? 1 : 0;
+ }
+ /*
+ * Convert ST into a tuple representation. Use Guido's function,
+ * since it's known to work already.
+ */
+ res = node2tuple(self->st_node,
+ PyList_New, PyList_SetItem, lineno);
+ }
+ return (res);
+}
+
+
+/* parser_compilest(PyObject* self, PyObject* args)
+ *
+ * This function creates code objects from the parse tree represented by
+ * the passed-in data object. An optional file name is passed in as well.
+ *
+ */
+static PyObject*
+parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ PyObject* res = 0;
+ char* str = "<syntax-tree>";
+ int ok;
+
+ static char *keywords[] = {"ast", "filename", NULL};
+
+ if (self == NULL)
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
+ &PyST_Type, &self, &str);
+ else
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
+ &str);
+
+ if (ok)
+ res = (PyObject *)PyNode_Compile(self->st_node, str);
+
+ return (res);
+}
+
+
+/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
+ * PyObject* parser_issuite(PyObject* self, PyObject* args)
+ *
+ * Checks the passed-in ST object to determine if it is an expression or
+ * a statement suite, respectively. The return is a Python truth value.
+ *
+ */
+static PyObject*
+parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ PyObject* res = 0;
+ int ok;
+
+ static char *keywords[] = {"ast", NULL};
+
+ if (self == NULL)
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
+ &PyST_Type, &self);
+ else
+ ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
+
+ if (ok) {
+ /* Check to see if the ST represents an expression or not. */
+ res = (self->st_type == PyST_EXPR) ? Py_True : Py_False;
+ Py_INCREF(res);
+ }
+ return (res);
+}
+
+
+static PyObject*
+parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ PyObject* res = 0;
+ int ok;
+
+ static char *keywords[] = {"ast", NULL};
+
+ if (self == NULL)
+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
+ &PyST_Type, &self);
+ else
+ ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
+
+ if (ok) {
+ /* Check to see if the ST represents an expression or not. */
+ res = (self->st_type == PyST_EXPR) ? Py_False : Py_True;
+ Py_INCREF(res);
+ }
+ return (res);
+}
+
+
+#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
+
+static PyMethodDef
+parser_methods[] = {
+ {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Compile this ST object into a code object.")},
+ {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Determines if this ST object was created from an expression.")},
+ {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Determines if this ST object was created from a suite.")},
+ {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates a list-tree representation of this ST.")},
+ {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates a tuple-tree representation of this ST.")},
+
+ {NULL, NULL, 0, NULL}
+};
+
+
+static PyObject*
+parser_getattr(PyObject *self, char *name)
+{
+ return (Py_FindMethod(parser_methods, self, name));
+}
+
+
+/* err_string(char* message)
+ *
+ * Sets the error string for an exception of type ParserError.
+ *
+ */
+static void
+err_string(char *message)
+{
+ PyErr_SetString(parser_error, message);
+}
+
+
+/* PyObject* parser_do_parse(PyObject* args, int type)
+ *
+ * Internal function to actually execute the parse and return the result if
+ * successful or set an exception if not.
+ *
+ */
+static PyObject*
+parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
+{
+ char* string = 0;
+ PyObject* res = 0;
+
+ static char *keywords[] = {"source", NULL};
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
+ node* n = PyParser_SimpleParseString(string,
+ (type == PyST_EXPR)
+ ? eval_input : file_input);
+
+ if (n)
+ res = parser_newstobject(n, type);
+ }
+ return (res);
+}
+
+
+/* PyObject* parser_expr(PyObject* self, PyObject* args)
+ * PyObject* parser_suite(PyObject* self, PyObject* args)
+ *
+ * External interfaces to the parser itself. Which is called determines if
+ * the parser attempts to recognize an expression ('eval' form) or statement
+ * suite ('exec' form). The real work is done by parser_do_parse() above.
+ *
+ */
+static PyObject*
+parser_expr(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ NOTE(ARGUNUSED(self))
+ return (parser_do_parse(args, kw, "s:expr", PyST_EXPR));
+}
+
+
+static PyObject*
+parser_suite(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ NOTE(ARGUNUSED(self))
+ return (parser_do_parse(args, kw, "s:suite", PyST_SUITE));
+}
+
+
+
+/* This is the messy part of the code. Conversion from a tuple to an ST
+ * object requires that the input tuple be valid without having to rely on
+ * catching an exception from the compiler. This is done to allow the
+ * compiler itself to remain fast, since most of its input will come from
+ * the parser directly, and therefore be known to be syntactically correct.
+ * This validation is done to ensure that we don't core dump the compile
+ * phase, returning an exception instead.
+ *
+ * Two aspects can be broken out in this code: creating a node tree from
+ * the tuple passed in, and verifying that it is indeed valid. It may be
+ * advantageous to expand the number of ST types to include funcdefs and
+ * lambdadefs to take advantage of the optimizer, recognizing those STs
+ * here. They are not necessary, and not quite as useful in a raw form.
+ * For now, let's get expressions and suites working reliably.
+ */
+
+
+static node* build_node_tree(PyObject *tuple);
+static int validate_expr_tree(node *tree);
+static int validate_file_input(node *tree);
+static int validate_encoding_decl(node *tree);
+
+/* PyObject* parser_tuple2st(PyObject* self, PyObject* args)
+ *
+ * This is the public function, called from the Python code. It receives a
+ * single tuple object from the caller, and creates an ST object if the
+ * tuple can be validated. It does this by checking the first code of the
+ * tuple, and, if acceptable, builds the internal representation. If this
+ * step succeeds, the internal representation is validated as fully as
+ * possible with the various validate_*() routines defined below.
+ *
+ * This function must be changed if support is to be added for PyST_FRAGMENT
+ * ST objects.
+ *
+ */
+static PyObject*
+parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
+{
+ NOTE(ARGUNUSED(self))
+ PyObject *st = 0;
+ PyObject *tuple;
+ node *tree;
+
+ static char *keywords[] = {"sequence", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords,
+ &tuple))
+ return (0);
+ if (!PySequence_Check(tuple)) {
+ PyErr_SetString(PyExc_ValueError,
+ "sequence2st() requires a single sequence argument");
+ return (0);
+ }
+ /*
+ * Convert the tree to the internal form before checking it.
+ */
+ tree = build_node_tree(tuple);
+ if (tree != 0) {
+ int start_sym = TYPE(tree);
+ if (start_sym == eval_input) {
+ /* Might be an eval form. */
+ if (validate_expr_tree(tree))
+ st = parser_newstobject(tree, PyST_EXPR);
+ else
+ PyNode_Free(tree);
+ }
+ else if (start_sym == file_input) {
+ /* This looks like an exec form so far. */
+ if (validate_file_input(tree))
+ st = parser_newstobject(tree, PyST_SUITE);
+ else
+ PyNode_Free(tree);
+ }
+ else if (start_sym == encoding_decl) {
+ /* This looks like an encoding_decl so far. */
+ if (validate_encoding_decl(tree))
+ st = parser_newstobject(tree, PyST_SUITE);
+ else
+ PyNode_Free(tree);
+ }
+ else {
+ /* This is a fragment, at best. */
+ PyNode_Free(tree);
+ err_string("parse tree does not use a valid start symbol");
+ }
+ }
+ /* Make sure we throw an exception on all errors. We should never
+ * get this, but we'd do well to be sure something is done.
+ */
+ if (st == NULL && !PyErr_Occurred())
+ err_string("unspecified ST error occurred");
+
+ return st;
+}
+
+
+/* node* build_node_children()
+ *
+ * Iterate across the children of the current non-terminal node and build
+ * their structures. If successful, return the root of this portion of
+ * the tree, otherwise, 0. Any required exception will be specified already,
+ * and no memory will have been deallocated.
+ *
+ */
+static node*
+build_node_children(PyObject *tuple, node *root, int *line_num)
+{
+ Py_ssize_t len = PyObject_Size(tuple);
+ Py_ssize_t i;
+ int err;
+
+ for (i = 1; i < len; ++i) {
+ /* elem must always be a sequence, however simple */
+ PyObject* elem = PySequence_GetItem(tuple, i);
+ int ok = elem != NULL;
+ long type = 0;
+ char *strn = 0;
+
+ if (ok)
+ ok = PySequence_Check(elem);
+ if (ok) {
+ PyObject *temp = PySequence_GetItem(elem, 0);
+ if (temp == NULL)
+ ok = 0;
+ else {
+ ok = PyInt_Check(temp);
+ if (ok)
+ type = PyInt_AS_LONG(temp);
+ Py_DECREF(temp);
+ }
+ }
+ if (!ok) {
+ PyObject *err = Py_BuildValue("os", elem,
+ "Illegal node construct.");
+ PyErr_SetObject(parser_error, err);
+ Py_XDECREF(err);
+ Py_XDECREF(elem);
+ return (0);
+ }
+ if (ISTERMINAL(type)) {
+ Py_ssize_t len = PyObject_Size(elem);
+ PyObject *temp;
+
+ if ((len != 2) && (len != 3)) {
+ err_string("terminal nodes must have 2 or 3 entries");
+ return 0;
+ }
+ temp = PySequence_GetItem(elem, 1);
+ if (temp == NULL)
+ return 0;
+ if (!PyString_Check(temp)) {
+ PyErr_Format(parser_error,
+ "second item in terminal node must be a string,"
+ " found %s",
+ temp->ob_type->tp_name);
+ Py_DECREF(temp);
+ return 0;
+ }
+ if (len == 3) {
+ PyObject *o = PySequence_GetItem(elem, 2);
+ if (o != NULL) {
+ if (PyInt_Check(o))
+ *line_num = PyInt_AS_LONG(o);
+ else {
+ PyErr_Format(parser_error,
+ "third item in terminal node must be an"
+ " integer, found %s",
+ temp->ob_type->tp_name);
+ Py_DECREF(o);
+ Py_DECREF(temp);
+ return 0;
+ }
+ Py_DECREF(o);
+ }
+ }
+ len = PyString_GET_SIZE(temp) + 1;
+ strn = (char *)PyObject_MALLOC(len);
+ if (strn != NULL)
+ (void) memcpy(strn, PyString_AS_STRING(temp), len);
+ Py_DECREF(temp);
+ }
+ else if (!ISNONTERMINAL(type)) {
+ /*
+ * It has to be one or the other; this is an error.
+ * Throw an exception.
+ */
+ PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
+ PyErr_SetObject(parser_error, err);
+ Py_XDECREF(err);
+ Py_XDECREF(elem);
+ return (0);
+ }
+ err = PyNode_AddChild(root, type, strn, *line_num, 0);
+ if (err == E_NOMEM) {
+ PyObject_FREE(strn);
+ return (node *) PyErr_NoMemory();
+ }
+ if (err == E_OVERFLOW) {
+ PyObject_FREE(strn);
+ PyErr_SetString(PyExc_ValueError,
+ "unsupported number of child nodes");
+ return NULL;
+ }
+
+ if (ISNONTERMINAL(type)) {
+ node* new_child = CHILD(root, i - 1);
+
+ if (new_child != build_node_children(elem, new_child, line_num)) {
+ Py_XDECREF(elem);
+ return (0);
+ }
+ }
+ else if (type == NEWLINE) { /* It's true: we increment the */
+ ++(*line_num); /* line number *after* the newline! */
+ }
+ Py_XDECREF(elem);
+ }
+ return root;
+}
+
+
+static node*
+build_node_tree(PyObject *tuple)
+{
+ node* res = 0;
+ PyObject *temp = PySequence_GetItem(tuple, 0);
+ long num = -1;
+
+ if (temp != NULL)
+ num = PyInt_AsLong(temp);
+ Py_XDECREF(temp);
+ if (ISTERMINAL(num)) {
+ /*
+ * The tuple is simple, but it doesn't start with a start symbol.
+ * Throw an exception now and be done with it.
+ */
+ tuple = Py_BuildValue("os", tuple,
+ "Illegal syntax-tree; cannot start with terminal symbol.");
+ PyErr_SetObject(parser_error, tuple);
+ Py_XDECREF(tuple);
+ }
+ else if (ISNONTERMINAL(num)) {
+ /*
+ * Not efficient, but that can be handled later.
+ */
+ int line_num = 0;
+ PyObject *encoding = NULL;
+
+ if (num == encoding_decl) {
+ encoding = PySequence_GetItem(tuple, 2);
+ /* tuple isn't borrowed anymore here, need to DECREF */
+ tuple = PySequence_GetSlice(tuple, 0, 2);
+ }
+ res = PyNode_New(num);
+ if (res != NULL) {
+ if (res != build_node_children(tuple, res, &line_num)) {
+ PyNode_Free(res);
+ res = NULL;
+ }
+ if (res && encoding) {
+ Py_ssize_t len;
+ len = PyString_GET_SIZE(encoding) + 1;
+ res->n_str = (char *)PyObject_MALLOC(len);
+ if (res->n_str != NULL)
+ (void) memcpy(res->n_str, PyString_AS_STRING(encoding), len);
+ Py_DECREF(encoding);
+ Py_DECREF(tuple);
+ }
+ }
+ }
+ else {
+ /* The tuple is illegal -- if the number is neither TERMINAL nor
+ * NONTERMINAL, we can't use it. Not sure the implementation
+ * allows this condition, but the API doesn't preclude it.
+ */
+ PyObject *err = Py_BuildValue("os", tuple,
+ "Illegal component tuple.");
+ PyErr_SetObject(parser_error, err);
+ Py_XDECREF(err);
+ }
+
+ return (res);
+}
+
+
+/*
+ * Validation routines used within the validation section:
+ */
+static int validate_terminal(node *terminal, int type, char *string);
+
+#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
+#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
+#define validate_colon(ch) validate_terminal(ch, COLON, ":")
+#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
+#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
+#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
+#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
+#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
+#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
+#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
+#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
+#define validate_star(ch) validate_terminal(ch, STAR, "*")
+#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
+#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
+#define validate_dot(ch) validate_terminal(ch, DOT, ".")
+#define validate_at(ch) validate_terminal(ch, AT, "@")
+#define validate_name(ch, str) validate_terminal(ch, NAME, str)
+
+#define VALIDATER(n) static int validate_##n(node *tree)
+
+VALIDATER(node); VALIDATER(small_stmt);
+VALIDATER(class); VALIDATER(node);
+VALIDATER(parameters); VALIDATER(suite);
+VALIDATER(testlist); VALIDATER(varargslist);
+VALIDATER(fpdef); VALIDATER(fplist);
+VALIDATER(stmt); VALIDATER(simple_stmt);
+VALIDATER(expr_stmt); VALIDATER(power);
+VALIDATER(print_stmt); VALIDATER(del_stmt);
+VALIDATER(return_stmt); VALIDATER(list_iter);
+VALIDATER(raise_stmt); VALIDATER(import_stmt);
+VALIDATER(import_name); VALIDATER(import_from);
+VALIDATER(global_stmt); VALIDATER(list_if);
+VALIDATER(assert_stmt); VALIDATER(list_for);
+VALIDATER(exec_stmt); VALIDATER(compound_stmt);
+VALIDATER(while); VALIDATER(for);
+VALIDATER(try); VALIDATER(except_clause);
+VALIDATER(test); VALIDATER(and_test);
+VALIDATER(not_test); VALIDATER(comparison);
+VALIDATER(comp_op); VALIDATER(expr);
+VALIDATER(xor_expr); VALIDATER(and_expr);
+VALIDATER(shift_expr); VALIDATER(arith_expr);
+VALIDATER(term); VALIDATER(factor);
+VALIDATER(atom); VALIDATER(lambdef);
+VALIDATER(trailer); VALIDATER(subscript);
+VALIDATER(subscriptlist); VALIDATER(sliceop);
+VALIDATER(exprlist); VALIDATER(dictmaker);
+VALIDATER(arglist); VALIDATER(argument);
+VALIDATER(listmaker); VALIDATER(yield_stmt);
+VALIDATER(testlist1); VALIDATER(gen_for);
+VALIDATER(gen_iter); VALIDATER(gen_if);
+VALIDATER(testlist_gexp); VALIDATER(yield_expr);
+VALIDATER(yield_or_testlist); VALIDATER(or_test);
+VALIDATER(old_test); VALIDATER(old_lambdef);
+
+#undef VALIDATER
+
+#define is_even(n) (((n) & 1) == 0)
+#define is_odd(n) (((n) & 1) == 1)
+
+
+static int
+validate_ntype(node *n, int t)
+{
+ if (TYPE(n) != t) {
+ PyErr_Format(parser_error, "Expected node type %d, got %d.",
+ t, TYPE(n));
+ return 0;
+ }
+ return 1;
+}
+
+
+/* Verifies that the number of child nodes is exactly 'num', raising
+ * an exception if it isn't. The exception message does not indicate
+ * the exact number of nodes, allowing this to be used to raise the
+ * "right" exception when the wrong number of nodes is present in a
+ * specific variant of a statement's syntax. This is commonly used
+ * in that fashion.
+ */
+static int
+validate_numnodes(node *n, int num, const char *const name)
+{
+ if (NCH(n) != num) {
+ PyErr_Format(parser_error,
+ "Illegal number of children for %s node.", name);
+ return 0;
+ }
+ return 1;
+}
+
+
+static int
+validate_terminal(node *terminal, int type, char *string)
+{
+ int res = (validate_ntype(terminal, type)
+ && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
+
+ if (!res && !PyErr_Occurred()) {
+ PyErr_Format(parser_error,
+ "Illegal terminal: expected \"%s\"", string);
+ }
+ return (res);
+}
+
+
+/* X (',' X) [',']
+ */
+static int
+validate_repeating_list(node *tree, int ntype, int (*vfunc)(node *),
+ const char *const name)
+{
+ int nch = NCH(tree);
+ int res = (nch && validate_ntype(tree, ntype)
+ && vfunc(CHILD(tree, 0)));
+
+ if (!res && !PyErr_Occurred())
+ (void) validate_numnodes(tree, 1, name);
+ else {
+ if (is_even(nch))
+ res = validate_comma(CHILD(tree, --nch));
+ if (res && nch > 1) {
+ int pos = 1;
+ for ( ; res && pos < nch; pos += 2)
+ res = (validate_comma(CHILD(tree, pos))
+ && vfunc(CHILD(tree, pos + 1)));
+ }
+ }
+ return (res);
+}
+
+
+/* validate_class()
+ *
+ * classdef:
+ * 'class' NAME ['(' testlist ')'] ':' suite
+ */
+static int
+validate_class(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, classdef) &&
+ ((nch == 4) || (nch == 6) || (nch == 7)));
+
+ if (res) {
+ res = (validate_name(CHILD(tree, 0), "class")
+ && validate_ntype(CHILD(tree, 1), NAME)
+ && validate_colon(CHILD(tree, nch - 2))
+ && validate_suite(CHILD(tree, nch - 1)));
+ }
+ else {
+ (void) validate_numnodes(tree, 4, "class");
+ }
+
+ if (res) {
+ if (nch == 7) {
+ res = ((validate_lparen(CHILD(tree, 2)) &&
+ validate_testlist(CHILD(tree, 3)) &&
+ validate_rparen(CHILD(tree, 4))));
+ }
+ else if (nch == 6) {
+ res = (validate_lparen(CHILD(tree,2)) &&
+ validate_rparen(CHILD(tree,3)));
+ }
+ }
+ return (res);
+}
+
+
+/* if_stmt:
+ * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+ */
+static int
+validate_if(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, if_stmt)
+ && (nch >= 4)
+ && validate_name(CHILD(tree, 0), "if")
+ && validate_test(CHILD(tree, 1))
+ && validate_colon(CHILD(tree, 2))
+ && validate_suite(CHILD(tree, 3)));
+
+ if (res && ((nch % 4) == 3)) {
+ /* ... 'else' ':' suite */
+ res = (validate_name(CHILD(tree, nch - 3), "else")
+ && validate_colon(CHILD(tree, nch - 2))
+ && validate_suite(CHILD(tree, nch - 1)));
+ nch -= 3;
+ }
+ else if (!res && !PyErr_Occurred())
+ (void) validate_numnodes(tree, 4, "if");
+ if ((nch % 4) != 0)
+ /* Will catch the case for nch < 4 */
+ res = validate_numnodes(tree, 0, "if");
+ else if (res && (nch > 4)) {
+ /* ... ('elif' test ':' suite)+ ... */
+ int j = 4;
+ while ((j < nch) && res) {
+ res = (validate_name(CHILD(tree, j), "elif")
+ && validate_colon(CHILD(tree, j + 2))
+ && validate_test(CHILD(tree, j + 1))
+ && validate_suite(CHILD(tree, j + 3)));
+ j += 4;
+ }
+ }
+ return (res);
+}
+
+
+/* parameters:
+ * '(' [varargslist] ')'
+ *
+ */
+static int
+validate_parameters(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
+
+ if (res) {
+ res = (validate_lparen(CHILD(tree, 0))
+ && validate_rparen(CHILD(tree, nch - 1)));
+ if (res && (nch == 3))
+ res = validate_varargslist(CHILD(tree, 1));
+ }
+ else {
+ (void) validate_numnodes(tree, 2, "parameters");
+ }
+ return (res);
+}
+
+
+/* validate_suite()
+ *
+ * suite:
+ * simple_stmt
+ * | NEWLINE INDENT stmt+ DEDENT
+ */
+static int
+validate_suite(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
+
+ if (res && (nch == 1))
+ res = validate_simple_stmt(CHILD(tree, 0));
+ else if (res) {
+ /* NEWLINE INDENT stmt+ DEDENT */
+ res = (validate_newline(CHILD(tree, 0))
+ && validate_indent(CHILD(tree, 1))
+ && validate_stmt(CHILD(tree, 2))
+ && validate_dedent(CHILD(tree, nch - 1)));
+
+ if (res && (nch > 4)) {
+ int i = 3;
+ --nch; /* forget the DEDENT */
+ for ( ; res && (i < nch); ++i)
+ res = validate_stmt(CHILD(tree, i));
+ }
+ else if (nch < 4)
+ res = validate_numnodes(tree, 4, "suite");
+ }
+ return (res);
+}
+
+
+static int
+validate_testlist(node *tree)
+{
+ return (validate_repeating_list(tree, testlist,
+ validate_test, "testlist"));
+}
+
+
+static int
+validate_testlist1(node *tree)
+{
+ return (validate_repeating_list(tree, testlist1,
+ validate_test, "testlist1"));
+}
+
+
+static int
+validate_testlist_safe(node *tree)
+{
+ return (validate_repeating_list(tree, testlist_safe,
+ validate_old_test, "testlist_safe"));
+}
+
+
+/* '*' NAME [',' '**' NAME] | '**' NAME
+ */
+static int
+validate_varargslist_trailer(node *tree, int start)
+{
+ int nch = NCH(tree);
+ int res = 0;
+ int sym;
+
+ if (nch <= start) {
+ err_string("expected variable argument trailer for varargslist");
+ return 0;
+ }
+ sym = TYPE(CHILD(tree, start));
+ if (sym == STAR) {
+ /*
+ * ('*' NAME [',' '**' NAME]
+ */
+ if (nch-start == 2)
+ res = validate_name(CHILD(tree, start+1), NULL);
+ else if (nch-start == 5)
+ res = (validate_name(CHILD(tree, start+1), NULL)
+ && validate_comma(CHILD(tree, start+2))
+ && validate_doublestar(CHILD(tree, start+3))
+ && validate_name(CHILD(tree, start+4), NULL));
+ }
+ else if (sym == DOUBLESTAR) {
+ /*
+ * '**' NAME
+ */
+ if (nch-start == 2)
+ res = validate_name(CHILD(tree, start+1), NULL);
+ }
+ if (!res)
+ err_string("illegal variable argument trailer for varargslist");
+ return res;
+}
+
+
+/* validate_varargslist()
+ *
+ * varargslist:
+ * (fpdef ['=' test] ',')*
+ * ('*' NAME [',' '**' NAME]
+ * | '**' NAME)
+ * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+ *
+ */
+static int
+validate_varargslist(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, varargslist) && (nch != 0);
+ int sym;
+
+ if (!res)
+ return 0;
+ if (nch < 1) {
+ err_string("varargslist missing child nodes");
+ return 0;
+ }
+ sym = TYPE(CHILD(tree, 0));
+ if (sym == STAR || sym == DOUBLESTAR)
+ /* whole thing matches:
+ * '*' NAME [',' '**' NAME] | '**' NAME
+ */
+ res = validate_varargslist_trailer(tree, 0);
+ else if (sym == fpdef) {
+ int i = 0;
+
+ sym = TYPE(CHILD(tree, nch-1));
+ if (sym == NAME) {
+ /*
+ * (fpdef ['=' test] ',')+
+ * ('*' NAME [',' '**' NAME]
+ * | '**' NAME)
+ */
+ /* skip over (fpdef ['=' test] ',')+ */
+ while (res && (i+2 <= nch)) {
+ res = validate_fpdef(CHILD(tree, i));
+ ++i;
+ if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
+ res = (validate_equal(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ if (res)
+ i += 2;
+ }
+ if (res && i < nch) {
+ res = validate_comma(CHILD(tree, i));
+ ++i;
+ if (res && i < nch
+ && (TYPE(CHILD(tree, i)) == DOUBLESTAR
+ || TYPE(CHILD(tree, i)) == STAR))
+ break;
+ }
+ }
+ /* ... '*' NAME [',' '**' NAME] | '**' NAME
+ * i --^^^
+ */
+ if (res)
+ res = validate_varargslist_trailer(tree, i);
+ }
+ else {
+ /*
+ * fpdef ['=' test] (',' fpdef ['=' test])* [',']
+ */
+ /* strip trailing comma node */
+ if (sym == COMMA) {
+ res = validate_comma(CHILD(tree, nch-1));
+ if (!res)
+ return 0;
+ --nch;
+ }
+ /*
+ * fpdef ['=' test] (',' fpdef ['=' test])*
+ */
+ res = validate_fpdef(CHILD(tree, 0));
+ ++i;
+ if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
+ res = (validate_equal(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ i += 2;
+ }
+ /*
+ * ... (',' fpdef ['=' test])*
+ * i ---^^^
+ */
+ while (res && (nch - i) >= 2) {
+ res = (validate_comma(CHILD(tree, i))
+ && validate_fpdef(CHILD(tree, i+1)));
+ i += 2;
+ if (res && (nch - i) >= 2 && TYPE(CHILD(tree, i)) == EQUAL) {
+ res = (validate_equal(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ i += 2;
+ }
+ }
+ if (res && nch - i != 0) {
+ res = 0;
+ err_string("illegal formation for varargslist");
+ }
+ }
+ }
+ return res;
+}
+
+
+/* list_iter: list_for | list_if
+ */
+static int
+validate_list_iter(node *tree)
+{
+ int res = (validate_ntype(tree, list_iter)
+ && validate_numnodes(tree, 1, "list_iter"));
+ if (res && TYPE(CHILD(tree, 0)) == list_for)
+ res = validate_list_for(CHILD(tree, 0));
+ else
+ res = validate_list_if(CHILD(tree, 0));
+
+ return res;
+}
+
+/* gen_iter: gen_for | gen_if
+ */
+static int
+validate_gen_iter(node *tree)
+{
+ int res = (validate_ntype(tree, gen_iter)
+ && validate_numnodes(tree, 1, "gen_iter"));
+ if (res && TYPE(CHILD(tree, 0)) == gen_for)
+ res = validate_gen_for(CHILD(tree, 0));
+ else
+ res = validate_gen_if(CHILD(tree, 0));
+
+ return res;
+}
+
+/* list_for: 'for' exprlist 'in' testlist [list_iter]
+ */
+static int
+validate_list_for(node *tree)
+{
+ int nch = NCH(tree);
+ int res;
+
+ if (nch == 5)
+ res = validate_list_iter(CHILD(tree, 4));
+ else
+ res = validate_numnodes(tree, 4, "list_for");
+
+ if (res)
+ res = (validate_name(CHILD(tree, 0), "for")
+ && validate_exprlist(CHILD(tree, 1))
+ && validate_name(CHILD(tree, 2), "in")
+ && validate_testlist_safe(CHILD(tree, 3)));
+
+ return res;
+}
+
+/* gen_for: 'for' exprlist 'in' test [gen_iter]
+ */
+static int
+validate_gen_for(node *tree)
+{
+ int nch = NCH(tree);
+ int res;
+
+ if (nch == 5)
+ res = validate_gen_iter(CHILD(tree, 4));
+ else
+ res = validate_numnodes(tree, 4, "gen_for");
+
+ if (res)
+ res = (validate_name(CHILD(tree, 0), "for")
+ && validate_exprlist(CHILD(tree, 1))
+ && validate_name(CHILD(tree, 2), "in")
+ && validate_or_test(CHILD(tree, 3)));
+
+ return res;
+}
+
+/* list_if: 'if' old_test [list_iter]
+ */
+static int
+validate_list_if(node *tree)
+{
+ int nch = NCH(tree);
+ int res;
+
+ if (nch == 3)
+ res = validate_list_iter(CHILD(tree, 2));
+ else
+ res = validate_numnodes(tree, 2, "list_if");
+
+ if (res)
+ res = (validate_name(CHILD(tree, 0), "if")
+ && validate_old_test(CHILD(tree, 1)));
+
+ return res;
+}
+
+/* gen_if: 'if' old_test [gen_iter]
+ */
+static int
+validate_gen_if(node *tree)
+{
+ int nch = NCH(tree);
+ int res;
+
+ if (nch == 3)
+ res = validate_gen_iter(CHILD(tree, 2));
+ else
+ res = validate_numnodes(tree, 2, "gen_if");
+
+ if (res)
+ res = (validate_name(CHILD(tree, 0), "if")
+ && validate_old_test(CHILD(tree, 1)));
+
+ return res;
+}
+
+/* validate_fpdef()
+ *
+ * fpdef:
+ * NAME
+ * | '(' fplist ')'
+ */
+static int
+validate_fpdef(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, fpdef);
+
+ if (res) {
+ if (nch == 1)
+ res = validate_ntype(CHILD(tree, 0), NAME);
+ else if (nch == 3)
+ res = (validate_lparen(CHILD(tree, 0))
+ && validate_fplist(CHILD(tree, 1))
+ && validate_rparen(CHILD(tree, 2)));
+ else
+ res = validate_numnodes(tree, 1, "fpdef");
+ }
+ return (res);
+}
+
+
+static int
+validate_fplist(node *tree)
+{
+ return (validate_repeating_list(tree, fplist,
+ validate_fpdef, "fplist"));
+}
+
+
+/* simple_stmt | compound_stmt
+ *
+ */
+static int
+validate_stmt(node *tree)
+{
+ int res = (validate_ntype(tree, stmt)
+ && validate_numnodes(tree, 1, "stmt"));
+
+ if (res) {
+ tree = CHILD(tree, 0);
+
+ if (TYPE(tree) == simple_stmt)
+ res = validate_simple_stmt(tree);
+ else
+ res = validate_compound_stmt(tree);
+ }
+ return (res);
+}
+
+
+/* small_stmt (';' small_stmt)* [';'] NEWLINE
+ *
+ */
+static int
+validate_simple_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, simple_stmt)
+ && (nch >= 2)
+ && validate_small_stmt(CHILD(tree, 0))
+ && validate_newline(CHILD(tree, nch - 1)));
+
+ if (nch < 2)
+ res = validate_numnodes(tree, 2, "simple_stmt");
+ --nch; /* forget the NEWLINE */
+ if (res && is_even(nch))
+ res = validate_semi(CHILD(tree, --nch));
+ if (res && (nch > 2)) {
+ int i;
+
+ for (i = 1; res && (i < nch); i += 2)
+ res = (validate_semi(CHILD(tree, i))
+ && validate_small_stmt(CHILD(tree, i + 1)));
+ }
+ return (res);
+}
+
+
+static int
+validate_small_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_numnodes(tree, 1, "small_stmt");
+
+ if (res) {
+ int ntype = TYPE(CHILD(tree, 0));
+
+ if ( (ntype == expr_stmt)
+ || (ntype == print_stmt)
+ || (ntype == del_stmt)
+ || (ntype == pass_stmt)
+ || (ntype == flow_stmt)
+ || (ntype == import_stmt)
+ || (ntype == global_stmt)
+ || (ntype == assert_stmt)
+ || (ntype == exec_stmt))
+ res = validate_node(CHILD(tree, 0));
+ else {
+ res = 0;
+ err_string("illegal small_stmt child type");
+ }
+ }
+ else if (nch == 1) {
+ res = 0;
+ PyErr_Format(parser_error,
+ "Unrecognized child node of small_stmt: %d.",
+ TYPE(CHILD(tree, 0)));
+ }
+ return (res);
+}
+
+
+/* compound_stmt:
+ * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+ */
+static int
+validate_compound_stmt(node *tree)
+{
+ int res = (validate_ntype(tree, compound_stmt)
+ && validate_numnodes(tree, 1, "compound_stmt"));
+ int ntype;
+
+ if (!res)
+ return (0);
+
+ tree = CHILD(tree, 0);
+ ntype = TYPE(tree);
+ if ( (ntype == if_stmt)
+ || (ntype == while_stmt)
+ || (ntype == for_stmt)
+ || (ntype == try_stmt)
+ || (ntype == funcdef)
+ || (ntype == classdef))
+ res = validate_node(tree);
+ else {
+ res = 0;
+ PyErr_Format(parser_error,
+ "Illegal compound statement type: %d.", TYPE(tree));
+ }
+ return (res);
+}
+
+
+static int
+validate_yield_or_testlist(node *tree)
+{
+ if (TYPE(tree) == yield_expr)
+ return validate_yield_expr(tree);
+ else
+ return validate_testlist(tree);
+}
+
+static int
+validate_expr_stmt(node *tree)
+{
+ int j;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, expr_stmt)
+ && is_odd(nch)
+ && validate_testlist(CHILD(tree, 0)));
+
+ if (res && nch == 3
+ && TYPE(CHILD(tree, 1)) == augassign) {
+ res = validate_numnodes(CHILD(tree, 1), 1, "augassign")
+ && validate_yield_or_testlist(CHILD(tree, 2));
+
+ if (res) {
+ char *s = STR(CHILD(CHILD(tree, 1), 0));
+
+ res = (strcmp(s, "+=") == 0
+ || strcmp(s, "-=") == 0
+ || strcmp(s, "*=") == 0
+ || strcmp(s, "/=") == 0
+ || strcmp(s, "//=") == 0
+ || strcmp(s, "%=") == 0
+ || strcmp(s, "&=") == 0
+ || strcmp(s, "|=") == 0
+ || strcmp(s, "^=") == 0
+ || strcmp(s, "<<=") == 0
+ || strcmp(s, ">>=") == 0
+ || strcmp(s, "**=") == 0);
+ if (!res)
+ err_string("illegal augmmented assignment operator");
+ }
+ }
+ else {
+ for (j = 1; res && (j < nch); j += 2)
+ res = validate_equal(CHILD(tree, j))
+ && validate_yield_or_testlist(CHILD(tree, j + 1));
+ }
+ return (res);
+}
+
+
+/* print_stmt:
+ *
+ * 'print' ( [ test (',' test)* [','] ]
+ * | '>>' test [ (',' test)+ [','] ] )
+ */
+static int
+validate_print_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, print_stmt)
+ && (nch > 0)
+ && validate_name(CHILD(tree, 0), "print"));
+
+ if (res && nch > 1) {
+ int sym = TYPE(CHILD(tree, 1));
+ int i = 1;
+ int allow_trailing_comma = 1;
+
+ if (sym == test)
+ res = validate_test(CHILD(tree, i++));
+ else {
+ if (nch < 3)
+ res = validate_numnodes(tree, 3, "print_stmt");
+ else {
+ res = (validate_ntype(CHILD(tree, i), RIGHTSHIFT)
+ && validate_test(CHILD(tree, i+1)));
+ i += 2;
+ allow_trailing_comma = 0;
+ }
+ }
+ if (res) {
+ /* ... (',' test)* [','] */
+ while (res && i+2 <= nch) {
+ res = (validate_comma(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ allow_trailing_comma = 1;
+ i += 2;
+ }
+ if (res && !allow_trailing_comma)
+ res = validate_numnodes(tree, i, "print_stmt");
+ else if (res && i < nch)
+ res = validate_comma(CHILD(tree, i));
+ }
+ }
+ return (res);
+}
+
+
+static int
+validate_del_stmt(node *tree)
+{
+ return (validate_numnodes(tree, 2, "del_stmt")
+ && validate_name(CHILD(tree, 0), "del")
+ && validate_exprlist(CHILD(tree, 1)));
+}
+
+
+static int
+validate_return_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, return_stmt)
+ && ((nch == 1) || (nch == 2))
+ && validate_name(CHILD(tree, 0), "return"));
+
+ if (res && (nch == 2))
+ res = validate_testlist(CHILD(tree, 1));
+
+ return (res);
+}
+
+
+static int
+validate_raise_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, raise_stmt)
+ && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
+
+ if (res) {
+ res = validate_name(CHILD(tree, 0), "raise");
+ if (res && (nch >= 2))
+ res = validate_test(CHILD(tree, 1));
+ if (res && nch > 2) {
+ res = (validate_comma(CHILD(tree, 2))
+ && validate_test(CHILD(tree, 3)));
+ if (res && (nch > 4))
+ res = (validate_comma(CHILD(tree, 4))
+ && validate_test(CHILD(tree, 5)));
+ }
+ }
+ else
+ (void) validate_numnodes(tree, 2, "raise");
+ if (res && (nch == 4))
+ res = (validate_comma(CHILD(tree, 2))
+ && validate_test(CHILD(tree, 3)));
+
+ return (res);
+}
+
+
+/* yield_expr: 'yield' [testlist]
+ */
+static int
+validate_yield_expr(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, yield_expr)
+ && ((nch == 1) || (nch == 2))
+ && validate_name(CHILD(tree, 0), "yield"));
+
+ if (res && (nch == 2))
+ res = validate_testlist(CHILD(tree, 1));
+
+ return (res);
+}
+
+
+/* yield_stmt: yield_expr
+ */
+static int
+validate_yield_stmt(node *tree)
+{
+ return (validate_ntype(tree, yield_stmt)
+ && validate_numnodes(tree, 1, "yield_stmt")
+ && validate_yield_expr(CHILD(tree, 0)));
+}
+
+
+static int
+validate_import_as_name(node *tree)
+{
+ int nch = NCH(tree);
+ int ok = validate_ntype(tree, import_as_name);
+
+ if (ok) {
+ if (nch == 1)
+ ok = validate_name(CHILD(tree, 0), NULL);
+ else if (nch == 3)
+ ok = (validate_name(CHILD(tree, 0), NULL)
+ && validate_name(CHILD(tree, 1), "as")
+ && validate_name(CHILD(tree, 2), NULL));
+ else
+ ok = validate_numnodes(tree, 3, "import_as_name");
+ }
+ return ok;
+}
+
+
+/* dotted_name: NAME ("." NAME)*
+ */
+static int
+validate_dotted_name(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, dotted_name)
+ && is_odd(nch)
+ && validate_name(CHILD(tree, 0), NULL));
+ int i;
+
+ for (i = 1; res && (i < nch); i += 2) {
+ res = (validate_dot(CHILD(tree, i))
+ && validate_name(CHILD(tree, i+1), NULL));
+ }
+ return res;
+}
+
+
+/* dotted_as_name: dotted_name [NAME NAME]
+ */
+static int
+validate_dotted_as_name(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, dotted_as_name);
+
+ if (res) {
+ if (nch == 1)
+ res = validate_dotted_name(CHILD(tree, 0));
+ else if (nch == 3)
+ res = (validate_dotted_name(CHILD(tree, 0))
+ && validate_name(CHILD(tree, 1), "as")
+ && validate_name(CHILD(tree, 2), NULL));
+ else {
+ res = 0;
+ err_string("illegal number of children for dotted_as_name");
+ }
+ }
+ return res;
+}
+
+
+/* dotted_as_name (',' dotted_as_name)* */
+static int
+validate_dotted_as_names(node *tree)
+{
+ int nch = NCH(tree);
+ int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0));
+ int i;
+
+ for (i = 1; res && (i < nch); i += 2)
+ res = (validate_comma(CHILD(tree, i))
+ && validate_dotted_as_name(CHILD(tree, i + 1)));
+ return (res);
+}
+
+
+/* import_as_name (',' import_as_name)* [','] */
+static int
+validate_import_as_names(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_import_as_name(CHILD(tree, 0));
+ int i;
+
+ for (i = 1; res && (i + 1 < nch); i += 2)
+ res = (validate_comma(CHILD(tree, i))
+ && validate_import_as_name(CHILD(tree, i + 1)));
+ return (res);
+}
+
+
+/* 'import' dotted_as_names */
+static int
+validate_import_name(node *tree)
+{
+ return (validate_ntype(tree, import_name)
+ && validate_numnodes(tree, 2, "import_name")
+ && validate_name(CHILD(tree, 0), "import")
+ && validate_dotted_as_names(CHILD(tree, 1)));
+}
+
+/* Helper function to count the number of leading dots in
+ * 'from ...module import name'
+ */
+static int
+count_from_dots(node *tree)
+{
+ int i;
+ for (i = 0; i < NCH(tree); i++)
+ if (TYPE(CHILD(tree, i)) != DOT)
+ break;
+ return i;
+}
+
+/* 'from' ('.'* dotted_name | '.') 'import' ('*' | '(' import_as_names ')' |
+ * import_as_names
+ */
+static int
+validate_import_from(node *tree)
+{
+ int nch = NCH(tree);
+ int ndots = count_from_dots(tree);
+ int havename = (TYPE(CHILD(tree, ndots + 1)) == dotted_name);
+ int offset = ndots + havename;
+ int res = validate_ntype(tree, import_from)
+ && (nch >= 4 + ndots)
+ && validate_name(CHILD(tree, 0), "from")
+ && (!havename || validate_dotted_name(CHILD(tree, ndots + 1)))
+ && validate_name(CHILD(tree, offset + 1), "import");
+
+ if (res && TYPE(CHILD(tree, offset + 2)) == LPAR)
+ res = ((nch == offset + 5)
+ && validate_lparen(CHILD(tree, offset + 2))
+ && validate_import_as_names(CHILD(tree, offset + 3))
+ && validate_rparen(CHILD(tree, offset + 4)));
+ else if (res && TYPE(CHILD(tree, offset + 2)) != STAR)
+ res = validate_import_as_names(CHILD(tree, offset + 2));
+ return (res);
+}
+
+
+/* import_stmt: import_name | import_from */
+static int
+validate_import_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_numnodes(tree, 1, "import_stmt");
+
+ if (res) {
+ int ntype = TYPE(CHILD(tree, 0));
+
+ if (ntype == import_name || ntype == import_from)
+ res = validate_node(CHILD(tree, 0));
+ else {
+ res = 0;
+ err_string("illegal import_stmt child type");
+ }
+ }
+ else if (nch == 1) {
+ res = 0;
+ PyErr_Format(parser_error,
+ "Unrecognized child node of import_stmt: %d.",
+ TYPE(CHILD(tree, 0)));
+ }
+ return (res);
+}
+
+
+
+
+static int
+validate_global_stmt(node *tree)
+{
+ int j;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, global_stmt)
+ && is_even(nch) && (nch >= 2));
+
+ if (!res && !PyErr_Occurred())
+ err_string("illegal global statement");
+
+ if (res)
+ res = (validate_name(CHILD(tree, 0), "global")
+ && validate_ntype(CHILD(tree, 1), NAME));
+ for (j = 2; res && (j < nch); j += 2)
+ res = (validate_comma(CHILD(tree, j))
+ && validate_ntype(CHILD(tree, j + 1), NAME));
+
+ return (res);
+}
+
+
+/* exec_stmt:
+ *
+ * 'exec' expr ['in' test [',' test]]
+ */
+static int
+validate_exec_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, exec_stmt)
+ && ((nch == 2) || (nch == 4) || (nch == 6))
+ && validate_name(CHILD(tree, 0), "exec")
+ && validate_expr(CHILD(tree, 1)));
+
+ if (!res && !PyErr_Occurred())
+ err_string("illegal exec statement");
+ if (res && (nch > 2))
+ res = (validate_name(CHILD(tree, 2), "in")
+ && validate_test(CHILD(tree, 3)));
+ if (res && (nch == 6))
+ res = (validate_comma(CHILD(tree, 4))
+ && validate_test(CHILD(tree, 5)));
+
+ return (res);
+}
+
+
+/* assert_stmt:
+ *
+ * 'assert' test [',' test]
+ */
+static int
+validate_assert_stmt(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, assert_stmt)
+ && ((nch == 2) || (nch == 4))
+ && (validate_name(CHILD(tree, 0), "assert"))
+ && validate_test(CHILD(tree, 1)));
+
+ if (!res && !PyErr_Occurred())
+ err_string("illegal assert statement");
+ if (res && (nch > 2))
+ res = (validate_comma(CHILD(tree, 2))
+ && validate_test(CHILD(tree, 3)));
+
+ return (res);
+}
+
+
+static int
+validate_while(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, while_stmt)
+ && ((nch == 4) || (nch == 7))
+ && validate_name(CHILD(tree, 0), "while")
+ && validate_test(CHILD(tree, 1))
+ && validate_colon(CHILD(tree, 2))
+ && validate_suite(CHILD(tree, 3)));
+
+ if (res && (nch == 7))
+ res = (validate_name(CHILD(tree, 4), "else")
+ && validate_colon(CHILD(tree, 5))
+ && validate_suite(CHILD(tree, 6)));
+
+ return (res);
+}
+
+
+static int
+validate_for(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, for_stmt)
+ && ((nch == 6) || (nch == 9))
+ && validate_name(CHILD(tree, 0), "for")
+ && validate_exprlist(CHILD(tree, 1))
+ && validate_name(CHILD(tree, 2), "in")
+ && validate_testlist(CHILD(tree, 3))
+ && validate_colon(CHILD(tree, 4))
+ && validate_suite(CHILD(tree, 5)));
+
+ if (res && (nch == 9))
+ res = (validate_name(CHILD(tree, 6), "else")
+ && validate_colon(CHILD(tree, 7))
+ && validate_suite(CHILD(tree, 8)));
+
+ return (res);
+}
+
+
+/* try_stmt:
+ * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+ * | 'try' ':' suite 'finally' ':' suite
+ *
+ */
+static int
+validate_try(node *tree)
+{
+ int nch = NCH(tree);
+ int pos = 3;
+ int res = (validate_ntype(tree, try_stmt)
+ && (nch >= 6) && ((nch % 3) == 0));
+
+ if (res)
+ res = (validate_name(CHILD(tree, 0), "try")
+ && validate_colon(CHILD(tree, 1))
+ && validate_suite(CHILD(tree, 2))
+ && validate_colon(CHILD(tree, nch - 2))
+ && validate_suite(CHILD(tree, nch - 1)));
+ else if (!PyErr_Occurred()) {
+ const char* name = "except";
+ if (TYPE(CHILD(tree, nch - 3)) != except_clause)
+ name = STR(CHILD(tree, nch - 3));
+
+ PyErr_Format(parser_error,
+ "Illegal number of children for try/%s node.", name);
+ }
+ /* Skip past except_clause sections: */
+ while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
+ res = (validate_except_clause(CHILD(tree, pos))
+ && validate_colon(CHILD(tree, pos + 1))
+ && validate_suite(CHILD(tree, pos + 2)));
+ pos += 3;
+ }
+ if (res && (pos < nch)) {
+ res = validate_ntype(CHILD(tree, pos), NAME);
+ if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
+ res = (validate_numnodes(tree, 6, "try/finally")
+ && validate_colon(CHILD(tree, 4))
+ && validate_suite(CHILD(tree, 5)));
+ else if (res) {
+ if (nch == (pos + 3)) {
+ res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
+ || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
+ if (!res)
+ err_string("illegal trailing triple in try statement");
+ }
+ else if (nch == (pos + 6)) {
+ res = (validate_name(CHILD(tree, pos), "except")
+ && validate_colon(CHILD(tree, pos + 1))
+ && validate_suite(CHILD(tree, pos + 2))
+ && validate_name(CHILD(tree, pos + 3), "else"));
+ }
+ else
+ res = validate_numnodes(tree, pos + 3, "try/except");
+ }
+ }
+ return (res);
+}
+
+
+static int
+validate_except_clause(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, except_clause)
+ && ((nch == 1) || (nch == 2) || (nch == 4))
+ && validate_name(CHILD(tree, 0), "except"));
+
+ if (res && (nch > 1))
+ res = validate_test(CHILD(tree, 1));
+ if (res && (nch == 4))
+ res = (validate_comma(CHILD(tree, 2))
+ && validate_test(CHILD(tree, 3)));
+
+ return (res);
+}
+
+
+static int
+validate_test(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, test) && is_odd(nch);
+
+ if (res && (TYPE(CHILD(tree, 0)) == lambdef))
+ res = ((nch == 1)
+ && validate_lambdef(CHILD(tree, 0)));
+ else if (res) {
+ res = validate_or_test(CHILD(tree, 0));
+ res = (res && (nch == 1 || (nch == 5 &&
+ validate_name(CHILD(tree, 1), "if") &&
+ validate_or_test(CHILD(tree, 2)) &&
+ validate_name(CHILD(tree, 3), "else") &&
+ validate_test(CHILD(tree, 4)))));
+ }
+ return (res);
+}
+
+static int
+validate_old_test(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, old_test) && (nch == 1);
+
+ if (res && (TYPE(CHILD(tree, 0)) == old_lambdef))
+ res = (validate_old_lambdef(CHILD(tree, 0)));
+ else if (res) {
+ res = (validate_or_test(CHILD(tree, 0)));
+ }
+ return (res);
+}
+
+static int
+validate_or_test(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, or_test) && is_odd(nch);
+
+ if (res) {
+ int pos;
+ res = validate_and_test(CHILD(tree, 0));
+ for (pos = 1; res && (pos < nch); pos += 2)
+ res = (validate_name(CHILD(tree, pos), "or")
+ && validate_and_test(CHILD(tree, pos + 1)));
+ }
+ return (res);
+}
+
+
+static int
+validate_and_test(node *tree)
+{
+ int pos;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, and_test)
+ && is_odd(nch)
+ && validate_not_test(CHILD(tree, 0)));
+
+ for (pos = 1; res && (pos < nch); pos += 2)
+ res = (validate_name(CHILD(tree, pos), "and")
+ && validate_not_test(CHILD(tree, 0)));
+
+ return (res);
+}
+
+
+static int
+validate_not_test(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
+
+ if (res) {
+ if (nch == 2)
+ res = (validate_name(CHILD(tree, 0), "not")
+ && validate_not_test(CHILD(tree, 1)));
+ else if (nch == 1)
+ res = validate_comparison(CHILD(tree, 0));
+ }
+ return (res);
+}
+
+
+static int
+validate_comparison(node *tree)
+{
+ int pos;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, comparison)
+ && is_odd(nch)
+ && validate_expr(CHILD(tree, 0)));
+
+ for (pos = 1; res && (pos < nch); pos += 2)
+ res = (validate_comp_op(CHILD(tree, pos))
+ && validate_expr(CHILD(tree, pos + 1)));
+
+ return (res);
+}
+
+
+static int
+validate_comp_op(node *tree)
+{
+ int res = 0;
+ int nch = NCH(tree);
+
+ if (!validate_ntype(tree, comp_op))
+ return (0);
+ if (nch == 1) {
+ /*
+ * Only child will be a terminal with a well-defined symbolic name
+ * or a NAME with a string of either 'is' or 'in'
+ */
+ tree = CHILD(tree, 0);
+ switch (TYPE(tree)) {
+ case LESS:
+ case GREATER:
+ case EQEQUAL:
+ case EQUAL:
+ case LESSEQUAL:
+ case GREATEREQUAL:
+ case NOTEQUAL:
+ res = 1;
+ break;
+ case NAME:
+ res = ((strcmp(STR(tree), "in") == 0)
+ || (strcmp(STR(tree), "is") == 0));
+ if (!res) {
+ PyErr_Format(parser_error,
+ "illegal operator '%s'", STR(tree));
+ }
+ break;
+ default:
+ err_string("illegal comparison operator type");
+ break;
+ }
+ }
+ else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
+ res = (validate_ntype(CHILD(tree, 0), NAME)
+ && validate_ntype(CHILD(tree, 1), NAME)
+ && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
+ && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
+ || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
+ && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
+ if (!res && !PyErr_Occurred())
+ err_string("unknown comparison operator");
+ }
+ return (res);
+}
+
+
+static int
+validate_expr(node *tree)
+{
+ int j;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, expr)
+ && is_odd(nch)
+ && validate_xor_expr(CHILD(tree, 0)));
+
+ for (j = 2; res && (j < nch); j += 2)
+ res = (validate_xor_expr(CHILD(tree, j))
+ && validate_vbar(CHILD(tree, j - 1)));
+
+ return (res);
+}
+
+
+static int
+validate_xor_expr(node *tree)
+{
+ int j;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, xor_expr)
+ && is_odd(nch)
+ && validate_and_expr(CHILD(tree, 0)));
+
+ for (j = 2; res && (j < nch); j += 2)
+ res = (validate_circumflex(CHILD(tree, j - 1))
+ && validate_and_expr(CHILD(tree, j)));
+
+ return (res);
+}
+
+
+static int
+validate_and_expr(node *tree)
+{
+ int pos;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, and_expr)
+ && is_odd(nch)
+ && validate_shift_expr(CHILD(tree, 0)));
+
+ for (pos = 1; res && (pos < nch); pos += 2)
+ res = (validate_ampersand(CHILD(tree, pos))
+ && validate_shift_expr(CHILD(tree, pos + 1)));
+
+ return (res);
+}
+
+
+static int
+validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
+ {
+ int pos = 1;
+ int nch = NCH(tree);
+ int res = (is_odd(nch)
+ && (*termvalid)(CHILD(tree, 0)));
+
+ for ( ; res && (pos < nch); pos += 2) {
+ if (TYPE(CHILD(tree, pos)) != op1)
+ res = validate_ntype(CHILD(tree, pos), op2);
+ if (res)
+ res = (*termvalid)(CHILD(tree, pos + 1));
+ }
+ return (res);
+}
+
+
+static int
+validate_shift_expr(node *tree)
+{
+ return (validate_ntype(tree, shift_expr)
+ && validate_chain_two_ops(tree, validate_arith_expr,
+ LEFTSHIFT, RIGHTSHIFT));
+}
+
+
+static int
+validate_arith_expr(node *tree)
+{
+ return (validate_ntype(tree, arith_expr)
+ && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
+}
+
+
+static int
+validate_term(node *tree)
+{
+ int pos = 1;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, term)
+ && is_odd(nch)
+ && validate_factor(CHILD(tree, 0)));
+
+ for ( ; res && (pos < nch); pos += 2)
+ res = (((TYPE(CHILD(tree, pos)) == STAR)
+ || (TYPE(CHILD(tree, pos)) == SLASH)
+ || (TYPE(CHILD(tree, pos)) == DOUBLESLASH)
+ || (TYPE(CHILD(tree, pos)) == PERCENT))
+ && validate_factor(CHILD(tree, pos + 1)));
+
+ return (res);
+}
+
+
+/* factor:
+ *
+ * factor: ('+'|'-'|'~') factor | power
+ */
+static int
+validate_factor(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, factor)
+ && (((nch == 2)
+ && ((TYPE(CHILD(tree, 0)) == PLUS)
+ || (TYPE(CHILD(tree, 0)) == MINUS)
+ || (TYPE(CHILD(tree, 0)) == TILDE))
+ && validate_factor(CHILD(tree, 1)))
+ || ((nch == 1)
+ && validate_power(CHILD(tree, 0)))));
+ return (res);
+}
+
+
+/* power:
+ *
+ * power: atom trailer* ('**' factor)*
+ */
+static int
+validate_power(node *tree)
+{
+ int pos = 1;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, power) && (nch >= 1)
+ && validate_atom(CHILD(tree, 0)));
+
+ while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
+ res = validate_trailer(CHILD(tree, pos++));
+ if (res && (pos < nch)) {
+ if (!is_even(nch - pos)) {
+ err_string("illegal number of nodes for 'power'");
+ return (0);
+ }
+ for ( ; res && (pos < (nch - 1)); pos += 2)
+ res = (validate_doublestar(CHILD(tree, pos))
+ && validate_factor(CHILD(tree, pos + 1)));
+ }
+ return (res);
+}
+
+
+static int
+validate_atom(node *tree)
+{
+ int pos;
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, atom);
+
+ if (res && nch < 1)
+ res = validate_numnodes(tree, nch+1, "atom");
+ if (res) {
+ switch (TYPE(CHILD(tree, 0))) {
+ case LPAR:
+ res = ((nch <= 3)
+ && (validate_rparen(CHILD(tree, nch - 1))));
+
+ if (res && (nch == 3)) {
+ if (TYPE(CHILD(tree, 1))==yield_expr)
+ res = validate_yield_expr(CHILD(tree, 1));
+ else
+ res = validate_testlist_gexp(CHILD(tree, 1));
+ }
+ break;
+ case LSQB:
+ if (nch == 2)
+ res = validate_ntype(CHILD(tree, 1), RSQB);
+ else if (nch == 3)
+ res = (validate_listmaker(CHILD(tree, 1))
+ && validate_ntype(CHILD(tree, 2), RSQB));
+ else {
+ res = 0;
+ err_string("illegal list display atom");
+ }
+ break;
+ case LBRACE:
+ res = ((nch <= 3)
+ && validate_ntype(CHILD(tree, nch - 1), RBRACE));
+
+ if (res && (nch == 3))
+ res = validate_dictmaker(CHILD(tree, 1));
+ break;
+ case BACKQUOTE:
+ res = ((nch == 3)
+ && validate_testlist1(CHILD(tree, 1))
+ && validate_ntype(CHILD(tree, 2), BACKQUOTE));
+ break;
+ case NAME:
+ case NUMBER:
+ res = (nch == 1);
+ break;
+ case STRING:
+ for (pos = 1; res && (pos < nch); ++pos)
+ res = validate_ntype(CHILD(tree, pos), STRING);
+ break;
+ default:
+ res = 0;
+ break;
+ }
+ }
+ return (res);
+}
+
+
+/* listmaker:
+ * test ( list_for | (',' test)* [','] )
+ */
+static int
+validate_listmaker(node *tree)
+{
+ int nch = NCH(tree);
+ int ok = nch;
+
+ if (nch == 0)
+ err_string("missing child nodes of listmaker");
+ else
+ ok = validate_test(CHILD(tree, 0));
+
+ /*
+ * list_for | (',' test)* [',']
+ */
+ if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for)
+ ok = validate_list_for(CHILD(tree, 1));
+ else {
+ /* (',' test)* [','] */
+ int i = 1;
+ while (ok && nch - i >= 2) {
+ ok = (validate_comma(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ i += 2;
+ }
+ if (ok && i == nch-1)
+ ok = validate_comma(CHILD(tree, i));
+ else if (i != nch) {
+ ok = 0;
+ err_string("illegal trailing nodes for listmaker");
+ }
+ }
+ return ok;
+}
+
+/* testlist_gexp:
+ * test ( gen_for | (',' test)* [','] )
+ */
+static int
+validate_testlist_gexp(node *tree)
+{
+ int nch = NCH(tree);
+ int ok = nch;
+
+ if (nch == 0)
+ err_string("missing child nodes of testlist_gexp");
+ else {
+ ok = validate_test(CHILD(tree, 0));
+ }
+
+ /*
+ * gen_for | (',' test)* [',']
+ */
+ if (nch == 2 && TYPE(CHILD(tree, 1)) == gen_for)
+ ok = validate_gen_for(CHILD(tree, 1));
+ else {
+ /* (',' test)* [','] */
+ int i = 1;
+ while (ok && nch - i >= 2) {
+ ok = (validate_comma(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ i += 2;
+ }
+ if (ok && i == nch-1)
+ ok = validate_comma(CHILD(tree, i));
+ else if (i != nch) {
+ ok = 0;
+ err_string("illegal trailing nodes for testlist_gexp");
+ }
+ }
+ return ok;
+}
+
+/* decorator:
+ * '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+ */
+static int
+validate_decorator(node *tree)
+{
+ int ok;
+ int nch = NCH(tree);
+ ok = (validate_ntype(tree, decorator) &&
+ (nch == 3 || nch == 5 || nch == 6) &&
+ validate_at(CHILD(tree, 0)) &&
+ validate_dotted_name(CHILD(tree, 1)) &&
+ validate_newline(RCHILD(tree, -1)));
+
+ if (ok && nch != 3) {
+ ok = (validate_lparen(CHILD(tree, 2)) &&
+ validate_rparen(RCHILD(tree, -2)));
+
+ if (ok && nch == 6)
+ ok = validate_arglist(CHILD(tree, 3));
+ }
+
+ return ok;
+}
+
+/* decorators:
+ * decorator+
+ */
+static int
+validate_decorators(node *tree)
+{
+ int i, nch, ok;
+ nch = NCH(tree);
+ ok = validate_ntype(tree, decorators) && nch >= 1;
+
+ for (i = 0; ok && i < nch; ++i)
+ ok = validate_decorator(CHILD(tree, i));
+
+ return ok;
+}
+
+/* funcdef:
+ *
+ * -6 -5 -4 -3 -2 -1
+ * [decorators] 'def' NAME parameters ':' suite
+ */
+static int
+validate_funcdef(node *tree)
+{
+ int nch = NCH(tree);
+ int ok = (validate_ntype(tree, funcdef)
+ && ((nch == 5) || (nch == 6))
+ && validate_name(RCHILD(tree, -5), "def")
+ && validate_ntype(RCHILD(tree, -4), NAME)
+ && validate_colon(RCHILD(tree, -2))
+ && validate_parameters(RCHILD(tree, -3))
+ && validate_suite(RCHILD(tree, -1)));
+
+ if (ok && (nch == 6))
+ ok = validate_decorators(CHILD(tree, 0));
+
+ return ok;
+}
+
+
+static int
+validate_lambdef(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, lambdef)
+ && ((nch == 3) || (nch == 4))
+ && validate_name(CHILD(tree, 0), "lambda")
+ && validate_colon(CHILD(tree, nch - 2))
+ && validate_test(CHILD(tree, nch - 1)));
+
+ if (res && (nch == 4))
+ res = validate_varargslist(CHILD(tree, 1));
+ else if (!res && !PyErr_Occurred())
+ (void) validate_numnodes(tree, 3, "lambdef");
+
+ return (res);
+}
+
+
+static int
+validate_old_lambdef(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, old_lambdef)
+ && ((nch == 3) || (nch == 4))
+ && validate_name(CHILD(tree, 0), "lambda")
+ && validate_colon(CHILD(tree, nch - 2))
+ && validate_test(CHILD(tree, nch - 1)));
+
+ if (res && (nch == 4))
+ res = validate_varargslist(CHILD(tree, 1));
+ else if (!res && !PyErr_Occurred())
+ (void) validate_numnodes(tree, 3, "old_lambdef");
+
+ return (res);
+}
+
+
+/* arglist:
+ *
+ * (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test)
+ */
+static int
+validate_arglist(node *tree)
+{
+ int nch = NCH(tree);
+ int i = 0;
+ int ok = 1;
+
+ if (nch <= 0)
+ /* raise the right error from having an invalid number of children */
+ return validate_numnodes(tree, nch + 1, "arglist");
+
+ if (nch > 1) {
+ for (i=0; i<nch; i++) {
+ if (TYPE(CHILD(tree, i)) == argument) {
+ node *ch = CHILD(tree, i);
+ if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == gen_for) {
+ err_string("need '(', ')' for generator expression");
+ return 0;
+ }
+ }
+ }
+ }
+
+ while (ok && nch-i >= 2) {
+ /* skip leading (argument ',') */
+ ok = (validate_argument(CHILD(tree, i))
+ && validate_comma(CHILD(tree, i+1)));
+ if (ok)
+ i += 2;
+ else
+ PyErr_Clear();
+ }
+ ok = 1;
+ if (nch-i > 0) {
+ /*
+ * argument | '*' test [',' '**' test] | '**' test
+ */
+ int sym = TYPE(CHILD(tree, i));
+
+ if (sym == argument) {
+ ok = validate_argument(CHILD(tree, i));
+ if (ok && i+1 != nch) {
+ err_string("illegal arglist specification"
+ " (extra stuff on end)");
+ ok = 0;
+ }
+ }
+ else if (sym == STAR) {
+ ok = validate_star(CHILD(tree, i));
+ if (ok && (nch-i == 2))
+ ok = validate_test(CHILD(tree, i+1));
+ else if (ok && (nch-i == 5))
+ ok = (validate_test(CHILD(tree, i+1))
+ && validate_comma(CHILD(tree, i+2))
+ && validate_doublestar(CHILD(tree, i+3))
+ && validate_test(CHILD(tree, i+4)));
+ else {
+ err_string("illegal use of '*' in arglist");
+ ok = 0;
+ }
+ }
+ else if (sym == DOUBLESTAR) {
+ if (nch-i == 2)
+ ok = (validate_doublestar(CHILD(tree, i))
+ && validate_test(CHILD(tree, i+1)));
+ else {
+ err_string("illegal use of '**' in arglist");
+ ok = 0;
+ }
+ }
+ else {
+ err_string("illegal arglist specification");
+ ok = 0;
+ }
+ }
+ return (ok);
+}
+
+
+
+/* argument:
+ *
+ * [test '='] test [gen_for]
+ */
+static int
+validate_argument(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, argument)
+ && ((nch == 1) || (nch == 2) || (nch == 3))
+ && validate_test(CHILD(tree, 0)));
+
+ if (res && (nch == 2))
+ res = validate_gen_for(CHILD(tree, 1));
+ else if (res && (nch == 3))
+ res = (validate_equal(CHILD(tree, 1))
+ && validate_test(CHILD(tree, 2)));
+
+ return (res);
+}
+
+
+
+/* trailer:
+ *
+ * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+ */
+static int
+validate_trailer(node *tree)
+{
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
+
+ if (res) {
+ switch (TYPE(CHILD(tree, 0))) {
+ case LPAR:
+ res = validate_rparen(CHILD(tree, nch - 1));
+ if (res && (nch == 3))
+ res = validate_arglist(CHILD(tree, 1));
+ break;
+ case LSQB:
+ res = (validate_numnodes(tree, 3, "trailer")
+ && validate_subscriptlist(CHILD(tree, 1))
+ && validate_ntype(CHILD(tree, 2), RSQB));
+ break;
+ case DOT:
+ res = (validate_numnodes(tree, 2, "trailer")
+ && validate_ntype(CHILD(tree, 1), NAME));
+ break;
+ default:
+ res = 0;
+ break;
+ }
+ }
+ else {
+ (void) validate_numnodes(tree, 2, "trailer");
+ }
+ return (res);
+}
+
+
+/* subscriptlist:
+ *
+ * subscript (',' subscript)* [',']
+ */
+static int
+validate_subscriptlist(node *tree)
+{
+ return (validate_repeating_list(tree, subscriptlist,
+ validate_subscript, "subscriptlist"));
+}
+
+
+/* subscript:
+ *
+ * '.' '.' '.' | test | [test] ':' [test] [sliceop]
+ */
+static int
+validate_subscript(node *tree)
+{
+ int offset = 0;
+ int nch = NCH(tree);
+ int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
+
+ if (!res) {
+ if (!PyErr_Occurred())
+ err_string("invalid number of arguments for subscript node");
+ return (0);
+ }
+ if (TYPE(CHILD(tree, 0)) == DOT)
+ /* take care of ('.' '.' '.') possibility */
+ return (validate_numnodes(tree, 3, "subscript")
+ && validate_dot(CHILD(tree, 0))
+ && validate_dot(CHILD(tree, 1))
+ && validate_dot(CHILD(tree, 2)));
+ if (nch == 1) {
+ if (TYPE(CHILD(tree, 0)) == test)
+ res = validate_test(CHILD(tree, 0));
+ else
+ res = validate_colon(CHILD(tree, 0));
+ return (res);
+ }
+ /* Must be [test] ':' [test] [sliceop],
+ * but at least one of the optional components will
+ * be present, but we don't know which yet.
+ */
+ if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
+ res = validate_test(CHILD(tree, 0));
+ offset = 1;
+ }
+ if (res)
+ res = validate_colon(CHILD(tree, offset));
+ if (res) {
+ int rem = nch - ++offset;
+ if (rem) {
+ if (TYPE(CHILD(tree, offset)) == test) {
+ res = validate_test(CHILD(tree, offset));
+ ++offset;
+ --rem;
+ }
+ if (res && rem)
+ res = validate_sliceop(CHILD(tree, offset));
+ }
+ }
+ return (res);
+}
+
+
+static int
+validate_sliceop(node *tree)
+{
+ int nch = NCH(tree);
+ int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
+ && validate_ntype(tree, sliceop);
+ if (!res && !PyErr_Occurred()) {
+ res = validate_numnodes(tree, 1, "sliceop");
+ }
+ if (res)
+ res = validate_colon(CHILD(tree, 0));
+ if (res && (nch == 2))
+ res = validate_test(CHILD(tree, 1));
+
+ return (res);
+}
+
+
+static int
+validate_exprlist(node *tree)
+{
+ return (validate_repeating_list(tree, exprlist,
+ validate_expr, "exprlist"));
+}
+
+
+static int
+validate_dictmaker(node *tree)
+{
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, dictmaker)
+ && (nch >= 3)
+ && validate_test(CHILD(tree, 0))
+ && validate_colon(CHILD(tree, 1))
+ && validate_test(CHILD(tree, 2)));
+
+ if (res && ((nch % 4) == 0))
+ res = validate_comma(CHILD(tree, --nch));
+ else if (res)
+ res = ((nch % 4) == 3);
+
+ if (res && (nch > 3)) {
+ int pos = 3;
+ /* ( ',' test ':' test )* */
+ while (res && (pos < nch)) {
+ res = (validate_comma(CHILD(tree, pos))
+ && validate_test(CHILD(tree, pos + 1))
+ && validate_colon(CHILD(tree, pos + 2))
+ && validate_test(CHILD(tree, pos + 3)));
+ pos += 4;
+ }
+ }
+ return (res);
+}
+
+
+static int
+validate_eval_input(node *tree)
+{
+ int pos;
+ int nch = NCH(tree);
+ int res = (validate_ntype(tree, eval_input)
+ && (nch >= 2)
+ && validate_testlist(CHILD(tree, 0))
+ && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
+
+ for (pos = 1; res && (pos < (nch - 1)); ++pos)
+ res = validate_ntype(CHILD(tree, pos), NEWLINE);
+
+ return (res);
+}
+
+
+static int
+validate_node(node *tree)
+{
+ int nch = 0; /* num. children on current node */
+ int res = 1; /* result value */
+ node* next = 0; /* node to process after this one */
+
+ while (res && (tree != 0)) {
+ nch = NCH(tree);
+ next = 0;
+ switch (TYPE(tree)) {
+ /*
+ * Definition nodes.
+ */
+ case funcdef:
+ res = validate_funcdef(tree);
+ break;
+ case classdef:
+ res = validate_class(tree);
+ break;
+ /*
+ * "Trivial" parse tree nodes.
+ * (Why did I call these trivial?)
+ */
+ case stmt:
+ res = validate_stmt(tree);
+ break;
+ case small_stmt:
+ /*
+ * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
+ * | import_stmt | global_stmt | exec_stmt | assert_stmt
+ */
+ res = validate_small_stmt(tree);
+ break;
+ case flow_stmt:
+ res = (validate_numnodes(tree, 1, "flow_stmt")
+ && ((TYPE(CHILD(tree, 0)) == break_stmt)
+ || (TYPE(CHILD(tree, 0)) == continue_stmt)
+ || (TYPE(CHILD(tree, 0)) == yield_stmt)
+ || (TYPE(CHILD(tree, 0)) == return_stmt)
+ || (TYPE(CHILD(tree, 0)) == raise_stmt)));
+ if (res)
+ next = CHILD(tree, 0);
+ else if (nch == 1)
+ err_string("illegal flow_stmt type");
+ break;
+ case yield_stmt:
+ res = validate_yield_stmt(tree);
+ break;
+ /*
+ * Compound statements.
+ */
+ case simple_stmt:
+ res = validate_simple_stmt(tree);
+ break;
+ case compound_stmt:
+ res = validate_compound_stmt(tree);
+ break;
+ /*
+ * Fundamental statements.
+ */
+ case expr_stmt:
+ res = validate_expr_stmt(tree);
+ break;
+ case print_stmt:
+ res = validate_print_stmt(tree);
+ break;
+ case del_stmt:
+ res = validate_del_stmt(tree);
+ break;
+ case pass_stmt:
+ res = (validate_numnodes(tree, 1, "pass")
+ && validate_name(CHILD(tree, 0), "pass"));
+ break;
+ case break_stmt:
+ res = (validate_numnodes(tree, 1, "break")
+ && validate_name(CHILD(tree, 0), "break"));
+ break;
+ case continue_stmt:
+ res = (validate_numnodes(tree, 1, "continue")
+ && validate_name(CHILD(tree, 0), "continue"));
+ break;
+ case return_stmt:
+ res = validate_return_stmt(tree);
+ break;
+ case raise_stmt:
+ res = validate_raise_stmt(tree);
+ break;
+ case import_stmt:
+ res = validate_import_stmt(tree);
+ break;
+ case import_name:
+ res = validate_import_name(tree);
+ break;
+ case import_from:
+ res = validate_import_from(tree);
+ break;
+ case global_stmt:
+ res = validate_global_stmt(tree);
+ break;
+ case exec_stmt:
+ res = validate_exec_stmt(tree);
+ break;
+ case assert_stmt:
+ res = validate_assert_stmt(tree);
+ break;
+ case if_stmt:
+ res = validate_if(tree);
+ break;
+ case while_stmt:
+ res = validate_while(tree);
+ break;
+ case for_stmt:
+ res = validate_for(tree);
+ break;
+ case try_stmt:
+ res = validate_try(tree);
+ break;
+ case suite:
+ res = validate_suite(tree);
+ break;
+ /*
+ * Expression nodes.
+ */
+ case testlist:
+ res = validate_testlist(tree);
+ break;
+ case yield_expr:
+ res = validate_yield_expr(tree);
+ break;
+ case testlist1:
+ res = validate_testlist1(tree);
+ break;
+ case test:
+ res = validate_test(tree);
+ break;
+ case and_test:
+ res = validate_and_test(tree);
+ break;
+ case not_test:
+ res = validate_not_test(tree);
+ break;
+ case comparison:
+ res = validate_comparison(tree);
+ break;
+ case exprlist:
+ res = validate_exprlist(tree);
+ break;
+ case comp_op:
+ res = validate_comp_op(tree);
+ break;
+ case expr:
+ res = validate_expr(tree);
+ break;
+ case xor_expr:
+ res = validate_xor_expr(tree);
+ break;
+ case and_expr:
+ res = validate_and_expr(tree);
+ break;
+ case shift_expr:
+ res = validate_shift_expr(tree);
+ break;
+ case arith_expr:
+ res = validate_arith_expr(tree);
+ break;
+ case term:
+ res = validate_term(tree);
+ break;
+ case factor:
+ res = validate_factor(tree);
+ break;
+ case power:
+ res = validate_power(tree);
+ break;
+ case atom:
+ res = validate_atom(tree);
+ break;
+
+ default:
+ /* Hopefully never reached! */
+ err_string("unrecognized node type");
+ res = 0;
+ break;
+ }
+ tree = next;
+ }
+ return (res);
+}
+
+
+static int
+validate_expr_tree(node *tree)
+{
+ int res = validate_eval_input(tree);
+
+ if (!res && !PyErr_Occurred())
+ err_string("could not validate expression tuple");
+
+ return (res);
+}
+
+
+/* file_input:
+ * (NEWLINE | stmt)* ENDMARKER
+ */
+static int
+validate_file_input(node *tree)
+{
+ int j;
+ int nch = NCH(tree) - 1;
+ int res = ((nch >= 0)
+ && validate_ntype(CHILD(tree, nch), ENDMARKER));
+
+ for (j = 0; res && (j < nch); ++j) {
+ if (TYPE(CHILD(tree, j)) == stmt)
+ res = validate_stmt(CHILD(tree, j));
+ else
+ res = validate_newline(CHILD(tree, j));
+ }
+ /* This stays in to prevent any internal failures from getting to the
+ * user. Hopefully, this won't be needed. If a user reports getting
+ * this, we have some debugging to do.
+ */
+ if (!res && !PyErr_Occurred())
+ err_string("VALIDATION FAILURE: report this to the maintainer!");
+
+ return (res);
+}
+
+static int
+validate_encoding_decl(node *tree)
+{
+ int nch = NCH(tree);
+ int res = ((nch == 1)
+ && validate_file_input(CHILD(tree, 0)));
+
+ if (!res && !PyErr_Occurred())
+ err_string("Error Parsing encoding_decl");
+
+ return res;
+}
+
+static PyObject*
+pickle_constructor = NULL;
+
+
+static PyObject*
+parser__pickler(PyObject *self, PyObject *args)
+{
+ NOTE(ARGUNUSED(self))
+ PyObject *result = NULL;
+ PyObject *st = NULL;
+ PyObject *empty_dict = NULL;
+
+ if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) {
+ PyObject *newargs;
+ PyObject *tuple;
+
+ if ((empty_dict = PyDict_New()) == NULL)
+ goto finally;
+ if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL)
+ goto finally;
+ tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict);
+ if (tuple != NULL) {
+ result = Py_BuildValue("O(O)", pickle_constructor, tuple);
+ Py_DECREF(tuple);
+ }
+ Py_DECREF(empty_dict);
+ Py_DECREF(newargs);
+ }
+ finally:
+ Py_XDECREF(empty_dict);
+
+ return (result);
+}
+
+
+/* Functions exported by this module. Most of this should probably
+ * be converted into an ST object with methods, but that is better
+ * done directly in Python, allowing subclasses to be created directly.
+ * We'd really have to write a wrapper around it all anyway to allow
+ * inheritance.
+ */
+static PyMethodDef parser_functions[] = {
+ {"ast2tuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates a tuple-tree representation of an ST.")},
+ {"ast2list", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates a list-tree representation of an ST.")},
+ {"compileast", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Compiles an ST object into a code object.")},
+ {"compilest", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Compiles an ST object into a code object.")},
+ {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates an ST object from an expression.")},
+ {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Determines if an ST object was created from an expression.")},
+ {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Determines if an ST object was created from a suite.")},
+ {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates an ST object from a suite.")},
+ {"sequence2ast", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates an ST object from a tree representation.")},
+ {"sequence2st", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates an ST object from a tree representation.")},
+ {"st2tuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates a tuple-tree representation of an ST.")},
+ {"st2list", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates a list-tree representation of an ST.")},
+ {"tuple2ast", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates an ST object from a tree representation.")},
+ {"tuple2st", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
+ PyDoc_STR("Creates an ST object from a tree representation.")},
+
+ /* private stuff: support pickle module */
+ {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
+ PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")},
+
+ {NULL, NULL, 0, NULL}
+ };
+
+
+PyMODINIT_FUNC initparser(void); /* supply a prototype */
+
+PyMODINIT_FUNC
+initparser(void)
+{
+ PyObject *module, *copyreg;
+
+ PyST_Type.ob_type = &PyType_Type;
+ module = Py_InitModule("parser", parser_functions);
+ if (module == NULL)
+ return;
+
+ if (parser_error == 0)
+ parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
+
+ if (parser_error == 0)
+ /* caller will check PyErr_Occurred() */
+ return;
+ /* CAUTION: The code next used to skip bumping the refcount on
+ * parser_error. That's a disaster if initparser() gets called more
+ * than once. By incref'ing, we ensure that each module dict that
+ * gets created owns its reference to the shared parser_error object,
+ * and the file static parser_error vrbl owns a reference too.
+ */
+ Py_INCREF(parser_error);
+ if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
+ return;
+
+ Py_INCREF(&PyST_Type);
+ PyModule_AddObject(module, "ASTType", (PyObject*)&PyST_Type);
+ Py_INCREF(&PyST_Type);
+ PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type);
+
+ PyModule_AddStringConstant(module, "__copyright__",
+ parser_copyright_string);
+ PyModule_AddStringConstant(module, "__doc__",
+ parser_doc_string);
+ PyModule_AddStringConstant(module, "__version__",
+ parser_version_string);
+
+ /* Register to support pickling.
+ * If this fails, the import of this module will fail because an
+ * exception will be raised here; should we clear the exception?
+ */
+ copyreg = PyImport_ImportModule("copy_reg");
+ if (copyreg != NULL) {
+ PyObject *func, *pickler;
+
+ func = PyObject_GetAttrString(copyreg, "pickle");
+ pickle_constructor = PyObject_GetAttrString(module, "sequence2st");
+ pickler = PyObject_GetAttrString(module, "_pickler");
+ Py_XINCREF(pickle_constructor);
+ if ((func != NULL) && (pickle_constructor != NULL)
+ && (pickler != NULL)) {
+ PyObject *res;
+
+ res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler,
+ pickle_constructor, NULL);
+ Py_XDECREF(res);
+ }
+ Py_XDECREF(func);
+ Py_XDECREF(pickle_constructor);
+ Py_XDECREF(pickler);
+ Py_DECREF(copyreg);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/posixmodule.c b/sys/src/cmd/python/Modules/posixmodule.c
new file mode 100644
index 000000000..958fb63d3
--- /dev/null
+++ b/sys/src/cmd/python/Modules/posixmodule.c
@@ -0,0 +1,8752 @@
+
+/* POSIX module implementation */
+
+/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
+ module actually calls itself 'nt' or 'os2', not 'posix', and a few
+ functions are either unimplemented or implemented differently. The source
+ assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
+ of the compiler used. Different compilers define their own feature
+ test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
+ independent macro PYOS_OS2 should be defined. On OS/2 the default
+ compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
+ as the compiler specific macro for the EMX port of gcc to OS/2. */
+
+/* See also ../Dos/dosmodule.c */
+
+#ifdef __APPLE__
+ /*
+ * Step 1 of support for weak-linking a number of symbols existing on
+ * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
+ * at the end of this file for more information.
+ */
+# pragma weak lchown
+# pragma weak statvfs
+# pragma weak fstatvfs
+
+#endif /* __APPLE__ */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structseq.h"
+
+#if defined(__VMS)
+# include <unixio.h>
+#endif /* defined(__VMS) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyDoc_STRVAR(posix__doc__,
+"This module provides access to operating system functionality that is\n\
+standardized by the C Standard and the POSIX standard (a thinly\n\
+disguised Unix interface). Refer to the library manual and\n\
+corresponding Unix manual entries for more information on calls.");
+
+#ifndef Py_USING_UNICODE
+/* This is used in signatures of functions. */
+#define Py_UNICODE void
+#endif
+
+#if defined(PYOS_OS2)
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_DOSPROCESS
+#define INCL_NOPMAPI
+#include <os2.h>
+#if defined(PYCC_GCC)
+#include <ctype.h>
+#include <io.h>
+#include <stdio.h>
+#include <process.h>
+#endif
+#include "osdefs.h"
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h> /* For WNOHANG */
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif /* HAVE_SYSEXITS_H */
+
+#ifdef HAVE_SYS_LOADAVG_H
+#include <sys/loadavg.h>
+#endif
+
+/* Various compilers have only certain posix functions */
+/* XXX Gosh I wish these were all moved into pyconfig.h */
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+#include <process.h>
+#else
+#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
+#define HAVE_GETCWD 1
+#define HAVE_OPENDIR 1
+#define HAVE_SYSTEM 1
+#if defined(__OS2__)
+#define HAVE_EXECV 1
+#define HAVE_WAIT 1
+#endif
+#include <process.h>
+#else
+#ifdef __BORLANDC__ /* Borland compiler */
+#define HAVE_EXECV 1
+#define HAVE_GETCWD 1
+#define HAVE_OPENDIR 1
+#define HAVE_PIPE 1
+#define HAVE_POPEN 1
+#define HAVE_SYSTEM 1
+#define HAVE_WAIT 1
+#else
+#ifdef _MSC_VER /* Microsoft compiler */
+#define HAVE_GETCWD 1
+#define HAVE_SPAWNV 1
+#define HAVE_EXECV 1
+#define HAVE_PIPE 1
+#define HAVE_POPEN 1
+#define HAVE_SYSTEM 1
+#define HAVE_CWAIT 1
+#define HAVE_FSYNC 1
+#define fsync _commit
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
+/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
+#else /* all other compilers */
+/* Unix functions that the configure script doesn't check for */
+#define HAVE_EXECV 1
+#define HAVE_FORK 1
+#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
+#define HAVE_FORK1 1
+#endif
+#define HAVE_GETCWD 1
+#define HAVE_GETEGID 1
+#define HAVE_GETEUID 1
+#define HAVE_GETGID 1
+#define HAVE_GETPPID 1
+#define HAVE_GETUID 1
+#define HAVE_KILL 1
+#define HAVE_OPENDIR 1
+#define HAVE_PIPE 1
+#ifndef __rtems__
+#define HAVE_POPEN 1
+#endif
+#define HAVE_SYSTEM 1
+#define HAVE_WAIT 1
+#define HAVE_TTYNAME 1
+#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
+#endif /* _MSC_VER */
+#endif /* __BORLANDC__ */
+#endif /* ! __WATCOMC__ || __QNX__ */
+#endif /* ! __IBMC__ */
+
+#ifndef _MSC_VER
+
+#if defined(__sgi)&&_COMPILER_VERSION>=700
+/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
+ (default) */
+extern char *ctermid_r(char *);
+#endif
+
+#ifndef HAVE_UNISTD_H
+#if defined(PYCC_VACPP)
+extern int mkdir(char *);
+#else
+#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
+extern int mkdir(const char *);
+#else
+extern int mkdir(const char *, mode_t);
+#endif
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+extern int chdir(char *);
+extern int rmdir(char *);
+#else
+extern int chdir(const char *);
+extern int rmdir(const char *);
+#endif
+#ifdef __BORLANDC__
+extern int chmod(const char *, int);
+#else
+extern int chmod(const char *, mode_t);
+#endif
+extern int chown(const char *, uid_t, gid_t);
+extern char *getcwd(char *, int);
+extern char *strerror(int);
+extern int link(const char *, const char *);
+extern int rename(const char *, const char *);
+extern int stat(const char *, struct stat *);
+extern int unlink(const char *);
+extern int pclose(FILE *);
+#ifdef HAVE_SYMLINK
+extern int symlink(const char *, const char *);
+#endif /* HAVE_SYMLINK */
+#ifdef HAVE_LSTAT
+extern int lstat(const char *, struct stat *);
+#endif /* HAVE_LSTAT */
+#endif /* !HAVE_UNISTD_H */
+
+#endif /* !_MSC_VER */
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif /* HAVE_UTIME_H */
+
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#define HAVE_UTIME_H /* pretend we do for the rest of this file */
+#endif /* HAVE_SYS_UTIME_H */
+
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif /* HAVE_SYS_TIMES_H */
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif /* HAVE_SYS_UTSNAME_H */
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#if defined(__WATCOMC__) && !defined(__QNX__)
+#include <direct.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#define dirent direct
+#define NAMLEN(dirent) (dirent)->d_namlen
+#endif
+#ifdef HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#ifdef HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#ifdef HAVE_NDIR_H
+#include <ndir.h>
+#endif
+#endif
+
+#ifdef _MSC_VER
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+#include "osdefs.h"
+#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
+#include <windows.h>
+#include <shellapi.h> /* for ShellExecute() */
+#define popen _popen
+#define pclose _pclose
+#endif /* _MSC_VER */
+
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+#include <io.h>
+#endif /* OS2 */
+
+#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 1024
+#endif
+#endif /* MAXPATHLEN */
+
+#ifdef UNION_WAIT
+/* Emulate some macros on systems that have a union instead of macros */
+
+#ifndef WIFEXITED
+#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(u_wait) ((u_wait).w_termsig)
+#endif
+
+#define WAIT_TYPE union wait
+#define WAIT_STATUS_INT(s) (s.w_status)
+
+#else /* !UNION_WAIT */
+#define WAIT_TYPE int
+#define WAIT_STATUS_INT(s) (s)
+#endif /* UNION_WAIT */
+
+/* Don't use the "_r" form if we don't need it (also, won't have a
+ prototype for it, at least on Solaris -- maybe others as well?). */
+#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
+#define USE_CTERMID_R
+#endif
+
+#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
+#define USE_TMPNAM_R
+#endif
+
+/* choose the appropriate stat and fstat functions and return structs */
+#undef STAT
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+# define STAT win32_stat
+# define FSTAT win32_fstat
+# define STRUCT_STAT struct win32_stat
+#else
+# define STAT stat
+# define FSTAT fstat
+# define STRUCT_STAT struct stat
+#endif
+
+#if defined(MAJOR_IN_MKDEV)
+#include <sys/mkdev.h>
+#else
+#if defined(MAJOR_IN_SYSMACROS)
+#include <sys/sysmacros.h>
+#endif
+#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
+#include <sys/mkdev.h>
+#endif
+#endif
+
+/* Return a dictionary corresponding to the POSIX environment table */
+#ifdef WITH_NEXT_FRAMEWORK
+/* On Darwin/MacOSX a shared library or framework has no access to
+** environ directly, we must obtain it with _NSGetEnviron().
+*/
+#include <crt_externs.h>
+static char **environ;
+#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
+extern char **environ;
+#endif /* !_MSC_VER */
+
+static PyObject *
+convertenviron(void)
+{
+ PyObject *d;
+ char **e;
+ d = PyDict_New();
+ if (d == NULL)
+ return NULL;
+#ifdef WITH_NEXT_FRAMEWORK
+ if (environ == NULL)
+ environ = *_NSGetEnviron();
+#endif
+ if (environ == NULL)
+ return d;
+ /* This part ignores errors */
+ for (e = environ; *e != NULL; e++) {
+ PyObject *k;
+ PyObject *v;
+ char *p = strchr(*e, '=');
+ if (p == NULL)
+ continue;
+ k = PyString_FromStringAndSize(*e, (int)(p-*e));
+ if (k == NULL) {
+ PyErr_Clear();
+ continue;
+ }
+ v = PyString_FromString(p+1);
+ if (v == NULL) {
+ PyErr_Clear();
+ Py_DECREF(k);
+ continue;
+ }
+ if (PyDict_GetItem(d, k) == NULL) {
+ if (PyDict_SetItem(d, k, v) != 0)
+ PyErr_Clear();
+ }
+ Py_DECREF(k);
+ Py_DECREF(v);
+ }
+#if defined(PYOS_OS2)
+ {
+ APIRET rc;
+ char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
+
+ rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
+ if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
+ PyObject *v = PyString_FromString(buffer);
+ PyDict_SetItemString(d, "BEGINLIBPATH", v);
+ Py_DECREF(v);
+ }
+ rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
+ if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
+ PyObject *v = PyString_FromString(buffer);
+ PyDict_SetItemString(d, "ENDLIBPATH", v);
+ Py_DECREF(v);
+ }
+ }
+#endif
+ return d;
+}
+
+
+/* Set a POSIX-specific error from errno, and return NULL */
+
+static PyObject *
+posix_error(void)
+{
+ return PyErr_SetFromErrno(PyExc_OSError);
+}
+static PyObject *
+posix_error_with_filename(char* name)
+{
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject *
+posix_error_with_unicode_filename(Py_UNICODE* name)
+{
+ return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+
+static PyObject *
+posix_error_with_allocated_filename(char* name)
+{
+ PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
+ PyMem_Free(name);
+ return rc;
+}
+
+#ifdef MS_WINDOWS
+static PyObject *
+win32_error(char* function, char* filename)
+{
+ /* XXX We should pass the function name along in the future.
+ (_winreg.c also wants to pass the function name.)
+ This would however require an additional param to the
+ Windows error object, which is non-trivial.
+ */
+ errno = GetLastError();
+ if (filename)
+ return PyErr_SetFromWindowsErrWithFilename(errno, filename);
+ else
+ return PyErr_SetFromWindowsErr(errno);
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject *
+win32_error_unicode(char* function, Py_UNICODE* filename)
+{
+ /* XXX - see win32_error for comments on 'function' */
+ errno = GetLastError();
+ if (filename)
+ return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
+ else
+ return PyErr_SetFromWindowsErr(errno);
+}
+
+static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
+{
+}
+
+/* Function suitable for O& conversion */
+static int
+convert_to_unicode(PyObject *arg, void* _param)
+{
+ PyObject **param = (PyObject**)_param;
+ if (PyUnicode_CheckExact(arg)) {
+ Py_INCREF(arg);
+ *param = arg;
+ }
+ else if (PyUnicode_Check(arg)) {
+ /* For a Unicode subtype that's not a Unicode object,
+ return a true Unicode object with the same data. */
+ *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
+ PyUnicode_GET_SIZE(arg));
+ return *param != NULL;
+ }
+ else
+ *param = PyUnicode_FromEncodedObject(arg,
+ Py_FileSystemDefaultEncoding,
+ "strict");
+ return (*param) != NULL;
+}
+
+#endif /* Py_WIN_WIDE_FILENAMES */
+
+#endif
+
+#if defined(PYOS_OS2)
+/**********************************************************************
+ * Helper Function to Trim and Format OS/2 Messages
+ **********************************************************************/
+ static void
+os2_formatmsg(char *msgbuf, int msglen, char *reason)
+{
+ msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
+
+ if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
+ char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
+
+ while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
+ *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
+ }
+
+ /* Add Optional Reason Text */
+ if (reason) {
+ strcat(msgbuf, " : ");
+ strcat(msgbuf, reason);
+ }
+}
+
+/**********************************************************************
+ * Decode an OS/2 Operating System Error Code
+ *
+ * A convenience function to lookup an OS/2 error code and return a
+ * text message we can use to raise a Python exception.
+ *
+ * Notes:
+ * The messages for errors returned from the OS/2 kernel reside in
+ * the file OSO001.MSG in the \OS2 directory hierarchy.
+ *
+ **********************************************************************/
+ static char *
+os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
+{
+ APIRET rc;
+ ULONG msglen;
+
+ /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
+ Py_BEGIN_ALLOW_THREADS
+ rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
+ errorcode, "oso001.msg", &msglen);
+ Py_END_ALLOW_THREADS
+
+ if (rc == NO_ERROR)
+ os2_formatmsg(msgbuf, msglen, reason);
+ else
+ PyOS_snprintf(msgbuf, msgbuflen,
+ "unknown OS error #%d", errorcode);
+
+ return msgbuf;
+}
+
+/* Set an OS/2-specific error and return NULL. OS/2 kernel
+ errors are not in a global variable e.g. 'errno' nor are
+ they congruent with posix error numbers. */
+
+static PyObject * os2_error(int code)
+{
+ char text[1024];
+ PyObject *v;
+
+ os2_strerror(text, sizeof(text), code, "");
+
+ v = Py_BuildValue("(is)", code, text);
+ if (v != NULL) {
+ PyErr_SetObject(PyExc_OSError, v);
+ Py_DECREF(v);
+ }
+ return NULL; /* Signal to Python that an Exception is Pending */
+}
+
+#endif /* OS2 */
+
+/* POSIX generic methods */
+
+static PyObject *
+posix_fildes(PyObject *fdobj, int (*func)(int))
+{
+ int fd;
+ int res;
+ fd = PyObject_AsFileDescriptor(fdobj);
+ if (fd < 0)
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = (*func)(fd);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static int
+unicode_file_names(void)
+{
+ static int canusewide = -1;
+ if (canusewide == -1) {
+ /* As per doc for ::GetVersion(), this is the correct test for
+ the Windows NT family. */
+ canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
+ }
+ return canusewide;
+}
+#endif
+
+static PyObject *
+posix_1str(PyObject *args, char *format, int (*func)(const char*))
+{
+ char *path1 = NULL;
+ int res;
+ if (!PyArg_ParseTuple(args, format,
+ Py_FileSystemDefaultEncoding, &path1))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = (*func)(path1);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path1);
+ PyMem_Free(path1);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+posix_2str(PyObject *args,
+ char *format,
+ int (*func)(const char *, const char *))
+{
+ char *path1 = NULL, *path2 = NULL;
+ int res;
+ if (!PyArg_ParseTuple(args, format,
+ Py_FileSystemDefaultEncoding, &path1,
+ Py_FileSystemDefaultEncoding, &path2))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = (*func)(path1, path2);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(path1);
+ PyMem_Free(path2);
+ if (res != 0)
+ /* XXX how to report both path1 and path2??? */
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject*
+win32_1str(PyObject* args, char* func,
+ char* format, BOOL (__stdcall *funcA)(LPCSTR),
+ char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
+{
+ PyObject *uni;
+ char *ansi;
+ BOOL result;
+ if (unicode_file_names()) {
+ if (!PyArg_ParseTuple(args, wformat, &uni))
+ PyErr_Clear();
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ result = funcW(PyUnicode_AsUnicode(uni));
+ Py_END_ALLOW_THREADS
+ if (!result)
+ return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ if (!PyArg_ParseTuple(args, format, &ansi))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ result = funcA(ansi);
+ Py_END_ALLOW_THREADS
+ if (!result)
+ return win32_error(func, ansi);
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+/* This is a reimplementation of the C library's chdir function,
+ but one that produces Win32 errors instead of DOS error codes.
+ chdir is essentially a wrapper around SetCurrentDirectory; however,
+ it also needs to set "magic" environment variables indicating
+ the per-drive current directory, which are of the form =<drive>: */
+BOOL __stdcall
+win32_chdir(LPCSTR path)
+{
+ char new_path[MAX_PATH+1];
+ int result;
+ char env[4] = "=x:";
+
+ if(!SetCurrentDirectoryA(path))
+ return FALSE;
+ result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
+ if (!result)
+ return FALSE;
+ /* In the ANSI API, there should not be any paths longer
+ than MAX_PATH. */
+ assert(result <= MAX_PATH+1);
+ if (strncmp(new_path, "\\\\", 2) == 0 ||
+ strncmp(new_path, "//", 2) == 0)
+ /* UNC path, nothing to do. */
+ return TRUE;
+ env[1] = new_path[0];
+ return SetEnvironmentVariableA(env, new_path);
+}
+
+/* The Unicode version differs from the ANSI version
+ since the current directory might exceed MAX_PATH characters */
+BOOL __stdcall
+win32_wchdir(LPCWSTR path)
+{
+ wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
+ int result;
+ wchar_t env[4] = L"=x:";
+
+ if(!SetCurrentDirectoryW(path))
+ return FALSE;
+ result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
+ if (!result)
+ return FALSE;
+ if (result > MAX_PATH+1) {
+ new_path = malloc(result);
+ if (!new_path) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+ }
+ if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
+ wcsncmp(new_path, L"//", 2) == 0)
+ /* UNC path, nothing to do. */
+ return TRUE;
+ env[1] = new_path[0];
+ result = SetEnvironmentVariableW(env, new_path);
+ if (new_path != _new_path)
+ free(new_path);
+ return result;
+}
+#endif
+
+#ifdef MS_WINDOWS
+/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
+ - time stamps are restricted to second resolution
+ - file modification times suffer from forth-and-back conversions between
+ UTC and local time
+ Therefore, we implement our own stat, based on the Win32 API directly.
+*/
+#define HAVE_STAT_NSEC 1
+
+struct win32_stat{
+ int st_dev;
+ __int64 st_ino;
+ unsigned short st_mode;
+ int st_nlink;
+ int st_uid;
+ int st_gid;
+ int st_rdev;
+ __int64 st_size;
+ int st_atime;
+ int st_atime_nsec;
+ int st_mtime;
+ int st_mtime_nsec;
+ int st_ctime;
+ int st_ctime_nsec;
+};
+
+static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
+
+static void
+FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
+{
+ /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
+ /* Cannot simply cast and dereference in_ptr,
+ since it might not be aligned properly */
+ __int64 in;
+ memcpy(&in, in_ptr, sizeof(in));
+ *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
+ /* XXX Win32 supports time stamps past 2038; we currently don't */
+ *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
+}
+
+static void
+time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
+{
+ /* XXX endianness */
+ __int64 out;
+ out = time_in + secs_between_epochs;
+ out = out * 10000000 + nsec_in / 100;
+ memcpy(out_ptr, &out, sizeof(out));
+}
+
+/* Below, we *know* that ugo+r is 0444 */
+#if _S_IREAD != 0400
+#error Unsupported C library
+#endif
+static int
+attributes_to_mode(DWORD attr)
+{
+ int m = 0;
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
+ else
+ m |= _S_IFREG;
+ if (attr & FILE_ATTRIBUTE_READONLY)
+ m |= 0444;
+ else
+ m |= 0666;
+ return m;
+}
+
+static int
+attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
+{
+ memset(result, 0, sizeof(*result));
+ result->st_mode = attributes_to_mode(info->dwFileAttributes);
+ result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
+ FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
+ FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
+ FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
+
+ return 0;
+}
+
+/* Emulate GetFileAttributesEx[AW] on Windows 95 */
+static int checked = 0;
+static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
+static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
+static void
+check_gfax()
+{
+ HINSTANCE hKernel32;
+ if (checked)
+ return;
+ checked = 1;
+ hKernel32 = GetModuleHandle("KERNEL32");
+ *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
+ *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
+}
+
+static BOOL
+attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
+{
+ HANDLE hFindFile;
+ WIN32_FIND_DATAA FileData;
+ hFindFile = FindFirstFileA(pszFile, &FileData);
+ if (hFindFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+ FindClose(hFindFile);
+ pfad->dwFileAttributes = FileData.dwFileAttributes;
+ pfad->ftCreationTime = FileData.ftCreationTime;
+ pfad->ftLastAccessTime = FileData.ftLastAccessTime;
+ pfad->ftLastWriteTime = FileData.ftLastWriteTime;
+ pfad->nFileSizeHigh = FileData.nFileSizeHigh;
+ pfad->nFileSizeLow = FileData.nFileSizeLow;
+ return TRUE;
+}
+
+static BOOL
+attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
+{
+ HANDLE hFindFile;
+ WIN32_FIND_DATAW FileData;
+ hFindFile = FindFirstFileW(pszFile, &FileData);
+ if (hFindFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+ FindClose(hFindFile);
+ pfad->dwFileAttributes = FileData.dwFileAttributes;
+ pfad->ftCreationTime = FileData.ftCreationTime;
+ pfad->ftLastAccessTime = FileData.ftLastAccessTime;
+ pfad->ftLastWriteTime = FileData.ftLastWriteTime;
+ pfad->nFileSizeHigh = FileData.nFileSizeHigh;
+ pfad->nFileSizeLow = FileData.nFileSizeLow;
+ return TRUE;
+}
+
+static BOOL WINAPI
+Py_GetFileAttributesExA(LPCSTR pszFile,
+ GET_FILEEX_INFO_LEVELS level,
+ LPVOID pv)
+{
+ BOOL result;
+ LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
+ /* First try to use the system's implementation, if that is
+ available and either succeeds to gives an error other than
+ that it isn't implemented. */
+ check_gfax();
+ if (gfaxa) {
+ result = gfaxa(pszFile, level, pv);
+ if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return result;
+ }
+ /* It's either not present, or not implemented.
+ Emulate using FindFirstFile. */
+ if (level != GetFileExInfoStandard) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ /* Use GetFileAttributes to validate that the file name
+ does not contain wildcards (which FindFirstFile would
+ accept). */
+ if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
+ return FALSE;
+ return attributes_from_dir(pszFile, pfad);
+}
+
+static BOOL WINAPI
+Py_GetFileAttributesExW(LPCWSTR pszFile,
+ GET_FILEEX_INFO_LEVELS level,
+ LPVOID pv)
+{
+ BOOL result;
+ LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
+ /* First try to use the system's implementation, if that is
+ available and either succeeds to gives an error other than
+ that it isn't implemented. */
+ check_gfax();
+ if (gfaxa) {
+ result = gfaxw(pszFile, level, pv);
+ if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return result;
+ }
+ /* It's either not present, or not implemented.
+ Emulate using FindFirstFile. */
+ if (level != GetFileExInfoStandard) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ /* Use GetFileAttributes to validate that the file name
+ does not contain wildcards (which FindFirstFile would
+ accept). */
+ if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
+ return FALSE;
+ return attributes_from_dir_w(pszFile, pfad);
+}
+
+static int
+win32_stat(const char* path, struct win32_stat *result)
+{
+ WIN32_FILE_ATTRIBUTE_DATA info;
+ int code;
+ char *dot;
+ /* XXX not supported on Win95 and NT 3.x */
+ if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
+ if (GetLastError() != ERROR_SHARING_VIOLATION) {
+ /* Protocol violation: we explicitly clear errno, instead of
+ setting it to a POSIX error. Callers should use GetLastError. */
+ errno = 0;
+ return -1;
+ } else {
+ /* Could not get attributes on open file. Fall back to
+ reading the directory. */
+ if (!attributes_from_dir(path, &info)) {
+ /* Very strange. This should not fail now */
+ errno = 0;
+ return -1;
+ }
+ }
+ }
+ code = attribute_data_to_stat(&info, result);
+ if (code != 0)
+ return code;
+ /* Set S_IFEXEC if it is an .exe, .bat, ... */
+ dot = strrchr(path, '.');
+ if (dot) {
+ if (stricmp(dot, ".bat") == 0 ||
+ stricmp(dot, ".cmd") == 0 ||
+ stricmp(dot, ".exe") == 0 ||
+ stricmp(dot, ".com") == 0)
+ result->st_mode |= 0111;
+ }
+ return code;
+}
+
+static int
+win32_wstat(const wchar_t* path, struct win32_stat *result)
+{
+ int code;
+ const wchar_t *dot;
+ WIN32_FILE_ATTRIBUTE_DATA info;
+ /* XXX not supported on Win95 and NT 3.x */
+ if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
+ if (GetLastError() != ERROR_SHARING_VIOLATION) {
+ /* Protocol violation: we explicitly clear errno, instead of
+ setting it to a POSIX error. Callers should use GetLastError. */
+ errno = 0;
+ return -1;
+ } else {
+ /* Could not get attributes on open file. Fall back to
+ reading the directory. */
+ if (!attributes_from_dir_w(path, &info)) {
+ /* Very strange. This should not fail now */
+ errno = 0;
+ return -1;
+ }
+ }
+ }
+ code = attribute_data_to_stat(&info, result);
+ if (code < 0)
+ return code;
+ /* Set IFEXEC if it is an .exe, .bat, ... */
+ dot = wcsrchr(path, '.');
+ if (dot) {
+ if (_wcsicmp(dot, L".bat") == 0 ||
+ _wcsicmp(dot, L".cmd") == 0 ||
+ _wcsicmp(dot, L".exe") == 0 ||
+ _wcsicmp(dot, L".com") == 0)
+ result->st_mode |= 0111;
+ }
+ return code;
+}
+
+static int
+win32_fstat(int file_number, struct win32_stat *result)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ HANDLE h;
+ int type;
+
+ h = (HANDLE)_get_osfhandle(file_number);
+
+ /* Protocol violation: we explicitly clear errno, instead of
+ setting it to a POSIX error. Callers should use GetLastError. */
+ errno = 0;
+
+ if (h == INVALID_HANDLE_VALUE) {
+ /* This is really a C library error (invalid file handle).
+ We set the Win32 error to the closes one matching. */
+ SetLastError(ERROR_INVALID_HANDLE);
+ return -1;
+ }
+ memset(result, 0, sizeof(*result));
+
+ type = GetFileType(h);
+ if (type == FILE_TYPE_UNKNOWN) {
+ DWORD error = GetLastError();
+ if (error != 0) {
+ return -1;
+ }
+ /* else: valid but unknown file */
+ }
+
+ if (type != FILE_TYPE_DISK) {
+ if (type == FILE_TYPE_CHAR)
+ result->st_mode = _S_IFCHR;
+ else if (type == FILE_TYPE_PIPE)
+ result->st_mode = _S_IFIFO;
+ return 0;
+ }
+
+ if (!GetFileInformationByHandle(h, &info)) {
+ return -1;
+ }
+
+ /* similar to stat() */
+ result->st_mode = attributes_to_mode(info.dwFileAttributes);
+ result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
+ FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
+ FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
+ FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
+ /* specific to fstat() */
+ result->st_nlink = info.nNumberOfLinks;
+ result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
+ return 0;
+}
+
+#endif /* MS_WINDOWS */
+
+PyDoc_STRVAR(stat_result__doc__,
+"stat_result: Result from stat or lstat.\n\n\
+This object may be accessed either as a tuple of\n\
+ (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
+or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
+\n\
+Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
+or st_flags, they are available as attributes only.\n\
+\n\
+See os.stat for more information.");
+
+static PyStructSequence_Field stat_result_fields[] = {
+ {"st_mode", "protection bits"},
+ {"st_ino", "inode"},
+ {"st_dev", "device"},
+ {"st_nlink", "number of hard links"},
+ {"st_uid", "user ID of owner"},
+ {"st_gid", "group ID of owner"},
+ {"st_size", "total size, in bytes"},
+ /* The NULL is replaced with PyStructSequence_UnnamedField later. */
+ {NULL, "integer time of last access"},
+ {NULL, "integer time of last modification"},
+ {NULL, "integer time of last change"},
+ {"st_atime", "time of last access"},
+ {"st_mtime", "time of last modification"},
+ {"st_ctime", "time of last change"},
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ {"st_blksize", "blocksize for filesystem I/O"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+ {"st_blocks", "number of blocks allocated"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+ {"st_rdev", "device type (if inode device)"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+ {"st_flags", "user defined flags for file"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+ {"st_gen", "generation number"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+ {"st_birthtime", "time of creation"},
+#endif
+ {0}
+};
+
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+#define ST_BLKSIZE_IDX 13
+#else
+#define ST_BLKSIZE_IDX 12
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
+#else
+#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
+#else
+#define ST_RDEV_IDX ST_BLOCKS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
+#else
+#define ST_FLAGS_IDX ST_RDEV_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+#define ST_GEN_IDX (ST_FLAGS_IDX+1)
+#else
+#define ST_GEN_IDX ST_FLAGS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
+#else
+#define ST_BIRTHTIME_IDX ST_GEN_IDX
+#endif
+
+static PyStructSequence_Desc stat_result_desc = {
+ "stat_result", /* name */
+ stat_result__doc__, /* doc */
+ stat_result_fields,
+ 10
+};
+
+PyDoc_STRVAR(statvfs_result__doc__,
+"statvfs_result: Result from statvfs or fstatvfs.\n\n\
+This object may be accessed either as a tuple of\n\
+ (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
+or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
+\n\
+See os.statvfs for more information.");
+
+static PyStructSequence_Field statvfs_result_fields[] = {
+ {"f_bsize", },
+ {"f_frsize", },
+ {"f_blocks", },
+ {"f_bfree", },
+ {"f_bavail", },
+ {"f_files", },
+ {"f_ffree", },
+ {"f_favail", },
+ {"f_flag", },
+ {"f_namemax",},
+ {0}
+};
+
+static PyStructSequence_Desc statvfs_result_desc = {
+ "statvfs_result", /* name */
+ statvfs_result__doc__, /* doc */
+ statvfs_result_fields,
+ 10
+};
+
+static int initialized;
+static PyTypeObject StatResultType;
+static PyTypeObject StatVFSResultType;
+static newfunc structseq_new;
+
+static PyObject *
+statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyStructSequence *result;
+ int i;
+
+ result = (PyStructSequence*)structseq_new(type, args, kwds);
+ if (!result)
+ return NULL;
+ /* If we have been initialized from a tuple,
+ st_?time might be set to None. Initialize it
+ from the int slots. */
+ for (i = 7; i <= 9; i++) {
+ if (result->ob_item[i+3] == Py_None) {
+ Py_DECREF(Py_None);
+ Py_INCREF(result->ob_item[i]);
+ result->ob_item[i+3] = result->ob_item[i];
+ }
+ }
+ return (PyObject*)result;
+}
+
+
+
+/* If true, st_?time is float. */
+static int _stat_float_times = 1;
+
+PyDoc_STRVAR(stat_float_times__doc__,
+"stat_float_times([newval]) -> oldval\n\n\
+Determine whether os.[lf]stat represents time stamps as float objects.\n\
+If newval is True, future calls to stat() return floats, if it is False,\n\
+future calls return ints. \n\
+If newval is omitted, return the current setting.\n");
+
+static PyObject*
+stat_float_times(PyObject* self, PyObject *args)
+{
+ int newval = -1;
+ if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
+ return NULL;
+ if (newval == -1)
+ /* Return old value */
+ return PyBool_FromLong(_stat_float_times);
+ _stat_float_times = newval;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static void
+fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
+{
+ PyObject *fval,*ival;
+#if SIZEOF_TIME_T > SIZEOF_LONG
+ ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
+#else
+ ival = PyInt_FromLong((long)sec);
+#endif
+ if (!ival)
+ return;
+ if (_stat_float_times) {
+ fval = PyFloat_FromDouble(sec + 1e-9*nsec);
+ } else {
+ fval = ival;
+ Py_INCREF(fval);
+ }
+ PyStructSequence_SET_ITEM(v, index, ival);
+ PyStructSequence_SET_ITEM(v, index+3, fval);
+}
+
+/* pack a system stat C structure into the Python stat tuple
+ (used by posix_stat() and posix_fstat()) */
+static PyObject*
+_pystat_fromstructstat(STRUCT_STAT *st)
+{
+ unsigned long ansec, mnsec, cnsec;
+ PyObject *v = PyStructSequence_New(&StatResultType);
+ if (v == NULL)
+ return NULL;
+
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
+#ifdef HAVE_LARGEFILE_SUPPORT
+ PyStructSequence_SET_ITEM(v, 1,
+ PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
+#else
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
+#endif
+#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
+ PyStructSequence_SET_ITEM(v, 2,
+ PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
+#else
+ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
+#endif
+ PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
+ PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
+ PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
+#ifdef HAVE_LARGEFILE_SUPPORT
+ PyStructSequence_SET_ITEM(v, 6,
+ PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
+#else
+ PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
+#endif
+
+#if defined(HAVE_STAT_TV_NSEC)
+ ansec = st->st_atim.tv_nsec;
+ mnsec = st->st_mtim.tv_nsec;
+ cnsec = st->st_ctim.tv_nsec;
+#elif defined(HAVE_STAT_TV_NSEC2)
+ ansec = st->st_atimespec.tv_nsec;
+ mnsec = st->st_mtimespec.tv_nsec;
+ cnsec = st->st_ctimespec.tv_nsec;
+#elif defined(HAVE_STAT_NSEC)
+ ansec = st->st_atime_nsec;
+ mnsec = st->st_mtime_nsec;
+ cnsec = st->st_ctime_nsec;
+#else
+ ansec = mnsec = cnsec = 0;
+#endif
+ fill_time(v, 7, st->st_atime, ansec);
+ fill_time(v, 8, st->st_mtime, mnsec);
+ fill_time(v, 9, st->st_ctime, cnsec);
+
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
+ PyInt_FromLong((long)st->st_blksize));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+ PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
+ PyInt_FromLong((long)st->st_blocks));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+ PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
+ PyInt_FromLong((long)st->st_rdev));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+ PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
+ PyInt_FromLong((long)st->st_gen));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+ {
+ PyObject *val;
+ unsigned long bsec,bnsec;
+ bsec = (long)st->st_birthtime;
+#ifdef HAVE_STAT_TV_NSEC2
+ bnsec = st->st_birthtimespec.tv_nsec;
+#else
+ bnsec = 0;
+#endif
+ if (_stat_float_times) {
+ val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
+ } else {
+ val = PyInt_FromLong((long)bsec);
+ }
+ PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
+ val);
+ }
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+ PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
+ PyInt_FromLong((long)st->st_flags));
+#endif
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+
+ return v;
+}
+
+#ifdef MS_WINDOWS
+
+/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
+ where / can be used in place of \ and the trailing slash is optional.
+ Both SERVER and SHARE must have at least one character.
+*/
+
+#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
+#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+static BOOL
+IsUNCRootA(char *path, int pathlen)
+{
+ #define ISSLASH ISSLASHA
+
+ int i, share;
+
+ if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
+ /* minimum UNCRoot is \\x\y */
+ return FALSE;
+ for (i = 2; i < pathlen ; i++)
+ if (ISSLASH(path[i])) break;
+ if (i == 2 || i == pathlen)
+ /* do not allow \\\SHARE or \\SERVER */
+ return FALSE;
+ share = i+1;
+ for (i = share; i < pathlen; i++)
+ if (ISSLASH(path[i])) break;
+ return (i != share && (i == pathlen || i == pathlen-1));
+
+ #undef ISSLASH
+}
+
+#ifdef Py_WIN_WIDE_FILENAMES
+static BOOL
+IsUNCRootW(Py_UNICODE *path, int pathlen)
+{
+ #define ISSLASH ISSLASHW
+
+ int i, share;
+
+ if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
+ /* minimum UNCRoot is \\x\y */
+ return FALSE;
+ for (i = 2; i < pathlen ; i++)
+ if (ISSLASH(path[i])) break;
+ if (i == 2 || i == pathlen)
+ /* do not allow \\\SHARE or \\SERVER */
+ return FALSE;
+ share = i+1;
+ for (i = share; i < pathlen; i++)
+ if (ISSLASH(path[i])) break;
+ return (i != share && (i == pathlen || i == pathlen-1));
+
+ #undef ISSLASH
+}
+#endif /* Py_WIN_WIDE_FILENAMES */
+#endif /* MS_WINDOWS */
+
+static PyObject *
+posix_do_stat(PyObject *self, PyObject *args,
+ char *format,
+#ifdef __VMS
+ int (*statfunc)(const char *, STRUCT_STAT *, ...),
+#else
+ int (*statfunc)(const char *, STRUCT_STAT *),
+#endif
+ char *wformat,
+ int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
+{
+ STRUCT_STAT st;
+ char *path = NULL; /* pass this to stat; do not free() it */
+ char *pathfree = NULL; /* this memory must be free'd */
+ int res;
+ PyObject *result;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+ /* If on wide-character-capable OS see if argument
+ is Unicode and if so use wide API. */
+ if (unicode_file_names()) {
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, wformat, &po)) {
+ Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
+
+ Py_BEGIN_ALLOW_THREADS
+ /* PyUnicode_AS_UNICODE result OK without
+ thread lock as it is a simple dereference. */
+ res = wstatfunc(wpath, &st);
+ Py_END_ALLOW_THREADS
+
+ if (res != 0)
+ return win32_error_unicode("stat", wpath);
+ return _pystat_fromstructstat(&st);
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+#endif
+
+ if (!PyArg_ParseTuple(args, format,
+ Py_FileSystemDefaultEncoding, &path))
+ return NULL;
+ pathfree = path;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = (*statfunc)(path, &st);
+ Py_END_ALLOW_THREADS
+
+ if (res != 0) {
+#ifdef MS_WINDOWS
+ result = win32_error("stat", pathfree);
+#else
+ result = posix_error_with_filename(pathfree);
+#endif
+ }
+ else
+ result = _pystat_fromstructstat(&st);
+
+ PyMem_Free(pathfree);
+ return result;
+}
+
+/* POSIX methods */
+
+PyDoc_STRVAR(posix_access__doc__,
+"access(path, mode) -> True if granted, False otherwise\n\n\
+Use the real uid/gid to test for access to a path. Note that most\n\
+operations will use the effective uid/gid, therefore this routine can\n\
+be used in a suid/sgid environment to test if the invoking user has the\n\
+specified access to the path. The mode argument can be F_OK to test\n\
+existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
+
+static PyObject *
+posix_access(PyObject *self, PyObject *args)
+{
+ char *path;
+ int mode;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+ DWORD attr;
+ if (unicode_file_names()) {
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
+ Py_BEGIN_ALLOW_THREADS
+ /* PyUnicode_AS_UNICODE OK without thread lock as
+ it is a simple dereference. */
+ attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+ Py_END_ALLOW_THREADS
+ goto finish;
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+ if (!PyArg_ParseTuple(args, "eti:access",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return 0;
+ Py_BEGIN_ALLOW_THREADS
+ attr = GetFileAttributesA(path);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(path);
+finish:
+ if (attr == 0xFFFFFFFF)
+ /* File does not exist, or cannot read attributes */
+ return PyBool_FromLong(0);
+ /* Access is possible if either write access wasn't requested, or
+ the file isn't read-only. */
+ return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
+#else
+ int res;
+ if (!PyArg_ParseTuple(args, "eti:access",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = access(path, mode);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(path);
+ return PyBool_FromLong(res == 0);
+#endif
+}
+
+#ifndef F_OK
+#define F_OK 0
+#endif
+#ifndef R_OK
+#define R_OK 4
+#endif
+#ifndef W_OK
+#define W_OK 2
+#endif
+#ifndef X_OK
+#define X_OK 1
+#endif
+
+#ifdef HAVE_TTYNAME
+PyDoc_STRVAR(posix_ttyname__doc__,
+"ttyname(fd) -> string\n\n\
+Return the name of the terminal device connected to 'fd'.");
+
+static PyObject *
+posix_ttyname(PyObject *self, PyObject *args)
+{
+ int id;
+ char *ret;
+
+ if (!PyArg_ParseTuple(args, "i:ttyname", &id))
+ return NULL;
+
+#if defined(__VMS)
+ /* file descriptor 0 only, the default input device (stdin) */
+ if (id == 0) {
+ ret = ttyname();
+ }
+ else {
+ ret = NULL;
+ }
+#else
+ ret = ttyname(id);
+#endif
+ if (ret == NULL)
+ return posix_error();
+ return PyString_FromString(ret);
+}
+#endif
+
+#ifdef HAVE_CTERMID
+PyDoc_STRVAR(posix_ctermid__doc__,
+"ctermid() -> string\n\n\
+Return the name of the controlling terminal for this process.");
+
+static PyObject *
+posix_ctermid(PyObject *self, PyObject *noargs)
+{
+ char *ret;
+ char buffer[L_ctermid];
+
+#ifdef USE_CTERMID_R
+ ret = ctermid_r(buffer);
+#else
+ ret = ctermid(buffer);
+#endif
+ if (ret == NULL)
+ return posix_error();
+ return PyString_FromString(buffer);
+}
+#endif
+
+PyDoc_STRVAR(posix_chdir__doc__,
+"chdir(path)\n\n\
+Change the current working directory to the specified path.");
+
+static PyObject *
+posix_chdir(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+ return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
+#elif defined(PYOS_OS2) && defined(PYCC_GCC)
+ return posix_1str(args, "et:chdir", _chdir2);
+#elif defined(__VMS)
+ return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
+#else
+ return posix_1str(args, "et:chdir", chdir);
+#endif
+}
+
+#ifdef HAVE_FCHDIR
+PyDoc_STRVAR(posix_fchdir__doc__,
+"fchdir(fildes)\n\n\
+Change to the directory of the given file descriptor. fildes must be\n\
+opened on a directory, not a file.");
+
+static PyObject *
+posix_fchdir(PyObject *self, PyObject *fdobj)
+{
+ return posix_fildes(fdobj, fchdir);
+}
+#endif /* HAVE_FCHDIR */
+
+
+PyDoc_STRVAR(posix_chmod__doc__,
+"chmod(path, mode)\n\n\
+Change the access permissions of a file.");
+
+static PyObject *
+posix_chmod(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ int i;
+ int res;
+#ifdef Py_WIN_WIDE_FILENAMES
+ DWORD attr;
+ if (unicode_file_names()) {
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
+ Py_BEGIN_ALLOW_THREADS
+ attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+ if (attr != 0xFFFFFFFF) {
+ if (i & _S_IWRITE)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+ res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
+ }
+ else
+ res = 0;
+ Py_END_ALLOW_THREADS
+ if (!res)
+ return win32_error_unicode("chmod",
+ PyUnicode_AS_UNICODE(po));
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+ if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
+ &path, &i))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ attr = GetFileAttributesA(path);
+ if (attr != 0xFFFFFFFF) {
+ if (i & _S_IWRITE)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+ res = SetFileAttributesA(path, attr);
+ }
+ else
+ res = 0;
+ Py_END_ALLOW_THREADS
+ if (!res) {
+ win32_error("chmod", path);
+ PyMem_Free(path);
+ return NULL;
+ }
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#else /* Py_WIN_WIDE_FILENAMES */
+ if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
+ &path, &i))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = chmod(path, i);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#endif
+}
+
+
+#ifdef HAVE_CHROOT
+PyDoc_STRVAR(posix_chroot__doc__,
+"chroot(path)\n\n\
+Change root directory to path.");
+
+static PyObject *
+posix_chroot(PyObject *self, PyObject *args)
+{
+ return posix_1str(args, "et:chroot", chroot);
+}
+#endif
+
+#ifdef HAVE_FSYNC
+PyDoc_STRVAR(posix_fsync__doc__,
+"fsync(fildes)\n\n\
+force write of file with filedescriptor to disk.");
+
+static PyObject *
+posix_fsync(PyObject *self, PyObject *fdobj)
+{
+ return posix_fildes(fdobj, fsync);
+}
+#endif /* HAVE_FSYNC */
+
+#ifdef HAVE_FDATASYNC
+
+#ifdef __hpux
+extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
+#endif
+
+PyDoc_STRVAR(posix_fdatasync__doc__,
+"fdatasync(fildes)\n\n\
+force write of file with filedescriptor to disk.\n\
+ does not force update of metadata.");
+
+static PyObject *
+posix_fdatasync(PyObject *self, PyObject *fdobj)
+{
+ return posix_fildes(fdobj, fdatasync);
+}
+#endif /* HAVE_FDATASYNC */
+
+
+#ifdef HAVE_CHOWN
+PyDoc_STRVAR(posix_chown__doc__,
+"chown(path, uid, gid)\n\n\
+Change the owner and group id of path to the numeric uid and gid.");
+
+static PyObject *
+posix_chown(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ int uid, gid;
+ int res;
+ if (!PyArg_ParseTuple(args, "etii:chown",
+ Py_FileSystemDefaultEncoding, &path,
+ &uid, &gid))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = chown(path, (uid_t) uid, (gid_t) gid);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_CHOWN */
+
+#ifdef HAVE_LCHOWN
+PyDoc_STRVAR(posix_lchown__doc__,
+"lchown(path, uid, gid)\n\n\
+Change the owner and group id of path to the numeric uid and gid.\n\
+This function will not follow symbolic links.");
+
+static PyObject *
+posix_lchown(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ int uid, gid;
+ int res;
+ if (!PyArg_ParseTuple(args, "etii:lchown",
+ Py_FileSystemDefaultEncoding, &path,
+ &uid, &gid))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = lchown(path, (uid_t) uid, (gid_t) gid);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_LCHOWN */
+
+
+#ifdef HAVE_GETCWD
+PyDoc_STRVAR(posix_getcwd__doc__,
+"getcwd() -> path\n\n\
+Return a string representing the current working directory.");
+
+static PyObject *
+posix_getcwd(PyObject *self, PyObject *noargs)
+{
+ char buf[1026];
+ char *res;
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ res = _getcwd2(buf, sizeof buf);
+#else
+ res = getcwd(buf, sizeof buf);
+#endif
+ Py_END_ALLOW_THREADS
+ if (res == NULL)
+ return posix_error();
+ return PyString_FromString(buf);
+}
+
+#ifdef Py_USING_UNICODE
+PyDoc_STRVAR(posix_getcwdu__doc__,
+"getcwdu() -> path\n\n\
+Return a unicode string representing the current working directory.");
+
+static PyObject *
+posix_getcwdu(PyObject *self, PyObject *noargs)
+{
+ char buf[1026];
+ char *res;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+ DWORD len;
+ if (unicode_file_names()) {
+ wchar_t wbuf[1026];
+ wchar_t *wbuf2 = wbuf;
+ PyObject *resobj;
+ Py_BEGIN_ALLOW_THREADS
+ len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
+ /* If the buffer is large enough, len does not include the
+ terminating \0. If the buffer is too small, len includes
+ the space needed for the terminator. */
+ if (len >= sizeof wbuf/ sizeof wbuf[0]) {
+ wbuf2 = malloc(len * sizeof(wchar_t));
+ if (wbuf2)
+ len = GetCurrentDirectoryW(len, wbuf2);
+ }
+ Py_END_ALLOW_THREADS
+ if (!wbuf2) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ if (!len) {
+ if (wbuf2 != wbuf) free(wbuf2);
+ return win32_error("getcwdu", NULL);
+ }
+ resobj = PyUnicode_FromWideChar(wbuf2, len);
+ if (wbuf2 != wbuf) free(wbuf2);
+ return resobj;
+ }
+#endif
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ res = _getcwd2(buf, sizeof buf);
+#else
+ res = getcwd(buf, sizeof buf);
+#endif
+ Py_END_ALLOW_THREADS
+ if (res == NULL)
+ return posix_error();
+ return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
+}
+#endif
+#endif
+
+
+#ifdef HAVE_LINK
+PyDoc_STRVAR(posix_link__doc__,
+"link(src, dst)\n\n\
+Create a hard link to a file.");
+
+static PyObject *
+posix_link(PyObject *self, PyObject *args)
+{
+ return posix_2str(args, "etet:link", link);
+}
+#endif /* HAVE_LINK */
+
+
+PyDoc_STRVAR(posix_listdir__doc__,
+"listdir(path) -> list_of_strings\n\n\
+Return a list containing the names of the entries in the directory.\n\
+\n\
+ path: path of directory to list\n\
+\n\
+The list is in arbitrary order. It does not include the special\n\
+entries '.' and '..' even if they are present in the directory.");
+
+static PyObject *
+posix_listdir(PyObject *self, PyObject *args)
+{
+ /* XXX Should redo this putting the (now four) versions of opendir
+ in separate files instead of having them all here... */
+#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
+
+ PyObject *d, *v;
+ HANDLE hFindFile;
+ BOOL result;
+ WIN32_FIND_DATA FileData;
+ char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
+ char *bufptr = namebuf;
+ Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
+
+#ifdef Py_WIN_WIDE_FILENAMES
+ /* If on wide-character-capable OS see if argument
+ is Unicode and if so use wide API. */
+ if (unicode_file_names()) {
+ PyObject *po;
+ if (PyArg_ParseTuple(args, "U:listdir", &po)) {
+ WIN32_FIND_DATAW wFileData;
+ Py_UNICODE *wnamebuf;
+ Py_UNICODE wch;
+ /* Overallocate for \\*.*\0 */
+ len = PyUnicode_GET_SIZE(po);
+ wnamebuf = malloc((len + 5) * sizeof(wchar_t));
+ if (!wnamebuf) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
+ wch = len > 0 ? wnamebuf[len-1] : '\0';
+ if (wch != L'/' && wch != L'\\' && wch != L':')
+ wnamebuf[len++] = L'\\';
+ wcscpy(wnamebuf + len, L"*.*");
+ if ((d = PyList_New(0)) == NULL) {
+ free(wnamebuf);
+ return NULL;
+ }
+ hFindFile = FindFirstFileW(wnamebuf, &wFileData);
+ if (hFindFile == INVALID_HANDLE_VALUE) {
+ int error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND) {
+ free(wnamebuf);
+ return d;
+ }
+ Py_DECREF(d);
+ win32_error_unicode("FindFirstFileW", wnamebuf);
+ free(wnamebuf);
+ return NULL;
+ }
+ do {
+ /* Skip over . and .. */
+ if (wcscmp(wFileData.cFileName, L".") != 0 &&
+ wcscmp(wFileData.cFileName, L"..") != 0) {
+ v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
+ if (v == NULL) {
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ if (PyList_Append(d, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ Py_DECREF(v);
+ }
+ Py_BEGIN_ALLOW_THREADS
+ result = FindNextFileW(hFindFile, &wFileData);
+ Py_END_ALLOW_THREADS
+ /* FindNextFile sets error to ERROR_NO_MORE_FILES if
+ it got to the end of the directory. */
+ if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+ Py_DECREF(d);
+ win32_error_unicode("FindNextFileW", wnamebuf);
+ FindClose(hFindFile);
+ free(wnamebuf);
+ return NULL;
+ }
+ } while (result == TRUE);
+
+ if (FindClose(hFindFile) == FALSE) {
+ Py_DECREF(d);
+ win32_error_unicode("FindClose", wnamebuf);
+ free(wnamebuf);
+ return NULL;
+ }
+ free(wnamebuf);
+ return d;
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+#endif
+
+ if (!PyArg_ParseTuple(args, "et#:listdir",
+ Py_FileSystemDefaultEncoding, &bufptr, &len))
+ return NULL;
+ if (len > 0) {
+ char ch = namebuf[len-1];
+ if (ch != SEP && ch != ALTSEP && ch != ':')
+ namebuf[len++] = '/';
+ }
+ strcpy(namebuf + len, "*.*");
+
+ if ((d = PyList_New(0)) == NULL)
+ return NULL;
+
+ hFindFile = FindFirstFile(namebuf, &FileData);
+ if (hFindFile == INVALID_HANDLE_VALUE) {
+ int error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND)
+ return d;
+ Py_DECREF(d);
+ return win32_error("FindFirstFile", namebuf);
+ }
+ do {
+ /* Skip over . and .. */
+ if (strcmp(FileData.cFileName, ".") != 0 &&
+ strcmp(FileData.cFileName, "..") != 0) {
+ v = PyString_FromString(FileData.cFileName);
+ if (v == NULL) {
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ if (PyList_Append(d, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ Py_DECREF(v);
+ }
+ Py_BEGIN_ALLOW_THREADS
+ result = FindNextFile(hFindFile, &FileData);
+ Py_END_ALLOW_THREADS
+ /* FindNextFile sets error to ERROR_NO_MORE_FILES if
+ it got to the end of the directory. */
+ if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+ Py_DECREF(d);
+ win32_error("FindNextFile", namebuf);
+ FindClose(hFindFile);
+ return NULL;
+ }
+ } while (result == TRUE);
+
+ if (FindClose(hFindFile) == FALSE) {
+ Py_DECREF(d);
+ return win32_error("FindClose", namebuf);
+ }
+
+ return d;
+
+#elif defined(PYOS_OS2)
+
+#ifndef MAX_PATH
+#define MAX_PATH CCHMAXPATH
+#endif
+ char *name, *pt;
+ Py_ssize_t len;
+ PyObject *d, *v;
+ char namebuf[MAX_PATH+5];
+ HDIR hdir = 1;
+ ULONG srchcnt = 1;
+ FILEFINDBUF3 ep;
+ APIRET rc;
+
+ if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
+ return NULL;
+ if (len >= MAX_PATH) {
+ PyErr_SetString(PyExc_ValueError, "path too long");
+ return NULL;
+ }
+ strcpy(namebuf, name);
+ for (pt = namebuf; *pt; pt++)
+ if (*pt == ALTSEP)
+ *pt = SEP;
+ if (namebuf[len-1] != SEP)
+ namebuf[len++] = SEP;
+ strcpy(namebuf + len, "*.*");
+
+ if ((d = PyList_New(0)) == NULL)
+ return NULL;
+
+ rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
+ &hdir, /* Handle to Use While Search Directory */
+ FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
+ &ep, sizeof(ep), /* Structure to Receive Directory Entry */
+ &srchcnt, /* Max and Actual Count of Entries Per Iteration */
+ FIL_STANDARD); /* Format of Entry (EAs or Not) */
+
+ if (rc != NO_ERROR) {
+ errno = ENOENT;
+ return posix_error_with_filename(name);
+ }
+
+ if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
+ do {
+ if (ep.achName[0] == '.'
+ && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
+ continue; /* Skip Over "." and ".." Names */
+
+ strcpy(namebuf, ep.achName);
+
+ /* Leave Case of Name Alone -- In Native Form */
+ /* (Removed Forced Lowercasing Code) */
+
+ v = PyString_FromString(namebuf);
+ if (v == NULL) {
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ if (PyList_Append(d, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ Py_DECREF(v);
+ } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
+ }
+
+ return d;
+#else
+
+ char *name = NULL;
+ PyObject *d, *v;
+ DIR *dirp;
+ struct dirent *ep;
+ int arg_is_unicode = 1;
+
+ errno = 0;
+ if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
+ arg_is_unicode = 0;
+ PyErr_Clear();
+ }
+ if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
+ return NULL;
+ if ((dirp = opendir(name)) == NULL) {
+ return posix_error_with_allocated_filename(name);
+ }
+ if ((d = PyList_New(0)) == NULL) {
+ closedir(dirp);
+ PyMem_Free(name);
+ return NULL;
+ }
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS
+ ep = readdir(dirp);
+ Py_END_ALLOW_THREADS
+ if (ep == NULL)
+ break;
+ if (ep->d_name[0] == '.' &&
+ (NAMLEN(ep) == 1 ||
+ (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
+ continue;
+ v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
+ if (v == NULL) {
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+#ifdef Py_USING_UNICODE
+ if (arg_is_unicode) {
+ PyObject *w;
+
+ w = PyUnicode_FromEncodedObject(v,
+ Py_FileSystemDefaultEncoding,
+ "strict");
+ if (w != NULL) {
+ Py_DECREF(v);
+ v = w;
+ }
+ else {
+ /* fall back to the original byte string, as
+ discussed in patch #683592 */
+ PyErr_Clear();
+ }
+ }
+#endif
+ if (PyList_Append(d, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ Py_DECREF(v);
+ }
+ if (errno != 0 && d != NULL) {
+ /* readdir() returned NULL and set errno */
+ closedir(dirp);
+ Py_DECREF(d);
+ return posix_error_with_allocated_filename(name);
+ }
+ closedir(dirp);
+ PyMem_Free(name);
+
+ return d;
+
+#endif /* which OS */
+} /* end of posix_listdir */
+
+#ifdef MS_WINDOWS
+/* A helper function for abspath on win32 */
+static PyObject *
+posix__getfullpathname(PyObject *self, PyObject *args)
+{
+ /* assume encoded strings wont more than double no of chars */
+ char inbuf[MAX_PATH*2];
+ char *inbufp = inbuf;
+ Py_ssize_t insize = sizeof(inbuf);
+ char outbuf[MAX_PATH*2];
+ char *temp;
+#ifdef Py_WIN_WIDE_FILENAMES
+ if (unicode_file_names()) {
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
+ Py_UNICODE woutbuf[MAX_PATH*2];
+ Py_UNICODE *wtemp;
+ if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
+ sizeof(woutbuf)/sizeof(woutbuf[0]),
+ woutbuf, &wtemp))
+ return win32_error("GetFullPathName", "");
+ return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+#endif
+ if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
+ Py_FileSystemDefaultEncoding, &inbufp,
+ &insize))
+ return NULL;
+ if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
+ outbuf, &temp))
+ return win32_error("GetFullPathName", inbuf);
+ if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
+ return PyUnicode_Decode(outbuf, strlen(outbuf),
+ Py_FileSystemDefaultEncoding, NULL);
+ }
+ return PyString_FromString(outbuf);
+} /* end of posix__getfullpathname */
+#endif /* MS_WINDOWS */
+
+PyDoc_STRVAR(posix_mkdir__doc__,
+"mkdir(path [, mode=0777])\n\n\
+Create a directory.");
+
+static PyObject *
+posix_mkdir(PyObject *self, PyObject *args)
+{
+ int res;
+ char *path = NULL;
+ int mode = 0777;
+
+#ifdef Py_WIN_WIDE_FILENAMES
+ if (unicode_file_names()) {
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
+ Py_BEGIN_ALLOW_THREADS
+ /* PyUnicode_AS_UNICODE OK without thread lock as
+ it is a simple dereference. */
+ res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
+ Py_END_ALLOW_THREADS
+ if (!res)
+ return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+ if (!PyArg_ParseTuple(args, "et|i:mkdir",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ /* PyUnicode_AS_UNICODE OK without thread lock as
+ it is a simple dereference. */
+ res = CreateDirectoryA(path, NULL);
+ Py_END_ALLOW_THREADS
+ if (!res) {
+ win32_error("mkdir", path);
+ PyMem_Free(path);
+ return NULL;
+ }
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#else
+
+ if (!PyArg_ParseTuple(args, "et|i:mkdir",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
+ res = mkdir(path);
+#else
+ res = mkdir(path, mode);
+#endif
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#endif
+}
+
+
+/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
+#if defined(HAVE_SYS_RESOURCE_H)
+#include <sys/resource.h>
+#endif
+
+
+#ifdef HAVE_NICE
+PyDoc_STRVAR(posix_nice__doc__,
+"nice(inc) -> new_priority\n\n\
+Decrease the priority of process by inc and return the new priority.");
+
+static PyObject *
+posix_nice(PyObject *self, PyObject *args)
+{
+ int increment, value;
+
+ if (!PyArg_ParseTuple(args, "i:nice", &increment))
+ return NULL;
+
+ /* There are two flavours of 'nice': one that returns the new
+ priority (as required by almost all standards out there) and the
+ Linux/FreeBSD/BSDI one, which returns '0' on success and advices
+ the use of getpriority() to get the new priority.
+
+ If we are of the nice family that returns the new priority, we
+ need to clear errno before the call, and check if errno is filled
+ before calling posix_error() on a returnvalue of -1, because the
+ -1 may be the actual new priority! */
+
+ errno = 0;
+ value = nice(increment);
+#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
+ if (value == 0)
+ value = getpriority(PRIO_PROCESS, 0);
+#endif
+ if (value == -1 && errno != 0)
+ /* either nice() or getpriority() returned an error */
+ return posix_error();
+ return PyInt_FromLong((long) value);
+}
+#endif /* HAVE_NICE */
+
+PyDoc_STRVAR(posix_rename__doc__,
+"rename(old, new)\n\n\
+Rename a file or directory.");
+
+static PyObject *
+posix_rename(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+ PyObject *o1, *o2;
+ char *p1, *p2;
+ BOOL result;
+ if (unicode_file_names()) {
+ if (!PyArg_ParseTuple(args, "O&O&:rename",
+ convert_to_unicode, &o1,
+ convert_to_unicode, &o2))
+ PyErr_Clear();
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ result = MoveFileW(PyUnicode_AsUnicode(o1),
+ PyUnicode_AsUnicode(o2));
+ Py_END_ALLOW_THREADS
+ Py_DECREF(o1);
+ Py_DECREF(o2);
+ if (!result)
+ return win32_error("rename", NULL);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ result = MoveFileA(p1, p2);
+ Py_END_ALLOW_THREADS
+ if (!result)
+ return win32_error("rename", NULL);
+ Py_INCREF(Py_None);
+ return Py_None;
+#else
+ return posix_2str(args, "etet:rename", rename);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_rmdir__doc__,
+"rmdir(path)\n\n\
+Remove a directory.");
+
+static PyObject *
+posix_rmdir(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+ return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
+#else
+ return posix_1str(args, "et:rmdir", rmdir);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_stat__doc__,
+"stat(path) -> stat result\n\n\
+Perform a stat system call on the given path.");
+
+static PyObject *
+posix_stat(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+ return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
+#else
+ return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
+#endif
+}
+
+
+#ifdef HAVE_SYSTEM
+PyDoc_STRVAR(posix_system__doc__,
+"system(command) -> exit_status\n\n\
+Execute the command (a string) in a subshell.");
+
+static PyObject *
+posix_system(PyObject *self, PyObject *args)
+{
+ char *command;
+ long sts;
+ if (!PyArg_ParseTuple(args, "s:system", &command))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ sts = system(command);
+ Py_END_ALLOW_THREADS
+ return PyInt_FromLong(sts);
+}
+#endif
+
+
+PyDoc_STRVAR(posix_umask__doc__,
+"umask(new_mask) -> old_mask\n\n\
+Set the current numeric umask and return the previous umask.");
+
+static PyObject *
+posix_umask(PyObject *self, PyObject *args)
+{
+ int i;
+ if (!PyArg_ParseTuple(args, "i:umask", &i))
+ return NULL;
+ i = (int)umask(i);
+ if (i < 0)
+ return posix_error();
+ return PyInt_FromLong((long)i);
+}
+
+
+PyDoc_STRVAR(posix_unlink__doc__,
+"unlink(path)\n\n\
+Remove a file (same as remove(path)).");
+
+PyDoc_STRVAR(posix_remove__doc__,
+"remove(path)\n\n\
+Remove a file (same as unlink(path)).");
+
+static PyObject *
+posix_unlink(PyObject *self, PyObject *args)
+{
+#ifdef MS_WINDOWS
+ return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
+#else
+ return posix_1str(args, "et:remove", unlink);
+#endif
+}
+
+
+#ifdef HAVE_UNAME
+PyDoc_STRVAR(posix_uname__doc__,
+"uname() -> (sysname, nodename, release, version, machine)\n\n\
+Return a tuple identifying the current operating system.");
+
+static PyObject *
+posix_uname(PyObject *self, PyObject *noargs)
+{
+ struct utsname u;
+ int res;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = uname(&u);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ return Py_BuildValue("(sssss)",
+ u.sysname,
+ u.nodename,
+ u.release,
+ u.version,
+ u.machine);
+}
+#endif /* HAVE_UNAME */
+
+static int
+extract_time(PyObject *t, long* sec, long* usec)
+{
+ long intval;
+ if (PyFloat_Check(t)) {
+ double tval = PyFloat_AsDouble(t);
+ PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
+ if (!intobj)
+ return -1;
+ intval = PyInt_AsLong(intobj);
+ Py_DECREF(intobj);
+ if (intval == -1 && PyErr_Occurred())
+ return -1;
+ *sec = intval;
+ *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
+ if (*usec < 0)
+ /* If rounding gave us a negative number,
+ truncate. */
+ *usec = 0;
+ return 0;
+ }
+ intval = PyInt_AsLong(t);
+ if (intval == -1 && PyErr_Occurred())
+ return -1;
+ *sec = intval;
+ *usec = 0;
+ return 0;
+}
+
+PyDoc_STRVAR(posix_utime__doc__,
+"utime(path, (atime, mtime))\n\
+utime(path, None)\n\n\
+Set the access and modified time of the file to the given values. If the\n\
+second form is used, set the access and modified times to the current time.");
+
+static PyObject *
+posix_utime(PyObject *self, PyObject *args)
+{
+#ifdef Py_WIN_WIDE_FILENAMES
+ PyObject *arg;
+ PyUnicodeObject *obwpath;
+ wchar_t *wpath = NULL;
+ char *apath = NULL;
+ HANDLE hFile;
+ long atimesec, mtimesec, ausec, musec;
+ FILETIME atime, mtime;
+ PyObject *result = NULL;
+
+ if (unicode_file_names()) {
+ if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
+ wpath = PyUnicode_AS_UNICODE(obwpath);
+ Py_BEGIN_ALLOW_THREADS
+ hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
+ NULL, OPEN_EXISTING, 0, NULL);
+ Py_END_ALLOW_THREADS
+ if (hFile == INVALID_HANDLE_VALUE)
+ return win32_error_unicode("utime", wpath);
+ } else
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+ if (!wpath) {
+ if (!PyArg_ParseTuple(args, "etO:utime",
+ Py_FileSystemDefaultEncoding, &apath, &arg))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
+ NULL, OPEN_EXISTING, 0, NULL);
+ Py_END_ALLOW_THREADS
+ if (hFile == INVALID_HANDLE_VALUE) {
+ win32_error("utime", apath);
+ PyMem_Free(apath);
+ return NULL;
+ }
+ PyMem_Free(apath);
+ }
+
+ if (arg == Py_None) {
+ SYSTEMTIME now;
+ GetSystemTime(&now);
+ if (!SystemTimeToFileTime(&now, &mtime) ||
+ !SystemTimeToFileTime(&now, &atime)) {
+ win32_error("utime", NULL);
+ goto done;
+ }
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "utime() arg 2 must be a tuple (atime, mtime)");
+ goto done;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &atimesec, &ausec) == -1)
+ goto done;
+ time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &mtimesec, &musec) == -1)
+ goto done;
+ time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
+ }
+ if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
+ /* Avoid putting the file name into the error here,
+ as that may confuse the user into believing that
+ something is wrong with the file, when it also
+ could be the time stamp that gives a problem. */
+ win32_error("utime", NULL);
+ }
+ Py_INCREF(Py_None);
+ result = Py_None;
+done:
+ CloseHandle(hFile);
+ return result;
+#else /* Py_WIN_WIDE_FILENAMES */
+
+ char *path = NULL;
+ long atime, mtime, ausec, musec;
+ int res;
+ PyObject* arg;
+
+#if defined(HAVE_UTIMES)
+ struct timeval buf[2];
+#define ATIME buf[0].tv_sec
+#define MTIME buf[1].tv_sec
+#elif defined(HAVE_UTIME_H)
+/* XXX should define struct utimbuf instead, above */
+ struct utimbuf buf;
+#define ATIME buf.actime
+#define MTIME buf.modtime
+#define UTIME_ARG &buf
+#else /* HAVE_UTIMES */
+ time_t buf[2];
+#define ATIME buf[0]
+#define MTIME buf[1]
+#define UTIME_ARG buf
+#endif /* HAVE_UTIMES */
+
+
+ if (!PyArg_ParseTuple(args, "etO:utime",
+ Py_FileSystemDefaultEncoding, &path, &arg))
+ return NULL;
+ if (arg == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = utime(path, NULL);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "utime() arg 2 must be a tuple (atime, mtime)");
+ PyMem_Free(path);
+ return NULL;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &atime, &ausec) == -1) {
+ PyMem_Free(path);
+ return NULL;
+ }
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &mtime, &musec) == -1) {
+ PyMem_Free(path);
+ return NULL;
+ }
+ ATIME = atime;
+ MTIME = mtime;
+#ifdef HAVE_UTIMES
+ buf[0].tv_usec = ausec;
+ buf[1].tv_usec = musec;
+ Py_BEGIN_ALLOW_THREADS
+ res = utimes(path, buf);
+ Py_END_ALLOW_THREADS
+#else
+ Py_BEGIN_ALLOW_THREADS
+ res = utime(path, UTIME_ARG);
+ Py_END_ALLOW_THREADS
+#endif /* HAVE_UTIMES */
+ }
+ if (res < 0) {
+ return posix_error_with_allocated_filename(path);
+ }
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#undef UTIME_ARG
+#undef ATIME
+#undef MTIME
+#endif /* Py_WIN_WIDE_FILENAMES */
+}
+
+
+/* Process operations */
+
+PyDoc_STRVAR(posix__exit__doc__,
+"_exit(status)\n\n\
+Exit to the system with specified status, without normal exit processing.");
+
+static PyObject *
+posix__exit(PyObject *self, PyObject *args)
+{
+ int sts;
+ if (!PyArg_ParseTuple(args, "i:_exit", &sts))
+ return NULL;
+ _exit(sts);
+ return NULL; /* Make gcc -Wall happy */
+}
+
+#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
+static void
+free_string_array(char **array, Py_ssize_t count)
+{
+ Py_ssize_t i;
+ for (i = 0; i < count; i++)
+ PyMem_Free(array[i]);
+ PyMem_DEL(array);
+}
+#endif
+
+
+#ifdef HAVE_EXECV
+PyDoc_STRVAR(posix_execv__doc__,
+"execv(path, args)\n\n\
+Execute an executable path with arguments, replacing current process.\n\
+\n\
+ path: path of executable file\n\
+ args: tuple or list of strings");
+
+static PyObject *
+posix_execv(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv;
+ char **argvlist;
+ Py_ssize_t i, argc;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+ /* execv has two arguments: (path, argv), where
+ argv is a list or tuple of strings. */
+
+ if (!PyArg_ParseTuple(args, "etO:execv",
+ Py_FileSystemDefaultEncoding,
+ &path, &argv))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyMem_Free(path);
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i), "et",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i])) {
+ free_string_array(argvlist, i);
+ PyErr_SetString(PyExc_TypeError,
+ "execv() arg 2 must contain only strings");
+ PyMem_Free(path);
+ return NULL;
+
+ }
+ }
+ argvlist[argc] = NULL;
+
+ execv(path, argvlist);
+
+ /* If we get here it's definitely an error */
+
+ free_string_array(argvlist, argc);
+ PyMem_Free(path);
+ return posix_error();
+}
+
+
+PyDoc_STRVAR(posix_execve__doc__,
+"execve(path, args, env)\n\n\
+Execute a path with arguments and environment, replacing current process.\n\
+\n\
+ path: path of executable file\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_execve(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ PyObject *key, *val, *keys=NULL, *vals=NULL;
+ Py_ssize_t i, pos, argc, envc;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ Py_ssize_t lastarg = 0;
+
+ /* execve has three arguments: (path, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "etOO:execve",
+ Py_FileSystemDefaultEncoding,
+ &path, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "execve() arg 2 must be a tuple or list");
+ goto fail_0;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "execve() arg 3 must be a mapping object");
+ goto fail_0;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_0;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i),
+ "et;execve() arg 2 must contain only strings",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ i = PyMapping_Size(env);
+ if (i < 0)
+ goto fail_1;
+ envlist = PyMem_NEW(char *, i + 1);
+ if (envlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_1;
+ }
+ envc = 0;
+ keys = PyMapping_Keys(env);
+ vals = PyMapping_Values(env);
+ if (!keys || !vals)
+ goto fail_2;
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "execve(): env.keys() or env.values() is not a list");
+ goto fail_2;
+ }
+
+ for (pos = 0; pos < i; pos++) {
+ char *p, *k, *v;
+ size_t len;
+
+ key = PyList_GetItem(keys, pos);
+ val = PyList_GetItem(vals, pos);
+ if (!key || !val)
+ goto fail_2;
+
+ if (!PyArg_Parse(
+ key,
+ "s;execve() arg 3 contains a non-string key",
+ &k) ||
+ !PyArg_Parse(
+ val,
+ "s;execve() arg 3 contains a non-string value",
+ &v))
+ {
+ goto fail_2;
+ }
+
+#if defined(PYOS_OS2)
+ /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
+ if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
+#endif
+ len = PyString_Size(key) + PyString_Size(val) + 2;
+ p = PyMem_NEW(char, len);
+ if (p == NULL) {
+ PyErr_NoMemory();
+ goto fail_2;
+ }
+ PyOS_snprintf(p, len, "%s=%s", k, v);
+ envlist[envc++] = p;
+#if defined(PYOS_OS2)
+ }
+#endif
+ }
+ envlist[envc] = 0;
+
+ execve(path, argvlist, envlist);
+
+ /* If we get here it's definitely an error */
+
+ (void) posix_error();
+
+ fail_2:
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ Py_XDECREF(vals);
+ Py_XDECREF(keys);
+ fail_0:
+ PyMem_Free(path);
+ return NULL;
+}
+#endif /* HAVE_EXECV */
+
+
+#ifdef HAVE_SPAWNV
+PyDoc_STRVAR(posix_spawnv__doc__,
+"spawnv(mode, path, args)\n\n\
+Execute the program 'path' in a new process.\n\
+\n\
+ mode: mode of process creation\n\
+ path: path of executable file\n\
+ args: tuple or list of strings");
+
+static PyObject *
+posix_spawnv(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv;
+ char **argvlist;
+ int mode, i;
+ Py_ssize_t argc;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+ /* spawnv has three arguments: (mode, path, argv), where
+ argv is a list or tuple of strings. */
+
+ if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnv() arg 2 must be a tuple or list");
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyMem_Free(path);
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i), "et",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i])) {
+ free_string_array(argvlist, i);
+ PyErr_SetString(
+ PyExc_TypeError,
+ "spawnv() arg 2 must contain only strings");
+ PyMem_Free(path);
+ return NULL;
+ }
+ }
+ argvlist[argc] = NULL;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = spawnv(mode, path, argvlist);
+ Py_END_ALLOW_THREADS
+#else
+ if (mode == _OLD_P_OVERLAY)
+ mode = _P_OVERLAY;
+
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = _spawnv(mode, path, argvlist);
+ Py_END_ALLOW_THREADS
+#endif
+
+ free_string_array(argvlist, argc);
+ PyMem_Free(path);
+
+ if (spawnval == -1)
+ return posix_error();
+ else
+#if SIZEOF_LONG == SIZEOF_VOID_P
+ return Py_BuildValue("l", (long) spawnval);
+#else
+ return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_spawnve__doc__,
+"spawnve(mode, path, args, env)\n\n\
+Execute the program 'path' in a new process.\n\
+\n\
+ mode: mode of process creation\n\
+ path: path of executable file\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_spawnve(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
+ int mode, pos, envc;
+ Py_ssize_t argc, i;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ Py_ssize_t lastarg = 0;
+
+ /* spawnve has four arguments: (mode, path, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnve() arg 2 must be a tuple or list");
+ goto fail_0;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnve() arg 3 must be a mapping object");
+ goto fail_0;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_0;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i),
+ "et;spawnve() arg 2 must contain only strings",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ i = PyMapping_Size(env);
+ if (i < 0)
+ goto fail_1;
+ envlist = PyMem_NEW(char *, i + 1);
+ if (envlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_1;
+ }
+ envc = 0;
+ keys = PyMapping_Keys(env);
+ vals = PyMapping_Values(env);
+ if (!keys || !vals)
+ goto fail_2;
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnve(): env.keys() or env.values() is not a list");
+ goto fail_2;
+ }
+
+ for (pos = 0; pos < i; pos++) {
+ char *p, *k, *v;
+ size_t len;
+
+ key = PyList_GetItem(keys, pos);
+ val = PyList_GetItem(vals, pos);
+ if (!key || !val)
+ goto fail_2;
+
+ if (!PyArg_Parse(
+ key,
+ "s;spawnve() arg 3 contains a non-string key",
+ &k) ||
+ !PyArg_Parse(
+ val,
+ "s;spawnve() arg 3 contains a non-string value",
+ &v))
+ {
+ goto fail_2;
+ }
+ len = PyString_Size(key) + PyString_Size(val) + 2;
+ p = PyMem_NEW(char, len);
+ if (p == NULL) {
+ PyErr_NoMemory();
+ goto fail_2;
+ }
+ PyOS_snprintf(p, len, "%s=%s", k, v);
+ envlist[envc++] = p;
+ }
+ envlist[envc] = 0;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = spawnve(mode, path, argvlist, envlist);
+ Py_END_ALLOW_THREADS
+#else
+ if (mode == _OLD_P_OVERLAY)
+ mode = _P_OVERLAY;
+
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = _spawnve(mode, path, argvlist, envlist);
+ Py_END_ALLOW_THREADS
+#endif
+
+ if (spawnval == -1)
+ (void) posix_error();
+ else
+#if SIZEOF_LONG == SIZEOF_VOID_P
+ res = Py_BuildValue("l", (long) spawnval);
+#else
+ res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
+#endif
+
+ fail_2:
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ Py_XDECREF(vals);
+ Py_XDECREF(keys);
+ fail_0:
+ PyMem_Free(path);
+ return res;
+}
+
+/* OS/2 supports spawnvp & spawnvpe natively */
+#if defined(PYOS_OS2)
+PyDoc_STRVAR(posix_spawnvp__doc__,
+"spawnvp(mode, file, args)\n\n\
+Execute the program 'file' in a new process, using the environment\n\
+search path to find the file.\n\
+\n\
+ mode: mode of process creation\n\
+ file: executable file name\n\
+ args: tuple or list of strings");
+
+static PyObject *
+posix_spawnvp(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv;
+ char **argvlist;
+ int mode, i, argc;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+ /* spawnvp has three arguments: (mode, path, argv), where
+ argv is a list or tuple of strings. */
+
+ if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvp() arg 2 must be a tuple or list");
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyMem_Free(path);
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i), "et",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i])) {
+ free_string_array(argvlist, i);
+ PyErr_SetString(
+ PyExc_TypeError,
+ "spawnvp() arg 2 must contain only strings");
+ PyMem_Free(path);
+ return NULL;
+ }
+ }
+ argvlist[argc] = NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(PYCC_GCC)
+ spawnval = spawnvp(mode, path, argvlist);
+#else
+ spawnval = _spawnvp(mode, path, argvlist);
+#endif
+ Py_END_ALLOW_THREADS
+
+ free_string_array(argvlist, argc);
+ PyMem_Free(path);
+
+ if (spawnval == -1)
+ return posix_error();
+ else
+ return Py_BuildValue("l", (long) spawnval);
+}
+
+
+PyDoc_STRVAR(posix_spawnvpe__doc__,
+"spawnvpe(mode, file, args, env)\n\n\
+Execute the program 'file' in a new process, using the environment\n\
+search path to find the file.\n\
+\n\
+ mode: mode of process creation\n\
+ file: executable file name\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_spawnvpe(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
+ int mode, i, pos, argc, envc;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ int lastarg = 0;
+
+ /* spawnvpe has four arguments: (mode, path, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvpe() arg 2 must be a tuple or list");
+ goto fail_0;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvpe() arg 3 must be a mapping object");
+ goto fail_0;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_0;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i),
+ "et;spawnvpe() arg 2 must contain only strings",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ i = PyMapping_Size(env);
+ if (i < 0)
+ goto fail_1;
+ envlist = PyMem_NEW(char *, i + 1);
+ if (envlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_1;
+ }
+ envc = 0;
+ keys = PyMapping_Keys(env);
+ vals = PyMapping_Values(env);
+ if (!keys || !vals)
+ goto fail_2;
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvpe(): env.keys() or env.values() is not a list");
+ goto fail_2;
+ }
+
+ for (pos = 0; pos < i; pos++) {
+ char *p, *k, *v;
+ size_t len;
+
+ key = PyList_GetItem(keys, pos);
+ val = PyList_GetItem(vals, pos);
+ if (!key || !val)
+ goto fail_2;
+
+ if (!PyArg_Parse(
+ key,
+ "s;spawnvpe() arg 3 contains a non-string key",
+ &k) ||
+ !PyArg_Parse(
+ val,
+ "s;spawnvpe() arg 3 contains a non-string value",
+ &v))
+ {
+ goto fail_2;
+ }
+ len = PyString_Size(key) + PyString_Size(val) + 2;
+ p = PyMem_NEW(char, len);
+ if (p == NULL) {
+ PyErr_NoMemory();
+ goto fail_2;
+ }
+ PyOS_snprintf(p, len, "%s=%s", k, v);
+ envlist[envc++] = p;
+ }
+ envlist[envc] = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(PYCC_GCC)
+ spawnval = spawnve(mode, path, argvlist, envlist);
+#else
+ spawnval = _spawnve(mode, path, argvlist, envlist);
+#endif
+ Py_END_ALLOW_THREADS
+
+ if (spawnval == -1)
+ (void) posix_error();
+ else
+ res = Py_BuildValue("l", (long) spawnval);
+
+ fail_2:
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ Py_XDECREF(vals);
+ Py_XDECREF(keys);
+ fail_0:
+ PyMem_Free(path);
+ return res;
+}
+#endif /* PYOS_OS2 */
+#endif /* HAVE_SPAWNV */
+
+
+#ifdef HAVE_FORK1
+PyDoc_STRVAR(posix_fork1__doc__,
+"fork1() -> pid\n\n\
+Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
+\n\
+Return 0 to child process and PID of child to parent process.");
+
+static PyObject *
+posix_fork1(PyObject *self, PyObject *noargs)
+{
+ int pid = fork1();
+ if (pid == -1)
+ return posix_error();
+ PyOS_AfterFork();
+ return PyInt_FromLong((long)pid);
+}
+#endif
+
+
+#ifdef HAVE_FORK
+PyDoc_STRVAR(posix_fork__doc__,
+"fork() -> pid\n\n\
+Fork a child process.\n\
+Return 0 to child process and PID of child to parent process.");
+
+static PyObject *
+posix_fork(PyObject *self, PyObject *noargs)
+{
+ int pid = fork();
+ if (pid == -1)
+ return posix_error();
+ if (pid == 0)
+ PyOS_AfterFork();
+ return PyInt_FromLong((long)pid);
+}
+#endif
+
+/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
+/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
+#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
+#define DEV_PTY_FILE "/dev/ptc"
+#define HAVE_DEV_PTMX
+#else
+#define DEV_PTY_FILE "/dev/ptmx"
+#endif
+
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#else
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h>
+#endif /* HAVE_LIBUTIL_H */
+#endif /* HAVE_PTY_H */
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
+
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
+PyDoc_STRVAR(posix_openpty__doc__,
+"openpty() -> (master_fd, slave_fd)\n\n\
+Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
+
+static PyObject *
+posix_openpty(PyObject *self, PyObject *noargs)
+{
+ int master_fd, slave_fd;
+#ifndef HAVE_OPENPTY
+ char * slave_name;
+#endif
+#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
+ PyOS_sighandler_t sig_saved;
+#ifdef sun
+ extern char *ptsname(int fildes);
+#endif
+#endif
+
+#ifdef HAVE_OPENPTY
+ if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
+ return posix_error();
+#elif defined(HAVE__GETPTY)
+ slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
+ if (slave_name == NULL)
+ return posix_error();
+
+ slave_fd = open(slave_name, O_RDWR);
+ if (slave_fd < 0)
+ return posix_error();
+#else
+ master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
+ if (master_fd < 0)
+ return posix_error();
+ sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
+ /* change permission of slave */
+ if (grantpt(master_fd) < 0) {
+ PyOS_setsig(SIGCHLD, sig_saved);
+ return posix_error();
+ }
+ /* unlock slave */
+ if (unlockpt(master_fd) < 0) {
+ PyOS_setsig(SIGCHLD, sig_saved);
+ return posix_error();
+ }
+ PyOS_setsig(SIGCHLD, sig_saved);
+ slave_name = ptsname(master_fd); /* get name of slave */
+ if (slave_name == NULL)
+ return posix_error();
+ slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
+ if (slave_fd < 0)
+ return posix_error();
+#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
+ ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
+ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
+#ifndef __hpux
+ ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
+#endif /* __hpux */
+#endif /* HAVE_CYGWIN */
+#endif /* HAVE_OPENPTY */
+
+ return Py_BuildValue("(ii)", master_fd, slave_fd);
+
+}
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
+
+#ifdef HAVE_FORKPTY
+PyDoc_STRVAR(posix_forkpty__doc__,
+"forkpty() -> (pid, master_fd)\n\n\
+Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
+Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
+To both, return fd of newly opened pseudo-terminal.\n");
+
+static PyObject *
+posix_forkpty(PyObject *self, PyObject *noargs)
+{
+ int master_fd = -1, pid;
+
+ pid = forkpty(&master_fd, NULL, NULL, NULL);
+ if (pid == -1)
+ return posix_error();
+ if (pid == 0)
+ PyOS_AfterFork();
+ return Py_BuildValue("(ii)", pid, master_fd);
+}
+#endif
+
+#ifdef HAVE_GETEGID
+PyDoc_STRVAR(posix_getegid__doc__,
+"getegid() -> egid\n\n\
+Return the current process's effective group id.");
+
+static PyObject *
+posix_getegid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getegid());
+}
+#endif
+
+
+#ifdef HAVE_GETEUID
+PyDoc_STRVAR(posix_geteuid__doc__,
+"geteuid() -> euid\n\n\
+Return the current process's effective user id.");
+
+static PyObject *
+posix_geteuid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)geteuid());
+}
+#endif
+
+
+#ifdef HAVE_GETGID
+PyDoc_STRVAR(posix_getgid__doc__,
+"getgid() -> gid\n\n\
+Return the current process's group id.");
+
+static PyObject *
+posix_getgid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getgid());
+}
+#endif
+
+
+PyDoc_STRVAR(posix_getpid__doc__,
+"getpid() -> pid\n\n\
+Return the current process id");
+
+static PyObject *
+posix_getpid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getpid());
+}
+
+
+#ifdef HAVE_GETGROUPS
+PyDoc_STRVAR(posix_getgroups__doc__,
+"getgroups() -> list of group IDs\n\n\
+Return list of supplemental group IDs for the process.");
+
+static PyObject *
+posix_getgroups(PyObject *self, PyObject *noargs)
+{
+ PyObject *result = NULL;
+
+#ifdef NGROUPS_MAX
+#define MAX_GROUPS NGROUPS_MAX
+#else
+ /* defined to be 16 on Solaris7, so this should be a small number */
+#define MAX_GROUPS 64
+#endif
+ gid_t grouplist[MAX_GROUPS];
+ int n;
+
+ n = getgroups(MAX_GROUPS, grouplist);
+ if (n < 0)
+ posix_error();
+ else {
+ result = PyList_New(n);
+ if (result != NULL) {
+ int i;
+ for (i = 0; i < n; ++i) {
+ PyObject *o = PyInt_FromLong((long)grouplist[i]);
+ if (o == NULL) {
+ Py_DECREF(result);
+ result = NULL;
+ break;
+ }
+ PyList_SET_ITEM(result, i, o);
+ }
+ }
+ }
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_GETPGID
+PyDoc_STRVAR(posix_getpgid__doc__,
+"getpgid(pid) -> pgid\n\n\
+Call the system call getpgid().");
+
+static PyObject *
+posix_getpgid(PyObject *self, PyObject *args)
+{
+ int pid, pgid;
+ if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
+ return NULL;
+ pgid = getpgid(pid);
+ if (pgid < 0)
+ return posix_error();
+ return PyInt_FromLong((long)pgid);
+}
+#endif /* HAVE_GETPGID */
+
+
+#ifdef HAVE_GETPGRP
+PyDoc_STRVAR(posix_getpgrp__doc__,
+"getpgrp() -> pgrp\n\n\
+Return the current process group id.");
+
+static PyObject *
+posix_getpgrp(PyObject *self, PyObject *noargs)
+{
+#ifdef GETPGRP_HAVE_ARG
+ return PyInt_FromLong((long)getpgrp(0));
+#else /* GETPGRP_HAVE_ARG */
+ return PyInt_FromLong((long)getpgrp());
+#endif /* GETPGRP_HAVE_ARG */
+}
+#endif /* HAVE_GETPGRP */
+
+
+#ifdef HAVE_SETPGRP
+PyDoc_STRVAR(posix_setpgrp__doc__,
+"setpgrp()\n\n\
+Make this process a session leader.");
+
+static PyObject *
+posix_setpgrp(PyObject *self, PyObject *noargs)
+{
+#ifdef SETPGRP_HAVE_ARG
+ if (setpgrp(0, 0) < 0)
+#else /* SETPGRP_HAVE_ARG */
+ if (setpgrp() < 0)
+#endif /* SETPGRP_HAVE_ARG */
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#endif /* HAVE_SETPGRP */
+
+#ifdef HAVE_GETPPID
+PyDoc_STRVAR(posix_getppid__doc__,
+"getppid() -> ppid\n\n\
+Return the parent's process id.");
+
+static PyObject *
+posix_getppid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getppid());
+}
+#endif
+
+
+#ifdef HAVE_GETLOGIN
+PyDoc_STRVAR(posix_getlogin__doc__,
+"getlogin() -> string\n\n\
+Return the actual login name.");
+
+static PyObject *
+posix_getlogin(PyObject *self, PyObject *noargs)
+{
+ PyObject *result = NULL;
+ char *name;
+ int old_errno = errno;
+
+ errno = 0;
+ name = getlogin();
+ if (name == NULL) {
+ if (errno)
+ posix_error();
+ else
+ PyErr_SetString(PyExc_OSError,
+ "unable to determine login name");
+ }
+ else
+ result = PyString_FromString(name);
+ errno = old_errno;
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_GETUID
+PyDoc_STRVAR(posix_getuid__doc__,
+"getuid() -> uid\n\n\
+Return the current process's user id.");
+
+static PyObject *
+posix_getuid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getuid());
+}
+#endif
+
+
+#ifdef HAVE_KILL
+PyDoc_STRVAR(posix_kill__doc__,
+"kill(pid, sig)\n\n\
+Kill a process with a signal.");
+
+static PyObject *
+posix_kill(PyObject *self, PyObject *args)
+{
+ int pid, sig;
+ if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
+ return NULL;
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+ if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
+ APIRET rc;
+ if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
+ return os2_error(rc);
+
+ } else if (sig == XCPT_SIGNAL_KILLPROC) {
+ APIRET rc;
+ if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
+ return os2_error(rc);
+
+ } else
+ return NULL; /* Unrecognized Signal Requested */
+#else
+ if (kill(pid, sig) == -1)
+ return posix_error();
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_KILLPG
+PyDoc_STRVAR(posix_killpg__doc__,
+"killpg(pgid, sig)\n\n\
+Kill a process group with a signal.");
+
+static PyObject *
+posix_killpg(PyObject *self, PyObject *args)
+{
+ int pgid, sig;
+ if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
+ return NULL;
+ if (killpg(pgid, sig) == -1)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_PLOCK
+
+#ifdef HAVE_SYS_LOCK_H
+#include <sys/lock.h>
+#endif
+
+PyDoc_STRVAR(posix_plock__doc__,
+"plock(op)\n\n\
+Lock program segments into memory.");
+
+static PyObject *
+posix_plock(PyObject *self, PyObject *args)
+{
+ int op;
+ if (!PyArg_ParseTuple(args, "i:plock", &op))
+ return NULL;
+ if (plock(op) == -1)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+
+#ifdef HAVE_POPEN
+PyDoc_STRVAR(posix_popen__doc__,
+"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
+Open a pipe to/from a command returning a file object.");
+
+#if defined(PYOS_OS2)
+#if defined(PYCC_VACPP)
+static int
+async_system(const char *command)
+{
+ char errormsg[256], args[1024];
+ RESULTCODES rcodes;
+ APIRET rc;
+
+ char *shell = getenv("COMSPEC");
+ if (!shell)
+ shell = "cmd";
+
+ /* avoid overflowing the argument buffer */
+ if (strlen(shell) + 3 + strlen(command) >= 1024)
+ return ERROR_NOT_ENOUGH_MEMORY
+
+ args[0] = '\0';
+ strcat(args, shell);
+ strcat(args, "/c ");
+ strcat(args, command);
+
+ /* execute asynchronously, inheriting the environment */
+ rc = DosExecPgm(errormsg,
+ sizeof(errormsg),
+ EXEC_ASYNC,
+ args,
+ NULL,
+ &rcodes,
+ shell);
+ return rc;
+}
+
+static FILE *
+popen(const char *command, const char *mode, int pipesize, int *err)
+{
+ int oldfd, tgtfd;
+ HFILE pipeh[2];
+ APIRET rc;
+
+ /* mode determines which of stdin or stdout is reconnected to
+ * the pipe to the child
+ */
+ if (strchr(mode, 'r') != NULL) {
+ tgt_fd = 1; /* stdout */
+ } else if (strchr(mode, 'w')) {
+ tgt_fd = 0; /* stdin */
+ } else {
+ *err = ERROR_INVALID_ACCESS;
+ return NULL;
+ }
+
+ /* setup the pipe */
+ if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
+ *err = rc;
+ return NULL;
+ }
+
+ /* prevent other threads accessing stdio */
+ DosEnterCritSec();
+
+ /* reconnect stdio and execute child */
+ oldfd = dup(tgtfd);
+ close(tgtfd);
+ if (dup2(pipeh[tgtfd], tgtfd) == 0) {
+ DosClose(pipeh[tgtfd]);
+ rc = async_system(command);
+ }
+
+ /* restore stdio */
+ dup2(oldfd, tgtfd);
+ close(oldfd);
+
+ /* allow other threads access to stdio */
+ DosExitCritSec();
+
+ /* if execution of child was successful return file stream */
+ if (rc == NO_ERROR)
+ return fdopen(pipeh[1 - tgtfd], mode);
+ else {
+ DosClose(pipeh[1 - tgtfd]);
+ *err = rc;
+ return NULL;
+ }
+}
+
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *mode = "r";
+ int err, bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return os2_error(err);
+
+ f = PyFile_FromFile(fp, name, mode, fclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+#elif defined(PYCC_GCC)
+
+/* standard posix version of popen() support */
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *mode = "r";
+ int bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ fp = popen(name, mode);
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return posix_error();
+ f = PyFile_FromFile(fp, name, mode, pclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+/* fork() under OS/2 has lots'o'warts
+ * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
+ * most of this code is a ripoff of the win32 code, but using the
+ * capabilities of EMX's C library routines
+ */
+
+/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
+#define POPEN_1 1
+#define POPEN_2 2
+#define POPEN_3 3
+#define POPEN_4 4
+
+static PyObject *_PyPopen(char *, int, int, int);
+static int _PyPclose(FILE *file);
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code. See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static PyObject *_PyPopenProcs = NULL;
+
+/* os2emx version of popen2()
+ *
+ * The result of this function is a pipe (file) connected to the
+ * process's stdin, and a pipe connected to the process's stdout.
+ */
+
+static PyObject *
+os2emx_popen2(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm=0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = O_BINARY;
+
+ f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
+
+ return f;
+}
+
+/*
+ * Variation on os2emx.popen2
+ *
+ * The result of this function is 3 pipes - the process's stdin,
+ * stdout and stderr
+ */
+
+static PyObject *
+os2emx_popen3(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = O_BINARY;
+
+ f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
+
+ return f;
+}
+
+/*
+ * Variation on os2emx.popen2
+ *
+ * The result of this function is 2 pipes - the processes stdin,
+ * and stdout+stderr combined as a single pipe.
+ */
+
+static PyObject *
+os2emx_popen4(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = O_BINARY;
+
+ f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
+
+ return f;
+}
+
+/* a couple of structures for convenient handling of multiple
+ * file handles and pipes
+ */
+struct file_ref
+{
+ int handle;
+ int flags;
+};
+
+struct pipe_ref
+{
+ int rd;
+ int wr;
+};
+
+/* The following code is derived from the win32 code */
+
+static PyObject *
+_PyPopen(char *cmdstring, int mode, int n, int bufsize)
+{
+ struct file_ref stdio[3];
+ struct pipe_ref p_fd[3];
+ FILE *p_s[3];
+ int file_count, i, pipe_err, pipe_pid;
+ char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
+ PyObject *f, *p_f[3];
+
+ /* file modes for subsequent fdopen's on pipe handles */
+ if (mode == O_TEXT)
+ {
+ rd_mode = "rt";
+ wr_mode = "wt";
+ }
+ else
+ {
+ rd_mode = "rb";
+ wr_mode = "wb";
+ }
+
+ /* prepare shell references */
+ if ((shell = getenv("EMXSHELL")) == NULL)
+ if ((shell = getenv("COMSPEC")) == NULL)
+ {
+ errno = ENOENT;
+ return posix_error();
+ }
+
+ sh_name = _getname(shell);
+ if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
+ opt = "/c";
+ else
+ opt = "-c";
+
+ /* save current stdio fds + their flags, and set not inheritable */
+ i = pipe_err = 0;
+ while (pipe_err >= 0 && i < 3)
+ {
+ pipe_err = stdio[i].handle = dup(i);
+ stdio[i].flags = fcntl(i, F_GETFD, 0);
+ fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
+ i++;
+ }
+ if (pipe_err < 0)
+ {
+ /* didn't get them all saved - clean up and bail out */
+ int saved_err = errno;
+ while (i-- > 0)
+ {
+ close(stdio[i].handle);
+ }
+ errno = saved_err;
+ return posix_error();
+ }
+
+ /* create pipe ends */
+ file_count = 2;
+ if (n == POPEN_3)
+ file_count = 3;
+ i = pipe_err = 0;
+ while ((pipe_err == 0) && (i < file_count))
+ pipe_err = pipe((int *)&p_fd[i++]);
+ if (pipe_err < 0)
+ {
+ /* didn't get them all made - clean up and bail out */
+ while (i-- > 0)
+ {
+ close(p_fd[i].wr);
+ close(p_fd[i].rd);
+ }
+ errno = EPIPE;
+ return posix_error();
+ }
+
+ /* change the actual standard IO streams over temporarily,
+ * making the retained pipe ends non-inheritable
+ */
+ pipe_err = 0;
+
+ /* - stdin */
+ if (dup2(p_fd[0].rd, 0) == 0)
+ {
+ close(p_fd[0].rd);
+ i = fcntl(p_fd[0].wr, F_GETFD, 0);
+ fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
+ if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
+ {
+ close(p_fd[0].wr);
+ pipe_err = -1;
+ }
+ }
+ else
+ {
+ pipe_err = -1;
+ }
+
+ /* - stdout */
+ if (pipe_err == 0)
+ {
+ if (dup2(p_fd[1].wr, 1) == 1)
+ {
+ close(p_fd[1].wr);
+ i = fcntl(p_fd[1].rd, F_GETFD, 0);
+ fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
+ if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
+ {
+ close(p_fd[1].rd);
+ pipe_err = -1;
+ }
+ }
+ else
+ {
+ pipe_err = -1;
+ }
+ }
+
+ /* - stderr, as required */
+ if (pipe_err == 0)
+ switch (n)
+ {
+ case POPEN_3:
+ {
+ if (dup2(p_fd[2].wr, 2) == 2)
+ {
+ close(p_fd[2].wr);
+ i = fcntl(p_fd[2].rd, F_GETFD, 0);
+ fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
+ if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
+ {
+ close(p_fd[2].rd);
+ pipe_err = -1;
+ }
+ }
+ else
+ {
+ pipe_err = -1;
+ }
+ break;
+ }
+
+ case POPEN_4:
+ {
+ if (dup2(1, 2) != 2)
+ {
+ pipe_err = -1;
+ }
+ break;
+ }
+ }
+
+ /* spawn the child process */
+ if (pipe_err == 0)
+ {
+ pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
+ if (pipe_pid == -1)
+ {
+ pipe_err = -1;
+ }
+ else
+ {
+ /* save the PID into the FILE structure
+ * NOTE: this implementation doesn't actually
+ * take advantage of this, but do it for
+ * completeness - AIM Apr01
+ */
+ for (i = 0; i < file_count; i++)
+ p_s[i]->_pid = pipe_pid;
+ }
+ }
+
+ /* reset standard IO to normal */
+ for (i = 0; i < 3; i++)
+ {
+ dup2(stdio[i].handle, i);
+ fcntl(i, F_SETFD, stdio[i].flags);
+ close(stdio[i].handle);
+ }
+
+ /* if any remnant problems, clean up and bail out */
+ if (pipe_err < 0)
+ {
+ for (i = 0; i < 3; i++)
+ {
+ close(p_fd[i].rd);
+ close(p_fd[i].wr);
+ }
+ errno = EPIPE;
+ return posix_error_with_filename(cmdstring);
+ }
+
+ /* build tuple of file objects to return */
+ if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
+ PyFile_SetBufSize(p_f[0], bufsize);
+ if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
+ PyFile_SetBufSize(p_f[1], bufsize);
+ if (n == POPEN_3)
+ {
+ if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
+ PyFile_SetBufSize(p_f[0], bufsize);
+ f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
+ }
+ else
+ f = PyTuple_Pack(2, p_f[0], p_f[1]);
+
+ /*
+ * Insert the files we've created into the process dictionary
+ * all referencing the list with the process handle and the
+ * initial number of files (see description below in _PyPclose).
+ * Since if _PyPclose later tried to wait on a process when all
+ * handles weren't closed, it could create a deadlock with the
+ * child, we spend some energy here to try to ensure that we
+ * either insert all file handles into the dictionary or none
+ * at all. It's a little clumsy with the various popen modes
+ * and variable number of files involved.
+ */
+ if (!_PyPopenProcs)
+ {
+ _PyPopenProcs = PyDict_New();
+ }
+
+ if (_PyPopenProcs)
+ {
+ PyObject *procObj, *pidObj, *intObj, *fileObj[3];
+ int ins_rc[3];
+
+ fileObj[0] = fileObj[1] = fileObj[2] = NULL;
+ ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
+
+ procObj = PyList_New(2);
+ pidObj = PyInt_FromLong((long) pipe_pid);
+ intObj = PyInt_FromLong((long) file_count);
+
+ if (procObj && pidObj && intObj)
+ {
+ PyList_SetItem(procObj, 0, pidObj);
+ PyList_SetItem(procObj, 1, intObj);
+
+ fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
+ if (fileObj[0])
+ {
+ ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[0],
+ procObj);
+ }
+ fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
+ if (fileObj[1])
+ {
+ ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[1],
+ procObj);
+ }
+ if (file_count >= 3)
+ {
+ fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
+ if (fileObj[2])
+ {
+ ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[2],
+ procObj);
+ }
+ }
+
+ if (ins_rc[0] < 0 || !fileObj[0] ||
+ ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
+ ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
+ {
+ /* Something failed - remove any dictionary
+ * entries that did make it.
+ */
+ if (!ins_rc[0] && fileObj[0])
+ {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[0]);
+ }
+ if (!ins_rc[1] && fileObj[1])
+ {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[1]);
+ }
+ if (!ins_rc[2] && fileObj[2])
+ {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[2]);
+ }
+ }
+ }
+
+ /*
+ * Clean up our localized references for the dictionary keys
+ * and value since PyDict_SetItem will Py_INCREF any copies
+ * that got placed in the dictionary.
+ */
+ Py_XDECREF(procObj);
+ Py_XDECREF(fileObj[0]);
+ Py_XDECREF(fileObj[1]);
+ Py_XDECREF(fileObj[2]);
+ }
+
+ /* Child is launched. */
+ return f;
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file. On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation. This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
+ */
+
+static int _PyPclose(FILE *file)
+{
+ int result;
+ int exit_code;
+ int pipe_pid;
+ PyObject *procObj, *pidObj, *intObj, *fileObj;
+ int file_count;
+#ifdef WITH_THREAD
+ PyGILState_STATE state;
+#endif
+
+ /* Close the file handle first, to ensure it can't block the
+ * child from exiting if it's the last handle.
+ */
+ result = fclose(file);
+
+#ifdef WITH_THREAD
+ state = PyGILState_Ensure();
+#endif
+ if (_PyPopenProcs)
+ {
+ if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
+ (procObj = PyDict_GetItem(_PyPopenProcs,
+ fileObj)) != NULL &&
+ (pidObj = PyList_GetItem(procObj,0)) != NULL &&
+ (intObj = PyList_GetItem(procObj,1)) != NULL)
+ {
+ pipe_pid = (int) PyInt_AsLong(pidObj);
+ file_count = (int) PyInt_AsLong(intObj);
+
+ if (file_count > 1)
+ {
+ /* Still other files referencing process */
+ file_count--;
+ PyList_SetItem(procObj,1,
+ PyInt_FromLong((long) file_count));
+ }
+ else
+ {
+ /* Last file for this process */
+ if (result != EOF &&
+ waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
+ {
+ /* extract exit status */
+ if (WIFEXITED(exit_code))
+ {
+ result = WEXITSTATUS(exit_code);
+ }
+ else
+ {
+ errno = EPIPE;
+ result = -1;
+ }
+ }
+ else
+ {
+ /* Indicate failure - this will cause the file object
+ * to raise an I/O error and translate the last
+ * error code from errno. We do have a problem with
+ * last errors that overlap the normal errno table,
+ * but that's a consistent problem with the file object.
+ */
+ result = -1;
+ }
+ }
+
+ /* Remove this file pointer from dictionary */
+ PyDict_DelItem(_PyPopenProcs, fileObj);
+
+ if (PyDict_Size(_PyPopenProcs) == 0)
+ {
+ Py_DECREF(_PyPopenProcs);
+ _PyPopenProcs = NULL;
+ }
+
+ } /* if object retrieval ok */
+
+ Py_XDECREF(fileObj);
+ } /* if _PyPopenProcs */
+
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+ return result;
+}
+
+#endif /* PYCC_??? */
+
+#elif defined(MS_WINDOWS)
+
+/*
+ * Portable 'popen' replacement for Win32.
+ *
+ * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
+ * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
+ * Return code handling by David Bolen <db3l@fitlinxx.com>.
+ */
+
+#include <malloc.h>
+#include <io.h>
+#include <fcntl.h>
+
+/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
+#define POPEN_1 1
+#define POPEN_2 2
+#define POPEN_3 3
+#define POPEN_4 4
+
+static PyObject *_PyPopen(char *, int, int);
+static int _PyPclose(FILE *file);
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code. See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static PyObject *_PyPopenProcs = NULL;
+
+
+/* popen that works from a GUI.
+ *
+ * The result of this function is a pipe (file) connected to the
+ * processes stdin or stdout, depending on the requested mode.
+ */
+
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "r";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 'r')
+ tm = _O_RDONLY;
+ else if (*mode != 'w') {
+ PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
+ return NULL;
+ } else
+ tm = _O_WRONLY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
+ return NULL;
+ }
+
+ if (*(mode+1) == 't')
+ f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
+ else if (*(mode+1) == 'b')
+ f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
+ else
+ f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
+
+ return f;
+}
+
+/* Variation on win32pipe.popen
+ *
+ * The result of this function is a pipe (file) connected to the
+ * process's stdin, and a pipe connected to the process's stdout.
+ */
+
+static PyObject *
+win32_popen2(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm=0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = _O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = _O_BINARY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
+ return NULL;
+ }
+
+ f = _PyPopen(cmdstring, tm, POPEN_2);
+
+ return f;
+}
+
+/*
+ * Variation on <om win32pipe.popen>
+ *
+ * The result of this function is 3 pipes - the process's stdin,
+ * stdout and stderr
+ */
+
+static PyObject *
+win32_popen3(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = _O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = _O_BINARY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
+ return NULL;
+ }
+
+ f = _PyPopen(cmdstring, tm, POPEN_3);
+
+ return f;
+}
+
+/*
+ * Variation on win32pipe.popen
+ *
+ * The result of this function is 2 pipes - the processes stdin,
+ * and stdout+stderr combined as a single pipe.
+ */
+
+static PyObject *
+win32_popen4(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = _O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = _O_BINARY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
+ return NULL;
+ }
+
+ f = _PyPopen(cmdstring, tm, POPEN_4);
+
+ return f;
+}
+
+static BOOL
+_PyPopenCreateProcess(char *cmdstring,
+ HANDLE hStdin,
+ HANDLE hStdout,
+ HANDLE hStderr,
+ HANDLE *hProcess)
+{
+ PROCESS_INFORMATION piProcInfo;
+ STARTUPINFO siStartInfo;
+ DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
+ char *s1,*s2, *s3 = " /c ";
+ const char *szConsoleSpawn = "w9xpopen.exe";
+ int i;
+ Py_ssize_t x;
+
+ if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
+ char *comshell;
+
+ s1 = (char *)alloca(i);
+ if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
+ /* x < i, so x fits into an integer */
+ return (int)x;
+
+ /* Explicitly check if we are using COMMAND.COM. If we are
+ * then use the w9xpopen hack.
+ */
+ comshell = s1 + x;
+ while (comshell >= s1 && *comshell != '\\')
+ --comshell;
+ ++comshell;
+
+ if (GetVersion() < 0x80000000 &&
+ _stricmp(comshell, "command.com") != 0) {
+ /* NT/2000 and not using command.com. */
+ x = i + strlen(s3) + strlen(cmdstring) + 1;
+ s2 = (char *)alloca(x);
+ ZeroMemory(s2, x);
+ PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
+ }
+ else {
+ /*
+ * Oh gag, we're on Win9x or using COMMAND.COM. Use
+ * the workaround listed in KB: Q150956
+ */
+ char modulepath[_MAX_PATH];
+ struct stat statinfo;
+ GetModuleFileName(NULL, modulepath, sizeof(modulepath));
+ for (x = i = 0; modulepath[i]; i++)
+ if (modulepath[i] == SEP)
+ x = i+1;
+ modulepath[x] = '\0';
+ /* Create the full-name to w9xpopen, so we can test it exists */
+ strncat(modulepath,
+ szConsoleSpawn,
+ (sizeof(modulepath)/sizeof(modulepath[0]))
+ -strlen(modulepath));
+ if (stat(modulepath, &statinfo) != 0) {
+ /* Eeek - file-not-found - possibly an embedding
+ situation - see if we can locate it in sys.prefix
+ */
+ strncpy(modulepath,
+ Py_GetExecPrefix(),
+ sizeof(modulepath)/sizeof(modulepath[0]));
+ if (modulepath[strlen(modulepath)-1] != '\\')
+ strcat(modulepath, "\\");
+ strncat(modulepath,
+ szConsoleSpawn,
+ (sizeof(modulepath)/sizeof(modulepath[0]))
+ -strlen(modulepath));
+ /* No where else to look - raise an easily identifiable
+ error, rather than leaving Windows to report
+ "file not found" - as the user is probably blissfully
+ unaware this shim EXE is used, and it will confuse them.
+ (well, it confused me for a while ;-)
+ */
+ if (stat(modulepath, &statinfo) != 0) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Can not locate '%s' which is needed "
+ "for popen to work with your shell "
+ "or platform.",
+ szConsoleSpawn);
+ return FALSE;
+ }
+ }
+ x = i + strlen(s3) + strlen(cmdstring) + 1 +
+ strlen(modulepath) +
+ strlen(szConsoleSpawn) + 1;
+
+ s2 = (char *)alloca(x);
+ ZeroMemory(s2, x);
+ /* To maintain correct argument passing semantics,
+ we pass the command-line as it stands, and allow
+ quoting to be applied. w9xpopen.exe will then
+ use its argv vector, and re-quote the necessary
+ args for the ultimate child process.
+ */
+ PyOS_snprintf(
+ s2, x,
+ "\"%s\" %s%s%s",
+ modulepath,
+ s1,
+ s3,
+ cmdstring);
+ /* Not passing CREATE_NEW_CONSOLE has been known to
+ cause random failures on win9x. Specifically a
+ dialog:
+ "Your program accessed mem currently in use at xxx"
+ and a hopeful warning about the stability of your
+ system.
+ Cost is Ctrl+C wont kill children, but anyone
+ who cares can have a go!
+ */
+ dwProcessFlags |= CREATE_NEW_CONSOLE;
+ }
+ }
+
+ /* Could be an else here to try cmd.exe / command.com in the path
+ Now we'll just error out.. */
+ else {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Cannot locate a COMSPEC environment variable to "
+ "use as the shell");
+ return FALSE;
+ }
+
+ ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
+ siStartInfo.cb = sizeof(STARTUPINFO);
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ siStartInfo.hStdInput = hStdin;
+ siStartInfo.hStdOutput = hStdout;
+ siStartInfo.hStdError = hStderr;
+ siStartInfo.wShowWindow = SW_HIDE;
+
+ if (CreateProcess(NULL,
+ s2,
+ NULL,
+ NULL,
+ TRUE,
+ dwProcessFlags,
+ NULL,
+ NULL,
+ &siStartInfo,
+ &piProcInfo) ) {
+ /* Close the handles now so anyone waiting is woken. */
+ CloseHandle(piProcInfo.hThread);
+
+ /* Return process handle */
+ *hProcess = piProcInfo.hProcess;
+ return TRUE;
+ }
+ win32_error("CreateProcess", s2);
+ return FALSE;
+}
+
+/* The following code is based off of KB: Q190351 */
+
+static PyObject *
+_PyPopen(char *cmdstring, int mode, int n)
+{
+ HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
+ hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
+ hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
+
+ SECURITY_ATTRIBUTES saAttr;
+ BOOL fSuccess;
+ int fd1, fd2, fd3;
+ FILE *f1, *f2, *f3;
+ long file_count;
+ PyObject *f;
+
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
+ return win32_error("CreatePipe", NULL);
+
+ /* Create new output read handle and the input write handle. Set
+ * the inheritance properties to FALSE. Otherwise, the child inherits
+ * these handles; resulting in non-closeable handles to the pipes
+ * being created. */
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
+ GetCurrentProcess(), &hChildStdinWrDup, 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ return win32_error("DuplicateHandle", NULL);
+
+ /* Close the inheritable version of ChildStdin
+ that we're using. */
+ CloseHandle(hChildStdinWr);
+
+ if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
+ return win32_error("CreatePipe", NULL);
+
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
+ GetCurrentProcess(), &hChildStdoutRdDup, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ return win32_error("DuplicateHandle", NULL);
+
+ /* Close the inheritable version of ChildStdout
+ that we're using. */
+ CloseHandle(hChildStdoutRd);
+
+ if (n != POPEN_4) {
+ if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
+ return win32_error("CreatePipe", NULL);
+ fSuccess = DuplicateHandle(GetCurrentProcess(),
+ hChildStderrRd,
+ GetCurrentProcess(),
+ &hChildStderrRdDup, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ return win32_error("DuplicateHandle", NULL);
+ /* Close the inheritable version of ChildStdErr that we're using. */
+ CloseHandle(hChildStderrRd);
+ }
+
+ switch (n) {
+ case POPEN_1:
+ switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
+ case _O_WRONLY | _O_TEXT:
+ /* Case for writing to child Stdin in text mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, "w");
+ f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+
+ case _O_RDONLY | _O_TEXT:
+ /* Case for reading from child Stdout in text mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f1 = _fdopen(fd1, "r");
+ f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdinWrDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+
+ case _O_RDONLY | _O_BINARY:
+ /* Case for readinig from child Stdout in binary mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f1 = _fdopen(fd1, "rb");
+ f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdinWrDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+
+ case _O_WRONLY | _O_BINARY:
+ /* Case for writing to child Stdin in binary mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, "wb");
+ f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+ }
+ file_count = 1;
+ break;
+
+ case POPEN_2:
+ case POPEN_4:
+ {
+ char *m1, *m2;
+ PyObject *p1, *p2;
+
+ if (mode & _O_TEXT) {
+ m1 = "r";
+ m2 = "w";
+ } else {
+ m1 = "rb";
+ m2 = "wb";
+ }
+
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, m2);
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f2 = _fdopen(fd2, m1);
+ p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
+ PyFile_SetBufSize(p1, 0);
+ p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
+ PyFile_SetBufSize(p2, 0);
+
+ if (n != 4)
+ CloseHandle(hChildStderrRdDup);
+
+ f = PyTuple_Pack(2,p1,p2);
+ Py_XDECREF(p1);
+ Py_XDECREF(p2);
+ file_count = 2;
+ break;
+ }
+
+ case POPEN_3:
+ {
+ char *m1, *m2;
+ PyObject *p1, *p2, *p3;
+
+ if (mode & _O_TEXT) {
+ m1 = "r";
+ m2 = "w";
+ } else {
+ m1 = "rb";
+ m2 = "wb";
+ }
+
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, m2);
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f2 = _fdopen(fd2, m1);
+ fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
+ f3 = _fdopen(fd3, m1);
+ p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
+ p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
+ p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
+ PyFile_SetBufSize(p1, 0);
+ PyFile_SetBufSize(p2, 0);
+ PyFile_SetBufSize(p3, 0);
+ f = PyTuple_Pack(3,p1,p2,p3);
+ Py_XDECREF(p1);
+ Py_XDECREF(p2);
+ Py_XDECREF(p3);
+ file_count = 3;
+ break;
+ }
+ }
+
+ if (n == POPEN_4) {
+ if (!_PyPopenCreateProcess(cmdstring,
+ hChildStdinRd,
+ hChildStdoutWr,
+ hChildStdoutWr,
+ &hProcess))
+ return NULL;
+ }
+ else {
+ if (!_PyPopenCreateProcess(cmdstring,
+ hChildStdinRd,
+ hChildStdoutWr,
+ hChildStderrWr,
+ &hProcess))
+ return NULL;
+ }
+
+ /*
+ * Insert the files we've created into the process dictionary
+ * all referencing the list with the process handle and the
+ * initial number of files (see description below in _PyPclose).
+ * Since if _PyPclose later tried to wait on a process when all
+ * handles weren't closed, it could create a deadlock with the
+ * child, we spend some energy here to try to ensure that we
+ * either insert all file handles into the dictionary or none
+ * at all. It's a little clumsy with the various popen modes
+ * and variable number of files involved.
+ */
+ if (!_PyPopenProcs) {
+ _PyPopenProcs = PyDict_New();
+ }
+
+ if (_PyPopenProcs) {
+ PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
+ int ins_rc[3];
+
+ fileObj[0] = fileObj[1] = fileObj[2] = NULL;
+ ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
+
+ procObj = PyList_New(2);
+ hProcessObj = PyLong_FromVoidPtr(hProcess);
+ intObj = PyInt_FromLong(file_count);
+
+ if (procObj && hProcessObj && intObj) {
+ PyList_SetItem(procObj,0,hProcessObj);
+ PyList_SetItem(procObj,1,intObj);
+
+ fileObj[0] = PyLong_FromVoidPtr(f1);
+ if (fileObj[0]) {
+ ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[0],
+ procObj);
+ }
+ if (file_count >= 2) {
+ fileObj[1] = PyLong_FromVoidPtr(f2);
+ if (fileObj[1]) {
+ ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[1],
+ procObj);
+ }
+ }
+ if (file_count >= 3) {
+ fileObj[2] = PyLong_FromVoidPtr(f3);
+ if (fileObj[2]) {
+ ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[2],
+ procObj);
+ }
+ }
+
+ if (ins_rc[0] < 0 || !fileObj[0] ||
+ ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
+ ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
+ /* Something failed - remove any dictionary
+ * entries that did make it.
+ */
+ if (!ins_rc[0] && fileObj[0]) {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[0]);
+ }
+ if (!ins_rc[1] && fileObj[1]) {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[1]);
+ }
+ if (!ins_rc[2] && fileObj[2]) {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[2]);
+ }
+ }
+ }
+
+ /*
+ * Clean up our localized references for the dictionary keys
+ * and value since PyDict_SetItem will Py_INCREF any copies
+ * that got placed in the dictionary.
+ */
+ Py_XDECREF(procObj);
+ Py_XDECREF(fileObj[0]);
+ Py_XDECREF(fileObj[1]);
+ Py_XDECREF(fileObj[2]);
+ }
+
+ /* Child is launched. Close the parents copy of those pipe
+ * handles that only the child should have open. You need to
+ * make sure that no handles to the write end of the output pipe
+ * are maintained in this process or else the pipe will not close
+ * when the child process exits and the ReadFile will hang. */
+
+ if (!CloseHandle(hChildStdinRd))
+ return win32_error("CloseHandle", NULL);
+
+ if (!CloseHandle(hChildStdoutWr))
+ return win32_error("CloseHandle", NULL);
+
+ if ((n != 4) && (!CloseHandle(hChildStderrWr)))
+ return win32_error("CloseHandle", NULL);
+
+ return f;
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file. On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation. This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
+ */
+
+static int _PyPclose(FILE *file)
+{
+ int result;
+ DWORD exit_code;
+ HANDLE hProcess;
+ PyObject *procObj, *hProcessObj, *intObj, *fileObj;
+ long file_count;
+#ifdef WITH_THREAD
+ PyGILState_STATE state;
+#endif
+
+ /* Close the file handle first, to ensure it can't block the
+ * child from exiting if it's the last handle.
+ */
+ result = fclose(file);
+#ifdef WITH_THREAD
+ state = PyGILState_Ensure();
+#endif
+ if (_PyPopenProcs) {
+ if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
+ (procObj = PyDict_GetItem(_PyPopenProcs,
+ fileObj)) != NULL &&
+ (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
+ (intObj = PyList_GetItem(procObj,1)) != NULL) {
+
+ hProcess = PyLong_AsVoidPtr(hProcessObj);
+ file_count = PyInt_AsLong(intObj);
+
+ if (file_count > 1) {
+ /* Still other files referencing process */
+ file_count--;
+ PyList_SetItem(procObj,1,
+ PyInt_FromLong(file_count));
+ } else {
+ /* Last file for this process */
+ if (result != EOF &&
+ WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
+ GetExitCodeProcess(hProcess, &exit_code)) {
+ /* Possible truncation here in 16-bit environments, but
+ * real exit codes are just the lower byte in any event.
+ */
+ result = exit_code;
+ } else {
+ /* Indicate failure - this will cause the file object
+ * to raise an I/O error and translate the last Win32
+ * error code from errno. We do have a problem with
+ * last errors that overlap the normal errno table,
+ * but that's a consistent problem with the file object.
+ */
+ if (result != EOF) {
+ /* If the error wasn't from the fclose(), then
+ * set errno for the file object error handling.
+ */
+ errno = GetLastError();
+ }
+ result = -1;
+ }
+
+ /* Free up the native handle at this point */
+ CloseHandle(hProcess);
+ }
+
+ /* Remove this file pointer from dictionary */
+ PyDict_DelItem(_PyPopenProcs, fileObj);
+
+ if (PyDict_Size(_PyPopenProcs) == 0) {
+ Py_DECREF(_PyPopenProcs);
+ _PyPopenProcs = NULL;
+ }
+
+ } /* if object retrieval ok */
+
+ Py_XDECREF(fileObj);
+ } /* if _PyPopenProcs */
+
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+ return result;
+}
+
+#else /* which OS? */
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *mode = "r";
+ int bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+ return NULL;
+ /* Strip mode of binary or text modifiers */
+ if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
+ mode = "r";
+ else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
+ mode = "w";
+ Py_BEGIN_ALLOW_THREADS
+ fp = popen(name, mode);
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return posix_error();
+ f = PyFile_FromFile(fp, name, mode, pclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+#endif /* PYOS_??? */
+#endif /* HAVE_POPEN */
+
+
+#ifdef HAVE_SETUID
+PyDoc_STRVAR(posix_setuid__doc__,
+"setuid(uid)\n\n\
+Set the current process's user id.");
+
+static PyObject *
+posix_setuid(PyObject *self, PyObject *args)
+{
+ int uid;
+ if (!PyArg_ParseTuple(args, "i:setuid", &uid))
+ return NULL;
+ if (setuid(uid) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETUID */
+
+
+#ifdef HAVE_SETEUID
+PyDoc_STRVAR(posix_seteuid__doc__,
+"seteuid(uid)\n\n\
+Set the current process's effective user id.");
+
+static PyObject *
+posix_seteuid (PyObject *self, PyObject *args)
+{
+ int euid;
+ if (!PyArg_ParseTuple(args, "i", &euid)) {
+ return NULL;
+ } else if (seteuid(euid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETEUID */
+
+#ifdef HAVE_SETEGID
+PyDoc_STRVAR(posix_setegid__doc__,
+"setegid(gid)\n\n\
+Set the current process's effective group id.");
+
+static PyObject *
+posix_setegid (PyObject *self, PyObject *args)
+{
+ int egid;
+ if (!PyArg_ParseTuple(args, "i", &egid)) {
+ return NULL;
+ } else if (setegid(egid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETEGID */
+
+#ifdef HAVE_SETREUID
+PyDoc_STRVAR(posix_setreuid__doc__,
+"setreuid(ruid, euid)\n\n\
+Set the current process's real and effective user ids.");
+
+static PyObject *
+posix_setreuid (PyObject *self, PyObject *args)
+{
+ int ruid, euid;
+ if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
+ return NULL;
+ } else if (setreuid(ruid, euid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETREUID */
+
+#ifdef HAVE_SETREGID
+PyDoc_STRVAR(posix_setregid__doc__,
+"setregid(rgid, egid)\n\n\
+Set the current process's real and effective group ids.");
+
+static PyObject *
+posix_setregid (PyObject *self, PyObject *args)
+{
+ int rgid, egid;
+ if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
+ return NULL;
+ } else if (setregid(rgid, egid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETREGID */
+
+#ifdef HAVE_SETGID
+PyDoc_STRVAR(posix_setgid__doc__,
+"setgid(gid)\n\n\
+Set the current process's group id.");
+
+static PyObject *
+posix_setgid(PyObject *self, PyObject *args)
+{
+ int gid;
+ if (!PyArg_ParseTuple(args, "i:setgid", &gid))
+ return NULL;
+ if (setgid(gid) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETGID */
+
+#ifdef HAVE_SETGROUPS
+PyDoc_STRVAR(posix_setgroups__doc__,
+"setgroups(list)\n\n\
+Set the groups of the current process to list.");
+
+static PyObject *
+posix_setgroups(PyObject *self, PyObject *groups)
+{
+ int i, len;
+ gid_t grouplist[MAX_GROUPS];
+
+ if (!PySequence_Check(groups)) {
+ PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
+ return NULL;
+ }
+ len = PySequence_Size(groups);
+ if (len > MAX_GROUPS) {
+ PyErr_SetString(PyExc_ValueError, "too many groups");
+ return NULL;
+ }
+ for(i = 0; i < len; i++) {
+ PyObject *elem;
+ elem = PySequence_GetItem(groups, i);
+ if (!elem)
+ return NULL;
+ if (!PyInt_Check(elem)) {
+ if (!PyLong_Check(elem)) {
+ PyErr_SetString(PyExc_TypeError,
+ "groups must be integers");
+ Py_DECREF(elem);
+ return NULL;
+ } else {
+ unsigned long x = PyLong_AsUnsignedLong(elem);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "group id too big");
+ Py_DECREF(elem);
+ return NULL;
+ }
+ grouplist[i] = x;
+ /* read back the value to see if it fitted in gid_t */
+ if (grouplist[i] != x) {
+ PyErr_SetString(PyExc_TypeError,
+ "group id too big");
+ Py_DECREF(elem);
+ return NULL;
+ }
+ }
+ } else {
+ long x = PyInt_AsLong(elem);
+ grouplist[i] = x;
+ if (grouplist[i] != x) {
+ PyErr_SetString(PyExc_TypeError,
+ "group id too big");
+ Py_DECREF(elem);
+ return NULL;
+ }
+ }
+ Py_DECREF(elem);
+ }
+
+ if (setgroups(len, grouplist) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETGROUPS */
+
+#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
+static PyObject *
+wait_helper(int pid, int status, struct rusage *ru)
+{
+ PyObject *result;
+ static PyObject *struct_rusage;
+
+ if (pid == -1)
+ return posix_error();
+
+ if (struct_rusage == NULL) {
+ PyObject *m = PyImport_ImportModule("resource");
+ if (m == NULL)
+ return NULL;
+ struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
+ Py_DECREF(m);
+ if (struct_rusage == NULL)
+ return NULL;
+ }
+
+ /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
+ result = PyStructSequence_New((PyTypeObject*) struct_rusage);
+ if (!result)
+ return NULL;
+
+#ifndef doubletime
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+#endif
+
+ PyStructSequence_SET_ITEM(result, 0,
+ PyFloat_FromDouble(doubletime(ru->ru_utime)));
+ PyStructSequence_SET_ITEM(result, 1,
+ PyFloat_FromDouble(doubletime(ru->ru_stime)));
+#define SET_INT(result, index, value)\
+ PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
+ SET_INT(result, 2, ru->ru_maxrss);
+ SET_INT(result, 3, ru->ru_ixrss);
+ SET_INT(result, 4, ru->ru_idrss);
+ SET_INT(result, 5, ru->ru_isrss);
+ SET_INT(result, 6, ru->ru_minflt);
+ SET_INT(result, 7, ru->ru_majflt);
+ SET_INT(result, 8, ru->ru_nswap);
+ SET_INT(result, 9, ru->ru_inblock);
+ SET_INT(result, 10, ru->ru_oublock);
+ SET_INT(result, 11, ru->ru_msgsnd);
+ SET_INT(result, 12, ru->ru_msgrcv);
+ SET_INT(result, 13, ru->ru_nsignals);
+ SET_INT(result, 14, ru->ru_nvcsw);
+ SET_INT(result, 15, ru->ru_nivcsw);
+#undef SET_INT
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return Py_BuildValue("iiN", pid, status, result);
+}
+#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
+
+#ifdef HAVE_WAIT3
+PyDoc_STRVAR(posix_wait3__doc__,
+"wait3(options) -> (pid, status, rusage)\n\n\
+Wait for completion of a child process.");
+
+static PyObject *
+posix_wait3(PyObject *self, PyObject *args)
+{
+ int pid, options;
+ struct rusage ru;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:wait3", &options))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ pid = wait3(&status, options, &ru);
+ Py_END_ALLOW_THREADS
+
+ return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
+}
+#endif /* HAVE_WAIT3 */
+
+#ifdef HAVE_WAIT4
+PyDoc_STRVAR(posix_wait4__doc__,
+"wait4(pid, options) -> (pid, status, rusage)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_wait4(PyObject *self, PyObject *args)
+{
+ int pid, options;
+ struct rusage ru;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ pid = wait4(pid, &status, options, &ru);
+ Py_END_ALLOW_THREADS
+
+ return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
+}
+#endif /* HAVE_WAIT4 */
+
+#ifdef HAVE_WAITPID
+PyDoc_STRVAR(posix_waitpid__doc__,
+"waitpid(pid, options) -> (pid, status)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+ int pid, options;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ pid = waitpid(pid, &status, options);
+ Py_END_ALLOW_THREADS
+ if (pid == -1)
+ return posix_error();
+
+ return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
+}
+
+#elif defined(HAVE_CWAIT)
+
+/* MS C has a variant of waitpid() that's usable for most purposes. */
+PyDoc_STRVAR(posix_waitpid__doc__,
+"waitpid(pid, options) -> (pid, status << 8)\n\n"
+"Wait for completion of a given process. options is ignored on Windows.");
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+ Py_intptr_t pid;
+ int status, options;
+
+ if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ pid = _cwait(&status, pid, options);
+ Py_END_ALLOW_THREADS
+ if (pid == -1)
+ return posix_error();
+
+ /* shift the status left a byte so this is more like the POSIX waitpid */
+ return Py_BuildValue("ii", pid, status << 8);
+}
+#endif /* HAVE_WAITPID || HAVE_CWAIT */
+
+#ifdef HAVE_WAIT
+PyDoc_STRVAR(posix_wait__doc__,
+"wait() -> (pid, status)\n\n\
+Wait for completion of a child process.");
+
+static PyObject *
+posix_wait(PyObject *self, PyObject *noargs)
+{
+ int pid;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+ pid = wait(&status);
+ Py_END_ALLOW_THREADS
+ if (pid == -1)
+ return posix_error();
+
+ return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
+}
+#endif
+
+
+PyDoc_STRVAR(posix_lstat__doc__,
+"lstat(path) -> stat result\n\n\
+Like stat(path), but do not follow symbolic links.");
+
+static PyObject *
+posix_lstat(PyObject *self, PyObject *args)
+{
+#ifdef HAVE_LSTAT
+ return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
+#else /* !HAVE_LSTAT */
+#ifdef MS_WINDOWS
+ return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
+#else
+ return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
+#endif
+#endif /* !HAVE_LSTAT */
+}
+
+
+#ifdef HAVE_READLINK
+PyDoc_STRVAR(posix_readlink__doc__,
+"readlink(path) -> path\n\n\
+Return a string representing the path to which the symbolic link points.");
+
+static PyObject *
+posix_readlink(PyObject *self, PyObject *args)
+{
+ char buf[MAXPATHLEN];
+ char *path;
+ int n;
+ if (!PyArg_ParseTuple(args, "s:readlink", &path))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ n = readlink(path, buf, (int) sizeof buf);
+ Py_END_ALLOW_THREADS
+ if (n < 0)
+ return posix_error_with_filename(path);
+ return PyString_FromStringAndSize(buf, n);
+}
+#endif /* HAVE_READLINK */
+
+
+#ifdef HAVE_SYMLINK
+PyDoc_STRVAR(posix_symlink__doc__,
+"symlink(src, dst)\n\n\
+Create a symbolic link pointing to src named dst.");
+
+static PyObject *
+posix_symlink(PyObject *self, PyObject *args)
+{
+ return posix_2str(args, "etet:symlink", symlink);
+}
+#endif /* HAVE_SYMLINK */
+
+
+#ifdef HAVE_TIMES
+#ifndef HZ
+#define HZ 60 /* Universal constant :-) */
+#endif /* HZ */
+
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+static long
+system_uptime(void)
+{
+ ULONG value = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+ DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
+ Py_END_ALLOW_THREADS
+
+ return value;
+}
+
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+ /* Currently Only Uptime is Provided -- Others Later */
+ return Py_BuildValue("ddddd",
+ (double)0 /* t.tms_utime / HZ */,
+ (double)0 /* t.tms_stime / HZ */,
+ (double)0 /* t.tms_cutime / HZ */,
+ (double)0 /* t.tms_cstime / HZ */,
+ (double)system_uptime() / 1000);
+}
+#else /* not OS2 */
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+ struct tms t;
+ clock_t c;
+ errno = 0;
+ c = times(&t);
+ if (c == (clock_t) -1)
+ return posix_error();
+ return Py_BuildValue("ddddd",
+ (double)t.tms_utime / HZ,
+ (double)t.tms_stime / HZ,
+ (double)t.tms_cutime / HZ,
+ (double)t.tms_cstime / HZ,
+ (double)c / HZ);
+}
+#endif /* not OS2 */
+#endif /* HAVE_TIMES */
+
+
+#ifdef MS_WINDOWS
+#define HAVE_TIMES /* so the method table will pick it up */
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+ FILETIME create, exit, kernel, user;
+ HANDLE hProc;
+ hProc = GetCurrentProcess();
+ GetProcessTimes(hProc, &create, &exit, &kernel, &user);
+ /* The fields of a FILETIME structure are the hi and lo part
+ of a 64-bit value expressed in 100 nanosecond units.
+ 1e7 is one second in such units; 1e-7 the inverse.
+ 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
+ */
+ return Py_BuildValue(
+ "ddddd",
+ (double)(kernel.dwHighDateTime*429.4967296 +
+ kernel.dwLowDateTime*1e-7),
+ (double)(user.dwHighDateTime*429.4967296 +
+ user.dwLowDateTime*1e-7),
+ (double)0,
+ (double)0,
+ (double)0);
+}
+#endif /* MS_WINDOWS */
+
+#ifdef HAVE_TIMES
+PyDoc_STRVAR(posix_times__doc__,
+"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
+Return a tuple of floating point numbers indicating process times.");
+#endif
+
+
+#ifdef HAVE_GETSID
+PyDoc_STRVAR(posix_getsid__doc__,
+"getsid(pid) -> sid\n\n\
+Call the system call getsid().");
+
+static PyObject *
+posix_getsid(PyObject *self, PyObject *args)
+{
+ int pid, sid;
+ if (!PyArg_ParseTuple(args, "i:getsid", &pid))
+ return NULL;
+ sid = getsid(pid);
+ if (sid < 0)
+ return posix_error();
+ return PyInt_FromLong((long)sid);
+}
+#endif /* HAVE_GETSID */
+
+
+#ifdef HAVE_SETSID
+PyDoc_STRVAR(posix_setsid__doc__,
+"setsid()\n\n\
+Call the system call setsid().");
+
+static PyObject *
+posix_setsid(PyObject *self, PyObject *noargs)
+{
+ if (setsid() < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETSID */
+
+#ifdef HAVE_SETPGID
+PyDoc_STRVAR(posix_setpgid__doc__,
+"setpgid(pid, pgrp)\n\n\
+Call the system call setpgid().");
+
+static PyObject *
+posix_setpgid(PyObject *self, PyObject *args)
+{
+ int pid, pgrp;
+ if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
+ return NULL;
+ if (setpgid(pid, pgrp) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETPGID */
+
+
+#ifdef HAVE_TCGETPGRP
+PyDoc_STRVAR(posix_tcgetpgrp__doc__,
+"tcgetpgrp(fd) -> pgid\n\n\
+Return the process group associated with the terminal given by a fd.");
+
+static PyObject *
+posix_tcgetpgrp(PyObject *self, PyObject *args)
+{
+ int fd, pgid;
+ if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
+ return NULL;
+ pgid = tcgetpgrp(fd);
+ if (pgid < 0)
+ return posix_error();
+ return PyInt_FromLong((long)pgid);
+}
+#endif /* HAVE_TCGETPGRP */
+
+
+#ifdef HAVE_TCSETPGRP
+PyDoc_STRVAR(posix_tcsetpgrp__doc__,
+"tcsetpgrp(fd, pgid)\n\n\
+Set the process group associated with the terminal given by a fd.");
+
+static PyObject *
+posix_tcsetpgrp(PyObject *self, PyObject *args)
+{
+ int fd, pgid;
+ if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
+ return NULL;
+ if (tcsetpgrp(fd, pgid) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_TCSETPGRP */
+
+/* Functions acting on file descriptors */
+
+PyDoc_STRVAR(posix_open__doc__,
+"open(filename, flag [, mode=0777]) -> fd\n\n\
+Open a file (for low level IO).");
+
+static PyObject *
+posix_open(PyObject *self, PyObject *args)
+{
+ char *file = NULL;
+ int flag;
+ int mode = 0777;
+ int fd;
+
+#ifdef MS_WINDOWS
+ if (unicode_file_names()) {
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
+ Py_BEGIN_ALLOW_THREADS
+ /* PyUnicode_AS_UNICODE OK without thread
+ lock as it is a simple dereference. */
+ fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
+ Py_END_ALLOW_THREADS
+ if (fd < 0)
+ return posix_error();
+ return PyInt_FromLong((long)fd);
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+#endif
+
+ if (!PyArg_ParseTuple(args, "eti|i",
+ Py_FileSystemDefaultEncoding, &file,
+ &flag, &mode))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ fd = open(file, flag, mode);
+ Py_END_ALLOW_THREADS
+ if (fd < 0)
+ return posix_error_with_allocated_filename(file);
+ PyMem_Free(file);
+ return PyInt_FromLong((long)fd);
+}
+
+
+PyDoc_STRVAR(posix_close__doc__,
+"close(fd)\n\n\
+Close a file descriptor (for low level IO).");
+
+static PyObject *
+posix_close(PyObject *self, PyObject *args)
+{
+ int fd, res;
+ if (!PyArg_ParseTuple(args, "i:close", &fd))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = close(fd);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(posix_dup__doc__,
+"dup(fd) -> fd2\n\n\
+Return a duplicate of a file descriptor.");
+
+static PyObject *
+posix_dup(PyObject *self, PyObject *args)
+{
+ int fd;
+ if (!PyArg_ParseTuple(args, "i:dup", &fd))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ fd = dup(fd);
+ Py_END_ALLOW_THREADS
+ if (fd < 0)
+ return posix_error();
+ return PyInt_FromLong((long)fd);
+}
+
+
+PyDoc_STRVAR(posix_dup2__doc__,
+"dup2(old_fd, new_fd)\n\n\
+Duplicate file descriptor.");
+
+static PyObject *
+posix_dup2(PyObject *self, PyObject *args)
+{
+ int fd, fd2, res;
+ if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = dup2(fd, fd2);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(posix_lseek__doc__,
+"lseek(fd, pos, how) -> newpos\n\n\
+Set the current position of a file descriptor.");
+
+static PyObject *
+posix_lseek(PyObject *self, PyObject *args)
+{
+ int fd, how;
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+ PY_LONG_LONG pos, res;
+#else
+ off_t pos, res;
+#endif
+ PyObject *posobj;
+ if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
+ return NULL;
+#ifdef SEEK_SET
+ /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
+ switch (how) {
+ case 0: how = SEEK_SET; break;
+ case 1: how = SEEK_CUR; break;
+ case 2: how = SEEK_END; break;
+ }
+#endif /* SEEK_END */
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ pos = PyInt_AsLong(posobj);
+#else
+ pos = PyLong_Check(posobj) ?
+ PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+ res = _lseeki64(fd, pos, how);
+#else
+ res = lseek(fd, pos, how);
+#endif
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ return PyInt_FromLong(res);
+#else
+ return PyLong_FromLongLong(res);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_read__doc__,
+"read(fd, buffersize) -> string\n\n\
+Read a file descriptor.");
+
+static PyObject *
+posix_read(PyObject *self, PyObject *args)
+{
+ int fd, size, n;
+ PyObject *buffer;
+ if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
+ return NULL;
+ if (size < 0) {
+ errno = EINVAL;
+ return posix_error();
+ }
+ buffer = PyString_FromStringAndSize((char *)NULL, size);
+ if (buffer == NULL)
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ n = read(fd, PyString_AsString(buffer), size);
+ Py_END_ALLOW_THREADS
+ if (n < 0) {
+ Py_DECREF(buffer);
+ return posix_error();
+ }
+ if (n != size)
+ _PyString_Resize(&buffer, n);
+ return buffer;
+}
+
+
+PyDoc_STRVAR(posix_write__doc__,
+"write(fd, string) -> byteswritten\n\n\
+Write a string to a file descriptor.");
+
+static PyObject *
+posix_write(PyObject *self, PyObject *args)
+{
+ int fd;
+ Py_ssize_t size;
+ char *buffer;
+
+ if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ size = write(fd, buffer, (size_t)size);
+ Py_END_ALLOW_THREADS
+ if (size < 0)
+ return posix_error();
+ return PyInt_FromSsize_t(size);
+}
+
+
+PyDoc_STRVAR(posix_fstat__doc__,
+"fstat(fd) -> stat result\n\n\
+Like stat(), but for an open file descriptor.");
+
+static PyObject *
+posix_fstat(PyObject *self, PyObject *args)
+{
+ int fd;
+ STRUCT_STAT st;
+ int res;
+ if (!PyArg_ParseTuple(args, "i:fstat", &fd))
+ return NULL;
+#ifdef __VMS
+ /* on OpenVMS we must ensure that all bytes are written to the file */
+ fsync(fd);
+#endif
+ Py_BEGIN_ALLOW_THREADS
+ res = FSTAT(fd, &st);
+ Py_END_ALLOW_THREADS
+ if (res != 0) {
+#ifdef MS_WINDOWS
+ return win32_error("fstat", NULL);
+#else
+ return posix_error();
+#endif
+ }
+
+ return _pystat_fromstructstat(&st);
+}
+
+
+PyDoc_STRVAR(posix_fdopen__doc__,
+"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
+Return an open file object connected to a file descriptor.");
+
+static PyObject *
+posix_fdopen(PyObject *self, PyObject *args)
+{
+ int fd;
+ char *mode = "r";
+ int bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
+ return NULL;
+
+ if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
+ PyErr_Format(PyExc_ValueError,
+ "invalid file mode '%s'", mode);
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
+ if (mode[0] == 'a') {
+ /* try to make sure the O_APPEND flag is set */
+ int flags;
+ flags = fcntl(fd, F_GETFL);
+ if (flags != -1)
+ fcntl(fd, F_SETFL, flags | O_APPEND);
+ fp = fdopen(fd, mode);
+ if (fp == NULL && flags != -1)
+ /* restore old mode if fdopen failed */
+ fcntl(fd, F_SETFL, flags);
+ } else {
+ fp = fdopen(fd, mode);
+ }
+#else
+ fp = fdopen(fd, mode);
+#endif
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return posix_error();
+ f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+PyDoc_STRVAR(posix_isatty__doc__,
+"isatty(fd) -> bool\n\n\
+Return True if the file descriptor 'fd' is an open file descriptor\n\
+connected to the slave end of a terminal.");
+
+static PyObject *
+posix_isatty(PyObject *self, PyObject *args)
+{
+ int fd;
+ if (!PyArg_ParseTuple(args, "i:isatty", &fd))
+ return NULL;
+ return PyBool_FromLong(isatty(fd));
+}
+
+#ifdef HAVE_PIPE
+PyDoc_STRVAR(posix_pipe__doc__,
+"pipe() -> (read_end, write_end)\n\n\
+Create a pipe.");
+
+static PyObject *
+posix_pipe(PyObject *self, PyObject *noargs)
+{
+#if defined(PYOS_OS2)
+ HFILE read, write;
+ APIRET rc;
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = DosCreatePipe( &read, &write, 4096);
+ Py_END_ALLOW_THREADS
+ if (rc != NO_ERROR)
+ return os2_error(rc);
+
+ return Py_BuildValue("(ii)", read, write);
+#else
+#if !defined(MS_WINDOWS)
+ int fds[2];
+ int res;
+ Py_BEGIN_ALLOW_THREADS
+ res = pipe(fds);
+ Py_END_ALLOW_THREADS
+ if (res != 0)
+ return posix_error();
+ return Py_BuildValue("(ii)", fds[0], fds[1]);
+#else /* MS_WINDOWS */
+ HANDLE read, write;
+ int read_fd, write_fd;
+ BOOL ok;
+ Py_BEGIN_ALLOW_THREADS
+ ok = CreatePipe(&read, &write, NULL, 0);
+ Py_END_ALLOW_THREADS
+ if (!ok)
+ return win32_error("CreatePipe", NULL);
+ read_fd = _open_osfhandle((Py_intptr_t)read, 0);
+ write_fd = _open_osfhandle((Py_intptr_t)write, 1);
+ return Py_BuildValue("(ii)", read_fd, write_fd);
+#endif /* MS_WINDOWS */
+#endif
+}
+#endif /* HAVE_PIPE */
+
+
+#ifdef HAVE_MKFIFO
+PyDoc_STRVAR(posix_mkfifo__doc__,
+"mkfifo(filename [, mode=0666])\n\n\
+Create a FIFO (a POSIX named pipe).");
+
+static PyObject *
+posix_mkfifo(PyObject *self, PyObject *args)
+{
+ char *filename;
+ int mode = 0666;
+ int res;
+ if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = mkfifo(filename, mode);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+PyDoc_STRVAR(posix_mknod__doc__,
+"mknod(filename [, mode=0600, device])\n\n\
+Create a filesystem node (file, device special file or named pipe)\n\
+named filename. mode specifies both the permissions to use and the\n\
+type of node to be created, being combined (bitwise OR) with one of\n\
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
+device defines the newly created device special file (probably using\n\
+os.makedev()), otherwise it is ignored.");
+
+
+static PyObject *
+posix_mknod(PyObject *self, PyObject *args)
+{
+ char *filename;
+ int mode = 0600;
+ int device = 0;
+ int res;
+ if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = mknod(filename, mode, device);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_DEVICE_MACROS
+PyDoc_STRVAR(posix_major__doc__,
+"major(device) -> major number\n\
+Extracts a device major number from a raw device number.");
+
+static PyObject *
+posix_major(PyObject *self, PyObject *args)
+{
+ int device;
+ if (!PyArg_ParseTuple(args, "i:major", &device))
+ return NULL;
+ return PyInt_FromLong((long)major(device));
+}
+
+PyDoc_STRVAR(posix_minor__doc__,
+"minor(device) -> minor number\n\
+Extracts a device minor number from a raw device number.");
+
+static PyObject *
+posix_minor(PyObject *self, PyObject *args)
+{
+ int device;
+ if (!PyArg_ParseTuple(args, "i:minor", &device))
+ return NULL;
+ return PyInt_FromLong((long)minor(device));
+}
+
+PyDoc_STRVAR(posix_makedev__doc__,
+"makedev(major, minor) -> device number\n\
+Composes a raw device number from the major and minor device numbers.");
+
+static PyObject *
+posix_makedev(PyObject *self, PyObject *args)
+{
+ int major, minor;
+ if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
+ return NULL;
+ return PyInt_FromLong((long)makedev(major, minor));
+}
+#endif /* device macros */
+
+
+#ifdef HAVE_FTRUNCATE
+PyDoc_STRVAR(posix_ftruncate__doc__,
+"ftruncate(fd, length)\n\n\
+Truncate a file to a specified length.");
+
+static PyObject *
+posix_ftruncate(PyObject *self, PyObject *args)
+{
+ int fd;
+ off_t length;
+ int res;
+ PyObject *lenobj;
+
+ if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ length = PyInt_AsLong(lenobj);
+#else
+ length = PyLong_Check(lenobj) ?
+ PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = ftruncate(fd, length);
+ Py_END_ALLOW_THREADS
+ if (res < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_PUTENV
+PyDoc_STRVAR(posix_putenv__doc__,
+"putenv(key, value)\n\n\
+Change or add an environment variable.");
+
+/* Save putenv() parameters as values here, so we can collect them when they
+ * get re-set with another call for the same key. */
+static PyObject *posix_putenv_garbage;
+
+static PyObject *
+posix_putenv(PyObject *self, PyObject *args)
+{
+ char *s1, *s2;
+ char *newenv;
+ PyObject *newstr;
+ size_t len;
+
+ if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
+ return NULL;
+
+#if defined(PYOS_OS2)
+ if (stricmp(s1, "BEGINLIBPATH") == 0) {
+ APIRET rc;
+
+ rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
+ if (rc != NO_ERROR)
+ return os2_error(rc);
+
+ } else if (stricmp(s1, "ENDLIBPATH") == 0) {
+ APIRET rc;
+
+ rc = DosSetExtLIBPATH(s2, END_LIBPATH);
+ if (rc != NO_ERROR)
+ return os2_error(rc);
+ } else {
+#endif
+
+ /* XXX This can leak memory -- not easy to fix :-( */
+ len = strlen(s1) + strlen(s2) + 2;
+ /* len includes space for a trailing \0; the size arg to
+ PyString_FromStringAndSize does not count that */
+ newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
+ if (newstr == NULL)
+ return PyErr_NoMemory();
+ newenv = PyString_AS_STRING(newstr);
+ PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
+ if (putenv(newenv)) {
+ Py_DECREF(newstr);
+ posix_error();
+ return NULL;
+ }
+ /* Install the first arg and newstr in posix_putenv_garbage;
+ * this will cause previous value to be collected. This has to
+ * happen after the real putenv() call because the old value
+ * was still accessible until then. */
+ if (PyDict_SetItem(posix_putenv_garbage,
+ PyTuple_GET_ITEM(args, 0), newstr)) {
+ /* really not much we can do; just leak */
+ PyErr_Clear();
+ }
+ else {
+ Py_DECREF(newstr);
+ }
+
+#if defined(PYOS_OS2)
+ }
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* putenv */
+
+#ifdef HAVE_UNSETENV
+PyDoc_STRVAR(posix_unsetenv__doc__,
+"unsetenv(key)\n\n\
+Delete an environment variable.");
+
+static PyObject *
+posix_unsetenv(PyObject *self, PyObject *args)
+{
+ char *s1;
+
+ if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
+ return NULL;
+
+ unsetenv(s1);
+
+ /* Remove the key from posix_putenv_garbage;
+ * this will cause it to be collected. This has to
+ * happen after the real unsetenv() call because the
+ * old value was still accessible until then.
+ */
+ if (PyDict_DelItem(posix_putenv_garbage,
+ PyTuple_GET_ITEM(args, 0))) {
+ /* really not much we can do; just leak */
+ PyErr_Clear();
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* unsetenv */
+
+#ifdef HAVE_STRERROR
+PyDoc_STRVAR(posix_strerror__doc__,
+"strerror(code) -> string\n\n\
+Translate an error code to a message string.");
+
+static PyObject *
+posix_strerror(PyObject *self, PyObject *args)
+{
+ int code;
+ char *message;
+ if (!PyArg_ParseTuple(args, "i:strerror", &code))
+ return NULL;
+ message = strerror(code);
+ if (message == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "strerror() argument out of range");
+ return NULL;
+ }
+ return PyString_FromString(message);
+}
+#endif /* strerror */
+
+
+#ifdef HAVE_SYS_WAIT_H
+
+#ifdef WCOREDUMP
+PyDoc_STRVAR(posix_WCOREDUMP__doc__,
+"WCOREDUMP(status) -> bool\n\n\
+Return True if the process returning 'status' was dumped to a core file.");
+
+static PyObject *
+posix_WCOREDUMP(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WCOREDUMP(status));
+}
+#endif /* WCOREDUMP */
+
+#ifdef WIFCONTINUED
+PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
+"WIFCONTINUED(status) -> bool\n\n\
+Return True if the process returning 'status' was continued from a\n\
+job control stop.");
+
+static PyObject *
+posix_WIFCONTINUED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFCONTINUED(status));
+}
+#endif /* WIFCONTINUED */
+
+#ifdef WIFSTOPPED
+PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
+"WIFSTOPPED(status) -> bool\n\n\
+Return True if the process returning 'status' was stopped.");
+
+static PyObject *
+posix_WIFSTOPPED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFSTOPPED(status));
+}
+#endif /* WIFSTOPPED */
+
+#ifdef WIFSIGNALED
+PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
+"WIFSIGNALED(status) -> bool\n\n\
+Return True if the process returning 'status' was terminated by a signal.");
+
+static PyObject *
+posix_WIFSIGNALED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFSIGNALED(status));
+}
+#endif /* WIFSIGNALED */
+
+#ifdef WIFEXITED
+PyDoc_STRVAR(posix_WIFEXITED__doc__,
+"WIFEXITED(status) -> bool\n\n\
+Return true if the process returning 'status' exited using the exit()\n\
+system call.");
+
+static PyObject *
+posix_WIFEXITED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFEXITED(status));
+}
+#endif /* WIFEXITED */
+
+#ifdef WEXITSTATUS
+PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
+"WEXITSTATUS(status) -> integer\n\n\
+Return the process return code from 'status'.");
+
+static PyObject *
+posix_WEXITSTATUS(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return Py_BuildValue("i", WEXITSTATUS(status));
+}
+#endif /* WEXITSTATUS */
+
+#ifdef WTERMSIG
+PyDoc_STRVAR(posix_WTERMSIG__doc__,
+"WTERMSIG(status) -> integer\n\n\
+Return the signal that terminated the process that provided the 'status'\n\
+value.");
+
+static PyObject *
+posix_WTERMSIG(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return Py_BuildValue("i", WTERMSIG(status));
+}
+#endif /* WTERMSIG */
+
+#ifdef WSTOPSIG
+PyDoc_STRVAR(posix_WSTOPSIG__doc__,
+"WSTOPSIG(status) -> integer\n\n\
+Return the signal that stopped the process that provided\n\
+the 'status' value.");
+
+static PyObject *
+posix_WSTOPSIG(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return Py_BuildValue("i", WSTOPSIG(status));
+}
+#endif /* WSTOPSIG */
+
+#endif /* HAVE_SYS_WAIT_H */
+
+
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
+#ifdef _SCO_DS
+/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
+ needed definitions in sys/statvfs.h */
+#define _SVID3
+#endif
+#include <sys/statvfs.h>
+
+static PyObject*
+_pystatvfs_fromstructstatvfs(struct statvfs st) {
+ PyObject *v = PyStructSequence_New(&StatVFSResultType);
+ if (v == NULL)
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
+ PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
+ PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
+ PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
+ PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
+ PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+#else
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+ PyStructSequence_SET_ITEM(v, 2,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
+ PyStructSequence_SET_ITEM(v, 3,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
+ PyStructSequence_SET_ITEM(v, 4,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
+ PyStructSequence_SET_ITEM(v, 5,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
+ PyStructSequence_SET_ITEM(v, 6,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
+ PyStructSequence_SET_ITEM(v, 7,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+#endif
+
+ return v;
+}
+
+PyDoc_STRVAR(posix_fstatvfs__doc__,
+"fstatvfs(fd) -> statvfs result\n\n\
+Perform an fstatvfs system call on the given fd.");
+
+static PyObject *
+posix_fstatvfs(PyObject *self, PyObject *args)
+{
+ int fd, res;
+ struct statvfs st;
+
+ if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = fstatvfs(fd, &st);
+ Py_END_ALLOW_THREADS
+ if (res != 0)
+ return posix_error();
+
+ return _pystatvfs_fromstructstatvfs(st);
+}
+#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
+
+
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
+#include <sys/statvfs.h>
+
+PyDoc_STRVAR(posix_statvfs__doc__,
+"statvfs(path) -> statvfs result\n\n\
+Perform a statvfs system call on the given path.");
+
+static PyObject *
+posix_statvfs(PyObject *self, PyObject *args)
+{
+ char *path;
+ int res;
+ struct statvfs st;
+ if (!PyArg_ParseTuple(args, "s:statvfs", &path))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = statvfs(path, &st);
+ Py_END_ALLOW_THREADS
+ if (res != 0)
+ return posix_error_with_filename(path);
+
+ return _pystatvfs_fromstructstatvfs(st);
+}
+#endif /* HAVE_STATVFS */
+
+
+#ifdef HAVE_TEMPNAM
+PyDoc_STRVAR(posix_tempnam__doc__,
+"tempnam([dir[, prefix]]) -> string\n\n\
+Return a unique name for a temporary file.\n\
+The directory and a prefix may be specified as strings; they may be omitted\n\
+or None if not needed.");
+
+static PyObject *
+posix_tempnam(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ char *dir = NULL;
+ char *pfx = NULL;
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
+ return NULL;
+
+ if (PyErr_Warn(PyExc_RuntimeWarning,
+ "tempnam is a potential security risk to your program") < 0)
+ return NULL;
+
+#ifdef MS_WINDOWS
+ name = _tempnam(dir, pfx);
+#else
+ name = tempnam(dir, pfx);
+#endif
+ if (name == NULL)
+ return PyErr_NoMemory();
+ result = PyString_FromString(name);
+ free(name);
+ return result;
+}
+#endif
+
+
+#ifdef HAVE_TMPFILE
+PyDoc_STRVAR(posix_tmpfile__doc__,
+"tmpfile() -> file object\n\n\
+Create a temporary file with no directory entries.");
+
+static PyObject *
+posix_tmpfile(PyObject *self, PyObject *noargs)
+{
+ FILE *fp;
+
+ fp = tmpfile();
+ if (fp == NULL)
+ return posix_error();
+ return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
+}
+#endif
+
+
+#ifdef HAVE_TMPNAM
+PyDoc_STRVAR(posix_tmpnam__doc__,
+"tmpnam() -> string\n\n\
+Return a unique name for a temporary file.");
+
+static PyObject *
+posix_tmpnam(PyObject *self, PyObject *noargs)
+{
+ char buffer[L_tmpnam];
+ char *name;
+
+ if (PyErr_Warn(PyExc_RuntimeWarning,
+ "tmpnam is a potential security risk to your program") < 0)
+ return NULL;
+
+#ifdef USE_TMPNAM_R
+ name = tmpnam_r(buffer);
+#else
+ name = tmpnam(buffer);
+#endif
+ if (name == NULL) {
+ PyObject *err = Py_BuildValue("is", 0,
+#ifdef USE_TMPNAM_R
+ "unexpected NULL from tmpnam_r"
+#else
+ "unexpected NULL from tmpnam"
+#endif
+ );
+ PyErr_SetObject(PyExc_OSError, err);
+ Py_XDECREF(err);
+ return NULL;
+ }
+ return PyString_FromString(buffer);
+}
+#endif
+
+
+/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
+ * It maps strings representing configuration variable names to
+ * integer values, allowing those functions to be called with the
+ * magic names instead of polluting the module's namespace with tons of
+ * rarely-used constants. There are three separate tables that use
+ * these definitions.
+ *
+ * This code is always included, even if none of the interfaces that
+ * need it are included. The #if hackery needed to avoid it would be
+ * sufficiently pervasive that it's not worth the loss of readability.
+ */
+struct constdef {
+ char *name;
+ long value;
+};
+
+static int
+conv_confname(PyObject *arg, int *valuep, struct constdef *table,
+ size_t tablesize)
+{
+ if (PyInt_Check(arg)) {
+ *valuep = PyInt_AS_LONG(arg);
+ return 1;
+ }
+ if (PyString_Check(arg)) {
+ /* look up the value in the table using a binary search */
+ size_t lo = 0;
+ size_t mid;
+ size_t hi = tablesize;
+ int cmp;
+ char *confname = PyString_AS_STRING(arg);
+ while (lo < hi) {
+ mid = (lo + hi) / 2;
+ cmp = strcmp(confname, table[mid].name);
+ if (cmp < 0)
+ hi = mid;
+ else if (cmp > 0)
+ lo = mid + 1;
+ else {
+ *valuep = table[mid].value;
+ return 1;
+ }
+ }
+ PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
+ }
+ else
+ PyErr_SetString(PyExc_TypeError,
+ "configuration names must be strings or integers");
+ return 0;
+}
+
+
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
+static struct constdef posix_constants_pathconf[] = {
+#ifdef _PC_ABI_AIO_XFER_MAX
+ {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
+#endif
+#ifdef _PC_ABI_ASYNC_IO
+ {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
+#endif
+#ifdef _PC_ASYNC_IO
+ {"PC_ASYNC_IO", _PC_ASYNC_IO},
+#endif
+#ifdef _PC_CHOWN_RESTRICTED
+ {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
+#endif
+#ifdef _PC_FILESIZEBITS
+ {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
+#endif
+#ifdef _PC_LAST
+ {"PC_LAST", _PC_LAST},
+#endif
+#ifdef _PC_LINK_MAX
+ {"PC_LINK_MAX", _PC_LINK_MAX},
+#endif
+#ifdef _PC_MAX_CANON
+ {"PC_MAX_CANON", _PC_MAX_CANON},
+#endif
+#ifdef _PC_MAX_INPUT
+ {"PC_MAX_INPUT", _PC_MAX_INPUT},
+#endif
+#ifdef _PC_NAME_MAX
+ {"PC_NAME_MAX", _PC_NAME_MAX},
+#endif
+#ifdef _PC_NO_TRUNC
+ {"PC_NO_TRUNC", _PC_NO_TRUNC},
+#endif
+#ifdef _PC_PATH_MAX
+ {"PC_PATH_MAX", _PC_PATH_MAX},
+#endif
+#ifdef _PC_PIPE_BUF
+ {"PC_PIPE_BUF", _PC_PIPE_BUF},
+#endif
+#ifdef _PC_PRIO_IO
+ {"PC_PRIO_IO", _PC_PRIO_IO},
+#endif
+#ifdef _PC_SOCK_MAXBUF
+ {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
+#endif
+#ifdef _PC_SYNC_IO
+ {"PC_SYNC_IO", _PC_SYNC_IO},
+#endif
+#ifdef _PC_VDISABLE
+ {"PC_VDISABLE", _PC_VDISABLE},
+#endif
+};
+
+static int
+conv_path_confname(PyObject *arg, int *valuep)
+{
+ return conv_confname(arg, valuep, posix_constants_pathconf,
+ sizeof(posix_constants_pathconf)
+ / sizeof(struct constdef));
+}
+#endif
+
+#ifdef HAVE_FPATHCONF
+PyDoc_STRVAR(posix_fpathconf__doc__,
+"fpathconf(fd, name) -> integer\n\n\
+Return the configuration limit name for the file descriptor fd.\n\
+If there is no limit, return -1.");
+
+static PyObject *
+posix_fpathconf(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name, fd;
+
+ if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
+ conv_path_confname, &name)) {
+ long limit;
+
+ errno = 0;
+ limit = fpathconf(fd, name);
+ if (limit == -1 && errno != 0)
+ posix_error();
+ else
+ result = PyInt_FromLong(limit);
+ }
+ return result;
+}
+#endif
+
+
+#ifdef HAVE_PATHCONF
+PyDoc_STRVAR(posix_pathconf__doc__,
+"pathconf(path, name) -> integer\n\n\
+Return the configuration limit name for the file or directory path.\n\
+If there is no limit, return -1.");
+
+static PyObject *
+posix_pathconf(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name;
+ char *path;
+
+ if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
+ conv_path_confname, &name)) {
+ long limit;
+
+ errno = 0;
+ limit = pathconf(path, name);
+ if (limit == -1 && errno != 0) {
+ if (errno == EINVAL)
+ /* could be a path or name problem */
+ posix_error();
+ else
+ posix_error_with_filename(path);
+ }
+ else
+ result = PyInt_FromLong(limit);
+ }
+ return result;
+}
+#endif
+
+#ifdef HAVE_CONFSTR
+static struct constdef posix_constants_confstr[] = {
+#ifdef _CS_ARCHITECTURE
+ {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
+#endif
+#ifdef _CS_HOSTNAME
+ {"CS_HOSTNAME", _CS_HOSTNAME},
+#endif
+#ifdef _CS_HW_PROVIDER
+ {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
+#endif
+#ifdef _CS_HW_SERIAL
+ {"CS_HW_SERIAL", _CS_HW_SERIAL},
+#endif
+#ifdef _CS_INITTAB_NAME
+ {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
+#endif
+#ifdef _CS_LFS64_CFLAGS
+ {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
+#endif
+#ifdef _CS_LFS64_LDFLAGS
+ {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
+#endif
+#ifdef _CS_LFS64_LIBS
+ {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
+#endif
+#ifdef _CS_LFS64_LINTFLAGS
+ {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
+#endif
+#ifdef _CS_LFS_CFLAGS
+ {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
+#endif
+#ifdef _CS_LFS_LDFLAGS
+ {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
+#endif
+#ifdef _CS_LFS_LIBS
+ {"CS_LFS_LIBS", _CS_LFS_LIBS},
+#endif
+#ifdef _CS_LFS_LINTFLAGS
+ {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
+#endif
+#ifdef _CS_MACHINE
+ {"CS_MACHINE", _CS_MACHINE},
+#endif
+#ifdef _CS_PATH
+ {"CS_PATH", _CS_PATH},
+#endif
+#ifdef _CS_RELEASE
+ {"CS_RELEASE", _CS_RELEASE},
+#endif
+#ifdef _CS_SRPC_DOMAIN
+ {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
+#endif
+#ifdef _CS_SYSNAME
+ {"CS_SYSNAME", _CS_SYSNAME},
+#endif
+#ifdef _CS_VERSION
+ {"CS_VERSION", _CS_VERSION},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
+ {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
+ {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LIBS
+ {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
+ {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
+ {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
+ {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
+ {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
+ {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
+ {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
+ {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LIBS
+ {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
+ {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
+ {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
+ {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
+ {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
+ {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
+#endif
+#ifdef _MIPS_CS_AVAIL_PROCESSORS
+ {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_BASE
+ {"MIPS_CS_BASE", _MIPS_CS_BASE},
+#endif
+#ifdef _MIPS_CS_HOSTID
+ {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
+#endif
+#ifdef _MIPS_CS_HW_NAME
+ {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
+#endif
+#ifdef _MIPS_CS_NUM_PROCESSORS
+ {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_OSREL_MAJ
+ {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
+#endif
+#ifdef _MIPS_CS_OSREL_MIN
+ {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
+#endif
+#ifdef _MIPS_CS_OSREL_PATCH
+ {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
+#endif
+#ifdef _MIPS_CS_OS_NAME
+ {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
+#endif
+#ifdef _MIPS_CS_OS_PROVIDER
+ {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
+#endif
+#ifdef _MIPS_CS_PROCESSORS
+ {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_SERIAL
+ {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
+#endif
+#ifdef _MIPS_CS_VENDOR
+ {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
+#endif
+};
+
+static int
+conv_confstr_confname(PyObject *arg, int *valuep)
+{
+ return conv_confname(arg, valuep, posix_constants_confstr,
+ sizeof(posix_constants_confstr)
+ / sizeof(struct constdef));
+}
+
+PyDoc_STRVAR(posix_confstr__doc__,
+"confstr(name) -> string\n\n\
+Return a string-valued system configuration variable.");
+
+static PyObject *
+posix_confstr(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name;
+ char buffer[256];
+
+ if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
+ int len;
+
+ errno = 0;
+ len = confstr(name, buffer, sizeof(buffer));
+ if (len == 0) {
+ if (errno) {
+ posix_error();
+ }
+ else {
+ result = Py_None;
+ Py_INCREF(Py_None);
+ }
+ }
+ else {
+ if ((unsigned int)len >= sizeof(buffer)) {
+ result = PyString_FromStringAndSize(NULL, len-1);
+ if (result != NULL)
+ confstr(name, PyString_AS_STRING(result), len);
+ }
+ else
+ result = PyString_FromStringAndSize(buffer, len-1);
+ }
+ }
+ return result;
+}
+#endif
+
+
+#ifdef HAVE_SYSCONF
+static struct constdef posix_constants_sysconf[] = {
+#ifdef _SC_2_CHAR_TERM
+ {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
+#endif
+#ifdef _SC_2_C_BIND
+ {"SC_2_C_BIND", _SC_2_C_BIND},
+#endif
+#ifdef _SC_2_C_DEV
+ {"SC_2_C_DEV", _SC_2_C_DEV},
+#endif
+#ifdef _SC_2_C_VERSION
+ {"SC_2_C_VERSION", _SC_2_C_VERSION},
+#endif
+#ifdef _SC_2_FORT_DEV
+ {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
+#endif
+#ifdef _SC_2_FORT_RUN
+ {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
+#endif
+#ifdef _SC_2_LOCALEDEF
+ {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
+#endif
+#ifdef _SC_2_SW_DEV
+ {"SC_2_SW_DEV", _SC_2_SW_DEV},
+#endif
+#ifdef _SC_2_UPE
+ {"SC_2_UPE", _SC_2_UPE},
+#endif
+#ifdef _SC_2_VERSION
+ {"SC_2_VERSION", _SC_2_VERSION},
+#endif
+#ifdef _SC_ABI_ASYNCHRONOUS_IO
+ {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
+#endif
+#ifdef _SC_ACL
+ {"SC_ACL", _SC_ACL},
+#endif
+#ifdef _SC_AIO_LISTIO_MAX
+ {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
+#endif
+#ifdef _SC_AIO_MAX
+ {"SC_AIO_MAX", _SC_AIO_MAX},
+#endif
+#ifdef _SC_AIO_PRIO_DELTA_MAX
+ {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
+#endif
+#ifdef _SC_ARG_MAX
+ {"SC_ARG_MAX", _SC_ARG_MAX},
+#endif
+#ifdef _SC_ASYNCHRONOUS_IO
+ {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
+#endif
+#ifdef _SC_ATEXIT_MAX
+ {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
+#endif
+#ifdef _SC_AUDIT
+ {"SC_AUDIT", _SC_AUDIT},
+#endif
+#ifdef _SC_AVPHYS_PAGES
+ {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
+#endif
+#ifdef _SC_BC_BASE_MAX
+ {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
+#endif
+#ifdef _SC_BC_DIM_MAX
+ {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
+#endif
+#ifdef _SC_BC_SCALE_MAX
+ {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
+#endif
+#ifdef _SC_BC_STRING_MAX
+ {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
+#endif
+#ifdef _SC_CAP
+ {"SC_CAP", _SC_CAP},
+#endif
+#ifdef _SC_CHARCLASS_NAME_MAX
+ {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
+#endif
+#ifdef _SC_CHAR_BIT
+ {"SC_CHAR_BIT", _SC_CHAR_BIT},
+#endif
+#ifdef _SC_CHAR_MAX
+ {"SC_CHAR_MAX", _SC_CHAR_MAX},
+#endif
+#ifdef _SC_CHAR_MIN
+ {"SC_CHAR_MIN", _SC_CHAR_MIN},
+#endif
+#ifdef _SC_CHILD_MAX
+ {"SC_CHILD_MAX", _SC_CHILD_MAX},
+#endif
+#ifdef _SC_CLK_TCK
+ {"SC_CLK_TCK", _SC_CLK_TCK},
+#endif
+#ifdef _SC_COHER_BLKSZ
+ {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
+#endif
+#ifdef _SC_COLL_WEIGHTS_MAX
+ {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
+#endif
+#ifdef _SC_DCACHE_ASSOC
+ {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
+#endif
+#ifdef _SC_DCACHE_BLKSZ
+ {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
+#endif
+#ifdef _SC_DCACHE_LINESZ
+ {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
+#endif
+#ifdef _SC_DCACHE_SZ
+ {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
+#endif
+#ifdef _SC_DCACHE_TBLKSZ
+ {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
+#endif
+#ifdef _SC_DELAYTIMER_MAX
+ {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
+#endif
+#ifdef _SC_EQUIV_CLASS_MAX
+ {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
+#endif
+#ifdef _SC_EXPR_NEST_MAX
+ {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
+#endif
+#ifdef _SC_FSYNC
+ {"SC_FSYNC", _SC_FSYNC},
+#endif
+#ifdef _SC_GETGR_R_SIZE_MAX
+ {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
+#endif
+#ifdef _SC_GETPW_R_SIZE_MAX
+ {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
+#endif
+#ifdef _SC_ICACHE_ASSOC
+ {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
+#endif
+#ifdef _SC_ICACHE_BLKSZ
+ {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
+#endif
+#ifdef _SC_ICACHE_LINESZ
+ {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
+#endif
+#ifdef _SC_ICACHE_SZ
+ {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
+#endif
+#ifdef _SC_INF
+ {"SC_INF", _SC_INF},
+#endif
+#ifdef _SC_INT_MAX
+ {"SC_INT_MAX", _SC_INT_MAX},
+#endif
+#ifdef _SC_INT_MIN
+ {"SC_INT_MIN", _SC_INT_MIN},
+#endif
+#ifdef _SC_IOV_MAX
+ {"SC_IOV_MAX", _SC_IOV_MAX},
+#endif
+#ifdef _SC_IP_SECOPTS
+ {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
+#endif
+#ifdef _SC_JOB_CONTROL
+ {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
+#endif
+#ifdef _SC_KERN_POINTERS
+ {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
+#endif
+#ifdef _SC_KERN_SIM
+ {"SC_KERN_SIM", _SC_KERN_SIM},
+#endif
+#ifdef _SC_LINE_MAX
+ {"SC_LINE_MAX", _SC_LINE_MAX},
+#endif
+#ifdef _SC_LOGIN_NAME_MAX
+ {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
+#endif
+#ifdef _SC_LOGNAME_MAX
+ {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
+#endif
+#ifdef _SC_LONG_BIT
+ {"SC_LONG_BIT", _SC_LONG_BIT},
+#endif
+#ifdef _SC_MAC
+ {"SC_MAC", _SC_MAC},
+#endif
+#ifdef _SC_MAPPED_FILES
+ {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
+#endif
+#ifdef _SC_MAXPID
+ {"SC_MAXPID", _SC_MAXPID},
+#endif
+#ifdef _SC_MB_LEN_MAX
+ {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
+#endif
+#ifdef _SC_MEMLOCK
+ {"SC_MEMLOCK", _SC_MEMLOCK},
+#endif
+#ifdef _SC_MEMLOCK_RANGE
+ {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
+#endif
+#ifdef _SC_MEMORY_PROTECTION
+ {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
+#endif
+#ifdef _SC_MESSAGE_PASSING
+ {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
+#endif
+#ifdef _SC_MMAP_FIXED_ALIGNMENT
+ {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
+#endif
+#ifdef _SC_MQ_OPEN_MAX
+ {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
+#endif
+#ifdef _SC_MQ_PRIO_MAX
+ {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
+#endif
+#ifdef _SC_NACLS_MAX
+ {"SC_NACLS_MAX", _SC_NACLS_MAX},
+#endif
+#ifdef _SC_NGROUPS_MAX
+ {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
+#endif
+#ifdef _SC_NL_ARGMAX
+ {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
+#endif
+#ifdef _SC_NL_LANGMAX
+ {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
+#endif
+#ifdef _SC_NL_MSGMAX
+ {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
+#endif
+#ifdef _SC_NL_NMAX
+ {"SC_NL_NMAX", _SC_NL_NMAX},
+#endif
+#ifdef _SC_NL_SETMAX
+ {"SC_NL_SETMAX", _SC_NL_SETMAX},
+#endif
+#ifdef _SC_NL_TEXTMAX
+ {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
+#endif
+#ifdef _SC_NPROCESSORS_CONF
+ {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+ {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
+#endif
+#ifdef _SC_NPROC_CONF
+ {"SC_NPROC_CONF", _SC_NPROC_CONF},
+#endif
+#ifdef _SC_NPROC_ONLN
+ {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
+#endif
+#ifdef _SC_NZERO
+ {"SC_NZERO", _SC_NZERO},
+#endif
+#ifdef _SC_OPEN_MAX
+ {"SC_OPEN_MAX", _SC_OPEN_MAX},
+#endif
+#ifdef _SC_PAGESIZE
+ {"SC_PAGESIZE", _SC_PAGESIZE},
+#endif
+#ifdef _SC_PAGE_SIZE
+ {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
+#endif
+#ifdef _SC_PASS_MAX
+ {"SC_PASS_MAX", _SC_PASS_MAX},
+#endif
+#ifdef _SC_PHYS_PAGES
+ {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
+#endif
+#ifdef _SC_PII
+ {"SC_PII", _SC_PII},
+#endif
+#ifdef _SC_PII_INTERNET
+ {"SC_PII_INTERNET", _SC_PII_INTERNET},
+#endif
+#ifdef _SC_PII_INTERNET_DGRAM
+ {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
+#endif
+#ifdef _SC_PII_INTERNET_STREAM
+ {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
+#endif
+#ifdef _SC_PII_OSI
+ {"SC_PII_OSI", _SC_PII_OSI},
+#endif
+#ifdef _SC_PII_OSI_CLTS
+ {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
+#endif
+#ifdef _SC_PII_OSI_COTS
+ {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
+#endif
+#ifdef _SC_PII_OSI_M
+ {"SC_PII_OSI_M", _SC_PII_OSI_M},
+#endif
+#ifdef _SC_PII_SOCKET
+ {"SC_PII_SOCKET", _SC_PII_SOCKET},
+#endif
+#ifdef _SC_PII_XTI
+ {"SC_PII_XTI", _SC_PII_XTI},
+#endif
+#ifdef _SC_POLL
+ {"SC_POLL", _SC_POLL},
+#endif
+#ifdef _SC_PRIORITIZED_IO
+ {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
+#endif
+#ifdef _SC_PRIORITY_SCHEDULING
+ {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
+#endif
+#ifdef _SC_REALTIME_SIGNALS
+ {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
+#endif
+#ifdef _SC_RE_DUP_MAX
+ {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
+#endif
+#ifdef _SC_RTSIG_MAX
+ {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
+#endif
+#ifdef _SC_SAVED_IDS
+ {"SC_SAVED_IDS", _SC_SAVED_IDS},
+#endif
+#ifdef _SC_SCHAR_MAX
+ {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
+#endif
+#ifdef _SC_SCHAR_MIN
+ {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
+#endif
+#ifdef _SC_SELECT
+ {"SC_SELECT", _SC_SELECT},
+#endif
+#ifdef _SC_SEMAPHORES
+ {"SC_SEMAPHORES", _SC_SEMAPHORES},
+#endif
+#ifdef _SC_SEM_NSEMS_MAX
+ {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
+#endif
+#ifdef _SC_SEM_VALUE_MAX
+ {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
+#endif
+#ifdef _SC_SHARED_MEMORY_OBJECTS
+ {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
+#endif
+#ifdef _SC_SHRT_MAX
+ {"SC_SHRT_MAX", _SC_SHRT_MAX},
+#endif
+#ifdef _SC_SHRT_MIN
+ {"SC_SHRT_MIN", _SC_SHRT_MIN},
+#endif
+#ifdef _SC_SIGQUEUE_MAX
+ {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
+#endif
+#ifdef _SC_SIGRT_MAX
+ {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
+#endif
+#ifdef _SC_SIGRT_MIN
+ {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
+#endif
+#ifdef _SC_SOFTPOWER
+ {"SC_SOFTPOWER", _SC_SOFTPOWER},
+#endif
+#ifdef _SC_SPLIT_CACHE
+ {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
+#endif
+#ifdef _SC_SSIZE_MAX
+ {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
+#endif
+#ifdef _SC_STACK_PROT
+ {"SC_STACK_PROT", _SC_STACK_PROT},
+#endif
+#ifdef _SC_STREAM_MAX
+ {"SC_STREAM_MAX", _SC_STREAM_MAX},
+#endif
+#ifdef _SC_SYNCHRONIZED_IO
+ {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
+#endif
+#ifdef _SC_THREADS
+ {"SC_THREADS", _SC_THREADS},
+#endif
+#ifdef _SC_THREAD_ATTR_STACKADDR
+ {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
+#endif
+#ifdef _SC_THREAD_ATTR_STACKSIZE
+ {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
+#endif
+#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
+ {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
+#endif
+#ifdef _SC_THREAD_KEYS_MAX
+ {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
+#endif
+#ifdef _SC_THREAD_PRIORITY_SCHEDULING
+ {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
+#endif
+#ifdef _SC_THREAD_PRIO_INHERIT
+ {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
+#endif
+#ifdef _SC_THREAD_PRIO_PROTECT
+ {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
+#endif
+#ifdef _SC_THREAD_PROCESS_SHARED
+ {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
+#endif
+#ifdef _SC_THREAD_SAFE_FUNCTIONS
+ {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
+#endif
+#ifdef _SC_THREAD_STACK_MIN
+ {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
+#endif
+#ifdef _SC_THREAD_THREADS_MAX
+ {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
+#endif
+#ifdef _SC_TIMERS
+ {"SC_TIMERS", _SC_TIMERS},
+#endif
+#ifdef _SC_TIMER_MAX
+ {"SC_TIMER_MAX", _SC_TIMER_MAX},
+#endif
+#ifdef _SC_TTY_NAME_MAX
+ {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
+#endif
+#ifdef _SC_TZNAME_MAX
+ {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
+#endif
+#ifdef _SC_T_IOV_MAX
+ {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
+#endif
+#ifdef _SC_UCHAR_MAX
+ {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
+#endif
+#ifdef _SC_UINT_MAX
+ {"SC_UINT_MAX", _SC_UINT_MAX},
+#endif
+#ifdef _SC_UIO_MAXIOV
+ {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
+#endif
+#ifdef _SC_ULONG_MAX
+ {"SC_ULONG_MAX", _SC_ULONG_MAX},
+#endif
+#ifdef _SC_USHRT_MAX
+ {"SC_USHRT_MAX", _SC_USHRT_MAX},
+#endif
+#ifdef _SC_VERSION
+ {"SC_VERSION", _SC_VERSION},
+#endif
+#ifdef _SC_WORD_BIT
+ {"SC_WORD_BIT", _SC_WORD_BIT},
+#endif
+#ifdef _SC_XBS5_ILP32_OFF32
+ {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
+#endif
+#ifdef _SC_XBS5_ILP32_OFFBIG
+ {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
+#endif
+#ifdef _SC_XBS5_LP64_OFF64
+ {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
+#endif
+#ifdef _SC_XBS5_LPBIG_OFFBIG
+ {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
+#endif
+#ifdef _SC_XOPEN_CRYPT
+ {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
+#endif
+#ifdef _SC_XOPEN_ENH_I18N
+ {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
+#endif
+#ifdef _SC_XOPEN_LEGACY
+ {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
+#endif
+#ifdef _SC_XOPEN_REALTIME
+ {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
+#endif
+#ifdef _SC_XOPEN_REALTIME_THREADS
+ {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
+#endif
+#ifdef _SC_XOPEN_SHM
+ {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
+#endif
+#ifdef _SC_XOPEN_UNIX
+ {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
+#endif
+#ifdef _SC_XOPEN_VERSION
+ {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
+#endif
+#ifdef _SC_XOPEN_XCU_VERSION
+ {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
+#endif
+#ifdef _SC_XOPEN_XPG2
+ {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
+#endif
+#ifdef _SC_XOPEN_XPG3
+ {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
+#endif
+#ifdef _SC_XOPEN_XPG4
+ {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
+#endif
+};
+
+static int
+conv_sysconf_confname(PyObject *arg, int *valuep)
+{
+ return conv_confname(arg, valuep, posix_constants_sysconf,
+ sizeof(posix_constants_sysconf)
+ / sizeof(struct constdef));
+}
+
+PyDoc_STRVAR(posix_sysconf__doc__,
+"sysconf(name) -> integer\n\n\
+Return an integer-valued system configuration variable.");
+
+static PyObject *
+posix_sysconf(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name;
+
+ if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
+ int value;
+
+ errno = 0;
+ value = sysconf(name);
+ if (value == -1 && errno != 0)
+ posix_error();
+ else
+ result = PyInt_FromLong(value);
+ }
+ return result;
+}
+#endif
+
+
+/* This code is used to ensure that the tables of configuration value names
+ * are in sorted order as required by conv_confname(), and also to build the
+ * the exported dictionaries that are used to publish information about the
+ * names available on the host platform.
+ *
+ * Sorting the table at runtime ensures that the table is properly ordered
+ * when used, even for platforms we're not able to test on. It also makes
+ * it easier to add additional entries to the tables.
+ */
+
+static int
+cmp_constdefs(const void *v1, const void *v2)
+{
+ const struct constdef *c1 =
+ (const struct constdef *) v1;
+ const struct constdef *c2 =
+ (const struct constdef *) v2;
+
+ return strcmp(c1->name, c2->name);
+}
+
+static int
+setup_confname_table(struct constdef *table, size_t tablesize,
+ char *tablename, PyObject *module)
+{
+ PyObject *d = NULL;
+ size_t i;
+
+ qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
+ d = PyDict_New();
+ if (d == NULL)
+ return -1;
+
+ for (i=0; i < tablesize; ++i) {
+ PyObject *o = PyInt_FromLong(table[i].value);
+ if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
+ Py_XDECREF(o);
+ Py_DECREF(d);
+ return -1;
+ }
+ Py_DECREF(o);
+ }
+ return PyModule_AddObject(module, tablename, d);
+}
+
+/* Return -1 on failure, 0 on success. */
+static int
+setup_confname_tables(PyObject *module)
+{
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
+ if (setup_confname_table(posix_constants_pathconf,
+ sizeof(posix_constants_pathconf)
+ / sizeof(struct constdef),
+ "pathconf_names", module))
+ return -1;
+#endif
+#ifdef HAVE_CONFSTR
+ if (setup_confname_table(posix_constants_confstr,
+ sizeof(posix_constants_confstr)
+ / sizeof(struct constdef),
+ "confstr_names", module))
+ return -1;
+#endif
+#ifdef HAVE_SYSCONF
+ if (setup_confname_table(posix_constants_sysconf,
+ sizeof(posix_constants_sysconf)
+ / sizeof(struct constdef),
+ "sysconf_names", module))
+ return -1;
+#endif
+ return 0;
+}
+
+
+PyDoc_STRVAR(posix_abort__doc__,
+"abort() -> does not return!\n\n\
+Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
+in the hardest way possible on the hosting operating system.");
+
+static PyObject *
+posix_abort(PyObject *self, PyObject *noargs)
+{
+ abort();
+ /*NOTREACHED*/
+ Py_FatalError("abort() called from Python code didn't abort!");
+ return NULL;
+}
+
+#ifdef MS_WINDOWS
+PyDoc_STRVAR(win32_startfile__doc__,
+"startfile(filepath [, operation]) - Start a file with its associated\n\
+application.\n\
+\n\
+When \"operation\" is not specified or \"open\", this acts like\n\
+double-clicking the file in Explorer, or giving the file name as an\n\
+argument to the DOS \"start\" command: the file is opened with whatever\n\
+application (if any) its extension is associated.\n\
+When another \"operation\" is given, it specifies what should be done with\n\
+the file. A typical operation is \"print\".\n\
+\n\
+startfile returns as soon as the associated application is launched.\n\
+There is no option to wait for the application to close, and no way\n\
+to retrieve the application's exit status.\n\
+\n\
+The filepath is relative to the current directory. If you want to use\n\
+an absolute path, make sure the first character is not a slash (\"/\");\n\
+the underlying Win32 ShellExecute function doesn't work if it is.");
+
+static PyObject *
+win32_startfile(PyObject *self, PyObject *args)
+{
+ char *filepath;
+ char *operation = NULL;
+ HINSTANCE rc;
+#ifdef Py_WIN_WIDE_FILENAMES
+ if (unicode_file_names()) {
+ PyObject *unipath, *woperation = NULL;
+ if (!PyArg_ParseTuple(args, "U|s:startfile",
+ &unipath, &operation)) {
+ PyErr_Clear();
+ goto normal;
+ }
+
+
+ if (operation) {
+ woperation = PyUnicode_DecodeASCII(operation,
+ strlen(operation), NULL);
+ if (!woperation) {
+ PyErr_Clear();
+ operation = NULL;
+ goto normal;
+ }
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
+ PyUnicode_AS_UNICODE(unipath),
+ NULL, NULL, SW_SHOWNORMAL);
+ Py_END_ALLOW_THREADS
+
+ Py_XDECREF(woperation);
+ if (rc <= (HINSTANCE)32) {
+ PyObject *errval = win32_error_unicode("startfile",
+ PyUnicode_AS_UNICODE(unipath));
+ return errval;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+#endif
+
+normal:
+ if (!PyArg_ParseTuple(args, "et|s:startfile",
+ Py_FileSystemDefaultEncoding, &filepath,
+ &operation))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rc = ShellExecute((HWND)0, operation, filepath,
+ NULL, NULL, SW_SHOWNORMAL);
+ Py_END_ALLOW_THREADS
+ if (rc <= (HINSTANCE)32) {
+ PyObject *errval = win32_error("startfile", filepath);
+ PyMem_Free(filepath);
+ return errval;
+ }
+ PyMem_Free(filepath);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_GETLOADAVG
+PyDoc_STRVAR(posix_getloadavg__doc__,
+"getloadavg() -> (float, float, float)\n\n\
+Return the number of processes in the system run queue averaged over\n\
+the last 1, 5, and 15 minutes or raises OSError if the load average\n\
+was unobtainable");
+
+static PyObject *
+posix_getloadavg(PyObject *self, PyObject *noargs)
+{
+ double loadavg[3];
+ if (getloadavg(loadavg, 3)!=3) {
+ PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
+ return NULL;
+ } else
+ return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
+}
+#endif
+
+#ifdef MS_WINDOWS
+
+PyDoc_STRVAR(win32_urandom__doc__,
+"urandom(n) -> str\n\n\
+Return a string of n random bytes suitable for cryptographic use.");
+
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
+ LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
+ DWORD dwFlags );
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
+ BYTE *pbBuffer );
+
+static CRYPTGENRANDOM pCryptGenRandom = NULL;
+static HCRYPTPROV hCryptProv = 0;
+
+static PyObject*
+win32_urandom(PyObject *self, PyObject *args)
+{
+ int howMany;
+ PyObject* result;
+
+ /* Read arguments */
+ if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
+ return NULL;
+ if (howMany < 0)
+ return PyErr_Format(PyExc_ValueError,
+ "negative argument not allowed");
+
+ if (hCryptProv == 0) {
+ HINSTANCE hAdvAPI32 = NULL;
+ CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
+
+ /* Obtain handle to the DLL containing CryptoAPI
+ This should not fail */
+ hAdvAPI32 = GetModuleHandle("advapi32.dll");
+ if(hAdvAPI32 == NULL)
+ return win32_error("GetModuleHandle", NULL);
+
+ /* Obtain pointers to the CryptoAPI functions
+ This will fail on some early versions of Win95 */
+ pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
+ hAdvAPI32,
+ "CryptAcquireContextA");
+ if (pCryptAcquireContext == NULL)
+ return PyErr_Format(PyExc_NotImplementedError,
+ "CryptAcquireContextA not found");
+
+ pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
+ hAdvAPI32, "CryptGenRandom");
+ if (pCryptGenRandom == NULL)
+ return PyErr_Format(PyExc_NotImplementedError,
+ "CryptGenRandom not found");
+
+ /* Acquire context */
+ if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ return win32_error("CryptAcquireContext", NULL);
+ }
+
+ /* Allocate bytes */
+ result = PyString_FromStringAndSize(NULL, howMany);
+ if (result != NULL) {
+ /* Get random data */
+ if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
+ PyString_AS_STRING(result))) {
+ Py_DECREF(result);
+ return win32_error("CryptGenRandom", NULL);
+ }
+ }
+ return result;
+}
+#endif
+
+#ifdef __VMS
+/* Use openssl random routine */
+#include <openssl/rand.h>
+PyDoc_STRVAR(vms_urandom__doc__,
+"urandom(n) -> str\n\n\
+Return a string of n random bytes suitable for cryptographic use.");
+
+static PyObject*
+vms_urandom(PyObject *self, PyObject *args)
+{
+ int howMany;
+ PyObject* result;
+
+ /* Read arguments */
+ if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
+ return NULL;
+ if (howMany < 0)
+ return PyErr_Format(PyExc_ValueError,
+ "negative argument not allowed");
+
+ /* Allocate bytes */
+ result = PyString_FromStringAndSize(NULL, howMany);
+ if (result != NULL) {
+ /* Get random data */
+ if (RAND_pseudo_bytes((unsigned char*)
+ PyString_AS_STRING(result),
+ howMany) < 0) {
+ Py_DECREF(result);
+ return PyErr_Format(PyExc_ValueError,
+ "RAND_pseudo_bytes");
+ }
+ }
+ return result;
+}
+#endif
+
+static PyMethodDef posix_methods[] = {
+ {"access", posix_access, METH_VARARGS, posix_access__doc__},
+#ifdef HAVE_TTYNAME
+ {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
+#endif
+ {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
+ {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
+#ifdef HAVE_CHOWN
+ {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
+#endif /* HAVE_CHOWN */
+#ifdef HAVE_LCHOWN
+ {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
+#endif /* HAVE_LCHOWN */
+#ifdef HAVE_CHROOT
+ {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
+#endif
+#ifdef HAVE_CTERMID
+ {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
+#endif
+#ifdef HAVE_GETCWD
+ {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
+#ifdef Py_USING_UNICODE
+ {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
+#endif
+#endif
+#ifdef HAVE_LINK
+ {"link", posix_link, METH_VARARGS, posix_link__doc__},
+#endif /* HAVE_LINK */
+ {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
+ {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
+ {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
+#ifdef HAVE_NICE
+ {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
+#endif /* HAVE_NICE */
+#ifdef HAVE_READLINK
+ {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
+#endif /* HAVE_READLINK */
+ {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
+ {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
+ {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
+ {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
+#ifdef HAVE_SYMLINK
+ {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
+#endif /* HAVE_SYMLINK */
+#ifdef HAVE_SYSTEM
+ {"system", posix_system, METH_VARARGS, posix_system__doc__},
+#endif
+ {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
+#ifdef HAVE_UNAME
+ {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
+#endif /* HAVE_UNAME */
+ {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
+ {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
+ {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
+#ifdef HAVE_TIMES
+ {"times", posix_times, METH_NOARGS, posix_times__doc__},
+#endif /* HAVE_TIMES */
+ {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
+#ifdef HAVE_EXECV
+ {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
+ {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
+#endif /* HAVE_EXECV */
+#ifdef HAVE_SPAWNV
+ {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
+ {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
+#if defined(PYOS_OS2)
+ {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
+ {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
+#endif /* PYOS_OS2 */
+#endif /* HAVE_SPAWNV */
+#ifdef HAVE_FORK1
+ {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
+#endif /* HAVE_FORK1 */
+#ifdef HAVE_FORK
+ {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
+#endif /* HAVE_FORK */
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
+ {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
+#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
+#ifdef HAVE_FORKPTY
+ {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
+#endif /* HAVE_FORKPTY */
+#ifdef HAVE_GETEGID
+ {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
+#endif /* HAVE_GETEGID */
+#ifdef HAVE_GETEUID
+ {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
+#endif /* HAVE_GETEUID */
+#ifdef HAVE_GETGID
+ {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
+#endif /* HAVE_GETGID */
+#ifdef HAVE_GETGROUPS
+ {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
+#endif
+ {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
+#ifdef HAVE_GETPGRP
+ {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
+#endif /* HAVE_GETPGRP */
+#ifdef HAVE_GETPPID
+ {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
+#endif /* HAVE_GETPPID */
+#ifdef HAVE_GETUID
+ {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
+#endif /* HAVE_GETUID */
+#ifdef HAVE_GETLOGIN
+ {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
+#endif
+#ifdef HAVE_KILL
+ {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
+#endif /* HAVE_KILL */
+#ifdef HAVE_KILLPG
+ {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
+#endif /* HAVE_KILLPG */
+#ifdef HAVE_PLOCK
+ {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
+#endif /* HAVE_PLOCK */
+#ifdef HAVE_POPEN
+ {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
+#ifdef MS_WINDOWS
+ {"popen2", win32_popen2, METH_VARARGS},
+ {"popen3", win32_popen3, METH_VARARGS},
+ {"popen4", win32_popen4, METH_VARARGS},
+ {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ {"popen2", os2emx_popen2, METH_VARARGS},
+ {"popen3", os2emx_popen3, METH_VARARGS},
+ {"popen4", os2emx_popen4, METH_VARARGS},
+#endif
+#endif
+#endif /* HAVE_POPEN */
+#ifdef HAVE_SETUID
+ {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
+#endif /* HAVE_SETUID */
+#ifdef HAVE_SETEUID
+ {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
+#endif /* HAVE_SETEUID */
+#ifdef HAVE_SETEGID
+ {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
+#endif /* HAVE_SETEGID */
+#ifdef HAVE_SETREUID
+ {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
+#endif /* HAVE_SETREUID */
+#ifdef HAVE_SETREGID
+ {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
+#endif /* HAVE_SETREGID */
+#ifdef HAVE_SETGID
+ {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
+#endif /* HAVE_SETGID */
+#ifdef HAVE_SETGROUPS
+ {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
+#endif /* HAVE_SETGROUPS */
+#ifdef HAVE_GETPGID
+ {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
+#endif /* HAVE_GETPGID */
+#ifdef HAVE_SETPGRP
+ {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
+#endif /* HAVE_SETPGRP */
+#ifdef HAVE_WAIT
+ {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
+#endif /* HAVE_WAIT */
+#ifdef HAVE_WAIT3
+ {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
+#endif /* HAVE_WAIT3 */
+#ifdef HAVE_WAIT4
+ {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
+#endif /* HAVE_WAIT4 */
+#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
+ {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
+#endif /* HAVE_WAITPID */
+#ifdef HAVE_GETSID
+ {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
+#endif /* HAVE_GETSID */
+#ifdef HAVE_SETSID
+ {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
+#endif /* HAVE_SETSID */
+#ifdef HAVE_SETPGID
+ {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
+#endif /* HAVE_SETPGID */
+#ifdef HAVE_TCGETPGRP
+ {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
+#endif /* HAVE_TCGETPGRP */
+#ifdef HAVE_TCSETPGRP
+ {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
+#endif /* HAVE_TCSETPGRP */
+ {"open", posix_open, METH_VARARGS, posix_open__doc__},
+ {"close", posix_close, METH_VARARGS, posix_close__doc__},
+ {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
+ {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
+ {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
+ {"read", posix_read, METH_VARARGS, posix_read__doc__},
+ {"write", posix_write, METH_VARARGS, posix_write__doc__},
+ {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
+ {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
+ {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
+#ifdef HAVE_PIPE
+ {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
+#endif
+#ifdef HAVE_MKFIFO
+ {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
+#endif
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+ {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
+#endif
+#ifdef HAVE_DEVICE_MACROS
+ {"major", posix_major, METH_VARARGS, posix_major__doc__},
+ {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
+ {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
+#endif
+#ifdef HAVE_FTRUNCATE
+ {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
+#endif
+#ifdef HAVE_PUTENV
+ {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
+#endif
+#ifdef HAVE_UNSETENV
+ {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
+#endif
+#ifdef HAVE_STRERROR
+ {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
+#endif
+#ifdef HAVE_FCHDIR
+ {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
+#endif
+#ifdef HAVE_FSYNC
+ {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
+#endif
+#ifdef HAVE_FDATASYNC
+ {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#ifdef WCOREDUMP
+ {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
+#endif /* WCOREDUMP */
+#ifdef WIFCONTINUED
+ {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
+#endif /* WIFCONTINUED */
+#ifdef WIFSTOPPED
+ {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
+#endif /* WIFSTOPPED */
+#ifdef WIFSIGNALED
+ {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
+#endif /* WIFSIGNALED */
+#ifdef WIFEXITED
+ {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
+#endif /* WIFEXITED */
+#ifdef WEXITSTATUS
+ {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
+#endif /* WEXITSTATUS */
+#ifdef WTERMSIG
+ {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
+#endif /* WTERMSIG */
+#ifdef WSTOPSIG
+ {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
+#endif /* WSTOPSIG */
+#endif /* HAVE_SYS_WAIT_H */
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
+ {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
+#endif
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
+ {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
+#endif
+#ifdef HAVE_TMPFILE
+ {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
+#endif
+#ifdef HAVE_TEMPNAM
+ {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
+#endif
+#ifdef HAVE_TMPNAM
+ {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
+#endif
+#ifdef HAVE_CONFSTR
+ {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
+#endif
+#ifdef HAVE_SYSCONF
+ {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
+#endif
+#ifdef HAVE_FPATHCONF
+ {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
+#endif
+#ifdef HAVE_PATHCONF
+ {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
+#endif
+ {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
+#ifdef MS_WINDOWS
+ {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
+#endif
+#ifdef HAVE_GETLOADAVG
+ {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
+#endif
+ #ifdef MS_WINDOWS
+ {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
+ #endif
+ #ifdef __VMS
+ {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
+ #endif
+ {NULL, NULL} /* Sentinel */
+};
+
+
+static int
+ins(PyObject *module, char *symbol, long value)
+{
+ return PyModule_AddIntConstant(module, symbol, value);
+}
+
+#if defined(PYOS_OS2)
+/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
+static int insertvalues(PyObject *module)
+{
+ APIRET rc;
+ ULONG values[QSV_MAX+1];
+ PyObject *v;
+ char *ver, tmp[50];
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
+ Py_END_ALLOW_THREADS
+
+ if (rc != NO_ERROR) {
+ os2_error(rc);
+ return -1;
+ }
+
+ if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
+ if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
+ if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
+ if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
+ if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
+ if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
+ if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
+
+ switch (values[QSV_VERSION_MINOR]) {
+ case 0: ver = "2.00"; break;
+ case 10: ver = "2.10"; break;
+ case 11: ver = "2.11"; break;
+ case 30: ver = "3.00"; break;
+ case 40: ver = "4.00"; break;
+ case 50: ver = "5.00"; break;
+ default:
+ PyOS_snprintf(tmp, sizeof(tmp),
+ "%d-%d", values[QSV_VERSION_MAJOR],
+ values[QSV_VERSION_MINOR]);
+ ver = &tmp[0];
+ }
+
+ /* Add Indicator of the Version of the Operating System */
+ if (PyModule_AddStringConstant(module, "version", tmp) < 0)
+ return -1;
+
+ /* Add Indicator of Which Drive was Used to Boot the System */
+ tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
+ tmp[1] = ':';
+ tmp[2] = '\0';
+
+ return PyModule_AddStringConstant(module, "bootdrive", tmp);
+}
+#endif
+
+static int
+all_ins(PyObject *d)
+{
+#ifdef F_OK
+ if (ins(d, "F_OK", (long)F_OK)) return -1;
+#endif
+#ifdef R_OK
+ if (ins(d, "R_OK", (long)R_OK)) return -1;
+#endif
+#ifdef W_OK
+ if (ins(d, "W_OK", (long)W_OK)) return -1;
+#endif
+#ifdef X_OK
+ if (ins(d, "X_OK", (long)X_OK)) return -1;
+#endif
+#ifdef NGROUPS_MAX
+ if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
+#endif
+#ifdef TMP_MAX
+ if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
+#endif
+#ifdef WCONTINUED
+ if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
+#endif
+#ifdef WNOHANG
+ if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
+#endif
+#ifdef WUNTRACED
+ if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
+#endif
+#ifdef O_RDONLY
+ if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
+#endif
+#ifdef O_WRONLY
+ if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
+#endif
+#ifdef O_RDWR
+ if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
+#endif
+#ifdef O_NDELAY
+ if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
+#endif
+#ifdef O_NONBLOCK
+ if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
+#endif
+#ifdef O_APPEND
+ if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
+#endif
+#ifdef O_DSYNC
+ if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
+#endif
+#ifdef O_RSYNC
+ if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
+#endif
+#ifdef O_SYNC
+ if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
+#endif
+#ifdef O_NOCTTY
+ if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
+#endif
+#ifdef O_CREAT
+ if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
+#endif
+#ifdef O_EXCL
+ if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
+#endif
+#ifdef O_TRUNC
+ if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
+#endif
+#ifdef O_BINARY
+ if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
+#endif
+#ifdef O_TEXT
+ if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
+#endif
+#ifdef O_LARGEFILE
+ if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
+#endif
+#ifdef O_SHLOCK
+ if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
+#endif
+#ifdef O_EXLOCK
+ if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
+#endif
+
+/* MS Windows */
+#ifdef O_NOINHERIT
+ /* Don't inherit in child processes. */
+ if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
+#endif
+#ifdef _O_SHORT_LIVED
+ /* Optimize for short life (keep in memory). */
+ /* MS forgot to define this one with a non-underscore form too. */
+ if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
+#endif
+#ifdef O_TEMPORARY
+ /* Automatically delete when last handle is closed. */
+ if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
+#endif
+#ifdef O_RANDOM
+ /* Optimize for random access. */
+ if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
+#endif
+#ifdef O_SEQUENTIAL
+ /* Optimize for sequential access. */
+ if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
+#endif
+
+/* GNU extensions. */
+#ifdef O_DIRECT
+ /* Direct disk access. */
+ if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
+#endif
+#ifdef O_DIRECTORY
+ /* Must be a directory. */
+ if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
+#endif
+#ifdef O_NOFOLLOW
+ /* Do not follow links. */
+ if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
+#endif
+
+ /* These come from sysexits.h */
+#ifdef EX_OK
+ if (ins(d, "EX_OK", (long)EX_OK)) return -1;
+#endif /* EX_OK */
+#ifdef EX_USAGE
+ if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
+#endif /* EX_USAGE */
+#ifdef EX_DATAERR
+ if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
+#endif /* EX_DATAERR */
+#ifdef EX_NOINPUT
+ if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
+#endif /* EX_NOINPUT */
+#ifdef EX_NOUSER
+ if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
+#endif /* EX_NOUSER */
+#ifdef EX_NOHOST
+ if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
+#endif /* EX_NOHOST */
+#ifdef EX_UNAVAILABLE
+ if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
+#endif /* EX_UNAVAILABLE */
+#ifdef EX_SOFTWARE
+ if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
+#endif /* EX_SOFTWARE */
+#ifdef EX_OSERR
+ if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
+#endif /* EX_OSERR */
+#ifdef EX_OSFILE
+ if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
+#endif /* EX_OSFILE */
+#ifdef EX_CANTCREAT
+ if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
+#endif /* EX_CANTCREAT */
+#ifdef EX_IOERR
+ if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
+#endif /* EX_IOERR */
+#ifdef EX_TEMPFAIL
+ if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
+#endif /* EX_TEMPFAIL */
+#ifdef EX_PROTOCOL
+ if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
+#endif /* EX_PROTOCOL */
+#ifdef EX_NOPERM
+ if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
+#endif /* EX_NOPERM */
+#ifdef EX_CONFIG
+ if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
+#endif /* EX_CONFIG */
+#ifdef EX_NOTFOUND
+ if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
+#endif /* EX_NOTFOUND */
+
+#ifdef HAVE_SPAWNV
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
+ if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
+ if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
+ if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
+ if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
+ if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
+ if (ins(d, "P_PM", (long)P_PM)) return -1;
+ if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
+ if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
+ if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
+ if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
+ if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
+ if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
+ if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
+ if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
+ if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
+ if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
+ if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
+ if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
+ if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
+#else
+ if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
+ if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
+ if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
+ if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
+ if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
+#endif
+#endif
+
+#if defined(PYOS_OS2)
+ if (insertvalues(d)) return -1;
+#endif
+ return 0;
+}
+
+
+#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
+#define INITFUNC initnt
+#define MODNAME "nt"
+
+#elif defined(PYOS_OS2)
+#define INITFUNC initos2
+#define MODNAME "os2"
+
+#else
+#define INITFUNC initposix
+#define MODNAME "posix"
+#endif
+
+PyMODINIT_FUNC
+INITFUNC(void)
+{
+ PyObject *m, *v;
+
+ m = Py_InitModule3(MODNAME,
+ posix_methods,
+ posix__doc__);
+ if (m == NULL)
+ return;
+
+ /* Initialize environ dictionary */
+ v = convertenviron();
+ Py_XINCREF(v);
+ if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
+ return;
+ Py_DECREF(v);
+
+ if (all_ins(m))
+ return;
+
+ if (setup_confname_tables(m))
+ return;
+
+ Py_INCREF(PyExc_OSError);
+ PyModule_AddObject(m, "error", PyExc_OSError);
+
+#ifdef HAVE_PUTENV
+ if (posix_putenv_garbage == NULL)
+ posix_putenv_garbage = PyDict_New();
+#endif
+
+ if (!initialized) {
+ stat_result_desc.name = MODNAME ".stat_result";
+ stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
+ stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
+ stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
+ PyStructSequence_InitType(&StatResultType, &stat_result_desc);
+ structseq_new = StatResultType.tp_new;
+ StatResultType.tp_new = statresult_new;
+
+ statvfs_result_desc.name = MODNAME ".statvfs_result";
+ PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
+ }
+ Py_INCREF((PyObject*) &StatResultType);
+ PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
+ Py_INCREF((PyObject*) &StatVFSResultType);
+ PyModule_AddObject(m, "statvfs_result",
+ (PyObject*) &StatVFSResultType);
+ initialized = 1;
+
+#ifdef __APPLE__
+ /*
+ * Step 2 of weak-linking support on Mac OS X.
+ *
+ * The code below removes functions that are not available on the
+ * currently active platform.
+ *
+ * This block allow one to use a python binary that was build on
+ * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
+ * OSX 10.4.
+ */
+#ifdef HAVE_FSTATVFS
+ if (fstatvfs == NULL) {
+ if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
+ return;
+ }
+ }
+#endif /* HAVE_FSTATVFS */
+
+#ifdef HAVE_STATVFS
+ if (statvfs == NULL) {
+ if (PyObject_DelAttrString(m, "statvfs") == -1) {
+ return;
+ }
+ }
+#endif /* HAVE_STATVFS */
+
+# ifdef HAVE_LCHOWN
+ if (lchown == NULL) {
+ if (PyObject_DelAttrString(m, "lchown") == -1) {
+ return;
+ }
+ }
+#endif /* HAVE_LCHOWN */
+
+
+#endif /* __APPLE__ */
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/sys/src/cmd/python/Modules/puremodule.c b/sys/src/cmd/python/Modules/puremodule.c
new file mode 100644
index 000000000..95f4bdecd
--- /dev/null
+++ b/sys/src/cmd/python/Modules/puremodule.c
@@ -0,0 +1,988 @@
+/* This module exports the C API to such Pure Software Inc. (tm) (now
+ * called Pure Atria Corporation) products as Purify (tm) and Quantify
+ * (tm). Other packages could be added, but I didn't have those products
+ * and thus lack the API documentation.
+ *
+ * Currently supported: Quantify 2.x, Purify 3.x
+ *
+ * You need to decide which products you want to incorporate into the
+ * module when you compile this file. The way to do this is to edit
+ * <Python>/Modules/Setup to pass the appropriate flags to the compiler.
+ * -DWITH_PURIFY compiles in the Purify support, and -DWITH_QUANTIFY
+ * compiles in the Quantify support. -DWITH_ALL_PURE compiles in both.
+ * You can also build a Purify'd or Quantify'd interpreter by passing in
+ * the LINKCC variable to make. E.g. if you want to build a Purify'd
+ * interpreter and are using gcc, build Python with this command:
+ *
+ * make LINKCC='purify gcc'
+ *
+ * It would be nice (and probably easy) to provide this file as a shared
+ * library, however since it doesn't appear that Pure gives us shared
+ * libraries of the stubs, it doesn't really matter. For now, you have to
+ * link this file in statically.
+ *
+ * Major bogosity. The purify.h header file exports purify_exit(), but
+ * guess what? It is not defined in the libpurify_stubs.a file! I tried
+ * to fake one here, hoping the Pure linker would Do The Right Thing when
+ * instrumented for Purify, but it doesn't seem to, so I don't export
+ * purify_exit() to the Python layer. In Python you should raise a
+ * SystemExit exception anyway.
+ *
+ * The actual purify.h and quantify.h files which embody the APIs are
+ * copyrighted by Pure Software, Inc. and are only attainable through them.
+ * This module assumes you have legally installed licenses of their
+ * software. Contact them on the Web via <http://www.pureatria.com/>
+ *
+ * Author: Barry Warsaw <bwarsaw@python.org>
+ * <bwarsaw@cnri.reston.va.us>
+ */
+
+#include "Python.h"
+
+#if defined(WITH_PURIFY) || defined(WITH_ALL_PURE)
+# include <purify.h>
+# define HAS_PURIFY_EXIT 0 /* See note at top of file */
+# define PURE_PURIFY_VERSION 3 /* not provided by purify.h */
+#endif
+#if defined(WITH_QUANTIFY) || defined(WITH_ALL_PURE)
+# include <quantify.h>
+# define PURE_QUANTIFY_VERSION 2 /* not provided by quantify.h */
+#endif
+#if defined(PURIFY_H) || defined(QUANTIFY_H)
+# define COMMON_PURE_FUNCTIONS
+#endif /* PURIFY_H || QUANTIFY_H */
+
+typedef int (*VoidArgFunc)(void);
+typedef int (*StringArgFunc)(char*);
+typedef int (*PrintfishFunc)(const char*, ...);
+typedef int (*StringIntArgFunc)(const char*, int);
+
+
+
+static PyObject*
+call_voidarg_function(VoidArgFunc func, PyObject *self, PyObject *args)
+{
+ int status;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ status = func();
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_stringarg_function(StringArgFunc func, PyObject *self, PyObject *args)
+{
+ int status;
+ char* stringarg;
+
+ if (!PyArg_ParseTuple(args, "s", &stringarg))
+ return NULL;
+
+ status = func(stringarg);
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_stringorint_function(StringArgFunc func, PyObject *self, PyObject *args)
+{
+ int status;
+ int intarg;
+ char* stringarg;
+
+ /* according to the quantify.h file, the argument to
+ * quantify_*_recording_system_call can be an integer or a string,
+ * but the functions are prototyped as taking a single char*
+ * argument. Yikes!
+ */
+ if (PyArg_ParseTuple(args, "i", &intarg))
+ /* func is prototyped as int(*)(char*)
+ * better shut up the compiler
+ */
+ status = func((char*)intarg);
+
+ else {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "s", &stringarg))
+ return NULL;
+ else
+ status = func(stringarg);
+ }
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_printfish_function(PrintfishFunc func, PyObject *self, PyObject *args)
+{
+ /* we support the printf() style vararg functions by requiring the
+ * formatting be done in Python. At the C level we pass just a string
+ * to the printf() style function.
+ */
+ int status;
+ char* argstring;
+
+ if (!PyArg_ParseTuple(args, "s", &argstring))
+ return NULL;
+
+ status = func("%s", argstring);
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+call_intasaddr_function(StringArgFunc func, PyObject *self, PyObject *args)
+{
+ long memrep;
+ int id;
+
+ if (!PyArg_ParseTuple(args, "l", &memrep))
+ return NULL;
+
+ id = func((char*)memrep);
+ return Py_BuildValue("i", id);
+}
+
+static PyObject*
+call_stringandint_function(StringIntArgFunc func, PyObject *self,
+ PyObject *args)
+{
+ long srcrep;
+ int size;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "li", &srcrep, &size))
+ return NULL;
+
+ status = func((char*)srcrep, size);
+ return Py_BuildValue("i", status);
+}
+
+
+
+/* functions common to all products
+ *
+ * N.B. These printf() style functions are a bit of a kludge. Since the
+ * API doesn't provide vprintf versions of them, we can't call them
+ * directly. They don't support all the standard printf % modifiers
+ * anyway. The way to use these is to use Python's % string operator to do
+ * the formatting. By the time these functions get the thing to print,
+ * it's already a string, and they just use "%s" as the format string.
+ */
+
+#ifdef COMMON_PURE_FUNCTIONS
+
+static PyObject*
+pure_pure_logfile_printf(PyObject* self, PyObject* args)
+{
+ return call_printfish_function(pure_logfile_printf, self, args);
+}
+
+static PyObject*
+pure_pure_printf(PyObject* self, PyObject* args)
+{
+ return call_printfish_function(pure_printf, self, args);
+}
+
+static PyObject*
+pure_pure_printf_with_banner(PyObject* self, PyObject* args)
+{
+ return call_printfish_function(pure_printf_with_banner, self, args);
+}
+
+
+#endif /* COMMON_PURE_FUNCTIONS */
+
+
+
+/* Purify functions
+ *
+ * N.B. There are some interfaces described in the purify.h file that are
+ * not described in the manual.
+ *
+ * Unsigned longs purify_report_{address,number,type,result} are not
+ * accessible from the Python layer since they seem mostly useful when
+ * purify_stop_here() is called by the (C) debugger. The same is true of
+ * the purify_stop_here_internal() function so it isn't exported either.
+ * And purify_stop_here() should never be called directly.
+ *
+ * The header file says purify_{new,all,clear_new}_reports() are obsolete
+ * so they aren't exported.
+ *
+ * None of the custom dynamic loader functions are exported.
+ *
+ * purify_unsafe_memcpy() isn't exported.
+ *
+ * purify_{start,size}_of_block() aren't exported.
+ *
+ * The manual that I have says that the prototype for the second argument
+ * to purify_map_pool is:
+ *
+ * void (*fn)(char*)
+ *
+ * but the purify.h file declares it as:
+ *
+ * void (*fn)(char*, int, void*)
+ *
+ * and does not explain what the other arguments are for. I support the
+ * latter but I don't know if I do it right or usefully.
+ *
+ * The header file says that purify_describe() returns a char* which is the
+ * pointer passed to it. The manual says it returns an int, but I believe
+ * that is a typo.
+ */
+#ifdef PURIFY_H
+
+static PyObject*
+pure_purify_all_inuse(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_all_inuse, self, args);
+}
+static PyObject*
+pure_purify_all_leaks(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_all_leaks, self, args);
+}
+static PyObject*
+pure_purify_new_inuse(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_new_inuse, self, args);
+}
+static PyObject*
+pure_purify_new_leaks(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_new_leaks, self, args);
+}
+static PyObject*
+pure_purify_clear_inuse(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_clear_inuse, self, args);
+}
+static PyObject*
+pure_purify_clear_leaks(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_clear_leaks, self, args);
+}
+static PyObject*
+pure_purify_all_fds_inuse(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_all_fds_inuse, self, args);
+}
+static PyObject*
+pure_purify_new_fds_inuse(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_new_fds_inuse, self, args);
+}
+static PyObject*
+pure_purify_printf_with_call_chain(PyObject *self, PyObject *args)
+{
+ return call_printfish_function(purify_printf_with_call_chain,
+ self, args);
+}
+static PyObject*
+pure_purify_set_pool_id(PyObject *self, PyObject *args)
+{
+ long memrep;
+ int id;
+
+ if (!PyArg_ParseTuple(args, "li:purify_set_pool_id", &memrep, &id))
+ return NULL;
+
+ purify_set_pool_id((char*)memrep, id);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject*
+pure_purify_get_pool_id(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_get_pool_id, self, args);
+}
+static PyObject*
+pure_purify_set_user_data(PyObject *self, PyObject *args)
+{
+ long memrep;
+ long datarep;
+
+ if (!PyArg_ParseTuple(args, "ll:purify_set_user_data", &memrep, &datarep))
+ return NULL;
+
+ purify_set_user_data((char*)memrep, (void*)datarep);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject*
+pure_purify_get_user_data(PyObject *self, PyObject *args)
+{
+ /* can't use call_intasaddr_function() since purify_get_user_data()
+ * returns a void*
+ */
+ long memrep;
+ void* data;
+
+ if (!PyArg_ParseTuple(args, "l:purify_get_user_data", &memrep))
+ return NULL;
+
+ data = purify_get_user_data((char*)memrep);
+ return Py_BuildValue("l", (long)data);
+}
+
+
+/* this global variable is shared by both mapping functions:
+ * pure_purify_map_pool() and pure_purify_map_pool_id(). Since they cache
+ * this variable it should be safe in the face of recursion or cross
+ * calling.
+ *
+ * Further note that the prototype for the callback function is wrong in
+ * the Purify manual. The manual says the function takes a single char*,
+ * but the header file says it takes an additional int and void*. I have
+ * no idea what these are for!
+ */
+static PyObject* MapCallable = NULL;
+
+static void
+map_pool_callback(char* mem, int user_size, void *user_aux_data)
+{
+ long memrep = (long)mem;
+ long user_aux_data_rep = (long)user_aux_data;
+ PyObject* result;
+ PyObject* memobj = Py_BuildValue("lil", memrep, user_size,
+ user_aux_data_rep);
+
+ if (memobj == NULL)
+ return;
+
+ result = PyEval_CallObject(MapCallable, memobj);
+ Py_DECREF(result);
+ Py_DECREF(memobj);
+}
+
+static PyObject*
+pure_purify_map_pool(PyObject *self, PyObject *args)
+{
+ /* cache global variable in case of recursion */
+ PyObject* saved_callable = MapCallable;
+ PyObject* arg_callable;
+ int id;
+
+ if (!PyArg_ParseTuple(args, "iO:purify_map_pool", &id, &arg_callable))
+ return NULL;
+
+ if (!PyCallable_Check(arg_callable)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Second argument must be callable");
+ return NULL;
+ }
+ MapCallable = arg_callable;
+ purify_map_pool(id, map_pool_callback);
+ MapCallable = saved_callable;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static void
+PurifyMapPoolIdCallback(int id)
+{
+ PyObject* result;
+ PyObject* intobj = Py_BuildValue("i", id);
+
+ if (intobj == NULL)
+ return;
+
+ result = PyEval_CallObject(MapCallable, intobj);
+ Py_DECREF(result);
+ Py_DECREF(intobj);
+}
+
+static PyObject*
+pure_purify_map_pool_id(PyObject *self, PyObject *args)
+{
+ /* cache global variable in case of recursion */
+ PyObject* saved_callable = MapCallable;
+ PyObject* arg_callable;
+
+ if (!PyArg_ParseTuple(args, "O:purify_map_pool_id", &arg_callable))
+ return NULL;
+
+ if (!PyCallable_Check(arg_callable)) {
+ PyErr_SetString(PyExc_TypeError, "Argument must be callable.");
+ return NULL;
+ }
+
+ MapCallable = arg_callable;
+ purify_map_pool_id(PurifyMapPoolIdCallback);
+ MapCallable = saved_callable;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+
+static PyObject*
+pure_purify_new_messages(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_new_messages, self, args);
+}
+static PyObject*
+pure_purify_all_messages(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_all_messages, self, args);
+}
+static PyObject*
+pure_purify_clear_messages(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_clear_messages, self, args);
+}
+static PyObject*
+pure_purify_clear_new_messages(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_clear_new_messages, self, args);
+}
+static PyObject*
+pure_purify_start_batch(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_start_batch, self, args);
+}
+static PyObject*
+pure_purify_start_batch_show_first(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_start_batch_show_first,
+ self, args);
+}
+static PyObject*
+pure_purify_stop_batch(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_stop_batch, self, args);
+}
+static PyObject*
+pure_purify_name_thread(PyObject *self, PyObject *args)
+{
+ /* can't strictly use call_stringarg_function since
+ * purify_name_thread takes a const char*, not a char*
+ */
+ int status;
+ char* stringarg;
+
+ if (!PyArg_ParseTuple(args, "s:purify_name_thread", &stringarg))
+ return NULL;
+
+ status = purify_name_thread(stringarg);
+ return Py_BuildValue("i", status);
+}
+static PyObject*
+pure_purify_watch(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch, self, args);
+}
+static PyObject*
+pure_purify_watch_1(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_1, self, args);
+}
+static PyObject*
+pure_purify_watch_2(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_2, self, args);
+}
+static PyObject*
+pure_purify_watch_4(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_4, self, args);
+}
+static PyObject*
+pure_purify_watch_8(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_8, self, args);
+}
+static PyObject*
+pure_purify_watch_w_1(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_w_1, self, args);
+}
+static PyObject*
+pure_purify_watch_w_2(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_w_2, self, args);
+}
+static PyObject*
+pure_purify_watch_w_4(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_w_4, self, args);
+}
+static PyObject*
+pure_purify_watch_w_8(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_w_8, self, args);
+}
+static PyObject*
+pure_purify_watch_r_1(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_r_1, self, args);
+}
+static PyObject*
+pure_purify_watch_r_2(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_r_2, self, args);
+}
+static PyObject*
+pure_purify_watch_r_4(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_r_4, self, args);
+}
+static PyObject*
+pure_purify_watch_r_8(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_r_8, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_1(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_rw_1, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_2(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_rw_2, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_4(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_rw_4, self, args);
+}
+static PyObject*
+pure_purify_watch_rw_8(PyObject *self, PyObject *args)
+{
+ return call_intasaddr_function(purify_watch_rw_8, self, args);
+}
+
+static PyObject*
+pure_purify_watch_n(PyObject *self, PyObject *args)
+{
+ long addrrep;
+ unsigned int size;
+ char* type;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "lis:purify_watch_n", &addrrep, &size, &type))
+ return NULL;
+
+ status = purify_watch_n((char*)addrrep, size, type);
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+pure_purify_watch_info(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_watch_info, self, args);
+}
+
+static PyObject*
+pure_purify_watch_remove(PyObject *self, PyObject *args)
+{
+ int watchno;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "i:purify_watch_remove", &watchno))
+ return NULL;
+
+ status = purify_watch_remove(watchno);
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+pure_purify_watch_remove_all(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_watch_remove_all, self, args);
+}
+static PyObject*
+pure_purify_describe(PyObject *self, PyObject *args)
+{
+ long addrrep;
+ char* rtn;
+
+ if (!PyArg_ParseTuple(args, "l:purify_describe", &addrrep))
+ return NULL;
+
+ rtn = purify_describe((char*)addrrep);
+ return Py_BuildValue("l", (long)rtn);
+}
+
+static PyObject*
+pure_purify_what_colors(PyObject *self, PyObject *args)
+{
+ long addrrep;
+ unsigned int size;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "li:purify_what_colors", &addrrep, &size))
+ return NULL;
+
+ status = purify_what_colors((char*)addrrep, size);
+ return Py_BuildValue("i", status);
+}
+
+static PyObject*
+pure_purify_is_running(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(purify_is_running, self, args);
+}
+
+static PyObject*
+pure_purify_assert_is_readable(PyObject *self, PyObject *args)
+{
+ return call_stringandint_function(purify_assert_is_readable,
+ self, args);
+}
+static PyObject*
+pure_purify_assert_is_writable(PyObject *self, PyObject *args)
+{
+ return call_stringandint_function(purify_assert_is_writable,
+ self, args);
+}
+
+#if HAS_PURIFY_EXIT
+
+/* I wish I could include this, but I can't. See the notes at the top of
+ * the file.
+ */
+
+static PyObject*
+pure_purify_exit(PyObject *self, PyObject *args)
+{
+ int status;
+
+ if (!PyArg_ParseTuple(args, "i:purify_exit", &status))
+ return NULL;
+
+ /* purify_exit doesn't always act like exit(). See the manual */
+ purify_exit(status);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAS_PURIFY_EXIT */
+
+#endif /* PURIFY_H */
+
+
+
+/* Quantify functions
+ *
+ * N.B. Some of these functions are only described in the quantify.h file,
+ * not in the version of the hardcopy manual that I had. If you're not
+ * sure what some of these do, check the header file, it is documented
+ * fairly well.
+ *
+ * None of the custom dynamic loader functions are exported.
+ *
+ */
+#ifdef QUANTIFY_H
+
+static PyObject*
+pure_quantify_is_running(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_is_running, self, args);
+}
+static PyObject*
+pure_quantify_help(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_help, self, args);
+}
+static PyObject*
+pure_quantify_print_recording_state(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_print_recording_state,
+ self, args);
+}
+static PyObject*
+pure_quantify_start_recording_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_start_recording_data,
+ self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_stop_recording_data, self, args);
+}
+static PyObject*
+pure_quantify_is_recording_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_is_recording_data, self, args);
+}
+static PyObject*
+pure_quantify_start_recording_system_calls(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_start_recording_system_calls,
+ self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_system_calls(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_stop_recording_system_calls,
+ self, args);
+}
+static PyObject*
+pure_quantify_is_recording_system_calls(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_is_recording_system_calls,
+ self, args);
+}
+static PyObject*
+pure_quantify_start_recording_system_call(PyObject *self, PyObject *args)
+{
+ return call_stringorint_function(quantify_start_recording_system_call,
+ self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_system_call(PyObject *self, PyObject *args)
+{
+ return call_stringorint_function(quantify_stop_recording_system_call,
+ self, args);
+}
+static PyObject*
+pure_quantify_is_recording_system_call(PyObject *self, PyObject *args)
+{
+ return call_stringorint_function(quantify_is_recording_system_call,
+ self, args);
+}
+static PyObject*
+pure_quantify_start_recording_dynamic_library_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(
+ quantify_start_recording_dynamic_library_data,
+ self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_dynamic_library_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(
+ quantify_stop_recording_dynamic_library_data,
+ self, args);
+}
+static PyObject*
+pure_quantify_is_recording_dynamic_library_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(
+ quantify_is_recording_dynamic_library_data,
+ self, args);
+}
+static PyObject*
+pure_quantify_start_recording_register_window_traps(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(
+ quantify_start_recording_register_window_traps,
+ self, args);
+}
+static PyObject*
+pure_quantify_stop_recording_register_window_traps(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(
+ quantify_stop_recording_register_window_traps,
+ self, args);
+}
+static PyObject*
+pure_quantify_is_recording_register_window_traps(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(
+ quantify_is_recording_register_window_traps,
+ self, args);
+}
+static PyObject*
+pure_quantify_disable_recording_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_disable_recording_data,
+ self, args);
+}
+static PyObject*
+pure_quantify_clear_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_clear_data, self, args);
+}
+static PyObject*
+pure_quantify_save_data(PyObject *self, PyObject *args)
+{
+ return call_voidarg_function(quantify_save_data, self, args);
+}
+static PyObject*
+pure_quantify_save_data_to_file(PyObject *self, PyObject *args)
+{
+ return call_stringarg_function(quantify_save_data_to_file, self, args);
+}
+static PyObject*
+pure_quantify_add_annotation(PyObject *self, PyObject *args)
+{
+ return call_stringarg_function(quantify_add_annotation, self, args);
+}
+
+#endif /* QUANTIFY_H */
+
+
+
+/* external interface
+ */
+static struct PyMethodDef
+pure_methods[] = {
+#ifdef COMMON_PURE_FUNCTIONS
+ {"pure_logfile_printf", pure_pure_logfile_printf, METH_VARARGS},
+ {"pure_printf", pure_pure_printf, METH_VARARGS},
+ {"pure_printf_with_banner", pure_pure_printf_with_banner, METH_VARARGS},
+#endif /* COMMON_PURE_FUNCTIONS */
+#ifdef PURIFY_H
+ {"purify_all_inuse", pure_purify_all_inuse, METH_VARARGS},
+ {"purify_all_leaks", pure_purify_all_leaks, METH_VARARGS},
+ {"purify_new_inuse", pure_purify_new_inuse, METH_VARARGS},
+ {"purify_new_leaks", pure_purify_new_leaks, METH_VARARGS},
+ {"purify_clear_inuse", pure_purify_clear_inuse, METH_VARARGS},
+ {"purify_clear_leaks", pure_purify_clear_leaks, METH_VARARGS},
+ {"purify_all_fds_inuse", pure_purify_all_fds_inuse, METH_VARARGS},
+ {"purify_new_fds_inuse", pure_purify_new_fds_inuse, METH_VARARGS},
+ /* see purify.h */
+ {"purify_logfile_printf", pure_pure_logfile_printf, METH_VARARGS},
+ {"purify_printf", pure_pure_printf, METH_VARARGS},
+ {"purify_printf_with_banner", pure_pure_printf_with_banner, METH_VARARGS},
+ /**/
+ {"purify_printf_with_call_chain", pure_purify_printf_with_call_chain, METH_VARARGS},
+ {"purify_set_pool_id", pure_purify_set_pool_id, METH_VARARGS},
+ {"purify_get_pool_id", pure_purify_get_pool_id, METH_VARARGS},
+ {"purify_set_user_data", pure_purify_set_user_data, METH_VARARGS},
+ {"purify_get_user_data", pure_purify_get_user_data, METH_VARARGS},
+ {"purify_map_pool", pure_purify_map_pool, METH_VARARGS},
+ {"purify_map_pool_id", pure_purify_map_pool_id, METH_VARARGS},
+ {"purify_new_messages", pure_purify_new_messages, METH_VARARGS},
+ {"purify_all_messages", pure_purify_all_messages, METH_VARARGS},
+ {"purify_clear_messages", pure_purify_clear_messages, METH_VARARGS},
+ {"purify_clear_new_messages", pure_purify_clear_new_messages, METH_VARARGS},
+ {"purify_start_batch", pure_purify_start_batch, METH_VARARGS},
+ {"purify_start_batch_show_first", pure_purify_start_batch_show_first, METH_VARARGS},
+ {"purify_stop_batch", pure_purify_stop_batch, METH_VARARGS},
+ {"purify_name_thread", pure_purify_name_thread, METH_VARARGS},
+ {"purify_watch", pure_purify_watch, METH_VARARGS},
+ {"purify_watch_1", pure_purify_watch_1, METH_VARARGS},
+ {"purify_watch_2", pure_purify_watch_2, METH_VARARGS},
+ {"purify_watch_4", pure_purify_watch_4, METH_VARARGS},
+ {"purify_watch_8", pure_purify_watch_8, METH_VARARGS},
+ {"purify_watch_w_1", pure_purify_watch_w_1, METH_VARARGS},
+ {"purify_watch_w_2", pure_purify_watch_w_2, METH_VARARGS},
+ {"purify_watch_w_4", pure_purify_watch_w_4, METH_VARARGS},
+ {"purify_watch_w_8", pure_purify_watch_w_8, METH_VARARGS},
+ {"purify_watch_r_1", pure_purify_watch_r_1, METH_VARARGS},
+ {"purify_watch_r_2", pure_purify_watch_r_2, METH_VARARGS},
+ {"purify_watch_r_4", pure_purify_watch_r_4, METH_VARARGS},
+ {"purify_watch_r_8", pure_purify_watch_r_8, METH_VARARGS},
+ {"purify_watch_rw_1", pure_purify_watch_rw_1, METH_VARARGS},
+ {"purify_watch_rw_2", pure_purify_watch_rw_2, METH_VARARGS},
+ {"purify_watch_rw_4", pure_purify_watch_rw_4, METH_VARARGS},
+ {"purify_watch_rw_8", pure_purify_watch_rw_8, METH_VARARGS},
+ {"purify_watch_n", pure_purify_watch_n, METH_VARARGS},
+ {"purify_watch_info", pure_purify_watch_info, METH_VARARGS},
+ {"purify_watch_remove", pure_purify_watch_remove, METH_VARARGS},
+ {"purify_watch_remove_all", pure_purify_watch_remove_all, METH_VARARGS},
+ {"purify_describe", pure_purify_describe, METH_VARARGS},
+ {"purify_what_colors", pure_purify_what_colors, METH_VARARGS},
+ {"purify_is_running", pure_purify_is_running, METH_VARARGS},
+ {"purify_assert_is_readable", pure_purify_assert_is_readable, METH_VARARGS},
+ {"purify_assert_is_writable", pure_purify_assert_is_writable, METH_VARARGS},
+#if HAS_PURIFY_EXIT
+ /* I wish I could include this, but I can't. See the notes at the
+ * top of the file.
+ */
+ {"purify_exit", pure_purify_exit, METH_VARARGS},
+#endif /* HAS_PURIFY_EXIT */
+#endif /* PURIFY_H */
+#ifdef QUANTIFY_H
+ {"quantify_is_running", pure_quantify_is_running, METH_VARARGS},
+ {"quantify_help", pure_quantify_help, METH_VARARGS},
+ {"quantify_print_recording_state", pure_quantify_print_recording_state, METH_VARARGS},
+ {"quantify_start_recording_data", pure_quantify_start_recording_data, METH_VARARGS},
+ {"quantify_stop_recording_data", pure_quantify_stop_recording_data, METH_VARARGS},
+ {"quantify_is_recording_data", pure_quantify_is_recording_data, METH_VARARGS},
+ {"quantify_start_recording_system_calls",
+ pure_quantify_start_recording_system_calls, METH_VARARGS},
+ {"quantify_stop_recording_system_calls",
+ pure_quantify_stop_recording_system_calls, METH_VARARGS},
+ {"quantify_is_recording_system_calls",
+ pure_quantify_is_recording_system_calls, METH_VARARGS},
+ {"quantify_start_recording_system_call",
+ pure_quantify_start_recording_system_call, METH_VARARGS},
+ {"quantify_stop_recording_system_call",
+ pure_quantify_stop_recording_system_call, METH_VARARGS},
+ {"quantify_is_recording_system_call",
+ pure_quantify_is_recording_system_call, METH_VARARGS},
+ {"quantify_start_recording_dynamic_library_data",
+ pure_quantify_start_recording_dynamic_library_data, METH_VARARGS},
+ {"quantify_stop_recording_dynamic_library_data",
+ pure_quantify_stop_recording_dynamic_library_data, METH_VARARGS},
+ {"quantify_is_recording_dynamic_library_data",
+ pure_quantify_is_recording_dynamic_library_data, METH_VARARGS},
+ {"quantify_start_recording_register_window_traps",
+ pure_quantify_start_recording_register_window_traps, METH_VARARGS},
+ {"quantify_stop_recording_register_window_traps",
+ pure_quantify_stop_recording_register_window_traps, METH_VARARGS},
+ {"quantify_is_recording_register_window_traps",
+ pure_quantify_is_recording_register_window_traps, METH_VARARGS},
+ {"quantify_disable_recording_data",
+ pure_quantify_disable_recording_data, METH_VARARGS},
+ {"quantify_clear_data", pure_quantify_clear_data, METH_VARARGS},
+ {"quantify_save_data", pure_quantify_save_data, METH_VARARGS},
+ {"quantify_save_data_to_file", pure_quantify_save_data_to_file, METH_VARARGS},
+ {"quantify_add_annotation", pure_quantify_add_annotation, METH_VARARGS},
+#endif /* QUANTIFY_H */
+ {NULL, NULL} /* sentinel */
+};
+
+
+
+static void
+ins(d, name, val)
+ PyObject *d;
+ char* name;
+ long val;
+{
+ PyObject *v = PyInt_FromLong(val);
+ if (v) {
+ (void)PyDict_SetItemString(d, name, v);
+ Py_DECREF(v);
+ }
+}
+
+
+void
+initpure()
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule("pure", pure_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ /* this is bogus because we should be able to find this information
+ * out from the header files. Pure's current versions don't
+ * include this information!
+ */
+#ifdef PURE_PURIFY_VERSION
+ ins(d, "PURIFY_VERSION", PURE_PURIFY_VERSION);
+#else
+ PyDict_SetItemString(d, "PURIFY_VERSION", Py_None);
+#endif
+
+ /* these aren't terribly useful because purify_exit() isn't
+ * exported correctly. See the note at the top of the file.
+ */
+#ifdef PURIFY_EXIT_ERRORS
+ ins(d, "PURIFY_EXIT_ERRORS", PURIFY_EXIT_ERRORS);
+#endif
+#ifdef PURIFY_EXIT_LEAKS
+ ins(d, "PURIFY_EXIT_LEAKS", PURIFY_EXIT_LEAKS);
+#endif
+#ifdef PURIFY_EXIT_PLEAKS
+ ins(d, "PURIFY_EXIT_PLEAKS", PURIFY_EXIT_PLEAKS);
+#endif
+
+
+#ifdef PURE_QUANTIFY_VERSION
+ ins(d, "QUANTIFY_VERSION", PURE_QUANTIFY_VERSION);
+#else
+ PyDict_SetItemString(d, "QUANTIFY_VERSION", Py_None);
+#endif
+}
diff --git a/sys/src/cmd/python/Modules/pwdmodule.c b/sys/src/cmd/python/Modules/pwdmodule.c
new file mode 100644
index 000000000..7600d05ee
--- /dev/null
+++ b/sys/src/cmd/python/Modules/pwdmodule.c
@@ -0,0 +1,198 @@
+
+/* UNIX password file access module */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <sys/types.h>
+#include <pwd.h>
+
+static PyStructSequence_Field struct_pwd_type_fields[] = {
+ {"pw_name", "user name"},
+ {"pw_passwd", "password"},
+ {"pw_uid", "user id"},
+ {"pw_gid", "group id"},
+ {"pw_gecos", "real name"},
+ {"pw_dir", "home directory"},
+ {"pw_shell", "shell program"},
+ {0}
+};
+
+PyDoc_STRVAR(struct_passwd__doc__,
+"pwd.struct_passwd: Results from getpw*() routines.\n\n\
+This object may be accessed either as a tuple of\n\
+ (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n\
+or via the object attributes as named in the above tuple.");
+
+static PyStructSequence_Desc struct_pwd_type_desc = {
+ "pwd.struct_passwd",
+ struct_passwd__doc__,
+ struct_pwd_type_fields,
+ 7,
+};
+
+PyDoc_STRVAR(pwd__doc__,
+"This module provides access to the Unix password database.\n\
+It is available on all Unix versions.\n\
+\n\
+Password database entries are reported as 7-tuples containing the following\n\
+items from the password database (see `<pwd.h>'), in order:\n\
+pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\
+The uid and gid items are integers, all others are strings. An\n\
+exception is raised if the entry asked for cannot be found.");
+
+
+static int initialized;
+static PyTypeObject StructPwdType;
+
+static void
+sets(PyObject *v, int i, char* val)
+{
+ if (val)
+ PyStructSequence_SET_ITEM(v, i, PyString_FromString(val));
+ else {
+ PyStructSequence_SET_ITEM(v, i, Py_None);
+ Py_INCREF(Py_None);
+ }
+}
+
+static PyObject *
+mkpwent(struct passwd *p)
+{
+ int setIndex = 0;
+ PyObject *v = PyStructSequence_New(&StructPwdType);
+ if (v == NULL)
+ return NULL;
+
+#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
+#define SETS(i,val) sets(v, i, val)
+
+ SETS(setIndex++, p->pw_name);
+#if defined( __VMS) || defined(PLAN9APE)
+ SETS(setIndex++, "");
+#else
+ SETS(setIndex++, p->pw_passwd);
+#endif
+ SETI(setIndex++, p->pw_uid);
+ SETI(setIndex++, p->pw_gid);
+#if defined( __VMS) || defined(PLAN9APE)
+ SETS(setIndex++, "");
+#else
+ SETS(setIndex++, p->pw_gecos);
+#endif
+ SETS(setIndex++, p->pw_dir);
+ SETS(setIndex++, p->pw_shell);
+
+#undef SETS
+#undef SETI
+
+ if (PyErr_Occurred()) {
+ Py_XDECREF(v);
+ return NULL;
+ }
+
+ return v;
+}
+
+PyDoc_STRVAR(pwd_getpwuid__doc__,
+"getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,\n\
+ pw_gid,pw_gecos,pw_dir,pw_shell)\n\
+Return the password database entry for the given numeric user ID.\n\
+See pwd.__doc__ for more on password database entries.");
+
+static PyObject *
+pwd_getpwuid(PyObject *self, PyObject *args)
+{
+ unsigned int uid;
+ struct passwd *p;
+ if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
+ return NULL;
+ if ((p = getpwuid(uid)) == NULL) {
+ PyErr_Format(PyExc_KeyError,
+ "getpwuid(): uid not found: %d", uid);
+ return NULL;
+ }
+ return mkpwent(p);
+}
+
+PyDoc_STRVAR(pwd_getpwnam__doc__,
+"getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\
+ pw_gid,pw_gecos,pw_dir,pw_shell)\n\
+Return the password database entry for the given user name.\n\
+See pwd.__doc__ for more on password database entries.");
+
+static PyObject *
+pwd_getpwnam(PyObject *self, PyObject *args)
+{
+ char *name;
+ struct passwd *p;
+ if (!PyArg_ParseTuple(args, "s:getpwnam", &name))
+ return NULL;
+ if ((p = getpwnam(name)) == NULL) {
+ PyErr_Format(PyExc_KeyError,
+ "getpwnam(): name not found: %s", name);
+ return NULL;
+ }
+ return mkpwent(p);
+}
+
+#ifdef HAVE_GETPWENT
+PyDoc_STRVAR(pwd_getpwall__doc__,
+"getpwall() -> list_of_entries\n\
+Return a list of all available password database entries, \
+in arbitrary order.\n\
+See pwd.__doc__ for more on password database entries.");
+
+static PyObject *
+pwd_getpwall(PyObject *self)
+{
+ PyObject *d;
+ struct passwd *p;
+ if ((d = PyList_New(0)) == NULL)
+ return NULL;
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ if ((p = getpwuid(0)) != NULL) {
+#else
+ setpwent();
+ while ((p = getpwent()) != NULL) {
+#endif
+ PyObject *v = mkpwent(p);
+ if (v == NULL || PyList_Append(d, v) != 0) {
+ Py_XDECREF(v);
+ Py_DECREF(d);
+ return NULL;
+ }
+ Py_DECREF(v);
+ }
+ endpwent();
+ return d;
+}
+#endif
+
+static PyMethodDef pwd_methods[] = {
+ {"getpwuid", pwd_getpwuid, METH_VARARGS, pwd_getpwuid__doc__},
+ {"getpwnam", pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__},
+#ifdef HAVE_GETPWENT
+ {"getpwall", (PyCFunction)pwd_getpwall,
+ METH_NOARGS, pwd_getpwall__doc__},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+initpwd(void)
+{
+ PyObject *m;
+ m = Py_InitModule3("pwd", pwd_methods, pwd__doc__);
+ if (m == NULL)
+ return;
+
+ if (!initialized)
+ PyStructSequence_InitType(&StructPwdType,
+ &struct_pwd_type_desc);
+ Py_INCREF((PyObject *) &StructPwdType);
+ PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType);
+ /* And for b/w compatibility (this was defined by mistake): */
+ PyModule_AddObject(m, "struct_pwent", (PyObject *) &StructPwdType);
+ initialized = 1;
+}
diff --git a/sys/src/cmd/python/Modules/pyexpat.c b/sys/src/cmd/python/Modules/pyexpat.c
new file mode 100644
index 000000000..cbf574ae5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/pyexpat.c
@@ -0,0 +1,2149 @@
+#include "Python.h"
+#include <ctype.h>
+
+#include "frameobject.h"
+#include "expat.h"
+
+#include "pyexpat.h"
+
+#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
+
+#ifndef PyDoc_STRVAR
+
+/*
+ * fdrake says:
+ * Don't change the PyDoc_STR macro definition to (str), because
+ * '''the parentheses cause compile failures
+ * ("non-constant static initializer" or something like that)
+ * on some platforms (Irix?)'''
+ */
+#define PyDoc_STR(str) str
+#define PyDoc_VAR(name) static char name[]
+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
+#endif
+
+#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)
+/* In Python 2.0 and 2.1, disabling Unicode was not possible. */
+#define Py_USING_UNICODE
+#else
+#define FIX_TRACE
+#endif
+
+enum HandlerTypes {
+ StartElement,
+ EndElement,
+ ProcessingInstruction,
+ CharacterData,
+ UnparsedEntityDecl,
+ NotationDecl,
+ StartNamespaceDecl,
+ EndNamespaceDecl,
+ Comment,
+ StartCdataSection,
+ EndCdataSection,
+ Default,
+ DefaultHandlerExpand,
+ NotStandalone,
+ ExternalEntityRef,
+ StartDoctypeDecl,
+ EndDoctypeDecl,
+ EntityDecl,
+ XmlDecl,
+ ElementDecl,
+ AttlistDecl,
+#if XML_COMBINED_VERSION >= 19504
+ SkippedEntity,
+#endif
+ _DummyDecl
+};
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type xmlparser */
+
+typedef struct {
+ PyObject_HEAD
+
+ XML_Parser itself;
+ int returns_unicode; /* True if Unicode strings are returned;
+ if false, UTF-8 strings are returned */
+ int ordered_attributes; /* Return attributes as a list. */
+ int specified_attributes; /* Report only specified attributes. */
+ int in_callback; /* Is a callback active? */
+ int ns_prefixes; /* Namespace-triplets mode? */
+ XML_Char *buffer; /* Buffer used when accumulating characters */
+ /* NULL if not enabled */
+ int buffer_size; /* Size of buffer, in XML_Char units */
+ int buffer_used; /* Buffer units in use */
+ PyObject *intern; /* Dictionary to intern strings */
+ PyObject **handlers;
+} xmlparseobject;
+
+#define CHARACTER_DATA_BUFFER_SIZE 8192
+
+static PyTypeObject Xmlparsetype;
+
+typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
+typedef void* xmlhandler;
+
+struct HandlerInfo {
+ const char *name;
+ xmlhandlersetter setter;
+ xmlhandler handler;
+ PyCodeObject *tb_code;
+ PyObject *nameobj;
+};
+
+static struct HandlerInfo handler_info[64];
+
+/* Set an integer attribute on the error object; return true on success,
+ * false on an exception.
+ */
+static int
+set_error_attr(PyObject *err, char *name, int value)
+{
+ PyObject *v = PyInt_FromLong(value);
+
+ if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
+ Py_XDECREF(v);
+ return 0;
+ }
+ Py_DECREF(v);
+ return 1;
+}
+
+/* Build and set an Expat exception, including positioning
+ * information. Always returns NULL.
+ */
+static PyObject *
+set_error(xmlparseobject *self, enum XML_Error code)
+{
+ PyObject *err;
+ char buffer[256];
+ XML_Parser parser = self->itself;
+ int lineno = XML_GetErrorLineNumber(parser);
+ int column = XML_GetErrorColumnNumber(parser);
+
+ /* There is no risk of overflowing this buffer, since
+ even for 64-bit integers, there is sufficient space. */
+ sprintf(buffer, "%.200s: line %i, column %i",
+ XML_ErrorString(code), lineno, column);
+ err = PyObject_CallFunction(ErrorObject, "s", buffer);
+ if ( err != NULL
+ && set_error_attr(err, "code", code)
+ && set_error_attr(err, "offset", column)
+ && set_error_attr(err, "lineno", lineno)) {
+ PyErr_SetObject(ErrorObject, err);
+ }
+ Py_XDECREF(err);
+ return NULL;
+}
+
+static int
+have_handler(xmlparseobject *self, int type)
+{
+ PyObject *handler = self->handlers[type];
+ return handler != NULL;
+}
+
+static PyObject *
+get_handler_name(struct HandlerInfo *hinfo)
+{
+ PyObject *name = hinfo->nameobj;
+ if (name == NULL) {
+ name = PyString_FromString(hinfo->name);
+ hinfo->nameobj = name;
+ }
+ Py_XINCREF(name);
+ return name;
+}
+
+
+#ifdef Py_USING_UNICODE
+/* Convert a string of XML_Chars into a Unicode string.
+ Returns None if str is a null pointer. */
+
+static PyObject *
+conv_string_to_unicode(const XML_Char *str)
+{
+ /* XXX currently this code assumes that XML_Char is 8-bit,
+ and hence in UTF-8. */
+ /* UTF-8 from Expat, Unicode desired */
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
+}
+
+static PyObject *
+conv_string_len_to_unicode(const XML_Char *str, int len)
+{
+ /* XXX currently this code assumes that XML_Char is 8-bit,
+ and hence in UTF-8. */
+ /* UTF-8 from Expat, Unicode desired */
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
+}
+#endif
+
+/* Convert a string of XML_Chars into an 8-bit Python string.
+ Returns None if str is a null pointer. */
+
+static PyObject *
+conv_string_to_utf8(const XML_Char *str)
+{
+ /* XXX currently this code assumes that XML_Char is 8-bit,
+ and hence in UTF-8. */
+ /* UTF-8 from Expat, UTF-8 desired */
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(str);
+}
+
+static PyObject *
+conv_string_len_to_utf8(const XML_Char *str, int len)
+{
+ /* XXX currently this code assumes that XML_Char is 8-bit,
+ and hence in UTF-8. */
+ /* UTF-8 from Expat, UTF-8 desired */
+ if (str == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromStringAndSize((const char *)str, len);
+}
+
+/* Callback routines */
+
+static void clear_handlers(xmlparseobject *self, int initial);
+
+/* This handler is used when an error has been detected, in the hope
+ that actual parsing can be terminated early. This will only help
+ if an external entity reference is encountered. */
+static int
+error_external_entity_ref_handler(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ return 0;
+}
+
+/* Dummy character data handler used when an error (exception) has
+ been detected, and the actual parsing can be terminated early.
+ This is needed since character data handler can't be safely removed
+ from within the character data handler, but can be replaced. It is
+ used only from the character data handler trampoline, and must be
+ used right after `flag_error()` is called. */
+static void
+noop_character_data_handler(void *userData, const XML_Char *data, int len)
+{
+ /* Do nothing. */
+}
+
+static void
+flag_error(xmlparseobject *self)
+{
+ clear_handlers(self, 0);
+ XML_SetExternalEntityRefHandler(self->itself,
+ error_external_entity_ref_handler);
+}
+
+static PyCodeObject*
+getcode(enum HandlerTypes slot, char* func_name, int lineno)
+{
+ PyObject *code = NULL;
+ PyObject *name = NULL;
+ PyObject *nulltuple = NULL;
+ PyObject *filename = NULL;
+
+ if (handler_info[slot].tb_code == NULL) {
+ code = PyString_FromString("");
+ if (code == NULL)
+ goto failed;
+ name = PyString_FromString(func_name);
+ if (name == NULL)
+ goto failed;
+ nulltuple = PyTuple_New(0);
+ if (nulltuple == NULL)
+ goto failed;
+ filename = PyString_FromString(__FILE__);
+ handler_info[slot].tb_code =
+ PyCode_New(0, /* argcount */
+ 0, /* nlocals */
+ 0, /* stacksize */
+ 0, /* flags */
+ code, /* code */
+ nulltuple, /* consts */
+ nulltuple, /* names */
+ nulltuple, /* varnames */
+#if PYTHON_API_VERSION >= 1010
+ nulltuple, /* freevars */
+ nulltuple, /* cellvars */
+#endif
+ filename, /* filename */
+ name, /* name */
+ lineno, /* firstlineno */
+ code /* lnotab */
+ );
+ if (handler_info[slot].tb_code == NULL)
+ goto failed;
+ Py_DECREF(code);
+ Py_DECREF(nulltuple);
+ Py_DECREF(filename);
+ Py_DECREF(name);
+ }
+ return handler_info[slot].tb_code;
+ failed:
+ Py_XDECREF(code);
+ Py_XDECREF(name);
+ return NULL;
+}
+
+#ifdef FIX_TRACE
+static int
+trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
+{
+ int result = 0;
+ if (!tstate->use_tracing || tstate->tracing)
+ return 0;
+ if (tstate->c_profilefunc != NULL) {
+ tstate->tracing++;
+ result = tstate->c_profilefunc(tstate->c_profileobj,
+ f, code , val);
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
+ tstate->tracing--;
+ if (result)
+ return result;
+ }
+ if (tstate->c_tracefunc != NULL) {
+ tstate->tracing++;
+ result = tstate->c_tracefunc(tstate->c_traceobj,
+ f, code , val);
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
+ tstate->tracing--;
+ }
+ return result;
+}
+
+static int
+trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
+{
+ PyObject *type, *value, *traceback, *arg;
+ int err;
+
+ if (tstate->c_tracefunc == NULL)
+ return 0;
+
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value == NULL) {
+ value = Py_None;
+ Py_INCREF(value);
+ }
+#if PY_VERSION_HEX < 0x02040000
+ arg = Py_BuildValue("(OOO)", type, value, traceback);
+#else
+ arg = PyTuple_Pack(3, type, value, traceback);
+#endif
+ if (arg == NULL) {
+ PyErr_Restore(type, value, traceback);
+ return 0;
+ }
+ err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
+ Py_DECREF(arg);
+ if (err == 0)
+ PyErr_Restore(type, value, traceback);
+ else {
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ }
+ return err;
+}
+#endif
+
+static PyObject*
+call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
+ xmlparseobject *self)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ PyFrameObject *f;
+ PyObject *res;
+
+ if (c == NULL)
+ return NULL;
+
+ f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
+ if (f == NULL)
+ return NULL;
+ tstate->frame = f;
+#ifdef FIX_TRACE
+ if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
+ return NULL;
+ }
+#endif
+ res = PyEval_CallObject(func, args);
+ if (res == NULL) {
+ if (tstate->curexc_traceback == NULL)
+ PyTraceBack_Here(f);
+ XML_StopParser(self->itself, XML_FALSE);
+#ifdef FIX_TRACE
+ if (trace_frame_exc(tstate, f) < 0) {
+ return NULL;
+ }
+ }
+ else {
+ if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
+ Py_XDECREF(res);
+ res = NULL;
+ }
+ }
+#else
+ }
+#endif
+ tstate->frame = f->f_back;
+ Py_DECREF(f);
+ return res;
+}
+
+#ifndef Py_USING_UNICODE
+#define STRING_CONV_FUNC conv_string_to_utf8
+#else
+/* Python 2.0 and later versions, when built with Unicode support */
+#define STRING_CONV_FUNC (self->returns_unicode \
+ ? conv_string_to_unicode : conv_string_to_utf8)
+#endif
+
+static PyObject*
+string_intern(xmlparseobject *self, const char* str)
+{
+ PyObject *result = STRING_CONV_FUNC(str);
+ PyObject *value;
+ /* result can be NULL if the unicode conversion failed. */
+ if (!result)
+ return result;
+ if (!self->intern)
+ return result;
+ value = PyDict_GetItem(self->intern, result);
+ if (!value) {
+ if (PyDict_SetItem(self->intern, result, result) == 0)
+ return result;
+ else
+ return NULL;
+ }
+ Py_INCREF(value);
+ Py_DECREF(result);
+ return value;
+}
+
+/* Return 0 on success, -1 on exception.
+ * flag_error() will be called before return if needed.
+ */
+static int
+call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
+{
+ PyObject *args;
+ PyObject *temp;
+
+ args = PyTuple_New(1);
+ if (args == NULL)
+ return -1;
+#ifdef Py_USING_UNICODE
+ temp = (self->returns_unicode
+ ? conv_string_len_to_unicode(buffer, len)
+ : conv_string_len_to_utf8(buffer, len));
+#else
+ temp = conv_string_len_to_utf8(buffer, len);
+#endif
+ if (temp == NULL) {
+ Py_DECREF(args);
+ flag_error(self);
+ XML_SetCharacterDataHandler(self->itself,
+ noop_character_data_handler);
+ return -1;
+ }
+ PyTuple_SET_ITEM(args, 0, temp);
+ /* temp is now a borrowed reference; consider it unused. */
+ self->in_callback = 1;
+ temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
+ self->handlers[CharacterData], args, self);
+ /* temp is an owned reference again, or NULL */
+ self->in_callback = 0;
+ Py_DECREF(args);
+ if (temp == NULL) {
+ flag_error(self);
+ XML_SetCharacterDataHandler(self->itself,
+ noop_character_data_handler);
+ return -1;
+ }
+ Py_DECREF(temp);
+ return 0;
+}
+
+static int
+flush_character_buffer(xmlparseobject *self)
+{
+ int rc;
+ if (self->buffer == NULL || self->buffer_used == 0)
+ return 0;
+ rc = call_character_handler(self, self->buffer, self->buffer_used);
+ self->buffer_used = 0;
+ return rc;
+}
+
+static void
+my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
+{
+ xmlparseobject *self = (xmlparseobject *) userData;
+ if (self->buffer == NULL)
+ call_character_handler(self, data, len);
+ else {
+ if ((self->buffer_used + len) > self->buffer_size) {
+ if (flush_character_buffer(self) < 0)
+ return;
+ /* handler might have changed; drop the rest on the floor
+ * if there isn't a handler anymore
+ */
+ if (!have_handler(self, CharacterData))
+ return;
+ }
+ if (len > self->buffer_size) {
+ call_character_handler(self, data, len);
+ self->buffer_used = 0;
+ }
+ else {
+ memcpy(self->buffer + self->buffer_used,
+ data, len * sizeof(XML_Char));
+ self->buffer_used += len;
+ }
+ }
+}
+
+static void
+my_StartElementHandler(void *userData,
+ const XML_Char *name, const XML_Char *atts[])
+{
+ xmlparseobject *self = (xmlparseobject *)userData;
+
+ if (have_handler(self, StartElement)) {
+ PyObject *container, *rv, *args;
+ int i, max;
+
+ if (flush_character_buffer(self) < 0)
+ return;
+ /* Set max to the number of slots filled in atts[]; max/2 is
+ * the number of attributes we need to process.
+ */
+ if (self->specified_attributes) {
+ max = XML_GetSpecifiedAttributeCount(self->itself);
+ }
+ else {
+ max = 0;
+ while (atts[max] != NULL)
+ max += 2;
+ }
+ /* Build the container. */
+ if (self->ordered_attributes)
+ container = PyList_New(max);
+ else
+ container = PyDict_New();
+ if (container == NULL) {
+ flag_error(self);
+ return;
+ }
+ for (i = 0; i < max; i += 2) {
+ PyObject *n = string_intern(self, (XML_Char *) atts[i]);
+ PyObject *v;
+ if (n == NULL) {
+ flag_error(self);
+ Py_DECREF(container);
+ return;
+ }
+ v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
+ if (v == NULL) {
+ flag_error(self);
+ Py_DECREF(container);
+ Py_DECREF(n);
+ return;
+ }
+ if (self->ordered_attributes) {
+ PyList_SET_ITEM(container, i, n);
+ PyList_SET_ITEM(container, i+1, v);
+ }
+ else if (PyDict_SetItem(container, n, v)) {
+ flag_error(self);
+ Py_DECREF(n);
+ Py_DECREF(v);
+ return;
+ }
+ else {
+ Py_DECREF(n);
+ Py_DECREF(v);
+ }
+ }
+ args = string_intern(self, name);
+ if (args != NULL)
+ args = Py_BuildValue("(NN)", args, container);
+ if (args == NULL) {
+ Py_DECREF(container);
+ return;
+ }
+ /* Container is now a borrowed reference; ignore it. */
+ self->in_callback = 1;
+ rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
+ self->handlers[StartElement], args, self);
+ self->in_callback = 0;
+ Py_DECREF(args);
+ if (rv == NULL) {
+ flag_error(self);
+ return;
+ }
+ Py_DECREF(rv);
+ }
+}
+
+#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
+ RETURN, GETUSERDATA) \
+static RC \
+my_##NAME##Handler PARAMS {\
+ xmlparseobject *self = GETUSERDATA ; \
+ PyObject *args = NULL; \
+ PyObject *rv = NULL; \
+ INIT \
+\
+ if (have_handler(self, NAME)) { \
+ if (flush_character_buffer(self) < 0) \
+ return RETURN; \
+ args = Py_BuildValue PARAM_FORMAT ;\
+ if (!args) { flag_error(self); return RETURN;} \
+ self->in_callback = 1; \
+ rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
+ self->handlers[NAME], args, self); \
+ self->in_callback = 0; \
+ Py_DECREF(args); \
+ if (rv == NULL) { \
+ flag_error(self); \
+ return RETURN; \
+ } \
+ CONVERSION \
+ Py_DECREF(rv); \
+ } \
+ return RETURN; \
+}
+
+#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
+ RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
+ (xmlparseobject *)userData)
+
+#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
+ RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
+ rc = PyInt_AsLong(rv);, rc, \
+ (xmlparseobject *)userData)
+
+VOID_HANDLER(EndElement,
+ (void *userData, const XML_Char *name),
+ ("(N)", string_intern(self, name)))
+
+VOID_HANDLER(ProcessingInstruction,
+ (void *userData,
+ const XML_Char *target,
+ const XML_Char *data),
+ ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
+
+VOID_HANDLER(UnparsedEntityDecl,
+ (void *userData,
+ const XML_Char *entityName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName),
+ ("(NNNNN)",
+ string_intern(self, entityName), string_intern(self, base),
+ string_intern(self, systemId), string_intern(self, publicId),
+ string_intern(self, notationName)))
+
+#ifndef Py_USING_UNICODE
+VOID_HANDLER(EntityDecl,
+ (void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName),
+ ("NiNNNNN",
+ string_intern(self, entityName), is_parameter_entity,
+ conv_string_len_to_utf8(value, value_length),
+ string_intern(self, base), string_intern(self, systemId),
+ string_intern(self, publicId),
+ string_intern(self, notationName)))
+#else
+VOID_HANDLER(EntityDecl,
+ (void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName),
+ ("NiNNNNN",
+ string_intern(self, entityName), is_parameter_entity,
+ (self->returns_unicode
+ ? conv_string_len_to_unicode(value, value_length)
+ : conv_string_len_to_utf8(value, value_length)),
+ string_intern(self, base), string_intern(self, systemId),
+ string_intern(self, publicId),
+ string_intern(self, notationName)))
+#endif
+
+VOID_HANDLER(XmlDecl,
+ (void *userData,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone),
+ ("(O&O&i)",
+ STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
+ standalone))
+
+static PyObject *
+conv_content_model(XML_Content * const model,
+ PyObject *(*conv_string)(const XML_Char *))
+{
+ PyObject *result = NULL;
+ PyObject *children = PyTuple_New(model->numchildren);
+ int i;
+
+ if (children != NULL) {
+ assert(model->numchildren < INT_MAX);
+ for (i = 0; i < (int)model->numchildren; ++i) {
+ PyObject *child = conv_content_model(&model->children[i],
+ conv_string);
+ if (child == NULL) {
+ Py_XDECREF(children);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(children, i, child);
+ }
+ result = Py_BuildValue("(iiO&N)",
+ model->type, model->quant,
+ conv_string,model->name, children);
+ }
+ return result;
+}
+
+static void
+my_ElementDeclHandler(void *userData,
+ const XML_Char *name,
+ XML_Content *model)
+{
+ xmlparseobject *self = (xmlparseobject *)userData;
+ PyObject *args = NULL;
+
+ if (have_handler(self, ElementDecl)) {
+ PyObject *rv = NULL;
+ PyObject *modelobj, *nameobj;
+
+ if (flush_character_buffer(self) < 0)
+ goto finally;
+#ifdef Py_USING_UNICODE
+ modelobj = conv_content_model(model,
+ (self->returns_unicode
+ ? conv_string_to_unicode
+ : conv_string_to_utf8));
+#else
+ modelobj = conv_content_model(model, conv_string_to_utf8);
+#endif
+ if (modelobj == NULL) {
+ flag_error(self);
+ goto finally;
+ }
+ nameobj = string_intern(self, name);
+ if (nameobj == NULL) {
+ Py_DECREF(modelobj);
+ flag_error(self);
+ goto finally;
+ }
+ args = Py_BuildValue("NN", nameobj, modelobj);
+ if (args == NULL) {
+ Py_DECREF(modelobj);
+ flag_error(self);
+ goto finally;
+ }
+ self->in_callback = 1;
+ rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
+ self->handlers[ElementDecl], args, self);
+ self->in_callback = 0;
+ if (rv == NULL) {
+ flag_error(self);
+ goto finally;
+ }
+ Py_DECREF(rv);
+ }
+ finally:
+ Py_XDECREF(args);
+ XML_FreeContentModel(self->itself, model);
+ return;
+}
+
+VOID_HANDLER(AttlistDecl,
+ (void *userData,
+ const XML_Char *elname,
+ const XML_Char *attname,
+ const XML_Char *att_type,
+ const XML_Char *dflt,
+ int isrequired),
+ ("(NNO&O&i)",
+ string_intern(self, elname), string_intern(self, attname),
+ STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
+ isrequired))
+
+#if XML_COMBINED_VERSION >= 19504
+VOID_HANDLER(SkippedEntity,
+ (void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity),
+ ("Ni",
+ string_intern(self, entityName), is_parameter_entity))
+#endif
+
+VOID_HANDLER(NotationDecl,
+ (void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId),
+ ("(NNNN)",
+ string_intern(self, notationName), string_intern(self, base),
+ string_intern(self, systemId), string_intern(self, publicId)))
+
+VOID_HANDLER(StartNamespaceDecl,
+ (void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri),
+ ("(NN)",
+ string_intern(self, prefix), string_intern(self, uri)))
+
+VOID_HANDLER(EndNamespaceDecl,
+ (void *userData,
+ const XML_Char *prefix),
+ ("(N)", string_intern(self, prefix)))
+
+VOID_HANDLER(Comment,
+ (void *userData, const XML_Char *data),
+ ("(O&)", STRING_CONV_FUNC,data))
+
+VOID_HANDLER(StartCdataSection,
+ (void *userData),
+ ("()"))
+
+VOID_HANDLER(EndCdataSection,
+ (void *userData),
+ ("()"))
+
+#ifndef Py_USING_UNICODE
+VOID_HANDLER(Default,
+ (void *userData, const XML_Char *s, int len),
+ ("(N)", conv_string_len_to_utf8(s,len)))
+
+VOID_HANDLER(DefaultHandlerExpand,
+ (void *userData, const XML_Char *s, int len),
+ ("(N)", conv_string_len_to_utf8(s,len)))
+#else
+VOID_HANDLER(Default,
+ (void *userData, const XML_Char *s, int len),
+ ("(N)", (self->returns_unicode
+ ? conv_string_len_to_unicode(s,len)
+ : conv_string_len_to_utf8(s,len))))
+
+VOID_HANDLER(DefaultHandlerExpand,
+ (void *userData, const XML_Char *s, int len),
+ ("(N)", (self->returns_unicode
+ ? conv_string_len_to_unicode(s,len)
+ : conv_string_len_to_utf8(s,len))))
+#endif
+
+INT_HANDLER(NotStandalone,
+ (void *userData),
+ ("()"))
+
+RC_HANDLER(int, ExternalEntityRef,
+ (XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId),
+ int rc=0;,
+ ("(O&NNN)",
+ STRING_CONV_FUNC,context, string_intern(self, base),
+ string_intern(self, systemId), string_intern(self, publicId)),
+ rc = PyInt_AsLong(rv);, rc,
+ XML_GetUserData(parser))
+
+/* XXX UnknownEncodingHandler */
+
+VOID_HANDLER(StartDoctypeDecl,
+ (void *userData, const XML_Char *doctypeName,
+ const XML_Char *sysid, const XML_Char *pubid,
+ int has_internal_subset),
+ ("(NNNi)", string_intern(self, doctypeName),
+ string_intern(self, sysid), string_intern(self, pubid),
+ has_internal_subset))
+
+VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
+
+/* ---------------------------------------------------------------- */
+
+static PyObject *
+get_parse_result(xmlparseobject *self, int rv)
+{
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ if (rv == 0) {
+ return set_error(self, XML_GetErrorCode(self->itself));
+ }
+ if (flush_character_buffer(self) < 0) {
+ return NULL;
+ }
+ return PyInt_FromLong(rv);
+}
+
+PyDoc_STRVAR(xmlparse_Parse__doc__,
+"Parse(data[, isfinal])\n\
+Parse XML data. `isfinal' should be true at end of input.");
+
+static PyObject *
+xmlparse_Parse(xmlparseobject *self, PyObject *args)
+{
+ char *s;
+ int slen;
+ int isFinal = 0;
+
+ if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
+ return NULL;
+
+ return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
+}
+
+/* File reading copied from cPickle */
+
+#define BUF_SIZE 2048
+
+static int
+readinst(char *buf, int buf_size, PyObject *meth)
+{
+ PyObject *arg = NULL;
+ PyObject *bytes = NULL;
+ PyObject *str = NULL;
+ int len = -1;
+
+ if ((bytes = PyInt_FromLong(buf_size)) == NULL)
+ goto finally;
+
+ if ((arg = PyTuple_New(1)) == NULL) {
+ Py_DECREF(bytes);
+ goto finally;
+ }
+
+ PyTuple_SET_ITEM(arg, 0, bytes);
+
+#if PY_VERSION_HEX < 0x02020000
+ str = PyObject_CallObject(meth, arg);
+#else
+ str = PyObject_Call(meth, arg, NULL);
+#endif
+ if (str == NULL)
+ goto finally;
+
+ /* XXX what to do if it returns a Unicode string? */
+ if (!PyString_Check(str)) {
+ PyErr_Format(PyExc_TypeError,
+ "read() did not return a string object (type=%.400s)",
+ str->ob_type->tp_name);
+ goto finally;
+ }
+ len = PyString_GET_SIZE(str);
+ if (len > buf_size) {
+ PyErr_Format(PyExc_ValueError,
+ "read() returned too much data: "
+ "%i bytes requested, %i returned",
+ buf_size, len);
+ goto finally;
+ }
+ memcpy(buf, PyString_AsString(str), len);
+finally:
+ Py_XDECREF(arg);
+ Py_XDECREF(str);
+ return len;
+}
+
+PyDoc_STRVAR(xmlparse_ParseFile__doc__,
+"ParseFile(file)\n\
+Parse XML data from file-like object.");
+
+static PyObject *
+xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
+{
+ int rv = 1;
+ FILE *fp;
+ PyObject *readmethod = NULL;
+
+ if (PyFile_Check(f)) {
+ fp = PyFile_AsFile(f);
+ }
+ else {
+ fp = NULL;
+ readmethod = PyObject_GetAttrString(f, "read");
+ if (readmethod == NULL) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "argument must have 'read' attribute");
+ return NULL;
+ }
+ }
+ for (;;) {
+ int bytes_read;
+ void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
+ if (buf == NULL) {
+ Py_XDECREF(readmethod);
+ return PyErr_NoMemory();
+ }
+
+ if (fp) {
+ bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
+ if (bytes_read < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ }
+ else {
+ bytes_read = readinst(buf, BUF_SIZE, readmethod);
+ if (bytes_read < 0) {
+ Py_DECREF(readmethod);
+ return NULL;
+ }
+ }
+ rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
+ if (PyErr_Occurred()) {
+ Py_XDECREF(readmethod);
+ return NULL;
+ }
+
+ if (!rv || bytes_read == 0)
+ break;
+ }
+ Py_XDECREF(readmethod);
+ return get_parse_result(self, rv);
+}
+
+PyDoc_STRVAR(xmlparse_SetBase__doc__,
+"SetBase(base_url)\n\
+Set the base URL for the parser.");
+
+static PyObject *
+xmlparse_SetBase(xmlparseobject *self, PyObject *args)
+{
+ char *base;
+
+ if (!PyArg_ParseTuple(args, "s:SetBase", &base))
+ return NULL;
+ if (!XML_SetBase(self->itself, base)) {
+ return PyErr_NoMemory();
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(xmlparse_GetBase__doc__,
+"GetBase() -> url\n\
+Return base URL string for the parser.");
+
+static PyObject *
+xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
+{
+ return Py_BuildValue("z", XML_GetBase(self->itself));
+}
+
+PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
+"GetInputContext() -> string\n\
+Return the untranslated text of the input that caused the current event.\n\
+If the event was generated by a large amount of text (such as a start tag\n\
+for an element with many attributes), not all of the text may be available.");
+
+static PyObject *
+xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
+{
+ if (self->in_callback) {
+ int offset, size;
+ const char *buffer
+ = XML_GetInputContext(self->itself, &offset, &size);
+
+ if (buffer != NULL)
+ return PyString_FromStringAndSize(buffer + offset,
+ size - offset);
+ else
+ Py_RETURN_NONE;
+ }
+ else
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
+"ExternalEntityParserCreate(context[, encoding])\n\
+Create a parser for parsing an external entity based on the\n\
+information passed to the ExternalEntityRefHandler.");
+
+static PyObject *
+xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
+{
+ char *context;
+ char *encoding = NULL;
+ xmlparseobject *new_parser;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
+ &context, &encoding)) {
+ return NULL;
+ }
+
+#ifndef Py_TPFLAGS_HAVE_GC
+ /* Python versions 2.0 and 2.1 */
+ new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
+#else
+ /* Python versions 2.2 and later */
+ new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
+#endif
+
+ if (new_parser == NULL)
+ return NULL;
+ new_parser->buffer_size = self->buffer_size;
+ new_parser->buffer_used = 0;
+ if (self->buffer != NULL) {
+ new_parser->buffer = malloc(new_parser->buffer_size);
+ if (new_parser->buffer == NULL) {
+#ifndef Py_TPFLAGS_HAVE_GC
+ /* Code for versions 2.0 and 2.1 */
+ PyObject_Del(new_parser);
+#else
+ /* Code for versions 2.2 and later. */
+ PyObject_GC_Del(new_parser);
+#endif
+ return PyErr_NoMemory();
+ }
+ }
+ else
+ new_parser->buffer = NULL;
+ new_parser->returns_unicode = self->returns_unicode;
+ new_parser->ordered_attributes = self->ordered_attributes;
+ new_parser->specified_attributes = self->specified_attributes;
+ new_parser->in_callback = 0;
+ new_parser->ns_prefixes = self->ns_prefixes;
+ new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
+ encoding);
+ new_parser->handlers = 0;
+ new_parser->intern = self->intern;
+ Py_XINCREF(new_parser->intern);
+#ifdef Py_TPFLAGS_HAVE_GC
+ PyObject_GC_Track(new_parser);
+#else
+ PyObject_GC_Init(new_parser);
+#endif
+
+ if (!new_parser->itself) {
+ Py_DECREF(new_parser);
+ return PyErr_NoMemory();
+ }
+
+ XML_SetUserData(new_parser->itself, (void *)new_parser);
+
+ /* allocate and clear handlers first */
+ for (i = 0; handler_info[i].name != NULL; i++)
+ /* do nothing */;
+
+ new_parser->handlers = malloc(sizeof(PyObject *) * i);
+ if (!new_parser->handlers) {
+ Py_DECREF(new_parser);
+ return PyErr_NoMemory();
+ }
+ clear_handlers(new_parser, 1);
+
+ /* then copy handlers from self */
+ for (i = 0; handler_info[i].name != NULL; i++) {
+ PyObject *handler = self->handlers[i];
+ if (handler != NULL) {
+ Py_INCREF(handler);
+ new_parser->handlers[i] = handler;
+ handler_info[i].setter(new_parser->itself,
+ handler_info[i].handler);
+ }
+ }
+ return (PyObject *)new_parser;
+}
+
+PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
+"SetParamEntityParsing(flag) -> success\n\
+Controls parsing of parameter entities (including the external DTD\n\
+subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
+XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
+XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
+was successful.");
+
+static PyObject*
+xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
+{
+ int flag;
+ if (!PyArg_ParseTuple(args, "i", &flag))
+ return NULL;
+ flag = XML_SetParamEntityParsing(p->itself, flag);
+ return PyInt_FromLong(flag);
+}
+
+
+#if XML_COMBINED_VERSION >= 19505
+PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
+"UseForeignDTD([flag])\n\
+Allows the application to provide an artificial external subset if one is\n\
+not specified as part of the document instance. This readily allows the\n\
+use of a 'default' document type controlled by the application, while still\n\
+getting the advantage of providing document type information to the parser.\n\
+'flag' defaults to True if not provided.");
+
+static PyObject *
+xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
+{
+ PyObject *flagobj = NULL;
+ XML_Bool flag = XML_TRUE;
+ enum XML_Error rc;
+ if (!PyArg_UnpackTuple(args, "UseForeignDTD", 0, 1, &flagobj))
+ return NULL;
+ if (flagobj != NULL)
+ flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
+ rc = XML_UseForeignDTD(self->itself, flag);
+ if (rc != XML_ERROR_NONE) {
+ return set_error(self, rc);
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+static struct PyMethodDef xmlparse_methods[] = {
+ {"Parse", (PyCFunction)xmlparse_Parse,
+ METH_VARARGS, xmlparse_Parse__doc__},
+ {"ParseFile", (PyCFunction)xmlparse_ParseFile,
+ METH_O, xmlparse_ParseFile__doc__},
+ {"SetBase", (PyCFunction)xmlparse_SetBase,
+ METH_VARARGS, xmlparse_SetBase__doc__},
+ {"GetBase", (PyCFunction)xmlparse_GetBase,
+ METH_NOARGS, xmlparse_GetBase__doc__},
+ {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
+ METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
+ {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
+ METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
+ {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
+ METH_NOARGS, xmlparse_GetInputContext__doc__},
+#if XML_COMBINED_VERSION >= 19505
+ {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
+ METH_VARARGS, xmlparse_UseForeignDTD__doc__},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+
+#ifdef Py_USING_UNICODE
+
+/* pyexpat international encoding support.
+ Make it as simple as possible.
+*/
+
+static char template_buffer[257];
+PyObject *template_string = NULL;
+
+static void
+init_template_buffer(void)
+{
+ int i;
+ for (i = 0; i < 256; i++) {
+ template_buffer[i] = i;
+ }
+ template_buffer[256] = 0;
+}
+
+static int
+PyUnknownEncodingHandler(void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info)
+{
+ PyUnicodeObject *_u_string = NULL;
+ int result = 0;
+ int i;
+
+ /* Yes, supports only 8bit encodings */
+ _u_string = (PyUnicodeObject *)
+ PyUnicode_Decode(template_buffer, 256, name, "replace");
+
+ if (_u_string == NULL)
+ return result;
+
+ for (i = 0; i < 256; i++) {
+ /* Stupid to access directly, but fast */
+ Py_UNICODE c = _u_string->str[i];
+ if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
+ info->map[i] = -1;
+ else
+ info->map[i] = c;
+ }
+ info->data = NULL;
+ info->convert = NULL;
+ info->release = NULL;
+ result = 1;
+ Py_DECREF(_u_string);
+ return result;
+}
+
+#endif
+
+static PyObject *
+newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
+{
+ int i;
+ xmlparseobject *self;
+
+#ifdef Py_TPFLAGS_HAVE_GC
+ /* Code for versions 2.2 and later */
+ self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
+#else
+ self = PyObject_New(xmlparseobject, &Xmlparsetype);
+#endif
+ if (self == NULL)
+ return NULL;
+
+#ifdef Py_USING_UNICODE
+ self->returns_unicode = 1;
+#else
+ self->returns_unicode = 0;
+#endif
+
+ self->buffer = NULL;
+ self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
+ self->buffer_used = 0;
+ self->ordered_attributes = 0;
+ self->specified_attributes = 0;
+ self->in_callback = 0;
+ self->ns_prefixes = 0;
+ self->handlers = NULL;
+ if (namespace_separator != NULL) {
+ self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
+ }
+ else {
+ self->itself = XML_ParserCreate(encoding);
+ }
+ self->intern = intern;
+ Py_XINCREF(self->intern);
+#ifdef Py_TPFLAGS_HAVE_GC
+ PyObject_GC_Track(self);
+#else
+ PyObject_GC_Init(self);
+#endif
+ if (self->itself == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "XML_ParserCreate failed");
+ Py_DECREF(self);
+ return NULL;
+ }
+ XML_SetUserData(self->itself, (void *)self);
+#ifdef Py_USING_UNICODE
+ XML_SetUnknownEncodingHandler(self->itself,
+ (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
+#endif
+
+ for (i = 0; handler_info[i].name != NULL; i++)
+ /* do nothing */;
+
+ self->handlers = malloc(sizeof(PyObject *) * i);
+ if (!self->handlers) {
+ Py_DECREF(self);
+ return PyErr_NoMemory();
+ }
+ clear_handlers(self, 1);
+
+ return (PyObject*)self;
+}
+
+
+static void
+xmlparse_dealloc(xmlparseobject *self)
+{
+ int i;
+#ifdef Py_TPFLAGS_HAVE_GC
+ PyObject_GC_UnTrack(self);
+#else
+ PyObject_GC_Fini(self);
+#endif
+ if (self->itself != NULL)
+ XML_ParserFree(self->itself);
+ self->itself = NULL;
+
+ if (self->handlers != NULL) {
+ PyObject *temp;
+ for (i = 0; handler_info[i].name != NULL; i++) {
+ temp = self->handlers[i];
+ self->handlers[i] = NULL;
+ Py_XDECREF(temp);
+ }
+ free(self->handlers);
+ self->handlers = NULL;
+ }
+ if (self->buffer != NULL) {
+ free(self->buffer);
+ self->buffer = NULL;
+ }
+ Py_XDECREF(self->intern);
+#ifndef Py_TPFLAGS_HAVE_GC
+ /* Code for versions 2.0 and 2.1 */
+ PyObject_Del(self);
+#else
+ /* Code for versions 2.2 and later. */
+ PyObject_GC_Del(self);
+#endif
+}
+
+static int
+handlername2int(const char *name)
+{
+ int i;
+ for (i = 0; handler_info[i].name != NULL; i++) {
+ if (strcmp(name, handler_info[i].name) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static PyObject *
+get_pybool(int istrue)
+{
+ PyObject *result = istrue ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyObject *
+xmlparse_getattr(xmlparseobject *self, char *name)
+{
+ int handlernum = handlername2int(name);
+
+ if (handlernum != -1) {
+ PyObject *result = self->handlers[handlernum];
+ if (result == NULL)
+ result = Py_None;
+ Py_INCREF(result);
+ return result;
+ }
+ if (name[0] == 'E') {
+ if (strcmp(name, "ErrorCode") == 0)
+ return PyInt_FromLong((long)
+ XML_GetErrorCode(self->itself));
+ if (strcmp(name, "ErrorLineNumber") == 0)
+ return PyInt_FromLong((long)
+ XML_GetErrorLineNumber(self->itself));
+ if (strcmp(name, "ErrorColumnNumber") == 0)
+ return PyInt_FromLong((long)
+ XML_GetErrorColumnNumber(self->itself));
+ if (strcmp(name, "ErrorByteIndex") == 0)
+ return PyInt_FromLong((long)
+ XML_GetErrorByteIndex(self->itself));
+ }
+ if (name[0] == 'C') {
+ if (strcmp(name, "CurrentLineNumber") == 0)
+ return PyInt_FromLong((long)
+ XML_GetCurrentLineNumber(self->itself));
+ if (strcmp(name, "CurrentColumnNumber") == 0)
+ return PyInt_FromLong((long)
+ XML_GetCurrentColumnNumber(self->itself));
+ if (strcmp(name, "CurrentByteIndex") == 0)
+ return PyInt_FromLong((long)
+ XML_GetCurrentByteIndex(self->itself));
+ }
+ if (name[0] == 'b') {
+ if (strcmp(name, "buffer_size") == 0)
+ return PyInt_FromLong((long) self->buffer_size);
+ if (strcmp(name, "buffer_text") == 0)
+ return get_pybool(self->buffer != NULL);
+ if (strcmp(name, "buffer_used") == 0)
+ return PyInt_FromLong((long) self->buffer_used);
+ }
+ if (strcmp(name, "namespace_prefixes") == 0)
+ return get_pybool(self->ns_prefixes);
+ if (strcmp(name, "ordered_attributes") == 0)
+ return get_pybool(self->ordered_attributes);
+ if (strcmp(name, "returns_unicode") == 0)
+ return get_pybool((long) self->returns_unicode);
+ if (strcmp(name, "specified_attributes") == 0)
+ return get_pybool((long) self->specified_attributes);
+ if (strcmp(name, "intern") == 0) {
+ if (self->intern == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else {
+ Py_INCREF(self->intern);
+ return self->intern;
+ }
+ }
+
+#define APPEND(list, str) \
+ do { \
+ PyObject *o = PyString_FromString(str); \
+ if (o != NULL) \
+ PyList_Append(list, o); \
+ Py_XDECREF(o); \
+ } while (0)
+
+ if (strcmp(name, "__members__") == 0) {
+ int i;
+ PyObject *rc = PyList_New(0);
+ if (!rc)
+ return NULL;
+ for (i = 0; handler_info[i].name != NULL; i++) {
+ PyObject *o = get_handler_name(&handler_info[i]);
+ if (o != NULL)
+ PyList_Append(rc, o);
+ Py_XDECREF(o);
+ }
+ APPEND(rc, "ErrorCode");
+ APPEND(rc, "ErrorLineNumber");
+ APPEND(rc, "ErrorColumnNumber");
+ APPEND(rc, "ErrorByteIndex");
+ APPEND(rc, "CurrentLineNumber");
+ APPEND(rc, "CurrentColumnNumber");
+ APPEND(rc, "CurrentByteIndex");
+ APPEND(rc, "buffer_size");
+ APPEND(rc, "buffer_text");
+ APPEND(rc, "buffer_used");
+ APPEND(rc, "namespace_prefixes");
+ APPEND(rc, "ordered_attributes");
+ APPEND(rc, "returns_unicode");
+ APPEND(rc, "specified_attributes");
+ APPEND(rc, "intern");
+
+#undef APPEND
+ return rc;
+ }
+ return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
+}
+
+static int
+sethandler(xmlparseobject *self, const char *name, PyObject* v)
+{
+ int handlernum = handlername2int(name);
+ if (handlernum >= 0) {
+ xmlhandler c_handler = NULL;
+ PyObject *temp = self->handlers[handlernum];
+
+ if (v == Py_None) {
+ /* If this is the character data handler, and a character
+ data handler is already active, we need to be more
+ careful. What we can safely do is replace the existing
+ character data handler callback function with a no-op
+ function that will refuse to call Python. The downside
+ is that this doesn't completely remove the character
+ data handler from the C layer if there's any callback
+ active, so Expat does a little more work than it
+ otherwise would, but that's really an odd case. A more
+ elaborate system of handlers and state could remove the
+ C handler more effectively. */
+ if (handlernum == CharacterData && self->in_callback)
+ c_handler = noop_character_data_handler;
+ v = NULL;
+ }
+ else if (v != NULL) {
+ Py_INCREF(v);
+ c_handler = handler_info[handlernum].handler;
+ }
+ self->handlers[handlernum] = v;
+ Py_XDECREF(temp);
+ handler_info[handlernum].setter(self->itself, c_handler);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
+{
+ /* Set attribute 'name' to value 'v'. v==NULL means delete */
+ if (v == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
+ return -1;
+ }
+ if (strcmp(name, "buffer_text") == 0) {
+ if (PyObject_IsTrue(v)) {
+ if (self->buffer == NULL) {
+ self->buffer = malloc(self->buffer_size);
+ if (self->buffer == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->buffer_used = 0;
+ }
+ }
+ else if (self->buffer != NULL) {
+ if (flush_character_buffer(self) < 0)
+ return -1;
+ free(self->buffer);
+ self->buffer = NULL;
+ }
+ return 0;
+ }
+ if (strcmp(name, "namespace_prefixes") == 0) {
+ if (PyObject_IsTrue(v))
+ self->ns_prefixes = 1;
+ else
+ self->ns_prefixes = 0;
+ XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
+ return 0;
+ }
+ if (strcmp(name, "ordered_attributes") == 0) {
+ if (PyObject_IsTrue(v))
+ self->ordered_attributes = 1;
+ else
+ self->ordered_attributes = 0;
+ return 0;
+ }
+ if (strcmp(name, "returns_unicode") == 0) {
+ if (PyObject_IsTrue(v)) {
+#ifndef Py_USING_UNICODE
+ PyErr_SetString(PyExc_ValueError,
+ "Unicode support not available");
+ return -1;
+#else
+ self->returns_unicode = 1;
+#endif
+ }
+ else
+ self->returns_unicode = 0;
+ return 0;
+ }
+ if (strcmp(name, "specified_attributes") == 0) {
+ if (PyObject_IsTrue(v))
+ self->specified_attributes = 1;
+ else
+ self->specified_attributes = 0;
+ return 0;
+ }
+ if (strcmp(name, "CharacterDataHandler") == 0) {
+ /* If we're changing the character data handler, flush all
+ * cached data with the old handler. Not sure there's a
+ * "right" thing to do, though, but this probably won't
+ * happen.
+ */
+ if (flush_character_buffer(self) < 0)
+ return -1;
+ }
+ if (sethandler(self, name, v)) {
+ return 0;
+ }
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+}
+
+#ifdef WITH_CYCLE_GC
+static int
+xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
+{
+ int i;
+ for (i = 0; handler_info[i].name != NULL; i++)
+ Py_VISIT(op->handlers[i]);
+ return 0;
+}
+
+static int
+xmlparse_clear(xmlparseobject *op)
+{
+ clear_handlers(op, 0);
+ Py_CLEAR(op->intern);
+ return 0;
+}
+#endif
+
+PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
+
+static PyTypeObject Xmlparsetype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "pyexpat.xmlparser", /*tp_name*/
+ sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)xmlparse_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)xmlparse_getattr, /*tp_getattr*/
+ (setattrfunc)xmlparse_setattr, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+#ifdef Py_TPFLAGS_HAVE_GC
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+#else
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
+#endif
+ Xmlparsetype__doc__, /* tp_doc - Documentation string */
+#ifdef WITH_CYCLE_GC
+ (traverseproc)xmlparse_traverse, /* tp_traverse */
+ (inquiry)xmlparse_clear /* tp_clear */
+#else
+ 0, 0
+#endif
+};
+
+/* End of code for xmlparser objects */
+/* -------------------------------------------------------- */
+
+PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
+"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
+Return a new XML parser object.");
+
+static PyObject *
+pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
+{
+ char *encoding = NULL;
+ char *namespace_separator = NULL;
+ PyObject *intern = NULL;
+ PyObject *result;
+ int intern_decref = 0;
+ static char *kwlist[] = {"encoding", "namespace_separator",
+ "intern", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
+ &encoding, &namespace_separator, &intern))
+ return NULL;
+ if (namespace_separator != NULL
+ && strlen(namespace_separator) > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "namespace_separator must be at most one"
+ " character, omitted, or None");
+ return NULL;
+ }
+ /* Explicitly passing None means no interning is desired.
+ Not passing anything means that a new dictionary is used. */
+ if (intern == Py_None)
+ intern = NULL;
+ else if (intern == NULL) {
+ intern = PyDict_New();
+ if (!intern)
+ return NULL;
+ intern_decref = 1;
+ }
+ else if (!PyDict_Check(intern)) {
+ PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
+ return NULL;
+ }
+
+ result = newxmlparseobject(encoding, namespace_separator, intern);
+ if (intern_decref) {
+ Py_DECREF(intern);
+ }
+ return result;
+}
+
+PyDoc_STRVAR(pyexpat_ErrorString__doc__,
+"ErrorString(errno) -> string\n\
+Returns string error for given number.");
+
+static PyObject *
+pyexpat_ErrorString(PyObject *self, PyObject *args)
+{
+ long code = 0;
+
+ if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
+ return NULL;
+ return Py_BuildValue("z", XML_ErrorString((int)code));
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef pyexpat_methods[] = {
+ {"ParserCreate", (PyCFunction)pyexpat_ParserCreate,
+ METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
+ {"ErrorString", (PyCFunction)pyexpat_ErrorString,
+ METH_VARARGS, pyexpat_ErrorString__doc__},
+
+ {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
+};
+
+/* Module docstring */
+
+PyDoc_STRVAR(pyexpat_module_documentation,
+"Python wrapper for Expat parser.");
+
+/* Return a Python string that represents the version number without the
+ * extra cruft added by revision control, even if the right options were
+ * given to the "cvs export" command to make it not include the extra
+ * cruft.
+ */
+static PyObject *
+get_version_string(void)
+{
+ static char *rcsid = "$Revision: 47253 $";
+ char *rev = rcsid;
+ int i = 0;
+
+ while (!isdigit(Py_CHARMASK(*rev)))
+ ++rev;
+ while (rev[i] != ' ' && rev[i] != '\0')
+ ++i;
+
+ return PyString_FromStringAndSize(rev, i);
+}
+
+/* Initialization function for the module */
+
+#ifndef MODULE_NAME
+#define MODULE_NAME "pyexpat"
+#endif
+
+#ifndef MODULE_INITFUNC
+#define MODULE_INITFUNC initpyexpat
+#endif
+
+#ifndef PyMODINIT_FUNC
+# ifdef MS_WINDOWS
+# define PyMODINIT_FUNC __declspec(dllexport) void
+# else
+# define PyMODINIT_FUNC void
+# endif
+#endif
+
+PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */
+
+PyMODINIT_FUNC
+MODULE_INITFUNC(void)
+{
+ PyObject *m, *d;
+ PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
+ PyObject *errors_module;
+ PyObject *modelmod_name;
+ PyObject *model_module;
+ PyObject *sys_modules;
+ static struct PyExpat_CAPI capi;
+ PyObject* capi_object;
+
+ if (errmod_name == NULL)
+ return;
+ modelmod_name = PyString_FromString(MODULE_NAME ".model");
+ if (modelmod_name == NULL)
+ return;
+
+ Xmlparsetype.ob_type = &PyType_Type;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
+ pyexpat_module_documentation);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ if (ErrorObject == NULL) {
+ ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
+ NULL, NULL);
+ if (ErrorObject == NULL)
+ return;
+ }
+ Py_INCREF(ErrorObject);
+ PyModule_AddObject(m, "error", ErrorObject);
+ Py_INCREF(ErrorObject);
+ PyModule_AddObject(m, "ExpatError", ErrorObject);
+ Py_INCREF(&Xmlparsetype);
+ PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
+
+ PyModule_AddObject(m, "__version__", get_version_string());
+ PyModule_AddStringConstant(m, "EXPAT_VERSION",
+ (char *) XML_ExpatVersion());
+ {
+ XML_Expat_Version info = XML_ExpatVersionInfo();
+ PyModule_AddObject(m, "version_info",
+ Py_BuildValue("(iii)", info.major,
+ info.minor, info.micro));
+ }
+#ifdef Py_USING_UNICODE
+ init_template_buffer();
+#endif
+ /* XXX When Expat supports some way of figuring out how it was
+ compiled, this should check and set native_encoding
+ appropriately.
+ */
+ PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
+
+ sys_modules = PySys_GetObject("modules");
+ d = PyModule_GetDict(m);
+ errors_module = PyDict_GetItem(d, errmod_name);
+ if (errors_module == NULL) {
+ errors_module = PyModule_New(MODULE_NAME ".errors");
+ if (errors_module != NULL) {
+ PyDict_SetItem(sys_modules, errmod_name, errors_module);
+ /* gives away the reference to errors_module */
+ PyModule_AddObject(m, "errors", errors_module);
+ }
+ }
+ Py_DECREF(errmod_name);
+ model_module = PyDict_GetItem(d, modelmod_name);
+ if (model_module == NULL) {
+ model_module = PyModule_New(MODULE_NAME ".model");
+ if (model_module != NULL) {
+ PyDict_SetItem(sys_modules, modelmod_name, model_module);
+ /* gives away the reference to model_module */
+ PyModule_AddObject(m, "model", model_module);
+ }
+ }
+ Py_DECREF(modelmod_name);
+ if (errors_module == NULL || model_module == NULL)
+ /* Don't core dump later! */
+ return;
+
+#if XML_COMBINED_VERSION > 19505
+ {
+ const XML_Feature *features = XML_GetFeatureList();
+ PyObject *list = PyList_New(0);
+ if (list == NULL)
+ /* just ignore it */
+ PyErr_Clear();
+ else {
+ int i = 0;
+ for (; features[i].feature != XML_FEATURE_END; ++i) {
+ int ok;
+ PyObject *item = Py_BuildValue("si", features[i].name,
+ features[i].value);
+ if (item == NULL) {
+ Py_DECREF(list);
+ list = NULL;
+ break;
+ }
+ ok = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (ok < 0) {
+ PyErr_Clear();
+ break;
+ }
+ }
+ if (list != NULL)
+ PyModule_AddObject(m, "features", list);
+ }
+ }
+#endif
+
+#define MYCONST(name) \
+ PyModule_AddStringConstant(errors_module, #name, \
+ (char*)XML_ErrorString(name))
+
+ MYCONST(XML_ERROR_NO_MEMORY);
+ MYCONST(XML_ERROR_SYNTAX);
+ MYCONST(XML_ERROR_NO_ELEMENTS);
+ MYCONST(XML_ERROR_INVALID_TOKEN);
+ MYCONST(XML_ERROR_UNCLOSED_TOKEN);
+ MYCONST(XML_ERROR_PARTIAL_CHAR);
+ MYCONST(XML_ERROR_TAG_MISMATCH);
+ MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
+ MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
+ MYCONST(XML_ERROR_PARAM_ENTITY_REF);
+ MYCONST(XML_ERROR_UNDEFINED_ENTITY);
+ MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
+ MYCONST(XML_ERROR_ASYNC_ENTITY);
+ MYCONST(XML_ERROR_BAD_CHAR_REF);
+ MYCONST(XML_ERROR_BINARY_ENTITY_REF);
+ MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
+ MYCONST(XML_ERROR_MISPLACED_XML_PI);
+ MYCONST(XML_ERROR_UNKNOWN_ENCODING);
+ MYCONST(XML_ERROR_INCORRECT_ENCODING);
+ MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
+ MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
+ MYCONST(XML_ERROR_NOT_STANDALONE);
+ MYCONST(XML_ERROR_UNEXPECTED_STATE);
+ MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
+ MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
+ MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
+ /* Added in Expat 1.95.7. */
+ MYCONST(XML_ERROR_UNBOUND_PREFIX);
+ /* Added in Expat 1.95.8. */
+ MYCONST(XML_ERROR_UNDECLARING_PREFIX);
+ MYCONST(XML_ERROR_INCOMPLETE_PE);
+ MYCONST(XML_ERROR_XML_DECL);
+ MYCONST(XML_ERROR_TEXT_DECL);
+ MYCONST(XML_ERROR_PUBLICID);
+ MYCONST(XML_ERROR_SUSPENDED);
+ MYCONST(XML_ERROR_NOT_SUSPENDED);
+ MYCONST(XML_ERROR_ABORTED);
+ MYCONST(XML_ERROR_FINISHED);
+ MYCONST(XML_ERROR_SUSPEND_PE);
+
+ PyModule_AddStringConstant(errors_module, "__doc__",
+ "Constants used to describe error conditions.");
+
+#undef MYCONST
+
+#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
+ MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
+ MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
+ MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
+#undef MYCONST
+
+#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
+ PyModule_AddStringConstant(model_module, "__doc__",
+ "Constants used to interpret content model information.");
+
+ MYCONST(XML_CTYPE_EMPTY);
+ MYCONST(XML_CTYPE_ANY);
+ MYCONST(XML_CTYPE_MIXED);
+ MYCONST(XML_CTYPE_NAME);
+ MYCONST(XML_CTYPE_CHOICE);
+ MYCONST(XML_CTYPE_SEQ);
+
+ MYCONST(XML_CQUANT_NONE);
+ MYCONST(XML_CQUANT_OPT);
+ MYCONST(XML_CQUANT_REP);
+ MYCONST(XML_CQUANT_PLUS);
+#undef MYCONST
+
+ /* initialize pyexpat dispatch table */
+ capi.size = sizeof(capi);
+ capi.magic = PyExpat_CAPI_MAGIC;
+ capi.MAJOR_VERSION = XML_MAJOR_VERSION;
+ capi.MINOR_VERSION = XML_MINOR_VERSION;
+ capi.MICRO_VERSION = XML_MICRO_VERSION;
+ capi.ErrorString = XML_ErrorString;
+ capi.GetErrorCode = XML_GetErrorCode;
+ capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
+ capi.GetErrorLineNumber = XML_GetErrorLineNumber;
+ capi.Parse = XML_Parse;
+ capi.ParserCreate_MM = XML_ParserCreate_MM;
+ capi.ParserFree = XML_ParserFree;
+ capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
+ capi.SetCommentHandler = XML_SetCommentHandler;
+ capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
+ capi.SetElementHandler = XML_SetElementHandler;
+ capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
+ capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
+ capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
+ capi.SetUserData = XML_SetUserData;
+
+ /* export as cobject */
+ capi_object = PyCObject_FromVoidPtr(&capi, NULL);
+ if (capi_object)
+ PyModule_AddObject(m, "expat_CAPI", capi_object);
+}
+
+static void
+clear_handlers(xmlparseobject *self, int initial)
+{
+ int i = 0;
+ PyObject *temp;
+
+ for (; handler_info[i].name != NULL; i++) {
+ if (initial)
+ self->handlers[i] = NULL;
+ else {
+ temp = self->handlers[i];
+ self->handlers[i] = NULL;
+ Py_XDECREF(temp);
+ handler_info[i].setter(self->itself, NULL);
+ }
+ }
+}
+
+static struct HandlerInfo handler_info[] = {
+ {"StartElementHandler",
+ (xmlhandlersetter)XML_SetStartElementHandler,
+ (xmlhandler)my_StartElementHandler},
+ {"EndElementHandler",
+ (xmlhandlersetter)XML_SetEndElementHandler,
+ (xmlhandler)my_EndElementHandler},
+ {"ProcessingInstructionHandler",
+ (xmlhandlersetter)XML_SetProcessingInstructionHandler,
+ (xmlhandler)my_ProcessingInstructionHandler},
+ {"CharacterDataHandler",
+ (xmlhandlersetter)XML_SetCharacterDataHandler,
+ (xmlhandler)my_CharacterDataHandler},
+ {"UnparsedEntityDeclHandler",
+ (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
+ (xmlhandler)my_UnparsedEntityDeclHandler},
+ {"NotationDeclHandler",
+ (xmlhandlersetter)XML_SetNotationDeclHandler,
+ (xmlhandler)my_NotationDeclHandler},
+ {"StartNamespaceDeclHandler",
+ (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
+ (xmlhandler)my_StartNamespaceDeclHandler},
+ {"EndNamespaceDeclHandler",
+ (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
+ (xmlhandler)my_EndNamespaceDeclHandler},
+ {"CommentHandler",
+ (xmlhandlersetter)XML_SetCommentHandler,
+ (xmlhandler)my_CommentHandler},
+ {"StartCdataSectionHandler",
+ (xmlhandlersetter)XML_SetStartCdataSectionHandler,
+ (xmlhandler)my_StartCdataSectionHandler},
+ {"EndCdataSectionHandler",
+ (xmlhandlersetter)XML_SetEndCdataSectionHandler,
+ (xmlhandler)my_EndCdataSectionHandler},
+ {"DefaultHandler",
+ (xmlhandlersetter)XML_SetDefaultHandler,
+ (xmlhandler)my_DefaultHandler},
+ {"DefaultHandlerExpand",
+ (xmlhandlersetter)XML_SetDefaultHandlerExpand,
+ (xmlhandler)my_DefaultHandlerExpandHandler},
+ {"NotStandaloneHandler",
+ (xmlhandlersetter)XML_SetNotStandaloneHandler,
+ (xmlhandler)my_NotStandaloneHandler},
+ {"ExternalEntityRefHandler",
+ (xmlhandlersetter)XML_SetExternalEntityRefHandler,
+ (xmlhandler)my_ExternalEntityRefHandler},
+ {"StartDoctypeDeclHandler",
+ (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
+ (xmlhandler)my_StartDoctypeDeclHandler},
+ {"EndDoctypeDeclHandler",
+ (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
+ (xmlhandler)my_EndDoctypeDeclHandler},
+ {"EntityDeclHandler",
+ (xmlhandlersetter)XML_SetEntityDeclHandler,
+ (xmlhandler)my_EntityDeclHandler},
+ {"XmlDeclHandler",
+ (xmlhandlersetter)XML_SetXmlDeclHandler,
+ (xmlhandler)my_XmlDeclHandler},
+ {"ElementDeclHandler",
+ (xmlhandlersetter)XML_SetElementDeclHandler,
+ (xmlhandler)my_ElementDeclHandler},
+ {"AttlistDeclHandler",
+ (xmlhandlersetter)XML_SetAttlistDeclHandler,
+ (xmlhandler)my_AttlistDeclHandler},
+#if XML_COMBINED_VERSION >= 19504
+ {"SkippedEntityHandler",
+ (xmlhandlersetter)XML_SetSkippedEntityHandler,
+ (xmlhandler)my_SkippedEntityHandler},
+#endif
+
+ {NULL, NULL, NULL} /* sentinel */
+};
diff --git a/sys/src/cmd/python/Modules/python.c b/sys/src/cmd/python/Modules/python.c
new file mode 100644
index 000000000..2739b8b11
--- /dev/null
+++ b/sys/src/cmd/python/Modules/python.c
@@ -0,0 +1,24 @@
+/* Minimal main program -- everything is loaded from the library */
+
+#include "Python.h"
+
+#ifdef __FreeBSD__
+#include <floatingpoint.h>
+#endif
+
+int
+main(int argc, char **argv)
+{
+ /* 754 requires that FP exceptions run in "no stop" mode by default,
+ * and until C vendors implement C99's ways to control FP exceptions,
+ * Python requires non-stop mode. Alas, some platforms enable FP
+ * exceptions by default. Here we disable them.
+ */
+#ifdef __FreeBSD__
+ fp_except_t m;
+
+ m = fpgetmask();
+ fpsetmask(m & ~FP_X_OFL);
+#endif
+ return Py_Main(argc, argv);
+}
diff --git a/sys/src/cmd/python/Modules/readline.c b/sys/src/cmd/python/Modules/readline.c
new file mode 100644
index 000000000..853874be2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/readline.c
@@ -0,0 +1,941 @@
+/* This module makes GNU readline available to Python. It has ideas
+ * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
+ * Center. The completer interface was inspired by Lele Gaifax. More
+ * recently, it was largely rewritten by Guido van Rossum.
+ */
+
+/* Standard definitions */
+#include "Python.h"
+#include <setjmp.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#if defined(HAVE_SETLOCALE)
+/* GNU readline() mistakenly sets the LC_CTYPE locale.
+ * This is evil. Only the user or the app's main() should do this!
+ * We must save and restore the locale around the rl_initialize() call.
+ */
+#define SAVE_LOCALE
+#include <locale.h>
+#endif
+
+#ifdef SAVE_LOCALE
+# define RESTORE_LOCALE(sl) { setlocale(LC_CTYPE, sl); free(sl); }
+#else
+# define RESTORE_LOCALE(sl)
+#endif
+
+/* GNU readline definitions */
+#undef HAVE_CONFIG_H /* Else readline/chardefs.h includes strings.h */
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#ifdef HAVE_RL_COMPLETION_MATCHES
+#define completion_matches(x, y) \
+ rl_completion_matches((x), ((rl_compentry_func_t *)(y)))
+#endif
+
+
+/* Exported function to send one line to readline's init file parser */
+
+static PyObject *
+parse_and_bind(PyObject *self, PyObject *args)
+{
+ char *s, *copy;
+ if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
+ return NULL;
+ /* Make a copy -- rl_parse_and_bind() modifies its argument */
+ /* Bernard Herzog */
+ copy = malloc(1 + strlen(s));
+ if (copy == NULL)
+ return PyErr_NoMemory();
+ strcpy(copy, s);
+ rl_parse_and_bind(copy);
+ free(copy); /* Free the copy */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_parse_and_bind,
+"parse_and_bind(string) -> None\n\
+Parse and execute single line of a readline init file.");
+
+
+/* Exported function to parse a readline init file */
+
+static PyObject *
+read_init_file(PyObject *self, PyObject *args)
+{
+ char *s = NULL;
+ if (!PyArg_ParseTuple(args, "|z:read_init_file", &s))
+ return NULL;
+ errno = rl_read_init_file(s);
+ if (errno)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_read_init_file,
+"read_init_file([filename]) -> None\n\
+Parse a readline initialization file.\n\
+The default filename is the last filename used.");
+
+
+/* Exported function to load a readline history file */
+
+static PyObject *
+read_history_file(PyObject *self, PyObject *args)
+{
+ char *s = NULL;
+ if (!PyArg_ParseTuple(args, "|z:read_history_file", &s))
+ return NULL;
+ errno = read_history(s);
+ if (errno)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int _history_length = -1; /* do not truncate history by default */
+PyDoc_STRVAR(doc_read_history_file,
+"read_history_file([filename]) -> None\n\
+Load a readline history file.\n\
+The default filename is ~/.history.");
+
+
+/* Exported function to save a readline history file */
+
+static PyObject *
+write_history_file(PyObject *self, PyObject *args)
+{
+ char *s = NULL;
+ if (!PyArg_ParseTuple(args, "|z:write_history_file", &s))
+ return NULL;
+ errno = write_history(s);
+ if (!errno && _history_length >= 0)
+ history_truncate_file(s, _history_length);
+ if (errno)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_write_history_file,
+"write_history_file([filename]) -> None\n\
+Save a readline history file.\n\
+The default filename is ~/.history.");
+
+
+/* Set history length */
+
+static PyObject*
+set_history_length(PyObject *self, PyObject *args)
+{
+ int length = _history_length;
+ if (!PyArg_ParseTuple(args, "i:set_history_length", &length))
+ return NULL;
+ _history_length = length;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(set_history_length_doc,
+"set_history_length(length) -> None\n\
+set the maximal number of items which will be written to\n\
+the history file. A negative length is used to inhibit\n\
+history truncation.");
+
+
+/* Get history length */
+
+static PyObject*
+get_history_length(PyObject *self, PyObject *noarg)
+{
+ return PyInt_FromLong(_history_length);
+}
+
+PyDoc_STRVAR(get_history_length_doc,
+"get_history_length() -> int\n\
+return the maximum number of items that will be written to\n\
+the history file.");
+
+
+/* Generic hook function setter */
+
+static PyObject *
+set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
+{
+ PyObject *function = Py_None;
+ char buf[80];
+ PyOS_snprintf(buf, sizeof(buf), "|O:set_%.50s", funcname);
+ if (!PyArg_ParseTuple(args, buf, &function))
+ return NULL;
+ if (function == Py_None) {
+ Py_XDECREF(*hook_var);
+ *hook_var = NULL;
+ }
+ else if (PyCallable_Check(function)) {
+ PyObject *tmp = *hook_var;
+ Py_INCREF(function);
+ *hook_var = function;
+ Py_XDECREF(tmp);
+ }
+ else {
+ PyOS_snprintf(buf, sizeof(buf),
+ "set_%.50s(func): argument not callable",
+ funcname);
+ PyErr_SetString(PyExc_TypeError, buf);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* Exported functions to specify hook functions in Python */
+
+static PyObject *startup_hook = NULL;
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static PyObject *pre_input_hook = NULL;
+#endif
+
+static PyObject *
+set_startup_hook(PyObject *self, PyObject *args)
+{
+ return set_hook("startup_hook", &startup_hook, args);
+}
+
+PyDoc_STRVAR(doc_set_startup_hook,
+"set_startup_hook([function]) -> None\n\
+Set or remove the startup_hook function.\n\
+The function is called with no arguments just\n\
+before readline prints the first prompt.");
+
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+
+/* Set pre-input hook */
+
+static PyObject *
+set_pre_input_hook(PyObject *self, PyObject *args)
+{
+ return set_hook("pre_input_hook", &pre_input_hook, args);
+}
+
+PyDoc_STRVAR(doc_set_pre_input_hook,
+"set_pre_input_hook([function]) -> None\n\
+Set or remove the pre_input_hook function.\n\
+The function is called with no arguments after the first prompt\n\
+has been printed and just before readline starts reading input\n\
+characters.");
+
+#endif
+
+
+/* Exported function to specify a word completer in Python */
+
+static PyObject *completer = NULL;
+
+static PyObject *begidx = NULL;
+static PyObject *endidx = NULL;
+
+
+/* Get the beginning index for the scope of the tab-completion */
+
+static PyObject *
+get_begidx(PyObject *self, PyObject *noarg)
+{
+ Py_INCREF(begidx);
+ return begidx;
+}
+
+PyDoc_STRVAR(doc_get_begidx,
+"get_begidx() -> int\n\
+get the beginning index of the readline tab-completion scope");
+
+
+/* Get the ending index for the scope of the tab-completion */
+
+static PyObject *
+get_endidx(PyObject *self, PyObject *noarg)
+{
+ Py_INCREF(endidx);
+ return endidx;
+}
+
+PyDoc_STRVAR(doc_get_endidx,
+"get_endidx() -> int\n\
+get the ending index of the readline tab-completion scope");
+
+
+/* Set the tab-completion word-delimiters that readline uses */
+
+static PyObject *
+set_completer_delims(PyObject *self, PyObject *args)
+{
+ char *break_chars;
+
+ if(!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
+ return NULL;
+ }
+ free((void*)rl_completer_word_break_characters);
+ rl_completer_word_break_characters = strdup(break_chars);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_set_completer_delims,
+"set_completer_delims(string) -> None\n\
+set the readline word delimiters for tab-completion");
+
+static PyObject *
+py_remove_history(PyObject *self, PyObject *args)
+{
+ int entry_number;
+ HIST_ENTRY *entry;
+
+ if (!PyArg_ParseTuple(args, "i:remove_history", &entry_number))
+ return NULL;
+ if (entry_number < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "History index cannot be negative");
+ return NULL;
+ }
+ entry = remove_history(entry_number);
+ if (!entry) {
+ PyErr_Format(PyExc_ValueError,
+ "No history item at position %d",
+ entry_number);
+ return NULL;
+ }
+ /* free memory allocated for the history entry */
+ if (entry->line)
+ free(entry->line);
+ if (entry->data)
+ free(entry->data);
+ free(entry);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_remove_history,
+"remove_history_item(pos) -> None\n\
+remove history item given by its position");
+
+static PyObject *
+py_replace_history(PyObject *self, PyObject *args)
+{
+ int entry_number;
+ char *line;
+ HIST_ENTRY *old_entry;
+
+ if (!PyArg_ParseTuple(args, "is:replace_history", &entry_number, &line)) {
+ return NULL;
+ }
+ if (entry_number < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "History index cannot be negative");
+ return NULL;
+ }
+ old_entry = replace_history_entry(entry_number, line, (void *)NULL);
+ if (!old_entry) {
+ PyErr_Format(PyExc_ValueError,
+ "No history item at position %d",
+ entry_number);
+ return NULL;
+ }
+ /* free memory allocated for the old history entry */
+ if (old_entry->line)
+ free(old_entry->line);
+ if (old_entry->data)
+ free(old_entry->data);
+ free(old_entry);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_replace_history,
+"replace_history_item(pos, line) -> None\n\
+replaces history item given by its position with contents of line");
+
+/* Add a line to the history buffer */
+
+static PyObject *
+py_add_history(PyObject *self, PyObject *args)
+{
+ char *line;
+
+ if(!PyArg_ParseTuple(args, "s:add_history", &line)) {
+ return NULL;
+ }
+ add_history(line);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_add_history,
+"add_history(string) -> None\n\
+add a line to the history buffer");
+
+
+/* Get the tab-completion word-delimiters that readline uses */
+
+static PyObject *
+get_completer_delims(PyObject *self, PyObject *noarg)
+{
+ return PyString_FromString(rl_completer_word_break_characters);
+}
+
+PyDoc_STRVAR(doc_get_completer_delims,
+"get_completer_delims() -> string\n\
+get the readline word delimiters for tab-completion");
+
+
+/* Set the completer function */
+
+static PyObject *
+set_completer(PyObject *self, PyObject *args)
+{
+ return set_hook("completer", &completer, args);
+}
+
+PyDoc_STRVAR(doc_set_completer,
+"set_completer([function]) -> None\n\
+Set or remove the completer function.\n\
+The function is called as function(text, state),\n\
+for state in 0, 1, 2, ..., until it returns a non-string.\n\
+It should return the next possible completion starting with 'text'.");
+
+
+static PyObject *
+get_completer(PyObject *self, PyObject *noargs)
+{
+ if (completer == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ Py_INCREF(completer);
+ return completer;
+}
+
+PyDoc_STRVAR(doc_get_completer,
+"get_completer() -> function\n\
+\n\
+Returns current completer function.");
+
+/* Exported function to get any element of history */
+
+static PyObject *
+get_history_item(PyObject *self, PyObject *args)
+{
+ int idx = 0;
+ HIST_ENTRY *hist_ent;
+
+ if (!PyArg_ParseTuple(args, "i:index", &idx))
+ return NULL;
+ if ((hist_ent = history_get(idx)))
+ return PyString_FromString(hist_ent->line);
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyDoc_STRVAR(doc_get_history_item,
+"get_history_item() -> string\n\
+return the current contents of history item at index.");
+
+
+/* Exported function to get current length of history */
+
+static PyObject *
+get_current_history_length(PyObject *self, PyObject *noarg)
+{
+ HISTORY_STATE *hist_st;
+
+ hist_st = history_get_history_state();
+ return PyInt_FromLong(hist_st ? (long) hist_st->length : (long) 0);
+}
+
+PyDoc_STRVAR(doc_get_current_history_length,
+"get_current_history_length() -> integer\n\
+return the current (not the maximum) length of history.");
+
+
+/* Exported function to read the current line buffer */
+
+static PyObject *
+get_line_buffer(PyObject *self, PyObject *noarg)
+{
+ return PyString_FromString(rl_line_buffer);
+}
+
+PyDoc_STRVAR(doc_get_line_buffer,
+"get_line_buffer() -> string\n\
+return the current contents of the line buffer.");
+
+
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+
+/* Exported function to clear the current history */
+
+static PyObject *
+py_clear_history(PyObject *self, PyObject *noarg)
+{
+ clear_history();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_clear_history,
+"clear_history() -> None\n\
+Clear the current readline history.");
+#endif
+
+
+/* Exported function to insert text into the line buffer */
+
+static PyObject *
+insert_text(PyObject *self, PyObject *args)
+{
+ char *s;
+ if (!PyArg_ParseTuple(args, "s:insert_text", &s))
+ return NULL;
+ rl_insert_text(s);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_insert_text,
+"insert_text(string) -> None\n\
+Insert text into the command line.");
+
+
+/* Redisplay the line buffer */
+
+static PyObject *
+redisplay(PyObject *self, PyObject *noarg)
+{
+ rl_redisplay();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_redisplay,
+"redisplay() -> None\n\
+Change what's displayed on the screen to reflect the current\n\
+contents of the line buffer.");
+
+
+/* Table of functions exported by the module */
+
+static struct PyMethodDef readline_methods[] =
+{
+ {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind},
+ {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer},
+ {"insert_text", insert_text, METH_VARARGS, doc_insert_text},
+ {"redisplay", redisplay, METH_NOARGS, doc_redisplay},
+ {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
+ {"read_history_file", read_history_file,
+ METH_VARARGS, doc_read_history_file},
+ {"write_history_file", write_history_file,
+ METH_VARARGS, doc_write_history_file},
+ {"get_history_item", get_history_item,
+ METH_VARARGS, doc_get_history_item},
+ {"get_current_history_length", (PyCFunction)get_current_history_length,
+ METH_NOARGS, doc_get_current_history_length},
+ {"set_history_length", set_history_length,
+ METH_VARARGS, set_history_length_doc},
+ {"get_history_length", get_history_length,
+ METH_NOARGS, get_history_length_doc},
+ {"set_completer", set_completer, METH_VARARGS, doc_set_completer},
+ {"get_completer", get_completer, METH_NOARGS, doc_get_completer},
+ {"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx},
+ {"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
+
+ {"set_completer_delims", set_completer_delims,
+ METH_VARARGS, doc_set_completer_delims},
+ {"add_history", py_add_history, METH_VARARGS, doc_add_history},
+ {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
+ {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
+ {"get_completer_delims", get_completer_delims,
+ METH_NOARGS, doc_get_completer_delims},
+
+ {"set_startup_hook", set_startup_hook,
+ METH_VARARGS, doc_set_startup_hook},
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+ {"set_pre_input_hook", set_pre_input_hook,
+ METH_VARARGS, doc_set_pre_input_hook},
+#endif
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+ {"clear_history", py_clear_history, METH_NOARGS, doc_clear_history},
+#endif
+ {0, 0}
+};
+
+
+/* C function to call the Python hooks. */
+
+static int
+on_hook(PyObject *func)
+{
+ int result = 0;
+ if (func != NULL) {
+ PyObject *r;
+#ifdef WITH_THREAD
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
+ r = PyObject_CallFunction(func, NULL);
+ if (r == NULL)
+ goto error;
+ if (r == Py_None)
+ result = 0;
+ else {
+ result = PyInt_AsLong(r);
+ if (result == -1 && PyErr_Occurred())
+ goto error;
+ }
+ Py_DECREF(r);
+ goto done;
+ error:
+ PyErr_Clear();
+ Py_XDECREF(r);
+ done:
+#ifdef WITH_THREAD
+ PyGILState_Release(gilstate);
+#endif
+ return result;
+ }
+ return result;
+}
+
+static int
+on_startup_hook(void)
+{
+ return on_hook(startup_hook);
+}
+
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+static int
+on_pre_input_hook(void)
+{
+ return on_hook(pre_input_hook);
+}
+#endif
+
+
+/* C function to call the Python completer. */
+
+static char *
+on_completion(char *text, int state)
+{
+ char *result = NULL;
+ if (completer != NULL) {
+ PyObject *r;
+#ifdef WITH_THREAD
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
+ rl_attempted_completion_over = 1;
+ r = PyObject_CallFunction(completer, "si", text, state);
+ if (r == NULL)
+ goto error;
+ if (r == Py_None) {
+ result = NULL;
+ }
+ else {
+ char *s = PyString_AsString(r);
+ if (s == NULL)
+ goto error;
+ result = strdup(s);
+ }
+ Py_DECREF(r);
+ goto done;
+ error:
+ PyErr_Clear();
+ Py_XDECREF(r);
+ done:
+#ifdef WITH_THREAD
+ PyGILState_Release(gilstate);
+#endif
+ return result;
+ }
+ return result;
+}
+
+
+/* A more flexible constructor that saves the "begidx" and "endidx"
+ * before calling the normal completer */
+
+static char **
+flex_complete(char *text, int start, int end)
+{
+ Py_XDECREF(begidx);
+ Py_XDECREF(endidx);
+ begidx = PyInt_FromLong((long) start);
+ endidx = PyInt_FromLong((long) end);
+ return completion_matches(text, *on_completion);
+}
+
+
+/* Helper to initialize GNU readline properly. */
+
+static void
+setup_readline(void)
+{
+#ifdef SAVE_LOCALE
+ char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
+ if (!saved_locale)
+ Py_FatalError("not enough memory to save locale");
+#endif
+
+ using_history();
+
+ rl_readline_name = "python";
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ /* Allow $if term= in .inputrc to work */
+ rl_terminal_name = getenv("TERM");
+#endif
+ /* Force rebind of TAB to insert-tab */
+ rl_bind_key('\t', rl_insert);
+ /* Bind both ESC-TAB and ESC-ESC to the completion function */
+ rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
+ rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
+ /* Set our hook functions */
+ rl_startup_hook = (Function *)on_startup_hook;
+#ifdef HAVE_RL_PRE_INPUT_HOOK
+ rl_pre_input_hook = (Function *)on_pre_input_hook;
+#endif
+ /* Set our completion function */
+ rl_attempted_completion_function = (CPPFunction *)flex_complete;
+ /* Set Python word break characters */
+ rl_completer_word_break_characters =
+ strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
+ /* All nonalphanums except '.' */
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+ rl_completion_append_character ='\0';
+#endif
+
+ begidx = PyInt_FromLong(0L);
+ endidx = PyInt_FromLong(0L);
+ /* Initialize (allows .inputrc to override)
+ *
+ * XXX: A bug in the readline-2.2 library causes a memory leak
+ * inside this function. Nothing we can do about it.
+ */
+ rl_initialize();
+
+ RESTORE_LOCALE(saved_locale)
+}
+
+/* Wrapper around GNU readline that handles signals differently. */
+
+
+#if defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT)
+
+static char *completed_input_string;
+static void
+rlhandler(char *text)
+{
+ completed_input_string = text;
+ rl_callback_handler_remove();
+}
+
+extern PyThreadState* _PyOS_ReadlineTState;
+
+static char *
+readline_until_enter_or_signal(char *prompt, int *signal)
+{
+ char * not_done_reading = "";
+ fd_set selectset;
+
+ *signal = 0;
+#ifdef HAVE_RL_CATCH_SIGNAL
+ rl_catch_signals = 0;
+#endif
+
+ rl_callback_handler_install (prompt, rlhandler);
+ FD_ZERO(&selectset);
+
+ completed_input_string = not_done_reading;
+
+ while (completed_input_string == not_done_reading) {
+ int has_input = 0;
+
+ while (!has_input)
+ { struct timeval timeout = {0, 100000}; /* 0.1 seconds */
+
+ /* [Bug #1552726] Only limit the pause if an input hook has been
+ defined. */
+ struct timeval *timeoutp = NULL;
+ if (PyOS_InputHook)
+ timeoutp = &timeout;
+ FD_SET(fileno(rl_instream), &selectset);
+ /* select resets selectset if no input was available */
+ has_input = select(fileno(rl_instream) + 1, &selectset,
+ NULL, NULL, timeoutp);
+ if(PyOS_InputHook) PyOS_InputHook();
+ }
+
+ if(has_input > 0) {
+ rl_callback_read_char();
+ }
+ else if (errno == EINTR) {
+ int s;
+#ifdef WITH_THREAD
+ PyEval_RestoreThread(_PyOS_ReadlineTState);
+#endif
+ s = PyErr_CheckSignals();
+#ifdef WITH_THREAD
+ PyEval_SaveThread();
+#endif
+ if (s < 0) {
+ rl_free_line_state();
+ rl_cleanup_after_signal();
+ rl_callback_handler_remove();
+ *signal = 1;
+ completed_input_string = NULL;
+ }
+ }
+ }
+
+ return completed_input_string;
+}
+
+
+#else
+
+/* Interrupt handler */
+
+static jmp_buf jbuf;
+
+/* ARGSUSED */
+static void
+onintr(int sig)
+{
+ longjmp(jbuf, 1);
+}
+
+
+static char *
+readline_until_enter_or_signal(char *prompt, int *signal)
+{
+ PyOS_sighandler_t old_inthandler;
+ char *p;
+
+ *signal = 0;
+
+ old_inthandler = PyOS_setsig(SIGINT, onintr);
+ if (setjmp(jbuf)) {
+#ifdef HAVE_SIGRELSE
+ /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
+ sigrelse(SIGINT);
+#endif
+ PyOS_setsig(SIGINT, old_inthandler);
+ *signal = 1;
+ return NULL;
+ }
+ rl_event_hook = PyOS_InputHook;
+ p = readline(prompt);
+ PyOS_setsig(SIGINT, old_inthandler);
+
+ return p;
+}
+#endif /*defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) */
+
+
+static char *
+call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+ size_t n;
+ char *p, *q;
+ int signal;
+
+#ifdef SAVE_LOCALE
+ char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
+ if (!saved_locale)
+ Py_FatalError("not enough memory to save locale");
+ setlocale(LC_CTYPE, "");
+#endif
+
+ if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
+ rl_instream = sys_stdin;
+ rl_outstream = sys_stdout;
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+ rl_prep_terminal (1);
+#endif
+ }
+
+ p = readline_until_enter_or_signal(prompt, &signal);
+
+ /* we got an interrupt signal */
+ if (signal) {
+ RESTORE_LOCALE(saved_locale)
+ return NULL;
+ }
+
+ /* We got an EOF, return a empty string. */
+ if (p == NULL) {
+ p = PyMem_Malloc(1);
+ if (p != NULL)
+ *p = '\0';
+ RESTORE_LOCALE(saved_locale)
+ return p;
+ }
+
+ /* we have a valid line */
+ n = strlen(p);
+ if (n > 0) {
+ char *line;
+ HISTORY_STATE *state = history_get_history_state();
+ if (state->length > 0)
+ line = history_get(state->length)->line;
+ else
+ line = "";
+ if (strcmp(p, line))
+ add_history(p);
+ /* the history docs don't say so, but the address of state
+ changes each time history_get_history_state is called
+ which makes me think it's freshly malloc'd memory...
+ on the other hand, the address of the last line stays the
+ same as long as history isn't extended, so it appears to
+ be malloc'd but managed by the history package... */
+ free(state);
+ }
+ /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
+ release the original. */
+ q = p;
+ p = PyMem_Malloc(n+2);
+ if (p != NULL) {
+ strncpy(p, q, n);
+ p[n] = '\n';
+ p[n+1] = '\0';
+ }
+ free(q);
+ RESTORE_LOCALE(saved_locale)
+ return p;
+}
+
+
+/* Initialize the module */
+
+PyDoc_STRVAR(doc_module,
+"Importing this module enables command line editing using GNU readline.");
+
+PyMODINIT_FUNC
+initreadline(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule4("readline", readline_methods, doc_module,
+ (PyObject *)NULL, PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ PyOS_ReadlineFunctionPointer = call_readline;
+ setup_readline();
+}
diff --git a/sys/src/cmd/python/Modules/resource.c b/sys/src/cmd/python/Modules/resource.c
new file mode 100644
index 000000000..fe6f3b6a2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/resource.c
@@ -0,0 +1,325 @@
+
+#include "Python.h"
+#include "structseq.h"
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <string.h>
+#include <errno.h>
+/* for sysconf */
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+/* On some systems, these aren't in any header file.
+ On others they are, with inconsistent prototypes.
+ We declare the (default) return type, to shut up gcc -Wall;
+ but we can't declare the prototype, to avoid errors
+ when the header files declare it different.
+ Worse, on some Linuxes, getpagesize() returns a size_t... */
+
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+
+static PyObject *ResourceError;
+
+PyDoc_STRVAR(struct_rusage__doc__,
+"struct_rusage: Result from getrusage.\n\n"
+"This object may be accessed either as a tuple of\n"
+" (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
+" nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
+"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
+
+static PyStructSequence_Field struct_rusage_fields[] = {
+ {"ru_utime", "user time used"},
+ {"ru_stime", "system time used"},
+ {"ru_maxrss", "max. resident set size"},
+ {"ru_ixrss", "shared memory size"},
+ {"ru_idrss", "unshared data size"},
+ {"ru_isrss", "unshared stack size"},
+ {"ru_minflt", "page faults not requiring I/O"},
+ {"ru_majflt", "page faults requiring I/O"},
+ {"ru_nswap", "number of swap outs"},
+ {"ru_inblock", "block input operations"},
+ {"ru_oublock", "block output operations"},
+ {"ru_msgsnd", "IPC messages sent"},
+ {"ru_msgrcv", "IPC messages received"},
+ {"ru_nsignals", "signals received"},
+ {"ru_nvcsw", "voluntary context switches"},
+ {"ru_nivcsw", "involuntary context switches"},
+ {0}
+};
+
+static PyStructSequence_Desc struct_rusage_desc = {
+ "resource.struct_rusage", /* name */
+ struct_rusage__doc__, /* doc */
+ struct_rusage_fields, /* fields */
+ 16 /* n_in_sequence */
+};
+
+static int initialized;
+static PyTypeObject StructRUsageType;
+
+static PyObject *
+resource_getrusage(PyObject *self, PyObject *args)
+{
+ int who;
+ struct rusage ru;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "i:getrusage", &who))
+ return NULL;
+
+ if (getrusage(who, &ru) == -1) {
+ if (errno == EINVAL) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid who parameter");
+ return NULL;
+ }
+ PyErr_SetFromErrno(ResourceError);
+ return NULL;
+ }
+
+ result = PyStructSequence_New(&StructRUsageType);
+ if (!result)
+ return NULL;
+
+ PyStructSequence_SET_ITEM(result, 0,
+ PyFloat_FromDouble(doubletime(ru.ru_utime)));
+ PyStructSequence_SET_ITEM(result, 1,
+ PyFloat_FromDouble(doubletime(ru.ru_stime)));
+ PyStructSequence_SET_ITEM(result, 2, PyInt_FromLong(ru.ru_maxrss));
+ PyStructSequence_SET_ITEM(result, 3, PyInt_FromLong(ru.ru_ixrss));
+ PyStructSequence_SET_ITEM(result, 4, PyInt_FromLong(ru.ru_idrss));
+ PyStructSequence_SET_ITEM(result, 5, PyInt_FromLong(ru.ru_isrss));
+ PyStructSequence_SET_ITEM(result, 6, PyInt_FromLong(ru.ru_minflt));
+ PyStructSequence_SET_ITEM(result, 7, PyInt_FromLong(ru.ru_majflt));
+ PyStructSequence_SET_ITEM(result, 8, PyInt_FromLong(ru.ru_nswap));
+ PyStructSequence_SET_ITEM(result, 9, PyInt_FromLong(ru.ru_inblock));
+ PyStructSequence_SET_ITEM(result, 10, PyInt_FromLong(ru.ru_oublock));
+ PyStructSequence_SET_ITEM(result, 11, PyInt_FromLong(ru.ru_msgsnd));
+ PyStructSequence_SET_ITEM(result, 12, PyInt_FromLong(ru.ru_msgrcv));
+ PyStructSequence_SET_ITEM(result, 13, PyInt_FromLong(ru.ru_nsignals));
+ PyStructSequence_SET_ITEM(result, 14, PyInt_FromLong(ru.ru_nvcsw));
+ PyStructSequence_SET_ITEM(result, 15, PyInt_FromLong(ru.ru_nivcsw));
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+static PyObject *
+resource_getrlimit(PyObject *self, PyObject *args)
+{
+ struct rlimit rl;
+ int resource;
+
+ if (!PyArg_ParseTuple(args, "i:getrlimit", &resource))
+ return NULL;
+
+ if (resource < 0 || resource >= RLIM_NLIMITS) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid resource specified");
+ return NULL;
+ }
+
+ if (getrlimit(resource, &rl) == -1) {
+ PyErr_SetFromErrno(ResourceError);
+ return NULL;
+ }
+
+#if defined(HAVE_LONG_LONG)
+ if (sizeof(rl.rlim_cur) > sizeof(long)) {
+ return Py_BuildValue("LL",
+ (PY_LONG_LONG) rl.rlim_cur,
+ (PY_LONG_LONG) rl.rlim_max);
+ }
+#endif
+ return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max);
+}
+
+static PyObject *
+resource_setrlimit(PyObject *self, PyObject *args)
+{
+ struct rlimit rl;
+ int resource;
+ PyObject *curobj, *maxobj;
+
+ if (!PyArg_ParseTuple(args, "i(OO):setrlimit",
+ &resource, &curobj, &maxobj))
+ return NULL;
+
+ if (resource < 0 || resource >= RLIM_NLIMITS) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid resource specified");
+ return NULL;
+ }
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ rl.rlim_cur = PyInt_AsLong(curobj);
+ if (rl.rlim_cur == -1 && PyErr_Occurred())
+ return NULL;
+ rl.rlim_max = PyInt_AsLong(maxobj);
+ if (rl.rlim_max == -1 && PyErr_Occurred())
+ return NULL;
+#else
+ /* The limits are probably bigger than a long */
+ rl.rlim_cur = PyLong_Check(curobj) ?
+ PyLong_AsLongLong(curobj) : PyInt_AsLong(curobj);
+ if (rl.rlim_cur == -1 && PyErr_Occurred())
+ return NULL;
+ rl.rlim_max = PyLong_Check(maxobj) ?
+ PyLong_AsLongLong(maxobj) : PyInt_AsLong(maxobj);
+ if (rl.rlim_max == -1 && PyErr_Occurred())
+ return NULL;
+#endif
+
+ rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
+ rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
+ if (setrlimit(resource, &rl) == -1) {
+ if (errno == EINVAL)
+ PyErr_SetString(PyExc_ValueError,
+ "current limit exceeds maximum limit");
+ else if (errno == EPERM)
+ PyErr_SetString(PyExc_ValueError,
+ "not allowed to raise maximum limit");
+ else
+ PyErr_SetFromErrno(ResourceError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+resource_getpagesize(PyObject *self, PyObject *unused)
+{
+ long pagesize = 0;
+#if defined(HAVE_GETPAGESIZE)
+ pagesize = getpagesize();
+#elif defined(HAVE_SYSCONF)
+#if defined(_SC_PAGE_SIZE)
+ pagesize = sysconf(_SC_PAGE_SIZE);
+#else
+ /* Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE */
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#endif
+ return Py_BuildValue("i", pagesize);
+
+}
+
+/* List of functions */
+
+static struct PyMethodDef
+resource_methods[] = {
+ {"getrusage", resource_getrusage, METH_VARARGS},
+ {"getrlimit", resource_getrlimit, METH_VARARGS},
+ {"setrlimit", resource_setrlimit, METH_VARARGS},
+ {"getpagesize", resource_getpagesize, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Module initialization */
+
+PyMODINIT_FUNC
+initresource(void)
+{
+ PyObject *m, *v;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("resource", resource_methods);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ if (ResourceError == NULL) {
+ ResourceError = PyErr_NewException("resource.error",
+ NULL, NULL);
+ }
+ Py_INCREF(ResourceError);
+ PyModule_AddObject(m, "error", ResourceError);
+ if (!initialized)
+ PyStructSequence_InitType(&StructRUsageType,
+ &struct_rusage_desc);
+ Py_INCREF(&StructRUsageType);
+ PyModule_AddObject(m, "struct_rusage",
+ (PyObject*) &StructRUsageType);
+
+ /* insert constants */
+#ifdef RLIMIT_CPU
+ PyModule_AddIntConstant(m, "RLIMIT_CPU", RLIMIT_CPU);
+#endif
+
+#ifdef RLIMIT_FSIZE
+ PyModule_AddIntConstant(m, "RLIMIT_FSIZE", RLIMIT_FSIZE);
+#endif
+
+#ifdef RLIMIT_DATA
+ PyModule_AddIntConstant(m, "RLIMIT_DATA", RLIMIT_DATA);
+#endif
+
+#ifdef RLIMIT_STACK
+ PyModule_AddIntConstant(m, "RLIMIT_STACK", RLIMIT_STACK);
+#endif
+
+#ifdef RLIMIT_CORE
+ PyModule_AddIntConstant(m, "RLIMIT_CORE", RLIMIT_CORE);
+#endif
+
+#ifdef RLIMIT_NOFILE
+ PyModule_AddIntConstant(m, "RLIMIT_NOFILE", RLIMIT_NOFILE);
+#endif
+
+#ifdef RLIMIT_OFILE
+ PyModule_AddIntConstant(m, "RLIMIT_OFILE", RLIMIT_OFILE);
+#endif
+
+#ifdef RLIMIT_VMEM
+ PyModule_AddIntConstant(m, "RLIMIT_VMEM", RLIMIT_VMEM);
+#endif
+
+#ifdef RLIMIT_AS
+ PyModule_AddIntConstant(m, "RLIMIT_AS", RLIMIT_AS);
+#endif
+
+#ifdef RLIMIT_RSS
+ PyModule_AddIntConstant(m, "RLIMIT_RSS", RLIMIT_RSS);
+#endif
+
+#ifdef RLIMIT_NPROC
+ PyModule_AddIntConstant(m, "RLIMIT_NPROC", RLIMIT_NPROC);
+#endif
+
+#ifdef RLIMIT_MEMLOCK
+ PyModule_AddIntConstant(m, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
+#endif
+
+#ifdef RUSAGE_SELF
+ PyModule_AddIntConstant(m, "RUSAGE_SELF", RUSAGE_SELF);
+#endif
+
+#ifdef RUSAGE_CHILDREN
+ PyModule_AddIntConstant(m, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
+#endif
+
+#ifdef RUSAGE_BOTH
+ PyModule_AddIntConstant(m, "RUSAGE_BOTH", RUSAGE_BOTH);
+#endif
+
+#if defined(HAVE_LONG_LONG)
+ if (sizeof(RLIM_INFINITY) > sizeof(long)) {
+ v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY);
+ } else
+#endif
+ {
+ v = PyInt_FromLong((long) RLIM_INFINITY);
+ }
+ if (v) {
+ PyModule_AddObject(m, "RLIM_INFINITY", v);
+ }
+ initialized = 1;
+}
diff --git a/sys/src/cmd/python/Modules/rgbimgmodule.c b/sys/src/cmd/python/Modules/rgbimgmodule.c
new file mode 100644
index 000000000..0f9ee71f2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/rgbimgmodule.c
@@ -0,0 +1,780 @@
+/*
+ * fastimg -
+ * Faster reading and writing of image files.
+ *
+ * This code should work on machines with any byte order.
+ *
+ * Could someone make this run real fast using multiple processors
+ * or how about using memory mapped files to speed it up?
+ *
+ * Paul Haeberli - 1991
+ *
+ * Changed to return sizes.
+ * Sjoerd Mullender - 1993
+ * Changed to incorporate into Python.
+ * Sjoerd Mullender - 1993
+ */
+#include "Python.h"
+
+#if SIZEOF_INT == 4
+typedef int Py_Int32;
+typedef unsigned int Py_UInt32;
+#else
+#if SIZEOF_LONG == 4
+typedef long Py_Int32;
+typedef unsigned long Py_UInt32;
+#else
+#error "No 4-byte integral type"
+#endif
+#endif
+
+#include <string.h>
+
+/*
+ * from image.h
+ *
+ */
+typedef struct {
+ unsigned short imagic; /* stuff saved on disk . . */
+ unsigned short type;
+ unsigned short dim;
+ unsigned short xsize;
+ unsigned short ysize;
+ unsigned short zsize;
+ Py_UInt32 min;
+ Py_UInt32 max;
+ Py_UInt32 wastebytes;
+ char name[80];
+ Py_UInt32 colormap;
+
+ Py_Int32 file; /* stuff used in core only */
+ unsigned short flags;
+ short dorev;
+ short x;
+ short y;
+ short z;
+ short cnt;
+ unsigned short *ptr;
+ unsigned short *base;
+ unsigned short *tmpbuf;
+ Py_UInt32 offset;
+ Py_UInt32 rleend; /* for rle images */
+ Py_UInt32 *rowstart; /* for rle images */
+ Py_Int32 *rowsize; /* for rle images */
+} IMAGE;
+
+#define IMAGIC 0732
+
+#define TYPEMASK 0xff00
+#define BPPMASK 0x00ff
+#define ITYPE_VERBATIM 0x0000
+#define ITYPE_RLE 0x0100
+#define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE)
+#define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM)
+#define BPP(type) ((type) & BPPMASK)
+#define RLE(bpp) (ITYPE_RLE | (bpp))
+#define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp))
+/*
+ * end of image.h stuff
+ *
+ */
+
+#define RINTLUM (79)
+#define GINTLUM (156)
+#define BINTLUM (21)
+
+#define ILUM(r,g,b) ((int)(RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b))>>8)
+
+#define OFFSET_R 3 /* this is byte order dependent */
+#define OFFSET_G 2
+#define OFFSET_B 1
+#define OFFSET_A 0
+
+#define CHANOFFSET(z) (3-(z)) /* this is byte order dependent */
+
+static void expandrow(unsigned char *, unsigned char *, int);
+static void setalpha(unsigned char *, int);
+static void copybw(Py_Int32 *, int);
+static void interleaverow(unsigned char*, unsigned char*, int, int);
+static int compressrow(unsigned char *, unsigned char *, int, int);
+static void lumrow(unsigned char *, unsigned char *, int);
+
+#ifdef ADD_TAGS
+#define TAGLEN (5)
+#else
+#define TAGLEN (0)
+#endif
+
+static PyObject *ImgfileError;
+
+static int reverse_order;
+
+#ifdef ADD_TAGS
+/*
+ * addlongimgtag -
+ * this is used to extract image data from core dumps.
+ *
+ */
+static void
+addlongimgtag(Py_UInt32 *dptr, int xsize, int ysize)
+{
+ dptr = dptr + (xsize * ysize);
+ dptr[0] = 0x12345678;
+ dptr[1] = 0x59493333;
+ dptr[2] = 0x69434222;
+ dptr[3] = xsize;
+ dptr[4] = ysize;
+}
+#endif
+
+/*
+ * byte order independent read/write of shorts and longs.
+ *
+ */
+static unsigned short
+getshort(FILE *inf)
+{
+ unsigned char buf[2];
+
+ fread(buf, 2, 1, inf);
+ return (buf[0] << 8) + (buf[1] << 0);
+}
+
+static Py_UInt32
+getlong(FILE *inf)
+{
+ unsigned char buf[4];
+
+ fread(buf, 4, 1, inf);
+ return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0);
+}
+
+static void
+putshort(FILE *outf, unsigned short val)
+{
+ unsigned char buf[2];
+
+ buf[0] = (val >> 8);
+ buf[1] = (val >> 0);
+ fwrite(buf, 2, 1, outf);
+}
+
+static int
+putlong(FILE *outf, Py_UInt32 val)
+{
+ unsigned char buf[4];
+
+ buf[0] = (unsigned char) (val >> 24);
+ buf[1] = (unsigned char) (val >> 16);
+ buf[2] = (unsigned char) (val >> 8);
+ buf[3] = (unsigned char) (val >> 0);
+ return (int)fwrite(buf, 4, 1, outf);
+}
+
+static void
+readheader(FILE *inf, IMAGE *image)
+{
+ memset(image ,0, sizeof(IMAGE));
+ image->imagic = getshort(inf);
+ image->type = getshort(inf);
+ image->dim = getshort(inf);
+ image->xsize = getshort(inf);
+ image->ysize = getshort(inf);
+ image->zsize = getshort(inf);
+}
+
+static int
+writeheader(FILE *outf, IMAGE *image)
+{
+ IMAGE t;
+
+ memset(&t, 0, sizeof(IMAGE));
+ fwrite(&t, sizeof(IMAGE), 1, outf);
+ fseek(outf, 0, SEEK_SET);
+ putshort(outf, image->imagic);
+ putshort(outf, image->type);
+ putshort(outf, image->dim);
+ putshort(outf, image->xsize);
+ putshort(outf, image->ysize);
+ putshort(outf, image->zsize);
+ putlong(outf, image->min);
+ putlong(outf, image->max);
+ putlong(outf, 0);
+ return (int)fwrite("no name", 8, 1, outf);
+}
+
+static int
+writetab(FILE *outf, /*unsigned*/ Py_Int32 *tab, int len)
+{
+ int r = 0;
+
+ while(len) {
+ r = putlong(outf, *tab++);
+ len--;
+ }
+ return r;
+}
+
+static void
+readtab(FILE *inf, /*unsigned*/ Py_Int32 *tab, int len)
+{
+ while(len) {
+ *tab++ = getlong(inf);
+ len--;
+ }
+}
+
+/*
+ * sizeofimage -
+ * return the xsize and ysize of an iris image file.
+ *
+ */
+static PyObject *
+sizeofimage(PyObject *self, PyObject *args)
+{
+ char *name;
+ IMAGE image;
+ FILE *inf;
+
+ if (!PyArg_ParseTuple(args, "s:sizeofimage", &name))
+ return NULL;
+
+ inf = fopen(name, "rb");
+ if (!inf) {
+ PyErr_SetString(ImgfileError, "can't open image file");
+ return NULL;
+ }
+ readheader(inf, &image);
+ fclose(inf);
+ if (image.imagic != IMAGIC) {
+ PyErr_SetString(ImgfileError,
+ "bad magic number in image file");
+ return NULL;
+ }
+ return Py_BuildValue("(ii)", image.xsize, image.ysize);
+}
+
+/*
+ * longimagedata -
+ * read in a B/W RGB or RGBA iris image file and return a
+ * pointer to an array of longs.
+ *
+ */
+static PyObject *
+longimagedata(PyObject *self, PyObject *args)
+{
+ char *name;
+ unsigned char *base, *lptr;
+ unsigned char *rledat = NULL, *verdat = NULL;
+ Py_Int32 *starttab = NULL, *lengthtab = NULL;
+ FILE *inf = NULL;
+ IMAGE image;
+ int y, z, tablen;
+ int xsize, ysize, zsize;
+ int bpp, rle, cur, badorder;
+ int rlebuflen;
+ PyObject *rv = NULL;
+
+ if (!PyArg_ParseTuple(args, "s:longimagedata", &name))
+ return NULL;
+
+ inf = fopen(name,"rb");
+ if (!inf) {
+ PyErr_SetString(ImgfileError, "can't open image file");
+ return NULL;
+ }
+ readheader(inf,&image);
+ if (image.imagic != IMAGIC) {
+ PyErr_SetString(ImgfileError,
+ "bad magic number in image file");
+ goto finally;
+ }
+ rle = ISRLE(image.type);
+ bpp = BPP(image.type);
+ if (bpp != 1) {
+ PyErr_SetString(ImgfileError,
+ "image must have 1 byte per pix chan");
+ goto finally;
+ }
+ xsize = image.xsize;
+ ysize = image.ysize;
+ zsize = image.zsize;
+ if (rle) {
+ tablen = ysize * zsize * sizeof(Py_Int32);
+ starttab = (Py_Int32 *)malloc(tablen);
+ lengthtab = (Py_Int32 *)malloc(tablen);
+ rlebuflen = (int) (1.05 * xsize +10);
+ rledat = (unsigned char *)malloc(rlebuflen);
+ if (!starttab || !lengthtab || !rledat) {
+ PyErr_NoMemory();
+ goto finally;
+ }
+
+ fseek(inf, 512, SEEK_SET);
+ readtab(inf, starttab, ysize*zsize);
+ readtab(inf, lengthtab, ysize*zsize);
+
+ /* check data order */
+ cur = 0;
+ badorder = 0;
+ for(y = 0; y < ysize; y++) {
+ for(z = 0; z < zsize; z++) {
+ if (starttab[y + z * ysize] < cur) {
+ badorder = 1;
+ break;
+ }
+ cur = starttab[y +z * ysize];
+ }
+ if (badorder)
+ break;
+ }
+
+ fseek(inf, 512 + 2 * tablen, SEEK_SET);
+ cur = 512 + 2 * tablen;
+ rv = PyString_FromStringAndSize((char *)NULL,
+ (xsize * ysize + TAGLEN) * sizeof(Py_Int32));
+ if (rv == NULL)
+ goto finally;
+
+ base = (unsigned char *) PyString_AsString(rv);
+#ifdef ADD_TAGS
+ addlongimgtag(base,xsize,ysize);
+#endif
+ if (badorder) {
+ for (z = 0; z < zsize; z++) {
+ lptr = base;
+ if (reverse_order)
+ lptr += (ysize - 1) * xsize
+ * sizeof(Py_UInt32);
+ for (y = 0; y < ysize; y++) {
+ int idx = y + z * ysize;
+ if (cur != starttab[idx]) {
+ fseek(inf,starttab[idx],
+ SEEK_SET);
+ cur = starttab[idx];
+ }
+ if (lengthtab[idx] > rlebuflen) {
+ PyErr_SetString(ImgfileError,
+ "rlebuf is too small");
+ Py_DECREF(rv);
+ rv = NULL;
+ goto finally;
+ }
+ fread(rledat, lengthtab[idx], 1, inf);
+ cur += lengthtab[idx];
+ expandrow(lptr, rledat, 3-z);
+ if (reverse_order)
+ lptr -= xsize
+ * sizeof(Py_UInt32);
+ else
+ lptr += xsize
+ * sizeof(Py_UInt32);
+ }
+ }
+ } else {
+ lptr = base;
+ if (reverse_order)
+ lptr += (ysize - 1) * xsize
+ * sizeof(Py_UInt32);
+ for (y = 0; y < ysize; y++) {
+ for(z = 0; z < zsize; z++) {
+ int idx = y + z * ysize;
+ if (cur != starttab[idx]) {
+ fseek(inf, starttab[idx],
+ SEEK_SET);
+ cur = starttab[idx];
+ }
+ fread(rledat, lengthtab[idx], 1, inf);
+ cur += lengthtab[idx];
+ expandrow(lptr, rledat, 3-z);
+ }
+ if (reverse_order)
+ lptr -= xsize * sizeof(Py_UInt32);
+ else
+ lptr += xsize * sizeof(Py_UInt32);
+ }
+ }
+ if (zsize == 3)
+ setalpha(base, xsize * ysize);
+ else if (zsize < 3)
+ copybw((Py_Int32 *) base, xsize * ysize);
+ }
+ else {
+ rv = PyString_FromStringAndSize((char *) 0,
+ (xsize*ysize+TAGLEN)*sizeof(Py_Int32));
+ if (rv == NULL)
+ goto finally;
+
+ base = (unsigned char *) PyString_AsString(rv);
+#ifdef ADD_TAGS
+ addlongimgtag(base, xsize, ysize);
+#endif
+ verdat = (unsigned char *)malloc(xsize);
+ if (!verdat) {
+ Py_CLEAR(rv);
+ goto finally;
+ }
+
+ fseek(inf, 512, SEEK_SET);
+ for (z = 0; z < zsize; z++) {
+ lptr = base;
+ if (reverse_order)
+ lptr += (ysize - 1) * xsize
+ * sizeof(Py_UInt32);
+ for (y = 0; y < ysize; y++) {
+ fread(verdat, xsize, 1, inf);
+ interleaverow(lptr, verdat, 3-z, xsize);
+ if (reverse_order)
+ lptr -= xsize * sizeof(Py_UInt32);
+ else
+ lptr += xsize * sizeof(Py_UInt32);
+ }
+ }
+ if (zsize == 3)
+ setalpha(base, xsize * ysize);
+ else if (zsize < 3)
+ copybw((Py_Int32 *) base, xsize * ysize);
+ }
+ finally:
+ if (starttab)
+ free(starttab);
+ if (lengthtab)
+ free(lengthtab);
+ if (rledat)
+ free(rledat);
+ if (verdat)
+ free(verdat);
+ fclose(inf);
+ return rv;
+}
+
+/* static utility functions for longimagedata */
+
+static void
+interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n)
+{
+ lptr += z;
+ while (n--) {
+ *lptr = *cptr++;
+ lptr += 4;
+ }
+}
+
+static void
+copybw(Py_Int32 *lptr, int n)
+{
+ while (n >= 8) {
+ lptr[0] = 0xff000000 + (0x010101 * (lptr[0] & 0xff));
+ lptr[1] = 0xff000000 + (0x010101 * (lptr[1] & 0xff));
+ lptr[2] = 0xff000000 + (0x010101 * (lptr[2] & 0xff));
+ lptr[3] = 0xff000000 + (0x010101 * (lptr[3] & 0xff));
+ lptr[4] = 0xff000000 + (0x010101 * (lptr[4] & 0xff));
+ lptr[5] = 0xff000000 + (0x010101 * (lptr[5] & 0xff));
+ lptr[6] = 0xff000000 + (0x010101 * (lptr[6] & 0xff));
+ lptr[7] = 0xff000000 + (0x010101 * (lptr[7] & 0xff));
+ lptr += 8;
+ n -= 8;
+ }
+ while (n--) {
+ *lptr = 0xff000000 + (0x010101 * (*lptr&0xff));
+ lptr++;
+ }
+}
+
+static void
+setalpha(unsigned char *lptr, int n)
+{
+ while (n >= 8) {
+ lptr[0 * 4] = 0xff;
+ lptr[1 * 4] = 0xff;
+ lptr[2 * 4] = 0xff;
+ lptr[3 * 4] = 0xff;
+ lptr[4 * 4] = 0xff;
+ lptr[5 * 4] = 0xff;
+ lptr[6 * 4] = 0xff;
+ lptr[7 * 4] = 0xff;
+ lptr += 4 * 8;
+ n -= 8;
+ }
+ while (n--) {
+ *lptr = 0xff;
+ lptr += 4;
+ }
+}
+
+static void
+expandrow(unsigned char *optr, unsigned char *iptr, int z)
+{
+ unsigned char pixel, count;
+
+ optr += z;
+ while (1) {
+ pixel = *iptr++;
+ if (!(count = (pixel & 0x7f)))
+ return;
+ if (pixel & 0x80) {
+ while (count >= 8) {
+ optr[0 * 4] = iptr[0];
+ optr[1 * 4] = iptr[1];
+ optr[2 * 4] = iptr[2];
+ optr[3 * 4] = iptr[3];
+ optr[4 * 4] = iptr[4];
+ optr[5 * 4] = iptr[5];
+ optr[6 * 4] = iptr[6];
+ optr[7 * 4] = iptr[7];
+ optr += 8 * 4;
+ iptr += 8;
+ count -= 8;
+ }
+ while (count--) {
+ *optr = *iptr++;
+ optr += 4;
+ }
+ }
+ else {
+ pixel = *iptr++;
+ while (count >= 8) {
+ optr[0 * 4] = pixel;
+ optr[1 * 4] = pixel;
+ optr[2 * 4] = pixel;
+ optr[3 * 4] = pixel;
+ optr[4 * 4] = pixel;
+ optr[5 * 4] = pixel;
+ optr[6 * 4] = pixel;
+ optr[7 * 4] = pixel;
+ optr += 8 * 4;
+ count -= 8;
+ }
+ while (count--) {
+ *optr = pixel;
+ optr += 4;
+ }
+ }
+ }
+}
+
+/*
+ * longstoimage -
+ * copy an array of longs to an iris image file. Each long
+ * represents one pixel. xsize and ysize specify the dimensions of
+ * the pixel array. zsize specifies what kind of image file to
+ * write out. if zsize is 1, the luminance of the pixels are
+ * calculated, and a single channel black and white image is saved.
+ * If zsize is 3, an RGB image file is saved. If zsize is 4, an
+ * RGBA image file is saved.
+ *
+ */
+static PyObject *
+longstoimage(PyObject *self, PyObject *args)
+{
+ unsigned char *lptr;
+ char *name;
+ int xsize, ysize, zsize;
+ FILE *outf = NULL;
+ IMAGE image;
+ int tablen, y, z, pos, len;
+ Py_Int32 *starttab = NULL, *lengthtab = NULL;
+ unsigned char *rlebuf = NULL;
+ unsigned char *lumbuf = NULL;
+ int rlebuflen;
+ Py_ssize_t goodwrite;
+ PyObject *retval = NULL;
+
+ if (!PyArg_ParseTuple(args, "s#iiis:longstoimage", &lptr, &len,
+ &xsize, &ysize, &zsize, &name))
+ return NULL;
+
+ goodwrite = 1;
+ outf = fopen(name, "wb");
+ if (!outf) {
+ PyErr_SetString(ImgfileError, "can't open output file");
+ return NULL;
+ }
+ tablen = ysize * zsize * sizeof(Py_Int32);
+
+ starttab = (Py_Int32 *)malloc(tablen);
+ lengthtab = (Py_Int32 *)malloc(tablen);
+ rlebuflen = (int) (1.05 * xsize + 10);
+ rlebuf = (unsigned char *)malloc(rlebuflen);
+ lumbuf = (unsigned char *)malloc(xsize * sizeof(Py_Int32));
+ if (!starttab || !lengthtab || !rlebuf || !lumbuf) {
+ PyErr_NoMemory();
+ goto finally;
+ }
+
+ memset(&image, 0, sizeof(IMAGE));
+ image.imagic = IMAGIC;
+ image.type = RLE(1);
+ if (zsize>1)
+ image.dim = 3;
+ else
+ image.dim = 2;
+ image.xsize = xsize;
+ image.ysize = ysize;
+ image.zsize = zsize;
+ image.min = 0;
+ image.max = 255;
+ goodwrite *= writeheader(outf, &image);
+ pos = 512 + 2 * tablen;
+ fseek(outf, pos, SEEK_SET);
+ if (reverse_order)
+ lptr += (ysize - 1) * xsize * sizeof(Py_UInt32);
+ for (y = 0; y < ysize; y++) {
+ for (z = 0; z < zsize; z++) {
+ if (zsize == 1) {
+ lumrow(lptr, lumbuf, xsize);
+ len = compressrow(lumbuf, rlebuf,
+ CHANOFFSET(z), xsize);
+ } else {
+ len = compressrow(lptr, rlebuf,
+ CHANOFFSET(z), xsize);
+ }
+ if(len > rlebuflen) {
+ PyErr_SetString(ImgfileError,
+ "rlebuf is too small");
+ goto finally;
+ }
+ goodwrite *= fwrite(rlebuf, len, 1, outf);
+ starttab[y + z * ysize] = pos;
+ lengthtab[y + z * ysize] = len;
+ pos += len;
+ }
+ if (reverse_order)
+ lptr -= xsize * sizeof(Py_UInt32);
+ else
+ lptr += xsize * sizeof(Py_UInt32);
+ }
+
+ fseek(outf, 512, SEEK_SET);
+ goodwrite *= writetab(outf, starttab, ysize*zsize);
+ goodwrite *= writetab(outf, lengthtab, ysize*zsize);
+ if (goodwrite) {
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ } else
+ PyErr_SetString(ImgfileError, "not enough space for image");
+
+ finally:
+ fclose(outf);
+ free(starttab);
+ free(lengthtab);
+ free(rlebuf);
+ free(lumbuf);
+ return retval;
+}
+
+/* static utility functions for longstoimage */
+
+static void
+lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n)
+{
+ lumptr += CHANOFFSET(0);
+ while (n--) {
+ *lumptr = ILUM(rgbptr[OFFSET_R],
+ rgbptr[OFFSET_G],
+ rgbptr[OFFSET_B]);
+ lumptr += 4;
+ rgbptr += 4;
+ }
+}
+
+static int
+compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt)
+{
+ unsigned char *iptr, *ibufend, *sptr, *optr;
+ short todo, cc;
+ Py_Int32 count;
+
+ lbuf += z;
+ iptr = lbuf;
+ ibufend = iptr + cnt * 4;
+ optr = rlebuf;
+
+ while(iptr < ibufend) {
+ sptr = iptr;
+ iptr += 8;
+ while ((iptr<ibufend) &&
+ ((iptr[-8]!=iptr[-4]) ||(iptr[-4]!=iptr[0])))
+ {
+ iptr += 4;
+ }
+ iptr -= 8;
+ count = (iptr - sptr) / 4;
+ while (count) {
+ todo = count > 126 ? 126 : (short)count;
+ count -= todo;
+ *optr++ = 0x80 | todo;
+ while (todo > 8) {
+ optr[0] = sptr[0 * 4];
+ optr[1] = sptr[1 * 4];
+ optr[2] = sptr[2 * 4];
+ optr[3] = sptr[3 * 4];
+ optr[4] = sptr[4 * 4];
+ optr[5] = sptr[5 * 4];
+ optr[6] = sptr[6 * 4];
+ optr[7] = sptr[7 * 4];
+ optr += 8;
+ sptr += 8 * 4;
+ todo -= 8;
+ }
+ while (todo--) {
+ *optr++ = *sptr;
+ sptr += 4;
+ }
+ }
+ sptr = iptr;
+ cc = *iptr;
+ iptr += 4;
+ while ((iptr < ibufend) && (*iptr == cc))
+ iptr += 4;
+ count = (iptr - sptr) / 4;
+ while (count) {
+ todo = count > 126 ? 126 : (short)count;
+ count -= todo;
+ *optr++ = (unsigned char) todo;
+ *optr++ = (unsigned char) cc;
+ }
+ }
+ *optr++ = 0;
+ return optr - (unsigned char *)rlebuf;
+}
+
+static PyObject *
+ttob(PyObject *self, PyObject *args)
+{
+ int order, oldorder;
+
+ if (!PyArg_ParseTuple(args, "i:ttob", &order))
+ return NULL;
+ oldorder = reverse_order;
+ reverse_order = order;
+ return PyInt_FromLong(oldorder);
+}
+
+static PyMethodDef
+rgbimg_methods[] = {
+ {"sizeofimage", sizeofimage, METH_VARARGS},
+ {"longimagedata", longimagedata, METH_VARARGS},
+ {"longstoimage", longstoimage, METH_VARARGS},
+ {"ttob", ttob, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyMODINIT_FUNC
+initrgbimg(void)
+{
+ PyObject *m, *d;
+ m = Py_InitModule("rgbimg", rgbimg_methods);
+ if (m == NULL)
+ return;
+
+ if (PyErr_Warn(PyExc_DeprecationWarning,
+ "the rgbimg module is deprecated"))
+ return;
+
+ d = PyModule_GetDict(m);
+ ImgfileError = PyErr_NewException("rgbimg.error", NULL, NULL);
+ if (ImgfileError != NULL)
+ PyDict_SetItemString(d, "error", ImgfileError);
+}
diff --git a/sys/src/cmd/python/Modules/rotatingtree.c b/sys/src/cmd/python/Modules/rotatingtree.c
new file mode 100644
index 000000000..39c6dd53e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/rotatingtree.c
@@ -0,0 +1,121 @@
+#include "rotatingtree.h"
+
+#define KEY_LOWER_THAN(key1, key2) ((char*)(key1) < (char*)(key2))
+
+/* The randombits() function below is a fast-and-dirty generator that
+ * is probably irregular enough for our purposes. Note that it's biased:
+ * I think that ones are slightly more probable than zeroes. It's not
+ * important here, though.
+ */
+
+static unsigned int random_value = 1;
+static unsigned int random_stream = 0;
+
+static int
+randombits(int bits)
+{
+ int result;
+ if (random_stream < (1U << bits)) {
+ random_value *= 1082527;
+ random_stream = random_value;
+ }
+ result = random_stream & ((1<<bits)-1);
+ random_stream >>= bits;
+ return result;
+}
+
+
+/* Insert a new node into the tree.
+ (*root) is modified to point to the new root. */
+void
+RotatingTree_Add(rotating_node_t **root, rotating_node_t *node)
+{
+ while (*root != NULL) {
+ if (KEY_LOWER_THAN(node->key, (*root)->key))
+ root = &((*root)->left);
+ else
+ root = &((*root)->right);
+ }
+ node->left = NULL;
+ node->right = NULL;
+ *root = node;
+}
+
+/* Locate the node with the given key. This is the most complicated
+ function because it occasionally rebalances the tree to move the
+ resulting node closer to the root. */
+rotating_node_t *
+RotatingTree_Get(rotating_node_t **root, void *key)
+{
+ if (randombits(3) != 4) {
+ /* Fast path, no rebalancing */
+ rotating_node_t *node = *root;
+ while (node != NULL) {
+ if (node->key == key)
+ return node;
+ if (KEY_LOWER_THAN(key, node->key))
+ node = node->left;
+ else
+ node = node->right;
+ }
+ return NULL;
+ }
+ else {
+ rotating_node_t **pnode = root;
+ rotating_node_t *node = *pnode;
+ rotating_node_t *next;
+ int rotate;
+ if (node == NULL)
+ return NULL;
+ while (1) {
+ if (node->key == key)
+ return node;
+ rotate = !randombits(1);
+ if (KEY_LOWER_THAN(key, node->key)) {
+ next = node->left;
+ if (next == NULL)
+ return NULL;
+ if (rotate) {
+ node->left = next->right;
+ next->right = node;
+ *pnode = next;
+ }
+ else
+ pnode = &(node->left);
+ }
+ else {
+ next = node->right;
+ if (next == NULL)
+ return NULL;
+ if (rotate) {
+ node->right = next->left;
+ next->left = node;
+ *pnode = next;
+ }
+ else
+ pnode = &(node->right);
+ }
+ node = next;
+ }
+ }
+}
+
+/* Enumerate all nodes in the tree. The callback enumfn() should return
+ zero to continue the enumeration, or non-zero to interrupt it.
+ A non-zero value is directly returned by RotatingTree_Enum(). */
+int
+RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn,
+ void *arg)
+{
+ int result;
+ rotating_node_t *node;
+ while (root != NULL) {
+ result = RotatingTree_Enum(root->left, enumfn, arg);
+ if (result != 0) return result;
+ node = root->right;
+ result = enumfn(root, arg);
+ if (result != 0) return result;
+ root = node;
+ }
+ return 0;
+}
diff --git a/sys/src/cmd/python/Modules/rotatingtree.h b/sys/src/cmd/python/Modules/rotatingtree.h
new file mode 100644
index 000000000..3aa0986b4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/rotatingtree.h
@@ -0,0 +1,27 @@
+/* "Rotating trees" (Armin Rigo)
+ *
+ * Google "splay trees" for the general idea.
+ *
+ * It's a dict-like data structure that works best when accesses are not
+ * random, but follow a strong pattern. The one implemented here is for
+ * access patterns where the same small set of keys is looked up over
+ * and over again, and this set of keys evolves slowly over time.
+ */
+
+#include <stdlib.h>
+
+#define EMPTY_ROTATING_TREE ((rotating_node_t *)NULL)
+
+typedef struct rotating_node_s rotating_node_t;
+typedef int (*rotating_tree_enum_fn) (rotating_node_t *node, void *arg);
+
+struct rotating_node_s {
+ void *key;
+ rotating_node_t *left;
+ rotating_node_t *right;
+};
+
+void RotatingTree_Add(rotating_node_t **root, rotating_node_t *node);
+rotating_node_t* RotatingTree_Get(rotating_node_t **root, void *key);
+int RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn,
+ void *arg);
diff --git a/sys/src/cmd/python/Modules/selectmodule.c b/sys/src/cmd/python/Modules/selectmodule.c
new file mode 100644
index 000000000..9eaae8488
--- /dev/null
+++ b/sys/src/cmd/python/Modules/selectmodule.c
@@ -0,0 +1,734 @@
+/* select - Module containing unix select(2) call.
+ Under Unix, the file descriptors are small integers.
+ Under Win32, select only exists for sockets, and sockets may
+ have any value except INVALID_SOCKET.
+ Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
+ >= 0.
+*/
+
+#include "Python.h"
+
+#ifdef __APPLE__
+ /* Perform runtime testing for a broken poll on OSX to make it easier
+ * to use the same binary on multiple releases of the OS.
+ */
+#undef HAVE_BROKEN_POLL
+#endif
+
+/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
+ 64 is too small (too many people have bumped into that limit).
+ Here we boost it.
+ Users who want even more than the boosted limit should #define
+ FD_SETSIZE higher before this; e.g., via compiler /D switch.
+*/
+#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 512
+#endif
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+#ifdef __sgi
+/* This is missing from unistd.h */
+extern void bzero(void *, int);
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#include <sys/time.h>
+#include <utils.h>
+#endif
+
+#ifdef MS_WINDOWS
+# include <winsock.h>
+#else
+# define SOCKET int
+# ifdef __BEOS__
+# include <net/socket.h>
+# elif defined(__VMS)
+# include <socket.h>
+# endif
+#endif
+
+
+static PyObject *SelectError;
+
+/* list of Python objects and their file descriptor */
+typedef struct {
+ PyObject *obj; /* owned reference */
+ SOCKET fd;
+ int sentinel; /* -1 == sentinel */
+} pylist;
+
+static void
+reap_obj(pylist fd2obj[FD_SETSIZE + 1])
+{
+ int i;
+ for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
+ Py_XDECREF(fd2obj[i].obj);
+ fd2obj[i].obj = NULL;
+ }
+ fd2obj[0].sentinel = -1;
+}
+
+
+/* returns -1 and sets the Python exception if an error occurred, otherwise
+ returns a number >= 0
+*/
+static int
+seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
+{
+ int i;
+ int max = -1;
+ int index = 0;
+ int len = -1;
+ PyObject* fast_seq = NULL;
+ PyObject* o = NULL;
+
+ fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
+ FD_ZERO(set);
+
+ fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
+ if (!fast_seq)
+ return -1;
+
+ len = PySequence_Fast_GET_SIZE(fast_seq);
+
+ for (i = 0; i < len; i++) {
+ SOCKET v;
+
+ /* any intervening fileno() calls could decr this refcnt */
+ if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
+ return -1;
+
+ Py_INCREF(o);
+ v = PyObject_AsFileDescriptor( o );
+ if (v == -1) goto finally;
+
+#if defined(_MSC_VER)
+ max = 0; /* not used for Win32 */
+#else /* !_MSC_VER */
+ if (v < 0 || v >= FD_SETSIZE) {
+ PyErr_SetString(PyExc_ValueError,
+ "filedescriptor out of range in select()");
+ goto finally;
+ }
+ if (v > max)
+ max = v;
+#endif /* _MSC_VER */
+ FD_SET(v, set);
+
+ /* add object and its file descriptor to the list */
+ if (index >= FD_SETSIZE) {
+ PyErr_SetString(PyExc_ValueError,
+ "too many file descriptors in select()");
+ goto finally;
+ }
+ fd2obj[index].obj = o;
+ fd2obj[index].fd = v;
+ fd2obj[index].sentinel = 0;
+ fd2obj[++index].sentinel = -1;
+ }
+ Py_DECREF(fast_seq);
+ return max+1;
+
+ finally:
+ Py_XDECREF(o);
+ Py_DECREF(fast_seq);
+ return -1;
+}
+
+/* returns NULL and sets the Python exception if an error occurred */
+static PyObject *
+set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
+{
+ int i, j, count=0;
+ PyObject *list, *o;
+ SOCKET fd;
+
+ for (j = 0; fd2obj[j].sentinel >= 0; j++) {
+ if (FD_ISSET(fd2obj[j].fd, set))
+ count++;
+ }
+ list = PyList_New(count);
+ if (!list)
+ return NULL;
+
+ i = 0;
+ for (j = 0; fd2obj[j].sentinel >= 0; j++) {
+ fd = fd2obj[j].fd;
+ if (FD_ISSET(fd, set)) {
+#ifndef _MSC_VER
+ if (fd > FD_SETSIZE) {
+ PyErr_SetString(PyExc_SystemError,
+ "filedescriptor out of range returned in select()");
+ goto finally;
+ }
+#endif
+ o = fd2obj[j].obj;
+ fd2obj[j].obj = NULL;
+ /* transfer ownership */
+ if (PyList_SetItem(list, i, o) < 0)
+ goto finally;
+
+ i++;
+ }
+ }
+ return list;
+ finally:
+ Py_DECREF(list);
+ return NULL;
+}
+
+#undef SELECT_USES_HEAP
+#if FD_SETSIZE > 1024
+#define SELECT_USES_HEAP
+#endif /* FD_SETSIZE > 1024 */
+
+static PyObject *
+select_select(PyObject *self, PyObject *args)
+{
+#ifdef SELECT_USES_HEAP
+ pylist *rfd2obj, *wfd2obj, *efd2obj;
+#else /* !SELECT_USES_HEAP */
+ /* XXX: All this should probably be implemented as follows:
+ * - find the highest descriptor we're interested in
+ * - add one
+ * - that's the size
+ * See: Stevens, APitUE, $12.5.1
+ */
+ pylist rfd2obj[FD_SETSIZE + 1];
+ pylist wfd2obj[FD_SETSIZE + 1];
+ pylist efd2obj[FD_SETSIZE + 1];
+#endif /* SELECT_USES_HEAP */
+ PyObject *ifdlist, *ofdlist, *efdlist;
+ PyObject *ret = NULL;
+ PyObject *tout = Py_None;
+ fd_set ifdset, ofdset, efdset;
+ double timeout;
+ struct timeval tv, *tvp;
+ long seconds;
+ int imax, omax, emax, max;
+ int n;
+
+ /* convert arguments */
+ if (!PyArg_UnpackTuple(args, "select", 3, 4,
+ &ifdlist, &ofdlist, &efdlist, &tout))
+ return NULL;
+
+ if (tout == Py_None)
+ tvp = (struct timeval *)0;
+ else if (!PyNumber_Check(tout)) {
+ PyErr_SetString(PyExc_TypeError,
+ "timeout must be a float or None");
+ return NULL;
+ }
+ else {
+ timeout = PyFloat_AsDouble(tout);
+ if (timeout == -1 && PyErr_Occurred())
+ return NULL;
+ if (timeout > (double)LONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "timeout period too long");
+ return NULL;
+ }
+ seconds = (long)timeout;
+ timeout = timeout - (double)seconds;
+ tv.tv_sec = seconds;
+ tv.tv_usec = (long)(timeout*1000000.0);
+ tvp = &tv;
+ }
+
+
+#ifdef SELECT_USES_HEAP
+ /* Allocate memory for the lists */
+ rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+ wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+ efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+ if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
+ if (rfd2obj) PyMem_DEL(rfd2obj);
+ if (wfd2obj) PyMem_DEL(wfd2obj);
+ if (efd2obj) PyMem_DEL(efd2obj);
+ return PyErr_NoMemory();
+ }
+#endif /* SELECT_USES_HEAP */
+ /* Convert sequences to fd_sets, and get maximum fd number
+ * propagates the Python exception set in seq2set()
+ */
+ rfd2obj[0].sentinel = -1;
+ wfd2obj[0].sentinel = -1;
+ efd2obj[0].sentinel = -1;
+ if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
+ goto finally;
+ if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
+ goto finally;
+ if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
+ goto finally;
+ max = imax;
+ if (omax > max) max = omax;
+ if (emax > max) max = emax;
+
+ Py_BEGIN_ALLOW_THREADS
+ n = select(max, &ifdset, &ofdset, &efdset, tvp);
+ Py_END_ALLOW_THREADS
+
+#ifdef MS_WINDOWS
+ if (n == SOCKET_ERROR) {
+ PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
+ }
+#else
+ if (n < 0) {
+ PyErr_SetFromErrno(SelectError);
+ }
+#endif
+ else if (n == 0) {
+ /* optimization */
+ ifdlist = PyList_New(0);
+ if (ifdlist) {
+ ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist);
+ Py_DECREF(ifdlist);
+ }
+ }
+ else {
+ /* any of these three calls can raise an exception. it's more
+ convenient to test for this after all three calls... but
+ is that acceptable?
+ */
+ ifdlist = set2list(&ifdset, rfd2obj);
+ ofdlist = set2list(&ofdset, wfd2obj);
+ efdlist = set2list(&efdset, efd2obj);
+ if (PyErr_Occurred())
+ ret = NULL;
+ else
+ ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
+
+ Py_DECREF(ifdlist);
+ Py_DECREF(ofdlist);
+ Py_DECREF(efdlist);
+ }
+
+ finally:
+ reap_obj(rfd2obj);
+ reap_obj(wfd2obj);
+ reap_obj(efd2obj);
+#ifdef SELECT_USES_HEAP
+ PyMem_DEL(rfd2obj);
+ PyMem_DEL(wfd2obj);
+ PyMem_DEL(efd2obj);
+#endif /* SELECT_USES_HEAP */
+ return ret;
+}
+
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+/*
+ * poll() support
+ */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *dict;
+ int ufd_uptodate;
+ int ufd_len;
+ struct pollfd *ufds;
+} pollObject;
+
+static PyTypeObject poll_Type;
+
+/* Update the malloc'ed array of pollfds to match the dictionary
+ contained within a pollObject. Return 1 on success, 0 on an error.
+*/
+
+static int
+update_ufd_array(pollObject *self)
+{
+ Py_ssize_t i, pos;
+ PyObject *key, *value;
+
+ self->ufd_len = PyDict_Size(self->dict);
+ PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
+ if (self->ufds == NULL) {
+ PyErr_NoMemory();
+ return 0;
+ }
+
+ i = pos = 0;
+ while (PyDict_Next(self->dict, &pos, &key, &value)) {
+ self->ufds[i].fd = PyInt_AsLong(key);
+ self->ufds[i].events = (short)PyInt_AsLong(value);
+ i++;
+ }
+ self->ufd_uptodate = 1;
+ return 1;
+}
+
+PyDoc_STRVAR(poll_register_doc,
+"register(fd [, eventmask] ) -> None\n\n\
+Register a file descriptor with the polling object.\n\
+fd -- either an integer, or an object with a fileno() method returning an\n\
+ int.\n\
+events -- an optional bitmask describing the type of events to check for");
+
+static PyObject *
+poll_register(pollObject *self, PyObject *args)
+{
+ PyObject *o, *key, *value;
+ int fd, events = POLLIN | POLLPRI | POLLOUT;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
+ return NULL;
+ }
+
+ fd = PyObject_AsFileDescriptor(o);
+ if (fd == -1) return NULL;
+
+ /* Add entry to the internal dictionary: the key is the
+ file descriptor, and the value is the event mask. */
+ key = PyInt_FromLong(fd);
+ if (key == NULL)
+ return NULL;
+ value = PyInt_FromLong(events);
+ if (value == NULL) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ err = PyDict_SetItem(self->dict, key, value);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ if (err < 0)
+ return NULL;
+
+ self->ufd_uptodate = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(poll_unregister_doc,
+"unregister(fd) -> None\n\n\
+Remove a file descriptor being tracked by the polling object.");
+
+static PyObject *
+poll_unregister(pollObject *self, PyObject *o)
+{
+ PyObject *key;
+ int fd;
+
+ fd = PyObject_AsFileDescriptor( o );
+ if (fd == -1)
+ return NULL;
+
+ /* Check whether the fd is already in the array */
+ key = PyInt_FromLong(fd);
+ if (key == NULL)
+ return NULL;
+
+ if (PyDict_DelItem(self->dict, key) == -1) {
+ Py_DECREF(key);
+ /* This will simply raise the KeyError set by PyDict_DelItem
+ if the file descriptor isn't registered. */
+ return NULL;
+ }
+
+ Py_DECREF(key);
+ self->ufd_uptodate = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(poll_poll_doc,
+"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
+Polls the set of registered file descriptors, returning a list containing \n\
+any descriptors that have events or errors to report.");
+
+static PyObject *
+poll_poll(pollObject *self, PyObject *args)
+{
+ PyObject *result_list = NULL, *tout = NULL;
+ int timeout = 0, poll_result, i, j;
+ PyObject *value = NULL, *num = NULL;
+
+ if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
+ return NULL;
+ }
+
+ /* Check values for timeout */
+ if (tout == NULL || tout == Py_None)
+ timeout = -1;
+ else if (!PyNumber_Check(tout)) {
+ PyErr_SetString(PyExc_TypeError,
+ "timeout must be an integer or None");
+ return NULL;
+ }
+ else {
+ tout = PyNumber_Int(tout);
+ if (!tout)
+ return NULL;
+ timeout = PyInt_AsLong(tout);
+ Py_DECREF(tout);
+ if (timeout == -1 && PyErr_Occurred())
+ return NULL;
+ }
+
+ /* Ensure the ufd array is up to date */
+ if (!self->ufd_uptodate)
+ if (update_ufd_array(self) == 0)
+ return NULL;
+
+ /* call poll() */
+ Py_BEGIN_ALLOW_THREADS;
+ poll_result = poll(self->ufds, self->ufd_len, timeout);
+ Py_END_ALLOW_THREADS;
+
+ if (poll_result < 0) {
+ PyErr_SetFromErrno(SelectError);
+ return NULL;
+ }
+
+ /* build the result list */
+
+ result_list = PyList_New(poll_result);
+ if (!result_list)
+ return NULL;
+ else {
+ for (i = 0, j = 0; j < poll_result; j++) {
+ /* skip to the next fired descriptor */
+ while (!self->ufds[i].revents) {
+ i++;
+ }
+ /* if we hit a NULL return, set value to NULL
+ and break out of loop; code at end will
+ clean up result_list */
+ value = PyTuple_New(2);
+ if (value == NULL)
+ goto error;
+ num = PyInt_FromLong(self->ufds[i].fd);
+ if (num == NULL) {
+ Py_DECREF(value);
+ goto error;
+ }
+ PyTuple_SET_ITEM(value, 0, num);
+
+ /* The &0xffff is a workaround for AIX. 'revents'
+ is a 16-bit short, and IBM assigned POLLNVAL
+ to be 0x8000, so the conversion to int results
+ in a negative number. See SF bug #923315. */
+ num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
+ if (num == NULL) {
+ Py_DECREF(value);
+ goto error;
+ }
+ PyTuple_SET_ITEM(value, 1, num);
+ if ((PyList_SetItem(result_list, j, value)) == -1) {
+ Py_DECREF(value);
+ goto error;
+ }
+ i++;
+ }
+ }
+ return result_list;
+
+ error:
+ Py_DECREF(result_list);
+ return NULL;
+}
+
+static PyMethodDef poll_methods[] = {
+ {"register", (PyCFunction)poll_register,
+ METH_VARARGS, poll_register_doc},
+ {"unregister", (PyCFunction)poll_unregister,
+ METH_O, poll_unregister_doc},
+ {"poll", (PyCFunction)poll_poll,
+ METH_VARARGS, poll_poll_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static pollObject *
+newPollObject(void)
+{
+ pollObject *self;
+ self = PyObject_New(pollObject, &poll_Type);
+ if (self == NULL)
+ return NULL;
+ /* ufd_uptodate is a Boolean, denoting whether the
+ array pointed to by ufds matches the contents of the dictionary. */
+ self->ufd_uptodate = 0;
+ self->ufds = NULL;
+ self->dict = PyDict_New();
+ if (self->dict == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ return self;
+}
+
+static void
+poll_dealloc(pollObject *self)
+{
+ if (self->ufds != NULL)
+ PyMem_DEL(self->ufds);
+ Py_XDECREF(self->dict);
+ PyObject_Del(self);
+}
+
+static PyObject *
+poll_getattr(pollObject *self, char *name)
+{
+ return Py_FindMethod(poll_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject poll_Type = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "select.poll", /*tp_name*/
+ sizeof(pollObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)poll_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)poll_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+PyDoc_STRVAR(poll_doc,
+"Returns a polling object, which supports registering and\n\
+unregistering file descriptors, and then polling them for I/O events.");
+
+static PyObject *
+select_poll(PyObject *self, PyObject *unused)
+{
+ return (PyObject *)newPollObject();
+}
+
+#ifdef __APPLE__
+/*
+ * On some systems poll() sets errno on invalid file descriptors. We test
+ * for this at runtime because this bug may be fixed or introduced between
+ * OS releases.
+ */
+static int select_have_broken_poll(void)
+{
+ int poll_test;
+ int filedes[2];
+
+ struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
+
+ /* Create a file descriptor to make invalid */
+ if (pipe(filedes) < 0) {
+ return 1;
+ }
+ poll_struct.fd = filedes[0];
+ close(filedes[0]);
+ close(filedes[1]);
+ poll_test = poll(&poll_struct, 1, 0);
+ if (poll_test < 0) {
+ return 1;
+ } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
+ return 1;
+ }
+ return 0;
+}
+#endif /* __APPLE__ */
+
+#endif /* HAVE_POLL */
+
+PyDoc_STRVAR(select_doc,
+"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
+\n\
+Wait until one or more file descriptors are ready for some kind of I/O.\n\
+The first three arguments are sequences of file descriptors to be waited for:\n\
+rlist -- wait until ready for reading\n\
+wlist -- wait until ready for writing\n\
+xlist -- wait for an ``exceptional condition''\n\
+If only one kind of condition is required, pass [] for the other lists.\n\
+A file descriptor is either a socket or file object, or a small integer\n\
+gotten from a fileno() method call on one of those.\n\
+\n\
+The optional 4th argument specifies a timeout in seconds; it may be\n\
+a floating point number to specify fractions of seconds. If it is absent\n\
+or None, the call will never time out.\n\
+\n\
+The return value is a tuple of three lists corresponding to the first three\n\
+arguments; each contains the subset of the corresponding file descriptors\n\
+that are ready.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
+
+static PyMethodDef select_methods[] = {
+ {"select", select_select, METH_VARARGS, select_doc},
+#if defined(HAVE_POLL)
+ {"poll", select_poll, METH_NOARGS, poll_doc},
+#endif /* HAVE_POLL */
+ {0, 0}, /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"This module supports asynchronous I/O on multiple file descriptors.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
+
+PyMODINIT_FUNC
+initselect(void)
+{
+ PyObject *m;
+ m = Py_InitModule3("select", select_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ SelectError = PyErr_NewException("select.error", NULL, NULL);
+ Py_INCREF(SelectError);
+ PyModule_AddObject(m, "error", SelectError);
+#if defined(HAVE_POLL)
+
+#ifdef __APPLE__
+ if (select_have_broken_poll()) {
+ if (PyObject_DelAttrString(m, "poll") == -1) {
+ PyErr_Clear();
+ }
+ } else {
+#else
+ {
+#endif
+ poll_Type.ob_type = &PyType_Type;
+ PyModule_AddIntConstant(m, "POLLIN", POLLIN);
+ PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
+ PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
+ PyModule_AddIntConstant(m, "POLLERR", POLLERR);
+ PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
+ PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
+
+#ifdef POLLRDNORM
+ PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
+#endif
+#ifdef POLLRDBAND
+ PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
+#endif
+#ifdef POLLWRNORM
+ PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
+#endif
+#ifdef POLLWRBAND
+ PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
+#endif
+#ifdef POLLMSG
+ PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
+#endif
+ }
+#endif /* HAVE_POLL */
+}
diff --git a/sys/src/cmd/python/Modules/sgimodule.c b/sys/src/cmd/python/Modules/sgimodule.c
new file mode 100644
index 000000000..f7e12635c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sgimodule.c
@@ -0,0 +1,55 @@
+
+/* SGI module -- random SGI-specific things */
+
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static PyObject *
+sgi_nap(PyObject *self, PyObject *args)
+{
+ long ticks;
+ if (!PyArg_ParseTuple(args, "l:nap", &ticks))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ sginap(ticks);
+ Py_END_ALLOW_THREADS
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+extern char *_getpty(int *, int, mode_t, int);
+
+static PyObject *
+sgi__getpty(PyObject *self, PyObject *args)
+{
+ int oflag;
+ int mode;
+ int nofork;
+ char *name;
+ int fildes;
+ if (!PyArg_ParseTuple(args, "iii:_getpty", &oflag, &mode, &nofork))
+ return NULL;
+ errno = 0;
+ name = _getpty(&fildes, oflag, (mode_t)mode, nofork);
+ if (name == NULL) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return Py_BuildValue("(si)", name, fildes);
+}
+
+static PyMethodDef sgi_methods[] = {
+ {"nap", sgi_nap, METH_VARARGS},
+ {"_getpty", sgi__getpty, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+void
+initsgi(void)
+{
+ Py_InitModule("sgi", sgi_methods);
+}
diff --git a/sys/src/cmd/python/Modules/sha256module.c b/sys/src/cmd/python/Modules/sha256module.c
new file mode 100644
index 000000000..0effb0734
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sha256module.c
@@ -0,0 +1,701 @@
+/* SHA256 module */
+
+/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */
+
+/* See below for information about the original code this module was
+ based upon. Additional work performed by:
+
+ Andrew Kuchling (amk@amk.ca)
+ Greg Stein (gstein@lyra.org)
+ Trevor Perrin (trevp@trevp.net)
+
+ Copyright (C) 2005 Gregory P. Smith (greg@electricrain.com)
+ Licensed to PSF under a Contributor Agreement.
+
+*/
+
+/* SHA objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+
+/* Endianness testing and definitions */
+#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
+ if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
+
+#define PCT_LITTLE_ENDIAN 1
+#define PCT_BIG_ENDIAN 0
+
+/* Some useful types */
+
+typedef unsigned char SHA_BYTE;
+
+#if SIZEOF_INT == 4
+typedef unsigned int SHA_INT32; /* 32-bit integer */
+#else
+/* not defined. compilation will die. */
+#endif
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_BLOCKSIZE 64
+#define SHA_DIGESTSIZE 32
+
+/* The structure for storing SHA info */
+
+typedef struct {
+ PyObject_HEAD
+ SHA_INT32 digest[8]; /* Message digest */
+ SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
+ SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
+ int Endianness;
+ int local; /* unprocessed amount in data */
+ int digestsize;
+} SHAobject;
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+ array of longwords. */
+
+static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
+{
+ SHA_INT32 value;
+
+ if ( Endianness == PCT_BIG_ENDIAN )
+ return;
+
+ byteCount /= sizeof(*buffer);
+ while (byteCount--) {
+ value = *buffer;
+ value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
+ ( ( value & 0x00FF00FFL ) << 8 );
+ *buffer++ = ( value << 16 ) | ( value >> 16 );
+ }
+}
+
+static void SHAcopy(SHAobject *src, SHAobject *dest)
+{
+ dest->Endianness = src->Endianness;
+ dest->local = src->local;
+ dest->digestsize = src->digestsize;
+ dest->count_lo = src->count_lo;
+ dest->count_hi = src->count_hi;
+ memcpy(dest->digest, src->digest, sizeof(src->digest));
+ memcpy(dest->data, src->data, sizeof(src->data));
+}
+
+
+/* ------------------------------------------------------------------------
+ *
+ * This code for the SHA-256 algorithm was noted as public domain. The
+ * original headers are pasted below.
+ *
+ * Several changes have been made to make it more compatible with the
+ * Python environment and desired interface.
+ *
+ */
+
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * gurantee it works.
+ *
+ * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
+ */
+
+
+/* SHA256 by Tom St Denis */
+
+/* Various logical functions */
+#define ROR(x, y)\
+( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
+((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) (((x | y) & z) | (x & y))
+#define S(x, n) ROR((x),(n))
+#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
+#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+
+
+static void
+sha_transform(SHAobject *sha_info)
+{
+ int i;
+ SHA_INT32 S[8], W[64], t0, t1;
+
+ memcpy(W, sha_info->data, sizeof(sha_info->data));
+ longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
+
+ for (i = 16; i < 64; ++i) {
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+ }
+ for (i = 0; i < 8; ++i) {
+ S[i] = sha_info->digest[i];
+ }
+
+ /* Compress */
+#define RND(a,b,c,d,e,f,g,h,i,ki) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
+
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
+
+#undef RND
+
+ /* feedback */
+ for (i = 0; i < 8; i++) {
+ sha_info->digest[i] = sha_info->digest[i] + S[i];
+ }
+
+}
+
+
+
+/* initialize the SHA digest */
+
+static void
+sha_init(SHAobject *sha_info)
+{
+ TestEndianness(sha_info->Endianness)
+ sha_info->digest[0] = 0x6A09E667L;
+ sha_info->digest[1] = 0xBB67AE85L;
+ sha_info->digest[2] = 0x3C6EF372L;
+ sha_info->digest[3] = 0xA54FF53AL;
+ sha_info->digest[4] = 0x510E527FL;
+ sha_info->digest[5] = 0x9B05688CL;
+ sha_info->digest[6] = 0x1F83D9ABL;
+ sha_info->digest[7] = 0x5BE0CD19L;
+ sha_info->count_lo = 0L;
+ sha_info->count_hi = 0L;
+ sha_info->local = 0;
+ sha_info->digestsize = 32;
+}
+
+static void
+sha224_init(SHAobject *sha_info)
+{
+ TestEndianness(sha_info->Endianness)
+ sha_info->digest[0] = 0xc1059ed8L;
+ sha_info->digest[1] = 0x367cd507L;
+ sha_info->digest[2] = 0x3070dd17L;
+ sha_info->digest[3] = 0xf70e5939L;
+ sha_info->digest[4] = 0xffc00b31L;
+ sha_info->digest[5] = 0x68581511L;
+ sha_info->digest[6] = 0x64f98fa7L;
+ sha_info->digest[7] = 0xbefa4fa4L;
+ sha_info->count_lo = 0L;
+ sha_info->count_hi = 0L;
+ sha_info->local = 0;
+ sha_info->digestsize = 28;
+}
+
+
+/* update the SHA digest */
+
+static void
+sha_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
+{
+ int i;
+ SHA_INT32 clo;
+
+ clo = sha_info->count_lo + ((SHA_INT32) count << 3);
+ if (clo < sha_info->count_lo) {
+ ++sha_info->count_hi;
+ }
+ sha_info->count_lo = clo;
+ sha_info->count_hi += (SHA_INT32) count >> 29;
+ if (sha_info->local) {
+ i = SHA_BLOCKSIZE - sha_info->local;
+ if (i > count) {
+ i = count;
+ }
+ memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
+ count -= i;
+ buffer += i;
+ sha_info->local += i;
+ if (sha_info->local == SHA_BLOCKSIZE) {
+ sha_transform(sha_info);
+ }
+ else {
+ return;
+ }
+ }
+ while (count >= SHA_BLOCKSIZE) {
+ memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+ buffer += SHA_BLOCKSIZE;
+ count -= SHA_BLOCKSIZE;
+ sha_transform(sha_info);
+ }
+ memcpy(sha_info->data, buffer, count);
+ sha_info->local = count;
+}
+
+/* finish computing the SHA digest */
+
+static void
+sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
+{
+ int count;
+ SHA_INT32 lo_bit_count, hi_bit_count;
+
+ lo_bit_count = sha_info->count_lo;
+ hi_bit_count = sha_info->count_hi;
+ count = (int) ((lo_bit_count >> 3) & 0x3f);
+ ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
+ if (count > SHA_BLOCKSIZE - 8) {
+ memset(((SHA_BYTE *) sha_info->data) + count, 0,
+ SHA_BLOCKSIZE - count);
+ sha_transform(sha_info);
+ memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
+ }
+ else {
+ memset(((SHA_BYTE *) sha_info->data) + count, 0,
+ SHA_BLOCKSIZE - 8 - count);
+ }
+
+ /* GJS: note that we add the hi/lo in big-endian. sha_transform will
+ swap these values into host-order. */
+ sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
+ sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
+ sha_info->data[58] = (hi_bit_count >> 8) & 0xff;
+ sha_info->data[59] = (hi_bit_count >> 0) & 0xff;
+ sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
+ sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
+ sha_info->data[62] = (lo_bit_count >> 8) & 0xff;
+ sha_info->data[63] = (lo_bit_count >> 0) & 0xff;
+ sha_transform(sha_info);
+ digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
+ digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
+ digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
+ digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
+ digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
+ digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
+ digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
+ digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
+ digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
+ digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
+ digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
+ digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
+ digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
+ digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
+ digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
+ digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
+ digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
+ digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
+ digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
+ digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
+ digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
+ digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
+ digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
+ digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
+ digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
+ digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
+ digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
+ digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
+ digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
+ digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
+ digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
+ digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
+}
+
+/*
+ * End of copied SHA code.
+ *
+ * ------------------------------------------------------------------------
+ */
+
+static PyTypeObject SHA224type;
+static PyTypeObject SHA256type;
+
+
+static SHAobject *
+newSHA224object(void)
+{
+ return (SHAobject *)PyObject_New(SHAobject, &SHA224type);
+}
+
+static SHAobject *
+newSHA256object(void)
+{
+ return (SHAobject *)PyObject_New(SHAobject, &SHA256type);
+}
+
+/* Internal methods for a hash object */
+
+static void
+SHA_dealloc(PyObject *ptr)
+{
+ PyObject_Del(ptr);
+}
+
+
+/* External methods for a hash object */
+
+PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+SHA256_copy(SHAobject *self, PyObject *unused)
+{
+ SHAobject *newobj;
+
+ if (((PyObject*)self)->ob_type == &SHA256type) {
+ if ( (newobj = newSHA256object())==NULL)
+ return NULL;
+ } else {
+ if ( (newobj = newSHA224object())==NULL)
+ return NULL;
+ }
+
+ SHAcopy(self, newobj);
+ return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SHA256_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SHA256_digest(SHAobject *self, PyObject *unused)
+{
+ unsigned char digest[SHA_DIGESTSIZE];
+ SHAobject temp;
+
+ SHAcopy(self, &temp);
+ sha_final(digest, &temp);
+ return PyString_FromStringAndSize((const char *)digest, self->digestsize);
+}
+
+PyDoc_STRVAR(SHA256_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SHA256_hexdigest(SHAobject *self, PyObject *unused)
+{
+ unsigned char digest[SHA_DIGESTSIZE];
+ SHAobject temp;
+ PyObject *retval;
+ char *hex_digest;
+ int i, j;
+
+ /* Get the raw (binary) digest value */
+ SHAcopy(self, &temp);
+ sha_final(digest, &temp);
+
+ /* Create a new string */
+ retval = PyString_FromStringAndSize(NULL, self->digestsize * 2);
+ if (!retval)
+ return NULL;
+ hex_digest = PyString_AsString(retval);
+ if (!hex_digest) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+
+ /* Make hex version of the digest */
+ for(i=j=0; i<self->digestsize; i++) {
+ char c;
+ c = (digest[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ c = (digest[i] & 0xf);
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ }
+ return retval;
+}
+
+PyDoc_STRVAR(SHA256_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+SHA256_update(SHAobject *self, PyObject *args)
+{
+ unsigned char *cp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+ return NULL;
+
+ sha_update(self, cp, len);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef SHA_methods[] = {
+ {"copy", (PyCFunction)SHA256_copy, METH_NOARGS, SHA256_copy__doc__},
+ {"digest", (PyCFunction)SHA256_digest, METH_NOARGS, SHA256_digest__doc__},
+ {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS, SHA256_hexdigest__doc__},
+ {"update", (PyCFunction)SHA256_update, METH_VARARGS, SHA256_update__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+SHA256_get_block_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(SHA_BLOCKSIZE);
+}
+
+static PyObject *
+SHA256_get_name(PyObject *self, void *closure)
+{
+ if (((SHAobject *)self)->digestsize == 32)
+ return PyString_FromStringAndSize("SHA256", 6);
+ else
+ return PyString_FromStringAndSize("SHA224", 6);
+}
+
+static PyGetSetDef SHA_getseters[] = {
+ {"block_size",
+ (getter)SHA256_get_block_size, NULL,
+ NULL,
+ NULL},
+ {"name",
+ (getter)SHA256_get_name, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyMemberDef SHA_members[] = {
+ {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+ /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+ * the old sha module also supported 'digestsize'. ugh. */
+ {"digestsize", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject SHA224type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_sha256.sha224", /*tp_name*/
+ sizeof(SHAobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ SHA_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ SHA_methods, /* tp_methods */
+ SHA_members, /* tp_members */
+ SHA_getseters, /* tp_getset */
+};
+
+static PyTypeObject SHA256type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_sha256.sha256", /*tp_name*/
+ sizeof(SHAobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ SHA_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ SHA_methods, /* tp_methods */
+ SHA_members, /* tp_members */
+ SHA_getseters, /* tp_getset */
+};
+
+
+/* The single module-level function: new() */
+
+PyDoc_STRVAR(SHA256_new__doc__,
+"Return a new SHA-256 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHAobject *new;
+ unsigned char *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+ &cp, &len)) {
+ return NULL;
+ }
+
+ if ((new = newSHA256object()) == NULL)
+ return NULL;
+
+ sha_init(new);
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (cp)
+ sha_update(new, cp, len);
+
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA224_new__doc__,
+"Return a new SHA-224 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHAobject *new;
+ unsigned char *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+ &cp, &len)) {
+ return NULL;
+ }
+
+ if ((new = newSHA224object()) == NULL)
+ return NULL;
+
+ sha224_init(new);
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (cp)
+ sha_update(new, cp, len);
+
+ return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SHA_functions[] = {
+ {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__},
+ {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
+
+PyMODINIT_FUNC
+init_sha256(void)
+{
+ PyObject *m;
+
+ SHA224type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA224type) < 0)
+ return;
+ SHA256type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA256type) < 0)
+ return;
+ m = Py_InitModule("_sha256", SHA_functions);
+ if (m == NULL)
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/sha512module.c b/sys/src/cmd/python/Modules/sha512module.c
new file mode 100644
index 000000000..9f47b6128
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sha512module.c
@@ -0,0 +1,769 @@
+/* SHA512 module */
+
+/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */
+
+/* See below for information about the original code this module was
+ based upon. Additional work performed by:
+
+ Andrew Kuchling (amk@amk.ca)
+ Greg Stein (gstein@lyra.org)
+ Trevor Perrin (trevp@trevp.net)
+
+ Copyright (C) 2005 Gregory P. Smith (greg@electricrain.com)
+ Licensed to PSF under a Contributor Agreement.
+
+*/
+
+/* SHA objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef PY_LONG_LONG /* If no PY_LONG_LONG, don't compile anything! */
+
+/* Endianness testing and definitions */
+#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
+ if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
+
+#define PCT_LITTLE_ENDIAN 1
+#define PCT_BIG_ENDIAN 0
+
+/* Some useful types */
+
+typedef unsigned char SHA_BYTE;
+
+#if SIZEOF_INT == 4
+typedef unsigned int SHA_INT32; /* 32-bit integer */
+typedef unsigned PY_LONG_LONG SHA_INT64; /* 64-bit integer */
+#else
+/* not defined. compilation will die. */
+#endif
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_BLOCKSIZE 128
+#define SHA_DIGESTSIZE 64
+
+/* The structure for storing SHA info */
+
+typedef struct {
+ PyObject_HEAD
+ SHA_INT64 digest[8]; /* Message digest */
+ SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
+ SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
+ int Endianness;
+ int local; /* unprocessed amount in data */
+ int digestsize;
+} SHAobject;
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+ array of longwords. */
+
+static void longReverse(SHA_INT64 *buffer, int byteCount, int Endianness)
+{
+ SHA_INT64 value;
+
+ if ( Endianness == PCT_BIG_ENDIAN )
+ return;
+
+ byteCount /= sizeof(*buffer);
+ while (byteCount--) {
+ value = *buffer;
+
+ ((unsigned char*)buffer)[0] = (unsigned char)(value >> 56) & 0xff;
+ ((unsigned char*)buffer)[1] = (unsigned char)(value >> 48) & 0xff;
+ ((unsigned char*)buffer)[2] = (unsigned char)(value >> 40) & 0xff;
+ ((unsigned char*)buffer)[3] = (unsigned char)(value >> 32) & 0xff;
+ ((unsigned char*)buffer)[4] = (unsigned char)(value >> 24) & 0xff;
+ ((unsigned char*)buffer)[5] = (unsigned char)(value >> 16) & 0xff;
+ ((unsigned char*)buffer)[6] = (unsigned char)(value >> 8) & 0xff;
+ ((unsigned char*)buffer)[7] = (unsigned char)(value ) & 0xff;
+
+ buffer++;
+ }
+}
+
+static void SHAcopy(SHAobject *src, SHAobject *dest)
+{
+ dest->Endianness = src->Endianness;
+ dest->local = src->local;
+ dest->digestsize = src->digestsize;
+ dest->count_lo = src->count_lo;
+ dest->count_hi = src->count_hi;
+ memcpy(dest->digest, src->digest, sizeof(src->digest));
+ memcpy(dest->data, src->data, sizeof(src->data));
+}
+
+
+/* ------------------------------------------------------------------------
+ *
+ * This code for the SHA-512 algorithm was noted as public domain. The
+ * original headers are pasted below.
+ *
+ * Several changes have been made to make it more compatible with the
+ * Python environment and desired interface.
+ *
+ */
+
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * gurantee it works.
+ *
+ * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
+ */
+
+
+/* SHA512 by Tom St Denis */
+
+/* Various logical functions */
+#define ROR64(x, y) \
+ ( ((((x) & Py_ULL(0xFFFFFFFFFFFFFFFF))>>((unsigned PY_LONG_LONG)(y) & 63)) | \
+ ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & Py_ULL(0xFFFFFFFFFFFFFFFF))
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) (((x | y) & z) | (x & y))
+#define S(x, n) ROR64((x),(n))
+#define R(x, n) (((x) & Py_ULL(0xFFFFFFFFFFFFFFFF)) >> ((unsigned PY_LONG_LONG)n))
+#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
+#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
+#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
+#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
+
+
+static void
+sha512_transform(SHAobject *sha_info)
+{
+ int i;
+ SHA_INT64 S[8], W[80], t0, t1;
+
+ memcpy(W, sha_info->data, sizeof(sha_info->data));
+ longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
+
+ for (i = 16; i < 80; ++i) {
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+ }
+ for (i = 0; i < 8; ++i) {
+ S[i] = sha_info->digest[i];
+ }
+
+ /* Compress */
+#define RND(a,b,c,d,e,f,g,h,i,ki) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
+
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,Py_ULL(0x428a2f98d728ae22));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,Py_ULL(0x7137449123ef65cd));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,Py_ULL(0xb5c0fbcfec4d3b2f));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,Py_ULL(0xe9b5dba58189dbbc));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,Py_ULL(0x3956c25bf348b538));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,Py_ULL(0x59f111f1b605d019));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,Py_ULL(0x923f82a4af194f9b));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,Py_ULL(0xab1c5ed5da6d8118));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,Py_ULL(0xd807aa98a3030242));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,Py_ULL(0x12835b0145706fbe));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,Py_ULL(0x243185be4ee4b28c));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,Py_ULL(0x550c7dc3d5ffb4e2));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,Py_ULL(0x72be5d74f27b896f));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,Py_ULL(0x80deb1fe3b1696b1));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,Py_ULL(0x9bdc06a725c71235));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,Py_ULL(0xc19bf174cf692694));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,Py_ULL(0xe49b69c19ef14ad2));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,Py_ULL(0xefbe4786384f25e3));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,Py_ULL(0x0fc19dc68b8cd5b5));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,Py_ULL(0x240ca1cc77ac9c65));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,Py_ULL(0x2de92c6f592b0275));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,Py_ULL(0x4a7484aa6ea6e483));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,Py_ULL(0x5cb0a9dcbd41fbd4));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,Py_ULL(0x76f988da831153b5));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,Py_ULL(0x983e5152ee66dfab));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,Py_ULL(0xa831c66d2db43210));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,Py_ULL(0xb00327c898fb213f));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,Py_ULL(0xbf597fc7beef0ee4));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,Py_ULL(0xc6e00bf33da88fc2));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,Py_ULL(0xd5a79147930aa725));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,Py_ULL(0x06ca6351e003826f));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,Py_ULL(0x142929670a0e6e70));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,Py_ULL(0x27b70a8546d22ffc));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,Py_ULL(0x2e1b21385c26c926));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,Py_ULL(0x4d2c6dfc5ac42aed));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,Py_ULL(0x53380d139d95b3df));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,Py_ULL(0x650a73548baf63de));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,Py_ULL(0x766a0abb3c77b2a8));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,Py_ULL(0x81c2c92e47edaee6));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,Py_ULL(0x92722c851482353b));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,Py_ULL(0xa2bfe8a14cf10364));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,Py_ULL(0xa81a664bbc423001));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,Py_ULL(0xc24b8b70d0f89791));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,Py_ULL(0xc76c51a30654be30));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,Py_ULL(0xd192e819d6ef5218));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,Py_ULL(0xd69906245565a910));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,Py_ULL(0xf40e35855771202a));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,Py_ULL(0x106aa07032bbd1b8));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,Py_ULL(0x19a4c116b8d2d0c8));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,Py_ULL(0x1e376c085141ab53));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,Py_ULL(0x2748774cdf8eeb99));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,Py_ULL(0x34b0bcb5e19b48a8));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,Py_ULL(0x391c0cb3c5c95a63));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,Py_ULL(0x4ed8aa4ae3418acb));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,Py_ULL(0x5b9cca4f7763e373));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,Py_ULL(0x682e6ff3d6b2b8a3));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,Py_ULL(0x748f82ee5defb2fc));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,Py_ULL(0x78a5636f43172f60));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,Py_ULL(0x84c87814a1f0ab72));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,Py_ULL(0x8cc702081a6439ec));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,Py_ULL(0x90befffa23631e28));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,Py_ULL(0xa4506cebde82bde9));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,Py_ULL(0xbef9a3f7b2c67915));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,Py_ULL(0xc67178f2e372532b));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,Py_ULL(0xca273eceea26619c));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,Py_ULL(0xd186b8c721c0c207));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,Py_ULL(0xeada7dd6cde0eb1e));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,Py_ULL(0xf57d4f7fee6ed178));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,Py_ULL(0x06f067aa72176fba));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,Py_ULL(0x0a637dc5a2c898a6));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,Py_ULL(0x113f9804bef90dae));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,Py_ULL(0x1b710b35131c471b));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,Py_ULL(0x28db77f523047d84));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,Py_ULL(0x32caab7b40c72493));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,Py_ULL(0x3c9ebe0a15c9bebc));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,Py_ULL(0x431d67c49c100d4c));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,Py_ULL(0x4cc5d4becb3e42b6));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,Py_ULL(0x597f299cfc657e2a));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,Py_ULL(0x5fcb6fab3ad6faec));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,Py_ULL(0x6c44198c4a475817));
+
+#undef RND
+
+ /* feedback */
+ for (i = 0; i < 8; i++) {
+ sha_info->digest[i] = sha_info->digest[i] + S[i];
+ }
+
+}
+
+
+
+/* initialize the SHA digest */
+
+static void
+sha512_init(SHAobject *sha_info)
+{
+ TestEndianness(sha_info->Endianness)
+ sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908);
+ sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b);
+ sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b);
+ sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1);
+ sha_info->digest[4] = Py_ULL(0x510e527fade682d1);
+ sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f);
+ sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b);
+ sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179);
+ sha_info->count_lo = 0L;
+ sha_info->count_hi = 0L;
+ sha_info->local = 0;
+ sha_info->digestsize = 64;
+}
+
+static void
+sha384_init(SHAobject *sha_info)
+{
+ TestEndianness(sha_info->Endianness)
+ sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8);
+ sha_info->digest[1] = Py_ULL(0x629a292a367cd507);
+ sha_info->digest[2] = Py_ULL(0x9159015a3070dd17);
+ sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939);
+ sha_info->digest[4] = Py_ULL(0x67332667ffc00b31);
+ sha_info->digest[5] = Py_ULL(0x8eb44a8768581511);
+ sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7);
+ sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4);
+ sha_info->count_lo = 0L;
+ sha_info->count_hi = 0L;
+ sha_info->local = 0;
+ sha_info->digestsize = 48;
+}
+
+
+/* update the SHA digest */
+
+static void
+sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
+{
+ int i;
+ SHA_INT32 clo;
+
+ clo = sha_info->count_lo + ((SHA_INT32) count << 3);
+ if (clo < sha_info->count_lo) {
+ ++sha_info->count_hi;
+ }
+ sha_info->count_lo = clo;
+ sha_info->count_hi += (SHA_INT32) count >> 29;
+ if (sha_info->local) {
+ i = SHA_BLOCKSIZE - sha_info->local;
+ if (i > count) {
+ i = count;
+ }
+ memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
+ count -= i;
+ buffer += i;
+ sha_info->local += i;
+ if (sha_info->local == SHA_BLOCKSIZE) {
+ sha512_transform(sha_info);
+ }
+ else {
+ return;
+ }
+ }
+ while (count >= SHA_BLOCKSIZE) {
+ memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+ buffer += SHA_BLOCKSIZE;
+ count -= SHA_BLOCKSIZE;
+ sha512_transform(sha_info);
+ }
+ memcpy(sha_info->data, buffer, count);
+ sha_info->local = count;
+}
+
+/* finish computing the SHA digest */
+
+static void
+sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
+{
+ int count;
+ SHA_INT32 lo_bit_count, hi_bit_count;
+
+ lo_bit_count = sha_info->count_lo;
+ hi_bit_count = sha_info->count_hi;
+ count = (int) ((lo_bit_count >> 3) & 0x7f);
+ ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
+ if (count > SHA_BLOCKSIZE - 16) {
+ memset(((SHA_BYTE *) sha_info->data) + count, 0,
+ SHA_BLOCKSIZE - count);
+ sha512_transform(sha_info);
+ memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16);
+ }
+ else {
+ memset(((SHA_BYTE *) sha_info->data) + count, 0,
+ SHA_BLOCKSIZE - 16 - count);
+ }
+
+ /* GJS: note that we add the hi/lo in big-endian. sha512_transform will
+ swap these values into host-order. */
+ sha_info->data[112] = 0;
+ sha_info->data[113] = 0;
+ sha_info->data[114] = 0;
+ sha_info->data[115] = 0;
+ sha_info->data[116] = 0;
+ sha_info->data[117] = 0;
+ sha_info->data[118] = 0;
+ sha_info->data[119] = 0;
+ sha_info->data[120] = (hi_bit_count >> 24) & 0xff;
+ sha_info->data[121] = (hi_bit_count >> 16) & 0xff;
+ sha_info->data[122] = (hi_bit_count >> 8) & 0xff;
+ sha_info->data[123] = (hi_bit_count >> 0) & 0xff;
+ sha_info->data[124] = (lo_bit_count >> 24) & 0xff;
+ sha_info->data[125] = (lo_bit_count >> 16) & 0xff;
+ sha_info->data[126] = (lo_bit_count >> 8) & 0xff;
+ sha_info->data[127] = (lo_bit_count >> 0) & 0xff;
+ sha512_transform(sha_info);
+ digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff);
+ digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff);
+ digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff);
+ digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff);
+ digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
+ digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
+ digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
+ digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
+ digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff);
+ digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff);
+ digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff);
+ digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff);
+ digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
+ digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
+ digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
+ digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
+ digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff);
+ digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff);
+ digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff);
+ digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff);
+ digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
+ digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
+ digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
+ digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
+ digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff);
+ digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff);
+ digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff);
+ digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff);
+ digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
+ digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
+ digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
+ digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
+ digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff);
+ digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff);
+ digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff);
+ digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff);
+ digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
+ digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
+ digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
+ digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
+ digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff);
+ digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff);
+ digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff);
+ digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff);
+ digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
+ digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
+ digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
+ digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
+ digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff);
+ digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff);
+ digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff);
+ digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff);
+ digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
+ digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
+ digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
+ digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
+ digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff);
+ digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff);
+ digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff);
+ digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff);
+ digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
+ digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
+ digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
+ digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
+}
+
+/*
+ * End of copied SHA code.
+ *
+ * ------------------------------------------------------------------------
+ */
+
+static PyTypeObject SHA384type;
+static PyTypeObject SHA512type;
+
+
+static SHAobject *
+newSHA384object(void)
+{
+ return (SHAobject *)PyObject_New(SHAobject, &SHA384type);
+}
+
+static SHAobject *
+newSHA512object(void)
+{
+ return (SHAobject *)PyObject_New(SHAobject, &SHA512type);
+}
+
+/* Internal methods for a hash object */
+
+static void
+SHA512_dealloc(PyObject *ptr)
+{
+ PyObject_Del(ptr);
+}
+
+
+/* External methods for a hash object */
+
+PyDoc_STRVAR(SHA512_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+SHA512_copy(SHAobject *self, PyObject *unused)
+{
+ SHAobject *newobj;
+
+ if (((PyObject*)self)->ob_type == &SHA512type) {
+ if ( (newobj = newSHA512object())==NULL)
+ return NULL;
+ } else {
+ if ( (newobj = newSHA384object())==NULL)
+ return NULL;
+ }
+
+ SHAcopy(self, newobj);
+ return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SHA512_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SHA512_digest(SHAobject *self, PyObject *unused)
+{
+ unsigned char digest[SHA_DIGESTSIZE];
+ SHAobject temp;
+
+ SHAcopy(self, &temp);
+ sha512_final(digest, &temp);
+ return PyString_FromStringAndSize((const char *)digest, self->digestsize);
+}
+
+PyDoc_STRVAR(SHA512_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SHA512_hexdigest(SHAobject *self, PyObject *unused)
+{
+ unsigned char digest[SHA_DIGESTSIZE];
+ SHAobject temp;
+ PyObject *retval;
+ char *hex_digest;
+ int i, j;
+
+ /* Get the raw (binary) digest value */
+ SHAcopy(self, &temp);
+ sha512_final(digest, &temp);
+
+ /* Create a new string */
+ retval = PyString_FromStringAndSize(NULL, self->digestsize * 2);
+ if (!retval)
+ return NULL;
+ hex_digest = PyString_AsString(retval);
+ if (!hex_digest) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+
+ /* Make hex version of the digest */
+ for (i=j=0; i<self->digestsize; i++) {
+ char c;
+ c = (digest[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ c = (digest[i] & 0xf);
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ }
+ return retval;
+}
+
+PyDoc_STRVAR(SHA512_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+SHA512_update(SHAobject *self, PyObject *args)
+{
+ unsigned char *cp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+ return NULL;
+
+ sha512_update(self, cp, len);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef SHA_methods[] = {
+ {"copy", (PyCFunction)SHA512_copy, METH_NOARGS, SHA512_copy__doc__},
+ {"digest", (PyCFunction)SHA512_digest, METH_NOARGS, SHA512_digest__doc__},
+ {"hexdigest", (PyCFunction)SHA512_hexdigest, METH_NOARGS, SHA512_hexdigest__doc__},
+ {"update", (PyCFunction)SHA512_update, METH_VARARGS, SHA512_update__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+SHA512_get_block_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(SHA_BLOCKSIZE);
+}
+
+static PyObject *
+SHA512_get_name(PyObject *self, void *closure)
+{
+ if (((SHAobject *)self)->digestsize == 64)
+ return PyString_FromStringAndSize("SHA512", 6);
+ else
+ return PyString_FromStringAndSize("SHA384", 6);
+}
+
+static PyGetSetDef SHA_getseters[] = {
+ {"block_size",
+ (getter)SHA512_get_block_size, NULL,
+ NULL,
+ NULL},
+ {"name",
+ (getter)SHA512_get_name, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyMemberDef SHA_members[] = {
+ {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+ /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+ * the old sha module also supported 'digestsize'. ugh. */
+ {"digestsize", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject SHA384type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_sha512.sha384", /*tp_name*/
+ sizeof(SHAobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ SHA512_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ SHA_methods, /* tp_methods */
+ SHA_members, /* tp_members */
+ SHA_getseters, /* tp_getset */
+};
+
+static PyTypeObject SHA512type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_sha512.sha512", /*tp_name*/
+ sizeof(SHAobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ SHA512_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ SHA_methods, /* tp_methods */
+ SHA_members, /* tp_members */
+ SHA_getseters, /* tp_getset */
+};
+
+
+/* The single module-level function: new() */
+
+PyDoc_STRVAR(SHA512_new__doc__,
+"Return a new SHA-512 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHAobject *new;
+ unsigned char *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+ &cp, &len)) {
+ return NULL;
+ }
+
+ if ((new = newSHA512object()) == NULL)
+ return NULL;
+
+ sha512_init(new);
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (cp)
+ sha512_update(new, cp, len);
+
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA384_new__doc__,
+"Return a new SHA-384 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHAobject *new;
+ unsigned char *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+ &cp, &len)) {
+ return NULL;
+ }
+
+ if ((new = newSHA384object()) == NULL)
+ return NULL;
+
+ sha384_init(new);
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (cp)
+ sha512_update(new, cp, len);
+
+ return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SHA_functions[] = {
+ {"sha512", (PyCFunction)SHA512_new, METH_VARARGS|METH_KEYWORDS, SHA512_new__doc__},
+ {"sha384", (PyCFunction)SHA384_new, METH_VARARGS|METH_KEYWORDS, SHA384_new__doc__},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
+
+PyMODINIT_FUNC
+init_sha512(void)
+{
+ PyObject *m;
+
+ SHA384type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA384type) < 0)
+ return;
+ SHA512type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA512type) < 0)
+ return;
+ m = Py_InitModule("_sha512", SHA_functions);
+ if (m == NULL)
+ return;
+}
+
+#endif
diff --git a/sys/src/cmd/python/Modules/shamodule.c b/sys/src/cmd/python/Modules/shamodule.c
new file mode 100644
index 000000000..8d68d16ea
--- /dev/null
+++ b/sys/src/cmd/python/Modules/shamodule.c
@@ -0,0 +1,593 @@
+/* SHA module */
+
+/* This module provides an interface to NIST's Secure Hash Algorithm */
+
+/* See below for information about the original code this module was
+ based upon. Additional work performed by:
+
+ Andrew Kuchling (amk@amk.ca)
+ Greg Stein (gstein@lyra.org)
+
+ Copyright (C) 2005 Gregory P. Smith (greg@electricrain.com)
+ Licensed to PSF under a Contributor Agreement.
+
+*/
+
+/* SHA objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+
+/* Endianness testing and definitions */
+#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
+ if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
+
+#define PCT_LITTLE_ENDIAN 1
+#define PCT_BIG_ENDIAN 0
+
+/* Some useful types */
+
+typedef unsigned char SHA_BYTE;
+
+#if SIZEOF_INT == 4
+typedef unsigned int SHA_INT32; /* 32-bit integer */
+#else
+/* not defined. compilation will die. */
+#endif
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_BLOCKSIZE 64
+#define SHA_DIGESTSIZE 20
+
+/* The structure for storing SHS info */
+
+typedef struct {
+ PyObject_HEAD
+ SHA_INT32 digest[5]; /* Message digest */
+ SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
+ SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
+ int Endianness;
+ int local; /* unprocessed amount in data */
+} SHAobject;
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+ array of longwords. */
+
+static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
+{
+ SHA_INT32 value;
+
+ if ( Endianness == PCT_BIG_ENDIAN )
+ return;
+
+ byteCount /= sizeof(*buffer);
+ while (byteCount--) {
+ value = *buffer;
+ value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
+ ( ( value & 0x00FF00FFL ) << 8 );
+ *buffer++ = ( value << 16 ) | ( value >> 16 );
+ }
+}
+
+static void SHAcopy(SHAobject *src, SHAobject *dest)
+{
+ dest->Endianness = src->Endianness;
+ dest->local = src->local;
+ dest->count_lo = src->count_lo;
+ dest->count_hi = src->count_hi;
+ memcpy(dest->digest, src->digest, sizeof(src->digest));
+ memcpy(dest->data, src->data, sizeof(src->data));
+}
+
+
+/* ------------------------------------------------------------------------
+ *
+ * This code for the SHA algorithm was noted as public domain. The original
+ * headers are pasted below.
+ *
+ * Several changes have been made to make it more compatible with the
+ * Python environment and desired interface.
+ *
+ */
+
+/* NIST Secure Hash Algorithm */
+/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
+/* from Peter C. Gutmann's implementation as found in */
+/* Applied Cryptography by Bruce Schneier */
+/* Further modifications to include the "UNRAVEL" stuff, below */
+
+/* This code is in the public domain */
+
+/* UNRAVEL should be fastest & biggest */
+/* UNROLL_LOOPS should be just as big, but slightly slower */
+/* both undefined should be smallest and slowest */
+
+#define UNRAVEL
+/* #define UNROLL_LOOPS */
+
+/* The SHA f()-functions. The f1 and f3 functions can be optimized to
+ save one boolean operation each - thanks to Rich Schroeppel,
+ rcs@cs.arizona.edu for discovering this */
+
+/*#define f1(x,y,z) ((x & y) | (~x & z)) // Rounds 0-19 */
+#define f1(x,y,z) (z ^ (x & (y ^ z))) /* Rounds 0-19 */
+#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39 */
+/*#define f3(x,y,z) ((x & y) | (x & z) | (y & z)) // Rounds 40-59 */
+#define f3(x,y,z) ((x & y) | (z & (x | y))) /* Rounds 40-59 */
+#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79 */
+
+/* SHA constants */
+
+#define CONST1 0x5a827999L /* Rounds 0-19 */
+#define CONST2 0x6ed9eba1L /* Rounds 20-39 */
+#define CONST3 0x8f1bbcdcL /* Rounds 40-59 */
+#define CONST4 0xca62c1d6L /* Rounds 60-79 */
+
+/* 32-bit rotate */
+
+#define R32(x,n) ((x << n) | (x >> (32 - n)))
+
+/* the generic case, for when the overall rotation is not unraveled */
+
+#define FG(n) \
+ T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; \
+ E = D; D = C; C = R32(B,30); B = A; A = T
+
+/* specific cases, for when the overall rotation is unraveled */
+
+#define FA(n) \
+ T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; B = R32(B,30)
+
+#define FB(n) \
+ E = R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n; A = R32(A,30)
+
+#define FC(n) \
+ D = R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n; T = R32(T,30)
+
+#define FD(n) \
+ C = R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n; E = R32(E,30)
+
+#define FE(n) \
+ B = R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n; D = R32(D,30)
+
+#define FT(n) \
+ A = R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n; C = R32(C,30)
+
+/* do SHA transformation */
+
+static void
+sha_transform(SHAobject *sha_info)
+{
+ int i;
+ SHA_INT32 T, A, B, C, D, E, W[80], *WP;
+
+ memcpy(W, sha_info->data, sizeof(sha_info->data));
+ longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
+
+ for (i = 16; i < 80; ++i) {
+ W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
+
+ /* extra rotation fix */
+ W[i] = R32(W[i], 1);
+ }
+ A = sha_info->digest[0];
+ B = sha_info->digest[1];
+ C = sha_info->digest[2];
+ D = sha_info->digest[3];
+ E = sha_info->digest[4];
+ WP = W;
+#ifdef UNRAVEL
+ FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
+ FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
+ FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
+ FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
+ FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
+ FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
+ FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
+ FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
+ sha_info->digest[0] += E;
+ sha_info->digest[1] += T;
+ sha_info->digest[2] += A;
+ sha_info->digest[3] += B;
+ sha_info->digest[4] += C;
+#else /* !UNRAVEL */
+#ifdef UNROLL_LOOPS
+ FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
+ FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
+ FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
+ FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
+ FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
+ FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
+ FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
+ FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
+#else /* !UNROLL_LOOPS */
+ for (i = 0; i < 20; ++i) { FG(1); }
+ for (i = 20; i < 40; ++i) { FG(2); }
+ for (i = 40; i < 60; ++i) { FG(3); }
+ for (i = 60; i < 80; ++i) { FG(4); }
+#endif /* !UNROLL_LOOPS */
+ sha_info->digest[0] += A;
+ sha_info->digest[1] += B;
+ sha_info->digest[2] += C;
+ sha_info->digest[3] += D;
+ sha_info->digest[4] += E;
+#endif /* !UNRAVEL */
+}
+
+/* initialize the SHA digest */
+
+static void
+sha_init(SHAobject *sha_info)
+{
+ TestEndianness(sha_info->Endianness)
+
+ sha_info->digest[0] = 0x67452301L;
+ sha_info->digest[1] = 0xefcdab89L;
+ sha_info->digest[2] = 0x98badcfeL;
+ sha_info->digest[3] = 0x10325476L;
+ sha_info->digest[4] = 0xc3d2e1f0L;
+ sha_info->count_lo = 0L;
+ sha_info->count_hi = 0L;
+ sha_info->local = 0;
+}
+
+/* update the SHA digest */
+
+static void
+sha_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
+{
+ int i;
+ SHA_INT32 clo;
+
+ clo = sha_info->count_lo + ((SHA_INT32) count << 3);
+ if (clo < sha_info->count_lo) {
+ ++sha_info->count_hi;
+ }
+ sha_info->count_lo = clo;
+ sha_info->count_hi += (SHA_INT32) count >> 29;
+ if (sha_info->local) {
+ i = SHA_BLOCKSIZE - sha_info->local;
+ if (i > count) {
+ i = count;
+ }
+ memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
+ count -= i;
+ buffer += i;
+ sha_info->local += i;
+ if (sha_info->local == SHA_BLOCKSIZE) {
+ sha_transform(sha_info);
+ }
+ else {
+ return;
+ }
+ }
+ while (count >= SHA_BLOCKSIZE) {
+ memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+ buffer += SHA_BLOCKSIZE;
+ count -= SHA_BLOCKSIZE;
+ sha_transform(sha_info);
+ }
+ memcpy(sha_info->data, buffer, count);
+ sha_info->local = count;
+}
+
+/* finish computing the SHA digest */
+
+static void
+sha_final(unsigned char digest[20], SHAobject *sha_info)
+{
+ int count;
+ SHA_INT32 lo_bit_count, hi_bit_count;
+
+ lo_bit_count = sha_info->count_lo;
+ hi_bit_count = sha_info->count_hi;
+ count = (int) ((lo_bit_count >> 3) & 0x3f);
+ ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
+ if (count > SHA_BLOCKSIZE - 8) {
+ memset(((SHA_BYTE *) sha_info->data) + count, 0,
+ SHA_BLOCKSIZE - count);
+ sha_transform(sha_info);
+ memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
+ }
+ else {
+ memset(((SHA_BYTE *) sha_info->data) + count, 0,
+ SHA_BLOCKSIZE - 8 - count);
+ }
+
+ /* GJS: note that we add the hi/lo in big-endian. sha_transform will
+ swap these values into host-order. */
+ sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
+ sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
+ sha_info->data[58] = (hi_bit_count >> 8) & 0xff;
+ sha_info->data[59] = (hi_bit_count >> 0) & 0xff;
+ sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
+ sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
+ sha_info->data[62] = (lo_bit_count >> 8) & 0xff;
+ sha_info->data[63] = (lo_bit_count >> 0) & 0xff;
+ sha_transform(sha_info);
+ digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
+ digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
+ digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
+ digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
+ digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
+ digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
+ digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
+ digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
+ digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
+ digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
+ digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
+ digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
+ digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
+ digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
+ digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
+ digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
+ digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
+ digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
+ digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
+ digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
+}
+
+/*
+ * End of copied SHA code.
+ *
+ * ------------------------------------------------------------------------
+ */
+
+static PyTypeObject SHAtype;
+
+
+static SHAobject *
+newSHAobject(void)
+{
+ return (SHAobject *)PyObject_New(SHAobject, &SHAtype);
+}
+
+/* Internal methods for a hashing object */
+
+static void
+SHA_dealloc(PyObject *ptr)
+{
+ PyObject_Del(ptr);
+}
+
+
+/* External methods for a hashing object */
+
+PyDoc_STRVAR(SHA_copy__doc__, "Return a copy of the hashing object.");
+
+static PyObject *
+SHA_copy(SHAobject *self, PyObject *unused)
+{
+ SHAobject *newobj;
+
+ if ( (newobj = newSHAobject())==NULL)
+ return NULL;
+
+ SHAcopy(self, newobj);
+ return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SHA_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SHA_digest(SHAobject *self, PyObject *unused)
+{
+ unsigned char digest[SHA_DIGESTSIZE];
+ SHAobject temp;
+
+ SHAcopy(self, &temp);
+ sha_final(digest, &temp);
+ return PyString_FromStringAndSize((const char *)digest, sizeof(digest));
+}
+
+PyDoc_STRVAR(SHA_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SHA_hexdigest(SHAobject *self, PyObject *unused)
+{
+ unsigned char digest[SHA_DIGESTSIZE];
+ SHAobject temp;
+ PyObject *retval;
+ char *hex_digest;
+ int i, j;
+
+ /* Get the raw (binary) digest value */
+ SHAcopy(self, &temp);
+ sha_final(digest, &temp);
+
+ /* Create a new string */
+ retval = PyString_FromStringAndSize(NULL, sizeof(digest) * 2);
+ if (!retval)
+ return NULL;
+ hex_digest = PyString_AsString(retval);
+ if (!hex_digest) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+
+ /* Make hex version of the digest */
+ for(i=j=0; i<sizeof(digest); i++) {
+ char c;
+ c = (digest[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ c = (digest[i] & 0xf);
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ }
+ return retval;
+}
+
+PyDoc_STRVAR(SHA_update__doc__,
+"Update this hashing object's state with the provided string.");
+
+static PyObject *
+SHA_update(SHAobject *self, PyObject *args)
+{
+ unsigned char *cp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+ return NULL;
+
+ sha_update(self, cp, len);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef SHA_methods[] = {
+ {"copy", (PyCFunction)SHA_copy, METH_NOARGS, SHA_copy__doc__},
+ {"digest", (PyCFunction)SHA_digest, METH_NOARGS, SHA_digest__doc__},
+ {"hexdigest", (PyCFunction)SHA_hexdigest, METH_NOARGS, SHA_hexdigest__doc__},
+ {"update", (PyCFunction)SHA_update, METH_VARARGS, SHA_update__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+SHA_get_block_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(SHA_BLOCKSIZE);
+}
+
+static PyObject *
+SHA_get_digest_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(SHA_DIGESTSIZE);
+}
+
+static PyObject *
+SHA_get_name(PyObject *self, void *closure)
+{
+ return PyString_FromStringAndSize("SHA1", 4);
+}
+
+static PyGetSetDef SHA_getseters[] = {
+ {"digest_size",
+ (getter)SHA_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {"block_size",
+ (getter)SHA_get_block_size, NULL,
+ NULL,
+ NULL},
+ {"name",
+ (getter)SHA_get_name, NULL,
+ NULL,
+ NULL},
+ /* the old md5 and sha modules support 'digest_size' as in PEP 247.
+ * the old sha module also supported 'digestsize'. ugh. */
+ {"digestsize",
+ (getter)SHA_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject SHAtype = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_sha.sha", /*tp_name*/
+ sizeof(SHAobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ SHA_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ SHA_methods, /* tp_methods */
+ 0, /* tp_members */
+ SHA_getseters, /* tp_getset */
+};
+
+
+/* The single module-level function: new() */
+
+PyDoc_STRVAR(SHA_new__doc__,
+"Return a new SHA hashing object. An optional string argument\n\
+may be provided; if present, this string will be automatically\n\
+hashed.");
+
+static PyObject *
+SHA_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHAobject *new;
+ unsigned char *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
+ &cp, &len)) {
+ return NULL;
+ }
+
+ if ((new = newSHAobject()) == NULL)
+ return NULL;
+
+ sha_init(new);
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (cp)
+ sha_update(new, cp, len);
+
+ return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SHA_functions[] = {
+ {"new", (PyCFunction)SHA_new, METH_VARARGS|METH_KEYWORDS, SHA_new__doc__},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
+
+PyMODINIT_FUNC
+init_sha(void)
+{
+ PyObject *m;
+
+ SHAtype.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHAtype) < 0)
+ return;
+ m = Py_InitModule("_sha", SHA_functions);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ insint("blocksize", 1); /* For future use, in case some hash
+ functions require an integral number of
+ blocks */
+ insint("digestsize", 20);
+ insint("digest_size", 20);
+}
diff --git a/sys/src/cmd/python/Modules/signalmodule.c b/sys/src/cmd/python/Modules/signalmodule.c
new file mode 100644
index 000000000..a729604a3
--- /dev/null
+++ b/sys/src/cmd/python/Modules/signalmodule.c
@@ -0,0 +1,676 @@
+
+/* Signal module -- many thanks to Lance Ellinghaus */
+
+/* XXX Signals should be recorded per thread, now we have thread state. */
+
+#include "Python.h"
+#include "intrcheck.h"
+
+#ifdef MS_WINDOWS
+#include <process.h>
+#endif
+
+#include <signal.h>
+
+#ifndef SIG_ERR
+#define SIG_ERR ((PyOS_sighandler_t)(-1))
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#define NSIG 12
+#include <process.h>
+#endif
+
+#ifndef NSIG
+# if defined(_NSIG)
+# define NSIG _NSIG /* For BSD/SysV */
+# elif defined(_SIGMAX)
+# define NSIG (_SIGMAX + 1) /* For QNX */
+# elif defined(SIGMAX)
+# define NSIG (SIGMAX + 1) /* For djgpp */
+# else
+# define NSIG 64 /* Use a reasonable default value */
+# endif
+#endif
+
+
+/*
+ NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
+
+ When threads are supported, we want the following semantics:
+
+ - only the main thread can set a signal handler
+ - any thread can get a signal handler
+ - signals are only delivered to the main thread
+
+ I.e. we don't support "synchronous signals" like SIGFPE (catching
+ this doesn't make much sense in Python anyway) nor do we support
+ signals as a means of inter-thread communication, since not all
+ thread implementations support that (at least our thread library
+ doesn't).
+
+ We still have the problem that in some implementations signals
+ generated by the keyboard (e.g. SIGINT) are delivered to all
+ threads (e.g. SGI), while in others (e.g. Solaris) such signals are
+ delivered to one random thread (an intermediate possibility would
+ be to deliver it to the main thread -- POSIX?). For now, we have
+ a working implementation that works in all three cases -- the
+ handler ignores signals if getpid() isn't the same as in the main
+ thread. XXX This is a hack.
+
+ GNU pth is a user-space threading library, and as such, all threads
+ run within the same process. In this case, if the currently running
+ thread is not the main_thread, send the signal to the main_thread.
+*/
+
+#ifdef WITH_THREAD
+#include <sys/types.h> /* For pid_t */
+#include "pythread.h"
+static long main_thread;
+static pid_t main_pid;
+#endif
+
+static struct {
+ int tripped;
+ PyObject *func;
+} Handlers[NSIG];
+
+static int is_tripped = 0; /* Speed up sigcheck() when none tripped */
+
+static PyObject *DefaultHandler;
+static PyObject *IgnoreHandler;
+static PyObject *IntHandler;
+
+/* On Solaris 8, gcc will produce a warning that the function
+ declaration is not a prototype. This is caused by the definition of
+ SIG_DFL as (void (*)())0; the correct declaration would have been
+ (void (*)(int))0. */
+
+static PyOS_sighandler_t old_siginthandler = SIG_DFL;
+
+
+static PyObject *
+signal_default_int_handler(PyObject *self, PyObject *args)
+{
+ PyErr_SetNone(PyExc_KeyboardInterrupt);
+ return NULL;
+}
+
+PyDoc_STRVAR(default_int_handler_doc,
+"default_int_handler(...)\n\
+\n\
+The default handler for SIGINT installed by Python.\n\
+It raises KeyboardInterrupt.");
+
+
+static int
+checksignals_witharg(void * unused)
+{
+ return PyErr_CheckSignals();
+}
+
+static void
+signal_handler(int sig_num)
+{
+#ifdef WITH_THREAD
+#ifdef WITH_PTH
+ if (PyThread_get_thread_ident() != main_thread) {
+ pth_raise(*(pth_t *) main_thread, sig_num);
+ return;
+ }
+#endif
+ /* See NOTES section above */
+ if (getpid() == main_pid) {
+#endif
+ is_tripped++;
+ Handlers[sig_num].tripped = 1;
+ Py_AddPendingCall(checksignals_witharg, NULL);
+#ifdef WITH_THREAD
+ }
+#endif
+#ifdef SIGCHLD
+ if (sig_num == SIGCHLD) {
+ /* To avoid infinite recursion, this signal remains
+ reset until explicit re-instated.
+ Don't clear the 'func' field as it is our pointer
+ to the Python handler... */
+ return;
+ }
+#endif
+ PyOS_setsig(sig_num, signal_handler);
+}
+
+
+#ifdef HAVE_ALARM
+static PyObject *
+signal_alarm(PyObject *self, PyObject *args)
+{
+ int t;
+ if (!PyArg_ParseTuple(args, "i:alarm", &t))
+ return NULL;
+ /* alarm() returns the number of seconds remaining */
+ return PyInt_FromLong((long)alarm(t));
+}
+
+PyDoc_STRVAR(alarm_doc,
+"alarm(seconds)\n\
+\n\
+Arrange for SIGALRM to arrive after the given number of seconds.");
+#endif
+
+#ifdef HAVE_PAUSE
+static PyObject *
+signal_pause(PyObject *self)
+{
+ Py_BEGIN_ALLOW_THREADS
+ (void)pause();
+ Py_END_ALLOW_THREADS
+ /* make sure that any exceptions that got raised are propagated
+ * back into Python
+ */
+ if (PyErr_CheckSignals())
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+PyDoc_STRVAR(pause_doc,
+"pause()\n\
+\n\
+Wait until a signal arrives.");
+
+#endif
+
+
+static PyObject *
+signal_signal(PyObject *self, PyObject *args)
+{
+ PyObject *obj;
+ int sig_num;
+ PyObject *old_handler;
+ void (*func)(int);
+ if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
+ return NULL;
+#ifdef WITH_THREAD
+ if (PyThread_get_thread_ident() != main_thread) {
+ PyErr_SetString(PyExc_ValueError,
+ "signal only works in main thread");
+ return NULL;
+ }
+#endif
+ if (sig_num < 1 || sig_num >= NSIG) {
+ PyErr_SetString(PyExc_ValueError,
+ "signal number out of range");
+ return NULL;
+ }
+ if (obj == IgnoreHandler)
+ func = SIG_IGN;
+ else if (obj == DefaultHandler)
+ func = SIG_DFL;
+ else if (!PyCallable_Check(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
+ return NULL;
+ }
+ else
+ func = signal_handler;
+ if (PyOS_setsig(sig_num, func) == SIG_ERR) {
+ PyErr_SetFromErrno(PyExc_RuntimeError);
+ return NULL;
+ }
+ old_handler = Handlers[sig_num].func;
+ Handlers[sig_num].tripped = 0;
+ Py_INCREF(obj);
+ Handlers[sig_num].func = obj;
+ return old_handler;
+}
+
+PyDoc_STRVAR(signal_doc,
+"signal(sig, action) -> action\n\
+\n\
+Set the action for the given signal. The action can be SIG_DFL,\n\
+SIG_IGN, or a callable Python object. The previous action is\n\
+returned. See getsignal() for possible return values.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+A signal handler function is called with two arguments:\n\
+the first is the signal number, the second is the interrupted stack frame.");
+
+
+static PyObject *
+signal_getsignal(PyObject *self, PyObject *args)
+{
+ int sig_num;
+ PyObject *old_handler;
+ if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
+ return NULL;
+ if (sig_num < 1 || sig_num >= NSIG) {
+ PyErr_SetString(PyExc_ValueError,
+ "signal number out of range");
+ return NULL;
+ }
+ old_handler = Handlers[sig_num].func;
+ Py_INCREF(old_handler);
+ return old_handler;
+}
+
+PyDoc_STRVAR(getsignal_doc,
+"getsignal(sig) -> action\n\
+\n\
+Return the current action for the given signal. The return value can be:\n\
+SIG_IGN -- if the signal is being ignored\n\
+SIG_DFL -- if the default action for the signal is in effect\n\
+None -- if an unknown handler is in effect\n\
+anything else -- the callable Python object used as a handler");
+
+
+/* List of functions defined in the module */
+static PyMethodDef signal_methods[] = {
+#ifdef HAVE_ALARM
+ {"alarm", signal_alarm, METH_VARARGS, alarm_doc},
+#endif
+ {"signal", signal_signal, METH_VARARGS, signal_doc},
+ {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc},
+#ifdef HAVE_PAUSE
+ {"pause", (PyCFunction)signal_pause,
+ METH_NOARGS,pause_doc},
+#endif
+ {"default_int_handler", signal_default_int_handler,
+ METH_VARARGS, default_int_handler_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module provides mechanisms to use signal handlers in Python.\n\
+\n\
+Functions:\n\
+\n\
+alarm() -- cause SIGALRM after a specified time [Unix only]\n\
+signal() -- set the action for a given signal\n\
+getsignal() -- get the signal action for a given signal\n\
+pause() -- wait until a signal arrives [Unix only]\n\
+default_int_handler() -- default SIGINT handler\n\
+\n\
+Constants:\n\
+\n\
+SIG_DFL -- used to refer to the system default handler\n\
+SIG_IGN -- used to ignore the signal\n\
+NSIG -- number of defined signals\n\
+\n\
+SIGINT, SIGTERM, etc. -- signal numbers\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+A signal handler function is called with two arguments:\n\
+the first is the signal number, the second is the interrupted stack frame.");
+
+PyMODINIT_FUNC
+initsignal(void)
+{
+ PyObject *m, *d, *x;
+ int i;
+
+#ifdef WITH_THREAD
+ main_thread = PyThread_get_thread_ident();
+ main_pid = getpid();
+#endif
+
+ /* Create the module and add the functions */
+ m = Py_InitModule3("signal", signal_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+
+ x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
+ if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
+ goto finally;
+
+ x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
+ if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
+ goto finally;
+
+ x = PyInt_FromLong((long)NSIG);
+ if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
+ goto finally;
+ Py_DECREF(x);
+
+ x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
+ if (!x)
+ goto finally;
+ Py_INCREF(IntHandler);
+
+ Handlers[0].tripped = 0;
+ for (i = 1; i < NSIG; i++) {
+ void (*t)(int);
+ t = PyOS_getsig(i);
+ Handlers[i].tripped = 0;
+ if (t == SIG_DFL)
+ Handlers[i].func = DefaultHandler;
+ else if (t == SIG_IGN)
+ Handlers[i].func = IgnoreHandler;
+ else
+ Handlers[i].func = Py_None; /* None of our business */
+ Py_INCREF(Handlers[i].func);
+ }
+ if (Handlers[SIGINT].func == DefaultHandler) {
+ /* Install default int handler */
+ Py_INCREF(IntHandler);
+ Py_DECREF(Handlers[SIGINT].func);
+ Handlers[SIGINT].func = IntHandler;
+ old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
+ }
+
+#ifdef SIGHUP
+ x = PyInt_FromLong(SIGHUP);
+ PyDict_SetItemString(d, "SIGHUP", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGINT
+ x = PyInt_FromLong(SIGINT);
+ PyDict_SetItemString(d, "SIGINT", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGBREAK
+ x = PyInt_FromLong(SIGBREAK);
+ PyDict_SetItemString(d, "SIGBREAK", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGQUIT
+ x = PyInt_FromLong(SIGQUIT);
+ PyDict_SetItemString(d, "SIGQUIT", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGILL
+ x = PyInt_FromLong(SIGILL);
+ PyDict_SetItemString(d, "SIGILL", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGTRAP
+ x = PyInt_FromLong(SIGTRAP);
+ PyDict_SetItemString(d, "SIGTRAP", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGIOT
+ x = PyInt_FromLong(SIGIOT);
+ PyDict_SetItemString(d, "SIGIOT", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGABRT
+ x = PyInt_FromLong(SIGABRT);
+ PyDict_SetItemString(d, "SIGABRT", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGEMT
+ x = PyInt_FromLong(SIGEMT);
+ PyDict_SetItemString(d, "SIGEMT", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGFPE
+ x = PyInt_FromLong(SIGFPE);
+ PyDict_SetItemString(d, "SIGFPE", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGKILL
+ x = PyInt_FromLong(SIGKILL);
+ PyDict_SetItemString(d, "SIGKILL", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGBUS
+ x = PyInt_FromLong(SIGBUS);
+ PyDict_SetItemString(d, "SIGBUS", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGSEGV
+ x = PyInt_FromLong(SIGSEGV);
+ PyDict_SetItemString(d, "SIGSEGV", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGSYS
+ x = PyInt_FromLong(SIGSYS);
+ PyDict_SetItemString(d, "SIGSYS", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGPIPE
+ x = PyInt_FromLong(SIGPIPE);
+ PyDict_SetItemString(d, "SIGPIPE", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGALRM
+ x = PyInt_FromLong(SIGALRM);
+ PyDict_SetItemString(d, "SIGALRM", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGTERM
+ x = PyInt_FromLong(SIGTERM);
+ PyDict_SetItemString(d, "SIGTERM", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGUSR1
+ x = PyInt_FromLong(SIGUSR1);
+ PyDict_SetItemString(d, "SIGUSR1", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGUSR2
+ x = PyInt_FromLong(SIGUSR2);
+ PyDict_SetItemString(d, "SIGUSR2", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGCLD
+ x = PyInt_FromLong(SIGCLD);
+ PyDict_SetItemString(d, "SIGCLD", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGCHLD
+ x = PyInt_FromLong(SIGCHLD);
+ PyDict_SetItemString(d, "SIGCHLD", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGPWR
+ x = PyInt_FromLong(SIGPWR);
+ PyDict_SetItemString(d, "SIGPWR", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGIO
+ x = PyInt_FromLong(SIGIO);
+ PyDict_SetItemString(d, "SIGIO", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGURG
+ x = PyInt_FromLong(SIGURG);
+ PyDict_SetItemString(d, "SIGURG", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGWINCH
+ x = PyInt_FromLong(SIGWINCH);
+ PyDict_SetItemString(d, "SIGWINCH", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGPOLL
+ x = PyInt_FromLong(SIGPOLL);
+ PyDict_SetItemString(d, "SIGPOLL", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGSTOP
+ x = PyInt_FromLong(SIGSTOP);
+ PyDict_SetItemString(d, "SIGSTOP", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGTSTP
+ x = PyInt_FromLong(SIGTSTP);
+ PyDict_SetItemString(d, "SIGTSTP", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGCONT
+ x = PyInt_FromLong(SIGCONT);
+ PyDict_SetItemString(d, "SIGCONT", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGTTIN
+ x = PyInt_FromLong(SIGTTIN);
+ PyDict_SetItemString(d, "SIGTTIN", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGTTOU
+ x = PyInt_FromLong(SIGTTOU);
+ PyDict_SetItemString(d, "SIGTTOU", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGVTALRM
+ x = PyInt_FromLong(SIGVTALRM);
+ PyDict_SetItemString(d, "SIGVTALRM", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGPROF
+ x = PyInt_FromLong(SIGPROF);
+ PyDict_SetItemString(d, "SIGPROF", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGXCPU
+ x = PyInt_FromLong(SIGXCPU);
+ PyDict_SetItemString(d, "SIGXCPU", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGXFSZ
+ x = PyInt_FromLong(SIGXFSZ);
+ PyDict_SetItemString(d, "SIGXFSZ", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGRTMIN
+ x = PyInt_FromLong(SIGRTMIN);
+ PyDict_SetItemString(d, "SIGRTMIN", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGRTMAX
+ x = PyInt_FromLong(SIGRTMAX);
+ PyDict_SetItemString(d, "SIGRTMAX", x);
+ Py_XDECREF(x);
+#endif
+#ifdef SIGINFO
+ x = PyInt_FromLong(SIGINFO);
+ PyDict_SetItemString(d, "SIGINFO", x);
+ Py_XDECREF(x);
+#endif
+ if (!PyErr_Occurred())
+ return;
+
+ /* Check for errors */
+ finally:
+ return;
+}
+
+static void
+finisignal(void)
+{
+ int i;
+ PyObject *func;
+
+ PyOS_setsig(SIGINT, old_siginthandler);
+ old_siginthandler = SIG_DFL;
+
+ for (i = 1; i < NSIG; i++) {
+ func = Handlers[i].func;
+ Handlers[i].tripped = 0;
+ Handlers[i].func = NULL;
+ if (i != SIGINT && func != NULL && func != Py_None &&
+ func != DefaultHandler && func != IgnoreHandler)
+ PyOS_setsig(i, SIG_DFL);
+ Py_XDECREF(func);
+ }
+
+ Py_XDECREF(IntHandler);
+ IntHandler = NULL;
+ Py_XDECREF(DefaultHandler);
+ DefaultHandler = NULL;
+ Py_XDECREF(IgnoreHandler);
+ IgnoreHandler = NULL;
+}
+
+
+/* Declared in pyerrors.h */
+int
+PyErr_CheckSignals(void)
+{
+ int i;
+ PyObject *f;
+
+ if (!is_tripped)
+ return 0;
+#ifdef WITH_THREAD
+ if (PyThread_get_thread_ident() != main_thread)
+ return 0;
+#endif
+ if (!(f = (PyObject *)PyEval_GetFrame()))
+ f = Py_None;
+
+ for (i = 1; i < NSIG; i++) {
+ if (Handlers[i].tripped) {
+ PyObject *result = NULL;
+ PyObject *arglist = Py_BuildValue("(iO)", i, f);
+ Handlers[i].tripped = 0;
+
+ if (arglist) {
+ result = PyEval_CallObject(Handlers[i].func,
+ arglist);
+ Py_DECREF(arglist);
+ }
+ if (!result)
+ return -1;
+
+ Py_DECREF(result);
+ }
+ }
+ is_tripped = 0;
+ return 0;
+}
+
+
+/* Replacements for intrcheck.c functionality
+ * Declared in pyerrors.h
+ */
+void
+PyErr_SetInterrupt(void)
+{
+ is_tripped++;
+ Handlers[SIGINT].tripped = 1;
+ Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
+}
+
+void
+PyOS_InitInterrupts(void)
+{
+ initsignal();
+ _PyImport_FixupExtension("signal", "signal");
+}
+
+void
+PyOS_FiniInterrupts(void)
+{
+ finisignal();
+}
+
+int
+PyOS_InterruptOccurred(void)
+{
+ if (Handlers[SIGINT].tripped) {
+#ifdef WITH_THREAD
+ if (PyThread_get_thread_ident() != main_thread)
+ return 0;
+#endif
+ Handlers[SIGINT].tripped = 0;
+ return 1;
+ }
+ return 0;
+}
+
+void
+PyOS_AfterFork(void)
+{
+#ifdef WITH_THREAD
+ PyEval_ReInitThreads();
+ main_thread = PyThread_get_thread_ident();
+ main_pid = getpid();
+ _PyImport_ReInitLock();
+#endif
+}
diff --git a/sys/src/cmd/python/Modules/socketmodule.c b/sys/src/cmd/python/Modules/socketmodule.c
new file mode 100644
index 000000000..892ee7b16
--- /dev/null
+++ b/sys/src/cmd/python/Modules/socketmodule.c
@@ -0,0 +1,5100 @@
+/* Socket module */
+
+/*
+
+This module provides an interface to Berkeley socket IPC.
+
+Limitations:
+
+- Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
+ portable manner, though AF_PACKET and AF_NETLINK are supported under Linux.
+- No read/write operations (use sendall/recv or makefile instead).
+- Additional restrictions apply on some non-Unix platforms (compensated
+ for by socket.py).
+
+Module interface:
+
+- socket.error: exception raised for socket specific errors
+- socket.gaierror: exception raised for getaddrinfo/getnameinfo errors,
+ a subclass of socket.error
+- socket.herror: exception raised for gethostby* errors,
+ a subclass of socket.error
+- socket.fromfd(fd, family, type[, proto]) --> new socket object (created
+ from an existing file descriptor)
+- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
+- socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...])
+- socket.gethostname() --> host name (string: 'spam' or 'spam.domain.com')
+- socket.getprotobyname(protocolname) --> protocol number
+- socket.getservbyname(servicename[, protocolname]) --> port number
+- socket.getservbyport(portnumber[, protocolname]) --> service name
+- socket.socket([family[, type [, proto]]]) --> new socket object
+- socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
+- socket.ntohs(16 bit value) --> new int object
+- socket.ntohl(32 bit value) --> new int object
+- socket.htons(16 bit value) --> new int object
+- socket.htonl(32 bit value) --> new int object
+- socket.getaddrinfo(host, port [, family, socktype, proto, flags])
+ --> List of (family, socktype, proto, canonname, sockaddr)
+- socket.getnameinfo(sockaddr, flags) --> (host, port)
+- socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h>
+- socket.has_ipv6: boolean value indicating if IPv6 is supported
+- socket.inet_aton(IP address) -> 32-bit packed IP representation
+- socket.inet_ntoa(packed IP) -> IP address string
+- socket.getdefaulttimeout() -> None | float
+- socket.setdefaulttimeout(None | float)
+- an Internet socket address is a pair (hostname, port)
+ where hostname can be anything recognized by gethostbyname()
+ (including the dd.dd.dd.dd notation) and port is in host byte order
+- where a hostname is returned, the dd.dd.dd.dd notation is used
+- a UNIX domain socket address is a string specifying the pathname
+- an AF_PACKET socket address is a tuple containing a string
+ specifying the ethernet interface and an integer specifying
+ the Ethernet protocol number to be received. For example:
+ ("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple
+ specify packet-type and ha-type/addr.
+
+Local naming conventions:
+
+- names starting with sock_ are socket object methods
+- names starting with socket_ are module-level functions
+- names starting with PySocket are exported through socketmodule.h
+
+*/
+
+#ifdef __APPLE__
+ /*
+ * inet_aton is not available on OSX 10.3, yet we want to use a binary
+ * that was build on 10.4 or later to work on that release, weak linking
+ * comes to the rescue.
+ */
+# pragma weak inet_aton
+#endif
+
+#include "Python.h"
+#include "structmember.h"
+
+#undef MAX
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+
+/* Socket object documentation */
+PyDoc_STRVAR(sock_doc,
+"socket([family[, type[, proto]]]) -> socket object\n\
+\n\
+Open a socket of the given type. The family argument specifies the\n\
+address family; it defaults to AF_INET. The type argument specifies\n\
+whether this is a stream (SOCK_STREAM, this is the default)\n\
+or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\
+specifying the default protocol. Keyword arguments are accepted.\n\
+\n\
+A socket object represents one endpoint of a network connection.\n\
+\n\
+Methods of socket objects (keyword arguments not allowed):\n\
+\n\
+accept() -- accept a connection, returning new socket and client address\n\
+bind(addr) -- bind the socket to a local address\n\
+close() -- close the socket\n\
+connect(addr) -- connect the socket to a remote address\n\
+connect_ex(addr) -- connect, return an error code instead of an exception\n\
+dup() -- return a new socket object identical to the current one [*]\n\
+fileno() -- return underlying file descriptor\n\
+getpeername() -- return remote address [*]\n\
+getsockname() -- return local address\n\
+getsockopt(level, optname[, buflen]) -- get socket options\n\
+gettimeout() -- return timeout or None\n\
+listen(n) -- start listening for incoming connections\n\
+makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
+recv(buflen[, flags]) -- receive data\n\
+recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
+recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
+recvfrom_into(buffer[, nbytes, [, flags])\n\
+ -- receive data and sender\'s address (into a buffer)\n\
+sendall(data[, flags]) -- send all data\n\
+send(data[, flags]) -- send data, may not send all of it\n\
+sendto(data[, flags], addr) -- send data to a given address\n\
+setblocking(0 | 1) -- set or clear the blocking I/O flag\n\
+setsockopt(level, optname, value) -- set socket options\n\
+settimeout(None | float) -- set or clear the timeout\n\
+shutdown(how) -- shut down traffic in one or both directions\n\
+\n\
+ [*] not available on all platforms!");
+
+/* XXX This is a terrible mess of platform-dependent preprocessor hacks.
+ I hope some day someone can clean this up please... */
+
+/* Hacks for gethostbyname_r(). On some non-Linux platforms, the configure
+ script doesn't get this right, so we hardcode some platform checks below.
+ On the other hand, not all Linux versions agree, so there the settings
+ computed by the configure script are needed! */
+
+#ifndef linux
+# undef HAVE_GETHOSTBYNAME_R_3_ARG
+# undef HAVE_GETHOSTBYNAME_R_5_ARG
+# undef HAVE_GETHOSTBYNAME_R_6_ARG
+#endif
+
+#ifndef WITH_THREAD
+# undef HAVE_GETHOSTBYNAME_R
+#endif
+
+#ifdef HAVE_GETHOSTBYNAME_R
+# if defined(_AIX) || defined(__osf__)
+# define HAVE_GETHOSTBYNAME_R_3_ARG
+# elif defined(__sun) || defined(__sgi)
+# define HAVE_GETHOSTBYNAME_R_5_ARG
+# elif defined(linux)
+/* Rely on the configure script */
+# else
+# undef HAVE_GETHOSTBYNAME_R
+# endif
+#endif
+
+#if !defined(HAVE_GETHOSTBYNAME_R) && defined(WITH_THREAD) && \
+ !defined(MS_WINDOWS)
+# define USE_GETHOSTBYNAME_LOCK
+#endif
+
+/* To use __FreeBSD_version */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+/* On systems on which getaddrinfo() is believed to not be thread-safe,
+ (this includes the getaddrinfo emulation) protect access with a lock. */
+#if defined(WITH_THREAD) && (defined(__APPLE__) || \
+ (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
+ defined(__OpenBSD__) || defined(__NetBSD__) || \
+ defined(__VMS) || !defined(HAVE_GETADDRINFO))
+#define USE_GETADDRINFO_LOCK
+#endif
+
+#ifdef USE_GETADDRINFO_LOCK
+#define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1);
+#define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock);
+#else
+#define ACQUIRE_GETADDRINFO_LOCK
+#define RELEASE_GETADDRINFO_LOCK
+#endif
+
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+# include "pythread.h"
+#endif
+
+#if defined(PYCC_VACPP)
+# include <types.h>
+# include <io.h>
+# include <sys/ioctl.h>
+# include <utils.h>
+# include <ctype.h>
+#endif
+
+#if defined(__VMS)
+# include <ioctl.h>
+#endif
+
+#if defined(PYOS_OS2)
+# define INCL_DOS
+# define INCL_DOSERRORS
+# define INCL_NOPMAPI
+# include <os2.h>
+#endif
+
+#if defined(__sgi) && _COMPILER_VERSION>700 && !_SGIAPI
+/* make sure that the reentrant (gethostbyaddr_r etc)
+ functions are declared correctly if compiling with
+ MIPSPro 7.x in ANSI C mode (default) */
+
+/* XXX Using _SGIAPI is the wrong thing,
+ but I don't know what the right thing is. */
+#undef _SGIAPI /* to avoid warning */
+#define _SGIAPI 1
+
+#undef _XOPEN_SOURCE
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#ifdef _SS_ALIGNSIZE
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETNAMEINFO 1
+#endif
+
+#define HAVE_INET_PTON
+#include <netdb.h>
+#endif
+
+/* Irix 6.5 fails to define this variable at all. This is needed
+ for both GCC and SGI's compiler. I'd say that the SGI headers
+ are just busted. Same thing for Solaris. */
+#if (defined(__sgi) || defined(sun)) && !defined(INET_ADDRSTRLEN)
+#define INET_ADDRSTRLEN 16
+#endif
+
+/* Generic includes */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+/* Generic socket object definitions and includes */
+#define PySocket_BUILDING_SOCKET
+#include "socketmodule.h"
+
+/* Addressing includes */
+
+#ifndef MS_WINDOWS
+
+/* Non-MS WINDOWS includes */
+# include <netdb.h>
+
+/* Headers needed for inet_ntoa() and inet_addr() */
+# ifdef __BEOS__
+# include <net/netdb.h>
+# elif defined(PYOS_OS2) && defined(PYCC_VACPP)
+# include <netdb.h>
+typedef size_t socklen_t;
+# else
+# include <arpa/inet.h>
+# endif
+
+# ifndef RISCOS
+# include <fcntl.h>
+# else
+# include <sys/ioctl.h>
+# include <socklib.h>
+# define NO_DUP
+int h_errno; /* not used */
+# define INET_ADDRSTRLEN 16
+# endif
+
+#else
+
+/* MS_WINDOWS includes */
+# ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+# endif
+
+#endif
+
+#include <stddef.h>
+
+#ifndef offsetof
+# define offsetof(type, member) ((size_t)(&((type *)0)->member))
+#endif
+
+#ifndef O_NONBLOCK
+# define O_NONBLOCK O_NDELAY
+#endif
+
+/* include Python's addrinfo.h unless it causes trouble */
+#if defined(__sgi) && _COMPILER_VERSION>700 && defined(_SS_ALIGNSIZE)
+ /* Do not include addinfo.h on some newer IRIX versions.
+ * _SS_ALIGNSIZE is defined in sys/socket.h by 6.5.21,
+ * for example, but not by 6.5.10.
+ */
+#elif defined(_MSC_VER) && _MSC_VER>1201
+ /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and
+ * EAI_* constants are defined in (the already included) ws2tcpip.h.
+ */
+#else
+# include "addrinfo.h"
+#endif
+
+#ifndef HAVE_INET_PTON
+int inet_pton(int af, const char *src, void *dst);
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
+#endif
+
+#ifdef __APPLE__
+/* On OS X, getaddrinfo returns no error indication of lookup
+ failure, so we must use the emulation instead of the libinfo
+ implementation. Unfortunately, performing an autoconf test
+ for this bug would require DNS access for the machine performing
+ the configuration, which is not acceptable. Therefore, we
+ determine the bug just by checking for __APPLE__. If this bug
+ gets ever fixed, perhaps checking for sys/version.h would be
+ appropriate, which is 10/0 on the system with the bug. */
+#ifndef HAVE_GETNAMEINFO
+/* This bug seems to be fixed in Jaguar. Ths easiest way I could
+ Find to check for Jaguar is that it has getnameinfo(), which
+ older releases don't have */
+#undef HAVE_GETADDRINFO
+#endif
+
+#ifdef HAVE_INET_ATON
+#define USE_INET_ATON_WEAKLINK
+#endif
+
+#endif
+
+/* I know this is a bad practice, but it is the easiest... */
+#if !defined(HAVE_GETADDRINFO)
+/* avoid clashes with the C library definition of the symbol. */
+#define getaddrinfo fake_getaddrinfo
+#define gai_strerror fake_gai_strerror
+#define freeaddrinfo fake_freeaddrinfo
+#include "getaddrinfo.c"
+#endif
+#if !defined(HAVE_GETNAMEINFO)
+#define getnameinfo fake_getnameinfo
+#include "getnameinfo.c"
+#endif
+
+#if defined(MS_WINDOWS) || defined(__BEOS__)
+/* BeOS suffers from the same socket dichotomy as Win32... - [cjh] */
+/* seem to be a few differences in the API */
+#define SOCKETCLOSE closesocket
+#define NO_DUP /* Actually it exists on NT 3.5, but what the heck... */
+#endif
+
+#ifdef MS_WIN32
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define snprintf _snprintf
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#define SOCKETCLOSE soclose
+#define NO_DUP /* Sockets are Not Actual File Handles under OS/2 */
+#endif
+
+#ifndef SOCKETCLOSE
+#define SOCKETCLOSE close
+#endif
+
+#if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)
+#define USE_BLUETOOTH 1
+#if defined(__FreeBSD__)
+#define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP
+#define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
+#define sockaddr_l2 sockaddr_l2cap
+#define sockaddr_rc sockaddr_rfcomm
+#define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb)
+#define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb)
+#elif defined(__NetBSD__)
+#define sockaddr_l2 sockaddr_bt
+#define sockaddr_rc sockaddr_bt
+#define sockaddr_sco sockaddr_bt
+#define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb)
+#define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb)
+#define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb)
+#else
+#define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb)
+#define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb)
+#define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb)
+#endif
+#endif
+
+#ifdef __VMS
+/* TCP/IP Services for VMS uses a maximum send/recv buffer length */
+#define SEGMENT_SIZE (32 * 1024 -1)
+#endif
+
+#define SAS2SA(x) ((struct sockaddr *)(x))
+
+/*
+ * Constants for getnameinfo()
+ */
+#if !defined(NI_MAXHOST)
+#define NI_MAXHOST 1025
+#endif
+#if !defined(NI_MAXSERV)
+#define NI_MAXSERV 32
+#endif
+
+/* XXX There's a problem here: *static* functions are not supposed to have
+ a Py prefix (or use CapitalizedWords). Later... */
+
+/* Global variable holding the exception type for errors detected
+ by this module (but not argument type or memory errors, etc.). */
+static PyObject *socket_error;
+static PyObject *socket_herror;
+static PyObject *socket_gaierror;
+static PyObject *socket_timeout;
+
+#ifdef RISCOS
+/* Global variable which is !=0 if Python is running in a RISC OS taskwindow */
+static int taskwindow;
+#endif
+
+/* A forward reference to the socket type object.
+ The sock_type variable contains pointers to various functions,
+ some of which call new_sockobject(), which uses sock_type, so
+ there has to be a circular reference. */
+static PyTypeObject sock_type;
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+#ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+/* Platform can select file descriptors beyond FD_SETSIZE */
+#define IS_SELECTABLE(s) 1
+#elif defined(HAVE_POLL)
+/* Instead of select(), we'll use poll() since poll() works on any fd. */
+#define IS_SELECTABLE(s) 1
+/* Can we call select() with this socket without a buffer overrun? */
+#else
+/* POSIX says selecting file descriptors beyond FD_SETSIZE
+ has undefined behaviour. If there's no timeout left, we don't have to
+ call select, so it's a safe, little white lie. */
+#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE || s->sock_timeout <= 0.0)
+#endif
+
+static PyObject*
+select_error(void)
+{
+ PyErr_SetString(socket_error, "unable to select on socket");
+ return NULL;
+}
+
+/* Convenience function to raise an error according to errno
+ and return a NULL pointer from a function. */
+
+static PyObject *
+set_error(void)
+{
+#ifdef MS_WINDOWS
+ int err_no = WSAGetLastError();
+ static struct {
+ int no;
+ const char *msg;
+ } *msgp, msgs[] = {
+ {WSAEINTR, "Interrupted system call"},
+ {WSAEBADF, "Bad file descriptor"},
+ {WSAEACCES, "Permission denied"},
+ {WSAEFAULT, "Bad address"},
+ {WSAEINVAL, "Invalid argument"},
+ {WSAEMFILE, "Too many open files"},
+ {WSAEWOULDBLOCK,
+ "The socket operation could not complete "
+ "without blocking"},
+ {WSAEINPROGRESS, "Operation now in progress"},
+ {WSAEALREADY, "Operation already in progress"},
+ {WSAENOTSOCK, "Socket operation on non-socket"},
+ {WSAEDESTADDRREQ, "Destination address required"},
+ {WSAEMSGSIZE, "Message too long"},
+ {WSAEPROTOTYPE, "Protocol wrong type for socket"},
+ {WSAENOPROTOOPT, "Protocol not available"},
+ {WSAEPROTONOSUPPORT, "Protocol not supported"},
+ {WSAESOCKTNOSUPPORT, "Socket type not supported"},
+ {WSAEOPNOTSUPP, "Operation not supported"},
+ {WSAEPFNOSUPPORT, "Protocol family not supported"},
+ {WSAEAFNOSUPPORT, "Address family not supported"},
+ {WSAEADDRINUSE, "Address already in use"},
+ {WSAEADDRNOTAVAIL, "Can't assign requested address"},
+ {WSAENETDOWN, "Network is down"},
+ {WSAENETUNREACH, "Network is unreachable"},
+ {WSAENETRESET, "Network dropped connection on reset"},
+ {WSAECONNABORTED, "Software caused connection abort"},
+ {WSAECONNRESET, "Connection reset by peer"},
+ {WSAENOBUFS, "No buffer space available"},
+ {WSAEISCONN, "Socket is already connected"},
+ {WSAENOTCONN, "Socket is not connected"},
+ {WSAESHUTDOWN, "Can't send after socket shutdown"},
+ {WSAETOOMANYREFS, "Too many references: can't splice"},
+ {WSAETIMEDOUT, "Operation timed out"},
+ {WSAECONNREFUSED, "Connection refused"},
+ {WSAELOOP, "Too many levels of symbolic links"},
+ {WSAENAMETOOLONG, "File name too long"},
+ {WSAEHOSTDOWN, "Host is down"},
+ {WSAEHOSTUNREACH, "No route to host"},
+ {WSAENOTEMPTY, "Directory not empty"},
+ {WSAEPROCLIM, "Too many processes"},
+ {WSAEUSERS, "Too many users"},
+ {WSAEDQUOT, "Disc quota exceeded"},
+ {WSAESTALE, "Stale NFS file handle"},
+ {WSAEREMOTE, "Too many levels of remote in path"},
+ {WSASYSNOTREADY, "Network subsystem is unvailable"},
+ {WSAVERNOTSUPPORTED, "WinSock version is not supported"},
+ {WSANOTINITIALISED,
+ "Successful WSAStartup() not yet performed"},
+ {WSAEDISCON, "Graceful shutdown in progress"},
+ /* Resolver errors */
+ {WSAHOST_NOT_FOUND, "No such host is known"},
+ {WSATRY_AGAIN, "Host not found, or server failed"},
+ {WSANO_RECOVERY, "Unexpected server error encountered"},
+ {WSANO_DATA, "Valid name without requested data"},
+ {WSANO_ADDRESS, "No address, look for MX record"},
+ {0, NULL}
+ };
+ if (err_no) {
+ PyObject *v;
+ const char *msg = "winsock error";
+
+ for (msgp = msgs; msgp->msg; msgp++) {
+ if (err_no == msgp->no) {
+ msg = msgp->msg;
+ break;
+ }
+ }
+
+ v = Py_BuildValue("(is)", err_no, msg);
+ if (v != NULL) {
+ PyErr_SetObject(socket_error, v);
+ Py_DECREF(v);
+ }
+ return NULL;
+ }
+ else
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+ if (sock_errno() != NO_ERROR) {
+ APIRET rc;
+ ULONG msglen;
+ char outbuf[100];
+ int myerrorcode = sock_errno();
+
+ /* Retrieve socket-related error message from MPTN.MSG file */
+ rc = DosGetMessage(NULL, 0, outbuf, sizeof(outbuf),
+ myerrorcode - SOCBASEERR + 26,
+ "mptn.msg",
+ &msglen);
+ if (rc == NO_ERROR) {
+ PyObject *v;
+
+ /* OS/2 doesn't guarantee a terminator */
+ outbuf[msglen] = '\0';
+ if (strlen(outbuf) > 0) {
+ /* If non-empty msg, trim CRLF */
+ char *lastc = &outbuf[ strlen(outbuf)-1 ];
+ while (lastc > outbuf &&
+ isspace(Py_CHARMASK(*lastc))) {
+ /* Trim trailing whitespace (CRLF) */
+ *lastc-- = '\0';
+ }
+ }
+ v = Py_BuildValue("(is)", myerrorcode, outbuf);
+ if (v != NULL) {
+ PyErr_SetObject(socket_error, v);
+ Py_DECREF(v);
+ }
+ return NULL;
+ }
+ }
+#endif
+
+#if defined(RISCOS)
+ if (_inet_error.errnum != NULL) {
+ PyObject *v;
+ v = Py_BuildValue("(is)", errno, _inet_err());
+ if (v != NULL) {
+ PyErr_SetObject(socket_error, v);
+ Py_DECREF(v);
+ }
+ return NULL;
+ }
+#endif
+
+ return PyErr_SetFromErrno(socket_error);
+}
+
+
+static PyObject *
+set_herror(int h_error)
+{
+ PyObject *v;
+
+#ifdef HAVE_HSTRERROR
+ v = Py_BuildValue("(is)", h_error, (char *)hstrerror(h_error));
+#else
+ v = Py_BuildValue("(is)", h_error, "host not found");
+#endif
+ if (v != NULL) {
+ PyErr_SetObject(socket_herror, v);
+ Py_DECREF(v);
+ }
+
+ return NULL;
+}
+
+
+static PyObject *
+set_gaierror(int error)
+{
+ PyObject *v;
+
+#ifdef EAI_SYSTEM
+ /* EAI_SYSTEM is not available on Windows XP. */
+ if (error == EAI_SYSTEM)
+ return set_error();
+#endif
+
+#ifdef HAVE_GAI_STRERROR
+ v = Py_BuildValue("(is)", error, gai_strerror(error));
+#else
+ v = Py_BuildValue("(is)", error, "getaddrinfo failed");
+#endif
+ if (v != NULL) {
+ PyErr_SetObject(socket_gaierror, v);
+ Py_DECREF(v);
+ }
+
+ return NULL;
+}
+
+#ifdef __VMS
+/* Function to send in segments */
+static int
+sendsegmented(int sock_fd, char *buf, int len, int flags)
+{
+ int n = 0;
+ int remaining = len;
+
+ while (remaining > 0) {
+ unsigned int segment;
+
+ segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining);
+ n = send(sock_fd, buf, segment, flags);
+ if (n < 0) {
+ return n;
+ }
+ remaining -= segment;
+ buf += segment;
+ } /* end while */
+
+ return len;
+}
+#endif
+
+/* Function to perform the setting of socket blocking mode
+ internally. block = (1 | 0). */
+static int
+internal_setblocking(PySocketSockObject *s, int block)
+{
+#ifndef RISCOS
+#ifndef MS_WINDOWS
+ int delay_flag;
+#endif
+#endif
+
+ Py_BEGIN_ALLOW_THREADS
+#ifdef __BEOS__
+ block = !block;
+ setsockopt(s->sock_fd, SOL_SOCKET, SO_NONBLOCK,
+ (void *)(&block), sizeof(int));
+#else
+#ifndef RISCOS
+#ifndef MS_WINDOWS
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+ block = !block;
+ ioctl(s->sock_fd, FIONBIO, (caddr_t)&block, sizeof(block));
+#elif defined(__VMS)
+ block = !block;
+ ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block);
+#else /* !PYOS_OS2 && !__VMS */
+ delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
+ if (block)
+ delay_flag &= (~O_NONBLOCK);
+ else
+ delay_flag |= O_NONBLOCK;
+ fcntl(s->sock_fd, F_SETFL, delay_flag);
+#endif /* !PYOS_OS2 */
+#else /* MS_WINDOWS */
+ block = !block;
+ ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block);
+#endif /* MS_WINDOWS */
+#else /* RISCOS */
+ block = !block;
+ socketioctl(s->sock_fd, FIONBIO, (u_long*)&block);
+#endif /* RISCOS */
+#endif /* __BEOS__ */
+ Py_END_ALLOW_THREADS
+
+ /* Since these don't return anything */
+ return 1;
+}
+
+/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).
+ The argument writing indicates the direction.
+ This does not raise an exception; we'll let our caller do that
+ after they've reacquired the interpreter lock.
+ Returns 1 on timeout, -1 on error, 0 otherwise. */
+static int
+internal_select(PySocketSockObject *s, int writing)
+{
+ int n;
+
+ /* Nothing to do unless we're in timeout mode (not non-blocking) */
+ if (s->sock_timeout <= 0.0)
+ return 0;
+
+ /* Guard against closed socket */
+ if (s->sock_fd < 0)
+ return 0;
+
+ /* Prefer poll, if available, since you can poll() any fd
+ * which can't be done with select(). */
+#ifdef HAVE_POLL
+ {
+ struct pollfd pollfd;
+ int timeout;
+
+ pollfd.fd = s->sock_fd;
+ pollfd.events = writing ? POLLOUT : POLLIN;
+
+ /* s->sock_timeout is in seconds, timeout in ms */
+ timeout = (int)(s->sock_timeout * 1000 + 0.5);
+ n = poll(&pollfd, 1, timeout);
+ }
+#else
+ {
+ /* Construct the arguments to select */
+ fd_set fds;
+ struct timeval tv;
+ tv.tv_sec = (int)s->sock_timeout;
+ tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+ FD_ZERO(&fds);
+ FD_SET(s->sock_fd, &fds);
+
+ /* See if the socket is ready */
+ if (writing)
+ n = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
+ else
+ n = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+ }
+#endif
+
+ if (n < 0)
+ return -1;
+ if (n == 0)
+ return 1;
+ return 0;
+}
+
+/* Initialize a new socket object. */
+
+static double defaulttimeout = -1.0; /* Default timeout for new sockets */
+
+PyMODINIT_FUNC
+init_sockobject(PySocketSockObject *s,
+ SOCKET_T fd, int family, int type, int proto)
+{
+#ifdef RISCOS
+ int block = 1;
+#endif
+ s->sock_fd = fd;
+ s->sock_family = family;
+ s->sock_type = type;
+ s->sock_proto = proto;
+ s->sock_timeout = defaulttimeout;
+
+ s->errorhandler = &set_error;
+
+ if (defaulttimeout >= 0.0)
+ internal_setblocking(s, 0);
+
+#ifdef RISCOS
+ if (taskwindow)
+ socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
+#endif
+}
+
+
+/* Create a new socket object.
+ This just creates the object and initializes it.
+ If the creation fails, return NULL and set an exception (implicit
+ in NEWOBJ()). */
+
+static PySocketSockObject *
+new_sockobject(SOCKET_T fd, int family, int type, int proto)
+{
+ PySocketSockObject *s;
+ s = (PySocketSockObject *)
+ PyType_GenericNew(&sock_type, NULL, NULL);
+ if (s != NULL)
+ init_sockobject(s, fd, family, type, proto);
+ return s;
+}
+
+
+/* Lock to allow python interpreter to continue, but only allow one
+ thread to be in gethostbyname or getaddrinfo */
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+PyThread_type_lock netdb_lock;
+#endif
+
+
+/* Convert a string specifying a host name or one of a few symbolic
+ names to a numeric IP address. This usually calls gethostbyname()
+ to do the work; the names "" and "<broadcast>" are special.
+ Return the length (IPv4 should be 4 bytes), or negative if
+ an error occurred; then an exception is raised. */
+
+static int
+setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af)
+{
+ struct addrinfo hints, *res;
+ int error;
+ int d1, d2, d3, d4;
+ char ch;
+
+ memset((void *) addr_ret, '\0', addr_ret_size);
+ if (name[0] == '\0') {
+ int siz;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_PASSIVE;
+ Py_BEGIN_ALLOW_THREADS
+ ACQUIRE_GETADDRINFO_LOCK
+ error = getaddrinfo(NULL, "0", &hints, &res);
+ Py_END_ALLOW_THREADS
+ /* We assume that those thread-unsafe getaddrinfo() versions
+ *are* safe regarding their return value, ie. that a
+ subsequent call to getaddrinfo() does not destroy the
+ outcome of the first call. */
+ RELEASE_GETADDRINFO_LOCK
+ if (error) {
+ set_gaierror(error);
+ return -1;
+ }
+ switch (res->ai_family) {
+ case AF_INET:
+ siz = 4;
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ siz = 16;
+ break;
+#endif
+ default:
+ freeaddrinfo(res);
+ PyErr_SetString(socket_error,
+ "unsupported address family");
+ return -1;
+ }
+ if (res->ai_next) {
+ freeaddrinfo(res);
+ PyErr_SetString(socket_error,
+ "wildcard resolved to multiple address");
+ return -1;
+ }
+ if (res->ai_addrlen < addr_ret_size)
+ addr_ret_size = res->ai_addrlen;
+ memcpy(addr_ret, res->ai_addr, addr_ret_size);
+ freeaddrinfo(res);
+ return siz;
+ }
+ if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
+ struct sockaddr_in *sin;
+ if (af != AF_INET && af != AF_UNSPEC) {
+ PyErr_SetString(socket_error,
+ "address family mismatched");
+ return -1;
+ }
+ sin = (struct sockaddr_in *)addr_ret;
+ memset((void *) sin, '\0', sizeof(*sin));
+ sin->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(*sin);
+#endif
+ sin->sin_addr.s_addr = INADDR_BROADCAST;
+ return sizeof(sin->sin_addr);
+ }
+ if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
+ 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
+ 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
+ struct sockaddr_in *sin;
+ sin = (struct sockaddr_in *)addr_ret;
+ sin->sin_addr.s_addr = htonl(
+ ((long) d1 << 24) | ((long) d2 << 16) |
+ ((long) d3 << 8) | ((long) d4 << 0));
+ sin->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(*sin);
+#endif
+ return 4;
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ Py_BEGIN_ALLOW_THREADS
+ ACQUIRE_GETADDRINFO_LOCK
+ error = getaddrinfo(name, NULL, &hints, &res);
+#if defined(__digital__) && defined(__unix__)
+ if (error == EAI_NONAME && af == AF_UNSPEC) {
+ /* On Tru64 V5.1, numeric-to-addr conversion fails
+ if no address family is given. Assume IPv4 for now.*/
+ hints.ai_family = AF_INET;
+ error = getaddrinfo(name, NULL, &hints, &res);
+ }
+#endif
+ Py_END_ALLOW_THREADS
+ RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */
+ if (error) {
+ set_gaierror(error);
+ return -1;
+ }
+ if (res->ai_addrlen < addr_ret_size)
+ addr_ret_size = res->ai_addrlen;
+ memcpy((char *) addr_ret, res->ai_addr, addr_ret_size);
+ freeaddrinfo(res);
+ switch (addr_ret->sa_family) {
+ case AF_INET:
+ return 4;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ return 16;
+#endif
+ default:
+ PyErr_SetString(socket_error, "unknown address family");
+ return -1;
+ }
+}
+
+
+/* Create a string object representing an IP address.
+ This is always a string of the form 'dd.dd.dd.dd' (with variable
+ size numbers). */
+
+static PyObject *
+makeipaddr(struct sockaddr *addr, int addrlen)
+{
+ char buf[NI_MAXHOST];
+ int error;
+
+ error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
+ NI_NUMERICHOST);
+ if (error) {
+ set_gaierror(error);
+ return NULL;
+ }
+ return PyString_FromString(buf);
+}
+
+
+#ifdef USE_BLUETOOTH
+/* Convert a string representation of a Bluetooth address into a numeric
+ address. Returns the length (6), or raises an exception and returns -1 if
+ an error occurred. */
+
+static int
+setbdaddr(char *name, bdaddr_t *bdaddr)
+{
+ unsigned int b0, b1, b2, b3, b4, b5;
+ char ch;
+ int n;
+
+ n = sscanf(name, "%X:%X:%X:%X:%X:%X%c",
+ &b5, &b4, &b3, &b2, &b1, &b0, &ch);
+ if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) {
+ bdaddr->b[0] = b0;
+ bdaddr->b[1] = b1;
+ bdaddr->b[2] = b2;
+ bdaddr->b[3] = b3;
+ bdaddr->b[4] = b4;
+ bdaddr->b[5] = b5;
+ return 6;
+ } else {
+ PyErr_SetString(socket_error, "bad bluetooth address");
+ return -1;
+ }
+}
+
+/* Create a string representation of the Bluetooth address. This is always a
+ string of the form 'XX:XX:XX:XX:XX:XX' where XX is a two digit hexadecimal
+ value (zero padded if necessary). */
+
+static PyObject *
+makebdaddr(bdaddr_t *bdaddr)
+{
+ char buf[(6 * 2) + 5 + 1];
+
+ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
+ bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ return PyString_FromString(buf);
+}
+#endif
+
+
+/* Create an object representing the given socket address,
+ suitable for passing it back to bind(), connect() etc.
+ The family field of the sockaddr structure is inspected
+ to determine what kind of address it really is. */
+
+/*ARGSUSED*/
+static PyObject *
+makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
+{
+ if (addrlen == 0) {
+ /* No address -- may be recvfrom() from known socket */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+#ifdef __BEOS__
+ /* XXX: BeOS version of accept() doesn't set family correctly */
+ addr->sa_family = AF_INET;
+#endif
+
+ switch (addr->sa_family) {
+
+ case AF_INET:
+ {
+ struct sockaddr_in *a;
+ PyObject *addrobj = makeipaddr(addr, sizeof(*a));
+ PyObject *ret = NULL;
+ if (addrobj) {
+ a = (struct sockaddr_in *)addr;
+ ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
+ Py_DECREF(addrobj);
+ }
+ return ret;
+ }
+
+#if defined(AF_UNIX)
+ case AF_UNIX:
+ {
+ struct sockaddr_un *a = (struct sockaddr_un *) addr;
+#ifdef linux
+ if (a->sun_path[0] == 0) { /* Linux abstract namespace */
+ addrlen -= (sizeof(*a) - sizeof(a->sun_path));
+ return PyString_FromStringAndSize(a->sun_path,
+ addrlen);
+ }
+ else
+#endif /* linux */
+ {
+ /* regular NULL-terminated string */
+ return PyString_FromString(a->sun_path);
+ }
+ }
+#endif /* AF_UNIX */
+
+#if defined(AF_NETLINK)
+ case AF_NETLINK:
+ {
+ struct sockaddr_nl *a = (struct sockaddr_nl *) addr;
+ return Py_BuildValue("II", a->nl_pid, a->nl_groups);
+ }
+#endif /* AF_NETLINK */
+
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *a;
+ PyObject *addrobj = makeipaddr(addr, sizeof(*a));
+ PyObject *ret = NULL;
+ if (addrobj) {
+ a = (struct sockaddr_in6 *)addr;
+ ret = Py_BuildValue("Oiii",
+ addrobj,
+ ntohs(a->sin6_port),
+ a->sin6_flowinfo,
+ a->sin6_scope_id);
+ Py_DECREF(addrobj);
+ }
+ return ret;
+ }
+#endif
+
+#ifdef USE_BLUETOOTH
+ case AF_BLUETOOTH:
+ switch (proto) {
+
+ case BTPROTO_L2CAP:
+ {
+ struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr;
+ PyObject *addrobj = makebdaddr(&_BT_L2_MEMB(a, bdaddr));
+ PyObject *ret = NULL;
+ if (addrobj) {
+ ret = Py_BuildValue("Oi",
+ addrobj,
+ _BT_L2_MEMB(a, psm));
+ Py_DECREF(addrobj);
+ }
+ return ret;
+ }
+
+ case BTPROTO_RFCOMM:
+ {
+ struct sockaddr_rc *a = (struct sockaddr_rc *) addr;
+ PyObject *addrobj = makebdaddr(&_BT_RC_MEMB(a, bdaddr));
+ PyObject *ret = NULL;
+ if (addrobj) {
+ ret = Py_BuildValue("Oi",
+ addrobj,
+ _BT_RC_MEMB(a, channel));
+ Py_DECREF(addrobj);
+ }
+ return ret;
+ }
+
+#if !defined(__FreeBSD__)
+ case BTPROTO_SCO:
+ {
+ struct sockaddr_sco *a = (struct sockaddr_sco *) addr;
+ return makebdaddr(&_BT_SCO_MEMB(a, bdaddr));
+ }
+#endif
+
+ }
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+ case AF_PACKET:
+ {
+ struct sockaddr_ll *a = (struct sockaddr_ll *)addr;
+ char *ifname = "";
+ struct ifreq ifr;
+ /* need to look up interface name give index */
+ if (a->sll_ifindex) {
+ ifr.ifr_ifindex = a->sll_ifindex;
+ if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0)
+ ifname = ifr.ifr_name;
+ }
+ return Py_BuildValue("shbhs#",
+ ifname,
+ ntohs(a->sll_protocol),
+ a->sll_pkttype,
+ a->sll_hatype,
+ a->sll_addr,
+ a->sll_halen);
+ }
+#endif
+
+ /* More cases here... */
+
+ default:
+ /* If we don't know the address family, don't raise an
+ exception -- return it as a tuple. */
+ return Py_BuildValue("is#",
+ addr->sa_family,
+ addr->sa_data,
+ sizeof(addr->sa_data));
+
+ }
+}
+
+
+/* Parse a socket address argument according to the socket object's
+ address family. Return 1 if the address was in the proper format,
+ 0 of not. The address is returned through addr_ret, its length
+ through len_ret. */
+
+static int
+getsockaddrarg(PySocketSockObject *s, PyObject *args,
+ struct sockaddr *addr_ret, int *len_ret)
+{
+ switch (s->sock_family) {
+
+#if defined(AF_UNIX)
+ case AF_UNIX:
+ {
+ struct sockaddr_un* addr;
+ char *path;
+ int len;
+ if (!PyArg_Parse(args, "t#", &path, &len))
+ return 0;
+
+ addr = (struct sockaddr_un*)addr_ret;
+#ifdef linux
+ if (len > 0 && path[0] == 0) {
+ /* Linux abstract namespace extension */
+ if (len > sizeof addr->sun_path) {
+ PyErr_SetString(socket_error,
+ "AF_UNIX path too long");
+ return 0;
+ }
+ }
+ else
+#endif /* linux */
+ {
+ /* regular NULL-terminated string */
+ if (len >= sizeof addr->sun_path) {
+ PyErr_SetString(socket_error,
+ "AF_UNIX path too long");
+ return 0;
+ }
+ addr->sun_path[len] = 0;
+ }
+ addr->sun_family = s->sock_family;
+ memcpy(addr->sun_path, path, len);
+#if defined(PYOS_OS2)
+ *len_ret = sizeof(*addr);
+#else
+ *len_ret = len + sizeof(*addr) - sizeof(addr->sun_path);
+#endif
+ return 1;
+ }
+#endif /* AF_UNIX */
+
+#if defined(AF_NETLINK)
+ case AF_NETLINK:
+ {
+ struct sockaddr_nl* addr;
+ int pid, groups;
+ addr = (struct sockaddr_nl *)addr_ret;
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_NETLINK address must be tuple, not %.500s",
+ args->ob_type->tp_name);
+ return 0;
+ }
+ if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &pid, &groups))
+ return 0;
+ addr->nl_family = AF_NETLINK;
+ addr->nl_pid = pid;
+ addr->nl_groups = groups;
+ *len_ret = sizeof(*addr);
+ return 1;
+ }
+#endif
+
+ case AF_INET:
+ {
+ struct sockaddr_in* addr;
+ char *host;
+ int port, result;
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_INET address must be tuple, not %.500s",
+ args->ob_type->tp_name);
+ return 0;
+ }
+ if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
+ "idna", &host, &port))
+ return 0;
+ addr=(struct sockaddr_in*)addr_ret;
+ result = setipaddr(host, (struct sockaddr *)addr,
+ sizeof(*addr), AF_INET);
+ PyMem_Free(host);
+ if (result < 0)
+ return 0;
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons((short)port);
+ *len_ret = sizeof *addr;
+ return 1;
+ }
+
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6* addr;
+ char *host;
+ int port, flowinfo, scope_id, result;
+ flowinfo = scope_id = 0;
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_INET6 address must be tuple, not %.500s",
+ args->ob_type->tp_name);
+ return 0;
+ }
+ if (!PyArg_ParseTuple(args, "eti|ii",
+ "idna", &host, &port, &flowinfo,
+ &scope_id)) {
+ return 0;
+ }
+ addr = (struct sockaddr_in6*)addr_ret;
+ result = setipaddr(host, (struct sockaddr *)addr,
+ sizeof(*addr), AF_INET6);
+ PyMem_Free(host);
+ if (result < 0)
+ return 0;
+ addr->sin6_family = s->sock_family;
+ addr->sin6_port = htons((short)port);
+ addr->sin6_flowinfo = flowinfo;
+ addr->sin6_scope_id = scope_id;
+ *len_ret = sizeof *addr;
+ return 1;
+ }
+#endif
+
+#ifdef USE_BLUETOOTH
+ case AF_BLUETOOTH:
+ {
+ switch (s->sock_proto) {
+ case BTPROTO_L2CAP:
+ {
+ struct sockaddr_l2 *addr;
+ char *straddr;
+
+ addr = (struct sockaddr_l2 *)addr_ret;
+ _BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
+ if (!PyArg_ParseTuple(args, "si", &straddr,
+ &_BT_L2_MEMB(addr, psm))) {
+ PyErr_SetString(socket_error, "getsockaddrarg: "
+ "wrong format");
+ return 0;
+ }
+ if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
+ return 0;
+
+ *len_ret = sizeof *addr;
+ return 1;
+ }
+ case BTPROTO_RFCOMM:
+ {
+ struct sockaddr_rc *addr;
+ char *straddr;
+
+ addr = (struct sockaddr_rc *)addr_ret;
+ _BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
+ if (!PyArg_ParseTuple(args, "si", &straddr,
+ &_BT_RC_MEMB(addr, channel))) {
+ PyErr_SetString(socket_error, "getsockaddrarg: "
+ "wrong format");
+ return 0;
+ }
+ if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
+ return 0;
+
+ *len_ret = sizeof *addr;
+ return 1;
+ }
+#if !defined(__FreeBSD__)
+ case BTPROTO_SCO:
+ {
+ struct sockaddr_sco *addr;
+ char *straddr;
+
+ addr = (struct sockaddr_sco *)addr_ret;
+ _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
+ straddr = PyString_AsString(args);
+ if (straddr == NULL) {
+ PyErr_SetString(socket_error, "getsockaddrarg: "
+ "wrong format");
+ return 0;
+ }
+ if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0)
+ return 0;
+
+ *len_ret = sizeof *addr;
+ return 1;
+ }
+#endif
+ default:
+ PyErr_SetString(socket_error, "getsockaddrarg: unknown Bluetooth protocol");
+ return 0;
+ }
+ }
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+ case AF_PACKET:
+ {
+ struct sockaddr_ll* addr;
+ struct ifreq ifr;
+ char *interfaceName;
+ int protoNumber;
+ int hatype = 0;
+ int pkttype = 0;
+ char *haddr = NULL;
+ unsigned int halen = 0;
+
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_PACKET address must be tuple, not %.500s",
+ args->ob_type->tp_name);
+ return 0;
+ }
+ if (!PyArg_ParseTuple(args, "si|iis#", &interfaceName,
+ &protoNumber, &pkttype, &hatype,
+ &haddr, &halen))
+ return 0;
+ strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name));
+ ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0';
+ if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) {
+ s->errorhandler();
+ return 0;
+ }
+ if (halen > 8) {
+ PyErr_SetString(PyExc_ValueError,
+ "Hardware address must be 8 bytes or less");
+ return 0;
+ }
+ addr = (struct sockaddr_ll*)addr_ret;
+ addr->sll_family = AF_PACKET;
+ addr->sll_protocol = htons((short)protoNumber);
+ addr->sll_ifindex = ifr.ifr_ifindex;
+ addr->sll_pkttype = pkttype;
+ addr->sll_hatype = hatype;
+ if (halen != 0) {
+ memcpy(&addr->sll_addr, haddr, halen);
+ }
+ addr->sll_halen = halen;
+ *len_ret = sizeof *addr;
+ return 1;
+ }
+#endif
+
+ /* More cases here... */
+
+ default:
+ PyErr_SetString(socket_error, "getsockaddrarg: bad family");
+ return 0;
+
+ }
+}
+
+
+/* Get the address length according to the socket object's address family.
+ Return 1 if the family is known, 0 otherwise. The length is returned
+ through len_ret. */
+
+static int
+getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
+{
+ switch (s->sock_family) {
+
+#if defined(AF_UNIX)
+ case AF_UNIX:
+ {
+ *len_ret = sizeof (struct sockaddr_un);
+ return 1;
+ }
+#endif /* AF_UNIX */
+#if defined(AF_NETLINK)
+ case AF_NETLINK:
+ {
+ *len_ret = sizeof (struct sockaddr_nl);
+ return 1;
+ }
+#endif
+
+ case AF_INET:
+ {
+ *len_ret = sizeof (struct sockaddr_in);
+ return 1;
+ }
+
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ {
+ *len_ret = sizeof (struct sockaddr_in6);
+ return 1;
+ }
+#endif
+
+#ifdef USE_BLUETOOTH
+ case AF_BLUETOOTH:
+ {
+ switch(s->sock_proto)
+ {
+
+ case BTPROTO_L2CAP:
+ *len_ret = sizeof (struct sockaddr_l2);
+ return 1;
+ case BTPROTO_RFCOMM:
+ *len_ret = sizeof (struct sockaddr_rc);
+ return 1;
+#if !defined(__FreeBSD__)
+ case BTPROTO_SCO:
+ *len_ret = sizeof (struct sockaddr_sco);
+ return 1;
+#endif
+ default:
+ PyErr_SetString(socket_error, "getsockaddrlen: "
+ "unknown BT protocol");
+ return 0;
+
+ }
+ }
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+ case AF_PACKET:
+ {
+ *len_ret = sizeof (struct sockaddr_ll);
+ return 1;
+ }
+#endif
+
+ /* More cases here... */
+
+ default:
+ PyErr_SetString(socket_error, "getsockaddrlen: bad family");
+ return 0;
+
+ }
+}
+
+
+/* s.accept() method */
+
+static PyObject *
+sock_accept(PySocketSockObject *s)
+{
+ sock_addr_t addrbuf;
+ SOCKET_T newfd;
+ socklen_t addrlen;
+ PyObject *sock = NULL;
+ PyObject *addr = NULL;
+ PyObject *res = NULL;
+ int timeout;
+
+ if (!getsockaddrlen(s, &addrlen))
+ return NULL;
+ memset(&addrbuf, 0, addrlen);
+
+#ifdef MS_WINDOWS
+ newfd = INVALID_SOCKET;
+#else
+ newfd = -1;
+#endif
+
+ if (!IS_SELECTABLE(s))
+ return select_error();
+
+ Py_BEGIN_ALLOW_THREADS
+ timeout = internal_select(s, 0);
+ if (!timeout)
+ newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return NULL;
+ }
+
+#ifdef MS_WINDOWS
+ if (newfd == INVALID_SOCKET)
+#else
+ if (newfd < 0)
+#endif
+ return s->errorhandler();
+
+ /* Create the new object with unspecified family,
+ to avoid calls to bind() etc. on it. */
+ sock = (PyObject *) new_sockobject(newfd,
+ s->sock_family,
+ s->sock_type,
+ s->sock_proto);
+
+ if (sock == NULL) {
+ SOCKETCLOSE(newfd);
+ goto finally;
+ }
+ addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
+ addrlen, s->sock_proto);
+ if (addr == NULL)
+ goto finally;
+
+ res = PyTuple_Pack(2, sock, addr);
+
+finally:
+ Py_XDECREF(sock);
+ Py_XDECREF(addr);
+ return res;
+}
+
+PyDoc_STRVAR(accept_doc,
+"accept() -> (socket object, address info)\n\
+\n\
+Wait for an incoming connection. Return a new socket representing the\n\
+connection, and the address of the client. For IP sockets, the address\n\
+info is a pair (hostaddr, port).");
+
+/* s.setblocking(flag) method. Argument:
+ False -- non-blocking mode; same as settimeout(0)
+ True -- blocking mode; same as settimeout(None)
+*/
+
+static PyObject *
+sock_setblocking(PySocketSockObject *s, PyObject *arg)
+{
+ int block;
+
+ block = PyInt_AsLong(arg);
+ if (block == -1 && PyErr_Occurred())
+ return NULL;
+
+ s->sock_timeout = block ? -1.0 : 0.0;
+ internal_setblocking(s, block);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(setblocking_doc,
+"setblocking(flag)\n\
+\n\
+Set the socket to blocking (flag is true) or non-blocking (false).\n\
+setblocking(True) is equivalent to settimeout(None);\n\
+setblocking(False) is equivalent to settimeout(0.0).");
+
+/* s.settimeout(timeout) method. Argument:
+ None -- no timeout, blocking mode; same as setblocking(True)
+ 0.0 -- non-blocking mode; same as setblocking(False)
+ > 0 -- timeout mode; operations time out after timeout seconds
+ < 0 -- illegal; raises an exception
+*/
+static PyObject *
+sock_settimeout(PySocketSockObject *s, PyObject *arg)
+{
+ double timeout;
+
+ if (arg == Py_None)
+ timeout = -1.0;
+ else {
+ timeout = PyFloat_AsDouble(arg);
+ if (timeout < 0.0) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_ValueError,
+ "Timeout value out of range");
+ return NULL;
+ }
+ }
+
+ s->sock_timeout = timeout;
+ internal_setblocking(s, timeout < 0.0);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(settimeout_doc,
+"settimeout(timeout)\n\
+\n\
+Set a timeout on socket operations. 'timeout' can be a float,\n\
+giving in seconds, or None. Setting a timeout of None disables\n\
+the timeout feature and is equivalent to setblocking(1).\n\
+Setting a timeout of zero is the same as setblocking(0).");
+
+/* s.gettimeout() method.
+ Returns the timeout associated with a socket. */
+static PyObject *
+sock_gettimeout(PySocketSockObject *s)
+{
+ if (s->sock_timeout < 0.0) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ return PyFloat_FromDouble(s->sock_timeout);
+}
+
+PyDoc_STRVAR(gettimeout_doc,
+"gettimeout() -> timeout\n\
+\n\
+Returns the timeout in floating seconds associated with socket \n\
+operations. A timeout of None indicates that timeouts on socket \n\
+operations are disabled.");
+
+#ifdef RISCOS
+/* s.sleeptaskw(1 | 0) method */
+
+static PyObject *
+sock_sleeptaskw(PySocketSockObject *s,PyObject *arg)
+{
+ int block;
+ block = PyInt_AsLong(arg);
+ if (block == -1 && PyErr_Occurred())
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
+ Py_END_ALLOW_THREADS
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+PyDoc_STRVAR(sleeptaskw_doc,
+"sleeptaskw(flag)\n\
+\n\
+Allow sleeps in taskwindows.");
+#endif
+
+
+/* s.setsockopt() method.
+ With an integer third argument, sets an integer option.
+ With a string third argument, sets an option from a buffer;
+ use optional built-in module 'struct' to encode the string. */
+
+static PyObject *
+sock_setsockopt(PySocketSockObject *s, PyObject *args)
+{
+ int level;
+ int optname;
+ int res;
+ char *buf;
+ int buflen;
+ int flag;
+
+ if (PyArg_ParseTuple(args, "iii:setsockopt",
+ &level, &optname, &flag)) {
+ buf = (char *) &flag;
+ buflen = sizeof flag;
+ }
+ else {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "iis#:setsockopt",
+ &level, &optname, &buf, &buflen))
+ return NULL;
+ }
+ res = setsockopt(s->sock_fd, level, optname, (void *)buf, buflen);
+ if (res < 0)
+ return s->errorhandler();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(setsockopt_doc,
+"setsockopt(level, option, value)\n\
+\n\
+Set a socket option. See the Unix manual for level and option.\n\
+The value argument can either be an integer or a string.");
+
+
+/* s.getsockopt() method.
+ With two arguments, retrieves an integer option.
+ With a third integer argument, retrieves a string buffer of that size;
+ use optional built-in module 'struct' to decode the string. */
+
+static PyObject *
+sock_getsockopt(PySocketSockObject *s, PyObject *args)
+{
+ int level;
+ int optname;
+ int res;
+ PyObject *buf;
+ socklen_t buflen = 0;
+
+#ifdef __BEOS__
+ /* We have incomplete socket support. */
+ PyErr_SetString(socket_error, "getsockopt not supported");
+ return NULL;
+#else
+
+ if (!PyArg_ParseTuple(args, "ii|i:getsockopt",
+ &level, &optname, &buflen))
+ return NULL;
+
+ if (buflen == 0) {
+ int flag = 0;
+ socklen_t flagsize = sizeof flag;
+ res = getsockopt(s->sock_fd, level, optname,
+ (void *)&flag, &flagsize);
+ if (res < 0)
+ return s->errorhandler();
+ return PyInt_FromLong(flag);
+ }
+#ifdef __VMS
+ /* socklen_t is unsigned so no negative test is needed,
+ test buflen == 0 is previously done */
+ if (buflen > 1024) {
+#else
+ if (buflen <= 0 || buflen > 1024) {
+#endif
+ PyErr_SetString(socket_error,
+ "getsockopt buflen out of range");
+ return NULL;
+ }
+ buf = PyString_FromStringAndSize((char *)NULL, buflen);
+ if (buf == NULL)
+ return NULL;
+ res = getsockopt(s->sock_fd, level, optname,
+ (void *)PyString_AS_STRING(buf), &buflen);
+ if (res < 0) {
+ Py_DECREF(buf);
+ return s->errorhandler();
+ }
+ _PyString_Resize(&buf, buflen);
+ return buf;
+#endif /* __BEOS__ */
+}
+
+PyDoc_STRVAR(getsockopt_doc,
+"getsockopt(level, option[, buffersize]) -> value\n\
+\n\
+Get a socket option. See the Unix manual for level and option.\n\
+If a nonzero buffersize argument is given, the return value is a\n\
+string of that length; otherwise it is an integer.");
+
+
+/* s.bind(sockaddr) method */
+
+static PyObject *
+sock_bind(PySocketSockObject *s, PyObject *addro)
+{
+ sock_addr_t addrbuf;
+ int addrlen;
+ int res;
+
+ if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return s->errorhandler();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(bind_doc,
+"bind(address)\n\
+\n\
+Bind the socket to a local address. For IP sockets, the address is a\n\
+pair (host, port); the host must refer to the local host. For raw packet\n\
+sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])");
+
+
+/* s.close() method.
+ Set the file descriptor to -1 so operations tried subsequently
+ will surely fail. */
+
+static PyObject *
+sock_close(PySocketSockObject *s)
+{
+ SOCKET_T fd;
+
+ if ((fd = s->sock_fd) != -1) {
+ s->sock_fd = -1;
+ Py_BEGIN_ALLOW_THREADS
+ (void) SOCKETCLOSE(fd);
+ Py_END_ALLOW_THREADS
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(close_doc,
+"close()\n\
+\n\
+Close the socket. It cannot be used after this call.");
+
+static int
+internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
+ int *timeoutp)
+{
+ int res, timeout;
+
+ timeout = 0;
+ res = connect(s->sock_fd, addr, addrlen);
+
+#ifdef MS_WINDOWS
+
+ if (s->sock_timeout > 0.0) {
+ if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK &&
+ IS_SELECTABLE(s)) {
+ /* This is a mess. Best solution: trust select */
+ fd_set fds;
+ fd_set fds_exc;
+ struct timeval tv;
+ tv.tv_sec = (int)s->sock_timeout;
+ tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+ FD_ZERO(&fds);
+ FD_SET(s->sock_fd, &fds);
+ FD_ZERO(&fds_exc);
+ FD_SET(s->sock_fd, &fds_exc);
+ res = select(s->sock_fd+1, NULL, &fds, &fds_exc, &tv);
+ if (res == 0) {
+ res = WSAEWOULDBLOCK;
+ timeout = 1;
+ } else if (res > 0) {
+ if (FD_ISSET(s->sock_fd, &fds))
+ /* The socket is in the writeable set - this
+ means connected */
+ res = 0;
+ else {
+ /* As per MS docs, we need to call getsockopt()
+ to get the underlying error */
+ int res_size = sizeof res;
+ /* It must be in the exception set */
+ assert(FD_ISSET(s->sock_fd, &fds_exc));
+ if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
+ (char *)&res, &res_size))
+ /* getsockopt also clears WSAGetLastError,
+ so reset it back. */
+ WSASetLastError(res);
+ else
+ res = WSAGetLastError();
+ }
+ }
+ /* else if (res < 0) an error occurred */
+ }
+ }
+
+ if (res < 0)
+ res = WSAGetLastError();
+
+#else
+
+ if (s->sock_timeout > 0.0) {
+ if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
+ timeout = internal_select(s, 1);
+ if (timeout == 0) {
+ res = connect(s->sock_fd, addr, addrlen);
+ if (res < 0 && errno == EISCONN)
+ res = 0;
+ }
+ else if (timeout == -1)
+ res = errno; /* had error */
+ else
+ res = EWOULDBLOCK; /* timed out */
+ }
+ }
+
+ if (res < 0)
+ res = errno;
+
+#endif
+ *timeoutp = timeout;
+
+ return res;
+}
+
+/* s.connect(sockaddr) method */
+
+static PyObject *
+sock_connect(PySocketSockObject *s, PyObject *addro)
+{
+ sock_addr_t addrbuf;
+ int addrlen;
+ int res;
+ int timeout;
+
+ if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return NULL;
+ }
+ if (res != 0)
+ return s->errorhandler();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(connect_doc,
+"connect(address)\n\
+\n\
+Connect the socket to a remote address. For IP sockets, the address\n\
+is a pair (host, port).");
+
+
+/* s.connect_ex(sockaddr) method */
+
+static PyObject *
+sock_connect_ex(PySocketSockObject *s, PyObject *addro)
+{
+ sock_addr_t addrbuf;
+ int addrlen;
+ int res;
+ int timeout;
+
+ if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
+ Py_END_ALLOW_THREADS
+
+ /* Signals are not errors (though they may raise exceptions). Adapted
+ from PyErr_SetFromErrnoWithFilenameObject(). */
+#ifdef EINTR
+ if (res == EINTR && PyErr_CheckSignals())
+ return NULL;
+#endif
+
+ return PyInt_FromLong((long) res);
+}
+
+PyDoc_STRVAR(connect_ex_doc,
+"connect_ex(address) -> errno\n\
+\n\
+This is like connect(address), but returns an error code (the errno value)\n\
+instead of raising an exception when an error occurs.");
+
+
+/* s.fileno() method */
+
+static PyObject *
+sock_fileno(PySocketSockObject *s)
+{
+#if SIZEOF_SOCKET_T <= SIZEOF_LONG
+ return PyInt_FromLong((long) s->sock_fd);
+#else
+ return PyLong_FromLongLong((PY_LONG_LONG)s->sock_fd);
+#endif
+}
+
+PyDoc_STRVAR(fileno_doc,
+"fileno() -> integer\n\
+\n\
+Return the integer file descriptor of the socket.");
+
+
+#ifndef NO_DUP
+/* s.dup() method */
+
+static PyObject *
+sock_dup(PySocketSockObject *s)
+{
+ SOCKET_T newfd;
+ PyObject *sock;
+
+ newfd = dup(s->sock_fd);
+ if (newfd < 0)
+ return s->errorhandler();
+ sock = (PyObject *) new_sockobject(newfd,
+ s->sock_family,
+ s->sock_type,
+ s->sock_proto);
+ if (sock == NULL)
+ SOCKETCLOSE(newfd);
+ return sock;
+}
+
+PyDoc_STRVAR(dup_doc,
+"dup() -> socket object\n\
+\n\
+Return a new socket object connected to the same system resource.");
+
+#endif
+
+
+/* s.getsockname() method */
+
+static PyObject *
+sock_getsockname(PySocketSockObject *s)
+{
+ sock_addr_t addrbuf;
+ int res;
+ socklen_t addrlen;
+
+ if (!getsockaddrlen(s, &addrlen))
+ return NULL;
+ memset(&addrbuf, 0, addrlen);
+ Py_BEGIN_ALLOW_THREADS
+ res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return s->errorhandler();
+ return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen,
+ s->sock_proto);
+}
+
+PyDoc_STRVAR(getsockname_doc,
+"getsockname() -> address info\n\
+\n\
+Return the address of the local endpoint. For IP sockets, the address\n\
+info is a pair (hostaddr, port).");
+
+
+#ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */
+/* s.getpeername() method */
+
+static PyObject *
+sock_getpeername(PySocketSockObject *s)
+{
+ sock_addr_t addrbuf;
+ int res;
+ socklen_t addrlen;
+
+ if (!getsockaddrlen(s, &addrlen))
+ return NULL;
+ memset(&addrbuf, 0, addrlen);
+ Py_BEGIN_ALLOW_THREADS
+ res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return s->errorhandler();
+ return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen,
+ s->sock_proto);
+}
+
+PyDoc_STRVAR(getpeername_doc,
+"getpeername() -> address info\n\
+\n\
+Return the address of the remote endpoint. For IP sockets, the address\n\
+info is a pair (hostaddr, port).");
+
+#endif /* HAVE_GETPEERNAME */
+
+
+/* s.listen(n) method */
+
+static PyObject *
+sock_listen(PySocketSockObject *s, PyObject *arg)
+{
+ int backlog;
+ int res;
+
+ backlog = PyInt_AsLong(arg);
+ if (backlog == -1 && PyErr_Occurred())
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ if (backlog < 1)
+ backlog = 1;
+ res = listen(s->sock_fd, backlog);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return s->errorhandler();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(listen_doc,
+"listen(backlog)\n\
+\n\
+Enable a server to accept connections. The backlog argument must be at\n\
+least 1; it specifies the number of unaccepted connection that the system\n\
+will allow before refusing new connections.");
+
+
+#ifndef NO_DUP
+/* s.makefile(mode) method.
+ Create a new open file object referring to a dupped version of
+ the socket's file descriptor. (The dup() call is necessary so
+ that the open file and socket objects may be closed independent
+ of each other.)
+ The mode argument specifies 'r' or 'w' passed to fdopen(). */
+
+static PyObject *
+sock_makefile(PySocketSockObject *s, PyObject *args)
+{
+ extern int fclose(FILE *);
+ char *mode = "r";
+ int bufsize = -1;
+#ifdef MS_WIN32
+ Py_intptr_t fd;
+#else
+ int fd;
+#endif
+ FILE *fp;
+ PyObject *f;
+#ifdef __VMS
+ char *mode_r = "r";
+ char *mode_w = "w";
+#endif
+
+ if (!PyArg_ParseTuple(args, "|si:makefile", &mode, &bufsize))
+ return NULL;
+#ifdef __VMS
+ if (strcmp(mode,"rb") == 0) {
+ mode = mode_r;
+ }
+ else {
+ if (strcmp(mode,"wb") == 0) {
+ mode = mode_w;
+ }
+ }
+#endif
+#ifdef MS_WIN32
+ if (((fd = _open_osfhandle(s->sock_fd, _O_BINARY)) < 0) ||
+ ((fd = dup(fd)) < 0) || ((fp = fdopen(fd, mode)) == NULL))
+#else
+ if ((fd = dup(s->sock_fd)) < 0 || (fp = fdopen(fd, mode)) == NULL)
+#endif
+ {
+ if (fd >= 0)
+ SOCKETCLOSE(fd);
+ return s->errorhandler();
+ }
+ f = PyFile_FromFile(fp, "<socket>", mode, fclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+PyDoc_STRVAR(makefile_doc,
+"makefile([mode[, buffersize]]) -> file object\n\
+\n\
+Return a regular file object corresponding to the socket.\n\
+The mode and buffersize arguments are as for the built-in open() function.");
+
+#endif /* NO_DUP */
+
+/*
+ * This is the guts of the recv() and recv_into() methods, which reads into a
+ * char buffer. If you have any inc/def ref to do to the objects that contain
+ * the buffer, do it in the caller. This function returns the number of bytes
+ * succesfully read. If there was an error, it returns -1. Note that it is
+ * also possible that we return a number of bytes smaller than the request
+ * bytes.
+ */
+static ssize_t
+sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
+{
+ ssize_t outlen = -1;
+ int timeout;
+#ifdef __VMS
+ int remaining;
+ char *read_buf;
+#endif
+
+ if (!IS_SELECTABLE(s)) {
+ select_error();
+ return -1;
+ }
+
+#ifndef __VMS
+ Py_BEGIN_ALLOW_THREADS
+ timeout = internal_select(s, 0);
+ if (!timeout)
+ outlen = recv(s->sock_fd, cbuf, len, flags);
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return -1;
+ }
+ if (outlen < 0) {
+ /* Note: the call to errorhandler() ALWAYS indirectly returned
+ NULL, so ignore its return value */
+ s->errorhandler();
+ return -1;
+ }
+#else
+ read_buf = cbuf;
+ remaining = len;
+ while (remaining != 0) {
+ unsigned int segment;
+ int nread = -1;
+
+ segment = remaining /SEGMENT_SIZE;
+ if (segment != 0) {
+ segment = SEGMENT_SIZE;
+ }
+ else {
+ segment = remaining;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ timeout = internal_select(s, 0);
+ if (!timeout)
+ nread = recv(s->sock_fd, read_buf, segment, flags);
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return -1;
+ }
+ if (nread < 0) {
+ s->errorhandler();
+ return -1;
+ }
+ if (nread != remaining) {
+ read_buf += nread;
+ break;
+ }
+
+ remaining -= segment;
+ read_buf += segment;
+ }
+ outlen = read_buf - cbuf;
+#endif /* !__VMS */
+
+ return outlen;
+}
+
+
+/* s.recv(nbytes [,flags]) method */
+
+static PyObject *
+sock_recv(PySocketSockObject *s, PyObject *args)
+{
+ int recvlen, flags = 0;
+ ssize_t outlen;
+ PyObject *buf;
+
+ if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
+ return NULL;
+
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recv");
+ return NULL;
+ }
+
+ /* Allocate a new string. */
+ buf = PyString_FromStringAndSize((char *) 0, recvlen);
+ if (buf == NULL)
+ return NULL;
+
+ /* Call the guts */
+ outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags);
+ if (outlen < 0) {
+ /* An error occurred, release the string and return an
+ error. */
+ Py_DECREF(buf);
+ return NULL;
+ }
+ if (outlen != recvlen) {
+ /* We did not read as many bytes as we anticipated, resize the
+ string if possible and be succesful. */
+ if (_PyString_Resize(&buf, outlen) < 0)
+ /* Oopsy, not so succesful after all. */
+ return NULL;
+ }
+
+ return buf;
+}
+
+PyDoc_STRVAR(recv_doc,
+"recv(buffersize[, flags]) -> data\n\
+\n\
+Receive up to buffersize bytes from the socket. For the optional flags\n\
+argument, see the Unix manual. When no data is available, block until\n\
+at least one byte is available or until the remote end is closed. When\n\
+the remote end is closed and all data is read, return the empty string.");
+
+
+/* s.recv_into(buffer, [nbytes [,flags]]) method */
+
+static PyObject*
+sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
+
+ int recvlen = 0, flags = 0;
+ ssize_t readlen;
+ char *buf;
+ int buflen;
+
+ /* Get the buffer's memory */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv_into", kwlist,
+ &buf, &buflen, &recvlen, &flags))
+ return NULL;
+ assert(buf != 0 && buflen > 0);
+
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recv_into");
+ return NULL;
+ }
+ if (recvlen == 0) {
+ /* If nbytes was not specified, use the buffer's length */
+ recvlen = buflen;
+ }
+
+ /* Check if the buffer is large enough */
+ if (buflen < recvlen) {
+ PyErr_SetString(PyExc_ValueError,
+ "buffer too small for requested bytes");
+ return NULL;
+ }
+
+ /* Call the guts */
+ readlen = sock_recv_guts(s, buf, recvlen, flags);
+ if (readlen < 0) {
+ /* Return an error. */
+ return NULL;
+ }
+
+ /* Return the number of bytes read. Note that we do not do anything
+ special here in the case that readlen < recvlen. */
+ return PyInt_FromSsize_t(readlen);
+}
+
+PyDoc_STRVAR(recv_into_doc,
+"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\
+\n\
+A version of recv() that stores its data into a buffer rather than creating \n\
+a new string. Receive up to buffersize bytes from the socket. If buffersize \n\
+is not specified (or 0), receive up to the size available in the given buffer.\n\
+\n\
+See recv() for documentation about the flags.");
+
+
+/*
+ * This is the guts of the recv() and recv_into() methods, which reads into a
+ * char buffer. If you have any inc/def ref to do to the objects that contain
+ * the buffer, do it in the caller. This function returns the number of bytes
+ * succesfully read. If there was an error, it returns -1. Note that it is
+ * also possible that we return a number of bytes smaller than the request
+ * bytes.
+ *
+ * 'addr' is a return value for the address object. Note that you must decref
+ * it yourself.
+ */
+static ssize_t
+sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
+ PyObject** addr)
+{
+ sock_addr_t addrbuf;
+ int timeout;
+ ssize_t n = -1;
+ socklen_t addrlen;
+
+ *addr = NULL;
+
+ if (!getsockaddrlen(s, &addrlen))
+ return -1;
+
+ if (!IS_SELECTABLE(s)) {
+ select_error();
+ return -1;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ memset(&addrbuf, 0, addrlen);
+ timeout = internal_select(s, 0);
+ if (!timeout) {
+#ifndef MS_WINDOWS
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+ n = recvfrom(s->sock_fd, cbuf, len, flags,
+ SAS2SA(&addrbuf), &addrlen);
+#else
+ n = recvfrom(s->sock_fd, cbuf, len, flags,
+ (void *) &addrbuf, &addrlen);
+#endif
+#else
+ n = recvfrom(s->sock_fd, cbuf, len, flags,
+ SAS2SA(&addrbuf), &addrlen);
+#endif
+ }
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return -1;
+ }
+ if (n < 0) {
+ s->errorhandler();
+ return -1;
+ }
+
+ if (!(*addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
+ addrlen, s->sock_proto)))
+ return -1;
+
+ return n;
+}
+
+/* s.recvfrom(nbytes [,flags]) method */
+
+static PyObject *
+sock_recvfrom(PySocketSockObject *s, PyObject *args)
+{
+ PyObject *buf = NULL;
+ PyObject *addr = NULL;
+ PyObject *ret = NULL;
+ int recvlen, flags = 0;
+ ssize_t outlen;
+
+ if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
+ return NULL;
+
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recvfrom");
+ return NULL;
+ }
+
+ buf = PyString_FromStringAndSize((char *) 0, recvlen);
+ if (buf == NULL)
+ return NULL;
+
+ outlen = sock_recvfrom_guts(s, PyString_AS_STRING(buf),
+ recvlen, flags, &addr);
+ if (outlen < 0) {
+ goto finally;
+ }
+
+ if (outlen != recvlen) {
+ /* We did not read as many bytes as we anticipated, resize the
+ string if possible and be succesful. */
+ if (_PyString_Resize(&buf, outlen) < 0)
+ /* Oopsy, not so succesful after all. */
+ goto finally;
+ }
+
+ ret = PyTuple_Pack(2, buf, addr);
+
+finally:
+ Py_XDECREF(buf);
+ Py_XDECREF(addr);
+ return ret;
+}
+
+PyDoc_STRVAR(recvfrom_doc,
+"recvfrom(buffersize[, flags]) -> (data, address info)\n\
+\n\
+Like recv(buffersize, flags) but also return the sender's address info.");
+
+
+/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */
+
+static PyObject *
+sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
+{
+ static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
+
+ int recvlen = 0, flags = 0;
+ ssize_t readlen;
+ char *buf;
+ int buflen;
+
+ PyObject *addr = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom_into",
+ kwlist, &buf, &buflen,
+ &recvlen, &flags))
+ return NULL;
+ assert(buf != 0 && buflen > 0);
+
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recvfrom_into");
+ return NULL;
+ }
+ if (recvlen == 0) {
+ /* If nbytes was not specified, use the buffer's length */
+ recvlen = buflen;
+ }
+
+ readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
+ if (readlen < 0) {
+ /* Return an error */
+ Py_XDECREF(addr);
+ return NULL;
+ }
+
+ /* Return the number of bytes read and the address. Note that we do
+ not do anything special here in the case that readlen < recvlen. */
+ return Py_BuildValue("lN", readlen, addr);
+}
+
+PyDoc_STRVAR(recvfrom_into_doc,
+"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
+\n\
+Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.");
+
+
+/* s.send(data [,flags]) method */
+
+static PyObject *
+sock_send(PySocketSockObject *s, PyObject *args)
+{
+ char *buf;
+ int len, n = -1, flags = 0, timeout;
+
+ if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
+ return NULL;
+
+ if (!IS_SELECTABLE(s))
+ return select_error();
+
+ Py_BEGIN_ALLOW_THREADS
+ timeout = internal_select(s, 1);
+ if (!timeout)
+#ifdef __VMS
+ n = sendsegmented(s->sock_fd, buf, len, flags);
+#else
+ n = send(s->sock_fd, buf, len, flags);
+#endif
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return NULL;
+ }
+ if (n < 0)
+ return s->errorhandler();
+ return PyInt_FromLong((long)n);
+}
+
+PyDoc_STRVAR(send_doc,
+"send(data[, flags]) -> count\n\
+\n\
+Send a data string to the socket. For the optional flags\n\
+argument, see the Unix manual. Return the number of bytes\n\
+sent; this may be less than len(data) if the network is busy.");
+
+
+/* s.sendall(data [,flags]) method */
+
+static PyObject *
+sock_sendall(PySocketSockObject *s, PyObject *args)
+{
+ char *buf;
+ int len, n = -1, flags = 0, timeout;
+
+ if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags))
+ return NULL;
+
+ if (!IS_SELECTABLE(s))
+ return select_error();
+
+ Py_BEGIN_ALLOW_THREADS
+ do {
+ timeout = internal_select(s, 1);
+ n = -1;
+ if (timeout)
+ break;
+#ifdef __VMS
+ n = sendsegmented(s->sock_fd, buf, len, flags);
+#else
+ n = send(s->sock_fd, buf, len, flags);
+#endif
+ if (n < 0)
+ break;
+ buf += n;
+ len -= n;
+ } while (len > 0);
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return NULL;
+ }
+ if (n < 0)
+ return s->errorhandler();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(sendall_doc,
+"sendall(data[, flags])\n\
+\n\
+Send a data string to the socket. For the optional flags\n\
+argument, see the Unix manual. This calls send() repeatedly\n\
+until all data is sent. If an error occurs, it's impossible\n\
+to tell how much data has been sent.");
+
+
+/* s.sendto(data, [flags,] sockaddr) method */
+
+static PyObject *
+sock_sendto(PySocketSockObject *s, PyObject *args)
+{
+ PyObject *addro;
+ char *buf;
+ sock_addr_t addrbuf;
+ int addrlen, len, n = -1, flags, timeout;
+
+ flags = 0;
+ if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "s#iO:sendto",
+ &buf, &len, &flags, &addro))
+ return NULL;
+ }
+
+ if (!IS_SELECTABLE(s))
+ return select_error();
+
+ if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ timeout = internal_select(s, 1);
+ if (!timeout)
+ n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
+ Py_END_ALLOW_THREADS
+
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return NULL;
+ }
+ if (n < 0)
+ return s->errorhandler();
+ return PyInt_FromLong((long)n);
+}
+
+PyDoc_STRVAR(sendto_doc,
+"sendto(data[, flags], address) -> count\n\
+\n\
+Like send(data, flags) but allows specifying the destination address.\n\
+For IP sockets, the address is a pair (hostaddr, port).");
+
+
+/* s.shutdown(how) method */
+
+static PyObject *
+sock_shutdown(PySocketSockObject *s, PyObject *arg)
+{
+ int how;
+ int res;
+
+ how = PyInt_AsLong(arg);
+ if (how == -1 && PyErr_Occurred())
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = shutdown(s->sock_fd, how);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return s->errorhandler();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(shutdown_doc,
+"shutdown(flag)\n\
+\n\
+Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\
+of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
+
+
+/* List of methods for socket objects */
+
+static PyMethodDef sock_methods[] = {
+ {"accept", (PyCFunction)sock_accept, METH_NOARGS,
+ accept_doc},
+ {"bind", (PyCFunction)sock_bind, METH_O,
+ bind_doc},
+ {"close", (PyCFunction)sock_close, METH_NOARGS,
+ close_doc},
+ {"connect", (PyCFunction)sock_connect, METH_O,
+ connect_doc},
+ {"connect_ex", (PyCFunction)sock_connect_ex, METH_O,
+ connect_ex_doc},
+#ifndef NO_DUP
+ {"dup", (PyCFunction)sock_dup, METH_NOARGS,
+ dup_doc},
+#endif
+ {"fileno", (PyCFunction)sock_fileno, METH_NOARGS,
+ fileno_doc},
+#ifdef HAVE_GETPEERNAME
+ {"getpeername", (PyCFunction)sock_getpeername,
+ METH_NOARGS, getpeername_doc},
+#endif
+ {"getsockname", (PyCFunction)sock_getsockname,
+ METH_NOARGS, getsockname_doc},
+ {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS,
+ getsockopt_doc},
+ {"listen", (PyCFunction)sock_listen, METH_O,
+ listen_doc},
+#ifndef NO_DUP
+ {"makefile", (PyCFunction)sock_makefile, METH_VARARGS,
+ makefile_doc},
+#endif
+ {"recv", (PyCFunction)sock_recv, METH_VARARGS,
+ recv_doc},
+ {"recv_into", (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS,
+ recv_into_doc},
+ {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS,
+ recvfrom_doc},
+ {"recvfrom_into", (PyCFunction)sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS,
+ recvfrom_into_doc},
+ {"send", (PyCFunction)sock_send, METH_VARARGS,
+ send_doc},
+ {"sendall", (PyCFunction)sock_sendall, METH_VARARGS,
+ sendall_doc},
+ {"sendto", (PyCFunction)sock_sendto, METH_VARARGS,
+ sendto_doc},
+ {"setblocking", (PyCFunction)sock_setblocking, METH_O,
+ setblocking_doc},
+ {"settimeout", (PyCFunction)sock_settimeout, METH_O,
+ settimeout_doc},
+ {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS,
+ gettimeout_doc},
+ {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS,
+ setsockopt_doc},
+ {"shutdown", (PyCFunction)sock_shutdown, METH_O,
+ shutdown_doc},
+#ifdef RISCOS
+ {"sleeptaskw", (PyCFunction)sock_sleeptaskw, METH_O,
+ sleeptaskw_doc},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+/* SockObject members */
+static PyMemberDef sock_memberlist[] = {
+ {"family", T_INT, offsetof(PySocketSockObject, sock_family), READONLY, "the socket family"},
+ {"type", T_INT, offsetof(PySocketSockObject, sock_type), READONLY, "the socket type"},
+ {"proto", T_INT, offsetof(PySocketSockObject, sock_proto), READONLY, "the socket protocol"},
+ {"timeout", T_DOUBLE, offsetof(PySocketSockObject, sock_timeout), READONLY, "the socket timeout"},
+ {0},
+};
+
+/* Deallocate a socket object in response to the last Py_DECREF().
+ First close the file description. */
+
+static void
+sock_dealloc(PySocketSockObject *s)
+{
+ if (s->sock_fd != -1)
+ (void) SOCKETCLOSE(s->sock_fd);
+ s->ob_type->tp_free((PyObject *)s);
+}
+
+
+static PyObject *
+sock_repr(PySocketSockObject *s)
+{
+ char buf[512];
+#if SIZEOF_SOCKET_T > SIZEOF_LONG
+ if (s->sock_fd > LONG_MAX) {
+ /* this can occur on Win64, and actually there is a special
+ ugly printf formatter for decimal pointer length integer
+ printing, only bother if necessary*/
+ PyErr_SetString(PyExc_OverflowError,
+ "no printf formatter to display "
+ "the socket descriptor in decimal");
+ return NULL;
+ }
+#endif
+ PyOS_snprintf(
+ buf, sizeof(buf),
+ "<socket object, fd=%ld, family=%d, type=%d, protocol=%d>",
+ (long)s->sock_fd, s->sock_family,
+ s->sock_type,
+ s->sock_proto);
+ return PyString_FromString(buf);
+}
+
+
+/* Create a new, uninitialized socket object. */
+
+static PyObject *
+sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *new;
+
+ new = type->tp_alloc(type, 0);
+ if (new != NULL) {
+ ((PySocketSockObject *)new)->sock_fd = -1;
+ ((PySocketSockObject *)new)->sock_timeout = -1.0;
+ ((PySocketSockObject *)new)->errorhandler = &set_error;
+ }
+ return new;
+}
+
+
+/* Initialize a new socket object. */
+
+/*ARGSUSED*/
+static int
+sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PySocketSockObject *s = (PySocketSockObject *)self;
+ SOCKET_T fd;
+ int family = AF_INET, type = SOCK_STREAM, proto = 0;
+ static char *keywords[] = {"family", "type", "proto", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "|iii:socket", keywords,
+ &family, &type, &proto))
+ return -1;
+
+ Py_BEGIN_ALLOW_THREADS
+ fd = socket(family, type, proto);
+ Py_END_ALLOW_THREADS
+
+#ifdef MS_WINDOWS
+ if (fd == INVALID_SOCKET)
+#else
+ if (fd < 0)
+#endif
+ {
+ set_error();
+ return -1;
+ }
+ init_sockobject(s, fd, family, type, proto);
+
+ return 0;
+
+}
+
+
+/* Type object for socket objects. */
+
+static PyTypeObject sock_type = {
+ PyObject_HEAD_INIT(0) /* Must fill in type value later */
+ 0, /* ob_size */
+ "_socket.socket", /* tp_name */
+ sizeof(PySocketSockObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)sock_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)sock_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ sock_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ sock_methods, /* tp_methods */
+ sock_memberlist, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ sock_initobj, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ sock_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+
+/* Python interface to gethostname(). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostname(PyObject *self, PyObject *unused)
+{
+ char buf[1024];
+ int res;
+ Py_BEGIN_ALLOW_THREADS
+ res = gethostname(buf, (int) sizeof buf - 1);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return set_error();
+ buf[sizeof buf - 1] = '\0';
+ return PyString_FromString(buf);
+}
+
+PyDoc_STRVAR(gethostname_doc,
+"gethostname() -> string\n\
+\n\
+Return the current host name.");
+
+
+/* Python interface to gethostbyname(name). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostbyname(PyObject *self, PyObject *args)
+{
+ char *name;
+ sock_addr_t addrbuf;
+
+ if (!PyArg_ParseTuple(args, "s:gethostbyname", &name))
+ return NULL;
+ if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0)
+ return NULL;
+ return makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
+}
+
+PyDoc_STRVAR(gethostbyname_doc,
+"gethostbyname(host) -> address\n\
+\n\
+Return the IP address (a string of the form '255.255.255.255') for a host.");
+
+
+/* Convenience function common to gethostbyname_ex and gethostbyaddr */
+
+static PyObject *
+gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af)
+{
+ char **pch;
+ PyObject *rtn_tuple = (PyObject *)NULL;
+ PyObject *name_list = (PyObject *)NULL;
+ PyObject *addr_list = (PyObject *)NULL;
+ PyObject *tmp;
+
+ if (h == NULL) {
+ /* Let's get real error message to return */
+#ifndef RISCOS
+ set_herror(h_errno);
+#else
+ PyErr_SetString(socket_error, "host not found");
+#endif
+ return NULL;
+ }
+
+ if (h->h_addrtype != af) {
+#ifdef HAVE_STRERROR
+ /* Let's get real error message to return */
+ PyErr_SetString(socket_error,
+ (char *)strerror(EAFNOSUPPORT));
+#else
+ PyErr_SetString(
+ socket_error,
+ "Address family not supported by protocol family");
+#endif
+ return NULL;
+ }
+
+ switch (af) {
+
+ case AF_INET:
+ if (alen < sizeof(struct sockaddr_in))
+ return NULL;
+ break;
+
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ if (alen < sizeof(struct sockaddr_in6))
+ return NULL;
+ break;
+#endif
+
+ }
+
+ if ((name_list = PyList_New(0)) == NULL)
+ goto err;
+
+ if ((addr_list = PyList_New(0)) == NULL)
+ goto err;
+
+ /* SF #1511317: h_aliases can be NULL */
+ if (h->h_aliases) {
+ for (pch = h->h_aliases; *pch != NULL; pch++) {
+ int status;
+ tmp = PyString_FromString(*pch);
+ if (tmp == NULL)
+ goto err;
+
+ status = PyList_Append(name_list, tmp);
+ Py_DECREF(tmp);
+
+ if (status)
+ goto err;
+ }
+ }
+
+ for (pch = h->h_addr_list; *pch != NULL; pch++) {
+ int status;
+
+ switch (af) {
+
+ case AF_INET:
+ {
+ struct sockaddr_in sin;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = af;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin.sin_len = sizeof(sin);
+#endif
+ memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr));
+ tmp = makeipaddr((struct sockaddr *)&sin, sizeof(sin));
+
+ if (pch == h->h_addr_list && alen >= sizeof(sin))
+ memcpy((char *) addr, &sin, sizeof(sin));
+ break;
+ }
+
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 sin6;
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = af;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin6.sin6_len = sizeof(sin6);
+#endif
+ memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr));
+ tmp = makeipaddr((struct sockaddr *)&sin6,
+ sizeof(sin6));
+
+ if (pch == h->h_addr_list && alen >= sizeof(sin6))
+ memcpy((char *) addr, &sin6, sizeof(sin6));
+ break;
+ }
+#endif
+
+ default: /* can't happen */
+ PyErr_SetString(socket_error,
+ "unsupported address family");
+ return NULL;
+ }
+
+ if (tmp == NULL)
+ goto err;
+
+ status = PyList_Append(addr_list, tmp);
+ Py_DECREF(tmp);
+
+ if (status)
+ goto err;
+ }
+
+ rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
+
+ err:
+ Py_XDECREF(name_list);
+ Py_XDECREF(addr_list);
+ return rtn_tuple;
+}
+
+
+/* Python interface to gethostbyname_ex(name). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostbyname_ex(PyObject *self, PyObject *args)
+{
+ char *name;
+ struct hostent *h;
+#ifdef ENABLE_IPV6
+ struct sockaddr_storage addr;
+#else
+ struct sockaddr_in addr;
+#endif
+ struct sockaddr *sa;
+ PyObject *ret;
+#ifdef HAVE_GETHOSTBYNAME_R
+ struct hostent hp_allocated;
+#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
+ struct hostent_data data;
+#else
+ char buf[16384];
+ int buf_len = (sizeof buf) - 1;
+ int errnop;
+#endif
+#if defined(HAVE_GETHOSTBYNAME_R_3_ARG) || defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+ int result;
+#endif
+#endif /* HAVE_GETHOSTBYNAME_R */
+
+ if (!PyArg_ParseTuple(args, "s:gethostbyname_ex", &name))
+ return NULL;
+ if (setipaddr(name, (struct sockaddr *)&addr, sizeof(addr), AF_INET) < 0)
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+#ifdef HAVE_GETHOSTBYNAME_R
+#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+ result = gethostbyname_r(name, &hp_allocated, buf, buf_len,
+ &h, &errnop);
+#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
+ h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop);
+#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
+ memset((void *) &data, '\0', sizeof(data));
+ result = gethostbyname_r(name, &hp_allocated, &data);
+ h = (result != 0) ? NULL : &hp_allocated;
+#endif
+#else /* not HAVE_GETHOSTBYNAME_R */
+#ifdef USE_GETHOSTBYNAME_LOCK
+ PyThread_acquire_lock(netdb_lock, 1);
+#endif
+ h = gethostbyname(name);
+#endif /* HAVE_GETHOSTBYNAME_R */
+ Py_END_ALLOW_THREADS
+ /* Some C libraries would require addr.__ss_family instead of
+ addr.ss_family.
+ Therefore, we cast the sockaddr_storage into sockaddr to
+ access sa_family. */
+ sa = (struct sockaddr*)&addr;
+ ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr),
+ sa->sa_family);
+#ifdef USE_GETHOSTBYNAME_LOCK
+ PyThread_release_lock(netdb_lock);
+#endif
+ return ret;
+}
+
+PyDoc_STRVAR(ghbn_ex_doc,
+"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\
+\n\
+Return the true host name, a list of aliases, and a list of IP addresses,\n\
+for a host. The host argument is a string giving a host name or IP number.");
+
+
+/* Python interface to gethostbyaddr(IP). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_gethostbyaddr(PyObject *self, PyObject *args)
+{
+#ifdef ENABLE_IPV6
+ struct sockaddr_storage addr;
+#else
+ struct sockaddr_in addr;
+#endif
+ struct sockaddr *sa = (struct sockaddr *)&addr;
+ char *ip_num;
+ struct hostent *h;
+ PyObject *ret;
+#ifdef HAVE_GETHOSTBYNAME_R
+ struct hostent hp_allocated;
+#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
+ struct hostent_data data;
+#else
+ char buf[16384];
+ int buf_len = (sizeof buf) - 1;
+ int errnop;
+#endif
+#if defined(HAVE_GETHOSTBYNAME_R_3_ARG) || defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+ int result;
+#endif
+#endif /* HAVE_GETHOSTBYNAME_R */
+ char *ap;
+ int al;
+ int af;
+
+ if (!PyArg_ParseTuple(args, "s:gethostbyaddr", &ip_num))
+ return NULL;
+ af = AF_UNSPEC;
+ if (setipaddr(ip_num, sa, sizeof(addr), af) < 0)
+ return NULL;
+ af = sa->sa_family;
+ ap = NULL;
+ al = 0;
+ switch (af) {
+ case AF_INET:
+ ap = (char *)&((struct sockaddr_in *)sa)->sin_addr;
+ al = sizeof(((struct sockaddr_in *)sa)->sin_addr);
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ ap = (char *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+ al = sizeof(((struct sockaddr_in6 *)sa)->sin6_addr);
+ break;
+#endif
+ default:
+ PyErr_SetString(socket_error, "unsupported address family");
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+#ifdef HAVE_GETHOSTBYNAME_R
+#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
+ result = gethostbyaddr_r(ap, al, af,
+ &hp_allocated, buf, buf_len,
+ &h, &errnop);
+#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
+ h = gethostbyaddr_r(ap, al, af,
+ &hp_allocated, buf, buf_len, &errnop);
+#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
+ memset((void *) &data, '\0', sizeof(data));
+ result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data);
+ h = (result != 0) ? NULL : &hp_allocated;
+#endif
+#else /* not HAVE_GETHOSTBYNAME_R */
+#ifdef USE_GETHOSTBYNAME_LOCK
+ PyThread_acquire_lock(netdb_lock, 1);
+#endif
+ h = gethostbyaddr(ap, al, af);
+#endif /* HAVE_GETHOSTBYNAME_R */
+ Py_END_ALLOW_THREADS
+ ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr), af);
+#ifdef USE_GETHOSTBYNAME_LOCK
+ PyThread_release_lock(netdb_lock);
+#endif
+ return ret;
+}
+
+PyDoc_STRVAR(gethostbyaddr_doc,
+"gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\
+\n\
+Return the true host name, a list of aliases, and a list of IP addresses,\n\
+for a host. The host argument is a string giving a host name or IP number.");
+
+
+/* Python interface to getservbyname(name).
+ This only returns the port number, since the other info is already
+ known or not useful (like the list of aliases). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getservbyname(PyObject *self, PyObject *args)
+{
+ char *name, *proto=NULL;
+ struct servent *sp;
+ if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ sp = getservbyname(name, proto);
+ Py_END_ALLOW_THREADS
+ if (sp == NULL) {
+ PyErr_SetString(socket_error, "service/proto not found");
+ return NULL;
+ }
+ return PyInt_FromLong((long) ntohs(sp->s_port));
+}
+
+PyDoc_STRVAR(getservbyname_doc,
+"getservbyname(servicename[, protocolname]) -> integer\n\
+\n\
+Return a port number from a service name and protocol name.\n\
+The optional protocol name, if given, should be 'tcp' or 'udp',\n\
+otherwise any protocol will match.");
+
+
+/* Python interface to getservbyport(port).
+ This only returns the service name, since the other info is already
+ known or not useful (like the list of aliases). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getservbyport(PyObject *self, PyObject *args)
+{
+ unsigned short port;
+ char *proto=NULL;
+ struct servent *sp;
+ if (!PyArg_ParseTuple(args, "H|s:getservbyport", &port, &proto))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ sp = getservbyport(htons(port), proto);
+ Py_END_ALLOW_THREADS
+ if (sp == NULL) {
+ PyErr_SetString(socket_error, "port/proto not found");
+ return NULL;
+ }
+ return PyString_FromString(sp->s_name);
+}
+
+PyDoc_STRVAR(getservbyport_doc,
+"getservbyport(port[, protocolname]) -> string\n\
+\n\
+Return the service name from a port number and protocol name.\n\
+The optional protocol name, if given, should be 'tcp' or 'udp',\n\
+otherwise any protocol will match.");
+
+/* Python interface to getprotobyname(name).
+ This only returns the protocol number, since the other info is
+ already known or not useful (like the list of aliases). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getprotobyname(PyObject *self, PyObject *args)
+{
+ char *name;
+ struct protoent *sp;
+#ifdef __BEOS__
+/* Not available in BeOS yet. - [cjh] */
+ PyErr_SetString(socket_error, "getprotobyname not supported");
+ return NULL;
+#else
+ if (!PyArg_ParseTuple(args, "s:getprotobyname", &name))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ sp = getprotobyname(name);
+ Py_END_ALLOW_THREADS
+ if (sp == NULL) {
+ PyErr_SetString(socket_error, "protocol not found");
+ return NULL;
+ }
+ return PyInt_FromLong((long) sp->p_proto);
+#endif
+}
+
+PyDoc_STRVAR(getprotobyname_doc,
+"getprotobyname(name) -> integer\n\
+\n\
+Return the protocol number for the named protocol. (Rarely used.)");
+
+
+#ifdef HAVE_SOCKETPAIR
+/* Create a pair of sockets using the socketpair() function.
+ Arguments as for socket() except the default family is AF_UNIX if
+ defined on the platform; otherwise, the default is AF_INET. */
+
+/*ARGSUSED*/
+static PyObject *
+socket_socketpair(PyObject *self, PyObject *args)
+{
+ PySocketSockObject *s0 = NULL, *s1 = NULL;
+ SOCKET_T sv[2];
+ int family, type = SOCK_STREAM, proto = 0;
+ PyObject *res = NULL;
+
+#if defined(AF_UNIX)
+ family = AF_UNIX;
+#else
+ family = AF_INET;
+#endif
+ if (!PyArg_ParseTuple(args, "|iii:socketpair",
+ &family, &type, &proto))
+ return NULL;
+ /* Create a pair of socket fds */
+ if (socketpair(family, type, proto, sv) < 0)
+ return set_error();
+ s0 = new_sockobject(sv[0], family, type, proto);
+ if (s0 == NULL)
+ goto finally;
+ s1 = new_sockobject(sv[1], family, type, proto);
+ if (s1 == NULL)
+ goto finally;
+ res = PyTuple_Pack(2, s0, s1);
+
+finally:
+ if (res == NULL) {
+ if (s0 == NULL)
+ SOCKETCLOSE(sv[0]);
+ if (s1 == NULL)
+ SOCKETCLOSE(sv[1]);
+ }
+ Py_XDECREF(s0);
+ Py_XDECREF(s1);
+ return res;
+}
+
+PyDoc_STRVAR(socketpair_doc,
+"socketpair([family[, type[, proto]]]) -> (socket object, socket object)\n\
+\n\
+Create a pair of socket objects from the sockets returned by the platform\n\
+socketpair() function.\n\
+The arguments are the same as for socket() except the default family is\n\
+AF_UNIX if defined on the platform; otherwise, the default is AF_INET.");
+
+#endif /* HAVE_SOCKETPAIR */
+
+
+#ifndef NO_DUP
+/* Create a socket object from a numeric file description.
+ Useful e.g. if stdin is a socket.
+ Additional arguments as for socket(). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_fromfd(PyObject *self, PyObject *args)
+{
+ PySocketSockObject *s;
+ SOCKET_T fd;
+ int family, type, proto = 0;
+ if (!PyArg_ParseTuple(args, "iii|i:fromfd",
+ &fd, &family, &type, &proto))
+ return NULL;
+ /* Dup the fd so it and the socket can be closed independently */
+ fd = dup(fd);
+ if (fd < 0)
+ return set_error();
+ s = new_sockobject(fd, family, type, proto);
+ return (PyObject *) s;
+}
+
+PyDoc_STRVAR(fromfd_doc,
+"fromfd(fd, family, type[, proto]) -> socket object\n\
+\n\
+Create a socket object from a duplicate of the given\n\
+file descriptor.\n\
+The remaining arguments are the same as for socket().");
+
+#endif /* NO_DUP */
+
+
+static PyObject *
+socket_ntohs(PyObject *self, PyObject *args)
+{
+ int x1, x2;
+
+ if (!PyArg_ParseTuple(args, "i:ntohs", &x1)) {
+ return NULL;
+ }
+ x2 = (int)ntohs((short)x1);
+ return PyInt_FromLong(x2);
+}
+
+PyDoc_STRVAR(ntohs_doc,
+"ntohs(integer) -> integer\n\
+\n\
+Convert a 16-bit integer from network to host byte order.");
+
+
+static PyObject *
+socket_ntohl(PyObject *self, PyObject *arg)
+{
+ unsigned long x;
+
+ if (PyInt_Check(arg)) {
+ x = PyInt_AS_LONG(arg);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return NULL;
+ }
+ else if (PyLong_Check(arg)) {
+ x = PyLong_AsUnsignedLong(arg);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return NULL;
+#if SIZEOF_LONG > 4
+ {
+ unsigned long y;
+ /* only want the trailing 32 bits */
+ y = x & 0xFFFFFFFFUL;
+ if (y ^ x)
+ return PyErr_Format(PyExc_OverflowError,
+ "long int larger than 32 bits");
+ x = y;
+ }
+#endif
+ }
+ else
+ return PyErr_Format(PyExc_TypeError,
+ "expected int/long, %s found",
+ arg->ob_type->tp_name);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return NULL;
+ return PyInt_FromLong(ntohl(x));
+}
+
+PyDoc_STRVAR(ntohl_doc,
+"ntohl(integer) -> integer\n\
+\n\
+Convert a 32-bit integer from network to host byte order.");
+
+
+static PyObject *
+socket_htons(PyObject *self, PyObject *args)
+{
+ int x1, x2;
+
+ if (!PyArg_ParseTuple(args, "i:htons", &x1)) {
+ return NULL;
+ }
+ x2 = (int)htons((short)x1);
+ return PyInt_FromLong(x2);
+}
+
+PyDoc_STRVAR(htons_doc,
+"htons(integer) -> integer\n\
+\n\
+Convert a 16-bit integer from host to network byte order.");
+
+
+static PyObject *
+socket_htonl(PyObject *self, PyObject *arg)
+{
+ unsigned long x;
+
+ if (PyInt_Check(arg)) {
+ x = PyInt_AS_LONG(arg);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return NULL;
+ }
+ else if (PyLong_Check(arg)) {
+ x = PyLong_AsUnsignedLong(arg);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return NULL;
+#if SIZEOF_LONG > 4
+ {
+ unsigned long y;
+ /* only want the trailing 32 bits */
+ y = x & 0xFFFFFFFFUL;
+ if (y ^ x)
+ return PyErr_Format(PyExc_OverflowError,
+ "long int larger than 32 bits");
+ x = y;
+ }
+#endif
+ }
+ else
+ return PyErr_Format(PyExc_TypeError,
+ "expected int/long, %s found",
+ arg->ob_type->tp_name);
+ return PyInt_FromLong(htonl(x));
+}
+
+PyDoc_STRVAR(htonl_doc,
+"htonl(integer) -> integer\n\
+\n\
+Convert a 32-bit integer from host to network byte order.");
+
+/* socket.inet_aton() and socket.inet_ntoa() functions. */
+
+PyDoc_STRVAR(inet_aton_doc,
+"inet_aton(string) -> packed 32-bit IP representation\n\
+\n\
+Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\
+binary format used in low-level network functions.");
+
+static PyObject*
+socket_inet_aton(PyObject *self, PyObject *args)
+{
+#ifndef INADDR_NONE
+#define INADDR_NONE (-1)
+#endif
+#ifdef HAVE_INET_ATON
+ struct in_addr buf;
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK)
+ /* Have to use inet_addr() instead */
+ unsigned long packed_addr;
+#endif
+ char *ip_addr;
+
+ if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr))
+ return NULL;
+
+
+#ifdef HAVE_INET_ATON
+
+#ifdef USE_INET_ATON_WEAKLINK
+ if (inet_aton != NULL) {
+#endif
+ if (inet_aton(ip_addr, &buf))
+ return PyString_FromStringAndSize((char *)(&buf),
+ sizeof(buf));
+
+ PyErr_SetString(socket_error,
+ "illegal IP address string passed to inet_aton");
+ return NULL;
+
+#ifdef USE_INET_ATON_WEAKLINK
+ } else {
+#endif
+
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK)
+
+ /* special-case this address as inet_addr might return INADDR_NONE
+ * for this */
+ if (strcmp(ip_addr, "255.255.255.255") == 0) {
+ packed_addr = 0xFFFFFFFF;
+ } else {
+
+ packed_addr = inet_addr(ip_addr);
+
+ if (packed_addr == INADDR_NONE) { /* invalid address */
+ PyErr_SetString(socket_error,
+ "illegal IP address string passed to inet_aton");
+ return NULL;
+ }
+ }
+ return PyString_FromStringAndSize((char *) &packed_addr,
+ sizeof(packed_addr));
+
+#ifdef USE_INET_ATON_WEAKLINK
+ }
+#endif
+
+#endif
+}
+
+PyDoc_STRVAR(inet_ntoa_doc,
+"inet_ntoa(packed_ip) -> ip_address_string\n\
+\n\
+Convert an IP address from 32-bit packed binary format to string format");
+
+static PyObject*
+socket_inet_ntoa(PyObject *self, PyObject *args)
+{
+ char *packed_str;
+ int addr_len;
+ struct in_addr packed_addr;
+
+ if (!PyArg_ParseTuple(args, "s#:inet_ntoa", &packed_str, &addr_len)) {
+ return NULL;
+ }
+
+ if (addr_len != sizeof(packed_addr)) {
+ PyErr_SetString(socket_error,
+ "packed IP wrong length for inet_ntoa");
+ return NULL;
+ }
+
+ memcpy(&packed_addr, packed_str, addr_len);
+
+ return PyString_FromString(inet_ntoa(packed_addr));
+}
+
+#ifdef HAVE_INET_PTON
+
+PyDoc_STRVAR(inet_pton_doc,
+"inet_pton(af, ip) -> packed IP address string\n\
+\n\
+Convert an IP address from string format to a packed string suitable\n\
+for use with low-level network functions.");
+
+static PyObject *
+socket_inet_pton(PyObject *self, PyObject *args)
+{
+ int af;
+ char* ip;
+ int retval;
+#ifdef ENABLE_IPV6
+ char packed[MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
+#else
+ char packed[sizeof(struct in_addr)];
+#endif
+ if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) {
+ return NULL;
+ }
+
+#if !defined(ENABLE_IPV6) && defined(AF_INET6)
+ if(af == AF_INET6) {
+ PyErr_SetString(socket_error,
+ "can't use AF_INET6, IPv6 is disabled");
+ return NULL;
+ }
+#endif
+
+ retval = inet_pton(af, ip, packed);
+ if (retval < 0) {
+ PyErr_SetFromErrno(socket_error);
+ return NULL;
+ } else if (retval == 0) {
+ PyErr_SetString(socket_error,
+ "illegal IP address string passed to inet_pton");
+ return NULL;
+ } else if (af == AF_INET) {
+ return PyString_FromStringAndSize(packed,
+ sizeof(struct in_addr));
+#ifdef ENABLE_IPV6
+ } else if (af == AF_INET6) {
+ return PyString_FromStringAndSize(packed,
+ sizeof(struct in6_addr));
+#endif
+ } else {
+ PyErr_SetString(socket_error, "unknown address family");
+ return NULL;
+ }
+}
+
+PyDoc_STRVAR(inet_ntop_doc,
+"inet_ntop(af, packed_ip) -> string formatted IP address\n\
+\n\
+Convert a packed IP address of the given family to string format.");
+
+static PyObject *
+socket_inet_ntop(PyObject *self, PyObject *args)
+{
+ int af;
+ char* packed;
+ int len;
+ const char* retval;
+#ifdef ENABLE_IPV6
+ char ip[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
+#else
+ char ip[INET_ADDRSTRLEN + 1];
+#endif
+
+ /* Guarantee NUL-termination for PyString_FromString() below */
+ memset((void *) &ip[0], '\0', sizeof(ip));
+
+ if (!PyArg_ParseTuple(args, "is#:inet_ntop", &af, &packed, &len)) {
+ return NULL;
+ }
+
+ if (af == AF_INET) {
+ if (len != sizeof(struct in_addr)) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid length of packed IP address string");
+ return NULL;
+ }
+#ifdef ENABLE_IPV6
+ } else if (af == AF_INET6) {
+ if (len != sizeof(struct in6_addr)) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid length of packed IP address string");
+ return NULL;
+ }
+#endif
+ } else {
+ PyErr_Format(PyExc_ValueError,
+ "unknown address family %d", af);
+ return NULL;
+ }
+
+ retval = inet_ntop(af, packed, ip, sizeof(ip));
+ if (!retval) {
+ PyErr_SetFromErrno(socket_error);
+ return NULL;
+ } else {
+ return PyString_FromString(retval);
+ }
+
+ /* NOTREACHED */
+ PyErr_SetString(PyExc_RuntimeError, "invalid handling of inet_ntop");
+ return NULL;
+}
+
+#endif /* HAVE_INET_PTON */
+
+/* Python interface to getaddrinfo(host, port). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getaddrinfo(PyObject *self, PyObject *args)
+{
+ struct addrinfo hints, *res;
+ struct addrinfo *res0 = NULL;
+ PyObject *hobj = NULL;
+ PyObject *pobj = (PyObject *)NULL;
+ char pbuf[30];
+ char *hptr, *pptr;
+ int family, socktype, protocol, flags;
+ int error;
+ PyObject *all = (PyObject *)NULL;
+ PyObject *single = (PyObject *)NULL;
+ PyObject *idna = NULL;
+
+ family = socktype = protocol = flags = 0;
+ family = AF_UNSPEC;
+ if (!PyArg_ParseTuple(args, "OO|iiii:getaddrinfo",
+ &hobj, &pobj, &family, &socktype,
+ &protocol, &flags)) {
+ return NULL;
+ }
+ if (hobj == Py_None) {
+ hptr = NULL;
+ } else if (PyUnicode_Check(hobj)) {
+ idna = PyObject_CallMethod(hobj, "encode", "s", "idna");
+ if (!idna)
+ return NULL;
+ hptr = PyString_AsString(idna);
+ } else if (PyString_Check(hobj)) {
+ hptr = PyString_AsString(hobj);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "getaddrinfo() argument 1 must be string or None");
+ return NULL;
+ }
+ if (PyInt_Check(pobj)) {
+ PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", PyInt_AsLong(pobj));
+ pptr = pbuf;
+ } else if (PyString_Check(pobj)) {
+ pptr = PyString_AsString(pobj);
+ } else if (pobj == Py_None) {
+ pptr = (char *)NULL;
+ } else {
+ PyErr_SetString(socket_error, "Int or String expected");
+ goto err;
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = socktype;
+ hints.ai_protocol = protocol;
+ hints.ai_flags = flags;
+ Py_BEGIN_ALLOW_THREADS
+ ACQUIRE_GETADDRINFO_LOCK
+ error = getaddrinfo(hptr, pptr, &hints, &res0);
+ Py_END_ALLOW_THREADS
+ RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */
+ if (error) {
+ set_gaierror(error);
+ goto err;
+ }
+
+ if ((all = PyList_New(0)) == NULL)
+ goto err;
+ for (res = res0; res; res = res->ai_next) {
+ PyObject *addr =
+ makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol);
+ if (addr == NULL)
+ goto err;
+ single = Py_BuildValue("iiisO", res->ai_family,
+ res->ai_socktype, res->ai_protocol,
+ res->ai_canonname ? res->ai_canonname : "",
+ addr);
+ Py_DECREF(addr);
+ if (single == NULL)
+ goto err;
+
+ if (PyList_Append(all, single))
+ goto err;
+ Py_XDECREF(single);
+ }
+ Py_XDECREF(idna);
+ if (res0)
+ freeaddrinfo(res0);
+ return all;
+ err:
+ Py_XDECREF(single);
+ Py_XDECREF(all);
+ Py_XDECREF(idna);
+ if (res0)
+ freeaddrinfo(res0);
+ return (PyObject *)NULL;
+}
+
+PyDoc_STRVAR(getaddrinfo_doc,
+"getaddrinfo(host, port [, family, socktype, proto, flags])\n\
+ -> list of (family, socktype, proto, canonname, sockaddr)\n\
+\n\
+Resolve host and port into addrinfo struct.");
+
+/* Python interface to getnameinfo(sa, flags). */
+
+/*ARGSUSED*/
+static PyObject *
+socket_getnameinfo(PyObject *self, PyObject *args)
+{
+ PyObject *sa = (PyObject *)NULL;
+ int flags;
+ char *hostp;
+ int port, flowinfo, scope_id;
+ char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+ struct addrinfo hints, *res = NULL;
+ int error;
+ PyObject *ret = (PyObject *)NULL;
+
+ flags = flowinfo = scope_id = 0;
+ if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags))
+ return NULL;
+ if (!PyArg_ParseTuple(sa, "si|ii",
+ &hostp, &port, &flowinfo, &scope_id))
+ return NULL;
+ PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; /* make numeric port happy */
+ Py_BEGIN_ALLOW_THREADS
+ ACQUIRE_GETADDRINFO_LOCK
+ error = getaddrinfo(hostp, pbuf, &hints, &res);
+ Py_END_ALLOW_THREADS
+ RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */
+ if (error) {
+ set_gaierror(error);
+ goto fail;
+ }
+ if (res->ai_next) {
+ PyErr_SetString(socket_error,
+ "sockaddr resolved to multiple addresses");
+ goto fail;
+ }
+ switch (res->ai_family) {
+ case AF_INET:
+ {
+ char *t1;
+ int t2;
+ if (PyArg_ParseTuple(sa, "si", &t1, &t2) == 0) {
+ PyErr_SetString(socket_error,
+ "IPv4 sockaddr must be 2 tuple");
+ goto fail;
+ }
+ break;
+ }
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
+ sin6 = (struct sockaddr_in6 *)res->ai_addr;
+ sin6->sin6_flowinfo = flowinfo;
+ sin6->sin6_scope_id = scope_id;
+ break;
+ }
+#endif
+ }
+ error = getnameinfo(res->ai_addr, res->ai_addrlen,
+ hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags);
+ if (error) {
+ set_gaierror(error);
+ goto fail;
+ }
+ ret = Py_BuildValue("ss", hbuf, pbuf);
+
+fail:
+ if (res)
+ freeaddrinfo(res);
+ return ret;
+}
+
+PyDoc_STRVAR(getnameinfo_doc,
+"getnameinfo(sockaddr, flags) --> (host, port)\n\
+\n\
+Get host and port for a sockaddr.");
+
+
+/* Python API to getting and setting the default timeout value. */
+
+static PyObject *
+socket_getdefaulttimeout(PyObject *self)
+{
+ if (defaulttimeout < 0.0) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ return PyFloat_FromDouble(defaulttimeout);
+}
+
+PyDoc_STRVAR(getdefaulttimeout_doc,
+"getdefaulttimeout() -> timeout\n\
+\n\
+Returns the default timeout in floating seconds for new socket objects.\n\
+A value of None indicates that new socket objects have no timeout.\n\
+When the socket module is first imported, the default is None.");
+
+static PyObject *
+socket_setdefaulttimeout(PyObject *self, PyObject *arg)
+{
+ double timeout;
+
+ if (arg == Py_None)
+ timeout = -1.0;
+ else {
+ timeout = PyFloat_AsDouble(arg);
+ if (timeout < 0.0) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_ValueError,
+ "Timeout value out of range");
+ return NULL;
+ }
+ }
+
+ defaulttimeout = timeout;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(setdefaulttimeout_doc,
+"setdefaulttimeout(timeout)\n\
+\n\
+Set the default timeout in floating seconds for new socket objects.\n\
+A value of None indicates that new socket objects have no timeout.\n\
+When the socket module is first imported, the default is None.");
+
+
+/* List of functions exported by this module. */
+
+static PyMethodDef socket_methods[] = {
+ {"gethostbyname", socket_gethostbyname,
+ METH_VARARGS, gethostbyname_doc},
+ {"gethostbyname_ex", socket_gethostbyname_ex,
+ METH_VARARGS, ghbn_ex_doc},
+ {"gethostbyaddr", socket_gethostbyaddr,
+ METH_VARARGS, gethostbyaddr_doc},
+ {"gethostname", socket_gethostname,
+ METH_NOARGS, gethostname_doc},
+ {"getservbyname", socket_getservbyname,
+ METH_VARARGS, getservbyname_doc},
+ {"getservbyport", socket_getservbyport,
+ METH_VARARGS, getservbyport_doc},
+ {"getprotobyname", socket_getprotobyname,
+ METH_VARARGS, getprotobyname_doc},
+#ifndef NO_DUP
+ {"fromfd", socket_fromfd,
+ METH_VARARGS, fromfd_doc},
+#endif
+#ifdef HAVE_SOCKETPAIR
+ {"socketpair", socket_socketpair,
+ METH_VARARGS, socketpair_doc},
+#endif
+ {"ntohs", socket_ntohs,
+ METH_VARARGS, ntohs_doc},
+ {"ntohl", socket_ntohl,
+ METH_O, ntohl_doc},
+ {"htons", socket_htons,
+ METH_VARARGS, htons_doc},
+ {"htonl", socket_htonl,
+ METH_O, htonl_doc},
+ {"inet_aton", socket_inet_aton,
+ METH_VARARGS, inet_aton_doc},
+ {"inet_ntoa", socket_inet_ntoa,
+ METH_VARARGS, inet_ntoa_doc},
+#ifdef HAVE_INET_PTON
+ {"inet_pton", socket_inet_pton,
+ METH_VARARGS, inet_pton_doc},
+ {"inet_ntop", socket_inet_ntop,
+ METH_VARARGS, inet_ntop_doc},
+#endif
+ {"getaddrinfo", socket_getaddrinfo,
+ METH_VARARGS, getaddrinfo_doc},
+ {"getnameinfo", socket_getnameinfo,
+ METH_VARARGS, getnameinfo_doc},
+ {"getdefaulttimeout", (PyCFunction)socket_getdefaulttimeout,
+ METH_NOARGS, getdefaulttimeout_doc},
+ {"setdefaulttimeout", socket_setdefaulttimeout,
+ METH_O, setdefaulttimeout_doc},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+#ifdef RISCOS
+#define OS_INIT_DEFINED
+
+static int
+os_init(void)
+{
+ _kernel_swi_regs r;
+
+ r.r[0] = 0;
+ _kernel_swi(0x43380, &r, &r);
+ taskwindow = r.r[0];
+
+ return 1;
+}
+
+#endif /* RISCOS */
+
+
+#ifdef MS_WINDOWS
+#define OS_INIT_DEFINED
+
+/* Additional initialization and cleanup for Windows */
+
+static void
+os_cleanup(void)
+{
+ WSACleanup();
+}
+
+static int
+os_init(void)
+{
+ WSADATA WSAData;
+ int ret;
+ char buf[100];
+ ret = WSAStartup(0x0101, &WSAData);
+ switch (ret) {
+ case 0: /* No error */
+ Py_AtExit(os_cleanup);
+ return 1; /* Success */
+ case WSASYSNOTREADY:
+ PyErr_SetString(PyExc_ImportError,
+ "WSAStartup failed: network not ready");
+ break;
+ case WSAVERNOTSUPPORTED:
+ case WSAEINVAL:
+ PyErr_SetString(
+ PyExc_ImportError,
+ "WSAStartup failed: requested version not supported");
+ break;
+ default:
+ PyOS_snprintf(buf, sizeof(buf),
+ "WSAStartup failed: error code %d", ret);
+ PyErr_SetString(PyExc_ImportError, buf);
+ break;
+ }
+ return 0; /* Failure */
+}
+
+#endif /* MS_WINDOWS */
+
+
+#ifdef PYOS_OS2
+#define OS_INIT_DEFINED
+
+/* Additional initialization for OS/2 */
+
+static int
+os_init(void)
+{
+#ifndef PYCC_GCC
+ char reason[64];
+ int rc = sock_init();
+
+ if (rc == 0) {
+ return 1; /* Success */
+ }
+
+ PyOS_snprintf(reason, sizeof(reason),
+ "OS/2 TCP/IP Error# %d", sock_errno());
+ PyErr_SetString(PyExc_ImportError, reason);
+
+ return 0; /* Failure */
+#else
+ /* No need to initialise sockets with GCC/EMX */
+ return 1; /* Success */
+#endif
+}
+
+#endif /* PYOS_OS2 */
+
+
+#ifndef OS_INIT_DEFINED
+static int
+os_init(void)
+{
+ return 1; /* Success */
+}
+#endif
+
+
+/* C API table - always add new things to the end for binary
+ compatibility. */
+static
+PySocketModule_APIObject PySocketModuleAPI =
+{
+ &sock_type,
+ NULL
+};
+
+
+/* Initialize the _socket module.
+
+ This module is actually called "_socket", and there's a wrapper
+ "socket.py" which implements some additional functionality. On some
+ platforms (e.g. Windows and OS/2), socket.py also implements a
+ wrapper for the socket type that provides missing functionality such
+ as makefile(), dup() and fromfd(). The import of "_socket" may fail
+ with an ImportError exception if os-specific initialization fails.
+ On Windows, this does WINSOCK initialization. When WINSOCK is
+ initialized succesfully, a call to WSACleanup() is scheduled to be
+ made at exit time.
+*/
+
+PyDoc_STRVAR(socket_doc,
+"Implementation module for socket operations.\n\
+\n\
+See the socket module for documentation.");
+
+PyMODINIT_FUNC
+init_socket(void)
+{
+ PyObject *m, *has_ipv6;
+
+ if (!os_init())
+ return;
+
+ sock_type.ob_type = &PyType_Type;
+ m = Py_InitModule3(PySocket_MODULE_NAME,
+ socket_methods,
+ socket_doc);
+ if (m == NULL)
+ return;
+
+ socket_error = PyErr_NewException("socket.error", NULL, NULL);
+ if (socket_error == NULL)
+ return;
+ PySocketModuleAPI.error = socket_error;
+ Py_INCREF(socket_error);
+ PyModule_AddObject(m, "error", socket_error);
+ socket_herror = PyErr_NewException("socket.herror",
+ socket_error, NULL);
+ if (socket_herror == NULL)
+ return;
+ Py_INCREF(socket_herror);
+ PyModule_AddObject(m, "herror", socket_herror);
+ socket_gaierror = PyErr_NewException("socket.gaierror", socket_error,
+ NULL);
+ if (socket_gaierror == NULL)
+ return;
+ Py_INCREF(socket_gaierror);
+ PyModule_AddObject(m, "gaierror", socket_gaierror);
+ socket_timeout = PyErr_NewException("socket.timeout",
+ socket_error, NULL);
+ if (socket_timeout == NULL)
+ return;
+ Py_INCREF(socket_timeout);
+ PyModule_AddObject(m, "timeout", socket_timeout);
+ Py_INCREF((PyObject *)&sock_type);
+ if (PyModule_AddObject(m, "SocketType",
+ (PyObject *)&sock_type) != 0)
+ return;
+ Py_INCREF((PyObject *)&sock_type);
+ if (PyModule_AddObject(m, "socket",
+ (PyObject *)&sock_type) != 0)
+ return;
+
+#ifdef ENABLE_IPV6
+ has_ipv6 = Py_True;
+#else
+ has_ipv6 = Py_False;
+#endif
+ Py_INCREF(has_ipv6);
+ PyModule_AddObject(m, "has_ipv6", has_ipv6);
+
+ /* Export C API */
+ if (PyModule_AddObject(m, PySocket_CAPI_NAME,
+ PyCObject_FromVoidPtr((void *)&PySocketModuleAPI, NULL)
+ ) != 0)
+ return;
+
+ /* Address families (we only support AF_INET and AF_UNIX) */
+#ifdef AF_UNSPEC
+ PyModule_AddIntConstant(m, "AF_UNSPEC", AF_UNSPEC);
+#endif
+ PyModule_AddIntConstant(m, "AF_INET", AF_INET);
+#ifdef AF_INET6
+ PyModule_AddIntConstant(m, "AF_INET6", AF_INET6);
+#endif /* AF_INET6 */
+#if defined(AF_UNIX)
+ PyModule_AddIntConstant(m, "AF_UNIX", AF_UNIX);
+#endif /* AF_UNIX */
+#ifdef AF_AX25
+ /* Amateur Radio AX.25 */
+ PyModule_AddIntConstant(m, "AF_AX25", AF_AX25);
+#endif
+#ifdef AF_IPX
+ PyModule_AddIntConstant(m, "AF_IPX", AF_IPX); /* Novell IPX */
+#endif
+#ifdef AF_APPLETALK
+ /* Appletalk DDP */
+ PyModule_AddIntConstant(m, "AF_APPLETALK", AF_APPLETALK);
+#endif
+#ifdef AF_NETROM
+ /* Amateur radio NetROM */
+ PyModule_AddIntConstant(m, "AF_NETROM", AF_NETROM);
+#endif
+#ifdef AF_BRIDGE
+ /* Multiprotocol bridge */
+ PyModule_AddIntConstant(m, "AF_BRIDGE", AF_BRIDGE);
+#endif
+#ifdef AF_ATMPVC
+ /* ATM PVCs */
+ PyModule_AddIntConstant(m, "AF_ATMPVC", AF_ATMPVC);
+#endif
+#ifdef AF_AAL5
+ /* Reserved for Werner's ATM */
+ PyModule_AddIntConstant(m, "AF_AAL5", AF_AAL5);
+#endif
+#ifdef AF_X25
+ /* Reserved for X.25 project */
+ PyModule_AddIntConstant(m, "AF_X25", AF_X25);
+#endif
+#ifdef AF_INET6
+ PyModule_AddIntConstant(m, "AF_INET6", AF_INET6); /* IP version 6 */
+#endif
+#ifdef AF_ROSE
+ /* Amateur Radio X.25 PLP */
+ PyModule_AddIntConstant(m, "AF_ROSE", AF_ROSE);
+#endif
+#ifdef AF_DECnet
+ /* Reserved for DECnet project */
+ PyModule_AddIntConstant(m, "AF_DECnet", AF_DECnet);
+#endif
+#ifdef AF_NETBEUI
+ /* Reserved for 802.2LLC project */
+ PyModule_AddIntConstant(m, "AF_NETBEUI", AF_NETBEUI);
+#endif
+#ifdef AF_SECURITY
+ /* Security callback pseudo AF */
+ PyModule_AddIntConstant(m, "AF_SECURITY", AF_SECURITY);
+#endif
+#ifdef AF_KEY
+ /* PF_KEY key management API */
+ PyModule_AddIntConstant(m, "AF_KEY", AF_KEY);
+#endif
+#ifdef AF_NETLINK
+ /* */
+ PyModule_AddIntConstant(m, "AF_NETLINK", AF_NETLINK);
+ PyModule_AddIntConstant(m, "NETLINK_ROUTE", NETLINK_ROUTE);
+#ifdef NETLINK_SKIP
+ PyModule_AddIntConstant(m, "NETLINK_SKIP", NETLINK_SKIP);
+#endif
+#ifdef NETLINK_W1
+ PyModule_AddIntConstant(m, "NETLINK_W1", NETLINK_W1);
+#endif
+ PyModule_AddIntConstant(m, "NETLINK_USERSOCK", NETLINK_USERSOCK);
+ PyModule_AddIntConstant(m, "NETLINK_FIREWALL", NETLINK_FIREWALL);
+#ifdef NETLINK_TCPDIAG
+ PyModule_AddIntConstant(m, "NETLINK_TCPDIAG", NETLINK_TCPDIAG);
+#endif
+#ifdef NETLINK_NFLOG
+ PyModule_AddIntConstant(m, "NETLINK_NFLOG", NETLINK_NFLOG);
+#endif
+#ifdef NETLINK_XFRM
+ PyModule_AddIntConstant(m, "NETLINK_XFRM", NETLINK_XFRM);
+#endif
+#ifdef NETLINK_ARPD
+ PyModule_AddIntConstant(m, "NETLINK_ARPD", NETLINK_ARPD);
+#endif
+#ifdef NETLINK_ROUTE6
+ PyModule_AddIntConstant(m, "NETLINK_ROUTE6", NETLINK_ROUTE6);
+#endif
+ PyModule_AddIntConstant(m, "NETLINK_IP6_FW", NETLINK_IP6_FW);
+#ifdef NETLINK_DNRTMSG
+ PyModule_AddIntConstant(m, "NETLINK_DNRTMSG", NETLINK_DNRTMSG);
+#endif
+#ifdef NETLINK_TAPBASE
+ PyModule_AddIntConstant(m, "NETLINK_TAPBASE", NETLINK_TAPBASE);
+#endif
+#endif /* AF_NETLINK */
+#ifdef AF_ROUTE
+ /* Alias to emulate 4.4BSD */
+ PyModule_AddIntConstant(m, "AF_ROUTE", AF_ROUTE);
+#endif
+#ifdef AF_ASH
+ /* Ash */
+ PyModule_AddIntConstant(m, "AF_ASH", AF_ASH);
+#endif
+#ifdef AF_ECONET
+ /* Acorn Econet */
+ PyModule_AddIntConstant(m, "AF_ECONET", AF_ECONET);
+#endif
+#ifdef AF_ATMSVC
+ /* ATM SVCs */
+ PyModule_AddIntConstant(m, "AF_ATMSVC", AF_ATMSVC);
+#endif
+#ifdef AF_SNA
+ /* Linux SNA Project (nutters!) */
+ PyModule_AddIntConstant(m, "AF_SNA", AF_SNA);
+#endif
+#ifdef AF_IRDA
+ /* IRDA sockets */
+ PyModule_AddIntConstant(m, "AF_IRDA", AF_IRDA);
+#endif
+#ifdef AF_PPPOX
+ /* PPPoX sockets */
+ PyModule_AddIntConstant(m, "AF_PPPOX", AF_PPPOX);
+#endif
+#ifdef AF_WANPIPE
+ /* Wanpipe API Sockets */
+ PyModule_AddIntConstant(m, "AF_WANPIPE", AF_WANPIPE);
+#endif
+#ifdef AF_LLC
+ /* Linux LLC */
+ PyModule_AddIntConstant(m, "AF_LLC", AF_LLC);
+#endif
+
+#ifdef USE_BLUETOOTH
+ PyModule_AddIntConstant(m, "AF_BLUETOOTH", AF_BLUETOOTH);
+ PyModule_AddIntConstant(m, "BTPROTO_L2CAP", BTPROTO_L2CAP);
+#if !defined(__FreeBSD__)
+ PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO);
+#endif
+ PyModule_AddIntConstant(m, "BTPROTO_RFCOMM", BTPROTO_RFCOMM);
+ PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00");
+ PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF");
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+ PyModule_AddIntConstant(m, "AF_PACKET", AF_PACKET);
+ PyModule_AddIntConstant(m, "PF_PACKET", PF_PACKET);
+ PyModule_AddIntConstant(m, "PACKET_HOST", PACKET_HOST);
+ PyModule_AddIntConstant(m, "PACKET_BROADCAST", PACKET_BROADCAST);
+ PyModule_AddIntConstant(m, "PACKET_MULTICAST", PACKET_MULTICAST);
+ PyModule_AddIntConstant(m, "PACKET_OTHERHOST", PACKET_OTHERHOST);
+ PyModule_AddIntConstant(m, "PACKET_OUTGOING", PACKET_OUTGOING);
+ PyModule_AddIntConstant(m, "PACKET_LOOPBACK", PACKET_LOOPBACK);
+ PyModule_AddIntConstant(m, "PACKET_FASTROUTE", PACKET_FASTROUTE);
+#endif
+
+ /* Socket types */
+ PyModule_AddIntConstant(m, "SOCK_STREAM", SOCK_STREAM);
+ PyModule_AddIntConstant(m, "SOCK_DGRAM", SOCK_DGRAM);
+#ifndef __BEOS__
+/* We have incomplete socket support. */
+ PyModule_AddIntConstant(m, "SOCK_RAW", SOCK_RAW);
+ PyModule_AddIntConstant(m, "SOCK_SEQPACKET", SOCK_SEQPACKET);
+#if defined(SOCK_RDM)
+ PyModule_AddIntConstant(m, "SOCK_RDM", SOCK_RDM);
+#endif
+#endif
+
+#ifdef SO_DEBUG
+ PyModule_AddIntConstant(m, "SO_DEBUG", SO_DEBUG);
+#endif
+#ifdef SO_ACCEPTCONN
+ PyModule_AddIntConstant(m, "SO_ACCEPTCONN", SO_ACCEPTCONN);
+#endif
+#ifdef SO_REUSEADDR
+ PyModule_AddIntConstant(m, "SO_REUSEADDR", SO_REUSEADDR);
+#endif
+#ifdef SO_EXCLUSIVEADDRUSE
+ PyModule_AddIntConstant(m, "SO_EXCLUSIVEADDRUSE", SO_EXCLUSIVEADDRUSE);
+#endif
+
+#ifdef SO_KEEPALIVE
+ PyModule_AddIntConstant(m, "SO_KEEPALIVE", SO_KEEPALIVE);
+#endif
+#ifdef SO_DONTROUTE
+ PyModule_AddIntConstant(m, "SO_DONTROUTE", SO_DONTROUTE);
+#endif
+#ifdef SO_BROADCAST
+ PyModule_AddIntConstant(m, "SO_BROADCAST", SO_BROADCAST);
+#endif
+#ifdef SO_USELOOPBACK
+ PyModule_AddIntConstant(m, "SO_USELOOPBACK", SO_USELOOPBACK);
+#endif
+#ifdef SO_LINGER
+ PyModule_AddIntConstant(m, "SO_LINGER", SO_LINGER);
+#endif
+#ifdef SO_OOBINLINE
+ PyModule_AddIntConstant(m, "SO_OOBINLINE", SO_OOBINLINE);
+#endif
+#ifdef SO_REUSEPORT
+ PyModule_AddIntConstant(m, "SO_REUSEPORT", SO_REUSEPORT);
+#endif
+#ifdef SO_SNDBUF
+ PyModule_AddIntConstant(m, "SO_SNDBUF", SO_SNDBUF);
+#endif
+#ifdef SO_RCVBUF
+ PyModule_AddIntConstant(m, "SO_RCVBUF", SO_RCVBUF);
+#endif
+#ifdef SO_SNDLOWAT
+ PyModule_AddIntConstant(m, "SO_SNDLOWAT", SO_SNDLOWAT);
+#endif
+#ifdef SO_RCVLOWAT
+ PyModule_AddIntConstant(m, "SO_RCVLOWAT", SO_RCVLOWAT);
+#endif
+#ifdef SO_SNDTIMEO
+ PyModule_AddIntConstant(m, "SO_SNDTIMEO", SO_SNDTIMEO);
+#endif
+#ifdef SO_RCVTIMEO
+ PyModule_AddIntConstant(m, "SO_RCVTIMEO", SO_RCVTIMEO);
+#endif
+#ifdef SO_ERROR
+ PyModule_AddIntConstant(m, "SO_ERROR", SO_ERROR);
+#endif
+#ifdef SO_TYPE
+ PyModule_AddIntConstant(m, "SO_TYPE", SO_TYPE);
+#endif
+
+ /* Maximum number of connections for "listen" */
+#ifdef SOMAXCONN
+ PyModule_AddIntConstant(m, "SOMAXCONN", SOMAXCONN);
+#else
+ PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */
+#endif
+
+ /* Flags for send, recv */
+#ifdef MSG_OOB
+ PyModule_AddIntConstant(m, "MSG_OOB", MSG_OOB);
+#endif
+#ifdef MSG_PEEK
+ PyModule_AddIntConstant(m, "MSG_PEEK", MSG_PEEK);
+#endif
+#ifdef MSG_DONTROUTE
+ PyModule_AddIntConstant(m, "MSG_DONTROUTE", MSG_DONTROUTE);
+#endif
+#ifdef MSG_DONTWAIT
+ PyModule_AddIntConstant(m, "MSG_DONTWAIT", MSG_DONTWAIT);
+#endif
+#ifdef MSG_EOR
+ PyModule_AddIntConstant(m, "MSG_EOR", MSG_EOR);
+#endif
+#ifdef MSG_TRUNC
+ PyModule_AddIntConstant(m, "MSG_TRUNC", MSG_TRUNC);
+#endif
+#ifdef MSG_CTRUNC
+ PyModule_AddIntConstant(m, "MSG_CTRUNC", MSG_CTRUNC);
+#endif
+#ifdef MSG_WAITALL
+ PyModule_AddIntConstant(m, "MSG_WAITALL", MSG_WAITALL);
+#endif
+#ifdef MSG_BTAG
+ PyModule_AddIntConstant(m, "MSG_BTAG", MSG_BTAG);
+#endif
+#ifdef MSG_ETAG
+ PyModule_AddIntConstant(m, "MSG_ETAG", MSG_ETAG);
+#endif
+
+ /* Protocol level and numbers, usable for [gs]etsockopt */
+#ifdef SOL_SOCKET
+ PyModule_AddIntConstant(m, "SOL_SOCKET", SOL_SOCKET);
+#endif
+#ifdef SOL_IP
+ PyModule_AddIntConstant(m, "SOL_IP", SOL_IP);
+#else
+ PyModule_AddIntConstant(m, "SOL_IP", 0);
+#endif
+#ifdef SOL_IPX
+ PyModule_AddIntConstant(m, "SOL_IPX", SOL_IPX);
+#endif
+#ifdef SOL_AX25
+ PyModule_AddIntConstant(m, "SOL_AX25", SOL_AX25);
+#endif
+#ifdef SOL_ATALK
+ PyModule_AddIntConstant(m, "SOL_ATALK", SOL_ATALK);
+#endif
+#ifdef SOL_NETROM
+ PyModule_AddIntConstant(m, "SOL_NETROM", SOL_NETROM);
+#endif
+#ifdef SOL_ROSE
+ PyModule_AddIntConstant(m, "SOL_ROSE", SOL_ROSE);
+#endif
+#ifdef SOL_TCP
+ PyModule_AddIntConstant(m, "SOL_TCP", SOL_TCP);
+#else
+ PyModule_AddIntConstant(m, "SOL_TCP", 6);
+#endif
+#ifdef SOL_UDP
+ PyModule_AddIntConstant(m, "SOL_UDP", SOL_UDP);
+#else
+ PyModule_AddIntConstant(m, "SOL_UDP", 17);
+#endif
+#ifdef IPPROTO_IP
+ PyModule_AddIntConstant(m, "IPPROTO_IP", IPPROTO_IP);
+#else
+ PyModule_AddIntConstant(m, "IPPROTO_IP", 0);
+#endif
+#ifdef IPPROTO_HOPOPTS
+ PyModule_AddIntConstant(m, "IPPROTO_HOPOPTS", IPPROTO_HOPOPTS);
+#endif
+#ifdef IPPROTO_ICMP
+ PyModule_AddIntConstant(m, "IPPROTO_ICMP", IPPROTO_ICMP);
+#else
+ PyModule_AddIntConstant(m, "IPPROTO_ICMP", 1);
+#endif
+#ifdef IPPROTO_IGMP
+ PyModule_AddIntConstant(m, "IPPROTO_IGMP", IPPROTO_IGMP);
+#endif
+#ifdef IPPROTO_GGP
+ PyModule_AddIntConstant(m, "IPPROTO_GGP", IPPROTO_GGP);
+#endif
+#ifdef IPPROTO_IPV4
+ PyModule_AddIntConstant(m, "IPPROTO_IPV4", IPPROTO_IPV4);
+#endif
+#ifdef IPPROTO_IPV6
+ PyModule_AddIntConstant(m, "IPPROTO_IPV6", IPPROTO_IPV6);
+#endif
+#ifdef IPPROTO_IPIP
+ PyModule_AddIntConstant(m, "IPPROTO_IPIP", IPPROTO_IPIP);
+#endif
+#ifdef IPPROTO_TCP
+ PyModule_AddIntConstant(m, "IPPROTO_TCP", IPPROTO_TCP);
+#else
+ PyModule_AddIntConstant(m, "IPPROTO_TCP", 6);
+#endif
+#ifdef IPPROTO_EGP
+ PyModule_AddIntConstant(m, "IPPROTO_EGP", IPPROTO_EGP);
+#endif
+#ifdef IPPROTO_PUP
+ PyModule_AddIntConstant(m, "IPPROTO_PUP", IPPROTO_PUP);
+#endif
+#ifdef IPPROTO_UDP
+ PyModule_AddIntConstant(m, "IPPROTO_UDP", IPPROTO_UDP);
+#else
+ PyModule_AddIntConstant(m, "IPPROTO_UDP", 17);
+#endif
+#ifdef IPPROTO_IDP
+ PyModule_AddIntConstant(m, "IPPROTO_IDP", IPPROTO_IDP);
+#endif
+#ifdef IPPROTO_HELLO
+ PyModule_AddIntConstant(m, "IPPROTO_HELLO", IPPROTO_HELLO);
+#endif
+#ifdef IPPROTO_ND
+ PyModule_AddIntConstant(m, "IPPROTO_ND", IPPROTO_ND);
+#endif
+#ifdef IPPROTO_TP
+ PyModule_AddIntConstant(m, "IPPROTO_TP", IPPROTO_TP);
+#endif
+#ifdef IPPROTO_IPV6
+ PyModule_AddIntConstant(m, "IPPROTO_IPV6", IPPROTO_IPV6);
+#endif
+#ifdef IPPROTO_ROUTING
+ PyModule_AddIntConstant(m, "IPPROTO_ROUTING", IPPROTO_ROUTING);
+#endif
+#ifdef IPPROTO_FRAGMENT
+ PyModule_AddIntConstant(m, "IPPROTO_FRAGMENT", IPPROTO_FRAGMENT);
+#endif
+#ifdef IPPROTO_RSVP
+ PyModule_AddIntConstant(m, "IPPROTO_RSVP", IPPROTO_RSVP);
+#endif
+#ifdef IPPROTO_GRE
+ PyModule_AddIntConstant(m, "IPPROTO_GRE", IPPROTO_GRE);
+#endif
+#ifdef IPPROTO_ESP
+ PyModule_AddIntConstant(m, "IPPROTO_ESP", IPPROTO_ESP);
+#endif
+#ifdef IPPROTO_AH
+ PyModule_AddIntConstant(m, "IPPROTO_AH", IPPROTO_AH);
+#endif
+#ifdef IPPROTO_MOBILE
+ PyModule_AddIntConstant(m, "IPPROTO_MOBILE", IPPROTO_MOBILE);
+#endif
+#ifdef IPPROTO_ICMPV6
+ PyModule_AddIntConstant(m, "IPPROTO_ICMPV6", IPPROTO_ICMPV6);
+#endif
+#ifdef IPPROTO_NONE
+ PyModule_AddIntConstant(m, "IPPROTO_NONE", IPPROTO_NONE);
+#endif
+#ifdef IPPROTO_DSTOPTS
+ PyModule_AddIntConstant(m, "IPPROTO_DSTOPTS", IPPROTO_DSTOPTS);
+#endif
+#ifdef IPPROTO_XTP
+ PyModule_AddIntConstant(m, "IPPROTO_XTP", IPPROTO_XTP);
+#endif
+#ifdef IPPROTO_EON
+ PyModule_AddIntConstant(m, "IPPROTO_EON", IPPROTO_EON);
+#endif
+#ifdef IPPROTO_PIM
+ PyModule_AddIntConstant(m, "IPPROTO_PIM", IPPROTO_PIM);
+#endif
+#ifdef IPPROTO_IPCOMP
+ PyModule_AddIntConstant(m, "IPPROTO_IPCOMP", IPPROTO_IPCOMP);
+#endif
+#ifdef IPPROTO_VRRP
+ PyModule_AddIntConstant(m, "IPPROTO_VRRP", IPPROTO_VRRP);
+#endif
+#ifdef IPPROTO_BIP
+ PyModule_AddIntConstant(m, "IPPROTO_BIP", IPPROTO_BIP);
+#endif
+/**/
+#ifdef IPPROTO_RAW
+ PyModule_AddIntConstant(m, "IPPROTO_RAW", IPPROTO_RAW);
+#else
+ PyModule_AddIntConstant(m, "IPPROTO_RAW", 255);
+#endif
+#ifdef IPPROTO_MAX
+ PyModule_AddIntConstant(m, "IPPROTO_MAX", IPPROTO_MAX);
+#endif
+
+ /* Some port configuration */
+#ifdef IPPORT_RESERVED
+ PyModule_AddIntConstant(m, "IPPORT_RESERVED", IPPORT_RESERVED);
+#else
+ PyModule_AddIntConstant(m, "IPPORT_RESERVED", 1024);
+#endif
+#ifdef IPPORT_USERRESERVED
+ PyModule_AddIntConstant(m, "IPPORT_USERRESERVED", IPPORT_USERRESERVED);
+#else
+ PyModule_AddIntConstant(m, "IPPORT_USERRESERVED", 5000);
+#endif
+
+ /* Some reserved IP v.4 addresses */
+#ifdef INADDR_ANY
+ PyModule_AddIntConstant(m, "INADDR_ANY", INADDR_ANY);
+#else
+ PyModule_AddIntConstant(m, "INADDR_ANY", 0x00000000);
+#endif
+#ifdef INADDR_BROADCAST
+ PyModule_AddIntConstant(m, "INADDR_BROADCAST", INADDR_BROADCAST);
+#else
+ PyModule_AddIntConstant(m, "INADDR_BROADCAST", 0xffffffff);
+#endif
+#ifdef INADDR_LOOPBACK
+ PyModule_AddIntConstant(m, "INADDR_LOOPBACK", INADDR_LOOPBACK);
+#else
+ PyModule_AddIntConstant(m, "INADDR_LOOPBACK", 0x7F000001);
+#endif
+#ifdef INADDR_UNSPEC_GROUP
+ PyModule_AddIntConstant(m, "INADDR_UNSPEC_GROUP", INADDR_UNSPEC_GROUP);
+#else
+ PyModule_AddIntConstant(m, "INADDR_UNSPEC_GROUP", 0xe0000000);
+#endif
+#ifdef INADDR_ALLHOSTS_GROUP
+ PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP",
+ INADDR_ALLHOSTS_GROUP);
+#else
+ PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP", 0xe0000001);
+#endif
+#ifdef INADDR_MAX_LOCAL_GROUP
+ PyModule_AddIntConstant(m, "INADDR_MAX_LOCAL_GROUP",
+ INADDR_MAX_LOCAL_GROUP);
+#else
+ PyModule_AddIntConstant(m, "INADDR_MAX_LOCAL_GROUP", 0xe00000ff);
+#endif
+#ifdef INADDR_NONE
+ PyModule_AddIntConstant(m, "INADDR_NONE", INADDR_NONE);
+#else
+ PyModule_AddIntConstant(m, "INADDR_NONE", 0xffffffff);
+#endif
+
+ /* IPv4 [gs]etsockopt options */
+#ifdef IP_OPTIONS
+ PyModule_AddIntConstant(m, "IP_OPTIONS", IP_OPTIONS);
+#endif
+#ifdef IP_HDRINCL
+ PyModule_AddIntConstant(m, "IP_HDRINCL", IP_HDRINCL);
+#endif
+#ifdef IP_TOS
+ PyModule_AddIntConstant(m, "IP_TOS", IP_TOS);
+#endif
+#ifdef IP_TTL
+ PyModule_AddIntConstant(m, "IP_TTL", IP_TTL);
+#endif
+#ifdef IP_RECVOPTS
+ PyModule_AddIntConstant(m, "IP_RECVOPTS", IP_RECVOPTS);
+#endif
+#ifdef IP_RECVRETOPTS
+ PyModule_AddIntConstant(m, "IP_RECVRETOPTS", IP_RECVRETOPTS);
+#endif
+#ifdef IP_RECVDSTADDR
+ PyModule_AddIntConstant(m, "IP_RECVDSTADDR", IP_RECVDSTADDR);
+#endif
+#ifdef IP_RETOPTS
+ PyModule_AddIntConstant(m, "IP_RETOPTS", IP_RETOPTS);
+#endif
+#ifdef IP_MULTICAST_IF
+ PyModule_AddIntConstant(m, "IP_MULTICAST_IF", IP_MULTICAST_IF);
+#endif
+#ifdef IP_MULTICAST_TTL
+ PyModule_AddIntConstant(m, "IP_MULTICAST_TTL", IP_MULTICAST_TTL);
+#endif
+#ifdef IP_MULTICAST_LOOP
+ PyModule_AddIntConstant(m, "IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
+#endif
+#ifdef IP_ADD_MEMBERSHIP
+ PyModule_AddIntConstant(m, "IP_ADD_MEMBERSHIP", IP_ADD_MEMBERSHIP);
+#endif
+#ifdef IP_DROP_MEMBERSHIP
+ PyModule_AddIntConstant(m, "IP_DROP_MEMBERSHIP", IP_DROP_MEMBERSHIP);
+#endif
+#ifdef IP_DEFAULT_MULTICAST_TTL
+ PyModule_AddIntConstant(m, "IP_DEFAULT_MULTICAST_TTL",
+ IP_DEFAULT_MULTICAST_TTL);
+#endif
+#ifdef IP_DEFAULT_MULTICAST_LOOP
+ PyModule_AddIntConstant(m, "IP_DEFAULT_MULTICAST_LOOP",
+ IP_DEFAULT_MULTICAST_LOOP);
+#endif
+#ifdef IP_MAX_MEMBERSHIPS
+ PyModule_AddIntConstant(m, "IP_MAX_MEMBERSHIPS", IP_MAX_MEMBERSHIPS);
+#endif
+
+ /* IPv6 [gs]etsockopt options, defined in RFC2553 */
+#ifdef IPV6_JOIN_GROUP
+ PyModule_AddIntConstant(m, "IPV6_JOIN_GROUP", IPV6_JOIN_GROUP);
+#endif
+#ifdef IPV6_LEAVE_GROUP
+ PyModule_AddIntConstant(m, "IPV6_LEAVE_GROUP", IPV6_LEAVE_GROUP);
+#endif
+#ifdef IPV6_MULTICAST_HOPS
+ PyModule_AddIntConstant(m, "IPV6_MULTICAST_HOPS", IPV6_MULTICAST_HOPS);
+#endif
+#ifdef IPV6_MULTICAST_IF
+ PyModule_AddIntConstant(m, "IPV6_MULTICAST_IF", IPV6_MULTICAST_IF);
+#endif
+#ifdef IPV6_MULTICAST_LOOP
+ PyModule_AddIntConstant(m, "IPV6_MULTICAST_LOOP", IPV6_MULTICAST_LOOP);
+#endif
+#ifdef IPV6_UNICAST_HOPS
+ PyModule_AddIntConstant(m, "IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS);
+#endif
+ /* Additional IPV6 socket options, defined in RFC 3493 */
+#ifdef IPV6_V6ONLY
+ PyModule_AddIntConstant(m, "IPV6_V6ONLY", IPV6_V6ONLY);
+#endif
+ /* Advanced IPV6 socket options, from RFC 3542 */
+#ifdef IPV6_CHECKSUM
+ PyModule_AddIntConstant(m, "IPV6_CHECKSUM", IPV6_CHECKSUM);
+#endif
+#ifdef IPV6_DONTFRAG
+ PyModule_AddIntConstant(m, "IPV6_DONTFRAG", IPV6_DONTFRAG);
+#endif
+#ifdef IPV6_DSTOPTS
+ PyModule_AddIntConstant(m, "IPV6_DSTOPTS", IPV6_DSTOPTS);
+#endif
+#ifdef IPV6_HOPLIMIT
+ PyModule_AddIntConstant(m, "IPV6_HOPLIMIT", IPV6_HOPLIMIT);
+#endif
+#ifdef IPV6_HOPOPTS
+ PyModule_AddIntConstant(m, "IPV6_HOPOPTS", IPV6_HOPOPTS);
+#endif
+#ifdef IPV6_NEXTHOP
+ PyModule_AddIntConstant(m, "IPV6_NEXTHOP", IPV6_NEXTHOP);
+#endif
+#ifdef IPV6_PATHMTU
+ PyModule_AddIntConstant(m, "IPV6_PATHMTU", IPV6_PATHMTU);
+#endif
+#ifdef IPV6_PKTINFO
+ PyModule_AddIntConstant(m, "IPV6_PKTINFO", IPV6_PKTINFO);
+#endif
+#ifdef IPV6_RECVDSTOPTS
+ PyModule_AddIntConstant(m, "IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS);
+#endif
+#ifdef IPV6_RECVHOPLIMIT
+ PyModule_AddIntConstant(m, "IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT);
+#endif
+#ifdef IPV6_RECVHOPOPTS
+ PyModule_AddIntConstant(m, "IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS);
+#endif
+#ifdef IPV6_RECVPKTINFO
+ PyModule_AddIntConstant(m, "IPV6_RECVPKTINFO", IPV6_RECVPKTINFO);
+#endif
+#ifdef IPV6_RECVRTHDR
+ PyModule_AddIntConstant(m, "IPV6_RECVRTHDR", IPV6_RECVRTHDR);
+#endif
+#ifdef IPV6_RECVTCLASS
+ PyModule_AddIntConstant(m, "IPV6_RECVTCLASS", IPV6_RECVTCLASS);
+#endif
+#ifdef IPV6_RTHDR
+ PyModule_AddIntConstant(m, "IPV6_RTHDR", IPV6_RTHDR);
+#endif
+#ifdef IPV6_RTHDRDSTOPTS
+ PyModule_AddIntConstant(m, "IPV6_RTHDRDSTOPTS", IPV6_RTHDRDSTOPTS);
+#endif
+#ifdef IPV6_RTHDR_TYPE_0
+ PyModule_AddIntConstant(m, "IPV6_RTHDR_TYPE_0", IPV6_RTHDR_TYPE_0);
+#endif
+#ifdef IPV6_RECVPATHMTU
+ PyModule_AddIntConstant(m, "IPV6_RECVPATHMTU", IPV6_RECVPATHMTU);
+#endif
+#ifdef IPV6_TCLASS
+ PyModule_AddIntConstant(m, "IPV6_TCLASS", IPV6_TCLASS);
+#endif
+#ifdef IPV6_USE_MIN_MTU
+ PyModule_AddIntConstant(m, "IPV6_USE_MIN_MTU", IPV6_USE_MIN_MTU);
+#endif
+
+ /* TCP options */
+#ifdef TCP_NODELAY
+ PyModule_AddIntConstant(m, "TCP_NODELAY", TCP_NODELAY);
+#endif
+#ifdef TCP_MAXSEG
+ PyModule_AddIntConstant(m, "TCP_MAXSEG", TCP_MAXSEG);
+#endif
+#ifdef TCP_CORK
+ PyModule_AddIntConstant(m, "TCP_CORK", TCP_CORK);
+#endif
+#ifdef TCP_KEEPIDLE
+ PyModule_AddIntConstant(m, "TCP_KEEPIDLE", TCP_KEEPIDLE);
+#endif
+#ifdef TCP_KEEPINTVL
+ PyModule_AddIntConstant(m, "TCP_KEEPINTVL", TCP_KEEPINTVL);
+#endif
+#ifdef TCP_KEEPCNT
+ PyModule_AddIntConstant(m, "TCP_KEEPCNT", TCP_KEEPCNT);
+#endif
+#ifdef TCP_SYNCNT
+ PyModule_AddIntConstant(m, "TCP_SYNCNT", TCP_SYNCNT);
+#endif
+#ifdef TCP_LINGER2
+ PyModule_AddIntConstant(m, "TCP_LINGER2", TCP_LINGER2);
+#endif
+#ifdef TCP_DEFER_ACCEPT
+ PyModule_AddIntConstant(m, "TCP_DEFER_ACCEPT", TCP_DEFER_ACCEPT);
+#endif
+#ifdef TCP_WINDOW_CLAMP
+ PyModule_AddIntConstant(m, "TCP_WINDOW_CLAMP", TCP_WINDOW_CLAMP);
+#endif
+#ifdef TCP_INFO
+ PyModule_AddIntConstant(m, "TCP_INFO", TCP_INFO);
+#endif
+#ifdef TCP_QUICKACK
+ PyModule_AddIntConstant(m, "TCP_QUICKACK", TCP_QUICKACK);
+#endif
+
+
+ /* IPX options */
+#ifdef IPX_TYPE
+ PyModule_AddIntConstant(m, "IPX_TYPE", IPX_TYPE);
+#endif
+
+ /* get{addr,name}info parameters */
+#ifdef EAI_ADDRFAMILY
+ PyModule_AddIntConstant(m, "EAI_ADDRFAMILY", EAI_ADDRFAMILY);
+#endif
+#ifdef EAI_AGAIN
+ PyModule_AddIntConstant(m, "EAI_AGAIN", EAI_AGAIN);
+#endif
+#ifdef EAI_BADFLAGS
+ PyModule_AddIntConstant(m, "EAI_BADFLAGS", EAI_BADFLAGS);
+#endif
+#ifdef EAI_FAIL
+ PyModule_AddIntConstant(m, "EAI_FAIL", EAI_FAIL);
+#endif
+#ifdef EAI_FAMILY
+ PyModule_AddIntConstant(m, "EAI_FAMILY", EAI_FAMILY);
+#endif
+#ifdef EAI_MEMORY
+ PyModule_AddIntConstant(m, "EAI_MEMORY", EAI_MEMORY);
+#endif
+#ifdef EAI_NODATA
+ PyModule_AddIntConstant(m, "EAI_NODATA", EAI_NODATA);
+#endif
+#ifdef EAI_NONAME
+ PyModule_AddIntConstant(m, "EAI_NONAME", EAI_NONAME);
+#endif
+#ifdef EAI_OVERFLOW
+ PyModule_AddIntConstant(m, "EAI_OVERFLOW", EAI_OVERFLOW);
+#endif
+#ifdef EAI_SERVICE
+ PyModule_AddIntConstant(m, "EAI_SERVICE", EAI_SERVICE);
+#endif
+#ifdef EAI_SOCKTYPE
+ PyModule_AddIntConstant(m, "EAI_SOCKTYPE", EAI_SOCKTYPE);
+#endif
+#ifdef EAI_SYSTEM
+ PyModule_AddIntConstant(m, "EAI_SYSTEM", EAI_SYSTEM);
+#endif
+#ifdef EAI_BADHINTS
+ PyModule_AddIntConstant(m, "EAI_BADHINTS", EAI_BADHINTS);
+#endif
+#ifdef EAI_PROTOCOL
+ PyModule_AddIntConstant(m, "EAI_PROTOCOL", EAI_PROTOCOL);
+#endif
+#ifdef EAI_MAX
+ PyModule_AddIntConstant(m, "EAI_MAX", EAI_MAX);
+#endif
+#ifdef AI_PASSIVE
+ PyModule_AddIntConstant(m, "AI_PASSIVE", AI_PASSIVE);
+#endif
+#ifdef AI_CANONNAME
+ PyModule_AddIntConstant(m, "AI_CANONNAME", AI_CANONNAME);
+#endif
+#ifdef AI_NUMERICHOST
+ PyModule_AddIntConstant(m, "AI_NUMERICHOST", AI_NUMERICHOST);
+#endif
+#ifdef AI_NUMERICSERV
+ PyModule_AddIntConstant(m, "AI_NUMERICSERV", AI_NUMERICSERV);
+#endif
+#ifdef AI_MASK
+ PyModule_AddIntConstant(m, "AI_MASK", AI_MASK);
+#endif
+#ifdef AI_ALL
+ PyModule_AddIntConstant(m, "AI_ALL", AI_ALL);
+#endif
+#ifdef AI_V4MAPPED_CFG
+ PyModule_AddIntConstant(m, "AI_V4MAPPED_CFG", AI_V4MAPPED_CFG);
+#endif
+#ifdef AI_ADDRCONFIG
+ PyModule_AddIntConstant(m, "AI_ADDRCONFIG", AI_ADDRCONFIG);
+#endif
+#ifdef AI_V4MAPPED
+ PyModule_AddIntConstant(m, "AI_V4MAPPED", AI_V4MAPPED);
+#endif
+#ifdef AI_DEFAULT
+ PyModule_AddIntConstant(m, "AI_DEFAULT", AI_DEFAULT);
+#endif
+#ifdef NI_MAXHOST
+ PyModule_AddIntConstant(m, "NI_MAXHOST", NI_MAXHOST);
+#endif
+#ifdef NI_MAXSERV
+ PyModule_AddIntConstant(m, "NI_MAXSERV", NI_MAXSERV);
+#endif
+#ifdef NI_NOFQDN
+ PyModule_AddIntConstant(m, "NI_NOFQDN", NI_NOFQDN);
+#endif
+#ifdef NI_NUMERICHOST
+ PyModule_AddIntConstant(m, "NI_NUMERICHOST", NI_NUMERICHOST);
+#endif
+#ifdef NI_NAMEREQD
+ PyModule_AddIntConstant(m, "NI_NAMEREQD", NI_NAMEREQD);
+#endif
+#ifdef NI_NUMERICSERV
+ PyModule_AddIntConstant(m, "NI_NUMERICSERV", NI_NUMERICSERV);
+#endif
+#ifdef NI_DGRAM
+ PyModule_AddIntConstant(m, "NI_DGRAM", NI_DGRAM);
+#endif
+
+ /* shutdown() parameters */
+#ifdef SHUT_RD
+ PyModule_AddIntConstant(m, "SHUT_RD", SHUT_RD);
+#elif defined(SD_RECEIVE)
+ PyModule_AddIntConstant(m, "SHUT_RD", SD_RECEIVE);
+#else
+ PyModule_AddIntConstant(m, "SHUT_RD", 0);
+#endif
+#ifdef SHUT_WR
+ PyModule_AddIntConstant(m, "SHUT_WR", SHUT_WR);
+#elif defined(SD_SEND)
+ PyModule_AddIntConstant(m, "SHUT_WR", SD_SEND);
+#else
+ PyModule_AddIntConstant(m, "SHUT_WR", 1);
+#endif
+#ifdef SHUT_RDWR
+ PyModule_AddIntConstant(m, "SHUT_RDWR", SHUT_RDWR);
+#elif defined(SD_BOTH)
+ PyModule_AddIntConstant(m, "SHUT_RDWR", SD_BOTH);
+#else
+ PyModule_AddIntConstant(m, "SHUT_RDWR", 2);
+#endif
+
+ /* Initialize gethostbyname lock */
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+ netdb_lock = PyThread_allocate_lock();
+#endif
+}
+
+
+#ifndef HAVE_INET_PTON
+
+/* Simplistic emulation code for inet_pton that only works for IPv4 */
+/* These are not exposed because they do not set errno properly */
+
+int
+inet_pton(int af, const char *src, void *dst)
+{
+ if (af == AF_INET) {
+ long packed_addr;
+ packed_addr = inet_addr(src);
+ if (packed_addr == INADDR_NONE)
+ return 0;
+#ifdef PLAN9APE
+ if(packed_addr == 0)
+ return 0;
+#endif
+ memcpy(dst, &packed_addr, 4);
+ return 1;
+ }
+ /* Should set errno to EAFNOSUPPORT */
+ return -1;
+}
+
+const char *
+inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+ if (af == AF_INET) {
+ struct in_addr packed_addr;
+ if (size < 16)
+ /* Should set errno to ENOSPC. */
+ return NULL;
+ memcpy(&packed_addr, src, sizeof(packed_addr));
+ return strncpy(dst, inet_ntoa(packed_addr), size);
+ }
+ /* Should set errno to EAFNOSUPPORT */
+ return NULL;
+}
+
+#endif
diff --git a/sys/src/cmd/python/Modules/socketmodule.h b/sys/src/cmd/python/Modules/socketmodule.h
new file mode 100644
index 000000000..84f2422f4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/socketmodule.h
@@ -0,0 +1,252 @@
+/* Socket module header file */
+
+/* Includes needed for the sockaddr_* symbols below */
+#ifndef MS_WINDOWS
+#ifdef __VMS
+# include <socket.h>
+# else
+# include <sys/socket.h>
+# endif
+# include <netinet/in.h>
+# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
+# include <netinet/tcp.h>
+# endif
+
+#else /* MS_WINDOWS */
+#if _MSC_VER >= 1300
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# define HAVE_ADDRINFO
+# define HAVE_SOCKADDR_STORAGE
+# define HAVE_GETADDRINFO
+# define HAVE_GETNAMEINFO
+# define ENABLE_IPV6
+#else
+# include <winsock.h>
+#endif
+#endif
+
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#else
+# undef AF_UNIX
+#endif
+
+#ifdef HAVE_LINUX_NETLINK_H
+# ifdef HAVE_ASM_TYPES_H
+# include <asm/types.h>
+# endif
+# include <linux/netlink.h>
+#else
+# undef AF_NETLINK
+#endif
+
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/l2cap.h>
+#include <bluetooth/sco.h>
+#endif
+
+#ifdef HAVE_BLUETOOTH_H
+#include <bluetooth.h>
+#endif
+
+#ifdef HAVE_NETPACKET_PACKET_H
+# include <sys/ioctl.h>
+# include <net/if.h>
+# include <netpacket/packet.h>
+#endif
+
+#ifndef Py__SOCKET_H
+#define Py__SOCKET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Python module and C API name */
+#define PySocket_MODULE_NAME "_socket"
+#define PySocket_CAPI_NAME "CAPI"
+
+/* Abstract the socket file descriptor type */
+#ifdef MS_WINDOWS
+typedef SOCKET SOCKET_T;
+# ifdef MS_WIN64
+# define SIZEOF_SOCKET_T 8
+# else
+# define SIZEOF_SOCKET_T 4
+# endif
+#else
+typedef int SOCKET_T;
+# define SIZEOF_SOCKET_T SIZEOF_INT
+#endif
+
+/* Socket address */
+typedef union sock_addr {
+ struct sockaddr_in in;
+#ifdef AF_UNIX
+ struct sockaddr_un un;
+#endif
+#ifdef AF_NETLINK
+ struct sockaddr_nl nl;
+#endif
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 in6;
+ struct sockaddr_storage storage;
+#endif
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
+ struct sockaddr_l2 bt_l2;
+ struct sockaddr_rc bt_rc;
+ struct sockaddr_sco bt_sco;
+#endif
+#ifdef HAVE_NETPACKET_PACKET_H
+ struct sockaddr_ll ll;
+#endif
+} sock_addr_t;
+
+/* The object holding a socket. It holds some extra information,
+ like the address family, which is used to decode socket address
+ arguments properly. */
+
+typedef struct {
+ PyObject_HEAD
+ SOCKET_T sock_fd; /* Socket file descriptor */
+ int sock_family; /* Address family, e.g., AF_INET */
+ int sock_type; /* Socket type, e.g., SOCK_STREAM */
+ int sock_proto; /* Protocol type, usually 0 */
+ PyObject *(*errorhandler)(void); /* Error handler; checks
+ errno, returns NULL and
+ sets a Python exception */
+ double sock_timeout; /* Operation timeout in seconds;
+ 0.0 means non-blocking */
+} PySocketSockObject;
+
+/* --- C API ----------------------------------------------------*/
+
+/* Short explanation of what this C API export mechanism does
+ and how it works:
+
+ The _ssl module needs access to the type object defined in
+ the _socket module. Since cross-DLL linking introduces a lot of
+ problems on many platforms, the "trick" is to wrap the
+ C API of a module in a struct which then gets exported to
+ other modules via a PyCObject.
+
+ The code in socketmodule.c defines this struct (which currently
+ only contains the type object reference, but could very
+ well also include other C APIs needed by other modules)
+ and exports it as PyCObject via the module dictionary
+ under the name "CAPI".
+
+ Other modules can now include the socketmodule.h file
+ which defines the needed C APIs to import and set up
+ a static copy of this struct in the importing module.
+
+ After initialization, the importing module can then
+ access the C APIs from the _socket module by simply
+ referring to the static struct, e.g.
+
+ Load _socket module and its C API; this sets up the global
+ PySocketModule:
+
+ if (PySocketModule_ImportModuleAndAPI())
+ return;
+
+
+ Now use the C API as if it were defined in the using
+ module:
+
+ if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+
+ PySocketModule.Sock_Type,
+
+ (PyObject*)&Sock,
+ &key_file, &cert_file))
+ return NULL;
+
+ Support could easily be extended to export more C APIs/symbols
+ this way. Currently, only the type object is exported,
+ other candidates would be socket constructors and socket
+ access functions.
+
+*/
+
+/* C API for usage by other Python modules */
+typedef struct {
+ PyTypeObject *Sock_Type;
+ PyObject *error;
+} PySocketModule_APIObject;
+
+/* XXX The net effect of the following appears to be to define a function
+ XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
+ XXX defined there directly.
+
+ >>> It's defined here because other modules might also want to use
+ >>> the C API.
+
+*/
+#ifndef PySocket_BUILDING_SOCKET
+
+/* --- C API ----------------------------------------------------*/
+
+/* Interfacestructure to C API for other modules.
+ Call PySocketModule_ImportModuleAndAPI() to initialize this
+ structure. After that usage is simple:
+
+ if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+ &PySocketModule.Sock_Type, (PyObject*)&Sock,
+ &key_file, &cert_file))
+ return NULL;
+ ...
+*/
+
+static
+PySocketModule_APIObject PySocketModule;
+
+/* You *must* call this before using any of the functions in
+ PySocketModule and check its outcome; otherwise all accesses will
+ result in a segfault. Returns 0 on success. */
+
+#ifndef DPRINTF
+# define DPRINTF if (0) printf
+#endif
+
+static
+int PySocketModule_ImportModuleAndAPI(void)
+{
+ PyObject *mod = 0, *v = 0;
+ char *apimodule = PySocket_MODULE_NAME;
+ char *apiname = PySocket_CAPI_NAME;
+ void *api;
+
+ DPRINTF("Importing the %s C API...\n", apimodule);
+ mod = PyImport_ImportModule(apimodule);
+ if (mod == NULL)
+ goto onError;
+ DPRINTF(" %s package found\n", apimodule);
+ v = PyObject_GetAttrString(mod, apiname);
+ if (v == NULL)
+ goto onError;
+ Py_DECREF(mod);
+ DPRINTF(" API object %s found\n", apiname);
+ api = PyCObject_AsVoidPtr(v);
+ if (api == NULL)
+ goto onError;
+ Py_DECREF(v);
+ memcpy(&PySocketModule, api, sizeof(PySocketModule));
+ DPRINTF(" API object loaded and initialized.\n");
+ return 0;
+
+ onError:
+ DPRINTF(" not found.\n");
+ Py_XDECREF(mod);
+ Py_XDECREF(v);
+ return -1;
+}
+
+#endif /* !PySocket_BUILDING_SOCKET */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py__SOCKET_H */
diff --git a/sys/src/cmd/python/Modules/spwdmodule.c b/sys/src/cmd/python/Modules/spwdmodule.c
new file mode 100644
index 000000000..d3f309afa
--- /dev/null
+++ b/sys/src/cmd/python/Modules/spwdmodule.c
@@ -0,0 +1,183 @@
+
+/* UNIX shadow password file access module */
+/* A lot of code has been taken from pwdmodule.c */
+/* For info also see http://www.unixpapa.com/incnote/passwd.html */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <sys/types.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
+
+PyDoc_STRVAR(spwd__doc__,
+"This module provides access to the Unix shadow password database.\n\
+It is available on various Unix versions.\n\
+\n\
+Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
+containing the following items from the password database (see `<shadow.h>'):\n\
+sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
+The sp_namp and sp_pwdp are strings, the rest are integers.\n\
+An exception is raised if the entry asked for cannot be found.\n\
+You have to be root to be able to use this module.");
+
+
+#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)
+
+static PyStructSequence_Field struct_spwd_type_fields[] = {
+ {"sp_nam", "login name"},
+ {"sp_pwd", "encrypted password"},
+ {"sp_lstchg", "date of last change"},
+ {"sp_min", "min #days between changes"},
+ {"sp_max", "max #days between changes"},
+ {"sp_warn", "#days before pw expires to warn user about it"},
+ {"sp_inact", "#days after pw expires until account is blocked"},
+ {"sp_expire", "#days since 1970-01-01 until account is disabled"},
+ {"sp_flag", "reserved"},
+ {0}
+};
+
+PyDoc_STRVAR(struct_spwd__doc__,
+"spwd.struct_spwd: Results from getsp*() routines.\n\n\
+This object may be accessed either as a 9-tuple of\n\
+ (sp_nam,sp_pwd,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
+or via the object attributes as named in the above tuple.");
+
+static PyStructSequence_Desc struct_spwd_type_desc = {
+ "spwd.struct_spwd",
+ struct_spwd__doc__,
+ struct_spwd_type_fields,
+ 9,
+};
+
+static int initialized;
+static PyTypeObject StructSpwdType;
+
+
+static void
+sets(PyObject *v, int i, char* val)
+{
+ if (val)
+ PyStructSequence_SET_ITEM(v, i, PyString_FromString(val));
+ else {
+ PyStructSequence_SET_ITEM(v, i, Py_None);
+ Py_INCREF(Py_None);
+ }
+}
+
+static PyObject *mkspent(struct spwd *p)
+{
+ int setIndex = 0;
+ PyObject *v = PyStructSequence_New(&StructSpwdType);
+ if (v == NULL)
+ return NULL;
+
+#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
+#define SETS(i,val) sets(v, i, val)
+
+ SETS(setIndex++, p->sp_namp);
+ SETS(setIndex++, p->sp_pwdp);
+ SETI(setIndex++, p->sp_lstchg);
+ SETI(setIndex++, p->sp_min);
+ SETI(setIndex++, p->sp_max);
+ SETI(setIndex++, p->sp_warn);
+ SETI(setIndex++, p->sp_inact);
+ SETI(setIndex++, p->sp_expire);
+ SETI(setIndex++, p->sp_flag);
+
+#undef SETS
+#undef SETI
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+
+ return v;
+}
+
+#endif /* HAVE_GETSPNAM || HAVE_GETSPENT */
+
+
+#ifdef HAVE_GETSPNAM
+
+PyDoc_STRVAR(spwd_getspnam__doc__,
+"getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\
+ sp_warn, sp_inact, sp_expire, sp_flag)\n\
+Return the shadow password database entry for the given user name.\n\
+See spwd.__doc__ for more on shadow password database entries.");
+
+static PyObject* spwd_getspnam(PyObject *self, PyObject *args)
+{
+ char *name;
+ struct spwd *p;
+ if (!PyArg_ParseTuple(args, "s:getspnam", &name))
+ return NULL;
+ if ((p = getspnam(name)) == NULL) {
+ PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
+ return NULL;
+ }
+ return mkspent(p);
+}
+
+#endif /* HAVE_GETSPNAM */
+
+#ifdef HAVE_GETSPENT
+
+PyDoc_STRVAR(spwd_getspall__doc__,
+"getspall() -> list_of_entries\n\
+Return a list of all available shadow password database entries, \
+in arbitrary order.\n\
+See spwd.__doc__ for more on shadow password database entries.");
+
+static PyObject *
+spwd_getspall(PyObject *self, PyObject *args)
+{
+ PyObject *d;
+ struct spwd *p;
+ if ((d = PyList_New(0)) == NULL)
+ return NULL;
+ setspent();
+ while ((p = getspent()) != NULL) {
+ PyObject *v = mkspent(p);
+ if (v == NULL || PyList_Append(d, v) != 0) {
+ Py_XDECREF(v);
+ Py_DECREF(d);
+ endspent();
+ return NULL;
+ }
+ Py_DECREF(v);
+ }
+ endspent();
+ return d;
+}
+
+#endif /* HAVE_GETSPENT */
+
+static PyMethodDef spwd_methods[] = {
+#ifdef HAVE_GETSPNAM
+ {"getspnam", spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__},
+#endif
+#ifdef HAVE_GETSPENT
+ {"getspall", spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyMODINIT_FUNC
+initspwd(void)
+{
+ PyObject *m;
+ m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
+ if (m == NULL)
+ return;
+ if (!initialized)
+ PyStructSequence_InitType(&StructSpwdType,
+ &struct_spwd_type_desc);
+ Py_INCREF((PyObject *) &StructSpwdType);
+ PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
+ initialized = 1;
+}
diff --git a/sys/src/cmd/python/Modules/sre.h b/sys/src/cmd/python/Modules/sre.h
new file mode 100644
index 000000000..d4af05c04
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sre.h
@@ -0,0 +1,94 @@
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
+ *
+ * See the _sre.c file for information on usage and redistribution.
+ */
+
+#ifndef SRE_INCLUDED
+#define SRE_INCLUDED
+
+#include "sre_constants.h"
+
+/* size of a code word (must be unsigned short or larger, and
+ large enough to hold a Py_UNICODE character) */
+#ifdef Py_UNICODE_WIDE
+#define SRE_CODE Py_UCS4
+#else
+#define SRE_CODE unsigned short
+#endif
+
+typedef struct {
+ PyObject_VAR_HEAD
+ Py_ssize_t groups; /* must be first! */
+ PyObject* groupindex;
+ PyObject* indexgroup;
+ /* compatibility */
+ PyObject* pattern; /* pattern source (or None) */
+ int flags; /* flags used when compiling pattern source */
+ PyObject *weakreflist; /* List of weak references */
+ /* pattern code */
+ Py_ssize_t codesize;
+ SRE_CODE code[1];
+} PatternObject;
+
+#define PatternObject_GetCode(o) (((PatternObject*)(o))->code)
+
+typedef struct {
+ PyObject_VAR_HEAD
+ PyObject* string; /* link to the target string (must be first) */
+ PyObject* regs; /* cached list of matching spans */
+ PatternObject* pattern; /* link to the regex (pattern) object */
+ Py_ssize_t pos, endpos; /* current target slice */
+ Py_ssize_t lastindex; /* last index marker seen by the engine (-1 if none) */
+ Py_ssize_t groups; /* number of groups (start/end marks) */
+ Py_ssize_t mark[1];
+} MatchObject;
+
+typedef unsigned int (*SRE_TOLOWER_HOOK)(unsigned int ch);
+
+/* FIXME: <fl> shouldn't be a constant, really... */
+#define SRE_MARK_SIZE 200
+
+typedef struct SRE_REPEAT_T {
+ Py_ssize_t count;
+ SRE_CODE* pattern; /* points to REPEAT operator arguments */
+ void* last_ptr; /* helper to check for infinite loops */
+ struct SRE_REPEAT_T *prev; /* points to previous repeat context */
+} SRE_REPEAT;
+
+typedef struct {
+ /* string pointers */
+ void* ptr; /* current position (also end of current slice) */
+ void* beginning; /* start of original string */
+ void* start; /* start of current slice */
+ void* end; /* end of original string */
+ /* attributes for the match object */
+ PyObject* string;
+ Py_ssize_t pos, endpos;
+ /* character size */
+ int charsize;
+ /* registers */
+ Py_ssize_t lastindex;
+ Py_ssize_t lastmark;
+ void* mark[SRE_MARK_SIZE];
+ /* dynamically allocated stuff */
+ char* data_stack;
+ size_t data_stack_size;
+ size_t data_stack_base;
+ /* current repeat context */
+ SRE_REPEAT *repeat;
+ /* hooks */
+ SRE_TOLOWER_HOOK lower;
+} SRE_STATE;
+
+typedef struct {
+ PyObject_HEAD
+ PyObject* pattern;
+ SRE_STATE state;
+} ScannerObject;
+
+#endif
diff --git a/sys/src/cmd/python/Modules/sre_constants.h b/sys/src/cmd/python/Modules/sre_constants.h
new file mode 100644
index 000000000..13c89583e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sre_constants.h
@@ -0,0 +1,86 @@
+/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * NOTE: This file is generated by sre_constants.py. If you need
+ * to change anything in here, edit sre_constants.py and run it.
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
+ *
+ * See the _sre.c file for information on usage and redistribution.
+ */
+
+#define SRE_MAGIC 20031017
+#define SRE_OP_FAILURE 0
+#define SRE_OP_SUCCESS 1
+#define SRE_OP_ANY 2
+#define SRE_OP_ANY_ALL 3
+#define SRE_OP_ASSERT 4
+#define SRE_OP_ASSERT_NOT 5
+#define SRE_OP_AT 6
+#define SRE_OP_BRANCH 7
+#define SRE_OP_CALL 8
+#define SRE_OP_CATEGORY 9
+#define SRE_OP_CHARSET 10
+#define SRE_OP_BIGCHARSET 11
+#define SRE_OP_GROUPREF 12
+#define SRE_OP_GROUPREF_EXISTS 13
+#define SRE_OP_GROUPREF_IGNORE 14
+#define SRE_OP_IN 15
+#define SRE_OP_IN_IGNORE 16
+#define SRE_OP_INFO 17
+#define SRE_OP_JUMP 18
+#define SRE_OP_LITERAL 19
+#define SRE_OP_LITERAL_IGNORE 20
+#define SRE_OP_MARK 21
+#define SRE_OP_MAX_UNTIL 22
+#define SRE_OP_MIN_UNTIL 23
+#define SRE_OP_NOT_LITERAL 24
+#define SRE_OP_NOT_LITERAL_IGNORE 25
+#define SRE_OP_NEGATE 26
+#define SRE_OP_RANGE 27
+#define SRE_OP_REPEAT 28
+#define SRE_OP_REPEAT_ONE 29
+#define SRE_OP_SUBPATTERN 30
+#define SRE_OP_MIN_REPEAT_ONE 31
+#define SRE_AT_BEGINNING 0
+#define SRE_AT_BEGINNING_LINE 1
+#define SRE_AT_BEGINNING_STRING 2
+#define SRE_AT_BOUNDARY 3
+#define SRE_AT_NON_BOUNDARY 4
+#define SRE_AT_END 5
+#define SRE_AT_END_LINE 6
+#define SRE_AT_END_STRING 7
+#define SRE_AT_LOC_BOUNDARY 8
+#define SRE_AT_LOC_NON_BOUNDARY 9
+#define SRE_AT_UNI_BOUNDARY 10
+#define SRE_AT_UNI_NON_BOUNDARY 11
+#define SRE_CATEGORY_DIGIT 0
+#define SRE_CATEGORY_NOT_DIGIT 1
+#define SRE_CATEGORY_SPACE 2
+#define SRE_CATEGORY_NOT_SPACE 3
+#define SRE_CATEGORY_WORD 4
+#define SRE_CATEGORY_NOT_WORD 5
+#define SRE_CATEGORY_LINEBREAK 6
+#define SRE_CATEGORY_NOT_LINEBREAK 7
+#define SRE_CATEGORY_LOC_WORD 8
+#define SRE_CATEGORY_LOC_NOT_WORD 9
+#define SRE_CATEGORY_UNI_DIGIT 10
+#define SRE_CATEGORY_UNI_NOT_DIGIT 11
+#define SRE_CATEGORY_UNI_SPACE 12
+#define SRE_CATEGORY_UNI_NOT_SPACE 13
+#define SRE_CATEGORY_UNI_WORD 14
+#define SRE_CATEGORY_UNI_NOT_WORD 15
+#define SRE_CATEGORY_UNI_LINEBREAK 16
+#define SRE_CATEGORY_UNI_NOT_LINEBREAK 17
+#define SRE_FLAG_TEMPLATE 1
+#define SRE_FLAG_IGNORECASE 2
+#define SRE_FLAG_LOCALE 4
+#define SRE_FLAG_MULTILINE 8
+#define SRE_FLAG_DOTALL 16
+#define SRE_FLAG_UNICODE 32
+#define SRE_FLAG_VERBOSE 64
+#define SRE_INFO_PREFIX 1
+#define SRE_INFO_LITERAL 2
+#define SRE_INFO_CHARSET 4
diff --git a/sys/src/cmd/python/Modules/stropmodule.c b/sys/src/cmd/python/Modules/stropmodule.c
new file mode 100644
index 000000000..8b00fed69
--- /dev/null
+++ b/sys/src/cmd/python/Modules/stropmodule.c
@@ -0,0 +1,1248 @@
+/* strop module */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include <ctype.h>
+
+PyDoc_STRVAR(strop_module__doc__,
+"Common string manipulations, optimized for speed.\n"
+"\n"
+"Always use \"import string\" rather than referencing\n"
+"this module directly.");
+
+/* XXX This file assumes that the <ctype.h> is*() functions
+ XXX are defined for all 8-bit characters! */
+
+#define WARN if (PyErr_Warn(PyExc_DeprecationWarning, \
+ "strop functions are obsolete; use string methods")) \
+ return NULL
+
+/* The lstrip(), rstrip() and strip() functions are implemented
+ in do_strip(), which uses an additional parameter to indicate what
+ type of strip should occur. */
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+
+static PyObject *
+split_whitespace(char *s, Py_ssize_t len, Py_ssize_t maxsplit)
+{
+ Py_ssize_t i = 0, j;
+ int err;
+ Py_ssize_t countsplit = 0;
+ PyObject* item;
+ PyObject *list = PyList_New(0);
+
+ if (list == NULL)
+ return NULL;
+
+ while (i < len) {
+ while (i < len && isspace(Py_CHARMASK(s[i]))) {
+ i = i+1;
+ }
+ j = i;
+ while (i < len && !isspace(Py_CHARMASK(s[i]))) {
+ i = i+1;
+ }
+ if (j < i) {
+ item = PyString_FromStringAndSize(s+j, i-j);
+ if (item == NULL)
+ goto finally;
+
+ err = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (err < 0)
+ goto finally;
+
+ countsplit++;
+ while (i < len && isspace(Py_CHARMASK(s[i]))) {
+ i = i+1;
+ }
+ if (maxsplit && (countsplit >= maxsplit) && i < len) {
+ item = PyString_FromStringAndSize(
+ s+i, len - i);
+ if (item == NULL)
+ goto finally;
+
+ err = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (err < 0)
+ goto finally;
+
+ i = len;
+ }
+ }
+ }
+ return list;
+ finally:
+ Py_DECREF(list);
+ return NULL;
+}
+
+
+PyDoc_STRVAR(splitfields__doc__,
+"split(s [,sep [,maxsplit]]) -> list of strings\n"
+"splitfields(s [,sep [,maxsplit]]) -> list of strings\n"
+"\n"
+"Return a list of the words in the string s, using sep as the\n"
+"delimiter string. If maxsplit is nonzero, splits into at most\n"
+"maxsplit words. If sep is not specified, any whitespace string\n"
+"is a separator. Maxsplit defaults to 0.\n"
+"\n"
+"(split and splitfields are synonymous)");
+
+static PyObject *
+strop_splitfields(PyObject *self, PyObject *args)
+{
+ Py_ssize_t len, n, i, j, err;
+ Py_ssize_t splitcount, maxsplit;
+ char *s, *sub;
+ PyObject *list, *item;
+
+ WARN;
+ sub = NULL;
+ n = 0;
+ splitcount = 0;
+ maxsplit = 0;
+ if (!PyArg_ParseTuple(args, "t#|z#n:split", &s, &len, &sub, &n, &maxsplit))
+ return NULL;
+ if (sub == NULL)
+ return split_whitespace(s, len, maxsplit);
+ if (n == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+
+ list = PyList_New(0);
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while (i+n <= len) {
+ if (s[i] == sub[0] && (n == 1 || memcmp(s+i, sub, n) == 0)) {
+ item = PyString_FromStringAndSize(s+j, i-j);
+ if (item == NULL)
+ goto fail;
+ err = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (err < 0)
+ goto fail;
+ i = j = i + n;
+ splitcount++;
+ if (maxsplit && (splitcount >= maxsplit))
+ break;
+ }
+ else
+ i++;
+ }
+ item = PyString_FromStringAndSize(s+j, len-j);
+ if (item == NULL)
+ goto fail;
+ err = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (err < 0)
+ goto fail;
+
+ return list;
+
+ fail:
+ Py_DECREF(list);
+ return NULL;
+}
+
+
+PyDoc_STRVAR(joinfields__doc__,
+"join(list [,sep]) -> string\n"
+"joinfields(list [,sep]) -> string\n"
+"\n"
+"Return a string composed of the words in list, with\n"
+"intervening occurrences of sep. Sep defaults to a single\n"
+"space.\n"
+"\n"
+"(join and joinfields are synonymous)");
+
+static PyObject *
+strop_joinfields(PyObject *self, PyObject *args)
+{
+ PyObject *seq;
+ char *sep = NULL;
+ Py_ssize_t seqlen, seplen = 0;
+ Py_ssize_t i, reslen = 0, slen = 0, sz = 100;
+ PyObject *res = NULL;
+ char* p = NULL;
+ ssizeargfunc getitemfunc;
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "O|t#:join", &seq, &sep, &seplen))
+ return NULL;
+ if (sep == NULL) {
+ sep = " ";
+ seplen = 1;
+ }
+
+ seqlen = PySequence_Size(seq);
+ if (seqlen < 0 && PyErr_Occurred())
+ return NULL;
+
+ if (seqlen == 1) {
+ /* Optimization if there's only one item */
+ PyObject *item = PySequence_GetItem(seq, 0);
+ if (item && !PyString_Check(item)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be sequence of strings");
+ Py_DECREF(item);
+ return NULL;
+ }
+ return item;
+ }
+
+ if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
+ return NULL;
+ p = PyString_AsString(res);
+
+ /* optimize for lists, since it's the most common case. all others
+ * (tuples and arbitrary sequences) just use the sequence abstract
+ * interface.
+ */
+ if (PyList_Check(seq)) {
+ for (i = 0; i < seqlen; i++) {
+ PyObject *item = PyList_GET_ITEM(seq, i);
+ if (!PyString_Check(item)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be sequence of strings");
+ Py_DECREF(res);
+ return NULL;
+ }
+ slen = PyString_GET_SIZE(item);
+ while (reslen + slen + seplen >= sz) {
+ if (_PyString_Resize(&res, sz * 2) < 0)
+ return NULL;
+ sz *= 2;
+ p = PyString_AsString(res) + reslen;
+ }
+ if (i > 0) {
+ memcpy(p, sep, seplen);
+ p += seplen;
+ reslen += seplen;
+ }
+ memcpy(p, PyString_AS_STRING(item), slen);
+ p += slen;
+ reslen += slen;
+ }
+ _PyString_Resize(&res, reslen);
+ return res;
+ }
+
+ if (seq->ob_type->tp_as_sequence == NULL ||
+ (getitemfunc = seq->ob_type->tp_as_sequence->sq_item) == NULL)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be a sequence");
+ return NULL;
+ }
+ /* This is now type safe */
+ for (i = 0; i < seqlen; i++) {
+ PyObject *item = getitemfunc(seq, i);
+ if (!item || !PyString_Check(item)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be sequence of strings");
+ Py_DECREF(res);
+ Py_XDECREF(item);
+ return NULL;
+ }
+ slen = PyString_GET_SIZE(item);
+ while (reslen + slen + seplen >= sz) {
+ if (_PyString_Resize(&res, sz * 2) < 0) {
+ Py_DECREF(item);
+ return NULL;
+ }
+ sz *= 2;
+ p = PyString_AsString(res) + reslen;
+ }
+ if (i > 0) {
+ memcpy(p, sep, seplen);
+ p += seplen;
+ reslen += seplen;
+ }
+ memcpy(p, PyString_AS_STRING(item), slen);
+ p += slen;
+ reslen += slen;
+ Py_DECREF(item);
+ }
+ _PyString_Resize(&res, reslen);
+ return res;
+}
+
+
+PyDoc_STRVAR(find__doc__,
+"find(s, sub [,start [,end]]) -> in\n"
+"\n"
+"Return the lowest index in s where substring sub is found,\n"
+"such that sub is contained within s[start,end]. Optional\n"
+"arguments start and end are interpreted as in slice notation.\n"
+"\n"
+"Return -1 on failure.");
+
+static PyObject *
+strop_find(PyObject *self, PyObject *args)
+{
+ char *s, *sub;
+ Py_ssize_t len, n, i = 0, last = PY_SSIZE_T_MAX;
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "t#t#|nn:find", &s, &len, &sub, &n, &i, &last))
+ return NULL;
+
+ if (last > len)
+ last = len;
+ if (last < 0)
+ last += len;
+ if (last < 0)
+ last = 0;
+ if (i < 0)
+ i += len;
+ if (i < 0)
+ i = 0;
+
+ if (n == 0 && i <= last)
+ return PyInt_FromLong((long)i);
+
+ last -= n;
+ for (; i <= last; ++i)
+ if (s[i] == sub[0] &&
+ (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))
+ return PyInt_FromLong((long)i);
+
+ return PyInt_FromLong(-1L);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"rfind(s, sub [,start [,end]]) -> int\n"
+"\n"
+"Return the highest index in s where substring sub is found,\n"
+"such that sub is contained within s[start,end]. Optional\n"
+"arguments start and end are interpreted as in slice notation.\n"
+"\n"
+"Return -1 on failure.");
+
+static PyObject *
+strop_rfind(PyObject *self, PyObject *args)
+{
+ char *s, *sub;
+ Py_ssize_t len, n, j;
+ Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "t#t#|nn:rfind", &s, &len, &sub, &n, &i, &last))
+ return NULL;
+
+ if (last > len)
+ last = len;
+ if (last < 0)
+ last += len;
+ if (last < 0)
+ last = 0;
+ if (i < 0)
+ i += len;
+ if (i < 0)
+ i = 0;
+
+ if (n == 0 && i <= last)
+ return PyInt_FromLong((long)last);
+
+ for (j = last-n; j >= i; --j)
+ if (s[j] == sub[0] &&
+ (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))
+ return PyInt_FromLong((long)j);
+
+ return PyInt_FromLong(-1L);
+}
+
+
+static PyObject *
+do_strip(PyObject *args, int striptype)
+{
+ char *s;
+ Py_ssize_t len, i, j;
+
+
+ if (PyString_AsStringAndSize(args, &s, &len))
+ return NULL;
+
+ i = 0;
+ if (striptype != RIGHTSTRIP) {
+ while (i < len && isspace(Py_CHARMASK(s[i]))) {
+ i++;
+ }
+ }
+
+ j = len;
+ if (striptype != LEFTSTRIP) {
+ do {
+ j--;
+ } while (j >= i && isspace(Py_CHARMASK(s[j])));
+ j++;
+ }
+
+ if (i == 0 && j == len) {
+ Py_INCREF(args);
+ return args;
+ }
+ else
+ return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+"strip(s) -> string\n"
+"\n"
+"Return a copy of the string s with leading and trailing\n"
+"whitespace removed.");
+
+static PyObject *
+strop_strip(PyObject *self, PyObject *args)
+{
+ WARN;
+ return do_strip(args, BOTHSTRIP);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+"lstrip(s) -> string\n"
+"\n"
+"Return a copy of the string s with leading whitespace removed.");
+
+static PyObject *
+strop_lstrip(PyObject *self, PyObject *args)
+{
+ WARN;
+ return do_strip(args, LEFTSTRIP);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+"rstrip(s) -> string\n"
+"\n"
+"Return a copy of the string s with trailing whitespace removed.");
+
+static PyObject *
+strop_rstrip(PyObject *self, PyObject *args)
+{
+ WARN;
+ return do_strip(args, RIGHTSTRIP);
+}
+
+
+PyDoc_STRVAR(lower__doc__,
+"lower(s) -> string\n"
+"\n"
+"Return a copy of the string s converted to lowercase.");
+
+static PyObject *
+strop_lower(PyObject *self, PyObject *args)
+{
+ char *s, *s_new;
+ Py_ssize_t i, n;
+ PyObject *newstr;
+ int changed;
+
+ WARN;
+ if (PyString_AsStringAndSize(args, &s, &n))
+ return NULL;
+ newstr = PyString_FromStringAndSize(NULL, n);
+ if (newstr == NULL)
+ return NULL;
+ s_new = PyString_AsString(newstr);
+ changed = 0;
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (isupper(c)) {
+ changed = 1;
+ *s_new = tolower(c);
+ } else
+ *s_new = c;
+ s_new++;
+ }
+ if (!changed) {
+ Py_DECREF(newstr);
+ Py_INCREF(args);
+ return args;
+ }
+ return newstr;
+}
+
+
+PyDoc_STRVAR(upper__doc__,
+"upper(s) -> string\n"
+"\n"
+"Return a copy of the string s converted to uppercase.");
+
+static PyObject *
+strop_upper(PyObject *self, PyObject *args)
+{
+ char *s, *s_new;
+ Py_ssize_t i, n;
+ PyObject *newstr;
+ int changed;
+
+ WARN;
+ if (PyString_AsStringAndSize(args, &s, &n))
+ return NULL;
+ newstr = PyString_FromStringAndSize(NULL, n);
+ if (newstr == NULL)
+ return NULL;
+ s_new = PyString_AsString(newstr);
+ changed = 0;
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (islower(c)) {
+ changed = 1;
+ *s_new = toupper(c);
+ } else
+ *s_new = c;
+ s_new++;
+ }
+ if (!changed) {
+ Py_DECREF(newstr);
+ Py_INCREF(args);
+ return args;
+ }
+ return newstr;
+}
+
+
+PyDoc_STRVAR(capitalize__doc__,
+"capitalize(s) -> string\n"
+"\n"
+"Return a copy of the string s with only its first character\n"
+"capitalized.");
+
+static PyObject *
+strop_capitalize(PyObject *self, PyObject *args)
+{
+ char *s, *s_new;
+ Py_ssize_t i, n;
+ PyObject *newstr;
+ int changed;
+
+ WARN;
+ if (PyString_AsStringAndSize(args, &s, &n))
+ return NULL;
+ newstr = PyString_FromStringAndSize(NULL, n);
+ if (newstr == NULL)
+ return NULL;
+ s_new = PyString_AsString(newstr);
+ changed = 0;
+ if (0 < n) {
+ int c = Py_CHARMASK(*s++);
+ if (islower(c)) {
+ changed = 1;
+ *s_new = toupper(c);
+ } else
+ *s_new = c;
+ s_new++;
+ }
+ for (i = 1; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (isupper(c)) {
+ changed = 1;
+ *s_new = tolower(c);
+ } else
+ *s_new = c;
+ s_new++;
+ }
+ if (!changed) {
+ Py_DECREF(newstr);
+ Py_INCREF(args);
+ return args;
+ }
+ return newstr;
+}
+
+
+PyDoc_STRVAR(expandtabs__doc__,
+"expandtabs(string, [tabsize]) -> string\n"
+"\n"
+"Expand tabs in a string, i.e. replace them by one or more spaces,\n"
+"depending on the current column and the given tab size (default 8).\n"
+"The column number is reset to zero after each newline occurring in the\n"
+"string. This doesn't understand other non-printing characters.");
+
+static PyObject *
+strop_expandtabs(PyObject *self, PyObject *args)
+{
+ /* Original by Fredrik Lundh */
+ char* e;
+ char* p;
+ char* q;
+ Py_ssize_t i, j;
+ PyObject* out;
+ char* string;
+ Py_ssize_t stringlen;
+ int tabsize = 8;
+
+ WARN;
+ /* Get arguments */
+ if (!PyArg_ParseTuple(args, "s#|i:expandtabs", &string, &stringlen, &tabsize))
+ return NULL;
+ if (tabsize < 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "tabsize must be at least 1");
+ return NULL;
+ }
+
+ /* First pass: determine size of output string */
+ i = j = 0; /* j: current column; i: total of previous lines */
+ e = string + stringlen;
+ for (p = string; p < e; p++) {
+ if (*p == '\t')
+ j += tabsize - (j%tabsize);
+ else {
+ j++;
+ if (*p == '\n') {
+ i += j;
+ j = 0;
+ }
+ }
+ }
+
+ /* Second pass: create output string and fill it */
+ out = PyString_FromStringAndSize(NULL, i+j);
+ if (out == NULL)
+ return NULL;
+
+ i = 0;
+ q = PyString_AS_STRING(out);
+
+ for (p = string; p < e; p++) {
+ if (*p == '\t') {
+ j = tabsize - (i%tabsize);
+ i += j;
+ while (j-- > 0)
+ *q++ = ' ';
+ } else {
+ *q++ = *p;
+ i++;
+ if (*p == '\n')
+ i = 0;
+ }
+ }
+
+ return out;
+}
+
+
+PyDoc_STRVAR(count__doc__,
+"count(s, sub[, start[, end]]) -> int\n"
+"\n"
+"Return the number of occurrences of substring sub in string\n"
+"s[start:end]. Optional arguments start and end are\n"
+"interpreted as in slice notation.");
+
+static PyObject *
+strop_count(PyObject *self, PyObject *args)
+{
+ char *s, *sub;
+ Py_ssize_t len, n;
+ Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
+ Py_ssize_t m, r;
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "t#t#|nn:count", &s, &len, &sub, &n, &i, &last))
+ return NULL;
+ if (last > len)
+ last = len;
+ if (last < 0)
+ last += len;
+ if (last < 0)
+ last = 0;
+ if (i < 0)
+ i += len;
+ if (i < 0)
+ i = 0;
+ m = last + 1 - n;
+ if (n == 0)
+ return PyInt_FromLong((long) (m-i));
+
+ r = 0;
+ while (i < m) {
+ if (!memcmp(s+i, sub, n)) {
+ r++;
+ i += n;
+ } else {
+ i++;
+ }
+ }
+ return PyInt_FromLong((long) r);
+}
+
+
+PyDoc_STRVAR(swapcase__doc__,
+"swapcase(s) -> string\n"
+"\n"
+"Return a copy of the string s with upper case characters\n"
+"converted to lowercase and vice versa.");
+
+static PyObject *
+strop_swapcase(PyObject *self, PyObject *args)
+{
+ char *s, *s_new;
+ Py_ssize_t i, n;
+ PyObject *newstr;
+ int changed;
+
+ WARN;
+ if (PyString_AsStringAndSize(args, &s, &n))
+ return NULL;
+ newstr = PyString_FromStringAndSize(NULL, n);
+ if (newstr == NULL)
+ return NULL;
+ s_new = PyString_AsString(newstr);
+ changed = 0;
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (islower(c)) {
+ changed = 1;
+ *s_new = toupper(c);
+ }
+ else if (isupper(c)) {
+ changed = 1;
+ *s_new = tolower(c);
+ }
+ else
+ *s_new = c;
+ s_new++;
+ }
+ if (!changed) {
+ Py_DECREF(newstr);
+ Py_INCREF(args);
+ return args;
+ }
+ return newstr;
+}
+
+
+PyDoc_STRVAR(atoi__doc__,
+"atoi(s [,base]) -> int\n"
+"\n"
+"Return the integer represented by the string s in the given\n"
+"base, which defaults to 10. The string s must consist of one\n"
+"or more digits, possibly preceded by a sign. If base is 0, it\n"
+"is chosen from the leading characters of s, 0 for octal, 0x or\n"
+"0X for hexadecimal. If base is 16, a preceding 0x or 0X is\n"
+"accepted.");
+
+static PyObject *
+strop_atoi(PyObject *self, PyObject *args)
+{
+ char *s, *end;
+ int base = 10;
+ long x;
+ char buffer[256]; /* For errors */
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "s|i:atoi", &s, &base))
+ return NULL;
+
+ if ((base != 0 && base < 2) || base > 36) {
+ PyErr_SetString(PyExc_ValueError, "invalid base for atoi()");
+ return NULL;
+ }
+
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ errno = 0;
+ if (base == 0 && s[0] == '0')
+ x = (long) PyOS_strtoul(s, &end, base);
+ else
+ x = PyOS_strtol(s, &end, base);
+ if (end == s || !isalnum(Py_CHARMASK(end[-1])))
+ goto bad;
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ bad:
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "invalid literal for atoi(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ else if (errno != 0) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "atoi() literal too large: %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ return PyInt_FromLong(x);
+}
+
+
+PyDoc_STRVAR(atol__doc__,
+"atol(s [,base]) -> long\n"
+"\n"
+"Return the long integer represented by the string s in the\n"
+"given base, which defaults to 10. The string s must consist\n"
+"of one or more digits, possibly preceded by a sign. If base\n"
+"is 0, it is chosen from the leading characters of s, 0 for\n"
+"octal, 0x or 0X for hexadecimal. If base is 16, a preceding\n"
+"0x or 0X is accepted. A trailing L or l is not accepted,\n"
+"unless base is 0.");
+
+static PyObject *
+strop_atol(PyObject *self, PyObject *args)
+{
+ char *s, *end;
+ int base = 10;
+ PyObject *x;
+ char buffer[256]; /* For errors */
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "s|i:atol", &s, &base))
+ return NULL;
+
+ if ((base != 0 && base < 2) || base > 36) {
+ PyErr_SetString(PyExc_ValueError, "invalid base for atol()");
+ return NULL;
+ }
+
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] == '\0') {
+ PyErr_SetString(PyExc_ValueError, "empty string for atol()");
+ return NULL;
+ }
+ x = PyLong_FromString(s, &end, base);
+ if (x == NULL)
+ return NULL;
+ if (base == 0 && (*end == 'l' || *end == 'L'))
+ end++;
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "invalid literal for atol(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ Py_DECREF(x);
+ return NULL;
+ }
+ return x;
+}
+
+
+PyDoc_STRVAR(atof__doc__,
+"atof(s) -> float\n"
+"\n"
+"Return the floating point number represented by the string s.");
+
+static PyObject *
+strop_atof(PyObject *self, PyObject *args)
+{
+ char *s, *end;
+ double x;
+ char buffer[256]; /* For errors */
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "s:atof", &s))
+ return NULL;
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] == '\0') {
+ PyErr_SetString(PyExc_ValueError, "empty string for atof()");
+ return NULL;
+ }
+ errno = 0;
+ PyFPE_START_PROTECT("strop_atof", return 0)
+ x = PyOS_ascii_strtod(s, &end);
+ PyFPE_END_PROTECT(x)
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "invalid literal for atof(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ else if (errno != 0) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "atof() literal too large: %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ return PyFloat_FromDouble(x);
+}
+
+
+PyDoc_STRVAR(maketrans__doc__,
+"maketrans(frm, to) -> string\n"
+"\n"
+"Return a translation table (a string of 256 bytes long)\n"
+"suitable for use in string.translate. The strings frm and to\n"
+"must be of the same length.");
+
+static PyObject *
+strop_maketrans(PyObject *self, PyObject *args)
+{
+ unsigned char *c, *from=NULL, *to=NULL;
+ Py_ssize_t i, fromlen=0, tolen=0;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "t#t#:maketrans", &from, &fromlen, &to, &tolen))
+ return NULL;
+
+ if (fromlen != tolen) {
+ PyErr_SetString(PyExc_ValueError,
+ "maketrans arguments must have same length");
+ return NULL;
+ }
+
+ result = PyString_FromStringAndSize((char *)NULL, 256);
+ if (result == NULL)
+ return NULL;
+ c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);
+ for (i = 0; i < 256; i++)
+ c[i]=(unsigned char)i;
+ for (i = 0; i < fromlen; i++)
+ c[from[i]]=to[i];
+
+ return result;
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"translate(s,table [,deletechars]) -> string\n"
+"\n"
+"Return a copy of the string s, where all characters occurring\n"
+"in the optional argument deletechars are removed, and the\n"
+"remaining characters have been mapped through the given\n"
+"translation table, which must be a string of length 256.");
+
+static PyObject *
+strop_translate(PyObject *self, PyObject *args)
+{
+ register char *input, *table, *output;
+ Py_ssize_t i;
+ int c, changed = 0;
+ PyObject *input_obj;
+ char *table1, *output_start, *del_table=NULL;
+ Py_ssize_t inlen, tablen, dellen = 0;
+ PyObject *result;
+ int trans_table[256];
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "St#|t#:translate", &input_obj,
+ &table1, &tablen, &del_table, &dellen))
+ return NULL;
+ if (tablen != 256) {
+ PyErr_SetString(PyExc_ValueError,
+ "translation table must be 256 characters long");
+ return NULL;
+ }
+
+ table = table1;
+ inlen = PyString_GET_SIZE(input_obj);
+ result = PyString_FromStringAndSize((char *)NULL, inlen);
+ if (result == NULL)
+ return NULL;
+ output_start = output = PyString_AsString(result);
+ input = PyString_AsString(input_obj);
+
+ if (dellen == 0) {
+ /* If no deletions are required, use faster code */
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (Py_CHARMASK((*output++ = table[c])) != c)
+ changed = 1;
+ }
+ if (changed)
+ return result;
+ Py_DECREF(result);
+ Py_INCREF(input_obj);
+ return input_obj;
+ }
+
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(table[i]);
+
+ for (i = 0; i < dellen; i++)
+ trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
+
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (trans_table[c] != -1)
+ if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+ continue;
+ changed = 1;
+ }
+ if (!changed) {
+ Py_DECREF(result);
+ Py_INCREF(input_obj);
+ return input_obj;
+ }
+ /* Fix the size of the resulting string */
+ if (inlen > 0)
+ _PyString_Resize(&result, output - output_start);
+ return result;
+}
+
+
+/* What follows is used for implementing replace(). Perry Stoll. */
+
+/*
+ mymemfind
+
+ strstr replacement for arbitrary blocks of memory.
+
+ Locates the first occurrence in the memory pointed to by MEM of the
+ contents of memory pointed to by PAT. Returns the index into MEM if
+ found, or -1 if not found. If len of PAT is greater than length of
+ MEM, the function returns -1.
+*/
+static Py_ssize_t
+mymemfind(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)
+{
+ register Py_ssize_t ii;
+
+ /* pattern can not occur in the last pat_len-1 chars */
+ len -= pat_len;
+
+ for (ii = 0; ii <= len; ii++) {
+ if (mem[ii] == pat[0] &&
+ (pat_len == 1 ||
+ memcmp(&mem[ii+1], &pat[1], pat_len-1) == 0)) {
+ return ii;
+ }
+ }
+ return -1;
+}
+
+/*
+ mymemcnt
+
+ Return the number of distinct times PAT is found in MEM.
+ meaning mem=1111 and pat==11 returns 2.
+ mem=11111 and pat==11 also return 2.
+ */
+static Py_ssize_t
+mymemcnt(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)
+{
+ register Py_ssize_t offset = 0;
+ Py_ssize_t nfound = 0;
+
+ while (len >= 0) {
+ offset = mymemfind(mem, len, pat, pat_len);
+ if (offset == -1)
+ break;
+ mem += offset + pat_len;
+ len -= offset + pat_len;
+ nfound++;
+ }
+ return nfound;
+}
+
+/*
+ mymemreplace
+
+ Return a string in which all occurrences of PAT in memory STR are
+ replaced with SUB.
+
+ If length of PAT is less than length of STR or there are no occurrences
+ of PAT in STR, then the original string is returned. Otherwise, a new
+ string is allocated here and returned.
+
+ on return, out_len is:
+ the length of output string, or
+ -1 if the input string is returned, or
+ unchanged if an error occurs (no memory).
+
+ return value is:
+ the new string allocated locally, or
+ NULL if an error occurred.
+*/
+static char *
+mymemreplace(const char *str, Py_ssize_t len, /* input string */
+ const char *pat, Py_ssize_t pat_len, /* pattern string to find */
+ const char *sub, Py_ssize_t sub_len, /* substitution string */
+ Py_ssize_t count, /* number of replacements */
+ Py_ssize_t *out_len)
+{
+ char *out_s;
+ char *new_s;
+ Py_ssize_t nfound, offset, new_len;
+
+ if (len == 0 || pat_len > len)
+ goto return_same;
+
+ /* find length of output string */
+ nfound = mymemcnt(str, len, pat, pat_len);
+ if (count < 0)
+ count = PY_SSIZE_T_MAX;
+ else if (nfound > count)
+ nfound = count;
+ if (nfound == 0)
+ goto return_same;
+
+ new_len = len + nfound*(sub_len - pat_len);
+ if (new_len == 0) {
+ /* Have to allocate something for the caller to free(). */
+ out_s = (char *)PyMem_MALLOC(1);
+ if (out_s == NULL)
+ return NULL;
+ out_s[0] = '\0';
+ }
+ else {
+ assert(new_len > 0);
+ new_s = (char *)PyMem_MALLOC(new_len);
+ if (new_s == NULL)
+ return NULL;
+ out_s = new_s;
+
+ for (; count > 0 && len > 0; --count) {
+ /* find index of next instance of pattern */
+ offset = mymemfind(str, len, pat, pat_len);
+ if (offset == -1)
+ break;
+
+ /* copy non matching part of input string */
+ memcpy(new_s, str, offset);
+ str += offset + pat_len;
+ len -= offset + pat_len;
+
+ /* copy substitute into the output string */
+ new_s += offset;
+ memcpy(new_s, sub, sub_len);
+ new_s += sub_len;
+ }
+ /* copy any remaining values into output string */
+ if (len > 0)
+ memcpy(new_s, str, len);
+ }
+ *out_len = new_len;
+ return out_s;
+
+ return_same:
+ *out_len = -1;
+ return (char *)str; /* cast away const */
+}
+
+
+PyDoc_STRVAR(replace__doc__,
+"replace (str, old, new[, maxsplit]) -> string\n"
+"\n"
+"Return a copy of string str with all occurrences of substring\n"
+"old replaced by new. If the optional argument maxsplit is\n"
+"given, only the first maxsplit occurrences are replaced.");
+
+static PyObject *
+strop_replace(PyObject *self, PyObject *args)
+{
+ char *str, *pat,*sub,*new_s;
+ Py_ssize_t len,pat_len,sub_len,out_len;
+ Py_ssize_t count = -1;
+ PyObject *newstr;
+
+ WARN;
+ if (!PyArg_ParseTuple(args, "t#t#t#|n:replace",
+ &str, &len, &pat, &pat_len, &sub, &sub_len,
+ &count))
+ return NULL;
+ if (pat_len <= 0) {
+ PyErr_SetString(PyExc_ValueError, "empty pattern string");
+ return NULL;
+ }
+ /* CAUTION: strop treats a replace count of 0 as infinity, unlke
+ * current (2.1) string.py and string methods. Preserve this for
+ * ... well, hard to say for what <wink>.
+ */
+ if (count == 0)
+ count = -1;
+ new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,count,&out_len);
+ if (new_s == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ if (out_len == -1) {
+ /* we're returning another reference to the input string */
+ newstr = PyTuple_GetItem(args, 0);
+ Py_XINCREF(newstr);
+ }
+ else {
+ newstr = PyString_FromStringAndSize(new_s, out_len);
+ PyMem_FREE(new_s);
+ }
+ return newstr;
+}
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef
+strop_methods[] = {
+ {"atof", strop_atof, METH_VARARGS, atof__doc__},
+ {"atoi", strop_atoi, METH_VARARGS, atoi__doc__},
+ {"atol", strop_atol, METH_VARARGS, atol__doc__},
+ {"capitalize", strop_capitalize, METH_O, capitalize__doc__},
+ {"count", strop_count, METH_VARARGS, count__doc__},
+ {"expandtabs", strop_expandtabs, METH_VARARGS, expandtabs__doc__},
+ {"find", strop_find, METH_VARARGS, find__doc__},
+ {"join", strop_joinfields, METH_VARARGS, joinfields__doc__},
+ {"joinfields", strop_joinfields, METH_VARARGS, joinfields__doc__},
+ {"lstrip", strop_lstrip, METH_O, lstrip__doc__},
+ {"lower", strop_lower, METH_O, lower__doc__},
+ {"maketrans", strop_maketrans, METH_VARARGS, maketrans__doc__},
+ {"replace", strop_replace, METH_VARARGS, replace__doc__},
+ {"rfind", strop_rfind, METH_VARARGS, rfind__doc__},
+ {"rstrip", strop_rstrip, METH_O, rstrip__doc__},
+ {"split", strop_splitfields, METH_VARARGS, splitfields__doc__},
+ {"splitfields", strop_splitfields, METH_VARARGS, splitfields__doc__},
+ {"strip", strop_strip, METH_O, strip__doc__},
+ {"swapcase", strop_swapcase, METH_O, swapcase__doc__},
+ {"translate", strop_translate, METH_VARARGS, translate__doc__},
+ {"upper", strop_upper, METH_O, upper__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyMODINIT_FUNC
+initstrop(void)
+{
+ PyObject *m, *s;
+ char buf[256];
+ int c, n;
+ m = Py_InitModule4("strop", strop_methods, strop_module__doc__,
+ (PyObject*)NULL, PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ /* Create 'whitespace' object */
+ n = 0;
+ for (c = 0; c < 256; c++) {
+ if (isspace(c))
+ buf[n++] = c;
+ }
+ s = PyString_FromStringAndSize(buf, n);
+ if (s)
+ PyModule_AddObject(m, "whitespace", s);
+
+ /* Create 'lowercase' object */
+ n = 0;
+ for (c = 0; c < 256; c++) {
+ if (islower(c))
+ buf[n++] = c;
+ }
+ s = PyString_FromStringAndSize(buf, n);
+ if (s)
+ PyModule_AddObject(m, "lowercase", s);
+
+ /* Create 'uppercase' object */
+ n = 0;
+ for (c = 0; c < 256; c++) {
+ if (isupper(c))
+ buf[n++] = c;
+ }
+ s = PyString_FromStringAndSize(buf, n);
+ if (s)
+ PyModule_AddObject(m, "uppercase", s);
+}
diff --git a/sys/src/cmd/python/Modules/sunaudiodev.c b/sys/src/cmd/python/Modules/sunaudiodev.c
new file mode 100644
index 000000000..802184d0d
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sunaudiodev.c
@@ -0,0 +1,465 @@
+
+/* Sad objects */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_SYS_AUDIOIO_H
+#define SOLARIS
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <stropts.h>
+#include <sys/ioctl.h>
+#ifdef SOLARIS
+#include <sys/audioio.h>
+#else
+#include <sun/audioio.h>
+#endif
+
+/* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
+
+typedef struct {
+ PyObject_HEAD
+ int x_fd; /* The open file */
+ int x_icount; /* # samples read */
+ int x_ocount; /* # samples written */
+ int x_isctl; /* True if control device */
+
+} sadobject;
+
+typedef struct {
+ PyObject_HEAD
+ audio_info_t ai;
+} sadstatusobject;
+
+static PyTypeObject Sadtype;
+static PyTypeObject Sadstatustype;
+static sadstatusobject *sads_alloc(void); /* Forward */
+
+static PyObject *SunAudioError;
+
+#define is_sadobject(v) ((v)->ob_type == &Sadtype)
+#define is_sadstatusobject(v) ((v)->ob_type == &Sadstatustype)
+
+
+static sadobject *
+newsadobject(PyObject *args)
+{
+ sadobject *xp;
+ int fd;
+ char *mode;
+ int imode;
+ char* basedev;
+ char* ctldev;
+ char* opendev;
+
+ /* Check arg for r/w/rw */
+ if (!PyArg_ParseTuple(args, "s", &mode))
+ return NULL;
+ if (strcmp(mode, "r") == 0)
+ imode = 0;
+ else if (strcmp(mode, "w") == 0)
+ imode = 1;
+ else if (strcmp(mode, "rw") == 0)
+ imode = 2;
+ else if (strcmp(mode, "control") == 0)
+ imode = -1;
+ else {
+ PyErr_SetString(SunAudioError,
+ "Mode should be one of 'r', 'w', 'rw' or 'control'");
+ return NULL;
+ }
+
+ /* Open the correct device. The base device name comes from the
+ * AUDIODEV environment variable first, then /dev/audio. The
+ * control device tacks "ctl" onto the base device name.
+ */
+ basedev = getenv("AUDIODEV");
+ if (!basedev)
+ basedev = "/dev/audio";
+ ctldev = PyMem_NEW(char, strlen(basedev) + 4);
+ if (!ctldev) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ strcpy(ctldev, basedev);
+ strcat(ctldev, "ctl");
+
+ if (imode < 0) {
+ opendev = ctldev;
+ fd = open(ctldev, 2);
+ }
+ else {
+ opendev = basedev;
+ fd = open(basedev, imode);
+ }
+ if (fd < 0) {
+ PyErr_SetFromErrnoWithFilename(SunAudioError, opendev);
+ PyMem_DEL(ctldev);
+ return NULL;
+ }
+ PyMem_DEL(ctldev);
+
+ /* Create and initialize the object */
+ xp = PyObject_New(sadobject, &Sadtype);
+ if (xp == NULL) {
+ close(fd);
+ return NULL;
+ }
+ xp->x_fd = fd;
+ xp->x_icount = xp->x_ocount = 0;
+ xp->x_isctl = (imode < 0);
+
+ return xp;
+}
+
+/* Sad methods */
+
+static void
+sad_dealloc(sadobject *xp)
+{
+ close(xp->x_fd);
+ PyObject_Del(xp);
+}
+
+static PyObject *
+sad_read(sadobject *self, PyObject *args)
+{
+ int size, count;
+ char *cp;
+ PyObject *rv;
+
+ if (!PyArg_ParseTuple(args, "i:read", &size))
+ return NULL;
+ rv = PyString_FromStringAndSize(NULL, size);
+ if (rv == NULL)
+ return NULL;
+
+ if (!(cp = PyString_AsString(rv)))
+ goto finally;
+
+ count = read(self->x_fd, cp, size);
+ if (count < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ goto finally;
+ }
+#if 0
+ /* TBD: why print this message if you can handle the condition?
+ * assume it's debugging info which we can just as well get rid
+ * of. in any case this message should *not* be using printf!
+ */
+ if (count != size)
+ printf("sunaudio: funny read rv %d wtd %d\n", count, size);
+#endif
+ self->x_icount += count;
+ return rv;
+
+ finally:
+ Py_DECREF(rv);
+ return NULL;
+}
+
+static PyObject *
+sad_write(sadobject *self, PyObject *args)
+{
+ char *cp;
+ int count, size;
+
+ if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
+ return NULL;
+
+ count = write(self->x_fd, cp, size);
+ if (count < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+#if 0
+ if (count != size)
+ printf("sunaudio: funny write rv %d wanted %d\n", count, size);
+#endif
+ self->x_ocount += count;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sad_getinfo(sadobject *self)
+{
+ sadstatusobject *rv;
+
+ if (!(rv = sads_alloc()))
+ return NULL;
+
+ if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ Py_DECREF(rv);
+ return NULL;
+ }
+ return (PyObject *)rv;
+}
+
+static PyObject *
+sad_setinfo(sadobject *self, sadstatusobject *arg)
+{
+ if (!is_sadstatusobject(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Must be sun audio status object");
+ return NULL;
+ }
+ if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sad_ibufcount(sadobject *self)
+{
+ audio_info_t ai;
+
+ if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+ return PyInt_FromLong(ai.record.samples - self->x_icount);
+}
+
+static PyObject *
+sad_obufcount(sadobject *self)
+{
+ audio_info_t ai;
+
+ if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+ /* x_ocount is in bytes, whereas play.samples is in frames */
+ /* we want frames */
+ return PyInt_FromLong(self->x_ocount / (ai.play.channels *
+ ai.play.precision / 8) -
+ ai.play.samples);
+}
+
+static PyObject *
+sad_drain(sadobject *self)
+{
+ if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef SOLARIS
+static PyObject *
+sad_getdev(sadobject *self)
+{
+ struct audio_device ad;
+
+ if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+ return Py_BuildValue("(sss)", ad.name, ad.version, ad.config);
+}
+#endif
+
+static PyObject *
+sad_flush(sadobject *self)
+{
+ if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) {
+ PyErr_SetFromErrno(SunAudioError);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sad_close(sadobject *self)
+{
+
+ if (self->x_fd >= 0) {
+ close(self->x_fd);
+ self->x_fd = -1;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sad_fileno(sadobject *self)
+{
+ return PyInt_FromLong(self->x_fd);
+}
+
+
+static PyMethodDef sad_methods[] = {
+ { "read", (PyCFunction)sad_read, METH_VARARGS },
+ { "write", (PyCFunction)sad_write, METH_VARARGS },
+ { "ibufcount", (PyCFunction)sad_ibufcount, METH_NOARGS },
+ { "obufcount", (PyCFunction)sad_obufcount, METH_NOARGS },
+#define CTL_METHODS 4
+ { "getinfo", (PyCFunction)sad_getinfo, METH_NOARGS },
+ { "setinfo", (PyCFunction)sad_setinfo, METH_O},
+ { "drain", (PyCFunction)sad_drain, METH_NOARGS },
+ { "flush", (PyCFunction)sad_flush, METH_NOARGS },
+#ifdef SOLARIS
+ { "getdev", (PyCFunction)sad_getdev, METH_NOARGS },
+#endif
+ { "close", (PyCFunction)sad_close, METH_NOARGS },
+ { "fileno", (PyCFunction)sad_fileno, METH_NOARGS },
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+sad_getattr(sadobject *xp, char *name)
+{
+ if (xp->x_isctl)
+ return Py_FindMethod(sad_methods+CTL_METHODS,
+ (PyObject *)xp, name);
+ else
+ return Py_FindMethod(sad_methods, (PyObject *)xp, name);
+}
+
+/* ----------------------------------------------------------------- */
+
+static sadstatusobject *
+sads_alloc(void) {
+ return PyObject_New(sadstatusobject, &Sadstatustype);
+}
+
+static void
+sads_dealloc(sadstatusobject *xp)
+{
+ PyMem_DEL(xp);
+}
+
+#define OFF(x) offsetof(audio_info_t,x)
+static struct memberlist sads_ml[] = {
+ { "i_sample_rate", T_UINT, OFF(record.sample_rate) },
+ { "i_channels", T_UINT, OFF(record.channels) },
+ { "i_precision", T_UINT, OFF(record.precision) },
+ { "i_encoding", T_UINT, OFF(record.encoding) },
+ { "i_gain", T_UINT, OFF(record.gain) },
+ { "i_port", T_UINT, OFF(record.port) },
+ { "i_samples", T_UINT, OFF(record.samples) },
+ { "i_eof", T_UINT, OFF(record.eof) },
+ { "i_pause", T_UBYTE, OFF(record.pause) },
+ { "i_error", T_UBYTE, OFF(record.error) },
+ { "i_waiting", T_UBYTE, OFF(record.waiting) },
+ { "i_open", T_UBYTE, OFF(record.open) , RO},
+ { "i_active", T_UBYTE, OFF(record.active) , RO},
+#ifdef SOLARIS
+ { "i_buffer_size", T_UINT, OFF(record.buffer_size) },
+ { "i_balance", T_UBYTE, OFF(record.balance) },
+ { "i_avail_ports", T_UINT, OFF(record.avail_ports) },
+#endif
+
+ { "o_sample_rate", T_UINT, OFF(play.sample_rate) },
+ { "o_channels", T_UINT, OFF(play.channels) },
+ { "o_precision", T_UINT, OFF(play.precision) },
+ { "o_encoding", T_UINT, OFF(play.encoding) },
+ { "o_gain", T_UINT, OFF(play.gain) },
+ { "o_port", T_UINT, OFF(play.port) },
+ { "o_samples", T_UINT, OFF(play.samples) },
+ { "o_eof", T_UINT, OFF(play.eof) },
+ { "o_pause", T_UBYTE, OFF(play.pause) },
+ { "o_error", T_UBYTE, OFF(play.error) },
+ { "o_waiting", T_UBYTE, OFF(play.waiting) },
+ { "o_open", T_UBYTE, OFF(play.open) , RO},
+ { "o_active", T_UBYTE, OFF(play.active) , RO},
+#ifdef SOLARIS
+ { "o_buffer_size", T_UINT, OFF(play.buffer_size) },
+ { "o_balance", T_UBYTE, OFF(play.balance) },
+ { "o_avail_ports", T_UINT, OFF(play.avail_ports) },
+#endif
+
+ { "monitor_gain", T_UINT, OFF(monitor_gain) },
+ { NULL, 0, 0},
+};
+
+static PyObject *
+sads_getattr(sadstatusobject *xp, char *name)
+{
+ return PyMember_Get((char *)&xp->ai, sads_ml, name);
+}
+
+static int
+sads_setattr(sadstatusobject *xp, char *name, PyObject *v)
+{
+
+ if (v == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete sun audio status attributes");
+ return -1;
+ }
+ return PyMember_Set((char *)&xp->ai, sads_ml, name, v);
+}
+
+/* ------------------------------------------------------------------- */
+
+
+static PyTypeObject Sadtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "sunaudiodev.sun_audio_device", /*tp_name*/
+ sizeof(sadobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)sad_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)sad_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyTypeObject Sadstatustype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "sunaudiodev.sun_audio_device_status", /*tp_name*/
+ sizeof(sadstatusobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)sads_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)sads_getattr, /*tp_getattr*/
+ (setattrfunc)sads_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+/* ------------------------------------------------------------------- */
+
+static PyObject *
+sadopen(PyObject *self, PyObject *args)
+{
+ return (PyObject *)newsadobject(args);
+}
+
+static PyMethodDef sunaudiodev_methods[] = {
+ { "open", sadopen, METH_VARARGS },
+ { 0, 0 },
+};
+
+void
+initsunaudiodev(void)
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule("sunaudiodev", sunaudiodev_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL);
+ if (SunAudioError)
+ PyDict_SetItemString(d, "error", SunAudioError);
+}
diff --git a/sys/src/cmd/python/Modules/svmodule.c b/sys/src/cmd/python/Modules/svmodule.c
new file mode 100644
index 000000000..fb58f19cc
--- /dev/null
+++ b/sys/src/cmd/python/Modules/svmodule.c
@@ -0,0 +1,966 @@
+/* SV module -- interface to the Indigo video board */
+
+/* WARNING! This module is for hardware that we don't have any more,
+ so it hasn't been tested. It has been converted to the new coding
+ style, and it is possible that this conversion has broken something
+ -- user beware! */
+
+#include <sys/time.h>
+#include <svideo.h>
+#include "Python.h"
+#include "compile.h"
+#include "yuv.h" /* for YUV conversion functions */
+
+typedef struct {
+ PyObject_HEAD
+ SV_nodeP ob_svideo;
+ svCaptureInfo ob_info;
+} svobject;
+
+typedef struct {
+ PyObject_HEAD
+ void *ob_capture;
+ int ob_mustunlock;
+ svCaptureInfo ob_info;
+ svobject *ob_svideo;
+} captureobject;
+
+static PyObject *SvError; /* exception sv.error */
+
+static PyObject *newcaptureobject(svobject *, void *, int);
+
+/* Set a SV-specific error from svideo_errno and return NULL */
+static PyObject *
+sv_error(void)
+{
+ PyErr_SetString(SvError, svStrerror(svideo_errno));
+ return NULL;
+}
+
+static PyObject *
+svc_conversion(captureobject *self, PyObject *args, void (*function)(), float factor)
+{
+ PyObject *output;
+ int invert;
+ char* outstr;
+
+ if (!PyArg_Parse(args, "i", &invert))
+ return NULL;
+
+ if (!(output = PyString_FromStringAndSize(
+ NULL,
+ (int)(self->ob_info.width * self->ob_info.height * factor))))
+ {
+ return NULL;
+ }
+ if (!(outstr = PyString_AsString(output))) {
+ Py_DECREF(output);
+ return NULL;
+ }
+
+ (*function)((boolean)invert, self->ob_capture,
+ outstr,
+ self->ob_info.width, self->ob_info.height);
+
+ return output;
+}
+
+/*
+ * 3 functions to convert from Starter Video YUV 4:1:1 format to
+ * Compression Library 4:2:2 Duplicate Chroma format.
+ */
+static PyObject *
+svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
+{
+ if (self->ob_info.format != SV_YUV411_FRAMES) {
+ PyErr_SetString(SvError, "data has bad format");
+ return NULL;
+ }
+ return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
+}
+
+static PyObject *
+svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
+{
+ if (self->ob_info.format != SV_YUV411_FRAMES) {
+ PyErr_SetString(SvError, "data has bad format");
+ return NULL;
+ }
+ return svc_conversion(self, args,
+ yuv_sv411_to_cl422dc_quartersize, 0.5);
+}
+
+static PyObject *
+svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
+{
+ if (self->ob_info.format != SV_YUV411_FRAMES) {
+ PyErr_SetString(SvError, "data has bad format");
+ return NULL;
+ }
+ return svc_conversion(self, args,
+ yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
+}
+
+static PyObject *
+svc_YUVtoRGB(captureobject *self, PyObject *args)
+{
+ switch (self->ob_info.format) {
+ case SV_YUV411_FRAMES:
+ case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
+ break;
+ default:
+ PyErr_SetString(SvError, "data had bad format");
+ return NULL;
+ }
+ return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
+}
+
+static PyObject *
+svc_RGB8toRGB32(captureobject *self, PyObject *args)
+{
+ if (self->ob_info.format != SV_RGB8_FRAMES) {
+ PyErr_SetString(SvError, "data has bad format");
+ return NULL;
+ }
+ return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
+}
+
+static PyObject *
+svc_InterleaveFields(captureobject *self, PyObject *args)
+{
+ if (self->ob_info.format != SV_RGB8_FRAMES) {
+ PyErr_SetString(SvError, "data has bad format");
+ return NULL;
+ }
+ return svc_conversion(self, args, svInterleaveFields, 1.0);
+}
+
+static PyObject *
+svc_GetFields(captureobject *self, PyObject *args)
+{
+ PyObject *f1 = NULL;
+ PyObject *f2 = NULL;
+ PyObject *ret = NULL;
+ int fieldsize;
+ char* obcapture;
+
+ if (self->ob_info.format != SV_RGB8_FRAMES) {
+ PyErr_SetString(SvError, "data has bad format");
+ return NULL;
+ }
+
+ fieldsize = self->ob_info.width * self->ob_info.height / 2;
+ obcapture = (char*)self->ob_capture;
+
+ if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
+ goto finally;
+ if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
+ fieldsize)))
+ goto finally;
+ ret = PyTuple_Pack(2, f1, f2);
+
+ finally:
+ Py_XDECREF(f1);
+ Py_XDECREF(f2);
+ return ret;
+}
+
+static PyObject *
+svc_UnlockCaptureData(captureobject *self, PyObject *args)
+{
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ if (!self->ob_mustunlock) {
+ PyErr_SetString(SvError, "buffer should not be unlocked");
+ return NULL;
+ }
+
+ if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
+ return sv_error();
+
+ self->ob_mustunlock = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef USE_GL
+#include <gl.h>
+
+static PyObject *
+svc_lrectwrite(captureobject *self, PyObject *args)
+{
+ Screencoord x1, x2, y1, y2;
+
+ if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
+ return NULL;
+
+ lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+static PyObject *
+svc_writefile(captureobject *self, PyObject *args)
+{
+ PyObject *file;
+ int size;
+ FILE* fp;
+
+ if (!PyArg_Parse(args, "O", &file))
+ return NULL;
+
+ if (!PyFile_Check(file)) {
+ PyErr_SetString(SvError, "not a file object");
+ return NULL;
+ }
+
+ if (!(fp = PyFile_AsFile(file)))
+ return NULL;
+
+ size = self->ob_info.width * self->ob_info.height;
+
+ if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
+ PyErr_SetString(SvError, "writing failed");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+svc_FindVisibleRegion(captureobject *self, PyObject *args)
+{
+ void *visible;
+ int width;
+
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
+ self->ob_capture, &visible,
+ self->ob_info.width))
+ return sv_error();
+
+ if (visible == NULL) {
+ PyErr_SetString(SvError, "data in wrong format");
+ return NULL;
+ }
+
+ return newcaptureobject(self->ob_svideo, visible, 0);
+}
+
+static PyMethodDef capture_methods[] = {
+ {"YUVtoRGB", (PyCFunction)svc_YUVtoRGB, METH_OLDARGS},
+ {"RGB8toRGB32", (PyCFunction)svc_RGB8toRGB32, METH_OLDARGS},
+ {"InterleaveFields", (PyCFunction)svc_InterleaveFields, METH_OLDARGS},
+ {"UnlockCaptureData", (PyCFunction)svc_UnlockCaptureData, METH_OLDARGS},
+ {"FindVisibleRegion", (PyCFunction)svc_FindVisibleRegion, METH_OLDARGS},
+ {"GetFields", (PyCFunction)svc_GetFields, METH_OLDARGS},
+ {"YUVtoYUV422DC", (PyCFunction)svc_YUVtoYUV422DC, METH_OLDARGS},
+ {"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter, METH_OLDARGS},
+ {"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth, METH_OLDARGS},
+#ifdef USE_GL
+ {"lrectwrite", (PyCFunction)svc_lrectwrite, METH_OLDARGS},
+#endif
+ {"writefile", (PyCFunction)svc_writefile, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+capture_dealloc(captureobject *self)
+{
+ if (self->ob_capture != NULL) {
+ if (self->ob_mustunlock)
+ (void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
+ self->ob_capture);
+ self->ob_capture = NULL;
+ Py_DECREF(self->ob_svideo);
+ self->ob_svideo = NULL;
+ }
+ PyObject_Del(self);
+}
+
+static PyObject *
+capture_getattr(svobject *self, char *name)
+{
+ return Py_FindMethod(capture_methods, (PyObject *)self, name);
+}
+
+PyTypeObject Capturetype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "sv.capture", /*tp_name*/
+ sizeof(captureobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)capture_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)capture_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyObject *
+newcaptureobject(svobject *self, void *ptr, int mustunlock)
+{
+ captureobject *p;
+
+ p = PyObject_New(captureobject, &Capturetype);
+ if (p == NULL)
+ return NULL;
+ p->ob_svideo = self;
+ Py_INCREF(self);
+ p->ob_capture = ptr;
+ p->ob_mustunlock = mustunlock;
+ p->ob_info = self->ob_info;
+ return (PyObject *) p;
+}
+
+static PyObject *
+sv_GetCaptureData(svobject *self, PyObject *args)
+{
+ void *ptr;
+ long fieldID;
+ PyObject *res, *c;
+
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
+ return sv_error();
+
+ if (ptr == NULL) {
+ PyErr_SetString(SvError, "no data available");
+ return NULL;
+ }
+
+ c = newcaptureobject(self, ptr, 1);
+ if (c == NULL)
+ return NULL;
+ res = Py_BuildValue("(Oi)", c, fieldID);
+ Py_DECREF(c);
+ return res;
+}
+
+static PyObject *
+sv_BindGLWindow(svobject *self, PyObject *args)
+{
+ long wid;
+ int mode;
+
+ if (!PyArg_Parse(args, "(ii)", &wid, &mode))
+ return NULL;
+
+ if (svBindGLWindow(self->ob_svideo, wid, mode))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_EndContinuousCapture(svobject *self, PyObject *args)
+{
+
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ if (svEndContinuousCapture(self->ob_svideo))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_IsVideoDisplayed(svobject *self, PyObject *args)
+{
+ int v;
+
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ v = svIsVideoDisplayed(self->ob_svideo);
+ if (v == -1)
+ return sv_error();
+
+ return PyInt_FromLong((long) v);
+}
+
+static PyObject *
+sv_OutputOffset(svobject *self, PyObject *args)
+{
+ int x_offset;
+ int y_offset;
+
+ if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
+ return NULL;
+
+ if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_PutFrame(svobject *self, PyObject *args)
+{
+ char *buffer;
+
+ if (!PyArg_Parse(args, "s", &buffer))
+ return NULL;
+
+ if (svPutFrame(self->ob_svideo, buffer))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_QuerySize(svobject *self, PyObject *args)
+{
+ int w;
+ int h;
+ int rw;
+ int rh;
+
+ if (!PyArg_Parse(args, "(ii)", &w, &h))
+ return NULL;
+
+ if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
+ return sv_error();
+
+ return Py_BuildValue("(ii)", (long) rw, (long) rh);
+}
+
+static PyObject *
+sv_SetSize(svobject *self, PyObject *args)
+{
+ int w;
+ int h;
+
+ if (!PyArg_Parse(args, "(ii)", &w, &h))
+ return NULL;
+
+ if (svSetSize(self->ob_svideo, w, h))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_SetStdDefaults(svobject *self, PyObject *args)
+{
+
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ if (svSetStdDefaults(self->ob_svideo))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_UseExclusive(svobject *self, PyObject *args)
+{
+ boolean onoff;
+ int mode;
+
+ if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
+ return NULL;
+
+ if (svUseExclusive(self->ob_svideo, onoff, mode))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_WindowOffset(svobject *self, PyObject *args)
+{
+ int x_offset;
+ int y_offset;
+
+ if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
+ return NULL;
+
+ if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
+ return sv_error();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+sv_CaptureBurst(svobject *self, PyObject *args)
+{
+ int bytes, i;
+ svCaptureInfo info;
+ void *bitvector = NULL;
+ PyObject *videodata = NULL;
+ PyObject *bitvecobj = NULL;
+ PyObject *res = NULL;
+ static PyObject *evenitem, *odditem;
+
+ if (!PyArg_Parse(args, "(iiiii)", &info.format,
+ &info.width, &info.height,
+ &info.size, &info.samplingrate))
+ return NULL;
+
+ switch (info.format) {
+ case SV_RGB8_FRAMES:
+ bitvector = malloc(SV_BITVEC_SIZE(info.size));
+ break;
+ case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
+ break;
+ default:
+ PyErr_SetString(SvError, "illegal format specified");
+ return NULL;
+ }
+
+ if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
+ res = sv_error();
+ goto finally;
+ }
+
+ if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
+ goto finally;
+
+ /* XXX -- need to do something about the bitvector */
+ {
+ char* str = PyString_AsString(videodata);
+ if (!str)
+ goto finally;
+
+ if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
+ res = sv_error();
+ goto finally;
+ }
+ }
+
+ if (bitvector) {
+ if (evenitem == NULL) {
+ if (!(evenitem = PyInt_FromLong(0)))
+ goto finally;
+ }
+ if (odditem == NULL) {
+ if (!(odditem = PyInt_FromLong(1)))
+ goto finally;
+ }
+ if (!(bitvecobj = PyTuple_New(2 * info.size)))
+ goto finally;
+
+ for (i = 0; i < 2 * info.size; i++) {
+ int sts;
+
+ if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
+ Py_INCREF(evenitem);
+ sts = PyTuple_SetItem(bitvecobj, i, evenitem);
+ } else {
+ Py_INCREF(odditem);
+ sts = PyTuple_SetItem(bitvecobj, i, odditem);
+ }
+ if (sts < 0)
+ goto finally;
+ }
+ } else {
+ bitvecobj = Py_None;
+ Py_INCREF(Py_None);
+ }
+
+ res = Py_BuildValue("((iiiii)OO)", info.format,
+ info.width, info.height,
+ info.size, info.samplingrate,
+ videodata, bitvecobj);
+
+ finally:
+ if (bitvector)
+ free(bitvector);
+
+ Py_XDECREF(videodata);
+ Py_XDECREF(bitvecobj);
+ return res;
+}
+
+static PyObject *
+sv_CaptureOneFrame(svobject *self, PyObject *args)
+{
+ svCaptureInfo info;
+ int format, width, height;
+ int bytes;
+ PyObject *videodata = NULL;
+ PyObject *res = NULL;
+ char *str;
+
+ if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
+ return NULL;
+
+ info.format = format;
+ info.width = width;
+ info.height = height;
+ info.size = 0;
+ info.samplingrate = 0;
+ if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
+ return sv_error();
+
+ if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
+ return NULL;
+
+ str = PyString_AsString(videodata);
+ if (!str)
+ goto finally;
+
+ if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
+ res = sv_error();
+ goto finally;
+ }
+
+ res = Py_BuildValue("(iiO)", width, height, videodata);
+
+ finally:
+ Py_XDECREF(videodata);
+ return res;
+}
+
+static PyObject *
+sv_InitContinuousCapture(svobject *self, PyObject *args)
+{
+ svCaptureInfo info;
+
+ if (!PyArg_Parse(args, "(iiiii)", &info.format,
+ &info.width, &info.height,
+ &info.size, &info.samplingrate))
+ return NULL;
+
+ if (svInitContinuousCapture(self->ob_svideo, &info))
+ return sv_error();
+
+ self->ob_info = info;
+
+ return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
+ info.size, info.samplingrate);
+}
+
+static PyObject *
+sv_LoadMap(svobject *self, PyObject *args)
+{
+ PyObject *rgb;
+ PyObject *res = NULL;
+ rgb_tuple *mapp = NULL;
+ int maptype;
+ int i, j; /* indices */
+
+ if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
+ return NULL;
+
+ if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
+ return PyErr_NoMemory();
+
+ for (i = 0; i < 256; i++) {
+ PyObject* v = PyList_GetItem(rgb, i);
+ if (!v)
+ goto finally;
+
+ if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
+ PyErr_BadArgument();
+ goto finally;
+ }
+ for (j = 0; j < 3; j++) {
+ PyObject* cell = PyTuple_GetItem(v, j);
+ if (!cell)
+ goto finally;
+
+ if (!PyInt_Check(cell)) {
+ PyErr_BadArgument();
+ goto finally;
+ }
+ switch (j) {
+ case 0: mapp[i].red = PyInt_AsLong(cell); break;
+ case 1: mapp[i].blue = PyInt_AsLong(cell); break;
+ case 2: mapp[i].green = PyInt_AsLong(cell); break;
+ }
+ if (PyErr_Occurred())
+ goto finally;
+ }
+ }
+
+ if (svLoadMap(self->ob_svideo, maptype, mapp)) {
+ res = sv_error();
+ goto finally;
+ }
+
+ Py_INCREF(Py_None);
+ res = Py_None;
+
+ finally:
+ PyMem_DEL(mapp);
+ return res;
+}
+
+static PyObject *
+sv_CloseVideo(svobject *self, PyObject *args)
+{
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ if (svCloseVideo(self->ob_svideo))
+ return sv_error();
+
+ self->ob_svideo = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+doParams(svobject *self, PyObject *args,
+ int (*func)(SV_nodeP, long *, int), int modified)
+{
+ PyObject *list;
+ PyObject *res = NULL;
+ long *PVbuffer = NULL;
+ long length;
+ int i;
+
+ if (!PyArg_Parse(args, "O", &list))
+ return NULL;
+
+ if (!PyList_Check(list)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ if ((length = PyList_Size(list)) < 0)
+ return NULL;
+
+ PVbuffer = PyMem_NEW(long, length);
+ if (PVbuffer == NULL)
+ return PyErr_NoMemory();
+
+ for (i = 0; i < length; i++) {
+ PyObject *v = PyList_GetItem(list, i);
+ if (!v)
+ goto finally;
+
+ if (!PyInt_Check(v)) {
+ PyErr_BadArgument();
+ goto finally;
+ }
+ PVbuffer[i] = PyInt_AsLong(v);
+ /* can't just test the return value, because what if the
+ value was -1?!
+ */
+ if (PVbuffer[i] == -1 && PyErr_Occurred())
+ goto finally;
+ }
+
+ if ((*func)(self->ob_svideo, PVbuffer, length)) {
+ res = sv_error();
+ goto finally;
+ }
+
+ if (modified) {
+ for (i = 0; i < length; i++) {
+ PyObject* v = PyInt_FromLong(PVbuffer[i]);
+ if (!v || PyList_SetItem(list, i, v) < 0)
+ goto finally;
+ }
+ }
+
+ Py_INCREF(Py_None);
+ res = Py_None;
+
+ finally:
+ PyMem_DEL(PVbuffer);
+ return res;
+}
+
+static PyObject *
+sv_GetParam(PyObject *self, PyObject *args)
+{
+ return doParams(self, args, svGetParam, 1);
+}
+
+static PyObject *
+sv_GetParamRange(PyObject *self, PyObject *args)
+{
+ return doParams(self, args, svGetParamRange, 1);
+}
+
+static PyObject *
+sv_SetParam(PyObject *self, PyObject *args)
+{
+ return doParams(self, args, svSetParam, 0);
+}
+
+static PyMethodDef svideo_methods[] = {
+ {"BindGLWindow", (PyCFunction)sv_BindGLWindow, METH_OLDARGS},
+ {"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture, METH_OLDARGS},
+ {"IsVideoDisplayed", (PyCFunction)sv_IsVideoDisplayed, METH_OLDARGS},
+ {"OutputOffset", (PyCFunction)sv_OutputOffset, METH_OLDARGS},
+ {"PutFrame", (PyCFunction)sv_PutFrame, METH_OLDARGS},
+ {"QuerySize", (PyCFunction)sv_QuerySize, METH_OLDARGS},
+ {"SetSize", (PyCFunction)sv_SetSize, METH_OLDARGS},
+ {"SetStdDefaults", (PyCFunction)sv_SetStdDefaults, METH_OLDARGS},
+ {"UseExclusive", (PyCFunction)sv_UseExclusive, METH_OLDARGS},
+ {"WindowOffset", (PyCFunction)sv_WindowOffset, METH_OLDARGS},
+ {"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture, METH_OLDARGS},
+ {"CaptureBurst", (PyCFunction)sv_CaptureBurst, METH_OLDARGS},
+ {"CaptureOneFrame", (PyCFunction)sv_CaptureOneFrame, METH_OLDARGS},
+ {"GetCaptureData", (PyCFunction)sv_GetCaptureData, METH_OLDARGS},
+ {"CloseVideo", (PyCFunction)sv_CloseVideo, METH_OLDARGS},
+ {"LoadMap", (PyCFunction)sv_LoadMap, METH_OLDARGS},
+ {"GetParam", (PyCFunction)sv_GetParam, METH_OLDARGS},
+ {"GetParamRange", (PyCFunction)sv_GetParamRange, METH_OLDARGS},
+ {"SetParam", (PyCFunction)sv_SetParam, METH_OLDARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+sv_conversion(PyObject *self, PyObject *args, void (*function)(),
+ int inputfactor, float factor)
+{
+ int invert, width, height, inputlength;
+ char *input, *str;
+ PyObject *output;
+
+ if (!PyArg_Parse(args, "(is#ii)", &invert,
+ &input, &inputlength, &width, &height))
+ return NULL;
+
+ if (width * height * inputfactor > inputlength) {
+ PyErr_SetString(SvError, "input buffer not long enough");
+ return NULL;
+ }
+
+ if (!(output = PyString_FromStringAndSize(NULL,
+ (int)(width * height * factor))))
+ return NULL;
+
+ str = PyString_AsString(output);
+ if (!str) {
+ Py_DECREF(output);
+ return NULL;
+ }
+ (*function)(invert, input, str, width, height);
+
+ return output;
+}
+
+static PyObject *
+sv_InterleaveFields(PyObject *self, PyObject *args)
+{
+ return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
+}
+
+static PyObject *
+sv_RGB8toRGB32(PyObject *self, PyObject *args)
+{
+ return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
+}
+
+static PyObject *
+sv_YUVtoRGB(PyObject *self, PyObject *args)
+{
+ return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
+}
+
+static void
+svideo_dealloc(svobject *self)
+{
+ if (self->ob_svideo != NULL)
+ (void) svCloseVideo(self->ob_svideo);
+ PyObject_Del(self);
+}
+
+static PyObject *
+svideo_getattr(svobject *self, char *name)
+{
+ return Py_FindMethod(svideo_methods, (PyObject *)self, name);
+}
+
+PyTypeObject Svtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "sv.sv", /*tp_name*/
+ sizeof(svobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)svideo_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)svideo_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static PyObject *
+newsvobject(SV_nodeP svp)
+{
+ svobject *p;
+
+ p = PyObject_New(svobject, &Svtype);
+ if (p == NULL)
+ return NULL;
+ p->ob_svideo = svp;
+ p->ob_info.format = 0;
+ p->ob_info.size = 0;
+ p->ob_info.width = 0;
+ p->ob_info.height = 0;
+ p->ob_info.samplingrate = 0;
+ return (PyObject *) p;
+}
+
+static PyObject *
+sv_OpenVideo(PyObject *self, PyObject *args)
+{
+ SV_nodeP svp;
+
+ if (!PyArg_Parse(args, ""))
+ return NULL;
+
+ svp = svOpenVideo();
+ if (svp == NULL)
+ return sv_error();
+
+ return newsvobject(svp);
+}
+
+static PyMethodDef sv_methods[] = {
+ {"InterleaveFields", (PyCFunction)sv_InterleaveFields, METH_OLDARGS},
+ {"RGB8toRGB32", (PyCFunction)sv_RGB8toRGB32, METH_OLDARGS},
+ {"YUVtoRGB", (PyCFunction)sv_YUVtoRGB, METH_OLDARGS},
+ {"OpenVideo", (PyCFunction)sv_OpenVideo, METH_OLDARGS},
+ {NULL, NULL} /* Sentinel */
+};
+
+void
+initsv(void)
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule("sv", sv_methods);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ SvError = PyErr_NewException("sv.error", NULL, NULL);
+ if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/symtablemodule.c b/sys/src/cmd/python/Modules/symtablemodule.c
new file mode 100644
index 000000000..c90d7650a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/symtablemodule.c
@@ -0,0 +1,84 @@
+#include "Python.h"
+
+#include "code.h"
+#include "compile.h"
+#include "Python-ast.h"
+#include "symtable.h"
+
+static PyObject *
+symtable_symtable(PyObject *self, PyObject *args)
+{
+ struct symtable *st;
+ PyObject *t;
+
+ char *str;
+ char *filename;
+ char *startstr;
+ int start;
+
+ if (!PyArg_ParseTuple(args, "sss:symtable", &str, &filename,
+ &startstr))
+ return NULL;
+ if (strcmp(startstr, "exec") == 0)
+ start = Py_file_input;
+ else if (strcmp(startstr, "eval") == 0)
+ start = Py_eval_input;
+ else if (strcmp(startstr, "single") == 0)
+ start = Py_single_input;
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "symtable() arg 3 must be 'exec' or 'eval' or 'single'");
+ return NULL;
+ }
+ st = Py_SymtableString(str, filename, start);
+ if (st == NULL)
+ return NULL;
+ t = st->st_symbols;
+ Py_INCREF(t);
+ PyMem_Free((void *)st->st_future);
+ PySymtable_Free(st);
+ return t;
+}
+
+static PyMethodDef symtable_methods[] = {
+ {"symtable", symtable_symtable, METH_VARARGS,
+ PyDoc_STR("Return symbol and scope dictionaries"
+ " used internally by compiler.")},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+init_symtable(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule("_symtable", symtable_methods);
+ if (m == NULL)
+ return;
+ PyModule_AddIntConstant(m, "USE", USE);
+ PyModule_AddIntConstant(m, "DEF_GLOBAL", DEF_GLOBAL);
+ PyModule_AddIntConstant(m, "DEF_LOCAL", DEF_LOCAL);
+ PyModule_AddIntConstant(m, "DEF_PARAM", DEF_PARAM);
+ PyModule_AddIntConstant(m, "DEF_STAR", DEF_STAR);
+ PyModule_AddIntConstant(m, "DEF_DOUBLESTAR", DEF_DOUBLESTAR);
+ PyModule_AddIntConstant(m, "DEF_INTUPLE", DEF_INTUPLE);
+ PyModule_AddIntConstant(m, "DEF_FREE", DEF_FREE);
+ PyModule_AddIntConstant(m, "DEF_FREE_GLOBAL", DEF_FREE_GLOBAL);
+ PyModule_AddIntConstant(m, "DEF_FREE_CLASS", DEF_FREE_CLASS);
+ PyModule_AddIntConstant(m, "DEF_IMPORT", DEF_IMPORT);
+ PyModule_AddIntConstant(m, "DEF_BOUND", DEF_BOUND);
+
+ PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock);
+ PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock);
+ PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock);
+
+ PyModule_AddIntConstant(m, "OPT_IMPORT_STAR", OPT_IMPORT_STAR);
+ PyModule_AddIntConstant(m, "OPT_EXEC", OPT_EXEC);
+ PyModule_AddIntConstant(m, "OPT_BARE_EXEC", OPT_BARE_EXEC);
+
+ PyModule_AddIntConstant(m, "LOCAL", LOCAL);
+ PyModule_AddIntConstant(m, "GLOBAL_EXPLICIT", GLOBAL_EXPLICIT);
+ PyModule_AddIntConstant(m, "GLOBAL_IMPLICIT", GLOBAL_IMPLICIT);
+ PyModule_AddIntConstant(m, "FREE", FREE);
+ PyModule_AddIntConstant(m, "CELL", CELL);
+}
diff --git a/sys/src/cmd/python/Modules/syslogmodule.c b/sys/src/cmd/python/Modules/syslogmodule.c
new file mode 100644
index 000000000..4a7791694
--- /dev/null
+++ b/sys/src/cmd/python/Modules/syslogmodule.c
@@ -0,0 +1,223 @@
+/***********************************************************
+Copyright 1994 by Lance Ellinghouse,
+Cathedral City, California Republic, United States of America.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Lance Ellinghouse
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/******************************************************************
+
+Revision history:
+
+1998/04/28 (Sean Reifschneider)
+ - When facility not specified to syslog() method, use default from openlog()
+ (This is how it was claimed to work in the documentation)
+ - Potential resource leak of o_ident, now cleaned up in closelog()
+ - Minor comment accuracy fix.
+
+95/06/29 (Steve Clift)
+ - Changed arg parsing to use PyArg_ParseTuple.
+ - Added PyErr_Clear() call(s) where needed.
+ - Fix core dumps if user message contains format specifiers.
+ - Change openlog arg defaults to match normal syslog behavior.
+ - Plug memory leak in openlog().
+ - Fix setlogmask() to return previous mask value.
+
+******************************************************************/
+
+/* syslog module */
+
+#include "Python.h"
+
+#include <syslog.h>
+
+/* only one instance, only one syslog, so globals should be ok */
+static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */
+
+
+static PyObject *
+syslog_openlog(PyObject * self, PyObject * args)
+{
+ long logopt = 0;
+ long facility = LOG_USER;
+ PyObject *new_S_ident_o;
+
+ if (!PyArg_ParseTuple(args,
+ "S|ll;ident string [, logoption [, facility]]",
+ &new_S_ident_o, &logopt, &facility))
+ return NULL;
+
+ /* This is needed because openlog() does NOT make a copy
+ * and syslog() later uses it.. cannot trash it.
+ */
+ Py_XDECREF(S_ident_o);
+ S_ident_o = new_S_ident_o;
+ Py_INCREF(S_ident_o);
+
+ openlog(PyString_AsString(S_ident_o), logopt, facility);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+static PyObject *
+syslog_syslog(PyObject * self, PyObject * args)
+{
+ char *message;
+ int priority = LOG_INFO;
+
+ if (!PyArg_ParseTuple(args, "is;[priority,] message string",
+ &priority, &message)) {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "s;[priority,] message string",
+ &message))
+ return NULL;
+ }
+
+ syslog(priority, "%s", message);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+syslog_closelog(PyObject *self, PyObject *unused)
+{
+ closelog();
+ Py_XDECREF(S_ident_o);
+ S_ident_o = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+syslog_setlogmask(PyObject *self, PyObject *args)
+{
+ long maskpri, omaskpri;
+
+ if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri))
+ return NULL;
+ omaskpri = setlogmask(maskpri);
+ return PyInt_FromLong(omaskpri);
+}
+
+static PyObject *
+syslog_log_mask(PyObject *self, PyObject *args)
+{
+ long mask;
+ long pri;
+ if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri))
+ return NULL;
+ mask = LOG_MASK(pri);
+ return PyInt_FromLong(mask);
+}
+
+static PyObject *
+syslog_log_upto(PyObject *self, PyObject *args)
+{
+ long mask;
+ long pri;
+ if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri))
+ return NULL;
+ mask = LOG_UPTO(pri);
+ return PyInt_FromLong(mask);
+}
+
+/* List of functions defined in the module */
+
+static PyMethodDef syslog_methods[] = {
+ {"openlog", syslog_openlog, METH_VARARGS},
+ {"closelog", syslog_closelog, METH_NOARGS},
+ {"syslog", syslog_syslog, METH_VARARGS},
+ {"setlogmask", syslog_setlogmask, METH_VARARGS},
+ {"LOG_MASK", syslog_log_mask, METH_VARARGS},
+ {"LOG_UPTO", syslog_log_upto, METH_VARARGS},
+ {NULL, NULL, 0}
+};
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+initsyslog(void)
+{
+ PyObject *m;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("syslog", syslog_methods);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+
+ /* Priorities */
+ PyModule_AddIntConstant(m, "LOG_EMERG", LOG_EMERG);
+ PyModule_AddIntConstant(m, "LOG_ALERT", LOG_ALERT);
+ PyModule_AddIntConstant(m, "LOG_CRIT", LOG_CRIT);
+ PyModule_AddIntConstant(m, "LOG_ERR", LOG_ERR);
+ PyModule_AddIntConstant(m, "LOG_WARNING", LOG_WARNING);
+ PyModule_AddIntConstant(m, "LOG_NOTICE", LOG_NOTICE);
+ PyModule_AddIntConstant(m, "LOG_INFO", LOG_INFO);
+ PyModule_AddIntConstant(m, "LOG_DEBUG", LOG_DEBUG);
+
+ /* openlog() option flags */
+ PyModule_AddIntConstant(m, "LOG_PID", LOG_PID);
+ PyModule_AddIntConstant(m, "LOG_CONS", LOG_CONS);
+ PyModule_AddIntConstant(m, "LOG_NDELAY", LOG_NDELAY);
+#ifdef LOG_NOWAIT
+ PyModule_AddIntConstant(m, "LOG_NOWAIT", LOG_NOWAIT);
+#endif
+#ifdef LOG_PERROR
+ PyModule_AddIntConstant(m, "LOG_PERROR", LOG_PERROR);
+#endif
+
+ /* Facilities */
+ PyModule_AddIntConstant(m, "LOG_KERN", LOG_KERN);
+ PyModule_AddIntConstant(m, "LOG_USER", LOG_USER);
+ PyModule_AddIntConstant(m, "LOG_MAIL", LOG_MAIL);
+ PyModule_AddIntConstant(m, "LOG_DAEMON", LOG_DAEMON);
+ PyModule_AddIntConstant(m, "LOG_AUTH", LOG_AUTH);
+ PyModule_AddIntConstant(m, "LOG_LPR", LOG_LPR);
+ PyModule_AddIntConstant(m, "LOG_LOCAL0", LOG_LOCAL0);
+ PyModule_AddIntConstant(m, "LOG_LOCAL1", LOG_LOCAL1);
+ PyModule_AddIntConstant(m, "LOG_LOCAL2", LOG_LOCAL2);
+ PyModule_AddIntConstant(m, "LOG_LOCAL3", LOG_LOCAL3);
+ PyModule_AddIntConstant(m, "LOG_LOCAL4", LOG_LOCAL4);
+ PyModule_AddIntConstant(m, "LOG_LOCAL5", LOG_LOCAL5);
+ PyModule_AddIntConstant(m, "LOG_LOCAL6", LOG_LOCAL6);
+ PyModule_AddIntConstant(m, "LOG_LOCAL7", LOG_LOCAL7);
+
+#ifndef LOG_SYSLOG
+#define LOG_SYSLOG LOG_DAEMON
+#endif
+#ifndef LOG_NEWS
+#define LOG_NEWS LOG_MAIL
+#endif
+#ifndef LOG_UUCP
+#define LOG_UUCP LOG_MAIL
+#endif
+#ifndef LOG_CRON
+#define LOG_CRON LOG_DAEMON
+#endif
+
+ PyModule_AddIntConstant(m, "LOG_SYSLOG", LOG_SYSLOG);
+ PyModule_AddIntConstant(m, "LOG_CRON", LOG_CRON);
+ PyModule_AddIntConstant(m, "LOG_UUCP", LOG_UUCP);
+ PyModule_AddIntConstant(m, "LOG_NEWS", LOG_NEWS);
+}
diff --git a/sys/src/cmd/python/Modules/termios.c b/sys/src/cmd/python/Modules/termios.c
new file mode 100644
index 000000000..c53566c12
--- /dev/null
+++ b/sys/src/cmd/python/Modules/termios.c
@@ -0,0 +1,926 @@
+/* termiosmodule.c -- POSIX terminal I/O module implementation. */
+
+#include "Python.h"
+
+#define PyInit_termios inittermios
+
+/* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE
+ is defined, so we define it here. */
+#if defined(__sgi)
+#define CTRL(c) ((c)&037)
+#endif
+
+#include <termios.h>
+#ifdef __osf__
+/* On OSF, sys/ioctl.h requires that struct termio already be defined,
+ * so this needs to be included first on that platform. */
+#include <termio.h>
+#endif
+#include <sys/ioctl.h>
+
+/* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR,
+ * MDTR, MRI, and MRTS (appearantly used internally by some things
+ * defined as macros; these are not used here directly).
+ */
+#ifdef HAVE_SYS_MODEM_H
+#include <sys/modem.h>
+#endif
+/* HP-UX requires that this be included to pick up TIOCGPGRP and friends */
+#ifdef HAVE_SYS_BSDTTY_H
+#include <sys/bsdtty.h>
+#endif
+
+PyDoc_STRVAR(termios__doc__,
+"This module provides an interface to the Posix calls for tty I/O control.\n\
+For a complete description of these calls, see the Posix or Unix manual\n\
+pages. It is only available for those Unix versions that support Posix\n\
+termios style tty I/O control.\n\
+\n\
+All functions in this module take a file descriptor fd as their first\n\
+argument. This can be an integer file descriptor, such as returned by\n\
+sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
+
+static PyObject *TermiosError;
+
+static int fdconv(PyObject* obj, void* p)
+{
+ int fd;
+
+ fd = PyObject_AsFileDescriptor(obj);
+ if (fd >= 0) {
+ *(int*)p = fd;
+ return 1;
+ }
+ return 0;
+}
+
+PyDoc_STRVAR(termios_tcgetattr__doc__,
+"tcgetattr(fd) -> list_of_attrs\n\
+\n\
+Get the tty attributes for file descriptor fd, as follows:\n\
+[iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\
+of the tty special characters (each a string of length 1, except the items\n\
+with indices VMIN and VTIME, which are integers when these fields are\n\
+defined). The interpretation of the flags and the speeds as well as the\n\
+indexing in the cc array must be done using the symbolic constants defined\n\
+in this module.");
+
+static PyObject *
+termios_tcgetattr(PyObject *self, PyObject *args)
+{
+ int fd;
+ struct termios mode;
+ PyObject *cc;
+ speed_t ispeed, ospeed;
+ PyObject *v;
+ int i;
+ char ch;
+
+ if (!PyArg_ParseTuple(args, "O&:tcgetattr",
+ fdconv, (void*)&fd))
+ return NULL;
+
+ if (tcgetattr(fd, &mode) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+
+ ispeed = cfgetispeed(&mode);
+ ospeed = cfgetospeed(&mode);
+
+ cc = PyList_New(NCCS);
+ if (cc == NULL)
+ return NULL;
+ for (i = 0; i < NCCS; i++) {
+ ch = (char)mode.c_cc[i];
+ v = PyString_FromStringAndSize(&ch, 1);
+ if (v == NULL)
+ goto err;
+ PyList_SetItem(cc, i, v);
+ }
+
+ /* Convert the MIN and TIME slots to integer. On some systems, the
+ MIN and TIME slots are the same as the EOF and EOL slots. So we
+ only do this in noncanonical input mode. */
+ if ((mode.c_lflag & ICANON) == 0) {
+ v = PyInt_FromLong((long)mode.c_cc[VMIN]);
+ if (v == NULL)
+ goto err;
+ PyList_SetItem(cc, VMIN, v);
+ v = PyInt_FromLong((long)mode.c_cc[VTIME]);
+ if (v == NULL)
+ goto err;
+ PyList_SetItem(cc, VTIME, v);
+ }
+
+ if (!(v = PyList_New(7)))
+ goto err;
+
+ PyList_SetItem(v, 0, PyInt_FromLong((long)mode.c_iflag));
+ PyList_SetItem(v, 1, PyInt_FromLong((long)mode.c_oflag));
+ PyList_SetItem(v, 2, PyInt_FromLong((long)mode.c_cflag));
+ PyList_SetItem(v, 3, PyInt_FromLong((long)mode.c_lflag));
+ PyList_SetItem(v, 4, PyInt_FromLong((long)ispeed));
+ PyList_SetItem(v, 5, PyInt_FromLong((long)ospeed));
+ PyList_SetItem(v, 6, cc);
+ if (PyErr_Occurred()){
+ Py_DECREF(v);
+ goto err;
+ }
+ return v;
+ err:
+ Py_DECREF(cc);
+ return NULL;
+}
+
+PyDoc_STRVAR(termios_tcsetattr__doc__,
+"tcsetattr(fd, when, attributes) -> None\n\
+\n\
+Set the tty attributes for file descriptor fd.\n\
+The attributes to be set are taken from the attributes argument, which\n\
+is a list like the one returned by tcgetattr(). The when argument\n\
+determines when the attributes are changed: termios.TCSANOW to\n\
+change immediately, termios.TCSADRAIN to change after transmitting all\n\
+queued output, or termios.TCSAFLUSH to change after transmitting all\n\
+queued output and discarding all queued input. ");
+
+static PyObject *
+termios_tcsetattr(PyObject *self, PyObject *args)
+{
+ int fd, when;
+ struct termios mode;
+ speed_t ispeed, ospeed;
+ PyObject *term, *cc, *v;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "O&iO:tcsetattr",
+ fdconv, &fd, &when, &term))
+ return NULL;
+ if (!PyList_Check(term) || PyList_Size(term) != 7) {
+ PyErr_SetString(PyExc_TypeError,
+ "tcsetattr, arg 3: must be 7 element list");
+ return NULL;
+ }
+
+ /* Get the old mode, in case there are any hidden fields... */
+ if (tcgetattr(fd, &mode) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+ mode.c_iflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 0));
+ mode.c_oflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 1));
+ mode.c_cflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 2));
+ mode.c_lflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 3));
+ ispeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 4));
+ ospeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 5));
+ cc = PyList_GetItem(term, 6);
+ if (PyErr_Occurred())
+ return NULL;
+
+ if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
+ PyErr_Format(PyExc_TypeError,
+ "tcsetattr: attributes[6] must be %d element list",
+ NCCS);
+ return NULL;
+ }
+
+ for (i = 0; i < NCCS; i++) {
+ v = PyList_GetItem(cc, i);
+
+ if (PyString_Check(v) && PyString_Size(v) == 1)
+ mode.c_cc[i] = (cc_t) * PyString_AsString(v);
+ else if (PyInt_Check(v))
+ mode.c_cc[i] = (cc_t) PyInt_AsLong(v);
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "tcsetattr: elements of attributes must be characters or integers");
+ return NULL;
+ }
+ }
+
+ if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+ if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+ if (tcsetattr(fd, when, &mode) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcsendbreak__doc__,
+"tcsendbreak(fd, duration) -> None\n\
+\n\
+Send a break on file descriptor fd.\n\
+A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
+has a system dependent meaning.");
+
+static PyObject *
+termios_tcsendbreak(PyObject *self, PyObject *args)
+{
+ int fd, duration;
+
+ if (!PyArg_ParseTuple(args, "O&i:tcsendbreak",
+ fdconv, &fd, &duration))
+ return NULL;
+ if (tcsendbreak(fd, duration) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcdrain__doc__,
+"tcdrain(fd) -> None\n\
+\n\
+Wait until all output written to file descriptor fd has been transmitted.");
+
+static PyObject *
+termios_tcdrain(PyObject *self, PyObject *args)
+{
+ int fd;
+
+ if (!PyArg_ParseTuple(args, "O&:tcdrain",
+ fdconv, &fd))
+ return NULL;
+ if (tcdrain(fd) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcflush__doc__,
+"tcflush(fd, queue) -> None\n\
+\n\
+Discard queued data on file descriptor fd.\n\
+The queue selector specifies which queue: termios.TCIFLUSH for the input\n\
+queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
+both queues. ");
+
+static PyObject *
+termios_tcflush(PyObject *self, PyObject *args)
+{
+ int fd, queue;
+
+ if (!PyArg_ParseTuple(args, "O&i:tcflush",
+ fdconv, &fd, &queue))
+ return NULL;
+ if (tcflush(fd, queue) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(termios_tcflow__doc__,
+"tcflow(fd, action) -> None\n\
+\n\
+Suspend or resume input or output on file descriptor fd.\n\
+The action argument can be termios.TCOOFF to suspend output,\n\
+termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
+or termios.TCION to restart input.");
+
+static PyObject *
+termios_tcflow(PyObject *self, PyObject *args)
+{
+ int fd, action;
+
+ if (!PyArg_ParseTuple(args, "O&i:tcflow",
+ fdconv, &fd, &action))
+ return NULL;
+ if (tcflow(fd, action) == -1)
+ return PyErr_SetFromErrno(TermiosError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef termios_methods[] =
+{
+ {"tcgetattr", termios_tcgetattr,
+ METH_VARARGS, termios_tcgetattr__doc__},
+ {"tcsetattr", termios_tcsetattr,
+ METH_VARARGS, termios_tcsetattr__doc__},
+ {"tcsendbreak", termios_tcsendbreak,
+ METH_VARARGS, termios_tcsendbreak__doc__},
+ {"tcdrain", termios_tcdrain,
+ METH_VARARGS, termios_tcdrain__doc__},
+ {"tcflush", termios_tcflush,
+ METH_VARARGS, termios_tcflush__doc__},
+ {"tcflow", termios_tcflow,
+ METH_VARARGS, termios_tcflow__doc__},
+ {NULL, NULL}
+};
+
+
+#if defined(VSWTCH) && !defined(VSWTC)
+#define VSWTC VSWTCH
+#endif
+
+#if defined(VSWTC) && !defined(VSWTCH)
+#define VSWTCH VSWTC
+#endif
+
+static struct constant {
+ char *name;
+ long value;
+} termios_constants[] = {
+ /* cfgetospeed(), cfsetospeed() constants */
+ {"B0", B0},
+ {"B50", B50},
+ {"B75", B75},
+ {"B110", B110},
+ {"B134", B134},
+ {"B150", B150},
+ {"B200", B200},
+ {"B300", B300},
+ {"B600", B600},
+ {"B1200", B1200},
+ {"B1800", B1800},
+ {"B2400", B2400},
+ {"B4800", B4800},
+ {"B9600", B9600},
+ {"B19200", B19200},
+ {"B38400", B38400},
+#ifdef B57600
+ {"B57600", B57600},
+#endif
+#ifdef B115200
+ {"B115200", B115200},
+#endif
+#ifdef B230400
+ {"B230400", B230400},
+#endif
+#ifdef CBAUDEX
+ {"CBAUDEX", CBAUDEX},
+#endif
+
+ /* tcsetattr() constants */
+ {"TCSANOW", TCSANOW},
+ {"TCSADRAIN", TCSADRAIN},
+ {"TCSAFLUSH", TCSAFLUSH},
+
+ /* tcflush() constants */
+ {"TCIFLUSH", TCIFLUSH},
+ {"TCOFLUSH", TCOFLUSH},
+ {"TCIOFLUSH", TCIOFLUSH},
+
+ /* tcflow() constants */
+ {"TCOOFF", TCOOFF},
+ {"TCOON", TCOON},
+ {"TCIOFF", TCIOFF},
+ {"TCION", TCION},
+
+ /* struct termios.c_iflag constants */
+ {"IGNBRK", IGNBRK},
+ {"BRKINT", BRKINT},
+ {"IGNPAR", IGNPAR},
+ {"PARMRK", PARMRK},
+ {"INPCK", INPCK},
+ {"ISTRIP", ISTRIP},
+ {"INLCR", INLCR},
+ {"IGNCR", IGNCR},
+ {"ICRNL", ICRNL},
+#ifdef IUCLC
+ {"IUCLC", IUCLC},
+#endif
+ {"IXON", IXON},
+ {"IXANY", IXANY},
+ {"IXOFF", IXOFF},
+#ifdef IMAXBEL
+ {"IMAXBEL", IMAXBEL},
+#endif
+
+ /* struct termios.c_oflag constants */
+ {"OPOST", OPOST},
+#ifdef OLCUC
+ {"OLCUC", OLCUC},
+#endif
+#ifdef ONLCR
+ {"ONLCR", ONLCR},
+#endif
+#ifdef OCRNL
+ {"OCRNL", OCRNL},
+#endif
+#ifdef ONOCR
+ {"ONOCR", ONOCR},
+#endif
+#ifdef ONLRET
+ {"ONLRET", ONLRET},
+#endif
+#ifdef OFILL
+ {"OFILL", OFILL},
+#endif
+#ifdef OFDEL
+ {"OFDEL", OFDEL},
+#endif
+#ifdef NLDLY
+ {"NLDLY", NLDLY},
+#endif
+#ifdef CRDLY
+ {"CRDLY", CRDLY},
+#endif
+#ifdef TABDLY
+ {"TABDLY", TABDLY},
+#endif
+#ifdef BSDLY
+ {"BSDLY", BSDLY},
+#endif
+#ifdef VTDLY
+ {"VTDLY", VTDLY},
+#endif
+#ifdef FFDLY
+ {"FFDLY", FFDLY},
+#endif
+
+ /* struct termios.c_oflag-related values (delay mask) */
+#ifdef NL0
+ {"NL0", NL0},
+#endif
+#ifdef NL1
+ {"NL1", NL1},
+#endif
+#ifdef CR0
+ {"CR0", CR0},
+#endif
+#ifdef CR1
+ {"CR1", CR1},
+#endif
+#ifdef CR2
+ {"CR2", CR2},
+#endif
+#ifdef CR3
+ {"CR3", CR3},
+#endif
+#ifdef TAB0
+ {"TAB0", TAB0},
+#endif
+#ifdef TAB1
+ {"TAB1", TAB1},
+#endif
+#ifdef TAB2
+ {"TAB2", TAB2},
+#endif
+#ifdef TAB3
+ {"TAB3", TAB3},
+#endif
+#ifdef XTABS
+ {"XTABS", XTABS},
+#endif
+#ifdef BS0
+ {"BS0", BS0},
+#endif
+#ifdef BS1
+ {"BS1", BS1},
+#endif
+#ifdef VT0
+ {"VT0", VT0},
+#endif
+#ifdef VT1
+ {"VT1", VT1},
+#endif
+#ifdef FF0
+ {"FF0", FF0},
+#endif
+#ifdef FF1
+ {"FF1", FF1},
+#endif
+
+ /* struct termios.c_cflag constants */
+ {"CSIZE", CSIZE},
+ {"CSTOPB", CSTOPB},
+ {"CREAD", CREAD},
+ {"PARENB", PARENB},
+ {"PARODD", PARODD},
+ {"HUPCL", HUPCL},
+ {"CLOCAL", CLOCAL},
+#ifdef CIBAUD
+ {"CIBAUD", CIBAUD},
+#endif
+#ifdef CRTSCTS
+ {"CRTSCTS", (long)CRTSCTS},
+#endif
+
+ /* struct termios.c_cflag-related values (character size) */
+ {"CS5", CS5},
+ {"CS6", CS6},
+ {"CS7", CS7},
+ {"CS8", CS8},
+
+ /* struct termios.c_lflag constants */
+ {"ISIG", ISIG},
+ {"ICANON", ICANON},
+#ifdef XCASE
+ {"XCASE", XCASE},
+#endif
+ {"ECHO", ECHO},
+ {"ECHOE", ECHOE},
+ {"ECHOK", ECHOK},
+ {"ECHONL", ECHONL},
+#ifdef ECHOCTL
+ {"ECHOCTL", ECHOCTL},
+#endif
+#ifdef ECHOPRT
+ {"ECHOPRT", ECHOPRT},
+#endif
+#ifdef ECHOKE
+ {"ECHOKE", ECHOKE},
+#endif
+#ifdef FLUSHO
+ {"FLUSHO", FLUSHO},
+#endif
+ {"NOFLSH", NOFLSH},
+ {"TOSTOP", TOSTOP},
+#ifdef PENDIN
+ {"PENDIN", PENDIN},
+#endif
+ {"IEXTEN", IEXTEN},
+
+ /* indexes into the control chars array returned by tcgetattr() */
+ {"VINTR", VINTR},
+ {"VQUIT", VQUIT},
+ {"VERASE", VERASE},
+ {"VKILL", VKILL},
+ {"VEOF", VEOF},
+ {"VTIME", VTIME},
+ {"VMIN", VMIN},
+#ifdef VSWTC
+ /* The #defines above ensure that if either is defined, both are,
+ * but both may be omitted by the system headers. ;-( */
+ {"VSWTC", VSWTC},
+ {"VSWTCH", VSWTCH},
+#endif
+ {"VSTART", VSTART},
+ {"VSTOP", VSTOP},
+ {"VSUSP", VSUSP},
+ {"VEOL", VEOL},
+#ifdef VREPRINT
+ {"VREPRINT", VREPRINT},
+#endif
+#ifdef VDISCARD
+ {"VDISCARD", VDISCARD},
+#endif
+#ifdef VWERASE
+ {"VWERASE", VWERASE},
+#endif
+#ifdef VLNEXT
+ {"VLNEXT", VLNEXT},
+#endif
+#ifdef VEOL2
+ {"VEOL2", VEOL2},
+#endif
+
+
+#ifdef B460800
+ {"B460800", B460800},
+#endif
+#ifdef CBAUD
+ {"CBAUD", CBAUD},
+#endif
+#ifdef CDEL
+ {"CDEL", CDEL},
+#endif
+#ifdef CDSUSP
+ {"CDSUSP", CDSUSP},
+#endif
+#ifdef CEOF
+ {"CEOF", CEOF},
+#endif
+#ifdef CEOL
+ {"CEOL", CEOL},
+#endif
+#ifdef CEOL2
+ {"CEOL2", CEOL2},
+#endif
+#ifdef CEOT
+ {"CEOT", CEOT},
+#endif
+#ifdef CERASE
+ {"CERASE", CERASE},
+#endif
+#ifdef CESC
+ {"CESC", CESC},
+#endif
+#ifdef CFLUSH
+ {"CFLUSH", CFLUSH},
+#endif
+#ifdef CINTR
+ {"CINTR", CINTR},
+#endif
+#ifdef CKILL
+ {"CKILL", CKILL},
+#endif
+#ifdef CLNEXT
+ {"CLNEXT", CLNEXT},
+#endif
+#ifdef CNUL
+ {"CNUL", CNUL},
+#endif
+#ifdef COMMON
+ {"COMMON", COMMON},
+#endif
+#ifdef CQUIT
+ {"CQUIT", CQUIT},
+#endif
+#ifdef CRPRNT
+ {"CRPRNT", CRPRNT},
+#endif
+#ifdef CSTART
+ {"CSTART", CSTART},
+#endif
+#ifdef CSTOP
+ {"CSTOP", CSTOP},
+#endif
+#ifdef CSUSP
+ {"CSUSP", CSUSP},
+#endif
+#ifdef CSWTCH
+ {"CSWTCH", CSWTCH},
+#endif
+#ifdef CWERASE
+ {"CWERASE", CWERASE},
+#endif
+#ifdef EXTA
+ {"EXTA", EXTA},
+#endif
+#ifdef EXTB
+ {"EXTB", EXTB},
+#endif
+#ifdef FIOASYNC
+ {"FIOASYNC", FIOASYNC},
+#endif
+#ifdef FIOCLEX
+ {"FIOCLEX", FIOCLEX},
+#endif
+#ifdef FIONBIO
+ {"FIONBIO", FIONBIO},
+#endif
+#ifdef FIONCLEX
+ {"FIONCLEX", FIONCLEX},
+#endif
+#ifdef FIONREAD
+ {"FIONREAD", FIONREAD},
+#endif
+#ifdef IBSHIFT
+ {"IBSHIFT", IBSHIFT},
+#endif
+#ifdef INIT_C_CC
+ {"INIT_C_CC", INIT_C_CC},
+#endif
+#ifdef IOCSIZE_MASK
+ {"IOCSIZE_MASK", IOCSIZE_MASK},
+#endif
+#ifdef IOCSIZE_SHIFT
+ {"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
+#endif
+#ifdef NCC
+ {"NCC", NCC},
+#endif
+#ifdef NCCS
+ {"NCCS", NCCS},
+#endif
+#ifdef NSWTCH
+ {"NSWTCH", NSWTCH},
+#endif
+#ifdef N_MOUSE
+ {"N_MOUSE", N_MOUSE},
+#endif
+#ifdef N_PPP
+ {"N_PPP", N_PPP},
+#endif
+#ifdef N_SLIP
+ {"N_SLIP", N_SLIP},
+#endif
+#ifdef N_STRIP
+ {"N_STRIP", N_STRIP},
+#endif
+#ifdef N_TTY
+ {"N_TTY", N_TTY},
+#endif
+#ifdef TCFLSH
+ {"TCFLSH", TCFLSH},
+#endif
+#ifdef TCGETA
+ {"TCGETA", TCGETA},
+#endif
+#ifdef TCGETS
+ {"TCGETS", TCGETS},
+#endif
+#ifdef TCSBRK
+ {"TCSBRK", TCSBRK},
+#endif
+#ifdef TCSBRKP
+ {"TCSBRKP", TCSBRKP},
+#endif
+#ifdef TCSETA
+ {"TCSETA", TCSETA},
+#endif
+#ifdef TCSETAF
+ {"TCSETAF", TCSETAF},
+#endif
+#ifdef TCSETAW
+ {"TCSETAW", TCSETAW},
+#endif
+#ifdef TCSETS
+ {"TCSETS", TCSETS},
+#endif
+#ifdef TCSETSF
+ {"TCSETSF", TCSETSF},
+#endif
+#ifdef TCSETSW
+ {"TCSETSW", TCSETSW},
+#endif
+#ifdef TCXONC
+ {"TCXONC", TCXONC},
+#endif
+#ifdef TIOCCONS
+ {"TIOCCONS", TIOCCONS},
+#endif
+#ifdef TIOCEXCL
+ {"TIOCEXCL", TIOCEXCL},
+#endif
+#ifdef TIOCGETD
+ {"TIOCGETD", TIOCGETD},
+#endif
+#ifdef TIOCGICOUNT
+ {"TIOCGICOUNT", TIOCGICOUNT},
+#endif
+#ifdef TIOCGLCKTRMIOS
+ {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
+#endif
+#ifdef TIOCGPGRP
+ {"TIOCGPGRP", TIOCGPGRP},
+#endif
+#ifdef TIOCGSERIAL
+ {"TIOCGSERIAL", TIOCGSERIAL},
+#endif
+#ifdef TIOCGSOFTCAR
+ {"TIOCGSOFTCAR", TIOCGSOFTCAR},
+#endif
+#ifdef TIOCGWINSZ
+ {"TIOCGWINSZ", TIOCGWINSZ},
+#endif
+#ifdef TIOCINQ
+ {"TIOCINQ", TIOCINQ},
+#endif
+#ifdef TIOCLINUX
+ {"TIOCLINUX", TIOCLINUX},
+#endif
+#ifdef TIOCMBIC
+ {"TIOCMBIC", TIOCMBIC},
+#endif
+#ifdef TIOCMBIS
+ {"TIOCMBIS", TIOCMBIS},
+#endif
+#ifdef TIOCMGET
+ {"TIOCMGET", TIOCMGET},
+#endif
+#ifdef TIOCMIWAIT
+ {"TIOCMIWAIT", TIOCMIWAIT},
+#endif
+#ifdef TIOCMSET
+ {"TIOCMSET", TIOCMSET},
+#endif
+#ifdef TIOCM_CAR
+ {"TIOCM_CAR", TIOCM_CAR},
+#endif
+#ifdef TIOCM_CD
+ {"TIOCM_CD", TIOCM_CD},
+#endif
+#ifdef TIOCM_CTS
+ {"TIOCM_CTS", TIOCM_CTS},
+#endif
+#ifdef TIOCM_DSR
+ {"TIOCM_DSR", TIOCM_DSR},
+#endif
+#ifdef TIOCM_DTR
+ {"TIOCM_DTR", TIOCM_DTR},
+#endif
+#ifdef TIOCM_LE
+ {"TIOCM_LE", TIOCM_LE},
+#endif
+#ifdef TIOCM_RI
+ {"TIOCM_RI", TIOCM_RI},
+#endif
+#ifdef TIOCM_RNG
+ {"TIOCM_RNG", TIOCM_RNG},
+#endif
+#ifdef TIOCM_RTS
+ {"TIOCM_RTS", TIOCM_RTS},
+#endif
+#ifdef TIOCM_SR
+ {"TIOCM_SR", TIOCM_SR},
+#endif
+#ifdef TIOCM_ST
+ {"TIOCM_ST", TIOCM_ST},
+#endif
+#ifdef TIOCNOTTY
+ {"TIOCNOTTY", TIOCNOTTY},
+#endif
+#ifdef TIOCNXCL
+ {"TIOCNXCL", TIOCNXCL},
+#endif
+#ifdef TIOCOUTQ
+ {"TIOCOUTQ", TIOCOUTQ},
+#endif
+#ifdef TIOCPKT
+ {"TIOCPKT", TIOCPKT},
+#endif
+#ifdef TIOCPKT_DATA
+ {"TIOCPKT_DATA", TIOCPKT_DATA},
+#endif
+#ifdef TIOCPKT_DOSTOP
+ {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
+#endif
+#ifdef TIOCPKT_FLUSHREAD
+ {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
+#endif
+#ifdef TIOCPKT_FLUSHWRITE
+ {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
+#endif
+#ifdef TIOCPKT_NOSTOP
+ {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
+#endif
+#ifdef TIOCPKT_START
+ {"TIOCPKT_START", TIOCPKT_START},
+#endif
+#ifdef TIOCPKT_STOP
+ {"TIOCPKT_STOP", TIOCPKT_STOP},
+#endif
+#ifdef TIOCSCTTY
+ {"TIOCSCTTY", TIOCSCTTY},
+#endif
+#ifdef TIOCSERCONFIG
+ {"TIOCSERCONFIG", TIOCSERCONFIG},
+#endif
+#ifdef TIOCSERGETLSR
+ {"TIOCSERGETLSR", TIOCSERGETLSR},
+#endif
+#ifdef TIOCSERGETMULTI
+ {"TIOCSERGETMULTI", TIOCSERGETMULTI},
+#endif
+#ifdef TIOCSERGSTRUCT
+ {"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
+#endif
+#ifdef TIOCSERGWILD
+ {"TIOCSERGWILD", TIOCSERGWILD},
+#endif
+#ifdef TIOCSERSETMULTI
+ {"TIOCSERSETMULTI", TIOCSERSETMULTI},
+#endif
+#ifdef TIOCSERSWILD
+ {"TIOCSERSWILD", TIOCSERSWILD},
+#endif
+#ifdef TIOCSER_TEMT
+ {"TIOCSER_TEMT", TIOCSER_TEMT},
+#endif
+#ifdef TIOCSETD
+ {"TIOCSETD", TIOCSETD},
+#endif
+#ifdef TIOCSLCKTRMIOS
+ {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
+#endif
+#ifdef TIOCSPGRP
+ {"TIOCSPGRP", TIOCSPGRP},
+#endif
+#ifdef TIOCSSERIAL
+ {"TIOCSSERIAL", TIOCSSERIAL},
+#endif
+#ifdef TIOCSSOFTCAR
+ {"TIOCSSOFTCAR", TIOCSSOFTCAR},
+#endif
+#ifdef TIOCSTI
+ {"TIOCSTI", TIOCSTI},
+#endif
+#ifdef TIOCSWINSZ
+ {"TIOCSWINSZ", TIOCSWINSZ},
+#endif
+#ifdef TIOCTTYGSTRUCT
+ {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
+#endif
+
+ /* sentinel */
+ {NULL, 0}
+};
+
+
+PyMODINIT_FUNC
+PyInit_termios(void)
+{
+ PyObject *m;
+ struct constant *constant = termios_constants;
+
+ m = Py_InitModule4("termios", termios_methods, termios__doc__,
+ (PyObject *)NULL, PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ if (TermiosError == NULL) {
+ TermiosError = PyErr_NewException("termios.error", NULL, NULL);
+ }
+ Py_INCREF(TermiosError);
+ PyModule_AddObject(m, "error", TermiosError);
+
+ while (constant->name != NULL) {
+ PyModule_AddIntConstant(m, constant->name, constant->value);
+ ++constant;
+ }
+}
diff --git a/sys/src/cmd/python/Modules/testcapi_long.h b/sys/src/cmd/python/Modules/testcapi_long.h
new file mode 100644
index 000000000..8ed6b021e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/testcapi_long.h
@@ -0,0 +1,166 @@
+/* Poor-man's template. Macros used:
+ TESTNAME name of the test (like test_long_api_inner)
+ TYPENAME the signed type (like long)
+ F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject*
+ F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME
+ F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject*
+ F_PY_TO_U convert pylong to unsigned; PyObject* -> unsigned TYPENAME
+*/
+
+static PyObject *
+TESTNAME(PyObject *error(const char*))
+{
+ const int NBITS = sizeof(TYPENAME) * 8;
+ unsigned TYPENAME base;
+ PyObject *pyresult;
+ int i;
+
+ /* Note: This test lets PyObjects leak if an error is raised. Since
+ an error should never be raised, leaks are impossible <wink>. */
+
+ /* Test native -> PyLong -> native roundtrip identity.
+ * Generate all powers of 2, and test them and their negations,
+ * plus the numbers +-1 off from them.
+ */
+ base = 1;
+ for (i = 0;
+ i < NBITS + 1; /* on last, base overflows to 0 */
+ ++i, base <<= 1)
+ {
+ int j;
+ for (j = 0; j < 6; ++j) {
+ TYPENAME in, out;
+ unsigned TYPENAME uin, uout;
+
+ /* For 0, 1, 2 use base; for 3, 4, 5 use -base */
+ uin = j < 3 ? base
+ : (unsigned TYPENAME)(-(TYPENAME)base);
+
+ /* For 0 & 3, subtract 1.
+ * For 1 & 4, leave alone.
+ * For 2 & 5, add 1.
+ */
+ uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1);
+
+ pyresult = F_U_TO_PY(uin);
+ if (pyresult == NULL)
+ return error(
+ "unsigned unexpected null result");
+
+ uout = F_PY_TO_U(pyresult);
+ if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred())
+ return error(
+ "unsigned unexpected -1 result");
+ if (uout != uin)
+ return error(
+ "unsigned output != input");
+ UNBIND(pyresult);
+
+ in = (TYPENAME)uin;
+ pyresult = F_S_TO_PY(in);
+ if (pyresult == NULL)
+ return error(
+ "signed unexpected null result");
+
+ out = F_PY_TO_S(pyresult);
+ if (out == (TYPENAME)-1 && PyErr_Occurred())
+ return error(
+ "signed unexpected -1 result");
+ if (out != in)
+ return error(
+ "signed output != input");
+ UNBIND(pyresult);
+ }
+ }
+
+ /* Overflow tests. The loop above ensured that all limit cases that
+ * should not overflow don't overflow, so all we need to do here is
+ * provoke one-over-the-limit cases (not exhaustive, but sharp).
+ */
+ {
+ PyObject *one, *x, *y;
+ TYPENAME out;
+ unsigned TYPENAME uout;
+
+ one = PyLong_FromLong(1);
+ if (one == NULL)
+ return error(
+ "unexpected NULL from PyLong_FromLong");
+
+ /* Unsigned complains about -1? */
+ x = PyNumber_Negative(one);
+ if (x == NULL)
+ return error(
+ "unexpected NULL from PyNumber_Negative");
+
+ uout = F_PY_TO_U(x);
+ if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
+ return error(
+ "PyLong_AsUnsignedXXX(-1) didn't complain");
+ PyErr_Clear();
+ UNBIND(x);
+
+ /* Unsigned complains about 2**NBITS? */
+ y = PyLong_FromLong((long)NBITS);
+ if (y == NULL)
+ return error(
+ "unexpected NULL from PyLong_FromLong");
+
+ x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */
+ UNBIND(y);
+ if (x == NULL)
+ return error(
+ "unexpected NULL from PyNumber_Lshift");
+
+ uout = F_PY_TO_U(x);
+ if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
+ return error(
+ "PyLong_AsUnsignedXXX(2**NBITS) didn't "
+ "complain");
+ PyErr_Clear();
+
+ /* Signed complains about 2**(NBITS-1)?
+ x still has 2**NBITS. */
+ y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */
+ UNBIND(x);
+ if (y == NULL)
+ return error(
+ "unexpected NULL from PyNumber_Rshift");
+
+ out = F_PY_TO_S(y);
+ if (out != (TYPENAME)-1 || !PyErr_Occurred())
+ return error(
+ "PyLong_AsXXX(2**(NBITS-1)) didn't "
+ "complain");
+ PyErr_Clear();
+
+ /* Signed complains about -2**(NBITS-1)-1?;
+ y still has 2**(NBITS-1). */
+ x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */
+ UNBIND(y);
+ if (x == NULL)
+ return error(
+ "unexpected NULL from PyNumber_Negative");
+
+ y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */
+ UNBIND(x);
+ if (y == NULL)
+ return error(
+ "unexpected NULL from PyNumber_Subtract");
+
+ out = F_PY_TO_S(y);
+ if (out != (TYPENAME)-1 || !PyErr_Occurred())
+ return error(
+ "PyLong_AsXXX(-2**(NBITS-1)-1) didn't "
+ "complain");
+ PyErr_Clear();
+ UNBIND(y);
+
+ Py_XDECREF(x);
+ Py_XDECREF(y);
+ Py_DECREF(one);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
diff --git a/sys/src/cmd/python/Modules/threadmodule.c b/sys/src/cmd/python/Modules/threadmodule.c
new file mode 100644
index 000000000..036619a8f
--- /dev/null
+++ b/sys/src/cmd/python/Modules/threadmodule.c
@@ -0,0 +1,720 @@
+
+/* Thread module */
+/* Interface to Sjoerd's portable C thread library */
+
+#include "Python.h"
+
+#ifndef WITH_THREAD
+#error "Error! The rest of Python is not compiled with thread support."
+#error "Rerun configure, adding a --with-threads option."
+#error "Then run `make clean' followed by `make'."
+#endif
+
+#include "pythread.h"
+
+static PyObject *ThreadError;
+
+
+/* Lock objects */
+
+typedef struct {
+ PyObject_HEAD
+ PyThread_type_lock lock_lock;
+} lockobject;
+
+static void
+lock_dealloc(lockobject *self)
+{
+ assert(self->lock_lock);
+ /* Unlock the lock so it's safe to free it */
+ PyThread_acquire_lock(self->lock_lock, 0);
+ PyThread_release_lock(self->lock_lock);
+
+ PyThread_free_lock(self->lock_lock);
+ PyObject_Del(self);
+}
+
+static PyObject *
+lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
+{
+ int i = 1;
+
+ if (!PyArg_ParseTuple(args, "|i:acquire", &i))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ i = PyThread_acquire_lock(self->lock_lock, i);
+ Py_END_ALLOW_THREADS
+
+ return PyBool_FromLong((long)i);
+}
+
+PyDoc_STRVAR(acquire_doc,
+"acquire([wait]) -> None or bool\n\
+(acquire_lock() is an obsolete synonym)\n\
+\n\
+Lock the lock. Without argument, this blocks if the lock is already\n\
+locked (even by the same thread), waiting for another thread to release\n\
+the lock, and return None once the lock is acquired.\n\
+With an argument, this will only block if the argument is true,\n\
+and the return value reflects whether the lock is acquired.\n\
+The blocking operation is not interruptible.");
+
+static PyObject *
+lock_PyThread_release_lock(lockobject *self)
+{
+ /* Sanity check: the lock must be locked */
+ if (PyThread_acquire_lock(self->lock_lock, 0)) {
+ PyThread_release_lock(self->lock_lock);
+ PyErr_SetString(ThreadError, "release unlocked lock");
+ return NULL;
+ }
+
+ PyThread_release_lock(self->lock_lock);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(release_doc,
+"release()\n\
+(release_lock() is an obsolete synonym)\n\
+\n\
+Release the lock, allowing another thread that is blocked waiting for\n\
+the lock to acquire the lock. The lock must be in the locked state,\n\
+but it needn't be locked by the same thread that unlocks it.");
+
+static PyObject *
+lock_locked_lock(lockobject *self)
+{
+ if (PyThread_acquire_lock(self->lock_lock, 0)) {
+ PyThread_release_lock(self->lock_lock);
+ return PyBool_FromLong(0L);
+ }
+ return PyBool_FromLong(1L);
+}
+
+PyDoc_STRVAR(locked_doc,
+"locked() -> bool\n\
+(locked_lock() is an obsolete synonym)\n\
+\n\
+Return whether the lock is in the locked state.");
+
+static PyMethodDef lock_methods[] = {
+ {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
+ METH_VARARGS, acquire_doc},
+ {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
+ METH_VARARGS, acquire_doc},
+ {"release_lock", (PyCFunction)lock_PyThread_release_lock,
+ METH_NOARGS, release_doc},
+ {"release", (PyCFunction)lock_PyThread_release_lock,
+ METH_NOARGS, release_doc},
+ {"locked_lock", (PyCFunction)lock_locked_lock,
+ METH_NOARGS, locked_doc},
+ {"locked", (PyCFunction)lock_locked_lock,
+ METH_NOARGS, locked_doc},
+ {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
+ METH_VARARGS, acquire_doc},
+ {"__exit__", (PyCFunction)lock_PyThread_release_lock,
+ METH_VARARGS, release_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+lock_getattr(lockobject *self, char *name)
+{
+ return Py_FindMethod(lock_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject Locktype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "thread.lock", /*tp_name*/
+ sizeof(lockobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)lock_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)lock_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+};
+
+static lockobject *
+newlockobject(void)
+{
+ lockobject *self;
+ self = PyObject_New(lockobject, &Locktype);
+ if (self == NULL)
+ return NULL;
+ self->lock_lock = PyThread_allocate_lock();
+ if (self->lock_lock == NULL) {
+ PyObject_Del(self);
+ self = NULL;
+ PyErr_SetString(ThreadError, "can't allocate lock");
+ }
+ return self;
+}
+
+/* Thread-local objects */
+
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *key;
+ PyObject *args;
+ PyObject *kw;
+ PyObject *dict;
+} localobject;
+
+static PyObject *
+local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ localobject *self;
+ PyObject *tdict;
+
+ if (type->tp_init == PyBaseObject_Type.tp_init
+ && ((args && PyObject_IsTrue(args))
+ || (kw && PyObject_IsTrue(kw)))) {
+ PyErr_SetString(PyExc_TypeError,
+ "Initialization arguments are not supported");
+ return NULL;
+ }
+
+ self = (localobject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ Py_XINCREF(args);
+ self->args = args;
+ Py_XINCREF(kw);
+ self->kw = kw;
+ self->dict = NULL; /* making sure */
+ self->key = PyString_FromFormat("thread.local.%p", self);
+ if (self->key == NULL)
+ goto err;
+
+ self->dict = PyDict_New();
+ if (self->dict == NULL)
+ goto err;
+
+ tdict = PyThreadState_GetDict();
+ if (tdict == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "Couldn't get thread-state dictionary");
+ goto err;
+ }
+
+ if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
+ goto err;
+
+ return (PyObject *)self;
+
+ err:
+ Py_DECREF(self);
+ return NULL;
+}
+
+static int
+local_traverse(localobject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->args);
+ Py_VISIT(self->kw);
+ Py_VISIT(self->dict);
+ return 0;
+}
+
+static int
+local_clear(localobject *self)
+{
+ Py_CLEAR(self->key);
+ Py_CLEAR(self->args);
+ Py_CLEAR(self->kw);
+ Py_CLEAR(self->dict);
+ return 0;
+}
+
+static void
+local_dealloc(localobject *self)
+{
+ PyThreadState *tstate;
+ if (self->key
+ && (tstate = PyThreadState_Get())
+ && tstate->interp) {
+ for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
+ tstate;
+ tstate = PyThreadState_Next(tstate))
+ if (tstate->dict &&
+ PyDict_GetItem(tstate->dict, self->key))
+ PyDict_DelItem(tstate->dict, self->key);
+ }
+
+ local_clear(self);
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+_ldict(localobject *self)
+{
+ PyObject *tdict, *ldict;
+
+ tdict = PyThreadState_GetDict();
+ if (tdict == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "Couldn't get thread-state dictionary");
+ return NULL;
+ }
+
+ ldict = PyDict_GetItem(tdict, self->key);
+ if (ldict == NULL) {
+ ldict = PyDict_New(); /* we own ldict */
+
+ if (ldict == NULL)
+ return NULL;
+ else {
+ int i = PyDict_SetItem(tdict, self->key, ldict);
+ Py_DECREF(ldict); /* now ldict is borrowed */
+ if (i < 0)
+ return NULL;
+ }
+
+ Py_CLEAR(self->dict);
+ Py_INCREF(ldict);
+ self->dict = ldict; /* still borrowed */
+
+ if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
+ self->ob_type->tp_init((PyObject*)self,
+ self->args, self->kw) < 0) {
+ /* we need to get rid of ldict from thread so
+ we create a new one the next time we do an attr
+ acces */
+ PyDict_DelItem(tdict, self->key);
+ return NULL;
+ }
+
+ }
+ else if (self->dict != ldict) {
+ Py_CLEAR(self->dict);
+ Py_INCREF(ldict);
+ self->dict = ldict;
+ }
+
+ return ldict;
+}
+
+static int
+local_setattro(localobject *self, PyObject *name, PyObject *v)
+{
+ PyObject *ldict;
+
+ ldict = _ldict(self);
+ if (ldict == NULL)
+ return -1;
+
+ return PyObject_GenericSetAttr((PyObject *)self, name, v);
+}
+
+static PyObject *
+local_getdict(localobject *self, void *closure)
+{
+ if (self->dict == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "__dict__");
+ return NULL;
+ }
+
+ Py_INCREF(self->dict);
+ return self->dict;
+}
+
+static PyGetSetDef local_getset[] = {
+ {"__dict__", (getter)local_getdict, (setter)NULL,
+ "Local-data dictionary", NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *local_getattro(localobject *, PyObject *);
+
+static PyTypeObject localtype = {
+ PyObject_HEAD_INIT(NULL)
+ /* ob_size */ 0,
+ /* tp_name */ "thread._local",
+ /* tp_basicsize */ sizeof(localobject),
+ /* tp_itemsize */ 0,
+ /* tp_dealloc */ (destructor)local_dealloc,
+ /* tp_print */ 0,
+ /* tp_getattr */ 0,
+ /* tp_setattr */ 0,
+ /* tp_compare */ 0,
+ /* tp_repr */ 0,
+ /* tp_as_number */ 0,
+ /* tp_as_sequence */ 0,
+ /* tp_as_mapping */ 0,
+ /* tp_hash */ 0,
+ /* tp_call */ 0,
+ /* tp_str */ 0,
+ /* tp_getattro */ (getattrofunc)local_getattro,
+ /* tp_setattro */ (setattrofunc)local_setattro,
+ /* tp_as_buffer */ 0,
+ /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /* tp_doc */ "Thread-local data",
+ /* tp_traverse */ (traverseproc)local_traverse,
+ /* tp_clear */ (inquiry)local_clear,
+ /* tp_richcompare */ 0,
+ /* tp_weaklistoffset */ 0,
+ /* tp_iter */ 0,
+ /* tp_iternext */ 0,
+ /* tp_methods */ 0,
+ /* tp_members */ 0,
+ /* tp_getset */ local_getset,
+ /* tp_base */ 0,
+ /* tp_dict */ 0, /* internal use */
+ /* tp_descr_get */ 0,
+ /* tp_descr_set */ 0,
+ /* tp_dictoffset */ offsetof(localobject, dict),
+ /* tp_init */ 0,
+ /* tp_alloc */ 0,
+ /* tp_new */ local_new,
+ /* tp_free */ 0, /* Low-level free-mem routine */
+ /* tp_is_gc */ 0, /* For PyObject_IS_GC */
+};
+
+static PyObject *
+local_getattro(localobject *self, PyObject *name)
+{
+ PyObject *ldict, *value;
+
+ ldict = _ldict(self);
+ if (ldict == NULL)
+ return NULL;
+
+ if (self->ob_type != &localtype)
+ /* use generic lookup for subtypes */
+ return PyObject_GenericGetAttr((PyObject *)self, name);
+
+ /* Optimization: just look in dict ourselves */
+ value = PyDict_GetItem(ldict, name);
+ if (value == NULL)
+ /* Fall back on generic to get __class__ and __dict__ */
+ return PyObject_GenericGetAttr((PyObject *)self, name);
+
+ Py_INCREF(value);
+ return value;
+}
+
+/* Module functions */
+
+struct bootstate {
+ PyInterpreterState *interp;
+ PyObject *func;
+ PyObject *args;
+ PyObject *keyw;
+};
+
+static void
+t_bootstrap(void *boot_raw)
+{
+ struct bootstate *boot = (struct bootstate *) boot_raw;
+ PyThreadState *tstate;
+ PyObject *res;
+
+ tstate = PyThreadState_New(boot->interp);
+
+ PyEval_AcquireThread(tstate);
+ res = PyEval_CallObjectWithKeywords(
+ boot->func, boot->args, boot->keyw);
+ if (res == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_SystemExit))
+ PyErr_Clear();
+ else {
+ PyObject *file;
+ PySys_WriteStderr(
+ "Unhandled exception in thread started by ");
+ file = PySys_GetObject("stderr");
+ if (file)
+ PyFile_WriteObject(boot->func, file, 0);
+ else
+ PyObject_Print(boot->func, stderr, 0);
+ PySys_WriteStderr("\n");
+ PyErr_PrintEx(0);
+ }
+ }
+ else
+ Py_DECREF(res);
+ Py_DECREF(boot->func);
+ Py_DECREF(boot->args);
+ Py_XDECREF(boot->keyw);
+ PyMem_DEL(boot_raw);
+ PyThreadState_Clear(tstate);
+ PyThreadState_DeleteCurrent();
+ PyThread_exit_thread();
+}
+
+static PyObject *
+thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
+{
+ PyObject *func, *args, *keyw = NULL;
+ struct bootstate *boot;
+ long ident;
+
+ if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
+ &func, &args, &keyw))
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first arg must be callable");
+ return NULL;
+ }
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "2nd arg must be a tuple");
+ return NULL;
+ }
+ if (keyw != NULL && !PyDict_Check(keyw)) {
+ PyErr_SetString(PyExc_TypeError,
+ "optional 3rd arg must be a dictionary");
+ return NULL;
+ }
+ boot = PyMem_NEW(struct bootstate, 1);
+ if (boot == NULL)
+ return PyErr_NoMemory();
+ boot->interp = PyThreadState_GET()->interp;
+ boot->func = func;
+ boot->args = args;
+ boot->keyw = keyw;
+ Py_INCREF(func);
+ Py_INCREF(args);
+ Py_XINCREF(keyw);
+ PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
+ ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
+ if (ident == -1) {
+ PyErr_SetString(ThreadError, "can't start new thread");
+ Py_DECREF(func);
+ Py_DECREF(args);
+ Py_XDECREF(keyw);
+ PyMem_DEL(boot);
+ return NULL;
+ }
+ return PyInt_FromLong(ident);
+}
+
+PyDoc_STRVAR(start_new_doc,
+"start_new_thread(function, args[, kwargs])\n\
+(start_new() is an obsolete synonym)\n\
+\n\
+Start a new thread and return its identifier. The thread will call the\n\
+function with positional arguments from the tuple args and keyword arguments\n\
+taken from the optional dictionary kwargs. The thread exits when the\n\
+function returns; the return value is ignored. The thread will also exit\n\
+when the function raises an unhandled exception; a stack trace will be\n\
+printed unless the exception is SystemExit.\n");
+
+static PyObject *
+thread_PyThread_exit_thread(PyObject *self)
+{
+ PyErr_SetNone(PyExc_SystemExit);
+ return NULL;
+}
+
+PyDoc_STRVAR(exit_doc,
+"exit()\n\
+(PyThread_exit_thread() is an obsolete synonym)\n\
+\n\
+This is synonymous to ``raise SystemExit''. It will cause the current\n\
+thread to exit silently unless the exception is caught.");
+
+static PyObject *
+thread_PyThread_interrupt_main(PyObject * self)
+{
+ PyErr_SetInterrupt();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(interrupt_doc,
+"interrupt_main()\n\
+\n\
+Raise a KeyboardInterrupt in the main thread.\n\
+A subthread can use this function to interrupt the main thread."
+);
+
+#ifndef NO_EXIT_PROG
+static PyObject *
+thread_PyThread_exit_prog(PyObject *self, PyObject *args)
+{
+ int sts;
+ if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
+ return NULL;
+ Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
+ for (;;) { } /* Should not be reached */
+}
+#endif
+
+static lockobject *newlockobject(void);
+
+static PyObject *
+thread_PyThread_allocate_lock(PyObject *self)
+{
+ return (PyObject *) newlockobject();
+}
+
+PyDoc_STRVAR(allocate_doc,
+"allocate_lock() -> lock object\n\
+(allocate() is an obsolete synonym)\n\
+\n\
+Create a new lock object. See LockType.__doc__ for information about locks.");
+
+static PyObject *
+thread_get_ident(PyObject *self)
+{
+ long ident;
+ ident = PyThread_get_thread_ident();
+ if (ident == -1) {
+ PyErr_SetString(ThreadError, "no current thread ident");
+ return NULL;
+ }
+ return PyInt_FromLong(ident);
+}
+
+PyDoc_STRVAR(get_ident_doc,
+"get_ident() -> integer\n\
+\n\
+Return a non-zero integer that uniquely identifies the current thread\n\
+amongst other threads that exist simultaneously.\n\
+This may be used to identify per-thread resources.\n\
+Even though on some platforms threads identities may appear to be\n\
+allocated consecutive numbers starting at 1, this behavior should not\n\
+be relied upon, and the number should be seen purely as a magic cookie.\n\
+A thread's identity may be reused for another thread after it exits.");
+
+static PyObject *
+thread_stack_size(PyObject *self, PyObject *args)
+{
+ size_t old_size;
+ Py_ssize_t new_size = 0;
+ int rc;
+
+ if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
+ return NULL;
+
+ if (new_size < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be 0 or a positive value");
+ return NULL;
+ }
+
+ old_size = PyThread_get_stacksize();
+
+ rc = PyThread_set_stacksize((size_t) new_size);
+ if (rc == -1) {
+ PyErr_Format(PyExc_ValueError,
+ "size not valid: %zd bytes",
+ new_size);
+ return NULL;
+ }
+ if (rc == -2) {
+ PyErr_SetString(ThreadError,
+ "setting stack size not supported");
+ return NULL;
+ }
+
+ return PyInt_FromSsize_t((Py_ssize_t) old_size);
+}
+
+PyDoc_STRVAR(stack_size_doc,
+"stack_size([size]) -> size\n\
+\n\
+Return the thread stack size used when creating new threads. The\n\
+optional size argument specifies the stack size (in bytes) to be used\n\
+for subsequently created threads, and must be 0 (use platform or\n\
+configured default) or a positive integer value of at least 32,768 (32k).\n\
+If changing the thread stack size is unsupported, a ThreadError\n\
+exception is raised. If the specified size is invalid, a ValueError\n\
+exception is raised, and the stack size is unmodified. 32k bytes\n\
+ currently the minimum supported stack size value to guarantee\n\
+sufficient stack space for the interpreter itself.\n\
+\n\
+Note that some platforms may have particular restrictions on values for\n\
+the stack size, such as requiring a minimum stack size larger than 32kB or\n\
+requiring allocation in multiples of the system memory page size\n\
+- platform documentation should be referred to for more information\n\
+(4kB pages are common; using multiples of 4096 for the stack size is\n\
+the suggested approach in the absence of more specific information).");
+
+static PyMethodDef thread_methods[] = {
+ {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
+ METH_VARARGS,
+ start_new_doc},
+ {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
+ METH_VARARGS,
+ start_new_doc},
+ {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
+ METH_NOARGS, allocate_doc},
+ {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
+ METH_NOARGS, allocate_doc},
+ {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
+ METH_NOARGS, exit_doc},
+ {"exit", (PyCFunction)thread_PyThread_exit_thread,
+ METH_NOARGS, exit_doc},
+ {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
+ METH_NOARGS, interrupt_doc},
+ {"get_ident", (PyCFunction)thread_get_ident,
+ METH_NOARGS, get_ident_doc},
+ {"stack_size", (PyCFunction)thread_stack_size,
+ METH_VARARGS,
+ stack_size_doc},
+#ifndef NO_EXIT_PROG
+ {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
+ METH_VARARGS},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Initialization function */
+
+PyDoc_STRVAR(thread_doc,
+"This module provides primitive operations to write multi-threaded programs.\n\
+The 'threading' module provides a more convenient interface.");
+
+PyDoc_STRVAR(lock_doc,
+"A lock object is a synchronization primitive. To create a lock,\n\
+call the PyThread_allocate_lock() function. Methods are:\n\
+\n\
+acquire() -- lock the lock, possibly blocking until it can be obtained\n\
+release() -- unlock of the lock\n\
+locked() -- test whether the lock is currently locked\n\
+\n\
+A lock is not owned by the thread that locked it; another thread may\n\
+unlock it. A thread attempting to lock a lock that it has already locked\n\
+will block until another thread unlocks it. Deadlocks may ensue.");
+
+PyMODINIT_FUNC
+initthread(void)
+{
+ PyObject *m, *d;
+
+ /* Initialize types: */
+ if (PyType_Ready(&localtype) < 0)
+ return;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule3("thread", thread_methods, thread_doc);
+ if (m == NULL)
+ return;
+
+ /* Add a symbolic constant */
+ d = PyModule_GetDict(m);
+ ThreadError = PyErr_NewException("thread.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", ThreadError);
+ Locktype.tp_doc = lock_doc;
+ Py_INCREF(&Locktype);
+ PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
+
+ Py_INCREF(&localtype);
+ if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
+ return;
+
+ /* Initialize the C thread library */
+ PyThread_init_thread();
+}
diff --git a/sys/src/cmd/python/Modules/timemodule.c b/sys/src/cmd/python/Modules/timemodule.c
new file mode 100644
index 000000000..7a1e44605
--- /dev/null
+++ b/sys/src/cmd/python/Modules/timemodule.c
@@ -0,0 +1,1030 @@
+
+/* Time module */
+
+#include "Python.h"
+#include "structseq.h"
+#include "timefuncs.h"
+
+#ifdef __APPLE__
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
+ /*
+ * floattime falls back to ftime when getttimeofday fails because the latter
+ * might fail on some platforms. This fallback is unwanted on MacOSX because
+ * that makes it impossible to use a binary build on OSX 10.4 on earlier
+ * releases of the OS. Therefore claim we don't support ftime.
+ */
+# undef HAVE_FTIME
+#endif
+#endif
+
+#include <ctype.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef QUICKWIN
+#include <io.h>
+#endif
+
+#ifdef HAVE_FTIME
+#include <sys/timeb.h>
+#if !defined(MS_WINDOWS) && !defined(PYOS_OS2)
+extern int ftime(struct timeb *);
+#endif /* MS_WINDOWS */
+#endif /* HAVE_FTIME */
+
+#if defined(__WATCOMC__) && !defined(__QNX__)
+#include <i86.h>
+#else
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "pythread.h"
+
+/* helper to allow us to interrupt sleep() on Windows*/
+static HANDLE hInterruptEvent = NULL;
+static BOOL WINAPI PyCtrlHandler(DWORD dwCtrlType)
+{
+ SetEvent(hInterruptEvent);
+ /* allow other default handlers to be called.
+ Default Python handler will setup the
+ KeyboardInterrupt exception.
+ */
+ return FALSE;
+}
+static long main_thread;
+
+
+#if defined(__BORLANDC__)
+/* These overrides not needed for Win32 */
+#define timezone _timezone
+#define tzname _tzname
+#define daylight _daylight
+#endif /* __BORLANDC__ */
+#endif /* MS_WINDOWS */
+#endif /* !__WATCOMC__ || __QNX__ */
+
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
+/* Win32 has better clock replacement; we have our own version below. */
+#undef HAVE_CLOCK
+#endif /* MS_WINDOWS && !defined(__BORLANDC__) */
+
+#if defined(PYOS_OS2)
+#define INCL_DOS
+#define INCL_ERRORS
+#include <os2.h>
+#endif
+
+#if defined(PYCC_VACPP)
+#include <sys/time.h>
+#endif
+
+#ifdef __BEOS__
+#include <time.h>
+/* For bigtime_t, snooze(). - [cjh] */
+#include <support/SupportDefs.h>
+#include <kernel/OS.h>
+#endif
+
+#ifdef RISCOS
+extern int riscos_sleep(double);
+#endif
+
+/* Forward declarations */
+static int floatsleep(double);
+static double floattime(void);
+
+/* For Y2K check */
+static PyObject *moddict;
+
+/* Exposed in timefuncs.h. */
+time_t
+_PyTime_DoubleToTimet(double x)
+{
+ time_t result;
+ double diff;
+
+ result = (time_t)x;
+ /* How much info did we lose? time_t may be an integral or
+ * floating type, and we don't know which. If it's integral,
+ * we don't know whether C truncates, rounds, returns the floor,
+ * etc. If we lost a second or more, the C rounding is
+ * unreasonable, or the input just doesn't fit in a time_t;
+ * call it an error regardless. Note that the original cast to
+ * time_t can cause a C error too, but nothing we can do to
+ * worm around that.
+ */
+ diff = x - (double)result;
+ if (diff <= -1.0 || diff >= 1.0) {
+ PyErr_SetString(PyExc_ValueError,
+ "timestamp out of range for platform time_t");
+ result = (time_t)-1;
+ }
+ return result;
+}
+
+static PyObject *
+time_time(PyObject *self, PyObject *unused)
+{
+ double secs;
+ secs = floattime();
+ if (secs == 0.0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return PyFloat_FromDouble(secs);
+}
+
+PyDoc_STRVAR(time_doc,
+"time() -> floating point number\n\
+\n\
+Return the current time in seconds since the Epoch.\n\
+Fractions of a second may be present if the system clock provides them.");
+
+#ifdef HAVE_CLOCK
+
+#ifndef CLOCKS_PER_SEC
+#ifdef CLK_TCK
+#define CLOCKS_PER_SEC CLK_TCK
+#else
+#define CLOCKS_PER_SEC 1000000
+#endif
+#endif
+
+static PyObject *
+time_clock(PyObject *self, PyObject *unused)
+{
+ return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
+}
+#endif /* HAVE_CLOCK */
+
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
+/* Due to Mark Hammond and Tim Peters */
+static PyObject *
+time_clock(PyObject *self, PyObject *unused)
+{
+ static LARGE_INTEGER ctrStart;
+ static double divisor = 0.0;
+ LARGE_INTEGER now;
+ double diff;
+
+ if (divisor == 0.0) {
+ LARGE_INTEGER freq;
+ QueryPerformanceCounter(&ctrStart);
+ if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {
+ /* Unlikely to happen - this works on all intel
+ machines at least! Revert to clock() */
+ return PyFloat_FromDouble(((double)clock()) /
+ CLOCKS_PER_SEC);
+ }
+ divisor = (double)freq.QuadPart;
+ }
+ QueryPerformanceCounter(&now);
+ diff = (double)(now.QuadPart - ctrStart.QuadPart);
+ return PyFloat_FromDouble(diff / divisor);
+}
+
+#define HAVE_CLOCK /* So it gets included in the methods */
+#endif /* MS_WINDOWS && !defined(__BORLANDC__) */
+
+#ifdef HAVE_CLOCK
+PyDoc_STRVAR(clock_doc,
+"clock() -> floating point number\n\
+\n\
+Return the CPU time or real time since the start of the process or since\n\
+the first call to clock(). This has as much precision as the system\n\
+records.");
+#endif
+
+static PyObject *
+time_sleep(PyObject *self, PyObject *args)
+{
+ double secs;
+ if (!PyArg_ParseTuple(args, "d:sleep", &secs))
+ return NULL;
+ if (floatsleep(secs) != 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(sleep_doc,
+"sleep(seconds)\n\
+\n\
+Delay execution for a given number of seconds. The argument may be\n\
+a floating point number for subsecond precision.");
+
+static PyStructSequence_Field struct_time_type_fields[] = {
+ {"tm_year", NULL},
+ {"tm_mon", NULL},
+ {"tm_mday", NULL},
+ {"tm_hour", NULL},
+ {"tm_min", NULL},
+ {"tm_sec", NULL},
+ {"tm_wday", NULL},
+ {"tm_yday", NULL},
+ {"tm_isdst", NULL},
+ {0}
+};
+
+static PyStructSequence_Desc struct_time_type_desc = {
+ "time.struct_time",
+ NULL,
+ struct_time_type_fields,
+ 9,
+};
+
+static int initialized;
+static PyTypeObject StructTimeType;
+
+static PyObject *
+tmtotuple(struct tm *p)
+{
+ PyObject *v = PyStructSequence_New(&StructTimeType);
+ if (v == NULL)
+ return NULL;
+
+#define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
+
+ SET(0, p->tm_year + 1900);
+ SET(1, p->tm_mon + 1); /* Want January == 1 */
+ SET(2, p->tm_mday);
+ SET(3, p->tm_hour);
+ SET(4, p->tm_min);
+ SET(5, p->tm_sec);
+ SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
+ SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */
+ SET(8, p->tm_isdst);
+#undef SET
+ if (PyErr_Occurred()) {
+ Py_XDECREF(v);
+ return NULL;
+ }
+
+ return v;
+}
+
+static PyObject *
+time_convert(double when, struct tm * (*function)(const time_t *))
+{
+ struct tm *p;
+ time_t whent = _PyTime_DoubleToTimet(when);
+
+ if (whent == (time_t)-1 && PyErr_Occurred())
+ return NULL;
+ errno = 0;
+ p = function(&whent);
+ if (p == NULL) {
+#ifdef EINVAL
+ if (errno == 0)
+ errno = EINVAL;
+#endif
+ return PyErr_SetFromErrno(PyExc_ValueError);
+ }
+ return tmtotuple(p);
+}
+
+/* Parse arg tuple that can contain an optional float-or-None value;
+ format needs to be "|O:name".
+ Returns non-zero on success (parallels PyArg_ParseTuple).
+*/
+static int
+parse_time_double_args(PyObject *args, char *format, double *pwhen)
+{
+ PyObject *ot = NULL;
+
+ if (!PyArg_ParseTuple(args, format, &ot))
+ return 0;
+ if (ot == NULL || ot == Py_None)
+ *pwhen = floattime();
+ else {
+ double when = PyFloat_AsDouble(ot);
+ if (PyErr_Occurred())
+ return 0;
+ *pwhen = when;
+ }
+ return 1;
+}
+
+static PyObject *
+time_gmtime(PyObject *self, PyObject *args)
+{
+ double when;
+ if (!parse_time_double_args(args, "|O:gmtime", &when))
+ return NULL;
+ return time_convert(when, gmtime);
+}
+
+PyDoc_STRVAR(gmtime_doc,
+"gmtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min,\n\
+ tm_sec, tm_wday, tm_yday, tm_isdst)\n\
+\n\
+Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
+GMT). When 'seconds' is not passed in, convert the current time instead.");
+
+static PyObject *
+time_localtime(PyObject *self, PyObject *args)
+{
+ double when;
+ if (!parse_time_double_args(args, "|O:localtime", &when))
+ return NULL;
+ return time_convert(when, localtime);
+}
+
+PyDoc_STRVAR(localtime_doc,
+"localtime([seconds]) -> (tm_year,tm_mon,tm_day,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)\n\
+\n\
+Convert seconds since the Epoch to a time tuple expressing local time.\n\
+When 'seconds' is not passed in, convert the current time instead.");
+
+static int
+gettmarg(PyObject *args, struct tm *p)
+{
+ int y;
+ memset((void *) p, '\0', sizeof(struct tm));
+
+ if (!PyArg_Parse(args, "(iiiiiiiii)",
+ &y,
+ &p->tm_mon,
+ &p->tm_mday,
+ &p->tm_hour,
+ &p->tm_min,
+ &p->tm_sec,
+ &p->tm_wday,
+ &p->tm_yday,
+ &p->tm_isdst))
+ return 0;
+ if (y < 1900) {
+ PyObject *accept = PyDict_GetItemString(moddict,
+ "accept2dyear");
+ if (accept == NULL || !PyInt_Check(accept) ||
+ PyInt_AsLong(accept) == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "year >= 1900 required");
+ return 0;
+ }
+ if (69 <= y && y <= 99)
+ y += 1900;
+ else if (0 <= y && y <= 68)
+ y += 2000;
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "year out of range");
+ return 0;
+ }
+ }
+ p->tm_year = y - 1900;
+ p->tm_mon--;
+ p->tm_wday = (p->tm_wday + 1) % 7;
+ p->tm_yday--;
+ return 1;
+}
+
+#ifdef HAVE_STRFTIME
+static PyObject *
+time_strftime(PyObject *self, PyObject *args)
+{
+ PyObject *tup = NULL;
+ struct tm buf;
+ const char *fmt;
+ size_t fmtlen, buflen;
+ char *outbuf = 0;
+ size_t i;
+
+ memset((void *) &buf, '\0', sizeof(buf));
+
+ if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup))
+ return NULL;
+
+ if (tup == NULL) {
+ time_t tt = time(NULL);
+ buf = *localtime(&tt);
+ } else if (!gettmarg(tup, &buf))
+ return NULL;
+
+ /* Checks added to make sure strftime() does not crash Python by
+ indexing blindly into some array for a textual representation
+ by some bad index (fixes bug #897625).
+
+ Also support values of zero from Python code for arguments in which
+ that is out of range by forcing that value to the lowest value that
+ is valid (fixed bug #1520914).
+
+ Valid ranges based on what is allowed in struct tm:
+
+ - tm_year: [0, max(int)] (1)
+ - tm_mon: [0, 11] (2)
+ - tm_mday: [1, 31]
+ - tm_hour: [0, 23]
+ - tm_min: [0, 59]
+ - tm_sec: [0, 60]
+ - tm_wday: [0, 6] (1)
+ - tm_yday: [0, 365] (2)
+ - tm_isdst: [-max(int), max(int)]
+
+ (1) gettmarg() handles bounds-checking.
+ (2) Python's acceptable range is one greater than the range in C,
+ thus need to check against automatic decrement by gettmarg().
+ */
+ if (buf.tm_mon == -1)
+ buf.tm_mon = 0;
+ else if (buf.tm_mon < 0 || buf.tm_mon > 11) {
+ PyErr_SetString(PyExc_ValueError, "month out of range");
+ return NULL;
+ }
+ if (buf.tm_mday == 0)
+ buf.tm_mday = 1;
+ else if (buf.tm_mday < 0 || buf.tm_mday > 31) {
+ PyErr_SetString(PyExc_ValueError, "day of month out of range");
+ return NULL;
+ }
+ if (buf.tm_hour < 0 || buf.tm_hour > 23) {
+ PyErr_SetString(PyExc_ValueError, "hour out of range");
+ return NULL;
+ }
+ if (buf.tm_min < 0 || buf.tm_min > 59) {
+ PyErr_SetString(PyExc_ValueError, "minute out of range");
+ return NULL;
+ }
+ if (buf.tm_sec < 0 || buf.tm_sec > 61) {
+ PyErr_SetString(PyExc_ValueError, "seconds out of range");
+ return NULL;
+ }
+ /* tm_wday does not need checking of its upper-bound since taking
+ ``% 7`` in gettmarg() automatically restricts the range. */
+ if (buf.tm_wday < 0) {
+ PyErr_SetString(PyExc_ValueError, "day of week out of range");
+ return NULL;
+ }
+ if (buf.tm_yday == -1)
+ buf.tm_yday = 0;
+ else if (buf.tm_yday < 0 || buf.tm_yday > 365) {
+ PyErr_SetString(PyExc_ValueError, "day of year out of range");
+ return NULL;
+ }
+ if (buf.tm_isdst < -1 || buf.tm_isdst > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "daylight savings flag out of range");
+ return NULL;
+ }
+
+ fmtlen = strlen(fmt);
+
+ /* I hate these functions that presume you know how big the output
+ * will be ahead of time...
+ */
+ for (i = 1024; ; i += i) {
+ outbuf = (char *)malloc(i);
+ if (outbuf == NULL) {
+ return PyErr_NoMemory();
+ }
+ buflen = strftime(outbuf, i, fmt, &buf);
+ if (buflen > 0 || i >= 256 * fmtlen) {
+ /* If the buffer is 256 times as long as the format,
+ it's probably not failing for lack of room!
+ More likely, the format yields an empty result,
+ e.g. an empty format, or %Z when the timezone
+ is unknown. */
+ PyObject *ret;
+ ret = PyString_FromStringAndSize(outbuf, buflen);
+ free(outbuf);
+ return ret;
+ }
+ free(outbuf);
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+ /* VisualStudio .NET 2005 does this properly */
+ if (buflen == 0 && errno == EINVAL) {
+ PyErr_SetString(PyExc_ValueError, "Invalid format string");
+ return 0;
+ }
+#endif
+
+ }
+}
+
+PyDoc_STRVAR(strftime_doc,
+"strftime(format[, tuple]) -> string\n\
+\n\
+Convert a time tuple to a string according to a format specification.\n\
+See the library reference manual for formatting codes. When the time tuple\n\
+is not present, current time as returned by localtime() is used.");
+#endif /* HAVE_STRFTIME */
+
+static PyObject *
+time_strptime(PyObject *self, PyObject *args)
+{
+ PyObject *strptime_module = PyImport_ImportModule("_strptime");
+ PyObject *strptime_result;
+
+ if (!strptime_module)
+ return NULL;
+ strptime_result = PyObject_CallMethod(strptime_module, "strptime", "O", args);
+ Py_DECREF(strptime_module);
+ return strptime_result;
+}
+
+PyDoc_STRVAR(strptime_doc,
+"strptime(string, format) -> struct_time\n\
+\n\
+Parse a string to a time tuple according to a format specification.\n\
+See the library reference manual for formatting codes (same as strftime()).");
+
+
+static PyObject *
+time_asctime(PyObject *self, PyObject *args)
+{
+ PyObject *tup = NULL;
+ struct tm buf;
+ char *p;
+ if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
+ return NULL;
+ if (tup == NULL) {
+ time_t tt = time(NULL);
+ buf = *localtime(&tt);
+ } else if (!gettmarg(tup, &buf))
+ return NULL;
+ p = asctime(&buf);
+ if (p[24] == '\n')
+ p[24] = '\0';
+ return PyString_FromString(p);
+}
+
+PyDoc_STRVAR(asctime_doc,
+"asctime([tuple]) -> string\n\
+\n\
+Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
+When the time tuple is not present, current time as returned by localtime()\n\
+is used.");
+
+static PyObject *
+time_ctime(PyObject *self, PyObject *args)
+{
+ PyObject *ot = NULL;
+ time_t tt;
+ char *p;
+
+ if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot))
+ return NULL;
+ if (ot == NULL || ot == Py_None)
+ tt = time(NULL);
+ else {
+ double dt = PyFloat_AsDouble(ot);
+ if (PyErr_Occurred())
+ return NULL;
+ tt = _PyTime_DoubleToTimet(dt);
+ if (tt == (time_t)-1 && PyErr_Occurred())
+ return NULL;
+ }
+ p = ctime(&tt);
+ if (p == NULL) {
+ PyErr_SetString(PyExc_ValueError, "unconvertible time");
+ return NULL;
+ }
+ if (p[24] == '\n')
+ p[24] = '\0';
+ return PyString_FromString(p);
+}
+
+PyDoc_STRVAR(ctime_doc,
+"ctime(seconds) -> string\n\
+\n\
+Convert a time in seconds since the Epoch to a string in local time.\n\
+This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
+not present, current time as returned by localtime() is used.");
+
+#ifdef HAVE_MKTIME
+static PyObject *
+time_mktime(PyObject *self, PyObject *tup)
+{
+ struct tm buf;
+ time_t tt;
+ tt = time(&tt);
+ buf = *localtime(&tt);
+ if (!gettmarg(tup, &buf))
+ return NULL;
+ tt = mktime(&buf);
+ if (tt == (time_t)(-1)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "mktime argument out of range");
+ return NULL;
+ }
+ return PyFloat_FromDouble((double)tt);
+}
+
+PyDoc_STRVAR(mktime_doc,
+"mktime(tuple) -> floating point number\n\
+\n\
+Convert a time tuple in local time to seconds since the Epoch.");
+#endif /* HAVE_MKTIME */
+
+#ifdef HAVE_WORKING_TZSET
+void inittimezone(PyObject *module);
+
+static PyObject *
+time_tzset(PyObject *self, PyObject *unused)
+{
+ PyObject* m;
+
+ m = PyImport_ImportModule("time");
+ if (m == NULL) {
+ return NULL;
+ }
+
+ tzset();
+
+ /* Reset timezone, altzone, daylight and tzname */
+ inittimezone(m);
+ Py_DECREF(m);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(tzset_doc,
+"tzset(zone)\n\
+\n\
+Initialize, or reinitialize, the local timezone to the value stored in\n\
+os.environ['TZ']. The TZ environment variable should be specified in\n\
+standard Unix timezone format as documented in the tzset man page\n\
+(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
+fall back to UTC. If the TZ environment variable is not set, the local\n\
+timezone is set to the systems best guess of wallclock time.\n\
+Changing the TZ environment variable without calling tzset *may* change\n\
+the local timezone used by methods such as localtime, but this behaviour\n\
+should not be relied on.");
+#endif /* HAVE_WORKING_TZSET */
+
+void inittimezone(PyObject *m) {
+ /* This code moved from inittime wholesale to allow calling it from
+ time_tzset. In the future, some parts of it can be moved back
+ (for platforms that don't HAVE_WORKING_TZSET, when we know what they
+ are), and the extranious calls to tzset(3) should be removed.
+ I havn't done this yet, as I don't want to change this code as
+ little as possible when introducing the time.tzset and time.tzsetwall
+ methods. This should simply be a method of doing the following once,
+ at the top of this function and removing the call to tzset() from
+ time_tzset():
+
+ #ifdef HAVE_TZSET
+ tzset()
+ #endif
+
+ And I'm lazy and hate C so nyer.
+ */
+#if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
+ tzset();
+#ifdef PYOS_OS2
+ PyModule_AddIntConstant(m, "timezone", _timezone);
+#else /* !PYOS_OS2 */
+#ifdef PLAN9APE
+ //PyModule_AddIntConstant(m, "timezone", timezone);
+ PyModule_AddIntConstant(m, "timezone", 0);
+#endif
+#endif /* PYOS_OS2 */
+#ifdef HAVE_ALTZONE
+ PyModule_AddIntConstant(m, "altzone", altzone);
+#else
+#ifdef PYOS_OS2
+ PyModule_AddIntConstant(m, "altzone", _timezone-3600);
+#else /* !PYOS_OS2 */
+#ifdef PLAN9APE
+ //PyModule_AddIntConstant(m, "altzone", timezone-3600);
+ PyModule_AddIntConstant(m, "altzone", 3600);
+#endif
+#endif /* PYOS_OS2 */
+#endif
+#ifdef PLAN9APE
+ //PyModule_AddIntConstant(m, "daylight", daylight);
+ PyModule_AddIntConstant(m, "daylight", 0);
+ PyModule_AddObject(m, "tzname",
+ Py_BuildValue("(zz)", tzname[0], tzname[1]));
+#endif
+#else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+ {
+#define YEAR ((time_t)((365 * 24 + 6) * 3600))
+ time_t t;
+ struct tm *p;
+ long janzone, julyzone;
+ char janname[10], julyname[10];
+ t = (time((time_t *)0) / YEAR) * YEAR;
+ p = localtime(&t);
+ janzone = -p->tm_gmtoff;
+ strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9);
+ janname[9] = '\0';
+ t += YEAR/2;
+ p = localtime(&t);
+ julyzone = -p->tm_gmtoff;
+ strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9);
+ julyname[9] = '\0';
+
+ if( janzone < julyzone ) {
+ /* DST is reversed in the southern hemisphere */
+ PyModule_AddIntConstant(m, "timezone", julyzone);
+ PyModule_AddIntConstant(m, "altzone", janzone);
+ PyModule_AddIntConstant(m, "daylight",
+ janzone != julyzone);
+ PyModule_AddObject(m, "tzname",
+ Py_BuildValue("(zz)",
+ julyname, janname));
+ } else {
+ PyModule_AddIntConstant(m, "timezone", janzone);
+ PyModule_AddIntConstant(m, "altzone", julyzone);
+ PyModule_AddIntConstant(m, "daylight",
+ janzone != julyzone);
+ PyModule_AddObject(m, "tzname",
+ Py_BuildValue("(zz)",
+ janname, julyname));
+ }
+ }
+#else
+#endif /* HAVE_STRUCT_TM_TM_ZONE */
+#ifdef __CYGWIN__
+ tzset();
+ PyModule_AddIntConstant(m, "timezone", _timezone);
+ PyModule_AddIntConstant(m, "altzone", _timezone-3600);
+ PyModule_AddIntConstant(m, "daylight", _daylight);
+ PyModule_AddObject(m, "tzname",
+ Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
+#endif /* __CYGWIN__ */
+#endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
+}
+
+
+static PyMethodDef time_methods[] = {
+ {"time", time_time, METH_NOARGS, time_doc},
+#ifdef HAVE_CLOCK
+ {"clock", time_clock, METH_NOARGS, clock_doc},
+#endif
+ {"sleep", time_sleep, METH_VARARGS, sleep_doc},
+ {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc},
+ {"localtime", time_localtime, METH_VARARGS, localtime_doc},
+ {"asctime", time_asctime, METH_VARARGS, asctime_doc},
+ {"ctime", time_ctime, METH_VARARGS, ctime_doc},
+#ifdef HAVE_MKTIME
+ {"mktime", time_mktime, METH_O, mktime_doc},
+#endif
+#ifdef HAVE_STRFTIME
+ {"strftime", time_strftime, METH_VARARGS, strftime_doc},
+#endif
+ {"strptime", time_strptime, METH_VARARGS, strptime_doc},
+#ifdef HAVE_WORKING_TZSET
+ {"tzset", time_tzset, METH_NOARGS, tzset_doc},
+#endif
+ {NULL, NULL} /* sentinel */
+};
+
+
+PyDoc_STRVAR(module_doc,
+"This module provides various functions to manipulate time values.\n\
+\n\
+There are two standard representations of time. One is the number\n\
+of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\
+or a floating point number (to represent fractions of seconds).\n\
+The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
+The actual value can be retrieved by calling gmtime(0).\n\
+\n\
+The other representation is a tuple of 9 integers giving local time.\n\
+The tuple items are:\n\
+ year (four digits, e.g. 1998)\n\
+ month (1-12)\n\
+ day (1-31)\n\
+ hours (0-23)\n\
+ minutes (0-59)\n\
+ seconds (0-59)\n\
+ weekday (0-6, Monday is 0)\n\
+ Julian day (day in the year, 1-366)\n\
+ DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
+If the DST flag is 0, the time is given in the regular time zone;\n\
+if it is 1, the time is given in the DST time zone;\n\
+if it is -1, mktime() should guess based on the date and time.\n\
+\n\
+Variables:\n\
+\n\
+timezone -- difference in seconds between UTC and local standard time\n\
+altzone -- difference in seconds between UTC and local DST time\n\
+daylight -- whether local time should reflect DST\n\
+tzname -- tuple of (standard time zone name, DST time zone name)\n\
+\n\
+Functions:\n\
+\n\
+time() -- return current time in seconds since the Epoch as a float\n\
+clock() -- return CPU time since process start as a float\n\
+sleep() -- delay for a number of seconds given as a float\n\
+gmtime() -- convert seconds since Epoch to UTC tuple\n\
+localtime() -- convert seconds since Epoch to local time tuple\n\
+asctime() -- convert time tuple to string\n\
+ctime() -- convert time in seconds to string\n\
+mktime() -- convert local time tuple to seconds since Epoch\n\
+strftime() -- convert time tuple to string according to format specification\n\
+strptime() -- parse string to time tuple according to format specification\n\
+tzset() -- change the local timezone");
+
+
+PyMODINIT_FUNC
+inittime(void)
+{
+ PyObject *m;
+ char *p;
+ m = Py_InitModule3("time", time_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
+ p = Py_GETENV("PYTHONY2K");
+ PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p));
+ /* Squirrel away the module's dictionary for the y2k check */
+ moddict = PyModule_GetDict(m);
+ Py_INCREF(moddict);
+
+ /* Set, or reset, module variables like time.timezone */
+ inittimezone(m);
+
+#ifdef MS_WINDOWS
+ /* Helper to allow interrupts for Windows.
+ If Ctrl+C event delivered while not sleeping
+ it will be ignored.
+ */
+ main_thread = PyThread_get_thread_ident();
+ hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
+#endif /* MS_WINDOWS */
+ if (!initialized) {
+ PyStructSequence_InitType(&StructTimeType,
+ &struct_time_type_desc);
+ }
+ Py_INCREF(&StructTimeType);
+ PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
+ initialized = 1;
+}
+
+
+/* Implement floattime() for various platforms */
+
+static double
+floattime(void)
+{
+ /* There are three ways to get the time:
+ (1) gettimeofday() -- resolution in microseconds
+ (2) ftime() -- resolution in milliseconds
+ (3) time() -- resolution in seconds
+ In all cases the return value is a float in seconds.
+ Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
+ fail, so we fall back on ftime() or time().
+ Note: clock resolution does not imply clock accuracy! */
+#ifdef HAVE_GETTIMEOFDAY
+ {
+ struct timeval t;
+#ifdef GETTIMEOFDAY_NO_TZ
+ if (gettimeofday(&t) == 0)
+ return (double)t.tv_sec + t.tv_usec*0.000001;
+#else /* !GETTIMEOFDAY_NO_TZ */
+ if (gettimeofday(&t, (struct timezone *)NULL) == 0)
+ return (double)t.tv_sec + t.tv_usec*0.000001;
+#endif /* !GETTIMEOFDAY_NO_TZ */
+ }
+
+#endif /* !HAVE_GETTIMEOFDAY */
+ {
+#if defined(HAVE_FTIME)
+ struct timeb t;
+ ftime(&t);
+ return (double)t.time + (double)t.millitm * (double)0.001;
+#else /* !HAVE_FTIME */
+ time_t secs;
+ time(&secs);
+ return (double)secs;
+#endif /* !HAVE_FTIME */
+ }
+}
+
+
+/* Implement floatsleep() for various platforms.
+ When interrupted (or when another error occurs), return -1 and
+ set an exception; else return 0. */
+
+static int
+floatsleep(double secs)
+{
+/* XXX Should test for MS_WINDOWS first! */
+#if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__)
+ struct timeval t;
+ double frac;
+ frac = fmod(secs, 1.0);
+ secs = floor(secs);
+ t.tv_sec = (long)secs;
+ t.tv_usec = (long)(frac*1000000.0);
+ Py_BEGIN_ALLOW_THREADS
+ if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
+#ifdef EINTR
+ if (errno != EINTR) {
+#else
+ if (1) {
+#endif
+ Py_BLOCK_THREADS
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+ }
+ Py_END_ALLOW_THREADS
+#elif defined(__WATCOMC__) && !defined(__QNX__)
+ /* XXX Can't interrupt this sleep */
+ Py_BEGIN_ALLOW_THREADS
+ delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
+ Py_END_ALLOW_THREADS
+#elif defined(MS_WINDOWS)
+ {
+ double millisecs = secs * 1000.0;
+ unsigned long ul_millis;
+
+ if (millisecs > (double)ULONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "sleep length is too large");
+ return -1;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ /* Allow sleep(0) to maintain win32 semantics, and as decreed
+ * by Guido, only the main thread can be interrupted.
+ */
+ ul_millis = (unsigned long)millisecs;
+ if (ul_millis == 0 ||
+ main_thread != PyThread_get_thread_ident())
+ Sleep(ul_millis);
+ else {
+ DWORD rc;
+ ResetEvent(hInterruptEvent);
+ rc = WaitForSingleObject(hInterruptEvent, ul_millis);
+ if (rc == WAIT_OBJECT_0) {
+ /* Yield to make sure real Python signal
+ * handler called.
+ */
+ Sleep(1);
+ Py_BLOCK_THREADS
+ errno = EINTR;
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+ }
+ Py_END_ALLOW_THREADS
+ }
+#elif defined(PYOS_OS2)
+ /* This Sleep *IS* Interruptable by Exceptions */
+ Py_BEGIN_ALLOW_THREADS
+ if (DosSleep(secs * 1000) != NO_ERROR) {
+ Py_BLOCK_THREADS
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+ Py_END_ALLOW_THREADS
+#elif defined(__BEOS__)
+ /* This sleep *CAN BE* interrupted. */
+ {
+ if( secs <= 0.0 ) {
+ return;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ /* BeOS snooze() is in microseconds... */
+ if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) {
+ Py_BLOCK_THREADS
+ PyErr_SetFromErrno( PyExc_IOError );
+ return -1;
+ }
+ Py_END_ALLOW_THREADS
+ }
+#elif defined(RISCOS)
+ if (secs <= 0.0)
+ return 0;
+ Py_BEGIN_ALLOW_THREADS
+ /* This sleep *CAN BE* interrupted. */
+ if ( riscos_sleep(secs) )
+ return -1;
+ Py_END_ALLOW_THREADS
+#elif defined(PLAN9)
+ {
+ double millisecs = secs * 1000.0;
+ if (millisecs > (double)LONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "sleep length is too large");
+ return -1;
+ }
+ /* This sleep *CAN BE* interrupted. */
+ Py_BEGIN_ALLOW_THREADS
+ if(sleep((long)millisecs) < 0){
+ Py_BLOCK_THREADS
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+ Py_END_ALLOW_THREADS
+ }
+#else
+ /* XXX Can't interrupt this sleep */
+ Py_BEGIN_ALLOW_THREADS
+ sleep((int)secs);
+ Py_END_ALLOW_THREADS
+#endif
+
+ return 0;
+}
+
+
diff --git a/sys/src/cmd/python/Modules/timing.h b/sys/src/cmd/python/Modules/timing.h
new file mode 100644
index 000000000..af26f1a6c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/timing.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1993 George V. Neville-Neil
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by George V. Neville-Neil
+ * 4. The name, George Neville-Neil may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _TIMING_H_
+#define _TIMING_H_
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else /* !TIME_WITH_SYS_TIME */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else /* !HAVE_SYS_TIME_H */
+#include <time.h>
+#endif /* !HAVE_SYS_TIME_H */
+#endif /* !TIME_WITH_SYS_TIME */
+
+static struct timeval aftertp, beforetp;
+
+#define BEGINTIMING gettimeofday(&beforetp, NULL)
+
+#define ENDTIMING gettimeofday(&aftertp, NULL); \
+ if(beforetp.tv_usec > aftertp.tv_usec) \
+ { \
+ aftertp.tv_usec += 1000000; \
+ aftertp.tv_sec--; \
+ }
+
+#define TIMINGUS (((aftertp.tv_sec - beforetp.tv_sec) * 1000000) + \
+ (aftertp.tv_usec - beforetp.tv_usec))
+
+#define TIMINGMS (((aftertp.tv_sec - beforetp.tv_sec) * 1000) + \
+ ((aftertp.tv_usec - beforetp.tv_usec) / 1000))
+
+#define TIMINGS ((aftertp.tv_sec - beforetp.tv_sec) + \
+ (aftertp.tv_usec - beforetp.tv_usec) / 1000000)
+
+#endif /* _TIMING_H_ */
diff --git a/sys/src/cmd/python/Modules/timingmodule.c b/sys/src/cmd/python/Modules/timingmodule.c
new file mode 100644
index 000000000..56e057a65
--- /dev/null
+++ b/sys/src/cmd/python/Modules/timingmodule.c
@@ -0,0 +1,58 @@
+/*
+ * Author: George V. Neville-Neil
+ */
+
+#include "Python.h"
+
+/* Our stuff... */
+#include "timing.h"
+
+static PyObject *
+start_timing(PyObject *self)
+{
+ Py_INCREF(Py_None);
+ BEGINTIMING;
+ return Py_None;
+}
+
+static PyObject *
+finish_timing(PyObject *self)
+{
+ ENDTIMING
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+seconds(PyObject *self)
+{
+ return PyInt_FromLong(TIMINGS);
+}
+
+static PyObject *
+milli(PyObject *self)
+{
+ return PyInt_FromLong(TIMINGMS);
+}
+
+static PyObject *
+micro(PyObject *self)
+{
+ return PyInt_FromLong(TIMINGUS);
+}
+
+
+static PyMethodDef timing_methods[] = {
+ {"start", (PyCFunction)start_timing, METH_NOARGS},
+ {"finish", (PyCFunction)finish_timing, METH_NOARGS},
+ {"seconds", (PyCFunction)seconds, METH_NOARGS},
+ {"milli", (PyCFunction)milli, METH_NOARGS},
+ {"micro", (PyCFunction)micro, METH_NOARGS},
+ {NULL, NULL}
+};
+
+
+PyMODINIT_FUNC inittiming(void)
+{
+ (void)Py_InitModule("timing", timing_methods);
+}
diff --git a/sys/src/cmd/python/Modules/tkappinit.c b/sys/src/cmd/python/Modules/tkappinit.c
new file mode 100644
index 000000000..1c676325e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/tkappinit.c
@@ -0,0 +1,149 @@
+/* appinit.c -- Tcl and Tk application initialization.
+
+ The function Tcl_AppInit() below initializes various Tcl packages.
+ It is called for each Tcl interpreter created by _tkinter.create().
+ It needs to be compiled with -DWITH_<package> flags for each package
+ that you are statically linking with. You may have to add sections
+ for packages not yet listed below.
+
+ Note that those packages for which Tcl_StaticPackage() is called with
+ a NULL first argument are known as "static loadable" packages to
+ Tcl but not actually initialized. To use these, you have to load
+ it explicitly, e.g. tkapp.eval("load {} Blt").
+ */
+
+#include <string.h>
+#include <tcl.h>
+#include <tk.h>
+
+int
+Tcl_AppInit(Tcl_Interp *interp)
+{
+ Tk_Window main_window;
+ const char * _tkinter_skip_tk_init;
+
+#ifdef TK_AQUA
+#ifndef MAX_PATH_LEN
+#define MAX_PATH_LEN 1024
+#endif
+ char tclLibPath[MAX_PATH_LEN], tkLibPath[MAX_PATH_LEN];
+ Tcl_Obj* pathPtr;
+
+ /* pre- Tcl_Init code copied from tkMacOSXAppInit.c */
+ Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tcllibrary",
+ tclLibPath, MAX_PATH_LEN, 0);
+
+ if (tclLibPath[0] != '\0') {
+ Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY);
+ }
+
+ if (tclLibPath[0] != '\0') {
+ Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY);
+ }
+#endif
+ if (Tcl_Init (interp) == TCL_ERROR)
+ return TCL_ERROR;
+
+#ifdef TK_AQUA
+ /* pre- Tk_Init code copied from tkMacOSXAppInit.c */
+ Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tklibrary",
+ tkLibPath, MAX_PATH_LEN, 1);
+
+ if (tclLibPath[0] != '\0') {
+ pathPtr = Tcl_NewStringObj(tclLibPath, -1);
+ } else {
+ Tcl_Obj *pathPtr = TclGetLibraryPath();
+ }
+
+ if (tkLibPath[0] != '\0') {
+ Tcl_Obj *objPtr;
+
+ Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY);
+ objPtr = Tcl_NewStringObj(tkLibPath, -1);
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ }
+
+ TclSetLibraryPath(pathPtr);
+#endif
+
+#ifdef WITH_XXX
+ // Initialize modules that don't require Tk
+#endif
+
+ _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY);
+ if (_tkinter_skip_tk_init != NULL && strcmp(_tkinter_skip_tk_init, "1") == 0) {
+ return TCL_OK;
+ }
+ if (Tk_Init(interp) == TCL_ERROR)
+ return TCL_ERROR;
+
+ main_window = Tk_MainWindow(interp);
+
+#ifdef TK_AQUA
+ TkMacOSXInitAppleEvents(interp);
+ TkMacOSXInitMenus(interp);
+#endif
+
+#ifdef WITH_MOREBUTTONS
+ {
+ extern Tcl_CmdProc studButtonCmd;
+ extern Tcl_CmdProc triButtonCmd;
+
+ Tcl_CreateCommand(interp, "studbutton", studButtonCmd,
+ (ClientData) main_window, NULL);
+ Tcl_CreateCommand(interp, "tributton", triButtonCmd,
+ (ClientData) main_window, NULL);
+ }
+#endif
+
+#ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */
+ {
+ extern void TkImaging_Init(Tcl_Interp *);
+ TkImaging_Init(interp);
+ /* XXX TkImaging_Init() doesn't have the right return type */
+ /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/
+ }
+#endif
+
+#ifdef WITH_PIL_OLD /* 0.2b4 and earlier */
+ {
+ extern void TkImaging_Init(void);
+ /* XXX TkImaging_Init() doesn't have the right prototype */
+ /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/
+ }
+#endif
+
+#ifdef WITH_TIX
+ {
+ extern int Tix_Init(Tcl_Interp *interp);
+ extern int Tix_SafeInit(Tcl_Interp *interp);
+ Tcl_StaticPackage(NULL, "Tix", Tix_Init, Tix_SafeInit);
+ }
+#endif
+
+#ifdef WITH_BLT
+ {
+ extern int Blt_Init(Tcl_Interp *);
+ extern int Blt_SafeInit(Tcl_Interp *);
+ Tcl_StaticPackage(NULL, "Blt", Blt_Init, Blt_SafeInit);
+ }
+#endif
+
+#ifdef WITH_TOGL
+ {
+ /* XXX I've heard rumors that this doesn't work */
+ extern int Togl_Init(Tcl_Interp *);
+ /* XXX Is there no Togl_SafeInit? */
+ Tcl_StaticPackage(NULL, "Togl", Togl_Init, NULL);
+ }
+#endif
+
+#ifdef WITH_XXX
+
+#endif
+ return TCL_OK;
+}
diff --git a/sys/src/cmd/python/Modules/unicodedata.c b/sys/src/cmd/python/Modules/unicodedata.c
new file mode 100644
index 000000000..a30d30c8e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/unicodedata.c
@@ -0,0 +1,1223 @@
+/* ------------------------------------------------------------------------
+
+ unicodedata -- Provides access to the Unicode 4.1 data base.
+
+ Data was extracted from the Unicode 4.1 UnicodeData.txt file.
+
+ Written by Marc-Andre Lemburg (mal@lemburg.com).
+ Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com)
+ Modified by Martin v. Löwis (martin@v.loewis.de)
+
+ Copyright (c) Corporation for National Research Initiatives.
+
+ ------------------------------------------------------------------------ */
+
+#include "Python.h"
+#include "ucnhash.h"
+#include "structmember.h"
+
+/* character properties */
+
+typedef struct {
+ const unsigned char category; /* index into
+ _PyUnicode_CategoryNames */
+ const unsigned char combining; /* combining class value 0 - 255 */
+ const unsigned char bidirectional; /* index into
+ _PyUnicode_BidirectionalNames */
+ const unsigned char mirrored; /* true if mirrored in bidir mode */
+ const unsigned char east_asian_width; /* index into
+ _PyUnicode_EastAsianWidth */
+} _PyUnicode_DatabaseRecord;
+
+typedef struct change_record {
+ /* sequence of fields should be the same as in merge_old_version */
+ const unsigned char bidir_changed;
+ const unsigned char category_changed;
+ const unsigned char decimal_changed;
+ const int numeric_changed;
+} change_record;
+
+/* data file generated by Tools/unicode/makeunicodedata.py */
+#include "unicodedata_db.h"
+
+static const _PyUnicode_DatabaseRecord*
+_getrecord_ex(Py_UCS4 code)
+{
+ int index;
+ if (code >= 0x110000)
+ index = 0;
+ else {
+ index = index1[(code>>SHIFT)];
+ index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
+ }
+
+ return &_PyUnicode_Database_Records[index];
+}
+
+static const _PyUnicode_DatabaseRecord*
+_getrecord(PyUnicodeObject* v)
+{
+ return _getrecord_ex(*PyUnicode_AS_UNICODE(v));
+}
+
+/* ------------- Previous-version API ------------------------------------- */
+typedef struct previous_version {
+ PyObject_HEAD
+ const char *name;
+ const change_record* (*getrecord)(Py_UCS4);
+ Py_UCS4 (*normalization)(Py_UCS4);
+} PreviousDBVersion;
+
+#define get_old_record(self, v) ((((PreviousDBVersion*)self)->getrecord)(v))
+
+static PyMemberDef DB_members[] = {
+ {"unidata_version", T_STRING, offsetof(PreviousDBVersion, name), READONLY},
+ {NULL}
+};
+
+/* forward declaration */
+static PyTypeObject UCD_Type;
+
+static PyObject*
+new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4),
+ Py_UCS4 (*normalization)(Py_UCS4))
+{
+ PreviousDBVersion *self;
+ self = PyObject_New(PreviousDBVersion, &UCD_Type);
+ if (self == NULL)
+ return NULL;
+ self->name = name;
+ self->getrecord = getrecord;
+ self->normalization = normalization;
+ return (PyObject*)self;
+}
+
+/* --- Module API --------------------------------------------------------- */
+
+PyDoc_STRVAR(unicodedata_decimal__doc__,
+"decimal(unichr[, default])\n\
+\n\
+Returns the decimal value assigned to the Unicode character unichr\n\
+as integer. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
+static PyObject *
+unicodedata_decimal(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ PyObject *defobj = NULL;
+ int have_old = 0;
+ long rc;
+
+ if (!PyArg_ParseTuple(args, "O!|O:decimal", &PyUnicode_Type, &v, &defobj))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0) {
+ /* unassigned */
+ have_old = 1;
+ rc = -1;
+ }
+ else if (old->decimal_changed != 0xFF) {
+ have_old = 1;
+ rc = old->decimal_changed;
+ }
+ }
+
+ if (!have_old)
+ rc = Py_UNICODE_TODECIMAL(*PyUnicode_AS_UNICODE(v));
+ if (rc < 0) {
+ if (defobj == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "not a decimal");
+ return NULL;
+ }
+ else {
+ Py_INCREF(defobj);
+ return defobj;
+ }
+ }
+ return PyInt_FromLong(rc);
+}
+
+PyDoc_STRVAR(unicodedata_digit__doc__,
+"digit(unichr[, default])\n\
+\n\
+Returns the digit value assigned to the Unicode character unichr as\n\
+integer. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
+static PyObject *
+unicodedata_digit(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ PyObject *defobj = NULL;
+ long rc;
+
+ if (!PyArg_ParseTuple(args, "O!|O:digit", &PyUnicode_Type, &v, &defobj))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+ rc = Py_UNICODE_TODIGIT(*PyUnicode_AS_UNICODE(v));
+ if (rc < 0) {
+ if (defobj == NULL) {
+ PyErr_SetString(PyExc_ValueError, "not a digit");
+ return NULL;
+ }
+ else {
+ Py_INCREF(defobj);
+ return defobj;
+ }
+ }
+ return PyInt_FromLong(rc);
+}
+
+PyDoc_STRVAR(unicodedata_numeric__doc__,
+"numeric(unichr[, default])\n\
+\n\
+Returns the numeric value assigned to the Unicode character unichr\n\
+as float. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
+static PyObject *
+unicodedata_numeric(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ PyObject *defobj = NULL;
+ int have_old = 0;
+ double rc;
+
+ if (!PyArg_ParseTuple(args, "O!|O:numeric", &PyUnicode_Type, &v, &defobj))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0) {
+ /* unassigned */
+ have_old = 1;
+ rc = -1.0;
+ }
+ else if (old->decimal_changed != 0xFF) {
+ have_old = 1;
+ rc = old->decimal_changed;
+ }
+ }
+
+ if (!have_old)
+ rc = Py_UNICODE_TONUMERIC(*PyUnicode_AS_UNICODE(v));
+ if (rc == -1.0) {
+ if (defobj == NULL) {
+ PyErr_SetString(PyExc_ValueError, "not a numeric character");
+ return NULL;
+ }
+ else {
+ Py_INCREF(defobj);
+ return defobj;
+ }
+ }
+ return PyFloat_FromDouble(rc);
+}
+
+PyDoc_STRVAR(unicodedata_category__doc__,
+"category(unichr)\n\
+\n\
+Returns the general category assigned to the Unicode character\n\
+unichr as string.");
+
+static PyObject *
+unicodedata_category(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ int index;
+
+ if (!PyArg_ParseTuple(args, "O!:category",
+ &PyUnicode_Type, &v))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+ index = (int) _getrecord(v)->category;
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed != 0xFF)
+ index = old->category_changed;
+ }
+ return PyString_FromString(_PyUnicode_CategoryNames[index]);
+}
+
+PyDoc_STRVAR(unicodedata_bidirectional__doc__,
+"bidirectional(unichr)\n\
+\n\
+Returns the bidirectional category assigned to the Unicode character\n\
+unichr as string. If no such value is defined, an empty string is\n\
+returned.");
+
+static PyObject *
+unicodedata_bidirectional(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ int index;
+
+ if (!PyArg_ParseTuple(args, "O!:bidirectional",
+ &PyUnicode_Type, &v))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+ index = (int) _getrecord(v)->bidirectional;
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0)
+ index = 0; /* unassigned */
+ else if (old->bidir_changed != 0xFF)
+ index = old->bidir_changed;
+ }
+ return PyString_FromString(_PyUnicode_BidirectionalNames[index]);
+}
+
+PyDoc_STRVAR(unicodedata_combining__doc__,
+"combining(unichr)\n\
+\n\
+Returns the canonical combining class assigned to the Unicode\n\
+character unichr as integer. Returns 0 if no combining class is\n\
+defined.");
+
+static PyObject *
+unicodedata_combining(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ int index;
+
+ if (!PyArg_ParseTuple(args, "O!:combining",
+ &PyUnicode_Type, &v))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+ index = (int) _getrecord(v)->combining;
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0)
+ index = 0; /* unassigned */
+ }
+ return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(unicodedata_mirrored__doc__,
+"mirrored(unichr)\n\
+\n\
+Returns the mirrored property assigned to the Unicode character\n\
+unichr as integer. Returns 1 if the character has been identified as\n\
+a \"mirrored\" character in bidirectional text, 0 otherwise.");
+
+static PyObject *
+unicodedata_mirrored(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ int index;
+
+ if (!PyArg_ParseTuple(args, "O!:mirrored",
+ &PyUnicode_Type, &v))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+ index = (int) _getrecord(v)->mirrored;
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0)
+ index = 0; /* unassigned */
+ }
+ return PyInt_FromLong(index);
+}
+
+PyDoc_STRVAR(unicodedata_east_asian_width__doc__,
+"east_asian_width(unichr)\n\
+\n\
+Returns the east asian width assigned to the Unicode character\n\
+unichr as string.");
+
+static PyObject *
+unicodedata_east_asian_width(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ int index;
+
+ if (!PyArg_ParseTuple(args, "O!:east_asian_width",
+ &PyUnicode_Type, &v))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+ index = (int) _getrecord(v)->east_asian_width;
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0)
+ index = 0; /* unassigned */
+ }
+ return PyString_FromString(_PyUnicode_EastAsianWidthNames[index]);
+}
+
+PyDoc_STRVAR(unicodedata_decomposition__doc__,
+"decomposition(unichr)\n\
+\n\
+Returns the character decomposition mapping assigned to the Unicode\n\
+character unichr as string. An empty string is returned in case no\n\
+such mapping is defined.");
+
+static PyObject *
+unicodedata_decomposition(PyObject *self, PyObject *args)
+{
+ PyUnicodeObject *v;
+ char decomp[256];
+ int code, index, count, i;
+ unsigned int prefix_index;
+
+ if (!PyArg_ParseTuple(args, "O!:decomposition",
+ &PyUnicode_Type, &v))
+ return NULL;
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+
+ code = (int) *PyUnicode_AS_UNICODE(v);
+
+ if (self) {
+ const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+ if (old->category_changed == 0)
+ return PyString_FromString(""); /* unassigned */
+ }
+
+ if (code < 0 || code >= 0x110000)
+ index = 0;
+ else {
+ index = decomp_index1[(code>>DECOMP_SHIFT)];
+ index = decomp_index2[(index<<DECOMP_SHIFT)+
+ (code&((1<<DECOMP_SHIFT)-1))];
+ }
+
+ /* high byte is number of hex bytes (usually one or two), low byte
+ is prefix code (from*/
+ count = decomp_data[index] >> 8;
+
+ /* XXX: could allocate the PyString up front instead
+ (strlen(prefix) + 5 * count + 1 bytes) */
+
+ /* Based on how index is calculated above and decomp_data is generated
+ from Tools/unicode/makeunicodedata.py, it should not be possible
+ to overflow decomp_prefix. */
+ prefix_index = decomp_data[index] & 255;
+ assert(prefix_index < (sizeof(decomp_prefix)/sizeof(*decomp_prefix)));
+
+ /* copy prefix */
+ i = strlen(decomp_prefix[prefix_index]);
+ memcpy(decomp, decomp_prefix[prefix_index], i);
+
+ while (count-- > 0) {
+ if (i)
+ decomp[i++] = ' ';
+ assert((size_t)i < sizeof(decomp));
+ PyOS_snprintf(decomp + i, sizeof(decomp) - i, "%04X",
+ decomp_data[++index]);
+ i += strlen(decomp + i);
+ }
+
+ decomp[i] = '\0';
+
+ return PyString_FromString(decomp);
+}
+
+static void
+get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count)
+{
+ if (code >= 0x110000) {
+ *index = 0;
+ } else if (self && get_old_record(self, code)->category_changed==0) {
+ /* unassigned in old version */
+ *index = 0;
+ }
+ else {
+ *index = decomp_index1[(code>>DECOMP_SHIFT)];
+ *index = decomp_index2[(*index<<DECOMP_SHIFT)+
+ (code&((1<<DECOMP_SHIFT)-1))];
+ }
+
+ /* high byte is number of hex bytes (usually one or two), low byte
+ is prefix code (from*/
+ *count = decomp_data[*index] >> 8;
+ *prefix = decomp_data[*index] & 255;
+
+ (*index)++;
+}
+
+#define SBase 0xAC00
+#define LBase 0x1100
+#define VBase 0x1161
+#define TBase 0x11A7
+#define LCount 19
+#define VCount 21
+#define TCount 28
+#define NCount (VCount*TCount)
+#define SCount (LCount*NCount)
+
+static PyObject*
+nfd_nfkd(PyObject *self, PyObject *input, int k)
+{
+ PyObject *result;
+ Py_UNICODE *i, *end, *o;
+ /* Longest decomposition in Unicode 3.2: U+FDFA */
+ Py_UNICODE stack[20];
+ Py_ssize_t space, isize;
+ int index, prefix, count, stackptr;
+ unsigned char prev, cur;
+
+ stackptr = 0;
+ isize = PyUnicode_GET_SIZE(input);
+ /* Overallocate atmost 10 characters. */
+ space = (isize > 10 ? 10 : isize) + isize;
+ result = PyUnicode_FromUnicode(NULL, space);
+ if (!result)
+ return NULL;
+ i = PyUnicode_AS_UNICODE(input);
+ end = i + isize;
+ o = PyUnicode_AS_UNICODE(result);
+
+ while (i < end) {
+ stack[stackptr++] = *i++;
+ while(stackptr) {
+ Py_UNICODE code = stack[--stackptr];
+ /* Hangul Decomposition adds three characters in
+ a single step, so we need atleast that much room. */
+ if (space < 3) {
+ Py_ssize_t newsize = PyString_GET_SIZE(result) + 10;
+ space += 10;
+ if (PyUnicode_Resize(&result, newsize) == -1)
+ return NULL;
+ o = PyUnicode_AS_UNICODE(result) + newsize - space;
+ }
+ /* Hangul Decomposition. */
+ if (SBase <= code && code < (SBase+SCount)) {
+ int SIndex = code - SBase;
+ int L = LBase + SIndex / NCount;
+ int V = VBase + (SIndex % NCount) / TCount;
+ int T = TBase + SIndex % TCount;
+ *o++ = L;
+ *o++ = V;
+ space -= 2;
+ if (T != TBase) {
+ *o++ = T;
+ space --;
+ }
+ continue;
+ }
+ /* normalization changes */
+ if (self) {
+ Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code);
+ if (value != 0) {
+ stack[stackptr++] = value;
+ continue;
+ }
+ }
+
+ /* Other decompositions. */
+ get_decomp_record(self, code, &index, &prefix, &count);
+
+ /* Copy character if it is not decomposable, or has a
+ compatibility decomposition, but we do NFD. */
+ if (!count || (prefix && !k)) {
+ *o++ = code;
+ space--;
+ continue;
+ }
+ /* Copy decomposition onto the stack, in reverse
+ order. */
+ while(count) {
+ code = decomp_data[index + (--count)];
+ stack[stackptr++] = code;
+ }
+ }
+ }
+
+ /* Drop overallocation. Cannot fail. */
+ PyUnicode_Resize(&result, PyUnicode_GET_SIZE(result) - space);
+
+ /* Sort canonically. */
+ i = PyUnicode_AS_UNICODE(result);
+ prev = _getrecord_ex(*i)->combining;
+ end = i + PyUnicode_GET_SIZE(result);
+ for (i++; i < end; i++) {
+ cur = _getrecord_ex(*i)->combining;
+ if (prev == 0 || cur == 0 || prev <= cur) {
+ prev = cur;
+ continue;
+ }
+ /* Non-canonical order. Need to switch *i with previous. */
+ o = i - 1;
+ while (1) {
+ Py_UNICODE tmp = o[1];
+ o[1] = o[0];
+ o[0] = tmp;
+ o--;
+ if (o < PyUnicode_AS_UNICODE(result))
+ break;
+ prev = _getrecord_ex(*o)->combining;
+ if (prev == 0 || prev <= cur)
+ break;
+ }
+ prev = _getrecord_ex(*i)->combining;
+ }
+ return result;
+}
+
+static int
+find_nfc_index(PyObject *self, struct reindex* nfc, Py_UNICODE code)
+{
+ int index;
+ for (index = 0; nfc[index].start; index++) {
+ int start = nfc[index].start;
+ if (code < start)
+ return -1;
+ if (code <= start + nfc[index].count) {
+ int delta = code - start;
+ return nfc[index].index + delta;
+ }
+ }
+ return -1;
+}
+
+static PyObject*
+nfc_nfkc(PyObject *self, PyObject *input, int k)
+{
+ PyObject *result;
+ Py_UNICODE *i, *i1, *o, *end;
+ int f,l,index,index1,comb;
+ Py_UNICODE code;
+ Py_UNICODE *skipped[20];
+ int cskipped = 0;
+
+ result = nfd_nfkd(self, input, k);
+ if (!result)
+ return NULL;
+
+ /* We are going to modify result in-place.
+ If nfd_nfkd is changed to sometimes return the input,
+ this code needs to be reviewed. */
+ assert(result != input);
+
+ i = PyUnicode_AS_UNICODE(result);
+ end = i + PyUnicode_GET_SIZE(result);
+ o = PyUnicode_AS_UNICODE(result);
+
+ again:
+ while (i < end) {
+ for (index = 0; index < cskipped; index++) {
+ if (skipped[index] == i) {
+ /* *i character is skipped.
+ Remove from list. */
+ skipped[index] = skipped[cskipped-1];
+ cskipped--;
+ i++;
+ goto again; /* continue while */
+ }
+ }
+ /* Hangul Composition. We don't need to check for <LV,T>
+ pairs, since we always have decomposed data. */
+ if (LBase <= *i && *i < (LBase+LCount) &&
+ i + 1 < end &&
+ VBase <= i[1] && i[1] <= (VBase+VCount)) {
+ int LIndex, VIndex;
+ LIndex = i[0] - LBase;
+ VIndex = i[1] - VBase;
+ code = SBase + (LIndex*VCount+VIndex)*TCount;
+ i+=2;
+ if (i < end &&
+ TBase <= *i && *i <= (TBase+TCount)) {
+ code += *i-TBase;
+ i++;
+ }
+ *o++ = code;
+ continue;
+ }
+
+ f = find_nfc_index(self, nfc_first, *i);
+ if (f == -1) {
+ *o++ = *i++;
+ continue;
+ }
+ /* Find next unblocked character. */
+ i1 = i+1;
+ comb = 0;
+ while (i1 < end) {
+ int comb1 = _getrecord_ex(*i1)->combining;
+ if (comb1 && comb == comb1) {
+ /* Character is blocked. */
+ i1++;
+ continue;
+ }
+ l = find_nfc_index(self, nfc_last, *i1);
+ /* *i1 cannot be combined with *i. If *i1
+ is a starter, we don't need to look further.
+ Otherwise, record the combining class. */
+ if (l == -1) {
+ not_combinable:
+ if (comb1 == 0)
+ break;
+ comb = comb1;
+ i1++;
+ continue;
+ }
+ index = f*TOTAL_LAST + l;
+ index1 = comp_index[index >> COMP_SHIFT];
+ code = comp_data[(index1<<COMP_SHIFT)+
+ (index&((1<<COMP_SHIFT)-1))];
+ if (code == 0)
+ goto not_combinable;
+
+ /* Replace the original character. */
+ *i = code;
+ /* Mark the second character unused. */
+ skipped[cskipped++] = i1;
+ i1++;
+ f = find_nfc_index(self, nfc_first, *i);
+ if (f == -1)
+ break;
+ }
+ *o++ = *i++;
+ }
+ if (o != end)
+ PyUnicode_Resize(&result, o - PyUnicode_AS_UNICODE(result));
+ return result;
+}
+
+PyDoc_STRVAR(unicodedata_normalize__doc__,
+"normalize(form, unistr)\n\
+\n\
+Return the normal form 'form' for the Unicode string unistr. Valid\n\
+values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'.");
+
+static PyObject*
+unicodedata_normalize(PyObject *self, PyObject *args)
+{
+ char *form;
+ PyObject *input;
+
+ if(!PyArg_ParseTuple(args, "sO!:normalize",
+ &form, &PyUnicode_Type, &input))
+ return NULL;
+
+ if (PyUnicode_GetSize(input) == 0) {
+ /* Special case empty input strings, since resizing
+ them later would cause internal errors. */
+ Py_INCREF(input);
+ return input;
+ }
+
+ if (strcmp(form, "NFC") == 0)
+ return nfc_nfkc(self, input, 0);
+ if (strcmp(form, "NFKC") == 0)
+ return nfc_nfkc(self, input, 1);
+ if (strcmp(form, "NFD") == 0)
+ return nfd_nfkd(self, input, 0);
+ if (strcmp(form, "NFKD") == 0)
+ return nfd_nfkd(self, input, 1);
+ PyErr_SetString(PyExc_ValueError, "invalid normalization form");
+ return NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* unicode character name tables */
+
+/* data file generated by Tools/unicode/makeunicodedata.py */
+#include "unicodename_db.h"
+
+/* -------------------------------------------------------------------- */
+/* database code (cut and pasted from the unidb package) */
+
+static unsigned long
+_gethash(const char *s, int len, int scale)
+{
+ int i;
+ unsigned long h = 0;
+ unsigned long ix;
+ for (i = 0; i < len; i++) {
+ h = (h * scale) + (unsigned char) toupper(Py_CHARMASK(s[i]));
+ ix = h & 0xff000000;
+ if (ix)
+ h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff;
+ }
+ return h;
+}
+
+static char *hangul_syllables[][3] = {
+ { "G", "A", "" },
+ { "GG", "AE", "G" },
+ { "N", "YA", "GG" },
+ { "D", "YAE", "GS" },
+ { "DD", "EO", "N", },
+ { "R", "E", "NJ" },
+ { "M", "YEO", "NH" },
+ { "B", "YE", "D" },
+ { "BB", "O", "L" },
+ { "S", "WA", "LG" },
+ { "SS", "WAE", "LM" },
+ { "", "OE", "LB" },
+ { "J", "YO", "LS" },
+ { "JJ", "U", "LT" },
+ { "C", "WEO", "LP" },
+ { "K", "WE", "LH" },
+ { "T", "WI", "M" },
+ { "P", "YU", "B" },
+ { "H", "EU", "BS" },
+ { 0, "YI", "S" },
+ { 0, "I", "SS" },
+ { 0, 0, "NG" },
+ { 0, 0, "J" },
+ { 0, 0, "C" },
+ { 0, 0, "K" },
+ { 0, 0, "T" },
+ { 0, 0, "P" },
+ { 0, 0, "H" }
+};
+
+static int
+is_unified_ideograph(Py_UCS4 code)
+{
+ return (
+ (0x3400 <= code && code <= 0x4DB5) || /* CJK Ideograph Extension A */
+ (0x4E00 <= code && code <= 0x9FBB) || /* CJK Ideograph */
+ (0x20000 <= code && code <= 0x2A6D6));/* CJK Ideograph Extension B */
+}
+
+static int
+_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen)
+{
+ int offset;
+ int i;
+ int word;
+ unsigned char* w;
+
+ if (code >= 0x110000)
+ return 0;
+
+ if (self) {
+ const change_record *old = get_old_record(self, code);
+ if (old->category_changed == 0) {
+ /* unassigned */
+ return 0;
+ }
+ }
+
+ if (SBase <= code && code < SBase+SCount) {
+ /* Hangul syllable. */
+ int SIndex = code - SBase;
+ int L = SIndex / NCount;
+ int V = (SIndex % NCount) / TCount;
+ int T = SIndex % TCount;
+
+ if (buflen < 27)
+ /* Worst case: HANGUL SYLLABLE <10chars>. */
+ return 0;
+ strcpy(buffer, "HANGUL SYLLABLE ");
+ buffer += 16;
+ strcpy(buffer, hangul_syllables[L][0]);
+ buffer += strlen(hangul_syllables[L][0]);
+ strcpy(buffer, hangul_syllables[V][1]);
+ buffer += strlen(hangul_syllables[V][1]);
+ strcpy(buffer, hangul_syllables[T][2]);
+ buffer += strlen(hangul_syllables[T][2]);
+ *buffer = '\0';
+ return 1;
+ }
+
+ if (is_unified_ideograph(code)) {
+ if (buflen < 28)
+ /* Worst case: CJK UNIFIED IDEOGRAPH-20000 */
+ return 0;
+ sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code);
+ return 1;
+ }
+
+ /* get offset into phrasebook */
+ offset = phrasebook_offset1[(code>>phrasebook_shift)];
+ offset = phrasebook_offset2[(offset<<phrasebook_shift) +
+ (code&((1<<phrasebook_shift)-1))];
+ if (!offset)
+ return 0;
+
+ i = 0;
+
+ for (;;) {
+ /* get word index */
+ word = phrasebook[offset] - phrasebook_short;
+ if (word >= 0) {
+ word = (word << 8) + phrasebook[offset+1];
+ offset += 2;
+ } else
+ word = phrasebook[offset++];
+ if (i) {
+ if (i > buflen)
+ return 0; /* buffer overflow */
+ buffer[i++] = ' ';
+ }
+ /* copy word string from lexicon. the last character in the
+ word has bit 7 set. the last word in a string ends with
+ 0x80 */
+ w = lexicon + lexicon_offset[word];
+ while (*w < 128) {
+ if (i >= buflen)
+ return 0; /* buffer overflow */
+ buffer[i++] = *w++;
+ }
+ if (i >= buflen)
+ return 0; /* buffer overflow */
+ buffer[i++] = *w & 127;
+ if (*w == 128)
+ break; /* end of word */
+ }
+
+ return 1;
+}
+
+static int
+_cmpname(PyObject *self, int code, const char* name, int namelen)
+{
+ /* check if code corresponds to the given name */
+ int i;
+ char buffer[NAME_MAXLEN];
+ if (!_getucname(self, code, buffer, sizeof(buffer)))
+ return 0;
+ for (i = 0; i < namelen; i++) {
+ if (toupper(Py_CHARMASK(name[i])) != buffer[i])
+ return 0;
+ }
+ return buffer[namelen] == '\0';
+}
+
+static void
+find_syllable(const char *str, int *len, int *pos, int count, int column)
+{
+ int i, len1;
+ *len = -1;
+ for (i = 0; i < count; i++) {
+ char *s = hangul_syllables[i][column];
+ len1 = strlen(s);
+ if (len1 <= *len)
+ continue;
+ if (strncmp(str, s, len1) == 0) {
+ *len = len1;
+ *pos = i;
+ }
+ }
+ if (*len == -1) {
+ *len = 0;
+ }
+}
+
+static int
+_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code)
+{
+ unsigned int h, v;
+ unsigned int mask = code_size-1;
+ unsigned int i, incr;
+
+ /* Check for hangul syllables. */
+ if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) {
+ int len, L = -1, V = -1, T = -1;
+ const char *pos = name + 16;
+ find_syllable(pos, &len, &L, LCount, 0);
+ pos += len;
+ find_syllable(pos, &len, &V, VCount, 1);
+ pos += len;
+ find_syllable(pos, &len, &T, TCount, 2);
+ pos += len;
+ if (L != -1 && V != -1 && T != -1 && pos-name == namelen) {
+ *code = SBase + (L*VCount+V)*TCount + T;
+ return 1;
+ }
+ /* Otherwise, it's an illegal syllable name. */
+ return 0;
+ }
+
+ /* Check for unified ideographs. */
+ if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) {
+ /* Four or five hexdigits must follow. */
+ v = 0;
+ name += 22;
+ namelen -= 22;
+ if (namelen != 4 && namelen != 5)
+ return 0;
+ while (namelen--) {
+ v *= 16;
+ if (*name >= '0' && *name <= '9')
+ v += *name - '0';
+ else if (*name >= 'A' && *name <= 'F')
+ v += *name - 'A' + 10;
+ else
+ return 0;
+ name++;
+ }
+ if (!is_unified_ideograph(v))
+ return 0;
+ *code = v;
+ return 1;
+ }
+
+ /* the following is the same as python's dictionary lookup, with
+ only minor changes. see the makeunicodedata script for more
+ details */
+
+ h = (unsigned int) _gethash(name, namelen, code_magic);
+ i = (~h) & mask;
+ v = code_hash[i];
+ if (!v)
+ return 0;
+ if (_cmpname(self, v, name, namelen)) {
+ *code = v;
+ return 1;
+ }
+ incr = (h ^ (h >> 3)) & mask;
+ if (!incr)
+ incr = mask;
+ for (;;) {
+ i = (i + incr) & mask;
+ v = code_hash[i];
+ if (!v)
+ return 0;
+ if (_cmpname(self, v, name, namelen)) {
+ *code = v;
+ return 1;
+ }
+ incr = incr << 1;
+ if (incr > mask)
+ incr = incr ^ code_poly;
+ }
+}
+
+static const _PyUnicode_Name_CAPI hashAPI =
+{
+ sizeof(_PyUnicode_Name_CAPI),
+ _getucname,
+ _getcode
+};
+
+/* -------------------------------------------------------------------- */
+/* Python bindings */
+
+PyDoc_STRVAR(unicodedata_name__doc__,
+"name(unichr[, default])\n\
+Returns the name assigned to the Unicode character unichr as a\n\
+string. If no name is defined, default is returned, or, if not\n\
+given, ValueError is raised.");
+
+static PyObject *
+unicodedata_name(PyObject* self, PyObject* args)
+{
+ char name[NAME_MAXLEN];
+
+ PyUnicodeObject* v;
+ PyObject* defobj = NULL;
+ if (!PyArg_ParseTuple(args, "O!|O:name", &PyUnicode_Type, &v, &defobj))
+ return NULL;
+
+ if (PyUnicode_GET_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "need a single Unicode character as parameter");
+ return NULL;
+ }
+
+ if (!_getucname(self, (Py_UCS4) *PyUnicode_AS_UNICODE(v),
+ name, sizeof(name))) {
+ if (defobj == NULL) {
+ PyErr_SetString(PyExc_ValueError, "no such name");
+ return NULL;
+ }
+ else {
+ Py_INCREF(defobj);
+ return defobj;
+ }
+ }
+
+ return Py_BuildValue("s", name);
+}
+
+PyDoc_STRVAR(unicodedata_lookup__doc__,
+"lookup(name)\n\
+\n\
+Look up character by name. If a character with the\n\
+given name is found, return the corresponding Unicode\n\
+character. If not found, KeyError is raised.");
+
+static PyObject *
+unicodedata_lookup(PyObject* self, PyObject* args)
+{
+ Py_UCS4 code;
+ Py_UNICODE str[1];
+ char errbuf[256];
+
+ char* name;
+ int namelen;
+ if (!PyArg_ParseTuple(args, "s#:lookup", &name, &namelen))
+ return NULL;
+
+ if (!_getcode(self, name, namelen, &code)) {
+ /* XXX(nnorwitz): why are we allocating for the error msg?
+ Why not always use snprintf? */
+ char fmt[] = "undefined character name '%s'";
+ char *buf = PyMem_MALLOC(sizeof(fmt) + namelen);
+ if (buf)
+ sprintf(buf, fmt, name);
+ else {
+ buf = errbuf;
+ PyOS_snprintf(buf, sizeof(errbuf), fmt, name);
+ }
+ PyErr_SetString(PyExc_KeyError, buf);
+ if (buf != errbuf)
+ PyMem_FREE(buf);
+ return NULL;
+ }
+
+ str[0] = (Py_UNICODE) code;
+ return PyUnicode_FromUnicode(str, 1);
+}
+
+/* XXX Add doc strings. */
+
+static PyMethodDef unicodedata_functions[] = {
+ {"decimal", unicodedata_decimal, METH_VARARGS, unicodedata_decimal__doc__},
+ {"digit", unicodedata_digit, METH_VARARGS, unicodedata_digit__doc__},
+ {"numeric", unicodedata_numeric, METH_VARARGS, unicodedata_numeric__doc__},
+ {"category", unicodedata_category, METH_VARARGS,
+ unicodedata_category__doc__},
+ {"bidirectional", unicodedata_bidirectional, METH_VARARGS,
+ unicodedata_bidirectional__doc__},
+ {"combining", unicodedata_combining, METH_VARARGS,
+ unicodedata_combining__doc__},
+ {"mirrored", unicodedata_mirrored, METH_VARARGS,
+ unicodedata_mirrored__doc__},
+ {"east_asian_width", unicodedata_east_asian_width, METH_VARARGS,
+ unicodedata_east_asian_width__doc__},
+ {"decomposition", unicodedata_decomposition, METH_VARARGS,
+ unicodedata_decomposition__doc__},
+ {"name", unicodedata_name, METH_VARARGS, unicodedata_name__doc__},
+ {"lookup", unicodedata_lookup, METH_VARARGS, unicodedata_lookup__doc__},
+ {"normalize", unicodedata_normalize, METH_VARARGS,
+ unicodedata_normalize__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject UCD_Type = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "unicodedata.UCD", /*tp_name*/
+ sizeof(PreviousDBVersion), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyObject_Del, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr,/*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ unicodedata_functions, /*tp_methods*/
+ DB_members, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+PyDoc_STRVAR(unicodedata_docstring,
+"This module provides access to the Unicode Character Database which\n\
+defines character properties for all Unicode characters. The data in\n\
+this database is based on the UnicodeData.txt file version\n\
+4.1.0 which is publically available from ftp://ftp.unicode.org/.\n\
+\n\
+The module uses the same names and symbols as defined by the\n\
+UnicodeData File Format 4.1.0 (see\n\
+http://www.unicode.org/Public/4.1.0/ucd/UCD.html).");
+
+PyMODINIT_FUNC
+initunicodedata(void)
+{
+ PyObject *m, *v;
+
+ UCD_Type.ob_type = &PyType_Type;
+
+ m = Py_InitModule3(
+ "unicodedata", unicodedata_functions, unicodedata_docstring);
+ if (!m)
+ return;
+
+ PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION);
+ Py_INCREF(&UCD_Type);
+ PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type);
+
+ /* Previous versions */
+ v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0);
+ if (v != NULL)
+ PyModule_AddObject(m, "ucd_3_2_0", v);
+
+ /* Export C API */
+ v = PyCObject_FromVoidPtr((void *) &hashAPI, NULL);
+ if (v != NULL)
+ PyModule_AddObject(m, "ucnhash_CAPI", v);
+}
+
+/*
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
diff --git a/sys/src/cmd/python/Modules/unicodedata_db.h b/sys/src/cmd/python/Modules/unicodedata_db.h
new file mode 100644
index 000000000..d68466a48
--- /dev/null
+++ b/sys/src/cmd/python/Modules/unicodedata_db.h
@@ -0,0 +1,5135 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
+
+#define UNIDATA_VERSION "4.1.0"
+/* a list of unique database records */
+const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {
+ {0, 0, 0, 0, 0},
+ {13, 0, 15, 0, 5},
+ {13, 0, 17, 0, 5},
+ {13, 0, 16, 0, 5},
+ {13, 0, 18, 0, 5},
+ {10, 0, 18, 0, 3},
+ {26, 0, 19, 0, 3},
+ {26, 0, 11, 0, 3},
+ {28, 0, 11, 0, 3},
+ {22, 0, 19, 1, 3},
+ {23, 0, 19, 1, 3},
+ {27, 0, 10, 0, 3},
+ {26, 0, 13, 0, 3},
+ {21, 0, 10, 0, 3},
+ {7, 0, 9, 0, 3},
+ {27, 0, 19, 1, 3},
+ {27, 0, 19, 0, 3},
+ {1, 0, 1, 0, 3},
+ {29, 0, 19, 0, 3},
+ {20, 0, 19, 0, 3},
+ {2, 0, 1, 0, 3},
+ {10, 0, 13, 0, 5},
+ {26, 0, 19, 0, 4},
+ {28, 0, 11, 0, 4},
+ {30, 0, 19, 0, 3},
+ {30, 0, 19, 0, 4},
+ {29, 0, 19, 0, 4},
+ {30, 0, 19, 0, 5},
+ {2, 0, 1, 0, 4},
+ {24, 0, 19, 1, 5},
+ {14, 0, 15, 0, 4},
+ {30, 0, 11, 0, 4},
+ {27, 0, 11, 0, 4},
+ {9, 0, 9, 0, 4},
+ {2, 0, 1, 0, 5},
+ {25, 0, 19, 1, 5},
+ {9, 0, 19, 0, 4},
+ {1, 0, 1, 0, 5},
+ {1, 0, 1, 0, 4},
+ {27, 0, 19, 0, 4},
+ {19, 0, 1, 0, 5},
+ {3, 0, 1, 0, 5},
+ {18, 0, 1, 0, 5},
+ {18, 0, 19, 0, 5},
+ {29, 0, 19, 0, 5},
+ {18, 0, 19, 0, 4},
+ {18, 0, 1, 0, 4},
+ {4, 230, 14, 0, 4},
+ {4, 232, 14, 0, 4},
+ {4, 220, 14, 0, 4},
+ {4, 216, 14, 0, 4},
+ {4, 202, 14, 0, 4},
+ {4, 1, 14, 0, 4},
+ {4, 240, 14, 0, 4},
+ {4, 0, 14, 0, 4},
+ {4, 233, 14, 0, 4},
+ {4, 234, 14, 0, 4},
+ {26, 0, 19, 0, 5},
+ {27, 0, 19, 0, 5},
+ {30, 0, 1, 0, 5},
+ {4, 230, 14, 0, 5},
+ {6, 0, 14, 0, 5},
+ {26, 0, 1, 0, 5},
+ {21, 0, 19, 0, 5},
+ {4, 220, 14, 0, 5},
+ {4, 222, 14, 0, 5},
+ {4, 228, 14, 0, 5},
+ {4, 10, 14, 0, 5},
+ {4, 11, 14, 0, 5},
+ {4, 12, 14, 0, 5},
+ {4, 13, 14, 0, 5},
+ {4, 14, 14, 0, 5},
+ {4, 15, 14, 0, 5},
+ {4, 16, 14, 0, 5},
+ {4, 17, 14, 0, 5},
+ {4, 18, 14, 0, 5},
+ {4, 19, 14, 0, 5},
+ {4, 20, 14, 0, 5},
+ {4, 21, 14, 0, 5},
+ {4, 22, 14, 0, 5},
+ {26, 0, 4, 0, 5},
+ {4, 23, 14, 0, 5},
+ {4, 24, 14, 0, 5},
+ {4, 25, 14, 0, 5},
+ {19, 0, 4, 0, 5},
+ {14, 0, 5, 0, 5},
+ {28, 0, 5, 0, 5},
+ {26, 0, 13, 0, 5},
+ {26, 0, 5, 0, 5},
+ {19, 0, 5, 0, 5},
+ {18, 0, 5, 0, 5},
+ {4, 27, 14, 0, 5},
+ {4, 28, 14, 0, 5},
+ {4, 29, 14, 0, 5},
+ {4, 30, 14, 0, 5},
+ {4, 31, 14, 0, 5},
+ {4, 32, 14, 0, 5},
+ {4, 33, 14, 0, 5},
+ {4, 34, 14, 0, 5},
+ {7, 0, 12, 0, 5},
+ {26, 0, 11, 0, 5},
+ {26, 0, 12, 0, 5},
+ {4, 35, 14, 0, 5},
+ {7, 0, 9, 0, 5},
+ {30, 0, 5, 0, 5},
+ {14, 0, 15, 0, 5},
+ {4, 36, 14, 0, 5},
+ {4, 0, 14, 0, 5},
+ {5, 0, 1, 0, 5},
+ {4, 7, 14, 0, 5},
+ {4, 9, 14, 0, 5},
+ {7, 0, 1, 0, 5},
+ {28, 0, 11, 0, 5},
+ {9, 0, 1, 0, 5},
+ {4, 84, 14, 0, 5},
+ {4, 91, 14, 0, 5},
+ {4, 0, 1, 0, 5},
+ {4, 103, 14, 0, 5},
+ {4, 107, 14, 0, 5},
+ {4, 118, 14, 0, 5},
+ {4, 122, 14, 0, 5},
+ {4, 216, 14, 0, 5},
+ {22, 0, 19, 0, 5},
+ {23, 0, 19, 0, 5},
+ {4, 129, 14, 0, 5},
+ {4, 130, 14, 0, 5},
+ {4, 132, 14, 0, 5},
+ {19, 0, 1, 0, 2},
+ {10, 0, 18, 0, 5},
+ {8, 0, 1, 0, 5},
+ {14, 0, 1, 0, 5},
+ {9, 0, 19, 0, 5},
+ {5, 0, 14, 0, 5},
+ {14, 0, 4, 0, 5},
+ {21, 0, 19, 0, 4},
+ {24, 0, 19, 0, 4},
+ {25, 0, 19, 0, 4},
+ {24, 0, 19, 0, 5},
+ {11, 0, 18, 0, 5},
+ {12, 0, 16, 0, 5},
+ {14, 0, 2, 0, 5},
+ {14, 0, 6, 0, 5},
+ {14, 0, 8, 0, 5},
+ {14, 0, 3, 0, 5},
+ {14, 0, 7, 0, 5},
+ {26, 0, 11, 0, 4},
+ {20, 0, 19, 0, 5},
+ {27, 0, 13, 0, 5},
+ {22, 0, 19, 1, 5},
+ {23, 0, 19, 1, 5},
+ {9, 0, 9, 0, 5},
+ {27, 0, 10, 0, 5},
+ {28, 0, 11, 0, 1},
+ {4, 1, 14, 0, 5},
+ {30, 0, 11, 0, 5},
+ {27, 0, 19, 1, 5},
+ {8, 0, 1, 0, 4},
+ {27, 0, 19, 1, 4},
+ {27, 0, 11, 0, 5},
+ {22, 0, 19, 1, 2},
+ {23, 0, 19, 1, 2},
+ {30, 0, 1, 0, 4},
+ {30, 0, 19, 0, 2},
+ {10, 0, 18, 0, 0},
+ {26, 0, 19, 0, 2},
+ {18, 0, 1, 0, 2},
+ {8, 0, 1, 0, 2},
+ {21, 0, 19, 0, 2},
+ {22, 0, 19, 0, 2},
+ {23, 0, 19, 0, 2},
+ {4, 218, 14, 0, 2},
+ {4, 228, 14, 0, 2},
+ {4, 232, 14, 0, 2},
+ {4, 222, 14, 0, 2},
+ {4, 224, 14, 0, 2},
+ {4, 8, 14, 0, 2},
+ {29, 0, 19, 0, 2},
+ {30, 0, 1, 0, 2},
+ {9, 0, 1, 0, 2},
+ {9, 0, 19, 0, 2},
+ {15, 0, 1, 0, 5},
+ {16, 0, 1, 0, 4},
+ {4, 26, 14, 0, 5},
+ {20, 0, 19, 0, 2},
+ {26, 0, 13, 0, 2},
+ {26, 0, 11, 0, 2},
+ {27, 0, 10, 0, 2},
+ {21, 0, 10, 0, 2},
+ {27, 0, 19, 0, 2},
+ {28, 0, 11, 0, 2},
+ {26, 0, 19, 0, 0},
+ {26, 0, 11, 0, 0},
+ {28, 0, 11, 0, 0},
+ {22, 0, 19, 1, 0},
+ {23, 0, 19, 1, 0},
+ {27, 0, 10, 0, 0},
+ {26, 0, 13, 0, 0},
+ {21, 0, 10, 0, 0},
+ {7, 0, 9, 0, 0},
+ {27, 0, 19, 1, 0},
+ {27, 0, 19, 0, 0},
+ {1, 0, 1, 0, 0},
+ {29, 0, 19, 0, 0},
+ {20, 0, 19, 0, 0},
+ {2, 0, 1, 0, 0},
+ {26, 0, 19, 0, 1},
+ {22, 0, 19, 1, 1},
+ {23, 0, 19, 1, 1},
+ {19, 0, 1, 0, 1},
+ {18, 0, 1, 0, 1},
+ {30, 0, 19, 0, 0},
+ {30, 0, 19, 0, 1},
+ {27, 0, 19, 0, 1},
+ {14, 0, 19, 0, 5},
+ {8, 0, 19, 0, 5},
+ {9, 0, 4, 0, 5},
+ {5, 216, 1, 0, 5},
+ {5, 226, 1, 0, 5},
+ {27, 0, 1, 0, 5},
+};
+
+/* Reindexing of NFC first characters. */
+#define TOTAL_FIRST 356
+#define TOTAL_LAST 53
+struct reindex{int start;short count,index;};
+struct reindex nfc_first[] = {
+ { 60, 2, 0},
+ { 65, 15, 3},
+ { 82, 8, 19},
+ { 97, 15, 28},
+ { 114, 8, 44},
+ { 168, 0, 53},
+ { 194, 0, 54},
+ { 196, 3, 55},
+ { 202, 0, 59},
+ { 207, 0, 60},
+ { 212, 2, 61},
+ { 216, 0, 64},
+ { 220, 0, 65},
+ { 226, 0, 66},
+ { 228, 3, 67},
+ { 234, 0, 71},
+ { 239, 0, 72},
+ { 244, 2, 73},
+ { 248, 0, 76},
+ { 252, 0, 77},
+ { 258, 1, 78},
+ { 274, 1, 80},
+ { 332, 1, 82},
+ { 346, 1, 84},
+ { 352, 1, 86},
+ { 360, 3, 88},
+ { 383, 0, 92},
+ { 416, 1, 93},
+ { 431, 1, 95},
+ { 439, 0, 97},
+ { 490, 1, 98},
+ { 550, 3, 100},
+ { 558, 1, 104},
+ { 658, 0, 106},
+ { 913, 0, 107},
+ { 917, 0, 108},
+ { 919, 0, 109},
+ { 921, 0, 110},
+ { 927, 0, 111},
+ { 929, 0, 112},
+ { 933, 0, 113},
+ { 937, 0, 114},
+ { 940, 0, 115},
+ { 942, 0, 116},
+ { 945, 0, 117},
+ { 949, 0, 118},
+ { 951, 0, 119},
+ { 953, 0, 120},
+ { 959, 0, 121},
+ { 961, 0, 122},
+ { 965, 0, 123},
+ { 969, 2, 124},
+ { 974, 0, 127},
+ { 978, 0, 128},
+ { 1030, 0, 129},
+ { 1040, 0, 130},
+ { 1043, 0, 131},
+ { 1045, 3, 132},
+ { 1050, 0, 136},
+ { 1054, 0, 137},
+ { 1059, 0, 138},
+ { 1063, 0, 139},
+ { 1067, 0, 140},
+ { 1069, 0, 141},
+ { 1072, 0, 142},
+ { 1075, 0, 143},
+ { 1077, 3, 144},
+ { 1082, 0, 148},
+ { 1086, 0, 149},
+ { 1091, 0, 150},
+ { 1095, 0, 151},
+ { 1099, 0, 152},
+ { 1101, 0, 153},
+ { 1110, 0, 154},
+ { 1140, 1, 155},
+ { 1240, 1, 157},
+ { 1256, 1, 159},
+ { 1575, 0, 161},
+ { 1608, 0, 162},
+ { 1610, 0, 163},
+ { 1729, 0, 164},
+ { 1746, 0, 165},
+ { 1749, 0, 166},
+ { 2344, 0, 167},
+ { 2352, 0, 168},
+ { 2355, 0, 169},
+ { 2503, 0, 170},
+ { 2887, 0, 171},
+ { 2962, 0, 172},
+ { 3014, 1, 173},
+ { 3142, 0, 175},
+ { 3263, 0, 176},
+ { 3270, 0, 177},
+ { 3274, 0, 178},
+ { 3398, 1, 179},
+ { 3545, 0, 181},
+ { 3548, 0, 182},
+ { 4133, 0, 183},
+ { 7734, 1, 184},
+ { 7770, 1, 186},
+ { 7778, 1, 188},
+ { 7840, 1, 190},
+ { 7864, 1, 192},
+ { 7884, 1, 194},
+ { 7936, 17, 196},
+ { 7960, 1, 214},
+ { 7968, 17, 216},
+ { 7992, 1, 234},
+ { 8000, 1, 236},
+ { 8008, 1, 238},
+ { 8016, 1, 240},
+ { 8025, 0, 242},
+ { 8032, 16, 243},
+ { 8052, 0, 260},
+ { 8060, 0, 261},
+ { 8118, 0, 262},
+ { 8127, 0, 263},
+ { 8134, 0, 264},
+ { 8182, 0, 265},
+ { 8190, 0, 266},
+ { 8592, 0, 267},
+ { 8594, 0, 268},
+ { 8596, 0, 269},
+ { 8656, 0, 270},
+ { 8658, 0, 271},
+ { 8660, 0, 272},
+ { 8707, 0, 273},
+ { 8712, 0, 274},
+ { 8715, 0, 275},
+ { 8739, 0, 276},
+ { 8741, 0, 277},
+ { 8764, 0, 278},
+ { 8771, 0, 279},
+ { 8773, 0, 280},
+ { 8776, 0, 281},
+ { 8781, 0, 282},
+ { 8801, 0, 283},
+ { 8804, 1, 284},
+ { 8818, 1, 286},
+ { 8822, 1, 288},
+ { 8826, 3, 290},
+ { 8834, 1, 294},
+ { 8838, 1, 296},
+ { 8849, 1, 298},
+ { 8866, 0, 300},
+ { 8872, 1, 301},
+ { 8875, 0, 303},
+ { 8882, 3, 304},
+ { 12358, 0, 308},
+ { 12363, 0, 309},
+ { 12365, 0, 310},
+ { 12367, 0, 311},
+ { 12369, 0, 312},
+ { 12371, 0, 313},
+ { 12373, 0, 314},
+ { 12375, 0, 315},
+ { 12377, 0, 316},
+ { 12379, 0, 317},
+ { 12381, 0, 318},
+ { 12383, 0, 319},
+ { 12385, 0, 320},
+ { 12388, 0, 321},
+ { 12390, 0, 322},
+ { 12392, 0, 323},
+ { 12399, 0, 324},
+ { 12402, 0, 325},
+ { 12405, 0, 326},
+ { 12408, 0, 327},
+ { 12411, 0, 328},
+ { 12445, 0, 329},
+ { 12454, 0, 330},
+ { 12459, 0, 331},
+ { 12461, 0, 332},
+ { 12463, 0, 333},
+ { 12465, 0, 334},
+ { 12467, 0, 335},
+ { 12469, 0, 336},
+ { 12471, 0, 337},
+ { 12473, 0, 338},
+ { 12475, 0, 339},
+ { 12477, 0, 340},
+ { 12479, 0, 341},
+ { 12481, 0, 342},
+ { 12484, 0, 343},
+ { 12486, 0, 344},
+ { 12488, 0, 345},
+ { 12495, 0, 346},
+ { 12498, 0, 347},
+ { 12501, 0, 348},
+ { 12504, 0, 349},
+ { 12507, 0, 350},
+ { 12527, 3, 351},
+ { 12541, 0, 355},
+ {0,0,0}
+};
+
+struct reindex nfc_last[] = {
+ { 768, 4, 0},
+ { 774, 6, 5},
+ { 783, 0, 12},
+ { 785, 0, 13},
+ { 787, 1, 14},
+ { 795, 0, 16},
+ { 803, 5, 17},
+ { 813, 1, 23},
+ { 816, 1, 25},
+ { 824, 0, 27},
+ { 834, 0, 28},
+ { 837, 0, 29},
+ { 1619, 2, 30},
+ { 2364, 0, 33},
+ { 2494, 0, 34},
+ { 2519, 0, 35},
+ { 2878, 0, 36},
+ { 2902, 1, 37},
+ { 3006, 0, 39},
+ { 3031, 0, 40},
+ { 3158, 0, 41},
+ { 3266, 0, 42},
+ { 3285, 1, 43},
+ { 3390, 0, 45},
+ { 3415, 0, 46},
+ { 3530, 0, 47},
+ { 3535, 0, 48},
+ { 3551, 0, 49},
+ { 4142, 0, 50},
+ { 12441, 1, 51},
+ {0,0,0}
+};
+
+/* string literals */
+const char *_PyUnicode_CategoryNames[] = {
+ "Cn",
+ "Lu",
+ "Ll",
+ "Lt",
+ "Mn",
+ "Mc",
+ "Me",
+ "Nd",
+ "Nl",
+ "No",
+ "Zs",
+ "Zl",
+ "Zp",
+ "Cc",
+ "Cf",
+ "Cs",
+ "Co",
+ "Cn",
+ "Lm",
+ "Lo",
+ "Pc",
+ "Pd",
+ "Ps",
+ "Pe",
+ "Pi",
+ "Pf",
+ "Po",
+ "Sm",
+ "Sc",
+ "Sk",
+ "So",
+ NULL
+};
+const char *_PyUnicode_BidirectionalNames[] = {
+ "",
+ "L",
+ "LRE",
+ "LRO",
+ "R",
+ "AL",
+ "RLE",
+ "RLO",
+ "PDF",
+ "EN",
+ "ES",
+ "ET",
+ "AN",
+ "CS",
+ "NSM",
+ "BN",
+ "B",
+ "S",
+ "WS",
+ "ON",
+ NULL
+};
+const char *_PyUnicode_EastAsianWidthNames[] = {
+ "F",
+ "H",
+ "W",
+ "Na",
+ "A",
+ "N",
+ NULL
+};
+static const char *decomp_prefix[] = {
+ "",
+ "<noBreak>",
+ "<compat>",
+ "<super>",
+ "<fraction>",
+ "<sub>",
+ "<font>",
+ "<circle>",
+ "<wide>",
+ "<vertical>",
+ "<square>",
+ "<isolated>",
+ "<final>",
+ "<initial>",
+ "<medial>",
+ "<small>",
+ "<narrow>",
+ NULL
+};
+/* index tables for the database records */
+#define SHIFT 8
+static unsigned char index1[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 8, 8, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 52, 53, 50, 50, 50, 54, 8, 8,
+ 55, 56, 8, 8, 8, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 57, 58, 58, 58, 58, 58, 58,
+ 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 50, 60, 61, 62, 63, 64, 65, 66, 67,
+ 8, 68, 69, 8, 8, 8, 70, 8, 71, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 72, 73, 74, 75, 76, 77, 78,
+ 79, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 80,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 50, 50, 81, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 82, 83, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 84, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 84,
+};
+
+static unsigned char index2[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12,
+ 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 9, 6, 10, 18, 19, 18, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 9, 16, 10, 16, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 8, 8, 23, 8, 24,
+ 25, 26, 27, 28, 29, 16, 30, 25, 18, 31, 32, 33, 33, 26, 34, 25, 22, 26,
+ 33, 28, 35, 36, 36, 36, 22, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 39, 38, 37, 37, 37, 37,
+ 37, 38, 28, 28, 28, 34, 34, 34, 34, 28, 34, 28, 28, 28, 34, 28, 28, 34,
+ 34, 28, 34, 28, 28, 34, 34, 34, 39, 28, 28, 28, 34, 28, 34, 28, 34, 37,
+ 28, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 28, 37,
+ 28, 37, 34, 37, 34, 37, 34, 37, 28, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 38, 28, 37, 34, 37, 28, 37, 34, 37, 34, 37, 28, 38, 28, 37, 34, 37,
+ 34, 28, 37, 34, 37, 34, 37, 34, 38, 28, 38, 28, 37, 28, 37, 34, 37, 28,
+ 28, 38, 28, 37, 28, 37, 34, 37, 34, 38, 28, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 38, 28, 37, 34, 37, 28, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 37, 34, 37, 34, 37, 34,
+ 34, 34, 37, 37, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 37, 37, 37,
+ 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 34, 37, 37, 34, 37, 37, 34, 37,
+ 34, 37, 34, 37, 37, 34, 37, 34, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34,
+ 37, 34, 37, 37, 34, 34, 40, 37, 34, 34, 34, 40, 40, 40, 40, 37, 41, 34,
+ 37, 41, 34, 37, 41, 34, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28,
+ 37, 28, 37, 28, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 34, 37, 41, 34, 37, 34, 37, 37, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 34, 34, 34, 34, 34, 34, 37, 37, 34, 37, 37, 34, 34, 37, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 44, 44, 26, 44, 43,
+ 45, 43, 45, 45, 45, 43, 45, 43, 43, 46, 42, 44, 44, 44, 44, 44, 44, 26,
+ 26, 26, 26, 44, 26, 44, 26, 42, 42, 42, 42, 42, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 42, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 48, 49, 49, 49, 49, 48, 50, 49, 49, 49, 49, 49,
+ 51, 51, 49, 49, 49, 49, 51, 51, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 52, 52, 52, 52, 52, 49, 49, 49, 49, 47, 47, 47, 47, 47, 47, 47, 47,
+ 53, 47, 49, 49, 49, 47, 47, 47, 49, 49, 54, 47, 47, 47, 49, 49, 49, 49,
+ 47, 48, 49, 49, 47, 55, 56, 56, 55, 56, 56, 55, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 44, 44, 0, 0, 0, 0, 42, 0, 0, 0,
+ 57, 0, 0, 0, 0, 0, 44, 44, 37, 57, 37, 37, 37, 0, 37, 0, 37, 37, 34, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 0, 38,
+ 38, 38, 38, 38, 38, 38, 37, 37, 34, 34, 34, 34, 34, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 28, 28, 28, 28, 28,
+ 28, 28, 34, 34, 34, 34, 34, 0, 34, 34, 37, 37, 37, 34, 34, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 34, 34, 34, 34, 37, 34, 58, 37, 34, 37, 37, 34, 34, 37,
+ 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 28, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 59, 60, 60, 60, 60, 0, 61, 61, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 0, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 0, 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 42, 62, 62, 62, 62, 62, 62,
+ 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 0, 62, 63, 0, 0, 0, 0, 0, 0, 64, 60, 60, 60, 60, 64, 60,
+ 60, 60, 65, 64, 60, 60, 60, 60, 60, 60, 64, 64, 64, 64, 64, 64, 60, 60,
+ 64, 60, 60, 65, 66, 60, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 0, 77,
+ 78, 79, 80, 81, 80, 82, 83, 80, 60, 64, 80, 75, 0, 0, 0, 0, 0, 0, 0, 0,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 0, 0, 0, 0, 84, 84, 84, 80, 80, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 86,
+ 87, 88, 27, 27, 60, 60, 60, 60, 60, 60, 0, 0, 0, 0, 0, 88, 0, 0, 88, 88,
+ 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 90, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 91, 92, 93, 94, 95, 96, 97, 98, 60, 60, 64, 64,
+ 60, 60, 60, 60, 60, 64, 60, 60, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 100, 101, 101, 88, 89, 89, 102, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 88, 89, 60, 60, 60, 60, 60, 60, 60, 85, 61, 60, 60, 60, 60, 64, 60, 90,
+ 90, 60, 60, 27, 64, 60, 60, 64, 89, 89, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 89, 89, 89, 104, 104, 89, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 0, 105, 89, 106, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 60, 64, 60, 60, 64, 60, 60, 64, 64, 64, 60, 64, 64,
+ 60, 64, 60, 60, 60, 64, 60, 64, 60, 64, 60, 64, 60, 60, 0, 0, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 107, 107, 108, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 109, 40, 108, 108, 108, 107,
+ 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 110, 0, 0, 40, 60,
+ 64, 60, 60, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 107, 107,
+ 62, 62, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 107, 108, 108, 0, 40, 40, 40, 40,
+ 40, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40,
+ 40, 40, 40, 0, 40, 0, 0, 0, 40, 40, 40, 40, 0, 0, 109, 40, 108, 108, 108,
+ 107, 107, 107, 107, 0, 0, 108, 108, 0, 0, 108, 108, 110, 40, 0, 0, 0, 0,
+ 0, 0, 0, 0, 108, 0, 0, 0, 0, 40, 40, 0, 40, 40, 40, 107, 107, 0, 0, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 40, 40, 112, 112, 113, 113,
+ 113, 113, 113, 113, 59, 0, 0, 0, 0, 0, 0, 107, 107, 108, 0, 40, 40, 40,
+ 40, 40, 40, 0, 0, 0, 0, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40,
+ 40, 40, 40, 0, 40, 40, 0, 40, 40, 0, 40, 40, 0, 0, 109, 0, 108, 108, 108,
+ 107, 107, 0, 0, 0, 0, 107, 107, 0, 0, 107, 107, 110, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 40, 40, 40, 40, 0, 40, 0, 0, 0, 0, 0, 0, 0, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 107, 107, 40, 40, 40, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 107, 107, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40,
+ 40, 0, 40, 40, 40, 40, 40, 0, 0, 109, 40, 108, 108, 108, 107, 107, 107,
+ 107, 107, 0, 107, 107, 108, 0, 108, 108, 110, 0, 0, 40, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 107, 107, 0, 0, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 107, 108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40,
+ 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40,
+ 40, 40, 40, 0, 0, 109, 40, 108, 107, 108, 107, 107, 107, 0, 0, 0, 108,
+ 108, 0, 0, 108, 108, 110, 0, 0, 0, 0, 0, 0, 0, 0, 107, 108, 0, 0, 0, 0,
+ 40, 40, 0, 40, 40, 40, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 59, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 107, 40, 0, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 40, 0, 40, 40, 40,
+ 40, 0, 0, 0, 40, 40, 0, 40, 0, 40, 40, 0, 0, 0, 40, 40, 0, 0, 0, 40, 40,
+ 40, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0,
+ 108, 108, 107, 108, 108, 0, 0, 0, 108, 108, 108, 0, 108, 108, 108, 110,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 113, 113, 113, 27, 27,
+ 27, 27, 27, 27, 112, 27, 0, 0, 0, 0, 0, 0, 108, 108, 108, 0, 40, 40, 40,
+ 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 0, 0, 107, 107,
+ 107, 108, 108, 108, 108, 0, 107, 107, 107, 0, 107, 107, 107, 110, 0, 0,
+ 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0, 0,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 108, 0, 40, 40, 40, 40, 40, 40, 40,
+ 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 109, 40, 108, 116, 108, 108,
+ 108, 108, 108, 0, 116, 108, 108, 0, 108, 108, 107, 110, 0, 0, 0, 0, 0, 0,
+ 0, 108, 108, 0, 0, 0, 0, 0, 0, 0, 40, 0, 40, 40, 0, 0, 0, 0, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40,
+ 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 108, 108, 108, 107, 107, 107, 0,
+ 0, 108, 108, 108, 0, 108, 108, 108, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 108, 108, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 0, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 110, 0, 0,
+ 0, 0, 108, 108, 108, 107, 107, 107, 0, 107, 0, 108, 108, 108, 108, 108,
+ 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108,
+ 108, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 107, 40, 40, 107, 107, 107, 107, 117, 117, 110, 0, 0,
+ 0, 0, 112, 40, 40, 40, 40, 40, 40, 42, 107, 118, 118, 118, 118, 107, 107,
+ 107, 62, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 62, 62, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 40, 0, 0, 40, 40, 0, 40, 0,
+ 0, 40, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40,
+ 0, 40, 40, 40, 0, 40, 0, 40, 0, 0, 40, 40, 0, 40, 40, 40, 40, 107, 40,
+ 40, 107, 107, 107, 107, 119, 119, 0, 107, 107, 40, 0, 0, 40, 40, 40, 40,
+ 40, 0, 42, 0, 120, 120, 120, 120, 107, 107, 0, 0, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 0, 0, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 40, 59, 59, 59, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 59, 59, 59, 59, 59, 64, 64, 59, 59, 59, 59, 59, 59, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 59, 64, 59, 64, 59, 121, 122, 123, 122, 123, 108, 108, 40,
+ 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 124, 125, 107, 126, 107, 107,
+ 107, 107, 107, 125, 125, 125, 125, 107, 108, 125, 107, 60, 60, 110, 62,
+ 60, 60, 40, 40, 40, 40, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107,
+ 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 59, 59, 59, 59, 59, 59,
+ 59, 59, 64, 59, 59, 59, 59, 59, 59, 0, 0, 59, 62, 62, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 40, 40,
+ 0, 108, 107, 107, 107, 107, 108, 107, 0, 0, 0, 107, 109, 108, 110, 0, 0,
+ 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 62, 62, 62,
+ 62, 62, 62, 40, 40, 40, 40, 40, 40, 108, 108, 107, 107, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, 42, 0, 0, 0, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 0, 0, 0, 0, 0, 127, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40,
+ 0, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0,
+ 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40,
+ 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 0, 40, 40, 40, 40,
+ 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 0, 0, 0, 0, 60, 59, 62, 62, 62, 62, 62, 62, 62, 62, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0,
+ 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, 62, 40, 40, 40, 40,
+ 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 122, 123, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, 62, 62, 129, 129, 129, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 107, 107, 110, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 107, 107, 110, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 107, 107,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 0, 40, 40, 40, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 130,
+ 130, 108, 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 108,
+ 108, 108, 108, 107, 108, 108, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 110, 107, 62, 62, 62, 42, 62, 62, 62, 112, 40, 60, 0, 0, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 57, 57, 57, 57, 57,
+ 57, 63, 57, 57, 57, 57, 107, 107, 107, 128, 0, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 0, 0, 0, 107, 107, 107, 108, 108, 108, 108, 107,
+ 107, 132, 132, 132, 0, 0, 0, 0, 108, 108, 107, 108, 108, 108, 108, 108,
+ 108, 65, 60, 64, 0, 0, 0, 0, 27, 0, 0, 0, 57, 57, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 0, 0, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 108, 108, 108, 108, 108, 108, 108, 108,
+ 108, 108, 108, 108, 108, 108, 108, 108, 108, 40, 40, 40, 40, 40, 40, 40,
+ 108, 108, 0, 0, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 0, 0, 0, 0, 57, 57, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 60, 64, 108, 108, 108, 0, 0, 62, 62, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 60, 60,
+ 64, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 34,
+ 34, 34, 34, 34, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37,
+ 34, 37, 34, 37, 34, 37, 34, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34,
+ 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37,
+ 37, 37, 37, 37, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37,
+ 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37,
+ 37, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, 0, 0, 34, 34,
+ 34, 34, 34, 34, 34, 34, 0, 37, 0, 37, 0, 37, 0, 37, 34, 34, 34, 34, 34,
+ 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41,
+ 41, 41, 41, 41, 41, 41, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41,
+ 41, 41, 41, 41, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41,
+ 41, 41, 34, 34, 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 34, 44,
+ 44, 44, 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 44, 44, 34, 34,
+ 34, 34, 0, 0, 34, 34, 37, 37, 37, 37, 0, 44, 44, 44, 34, 34, 34, 34, 34,
+ 34, 34, 34, 37, 37, 37, 37, 37, 44, 44, 44, 0, 0, 34, 34, 34, 0, 34, 34,
+ 37, 37, 37, 37, 41, 44, 44, 0, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 105, 105, 105, 130, 133, 134, 63, 63, 134, 134, 134, 22,
+ 57, 135, 136, 122, 137, 135, 136, 122, 137, 22, 22, 22, 57, 22, 22, 22,
+ 22, 138, 139, 140, 141, 142, 143, 144, 21, 145, 100, 145, 145, 100, 22,
+ 57, 57, 57, 29, 35, 22, 57, 57, 22, 146, 146, 57, 57, 57, 147, 148, 149,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 57, 146, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 128, 105, 105, 105, 105, 0, 0, 0, 0, 0, 0, 105,
+ 105, 105, 105, 105, 105, 150, 34, 0, 0, 33, 150, 150, 150, 150, 150, 151,
+ 151, 58, 148, 149, 28, 150, 33, 33, 33, 33, 150, 150, 150, 150, 150, 151,
+ 151, 58, 148, 149, 0, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 112, 112, 112, 112, 112, 112, 112, 112, 112, 152, 112, 112, 23, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 153, 153, 60, 60,
+ 60, 60, 153, 153, 153, 60, 60, 61, 61, 61, 61, 60, 61, 61, 61, 153, 153,
+ 60, 64, 60, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 27, 27, 37, 25, 27, 25, 27, 37, 27, 25, 34, 37, 37, 37, 34, 34,
+ 37, 37, 37, 28, 27, 37, 25, 27, 27, 37, 37, 37, 37, 37, 27, 27, 27, 25,
+ 25, 27, 37, 27, 38, 27, 37, 27, 37, 38, 37, 37, 154, 34, 37, 37, 27, 37,
+ 34, 40, 40, 40, 40, 34, 27, 27, 34, 34, 37, 37, 155, 58, 58, 58, 58, 37,
+ 34, 34, 34, 34, 27, 58, 27, 0, 0, 0, 0, 0, 0, 36, 36, 131, 131, 131, 131,
+ 131, 131, 36, 36, 36, 36, 131, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 129, 129, 129, 129, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 25, 25, 25, 25, 25,
+ 58, 58, 27, 27, 27, 27, 58, 27, 27, 58, 27, 27, 58, 27, 27, 27, 27, 27,
+ 27, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58,
+ 27, 27, 39, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 39, 155, 157, 157, 155,
+ 58, 58, 39, 157, 155, 155, 157, 155, 155, 58, 39, 58, 157, 151, 158, 58,
+ 157, 155, 58, 58, 58, 157, 155, 155, 157, 39, 157, 157, 155, 155, 39,
+ 155, 39, 155, 39, 39, 39, 39, 157, 157, 155, 157, 155, 155, 155, 155,
+ 155, 39, 39, 39, 39, 58, 155, 58, 155, 157, 157, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 157, 155, 155, 155, 157, 58, 58, 58, 58, 58,
+ 157, 155, 155, 155, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 157, 39,
+ 155, 58, 157, 157, 157, 157, 155, 155, 157, 157, 58, 58, 157, 157, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 157, 157, 155, 155, 157, 157, 155, 155, 155, 155, 155, 58,
+ 58, 155, 155, 155, 155, 58, 58, 39, 58, 58, 155, 39, 58, 58, 58, 58, 58,
+ 58, 58, 58, 155, 155, 58, 39, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 58, 58, 58, 58,
+ 58, 155, 157, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 155, 155,
+ 155, 58, 58, 155, 155, 58, 58, 58, 58, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 58, 58, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 27, 27, 27, 27, 27, 27, 27, 27, 155, 155,
+ 155, 155, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 155, 155, 27, 27, 27, 27, 27, 27, 27, 159, 160, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, 27,
+ 27, 27, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 122, 123, 57, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 131, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25,
+ 27, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25,
+ 27, 27, 25, 39, 27, 27, 27, 27, 25, 25, 27, 27, 25, 39, 27, 27, 27, 27,
+ 25, 25, 25, 27, 27, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58,
+ 58, 58, 58, 58, 27, 27, 27, 27, 27, 25, 25, 27, 27, 25, 27, 27, 27, 27,
+ 25, 25, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 27, 27, 25, 27, 25, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 25, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 25, 25, 25, 27, 25,
+ 25, 25, 25, 27, 25, 25, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0,
+ 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, 27, 27,
+ 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 0, 27, 27, 27, 27, 0, 0, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 0, 27, 27, 27, 27, 0, 0, 0, 27, 0,
+ 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 148, 149,
+ 148, 149, 148, 149, 148, 149, 148, 149, 148, 149, 148, 149, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 131, 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 27, 0, 0, 0, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 0, 155, 58, 58, 155, 155, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 58, 58, 58, 155, 155, 155, 155, 58, 58, 58, 58, 58, 155, 155, 155, 58,
+ 58, 58, 155, 155, 155, 155, 9, 10, 9, 10, 9, 10, 0, 0, 0, 0, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 148, 149, 9, 10, 148, 149, 148, 149, 148, 149, 148, 149,
+ 148, 149, 148, 149, 148, 149, 148, 149, 148, 149, 58, 58, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 58, 58, 58, 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
+ 58, 58, 58, 155, 155, 155, 155, 155, 155, 58, 58, 58, 155, 58, 58, 58,
+ 58, 155, 155, 155, 155, 155, 58, 155, 155, 58, 58, 148, 149, 148, 149,
+ 155, 58, 58, 58, 58, 155, 58, 155, 155, 155, 58, 58, 155, 155, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 155, 155, 155, 155, 58, 58,
+ 148, 149, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 58, 155, 155, 155, 155, 58, 58, 155, 58, 155, 58, 58, 155, 58,
+ 155, 155, 155, 155, 58, 58, 58, 58, 58, 155, 155, 58, 58, 58, 58, 58, 58,
+ 155, 155, 155, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 155, 155, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 155, 155, 58, 58, 58, 58, 155, 155, 155, 155, 58,
+ 155, 155, 58, 58, 155, 155, 58, 58, 58, 58, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 58, 58, 155, 155, 155, 155,
+ 155, 155, 155, 155, 58, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 58, 58, 58, 58, 58, 155, 58, 155, 58, 58, 58, 155, 155, 155,
+ 155, 155, 58, 58, 58, 58, 58, 155, 155, 155, 58, 58, 58, 58, 155, 58, 58,
+ 58, 155, 155, 155, 155, 155, 58, 155, 58, 58, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34,
+ 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 27, 27, 27,
+ 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 57, 57, 57,
+ 131, 57, 57, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40,
+ 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40,
+ 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40,
+ 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 57, 57, 29, 35, 29, 35, 57, 57, 57, 29, 35, 57, 29, 35, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 63, 0, 0, 0, 0, 29, 35, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 0, 0, 0, 0, 163, 164, 164, 164,
+ 162, 165, 127, 166, 159, 160, 159, 160, 159, 160, 159, 160, 159, 160,
+ 162, 162, 159, 160, 159, 160, 159, 160, 159, 160, 167, 168, 169, 169,
+ 162, 166, 166, 166, 166, 166, 166, 166, 166, 166, 170, 171, 172, 173,
+ 174, 174, 167, 165, 165, 165, 165, 165, 162, 162, 166, 166, 166, 165,
+ 127, 164, 162, 27, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 0, 0, 175, 175, 176, 176, 165, 165, 127,
+ 167, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 164, 165, 165, 165, 127, 0, 0, 0, 0,
+ 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 177, 177, 178, 178,
+ 178, 178, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 162, 162, 0, 178, 178, 178, 178, 178,
+ 178, 178, 178, 178, 178, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 179, 179, 179,
+ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 162, 162,
+ 162, 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 179, 179, 179, 179, 179,
+ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 162, 162, 162, 162, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 162, 162, 162, 162,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 162, 162, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 162, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 165, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 0, 0, 0, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 132, 40, 40, 40, 110,
+ 40, 40, 40, 40, 107, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 108, 108, 107, 107, 108, 27, 27,
+ 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34,
+ 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34,
+ 34, 0, 0, 0, 0, 0, 84, 182, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 151,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 84, 84, 84, 84,
+ 84, 0, 84, 0, 84, 84, 0, 84, 84, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 122, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 0, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 86, 27, 0, 0, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 164, 164,
+ 164, 164, 164, 164, 164, 168, 169, 164, 0, 0, 0, 0, 0, 0, 60, 60, 60, 60,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 167, 167, 183, 183, 168, 169,
+ 168, 169, 168, 169, 168, 169, 168, 169, 168, 169, 168, 169, 168, 169,
+ 164, 164, 168, 169, 164, 164, 164, 164, 183, 183, 183, 184, 164, 184, 0,
+ 164, 184, 164, 164, 167, 168, 169, 168, 169, 168, 169, 185, 164, 164,
+ 186, 187, 188, 188, 188, 0, 164, 189, 185, 164, 0, 0, 0, 0, 89, 89, 89,
+ 89, 89, 0, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 0, 0, 105, 0, 190, 190,
+ 191, 192, 191, 190, 190, 193, 194, 190, 195, 196, 197, 196, 196, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 196, 190, 199, 200, 199,
+ 190, 190, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 193, 190, 194, 202, 203, 202, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 193, 200, 194, 200, 193, 194, 205, 206, 207, 205,
+ 205, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, 208, 208,
+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+ 208, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+ 208, 208, 208, 208, 208, 208, 0, 0, 0, 208, 208, 208, 208, 208, 208, 0,
+ 0, 208, 208, 208, 208, 208, 208, 0, 0, 208, 208, 208, 208, 208, 208, 0,
+ 0, 208, 208, 208, 0, 0, 0, 192, 192, 200, 202, 210, 192, 192, 0, 211,
+ 212, 212, 212, 212, 211, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 213,
+ 213, 27, 25, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 62, 57, 59, 0, 0,
+ 0, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 131, 131, 131, 131, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 131, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 113, 113, 113, 113, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 129, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 62, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0,
+ 40, 40, 40, 40, 40, 40, 40, 40, 59, 214, 214, 214, 214, 214, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 84, 84, 84, 84,
+ 84, 0, 0, 84, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 84, 84, 0, 0, 0, 84,
+ 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 84, 107, 107, 107, 0, 107, 107, 0, 0, 0, 0, 0, 107, 64, 107, 60,
+ 84, 84, 84, 84, 0, 84, 84, 84, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, 0,
+ 0, 0, 60, 153, 64, 0, 0, 0, 0, 110, 215, 215, 215, 215, 215, 215, 215,
+ 215, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 216, 216, 153, 153, 153, 59, 59, 59, 217,
+ 216, 216, 216, 216, 216, 105, 105, 105, 105, 105, 105, 105, 105, 64, 64,
+ 64, 64, 64, 64, 64, 64, 59, 59, 60, 60, 60, 60, 60, 64, 64, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 60, 60, 60, 27, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 0,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 0,
+ 37, 37, 0, 0, 37, 0, 0, 37, 37, 0, 0, 37, 37, 37, 37, 0, 37, 37, 37, 37,
+ 37, 37, 37, 37, 34, 34, 34, 34, 0, 34, 0, 34, 34, 34, 34, 34, 34, 34, 0,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 0, 37, 37, 37, 37, 0, 0, 37,
+ 37, 37, 37, 37, 37, 37, 37, 0, 37, 37, 37, 37, 37, 37, 37, 0, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 37, 37, 0, 37, 37, 37, 37, 0, 37, 37, 37, 37, 37, 0,
+ 37, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 218,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 218, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 218, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 218, 34, 34, 34, 34, 34, 34,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 218, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 218, 34, 34,
+ 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 218, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 218, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 218, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 218, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 0, 0,
+};
+
+/* decomposition data */
+static unsigned int decomp_data[] = {
+ 0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514,
+ 32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52,
+ 772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512,
+ 65, 770, 512, 65, 771, 512, 65, 776, 512, 65, 778, 512, 67, 807, 512, 69,
+ 768, 512, 69, 769, 512, 69, 770, 512, 69, 776, 512, 73, 768, 512, 73,
+ 769, 512, 73, 770, 512, 73, 776, 512, 78, 771, 512, 79, 768, 512, 79,
+ 769, 512, 79, 770, 512, 79, 771, 512, 79, 776, 512, 85, 768, 512, 85,
+ 769, 512, 85, 770, 512, 85, 776, 512, 89, 769, 512, 97, 768, 512, 97,
+ 769, 512, 97, 770, 512, 97, 771, 512, 97, 776, 512, 97, 778, 512, 99,
+ 807, 512, 101, 768, 512, 101, 769, 512, 101, 770, 512, 101, 776, 512,
+ 105, 768, 512, 105, 769, 512, 105, 770, 512, 105, 776, 512, 110, 771,
+ 512, 111, 768, 512, 111, 769, 512, 111, 770, 512, 111, 771, 512, 111,
+ 776, 512, 117, 768, 512, 117, 769, 512, 117, 770, 512, 117, 776, 512,
+ 121, 769, 512, 121, 776, 512, 65, 772, 512, 97, 772, 512, 65, 774, 512,
+ 97, 774, 512, 65, 808, 512, 97, 808, 512, 67, 769, 512, 99, 769, 512, 67,
+ 770, 512, 99, 770, 512, 67, 775, 512, 99, 775, 512, 67, 780, 512, 99,
+ 780, 512, 68, 780, 512, 100, 780, 512, 69, 772, 512, 101, 772, 512, 69,
+ 774, 512, 101, 774, 512, 69, 775, 512, 101, 775, 512, 69, 808, 512, 101,
+ 808, 512, 69, 780, 512, 101, 780, 512, 71, 770, 512, 103, 770, 512, 71,
+ 774, 512, 103, 774, 512, 71, 775, 512, 103, 775, 512, 71, 807, 512, 103,
+ 807, 512, 72, 770, 512, 104, 770, 512, 73, 771, 512, 105, 771, 512, 73,
+ 772, 512, 105, 772, 512, 73, 774, 512, 105, 774, 512, 73, 808, 512, 105,
+ 808, 512, 73, 775, 514, 73, 74, 514, 105, 106, 512, 74, 770, 512, 106,
+ 770, 512, 75, 807, 512, 107, 807, 512, 76, 769, 512, 108, 769, 512, 76,
+ 807, 512, 108, 807, 512, 76, 780, 512, 108, 780, 514, 76, 183, 514, 108,
+ 183, 512, 78, 769, 512, 110, 769, 512, 78, 807, 512, 110, 807, 512, 78,
+ 780, 512, 110, 780, 514, 700, 110, 512, 79, 772, 512, 111, 772, 512, 79,
+ 774, 512, 111, 774, 512, 79, 779, 512, 111, 779, 512, 82, 769, 512, 114,
+ 769, 512, 82, 807, 512, 114, 807, 512, 82, 780, 512, 114, 780, 512, 83,
+ 769, 512, 115, 769, 512, 83, 770, 512, 115, 770, 512, 83, 807, 512, 115,
+ 807, 512, 83, 780, 512, 115, 780, 512, 84, 807, 512, 116, 807, 512, 84,
+ 780, 512, 116, 780, 512, 85, 771, 512, 117, 771, 512, 85, 772, 512, 117,
+ 772, 512, 85, 774, 512, 117, 774, 512, 85, 778, 512, 117, 778, 512, 85,
+ 779, 512, 117, 779, 512, 85, 808, 512, 117, 808, 512, 87, 770, 512, 119,
+ 770, 512, 89, 770, 512, 121, 770, 512, 89, 776, 512, 90, 769, 512, 122,
+ 769, 512, 90, 775, 512, 122, 775, 512, 90, 780, 512, 122, 780, 258, 115,
+ 512, 79, 795, 512, 111, 795, 512, 85, 795, 512, 117, 795, 514, 68, 381,
+ 514, 68, 382, 514, 100, 382, 514, 76, 74, 514, 76, 106, 514, 108, 106,
+ 514, 78, 74, 514, 78, 106, 514, 110, 106, 512, 65, 780, 512, 97, 780,
+ 512, 73, 780, 512, 105, 780, 512, 79, 780, 512, 111, 780, 512, 85, 780,
+ 512, 117, 780, 512, 220, 772, 512, 252, 772, 512, 220, 769, 512, 252,
+ 769, 512, 220, 780, 512, 252, 780, 512, 220, 768, 512, 252, 768, 512,
+ 196, 772, 512, 228, 772, 512, 550, 772, 512, 551, 772, 512, 198, 772,
+ 512, 230, 772, 512, 71, 780, 512, 103, 780, 512, 75, 780, 512, 107, 780,
+ 512, 79, 808, 512, 111, 808, 512, 490, 772, 512, 491, 772, 512, 439, 780,
+ 512, 658, 780, 512, 106, 780, 514, 68, 90, 514, 68, 122, 514, 100, 122,
+ 512, 71, 769, 512, 103, 769, 512, 78, 768, 512, 110, 768, 512, 197, 769,
+ 512, 229, 769, 512, 198, 769, 512, 230, 769, 512, 216, 769, 512, 248,
+ 769, 512, 65, 783, 512, 97, 783, 512, 65, 785, 512, 97, 785, 512, 69,
+ 783, 512, 101, 783, 512, 69, 785, 512, 101, 785, 512, 73, 783, 512, 105,
+ 783, 512, 73, 785, 512, 105, 785, 512, 79, 783, 512, 111, 783, 512, 79,
+ 785, 512, 111, 785, 512, 82, 783, 512, 114, 783, 512, 82, 785, 512, 114,
+ 785, 512, 85, 783, 512, 117, 783, 512, 85, 785, 512, 117, 785, 512, 83,
+ 806, 512, 115, 806, 512, 84, 806, 512, 116, 806, 512, 72, 780, 512, 104,
+ 780, 512, 65, 775, 512, 97, 775, 512, 69, 807, 512, 101, 807, 512, 214,
+ 772, 512, 246, 772, 512, 213, 772, 512, 245, 772, 512, 79, 775, 512, 111,
+ 775, 512, 558, 772, 512, 559, 772, 512, 89, 772, 512, 121, 772, 259, 104,
+ 259, 614, 259, 106, 259, 114, 259, 633, 259, 635, 259, 641, 259, 119,
+ 259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514,
+ 32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661,
+ 256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256,
+ 59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769,
+ 512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937,
+ 769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512,
+ 949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776,
+ 512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946,
+ 258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960,
+ 258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045,
+ 768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512,
+ 1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077,
+ 768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512,
+ 1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046,
+ 774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512,
+ 1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241,
+ 776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512,
+ 1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054,
+ 776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512,
+ 1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091,
+ 776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512,
+ 1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575,
+ 1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652,
+ 514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512,
+ 1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355,
+ 2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364,
+ 512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512,
+ 2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479,
+ 2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620,
+ 512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512,
+ 2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014,
+ 3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285,
+ 512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512,
+ 3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545,
+ 3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762,
+ 514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916,
+ 4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021,
+ 512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512,
+ 4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996,
+ 4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021,
+ 512, 4133, 4142, 259, 4316, 259, 65, 259, 198, 259, 66, 259, 68, 259, 69,
+ 259, 398, 259, 71, 259, 72, 259, 73, 259, 74, 259, 75, 259, 76, 259, 77,
+ 259, 78, 259, 79, 259, 546, 259, 80, 259, 82, 259, 84, 259, 85, 259, 87,
+ 259, 97, 259, 592, 259, 593, 259, 7426, 259, 98, 259, 100, 259, 101, 259,
+ 601, 259, 603, 259, 604, 259, 103, 259, 107, 259, 109, 259, 331, 259,
+ 111, 259, 596, 259, 7446, 259, 7447, 259, 112, 259, 116, 259, 117, 259,
+ 7453, 259, 623, 259, 118, 259, 7461, 259, 946, 259, 947, 259, 948, 259,
+ 966, 259, 967, 261, 105, 261, 114, 261, 117, 261, 118, 261, 946, 261,
+ 947, 261, 961, 261, 966, 261, 967, 259, 1085, 259, 594, 259, 99, 259,
+ 597, 259, 240, 259, 604, 259, 102, 259, 607, 259, 609, 259, 613, 259,
+ 616, 259, 617, 259, 618, 259, 7547, 259, 669, 259, 621, 259, 7557, 259,
+ 671, 259, 625, 259, 624, 259, 626, 259, 627, 259, 628, 259, 629, 259,
+ 632, 259, 642, 259, 643, 259, 427, 259, 649, 259, 650, 259, 7452, 259,
+ 651, 259, 652, 259, 122, 259, 656, 259, 657, 259, 658, 259, 952, 512, 65,
+ 805, 512, 97, 805, 512, 66, 775, 512, 98, 775, 512, 66, 803, 512, 98,
+ 803, 512, 66, 817, 512, 98, 817, 512, 199, 769, 512, 231, 769, 512, 68,
+ 775, 512, 100, 775, 512, 68, 803, 512, 100, 803, 512, 68, 817, 512, 100,
+ 817, 512, 68, 807, 512, 100, 807, 512, 68, 813, 512, 100, 813, 512, 274,
+ 768, 512, 275, 768, 512, 274, 769, 512, 275, 769, 512, 69, 813, 512, 101,
+ 813, 512, 69, 816, 512, 101, 816, 512, 552, 774, 512, 553, 774, 512, 70,
+ 775, 512, 102, 775, 512, 71, 772, 512, 103, 772, 512, 72, 775, 512, 104,
+ 775, 512, 72, 803, 512, 104, 803, 512, 72, 776, 512, 104, 776, 512, 72,
+ 807, 512, 104, 807, 512, 72, 814, 512, 104, 814, 512, 73, 816, 512, 105,
+ 816, 512, 207, 769, 512, 239, 769, 512, 75, 769, 512, 107, 769, 512, 75,
+ 803, 512, 107, 803, 512, 75, 817, 512, 107, 817, 512, 76, 803, 512, 108,
+ 803, 512, 7734, 772, 512, 7735, 772, 512, 76, 817, 512, 108, 817, 512,
+ 76, 813, 512, 108, 813, 512, 77, 769, 512, 109, 769, 512, 77, 775, 512,
+ 109, 775, 512, 77, 803, 512, 109, 803, 512, 78, 775, 512, 110, 775, 512,
+ 78, 803, 512, 110, 803, 512, 78, 817, 512, 110, 817, 512, 78, 813, 512,
+ 110, 813, 512, 213, 769, 512, 245, 769, 512, 213, 776, 512, 245, 776,
+ 512, 332, 768, 512, 333, 768, 512, 332, 769, 512, 333, 769, 512, 80, 769,
+ 512, 112, 769, 512, 80, 775, 512, 112, 775, 512, 82, 775, 512, 114, 775,
+ 512, 82, 803, 512, 114, 803, 512, 7770, 772, 512, 7771, 772, 512, 82,
+ 817, 512, 114, 817, 512, 83, 775, 512, 115, 775, 512, 83, 803, 512, 115,
+ 803, 512, 346, 775, 512, 347, 775, 512, 352, 775, 512, 353, 775, 512,
+ 7778, 775, 512, 7779, 775, 512, 84, 775, 512, 116, 775, 512, 84, 803,
+ 512, 116, 803, 512, 84, 817, 512, 116, 817, 512, 84, 813, 512, 116, 813,
+ 512, 85, 804, 512, 117, 804, 512, 85, 816, 512, 117, 816, 512, 85, 813,
+ 512, 117, 813, 512, 360, 769, 512, 361, 769, 512, 362, 776, 512, 363,
+ 776, 512, 86, 771, 512, 118, 771, 512, 86, 803, 512, 118, 803, 512, 87,
+ 768, 512, 119, 768, 512, 87, 769, 512, 119, 769, 512, 87, 776, 512, 119,
+ 776, 512, 87, 775, 512, 119, 775, 512, 87, 803, 512, 119, 803, 512, 88,
+ 775, 512, 120, 775, 512, 88, 776, 512, 120, 776, 512, 89, 775, 512, 121,
+ 775, 512, 90, 770, 512, 122, 770, 512, 90, 803, 512, 122, 803, 512, 90,
+ 817, 512, 122, 817, 512, 104, 817, 512, 116, 776, 512, 119, 778, 512,
+ 121, 778, 514, 97, 702, 512, 383, 775, 512, 65, 803, 512, 97, 803, 512,
+ 65, 777, 512, 97, 777, 512, 194, 769, 512, 226, 769, 512, 194, 768, 512,
+ 226, 768, 512, 194, 777, 512, 226, 777, 512, 194, 771, 512, 226, 771,
+ 512, 7840, 770, 512, 7841, 770, 512, 258, 769, 512, 259, 769, 512, 258,
+ 768, 512, 259, 768, 512, 258, 777, 512, 259, 777, 512, 258, 771, 512,
+ 259, 771, 512, 7840, 774, 512, 7841, 774, 512, 69, 803, 512, 101, 803,
+ 512, 69, 777, 512, 101, 777, 512, 69, 771, 512, 101, 771, 512, 202, 769,
+ 512, 234, 769, 512, 202, 768, 512, 234, 768, 512, 202, 777, 512, 234,
+ 777, 512, 202, 771, 512, 234, 771, 512, 7864, 770, 512, 7865, 770, 512,
+ 73, 777, 512, 105, 777, 512, 73, 803, 512, 105, 803, 512, 79, 803, 512,
+ 111, 803, 512, 79, 777, 512, 111, 777, 512, 212, 769, 512, 244, 769, 512,
+ 212, 768, 512, 244, 768, 512, 212, 777, 512, 244, 777, 512, 212, 771,
+ 512, 244, 771, 512, 7884, 770, 512, 7885, 770, 512, 416, 769, 512, 417,
+ 769, 512, 416, 768, 512, 417, 768, 512, 416, 777, 512, 417, 777, 512,
+ 416, 771, 512, 417, 771, 512, 416, 803, 512, 417, 803, 512, 85, 803, 512,
+ 117, 803, 512, 85, 777, 512, 117, 777, 512, 431, 769, 512, 432, 769, 512,
+ 431, 768, 512, 432, 768, 512, 431, 777, 512, 432, 777, 512, 431, 771,
+ 512, 432, 771, 512, 431, 803, 512, 432, 803, 512, 89, 768, 512, 121, 768,
+ 512, 89, 803, 512, 121, 803, 512, 89, 777, 512, 121, 777, 512, 89, 771,
+ 512, 121, 771, 512, 945, 787, 512, 945, 788, 512, 7936, 768, 512, 7937,
+ 768, 512, 7936, 769, 512, 7937, 769, 512, 7936, 834, 512, 7937, 834, 512,
+ 913, 787, 512, 913, 788, 512, 7944, 768, 512, 7945, 768, 512, 7944, 769,
+ 512, 7945, 769, 512, 7944, 834, 512, 7945, 834, 512, 949, 787, 512, 949,
+ 788, 512, 7952, 768, 512, 7953, 768, 512, 7952, 769, 512, 7953, 769, 512,
+ 917, 787, 512, 917, 788, 512, 7960, 768, 512, 7961, 768, 512, 7960, 769,
+ 512, 7961, 769, 512, 951, 787, 512, 951, 788, 512, 7968, 768, 512, 7969,
+ 768, 512, 7968, 769, 512, 7969, 769, 512, 7968, 834, 512, 7969, 834, 512,
+ 919, 787, 512, 919, 788, 512, 7976, 768, 512, 7977, 768, 512, 7976, 769,
+ 512, 7977, 769, 512, 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953,
+ 788, 512, 7984, 768, 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512,
+ 7984, 834, 512, 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768,
+ 512, 7993, 768, 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512,
+ 7993, 834, 512, 959, 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768,
+ 512, 8000, 769, 512, 8001, 769, 512, 927, 787, 512, 927, 788, 512, 8008,
+ 768, 512, 8009, 768, 512, 8008, 769, 512, 8009, 769, 512, 965, 787, 512,
+ 965, 788, 512, 8016, 768, 512, 8017, 768, 512, 8016, 769, 512, 8017, 769,
+ 512, 8016, 834, 512, 8017, 834, 512, 933, 788, 512, 8025, 768, 512, 8025,
+ 769, 512, 8025, 834, 512, 969, 787, 512, 969, 788, 512, 8032, 768, 512,
+ 8033, 768, 512, 8032, 769, 512, 8033, 769, 512, 8032, 834, 512, 8033,
+ 834, 512, 937, 787, 512, 937, 788, 512, 8040, 768, 512, 8041, 768, 512,
+ 8040, 769, 512, 8041, 769, 512, 8040, 834, 512, 8041, 834, 512, 945, 768,
+ 256, 940, 512, 949, 768, 256, 941, 512, 951, 768, 256, 942, 512, 953,
+ 768, 256, 943, 512, 959, 768, 256, 972, 512, 965, 768, 256, 973, 512,
+ 969, 768, 256, 974, 512, 7936, 837, 512, 7937, 837, 512, 7938, 837, 512,
+ 7939, 837, 512, 7940, 837, 512, 7941, 837, 512, 7942, 837, 512, 7943,
+ 837, 512, 7944, 837, 512, 7945, 837, 512, 7946, 837, 512, 7947, 837, 512,
+ 7948, 837, 512, 7949, 837, 512, 7950, 837, 512, 7951, 837, 512, 7968,
+ 837, 512, 7969, 837, 512, 7970, 837, 512, 7971, 837, 512, 7972, 837, 512,
+ 7973, 837, 512, 7974, 837, 512, 7975, 837, 512, 7976, 837, 512, 7977,
+ 837, 512, 7978, 837, 512, 7979, 837, 512, 7980, 837, 512, 7981, 837, 512,
+ 7982, 837, 512, 7983, 837, 512, 8032, 837, 512, 8033, 837, 512, 8034,
+ 837, 512, 8035, 837, 512, 8036, 837, 512, 8037, 837, 512, 8038, 837, 512,
+ 8039, 837, 512, 8040, 837, 512, 8041, 837, 512, 8042, 837, 512, 8043,
+ 837, 512, 8044, 837, 512, 8045, 837, 512, 8046, 837, 512, 8047, 837, 512,
+ 945, 774, 512, 945, 772, 512, 8048, 837, 512, 945, 837, 512, 940, 837,
+ 512, 945, 834, 512, 8118, 837, 512, 913, 774, 512, 913, 772, 512, 913,
+ 768, 256, 902, 512, 913, 837, 514, 32, 787, 256, 953, 514, 32, 787, 514,
+ 32, 834, 512, 168, 834, 512, 8052, 837, 512, 951, 837, 512, 942, 837,
+ 512, 951, 834, 512, 8134, 837, 512, 917, 768, 256, 904, 512, 919, 768,
+ 256, 905, 512, 919, 837, 512, 8127, 768, 512, 8127, 769, 512, 8127, 834,
+ 512, 953, 774, 512, 953, 772, 512, 970, 768, 256, 912, 512, 953, 834,
+ 512, 970, 834, 512, 921, 774, 512, 921, 772, 512, 921, 768, 256, 906,
+ 512, 8190, 768, 512, 8190, 769, 512, 8190, 834, 512, 965, 774, 512, 965,
+ 772, 512, 971, 768, 256, 944, 512, 961, 787, 512, 961, 788, 512, 965,
+ 834, 512, 971, 834, 512, 933, 774, 512, 933, 772, 512, 933, 768, 256,
+ 910, 512, 929, 788, 512, 168, 768, 256, 901, 256, 96, 512, 8060, 837,
+ 512, 969, 837, 512, 974, 837, 512, 969, 834, 512, 8182, 837, 512, 927,
+ 768, 256, 908, 512, 937, 768, 256, 911, 512, 937, 837, 256, 180, 514, 32,
+ 788, 256, 8194, 256, 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32,
+ 257, 32, 258, 32, 258, 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46,
+ 514, 46, 46, 770, 46, 46, 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242,
+ 8242, 514, 8245, 8245, 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773,
+ 514, 63, 63, 514, 63, 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258,
+ 32, 259, 48, 259, 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259,
+ 57, 259, 43, 259, 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48,
+ 261, 49, 261, 50, 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56,
+ 261, 57, 261, 43, 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261,
+ 101, 261, 111, 261, 120, 261, 601, 514, 82, 115, 770, 97, 47, 99, 770,
+ 97, 47, 115, 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117,
+ 258, 400, 514, 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104,
+ 262, 295, 262, 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111,
+ 262, 80, 262, 81, 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69,
+ 76, 515, 84, 77, 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66,
+ 262, 67, 262, 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258,
+ 1489, 258, 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262,
+ 947, 262, 915, 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262,
+ 105, 262, 106, 772, 49, 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53,
+ 772, 50, 8260, 53, 772, 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260,
+ 54, 772, 53, 8260, 54, 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53,
+ 8260, 56, 772, 55, 8260, 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770,
+ 73, 73, 73, 514, 73, 86, 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86,
+ 73, 73, 73, 514, 73, 88, 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76,
+ 258, 67, 258, 68, 258, 77, 258, 105, 514, 105, 105, 770, 105, 105, 105,
+ 514, 105, 118, 258, 118, 514, 118, 105, 770, 118, 105, 105, 1026, 118,
+ 105, 105, 105, 514, 105, 120, 258, 120, 514, 120, 105, 770, 120, 105,
+ 105, 258, 108, 258, 99, 258, 100, 258, 109, 512, 8592, 824, 512, 8594,
+ 824, 512, 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512,
+ 8707, 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741,
+ 824, 514, 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750,
+ 8750, 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776,
+ 824, 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62,
+ 824, 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512,
+ 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834,
+ 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512,
+ 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829,
+ 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512,
+ 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263,
+ 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48,
+ 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49,
+ 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41,
+ 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770,
+ 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40,
+ 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51,
+ 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41,
+ 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026,
+ 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514,
+ 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48,
+ 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46,
+ 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770,
+ 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40,
+ 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40,
+ 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40,
+ 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40,
+ 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40,
+ 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40,
+ 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65,
+ 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73,
+ 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81,
+ 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89,
+ 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263,
+ 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263,
+ 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263,
+ 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026,
+ 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61,
+ 512, 10973, 824, 259, 11617, 258, 27597, 258, 40863, 258, 19968, 258,
+ 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, 258, 20108, 258,
+ 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, 258, 20866, 258,
+ 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, 258, 21147, 258,
+ 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, 258, 21340, 258,
+ 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, 258, 22231, 258,
+ 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, 258, 22823, 258,
+ 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, 258, 23586, 258,
+ 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, 258, 24049, 258,
+ 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, 258, 24318, 258,
+ 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, 258, 24515, 258,
+ 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, 258, 25991, 258,
+ 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, 258, 26352, 258,
+ 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, 258, 27571, 258,
+ 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, 258, 27700, 258,
+ 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, 258, 29255, 258,
+ 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, 258, 29916, 258,
+ 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, 258, 30091, 258,
+ 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, 258, 30446, 258,
+ 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, 258, 31166, 258,
+ 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, 258, 32566, 258,
+ 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, 258, 32786, 258,
+ 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, 258, 33267, 258,
+ 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, 258, 33394, 258,
+ 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, 258, 34915, 258,
+ 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, 258, 35910, 258,
+ 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, 258, 36275, 258,
+ 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, 258, 37009, 258,
+ 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, 258, 38272, 258,
+ 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, 258, 38750, 258,
+ 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, 258, 38913, 258,
+ 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, 258, 39340, 258,
+ 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, 258, 39730, 258,
+ 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, 258, 40613, 258,
+ 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, 258, 40701, 258,
+ 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, 258, 40786, 258,
+ 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, 21313, 258,
+ 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, 12367,
+ 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, 512,
+ 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, 12441,
+ 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, 12390,
+ 12441, 512, 12392, 12441, 512, 12399, 12441, 512, 12399, 12442, 512,
+ 12402, 12441, 512, 12402, 12442, 512, 12405, 12441, 512, 12405, 12442,
+ 512, 12408, 12441, 512, 12408, 12442, 512, 12411, 12441, 512, 12411,
+ 12442, 512, 12358, 12441, 514, 32, 12441, 514, 32, 12442, 512, 12445,
+ 12441, 521, 12424, 12426, 512, 12459, 12441, 512, 12461, 12441, 512,
+ 12463, 12441, 512, 12465, 12441, 512, 12467, 12441, 512, 12469, 12441,
+ 512, 12471, 12441, 512, 12473, 12441, 512, 12475, 12441, 512, 12477,
+ 12441, 512, 12479, 12441, 512, 12481, 12441, 512, 12484, 12441, 512,
+ 12486, 12441, 512, 12488, 12441, 512, 12495, 12441, 512, 12495, 12442,
+ 512, 12498, 12441, 512, 12498, 12442, 512, 12501, 12441, 512, 12501,
+ 12442, 512, 12504, 12441, 512, 12504, 12442, 512, 12507, 12441, 512,
+ 12507, 12442, 512, 12454, 12441, 512, 12527, 12441, 512, 12528, 12441,
+ 512, 12529, 12441, 512, 12530, 12441, 512, 12541, 12441, 521, 12467,
+ 12488, 258, 4352, 258, 4353, 258, 4522, 258, 4354, 258, 4524, 258, 4525,
+ 258, 4355, 258, 4356, 258, 4357, 258, 4528, 258, 4529, 258, 4530, 258,
+ 4531, 258, 4532, 258, 4533, 258, 4378, 258, 4358, 258, 4359, 258, 4360,
+ 258, 4385, 258, 4361, 258, 4362, 258, 4363, 258, 4364, 258, 4365, 258,
+ 4366, 258, 4367, 258, 4368, 258, 4369, 258, 4370, 258, 4449, 258, 4450,
+ 258, 4451, 258, 4452, 258, 4453, 258, 4454, 258, 4455, 258, 4456, 258,
+ 4457, 258, 4458, 258, 4459, 258, 4460, 258, 4461, 258, 4462, 258, 4463,
+ 258, 4464, 258, 4465, 258, 4466, 258, 4467, 258, 4468, 258, 4469, 258,
+ 4448, 258, 4372, 258, 4373, 258, 4551, 258, 4552, 258, 4556, 258, 4558,
+ 258, 4563, 258, 4567, 258, 4569, 258, 4380, 258, 4573, 258, 4575, 258,
+ 4381, 258, 4382, 258, 4384, 258, 4386, 258, 4387, 258, 4391, 258, 4393,
+ 258, 4395, 258, 4396, 258, 4397, 258, 4398, 258, 4399, 258, 4402, 258,
+ 4406, 258, 4416, 258, 4423, 258, 4428, 258, 4593, 258, 4594, 258, 4439,
+ 258, 4440, 258, 4441, 258, 4484, 258, 4485, 258, 4488, 258, 4497, 258,
+ 4498, 258, 4500, 258, 4510, 258, 4513, 259, 19968, 259, 20108, 259,
+ 19977, 259, 22235, 259, 19978, 259, 20013, 259, 19979, 259, 30002, 259,
+ 20057, 259, 19993, 259, 19969, 259, 22825, 259, 22320, 259, 20154, 770,
+ 40, 4352, 41, 770, 40, 4354, 41, 770, 40, 4355, 41, 770, 40, 4357, 41,
+ 770, 40, 4358, 41, 770, 40, 4359, 41, 770, 40, 4361, 41, 770, 40, 4363,
+ 41, 770, 40, 4364, 41, 770, 40, 4366, 41, 770, 40, 4367, 41, 770, 40,
+ 4368, 41, 770, 40, 4369, 41, 770, 40, 4370, 41, 1026, 40, 4352, 4449, 41,
+ 1026, 40, 4354, 4449, 41, 1026, 40, 4355, 4449, 41, 1026, 40, 4357, 4449,
+ 41, 1026, 40, 4358, 4449, 41, 1026, 40, 4359, 4449, 41, 1026, 40, 4361,
+ 4449, 41, 1026, 40, 4363, 4449, 41, 1026, 40, 4364, 4449, 41, 1026, 40,
+ 4366, 4449, 41, 1026, 40, 4367, 4449, 41, 1026, 40, 4368, 4449, 41, 1026,
+ 40, 4369, 4449, 41, 1026, 40, 4370, 4449, 41, 1026, 40, 4364, 4462, 41,
+ 1794, 40, 4363, 4457, 4364, 4453, 4523, 41, 1538, 40, 4363, 4457, 4370,
+ 4462, 41, 770, 40, 19968, 41, 770, 40, 20108, 41, 770, 40, 19977, 41,
+ 770, 40, 22235, 41, 770, 40, 20116, 41, 770, 40, 20845, 41, 770, 40,
+ 19971, 41, 770, 40, 20843, 41, 770, 40, 20061, 41, 770, 40, 21313, 41,
+ 770, 40, 26376, 41, 770, 40, 28779, 41, 770, 40, 27700, 41, 770, 40,
+ 26408, 41, 770, 40, 37329, 41, 770, 40, 22303, 41, 770, 40, 26085, 41,
+ 770, 40, 26666, 41, 770, 40, 26377, 41, 770, 40, 31038, 41, 770, 40,
+ 21517, 41, 770, 40, 29305, 41, 770, 40, 36001, 41, 770, 40, 31069, 41,
+ 770, 40, 21172, 41, 770, 40, 20195, 41, 770, 40, 21628, 41, 770, 40,
+ 23398, 41, 770, 40, 30435, 41, 770, 40, 20225, 41, 770, 40, 36039, 41,
+ 770, 40, 21332, 41, 770, 40, 31085, 41, 770, 40, 20241, 41, 770, 40,
+ 33258, 41, 770, 40, 33267, 41, 778, 80, 84, 69, 519, 50, 49, 519, 50, 50,
+ 519, 50, 51, 519, 50, 52, 519, 50, 53, 519, 50, 54, 519, 50, 55, 519, 50,
+ 56, 519, 50, 57, 519, 51, 48, 519, 51, 49, 519, 51, 50, 519, 51, 51, 519,
+ 51, 52, 519, 51, 53, 263, 4352, 263, 4354, 263, 4355, 263, 4357, 263,
+ 4358, 263, 4359, 263, 4361, 263, 4363, 263, 4364, 263, 4366, 263, 4367,
+ 263, 4368, 263, 4369, 263, 4370, 519, 4352, 4449, 519, 4354, 4449, 519,
+ 4355, 4449, 519, 4357, 4449, 519, 4358, 4449, 519, 4359, 4449, 519, 4361,
+ 4449, 519, 4363, 4449, 519, 4364, 4449, 519, 4366, 4449, 519, 4367, 4449,
+ 519, 4368, 4449, 519, 4369, 4449, 519, 4370, 4449, 1287, 4366, 4449,
+ 4535, 4352, 4457, 1031, 4364, 4462, 4363, 4468, 519, 4363, 4462, 263,
+ 19968, 263, 20108, 263, 19977, 263, 22235, 263, 20116, 263, 20845, 263,
+ 19971, 263, 20843, 263, 20061, 263, 21313, 263, 26376, 263, 28779, 263,
+ 27700, 263, 26408, 263, 37329, 263, 22303, 263, 26085, 263, 26666, 263,
+ 26377, 263, 31038, 263, 21517, 263, 29305, 263, 36001, 263, 31069, 263,
+ 21172, 263, 31192, 263, 30007, 263, 22899, 263, 36969, 263, 20778, 263,
+ 21360, 263, 27880, 263, 38917, 263, 20241, 263, 20889, 263, 27491, 263,
+ 19978, 263, 20013, 263, 19979, 263, 24038, 263, 21491, 263, 21307, 263,
+ 23447, 263, 23398, 263, 30435, 263, 20225, 263, 36039, 263, 21332, 263,
+ 22812, 519, 51, 54, 519, 51, 55, 519, 51, 56, 519, 51, 57, 519, 52, 48,
+ 519, 52, 49, 519, 52, 50, 519, 52, 51, 519, 52, 52, 519, 52, 53, 519, 52,
+ 54, 519, 52, 55, 519, 52, 56, 519, 52, 57, 519, 53, 48, 514, 49, 26376,
+ 514, 50, 26376, 514, 51, 26376, 514, 52, 26376, 514, 53, 26376, 514, 54,
+ 26376, 514, 55, 26376, 514, 56, 26376, 514, 57, 26376, 770, 49, 48,
+ 26376, 770, 49, 49, 26376, 770, 49, 50, 26376, 522, 72, 103, 778, 101,
+ 114, 103, 522, 101, 86, 778, 76, 84, 68, 263, 12450, 263, 12452, 263,
+ 12454, 263, 12456, 263, 12458, 263, 12459, 263, 12461, 263, 12463, 263,
+ 12465, 263, 12467, 263, 12469, 263, 12471, 263, 12473, 263, 12475, 263,
+ 12477, 263, 12479, 263, 12481, 263, 12484, 263, 12486, 263, 12488, 263,
+ 12490, 263, 12491, 263, 12492, 263, 12493, 263, 12494, 263, 12495, 263,
+ 12498, 263, 12501, 263, 12504, 263, 12507, 263, 12510, 263, 12511, 263,
+ 12512, 263, 12513, 263, 12514, 263, 12516, 263, 12518, 263, 12520, 263,
+ 12521, 263, 12522, 263, 12523, 263, 12524, 263, 12525, 263, 12527, 263,
+ 12528, 263, 12529, 263, 12530, 1034, 12450, 12497, 12540, 12488, 1034,
+ 12450, 12523, 12501, 12449, 1034, 12450, 12531, 12506, 12450, 778, 12450,
+ 12540, 12523, 1034, 12452, 12491, 12531, 12464, 778, 12452, 12531, 12481,
+ 778, 12454, 12457, 12531, 1290, 12456, 12473, 12463, 12540, 12489, 1034,
+ 12456, 12540, 12459, 12540, 778, 12458, 12531, 12473, 778, 12458, 12540,
+ 12512, 778, 12459, 12452, 12522, 1034, 12459, 12521, 12483, 12488, 1034,
+ 12459, 12525, 12522, 12540, 778, 12460, 12525, 12531, 778, 12460, 12531,
+ 12510, 522, 12462, 12460, 778, 12462, 12491, 12540, 1034, 12461, 12517,
+ 12522, 12540, 1034, 12462, 12523, 12480, 12540, 522, 12461, 12525, 1290,
+ 12461, 12525, 12464, 12521, 12512, 1546, 12461, 12525, 12513, 12540,
+ 12488, 12523, 1290, 12461, 12525, 12527, 12483, 12488, 778, 12464, 12521,
+ 12512, 1290, 12464, 12521, 12512, 12488, 12531, 1290, 12463, 12523,
+ 12476, 12452, 12525, 1034, 12463, 12525, 12540, 12493, 778, 12465, 12540,
+ 12473, 778, 12467, 12523, 12490, 778, 12467, 12540, 12509, 1034, 12469,
+ 12452, 12463, 12523, 1290, 12469, 12531, 12481, 12540, 12512, 1034,
+ 12471, 12522, 12531, 12464, 778, 12475, 12531, 12481, 778, 12475, 12531,
+ 12488, 778, 12480, 12540, 12473, 522, 12487, 12471, 522, 12489, 12523,
+ 522, 12488, 12531, 522, 12490, 12494, 778, 12494, 12483, 12488, 778,
+ 12495, 12452, 12484, 1290, 12497, 12540, 12475, 12531, 12488, 778, 12497,
+ 12540, 12484, 1034, 12496, 12540, 12524, 12523, 1290, 12500, 12450,
+ 12473, 12488, 12523, 778, 12500, 12463, 12523, 522, 12500, 12467, 522,
+ 12499, 12523, 1290, 12501, 12449, 12521, 12483, 12489, 1034, 12501,
+ 12451, 12540, 12488, 1290, 12502, 12483, 12471, 12455, 12523, 778, 12501,
+ 12521, 12531, 1290, 12504, 12463, 12479, 12540, 12523, 522, 12506, 12477,
+ 778, 12506, 12491, 12498, 778, 12504, 12523, 12484, 778, 12506, 12531,
+ 12473, 778, 12506, 12540, 12472, 778, 12505, 12540, 12479, 1034, 12509,
+ 12452, 12531, 12488, 778, 12508, 12523, 12488, 522, 12507, 12531, 778,
+ 12509, 12531, 12489, 778, 12507, 12540, 12523, 778, 12507, 12540, 12531,
+ 1034, 12510, 12452, 12463, 12525, 778, 12510, 12452, 12523, 778, 12510,
+ 12483, 12495, 778, 12510, 12523, 12463, 1290, 12510, 12531, 12471, 12519,
+ 12531, 1034, 12511, 12463, 12525, 12531, 522, 12511, 12522, 1290, 12511,
+ 12522, 12496, 12540, 12523, 522, 12513, 12460, 1034, 12513, 12460, 12488,
+ 12531, 1034, 12513, 12540, 12488, 12523, 778, 12516, 12540, 12489, 778,
+ 12516, 12540, 12523, 778, 12518, 12450, 12531, 1034, 12522, 12483, 12488,
+ 12523, 522, 12522, 12521, 778, 12523, 12500, 12540, 1034, 12523, 12540,
+ 12502, 12523, 522, 12524, 12512, 1290, 12524, 12531, 12488, 12466, 12531,
+ 778, 12527, 12483, 12488, 514, 48, 28857, 514, 49, 28857, 514, 50, 28857,
+ 514, 51, 28857, 514, 52, 28857, 514, 53, 28857, 514, 54, 28857, 514, 55,
+ 28857, 514, 56, 28857, 514, 57, 28857, 770, 49, 48, 28857, 770, 49, 49,
+ 28857, 770, 49, 50, 28857, 770, 49, 51, 28857, 770, 49, 52, 28857, 770,
+ 49, 53, 28857, 770, 49, 54, 28857, 770, 49, 55, 28857, 770, 49, 56,
+ 28857, 770, 49, 57, 28857, 770, 50, 48, 28857, 770, 50, 49, 28857, 770,
+ 50, 50, 28857, 770, 50, 51, 28857, 770, 50, 52, 28857, 778, 104, 80, 97,
+ 522, 100, 97, 522, 65, 85, 778, 98, 97, 114, 522, 111, 86, 522, 112, 99,
+ 522, 100, 109, 778, 100, 109, 178, 778, 100, 109, 179, 522, 73, 85, 522,
+ 24179, 25104, 522, 26157, 21644, 522, 22823, 27491, 522, 26126, 27835,
+ 1034, 26666, 24335, 20250, 31038, 522, 112, 65, 522, 110, 65, 522, 956,
+ 65, 522, 109, 65, 522, 107, 65, 522, 75, 66, 522, 77, 66, 522, 71, 66,
+ 778, 99, 97, 108, 1034, 107, 99, 97, 108, 522, 112, 70, 522, 110, 70,
+ 522, 956, 70, 522, 956, 103, 522, 109, 103, 522, 107, 103, 522, 72, 122,
+ 778, 107, 72, 122, 778, 77, 72, 122, 778, 71, 72, 122, 778, 84, 72, 122,
+ 522, 956, 8467, 522, 109, 8467, 522, 100, 8467, 522, 107, 8467, 522, 102,
+ 109, 522, 110, 109, 522, 956, 109, 522, 109, 109, 522, 99, 109, 522, 107,
+ 109, 778, 109, 109, 178, 778, 99, 109, 178, 522, 109, 178, 778, 107, 109,
+ 178, 778, 109, 109, 179, 778, 99, 109, 179, 522, 109, 179, 778, 107, 109,
+ 179, 778, 109, 8725, 115, 1034, 109, 8725, 115, 178, 522, 80, 97, 778,
+ 107, 80, 97, 778, 77, 80, 97, 778, 71, 80, 97, 778, 114, 97, 100, 1290,
+ 114, 97, 100, 8725, 115, 1546, 114, 97, 100, 8725, 115, 178, 522, 112,
+ 115, 522, 110, 115, 522, 956, 115, 522, 109, 115, 522, 112, 86, 522, 110,
+ 86, 522, 956, 86, 522, 109, 86, 522, 107, 86, 522, 77, 86, 522, 112, 87,
+ 522, 110, 87, 522, 956, 87, 522, 109, 87, 522, 107, 87, 522, 77, 87, 522,
+ 107, 937, 522, 77, 937, 1034, 97, 46, 109, 46, 522, 66, 113, 522, 99, 99,
+ 522, 99, 100, 1034, 67, 8725, 107, 103, 778, 67, 111, 46, 522, 100, 66,
+ 522, 71, 121, 522, 104, 97, 522, 72, 80, 522, 105, 110, 522, 75, 75, 522,
+ 75, 77, 522, 107, 116, 522, 108, 109, 522, 108, 110, 778, 108, 111, 103,
+ 522, 108, 120, 522, 109, 98, 778, 109, 105, 108, 778, 109, 111, 108, 522,
+ 80, 72, 1034, 112, 46, 109, 46, 778, 80, 80, 77, 522, 80, 82, 522, 115,
+ 114, 522, 83, 118, 522, 87, 98, 778, 86, 8725, 109, 778, 65, 8725, 109,
+ 514, 49, 26085, 514, 50, 26085, 514, 51, 26085, 514, 52, 26085, 514, 53,
+ 26085, 514, 54, 26085, 514, 55, 26085, 514, 56, 26085, 514, 57, 26085,
+ 770, 49, 48, 26085, 770, 49, 49, 26085, 770, 49, 50, 26085, 770, 49, 51,
+ 26085, 770, 49, 52, 26085, 770, 49, 53, 26085, 770, 49, 54, 26085, 770,
+ 49, 55, 26085, 770, 49, 56, 26085, 770, 49, 57, 26085, 770, 50, 48,
+ 26085, 770, 50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770,
+ 50, 52, 26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55,
+ 26085, 770, 50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770,
+ 51, 49, 26085, 778, 103, 97, 108, 256, 35912, 256, 26356, 256, 36554,
+ 256, 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 40860,
+ 256, 22865, 256, 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313,
+ 256, 32645, 256, 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138,
+ 256, 27931, 256, 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409,
+ 256, 20098, 256, 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478,
+ 256, 23888, 256, 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240,
+ 256, 34847, 256, 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070,
+ 256, 20358, 256, 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200,
+ 256, 30439, 256, 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706,
+ 256, 39791, 256, 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737,
+ 256, 37636, 256, 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840,
+ 256, 32894, 256, 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744,
+ 256, 23650, 256, 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311,
+ 256, 38475, 256, 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260,
+ 256, 32190, 256, 33777, 256, 38517, 256, 35712, 256, 25295, 256, 27138,
+ 256, 35582, 256, 20025, 256, 23527, 256, 24594, 256, 29575, 256, 30064,
+ 256, 21271, 256, 30971, 256, 20415, 256, 24489, 256, 19981, 256, 27852,
+ 256, 25976, 256, 32034, 256, 21443, 256, 22622, 256, 30465, 256, 33865,
+ 256, 35498, 256, 27578, 256, 36784, 256, 27784, 256, 25342, 256, 33509,
+ 256, 25504, 256, 30053, 256, 20142, 256, 20841, 256, 20937, 256, 26753,
+ 256, 31975, 256, 33391, 256, 35538, 256, 37327, 256, 21237, 256, 21570,
+ 256, 22899, 256, 24300, 256, 26053, 256, 28670, 256, 31018, 256, 38317,
+ 256, 39530, 256, 40599, 256, 40654, 256, 21147, 256, 26310, 256, 27511,
+ 256, 36706, 256, 24180, 256, 24976, 256, 25088, 256, 25754, 256, 28451,
+ 256, 29001, 256, 29833, 256, 31178, 256, 32244, 256, 32879, 256, 36646,
+ 256, 34030, 256, 36899, 256, 37706, 256, 21015, 256, 21155, 256, 21693,
+ 256, 28872, 256, 35010, 256, 35498, 256, 24265, 256, 24565, 256, 25467,
+ 256, 27566, 256, 31806, 256, 29557, 256, 20196, 256, 22265, 256, 23527,
+ 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, 32666, 256, 32838,
+ 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, 20363, 256, 31150,
+ 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, 20698, 256, 23534,
+ 256, 23615, 256, 26009, 256, 27138, 256, 29134, 256, 30274, 256, 34044,
+ 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, 26491,
+ 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, 30827,
+ 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, 20523,
+ 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, 26647,
+ 256, 29575, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131,
+ 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, 30178, 256, 32633,
+ 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, 21311, 256, 28346,
+ 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, 38563, 256, 40023,
+ 256, 40607, 256, 26519, 256, 28107, 256, 33256, 256, 31435, 256, 31520,
+ 256, 31890, 256, 29376, 256, 28825, 256, 35672, 256, 20160, 256, 33590,
+ 256, 21050, 256, 20999, 256, 24230, 256, 25299, 256, 31958, 256, 23429,
+ 256, 27934, 256, 26292, 256, 36667, 256, 34892, 256, 38477, 256, 35211,
+ 256, 24275, 256, 20800, 256, 21952, 256, 22618, 256, 26228, 256, 20958,
+ 256, 29482, 256, 30410, 256, 31036, 256, 31070, 256, 31077, 256, 31119,
+ 256, 38742, 256, 31934, 256, 32701, 256, 34322, 256, 35576, 256, 36920,
+ 256, 37117, 256, 39151, 256, 39164, 256, 39208, 256, 40372, 256, 20398,
+ 256, 20711, 256, 20813, 256, 21193, 256, 21220, 256, 21329, 256, 21917,
+ 256, 22022, 256, 22120, 256, 22592, 256, 22696, 256, 23652, 256, 23662,
+ 256, 24724, 256, 24936, 256, 24974, 256, 25074, 256, 25935, 256, 26082,
+ 256, 26257, 256, 26757, 256, 28023, 256, 28186, 256, 28450, 256, 29038,
+ 256, 29227, 256, 29730, 256, 30865, 256, 31038, 256, 31049, 256, 31048,
+ 256, 31056, 256, 31062, 256, 31069, 256, 31117, 256, 31118, 256, 31296,
+ 256, 31361, 256, 31680, 256, 32244, 256, 32265, 256, 32321, 256, 32626,
+ 256, 32773, 256, 33261, 256, 33401, 256, 33401, 256, 33879, 256, 35088,
+ 256, 35222, 256, 35585, 256, 35641, 256, 36051, 256, 36104, 256, 36790,
+ 256, 36920, 256, 38627, 256, 38911, 256, 38971, 256, 20006, 256, 20917,
+ 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, 256, 21242,
+ 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, 256, 22707,
+ 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281,
+ 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24974,
+ 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, 256, 25682,
+ 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, 256, 27513,
+ 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, 256, 28702,
+ 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, 256, 29809,
+ 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, 256, 30427,
+ 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, 256, 31680,
+ 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, 256, 33618,
+ 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, 256, 35519,
+ 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, 256, 35641,
+ 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, 256, 37494,
+ 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, 256, 38923,
+ 256, 38971, 256, 39698, 256, 40860, 256, 141386, 256, 141380, 256,
+ 144341, 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, 154832,
+ 256, 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514,
+ 102, 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514,
+ 115, 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406,
+ 1398, 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262,
+ 1488, 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512,
+ 262, 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473,
+ 512, 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512,
+ 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493,
+ 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468,
+ 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512,
+ 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511,
+ 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465,
+ 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267,
+ 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662,
+ 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270,
+ 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663,
+ 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267,
+ 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702,
+ 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268,
+ 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670,
+ 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267,
+ 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688,
+ 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270,
+ 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715,
+ 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267,
+ 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728,
+ 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268,
+ 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747,
+ 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267,
+ 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739,
+ 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269,
+ 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575,
+ 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523,
+ 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574,
+ 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744,
+ 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740,
+ 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605,
+ 523, 1574, 1609, 523, 1574, 1610, 523, 1576, 1580, 523, 1576, 1581, 523,
+ 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, 1610, 523, 1578,
+ 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, 523, 1578, 1609,
+ 523, 1578, 1610, 523, 1579, 1580, 523, 1579, 1605, 523, 1579, 1609, 523,
+ 1579, 1610, 523, 1580, 1581, 523, 1580, 1605, 523, 1581, 1580, 523, 1581,
+ 1605, 523, 1582, 1580, 523, 1582, 1581, 523, 1582, 1605, 523, 1587, 1580,
+ 523, 1587, 1581, 523, 1587, 1582, 523, 1587, 1605, 523, 1589, 1581, 523,
+ 1589, 1605, 523, 1590, 1580, 523, 1590, 1581, 523, 1590, 1582, 523, 1590,
+ 1605, 523, 1591, 1581, 523, 1591, 1605, 523, 1592, 1605, 523, 1593, 1580,
+ 523, 1593, 1605, 523, 1594, 1580, 523, 1594, 1605, 523, 1601, 1580, 523,
+ 1601, 1581, 523, 1601, 1582, 523, 1601, 1605, 523, 1601, 1609, 523, 1601,
+ 1610, 523, 1602, 1581, 523, 1602, 1605, 523, 1602, 1609, 523, 1602, 1610,
+ 523, 1603, 1575, 523, 1603, 1580, 523, 1603, 1581, 523, 1603, 1582, 523,
+ 1603, 1604, 523, 1603, 1605, 523, 1603, 1609, 523, 1603, 1610, 523, 1604,
+ 1580, 523, 1604, 1581, 523, 1604, 1582, 523, 1604, 1605, 523, 1604, 1609,
+ 523, 1604, 1610, 523, 1605, 1580, 523, 1605, 1581, 523, 1605, 1582, 523,
+ 1605, 1605, 523, 1605, 1609, 523, 1605, 1610, 523, 1606, 1580, 523, 1606,
+ 1581, 523, 1606, 1582, 523, 1606, 1605, 523, 1606, 1609, 523, 1606, 1610,
+ 523, 1607, 1580, 523, 1607, 1605, 523, 1607, 1609, 523, 1607, 1610, 523,
+ 1610, 1580, 523, 1610, 1581, 523, 1610, 1582, 523, 1610, 1605, 523, 1610,
+ 1609, 523, 1610, 1610, 523, 1584, 1648, 523, 1585, 1648, 523, 1609, 1648,
+ 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, 1617, 779, 32,
+ 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, 1574, 1585,
+ 524, 1574, 1586, 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1609, 524,
+ 1574, 1610, 524, 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, 524, 1576,
+ 1606, 524, 1576, 1609, 524, 1576, 1610, 524, 1578, 1585, 524, 1578, 1586,
+ 524, 1578, 1605, 524, 1578, 1606, 524, 1578, 1609, 524, 1578, 1610, 524,
+ 1579, 1585, 524, 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, 524, 1579,
+ 1609, 524, 1579, 1610, 524, 1601, 1609, 524, 1601, 1610, 524, 1602, 1609,
+ 524, 1602, 1610, 524, 1603, 1575, 524, 1603, 1604, 524, 1603, 1605, 524,
+ 1603, 1609, 524, 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, 524, 1604,
+ 1610, 524, 1605, 1575, 524, 1605, 1605, 524, 1606, 1585, 524, 1606, 1586,
+ 524, 1606, 1605, 524, 1606, 1606, 524, 1606, 1609, 524, 1606, 1610, 524,
+ 1609, 1648, 524, 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, 524, 1610,
+ 1606, 524, 1610, 1609, 524, 1610, 1610, 525, 1574, 1580, 525, 1574, 1581,
+ 525, 1574, 1582, 525, 1574, 1605, 525, 1574, 1607, 525, 1576, 1580, 525,
+ 1576, 1581, 525, 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, 525, 1578,
+ 1580, 525, 1578, 1581, 525, 1578, 1582, 525, 1578, 1605, 525, 1578, 1607,
+ 525, 1579, 1605, 525, 1580, 1581, 525, 1580, 1605, 525, 1581, 1580, 525,
+ 1581, 1605, 525, 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, 525, 1587,
+ 1581, 525, 1587, 1582, 525, 1587, 1605, 525, 1589, 1581, 525, 1589, 1582,
+ 525, 1589, 1605, 525, 1590, 1580, 525, 1590, 1581, 525, 1590, 1582, 525,
+ 1590, 1605, 525, 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, 525, 1593,
+ 1605, 525, 1594, 1580, 525, 1594, 1605, 525, 1601, 1580, 525, 1601, 1581,
+ 525, 1601, 1582, 525, 1601, 1605, 525, 1602, 1581, 525, 1602, 1605, 525,
+ 1603, 1580, 525, 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, 525, 1603,
+ 1605, 525, 1604, 1580, 525, 1604, 1581, 525, 1604, 1582, 525, 1604, 1605,
+ 525, 1604, 1607, 525, 1605, 1580, 525, 1605, 1581, 525, 1605, 1582, 525,
+ 1605, 1605, 525, 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, 525, 1606,
+ 1605, 525, 1606, 1607, 525, 1607, 1580, 525, 1607, 1605, 525, 1607, 1648,
+ 525, 1610, 1580, 525, 1610, 1581, 525, 1610, 1582, 525, 1610, 1605, 525,
+ 1610, 1607, 526, 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, 526, 1576,
+ 1607, 526, 1578, 1605, 526, 1578, 1607, 526, 1579, 1605, 526, 1579, 1607,
+ 526, 1587, 1605, 526, 1587, 1607, 526, 1588, 1605, 526, 1588, 1607, 526,
+ 1603, 1604, 526, 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, 526, 1606,
+ 1607, 526, 1610, 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, 782, 1600,
+ 1615, 1617, 782, 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523,
+ 1593, 1609, 523, 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587,
+ 1609, 523, 1587, 1610, 523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609,
+ 523, 1581, 1610, 523, 1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523,
+ 1582, 1610, 523, 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590,
+ 1610, 523, 1588, 1580, 523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605,
+ 523, 1588, 1585, 523, 1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524,
+ 1591, 1609, 524, 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594,
+ 1609, 524, 1594, 1610, 524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609,
+ 524, 1588, 1610, 524, 1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524,
+ 1580, 1610, 524, 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589,
+ 1610, 524, 1590, 1609, 524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581,
+ 524, 1588, 1582, 524, 1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524,
+ 1589, 1585, 524, 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588,
+ 1582, 525, 1588, 1605, 525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605,
+ 526, 1587, 1580, 526, 1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526,
+ 1588, 1581, 526, 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575,
+ 1611, 523, 1575, 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781,
+ 1578, 1581, 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, 1605, 781,
+ 1578, 1605, 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, 1582, 780,
+ 1580, 1605, 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, 1610, 780,
+ 1581, 1605, 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, 1581, 780,
+ 1587, 1580, 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, 1581, 781,
+ 1587, 1605, 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, 1605, 780,
+ 1589, 1581, 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, 1605, 780,
+ 1588, 1581, 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, 1610, 780,
+ 1588, 1605, 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, 1605, 781,
+ 1588, 1605, 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, 1605, 781,
+ 1590, 1582, 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, 1581, 781,
+ 1591, 1605, 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, 1605, 780,
+ 1593, 1605, 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, 1609, 780,
+ 1594, 1605, 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, 1609, 780,
+ 1601, 1582, 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, 1581, 780,
+ 1602, 1605, 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, 1610, 780,
+ 1604, 1581, 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, 1580, 780,
+ 1604, 1582, 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, 1581, 781,
+ 1604, 1605, 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, 1605, 780,
+ 1605, 1581, 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, 1605, 781,
+ 1605, 1582, 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, 1582, 781,
+ 1607, 1605, 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, 1605, 780,
+ 1606, 1581, 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, 1605, 780,
+ 1606, 1580, 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, 1609, 780,
+ 1610, 1605, 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, 1610, 780,
+ 1578, 1580, 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, 1610, 780,
+ 1578, 1582, 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, 1609, 780,
+ 1580, 1605, 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, 1609, 780,
+ 1587, 1582, 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, 1610, 780,
+ 1590, 1581, 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, 1610, 780,
+ 1610, 1581, 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, 1610, 780,
+ 1605, 1605, 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, 1610, 781,
+ 1602, 1605, 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, 1610, 780,
+ 1603, 1605, 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, 1610, 781,
+ 1604, 1580, 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, 1605, 780,
+ 1606, 1580, 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, 1610, 780,
+ 1605, 1580, 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, 1610, 781,
+ 1603, 1605, 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, 1605, 780,
+ 1587, 1582, 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, 1746, 779,
+ 1602, 1604, 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576,
+ 1585, 1035, 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035,
+ 1585, 1587, 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587,
+ 1604, 1605, 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575,
+ 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605,
+ 2059, 1580, 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, 1585, 1740,
+ 1575, 1604, 265, 44, 265, 12289, 265, 12290, 265, 58, 265, 59, 265, 33,
+ 265, 63, 265, 12310, 265, 12311, 265, 8230, 265, 8229, 265, 8212, 265,
+ 8211, 265, 95, 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, 265, 12308,
+ 265, 12309, 265, 12304, 265, 12305, 265, 12298, 265, 12299, 265, 12296,
+ 265, 12297, 265, 12300, 265, 12301, 265, 12302, 265, 12303, 265, 91, 265,
+ 93, 258, 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, 258, 95, 258,
+ 95, 271, 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33,
+ 271, 8212, 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309,
+ 271, 35, 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61,
+ 271, 92, 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523,
+ 32, 1612, 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615,
+ 526, 1600, 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526,
+ 1600, 1617, 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268,
+ 1570, 267, 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573,
+ 267, 1574, 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267,
+ 1576, 268, 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578,
+ 268, 1578, 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270,
+ 1579, 267, 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581,
+ 269, 1581, 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267,
+ 1583, 268, 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586,
+ 268, 1586, 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268,
+ 1588, 269, 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589,
+ 267, 1590, 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269,
+ 1591, 270, 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593,
+ 268, 1593, 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270,
+ 1594, 267, 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602,
+ 269, 1602, 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267,
+ 1604, 268, 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605,
+ 270, 1605, 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268,
+ 1607, 269, 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609,
+ 267, 1610, 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604,
+ 1570, 523, 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573,
+ 523, 1604, 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36,
+ 264, 37, 264, 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44,
+ 264, 45, 264, 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52,
+ 264, 53, 264, 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60,
+ 264, 61, 264, 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68,
+ 264, 69, 264, 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76,
+ 264, 77, 264, 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84,
+ 264, 85, 264, 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92,
+ 264, 93, 264, 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100,
+ 264, 101, 264, 102, 264, 103, 264, 104, 264, 105, 264, 106, 264, 107,
+ 264, 108, 264, 109, 264, 110, 264, 111, 264, 112, 264, 113, 264, 114,
+ 264, 115, 264, 116, 264, 117, 264, 118, 264, 119, 264, 120, 264, 121,
+ 264, 122, 264, 123, 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630,
+ 272, 12290, 272, 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530,
+ 272, 12449, 272, 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515,
+ 272, 12517, 272, 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452,
+ 272, 12454, 272, 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463,
+ 272, 12465, 272, 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475,
+ 272, 12477, 272, 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488,
+ 272, 12490, 272, 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495,
+ 272, 12498, 272, 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511,
+ 272, 12512, 272, 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520,
+ 272, 12521, 272, 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527,
+ 272, 12531, 272, 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594,
+ 272, 12595, 272, 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600,
+ 272, 12601, 272, 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606,
+ 272, 12607, 272, 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612,
+ 272, 12613, 272, 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618,
+ 272, 12619, 272, 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624,
+ 272, 12625, 272, 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630,
+ 272, 12631, 272, 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636,
+ 272, 12637, 272, 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642,
+ 272, 12643, 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165,
+ 264, 8361, 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272,
+ 9632, 272, 9675, 512, 119127, 119141, 512, 119128, 119141, 512, 119135,
+ 119150, 512, 119135, 119151, 512, 119135, 119152, 512, 119135, 119153,
+ 512, 119135, 119154, 512, 119225, 119141, 512, 119226, 119141, 512,
+ 119227, 119150, 512, 119228, 119150, 512, 119227, 119151, 512, 119228,
+ 119151, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71,
+ 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79,
+ 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87,
+ 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101,
+ 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108,
+ 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115,
+ 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122,
+ 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72,
+ 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80,
+ 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88,
+ 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262,
+ 102, 262, 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262,
+ 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262,
+ 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66,
+ 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74,
+ 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82,
+ 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90,
+ 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262,
+ 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262,
+ 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262,
+ 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 67, 262, 68,
+ 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83,
+ 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97,
+ 262, 98, 262, 99, 262, 100, 262, 102, 262, 104, 262, 105, 262, 106, 262,
+ 107, 262, 108, 262, 109, 262, 110, 262, 112, 262, 113, 262, 114, 262,
+ 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262,
+ 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262,
+ 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262,
+ 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262,
+ 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262,
+ 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262,
+ 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262,
+ 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65,
+ 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76,
+ 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85,
+ 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100,
+ 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107,
+ 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114,
+ 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121,
+ 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73,
+ 262, 74, 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85,
+ 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100,
+ 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107,
+ 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114,
+ 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121,
+ 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71,
+ 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79,
+ 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87,
+ 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101,
+ 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108,
+ 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115,
+ 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122,
+ 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72,
+ 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80,
+ 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88,
+ 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262,
+ 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262,
+ 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262,
+ 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65,
+ 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73,
+ 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81,
+ 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89,
+ 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262,
+ 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262,
+ 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262,
+ 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66,
+ 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74,
+ 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82,
+ 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90,
+ 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262,
+ 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262,
+ 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262,
+ 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67,
+ 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75,
+ 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83,
+ 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97,
+ 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262,
+ 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262,
+ 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262,
+ 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68,
+ 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76,
+ 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84,
+ 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98,
+ 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262,
+ 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262,
+ 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262,
+ 120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, 262, 914, 262,
+ 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262,
+ 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262,
+ 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262,
+ 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262,
+ 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262,
+ 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262,
+ 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262,
+ 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262,
+ 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262,
+ 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262,
+ 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262,
+ 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262,
+ 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262,
+ 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262,
+ 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262,
+ 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262,
+ 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262,
+ 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262,
+ 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262,
+ 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262,
+ 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262,
+ 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262,
+ 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262,
+ 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262,
+ 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262,
+ 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262,
+ 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262,
+ 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262,
+ 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262,
+ 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262,
+ 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262,
+ 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262,
+ 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262,
+ 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262,
+ 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262,
+ 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262,
+ 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262,
+ 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262,
+ 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262,
+ 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262,
+ 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262,
+ 982, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262,
+ 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262,
+ 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262,
+ 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262,
+ 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262,
+ 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262,
+ 55, 262, 56, 262, 57, 256, 20029, 256, 20024, 256, 20033, 256, 131362,
+ 256, 20320, 256, 20398, 256, 20411, 256, 20482, 256, 20602, 256, 20633,
+ 256, 20711, 256, 20687, 256, 13470, 256, 132666, 256, 20813, 256, 20820,
+ 256, 20836, 256, 20855, 256, 132380, 256, 13497, 256, 20839, 256, 20877,
+ 256, 132427, 256, 20887, 256, 20900, 256, 20172, 256, 20908, 256, 20917,
+ 256, 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062,
+ 256, 21106, 256, 21111, 256, 13589, 256, 21191, 256, 21193, 256, 21220,
+ 256, 21242, 256, 21253, 256, 21254, 256, 21271, 256, 21321, 256, 21329,
+ 256, 21338, 256, 21363, 256, 21373, 256, 21375, 256, 21375, 256, 21375,
+ 256, 133676, 256, 28784, 256, 21450, 256, 21471, 256, 133987, 256, 21483,
+ 256, 21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608,
+ 256, 21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892,
+ 256, 21892, 256, 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294,
+ 256, 22022, 256, 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766,
+ 256, 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577,
+ 256, 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810,
+ 256, 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067,
+ 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, 256, 23304,
+ 256, 23358, 256, 23358, 256, 137672, 256, 23491, 256, 23512, 256, 23527,
+ 256, 23539, 256, 138008, 256, 23551, 256, 23558, 256, 24403, 256, 23586,
+ 256, 14209, 256, 23648, 256, 23662, 256, 23744, 256, 23693, 256, 138724,
+ 256, 23875, 256, 138726, 256, 23918, 256, 23915, 256, 23932, 256, 24033,
+ 256, 24034, 256, 14383, 256, 24061, 256, 24104, 256, 24125, 256, 24169,
+ 256, 14434, 256, 139651, 256, 14460, 256, 24240, 256, 24243, 256, 24246,
+ 256, 24266, 256, 172946, 256, 24318, 256, 140081, 256, 140081, 256,
+ 33281, 256, 24354, 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256,
+ 24418, 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256,
+ 24569, 256, 24705, 256, 14650, 256, 14620, 256, 24724, 256, 141012, 256,
+ 24775, 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256,
+ 24974, 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256,
+ 25078, 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256,
+ 25424, 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256,
+ 25572, 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256,
+ 25705, 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, 25935, 256,
+ 25964, 256, 143370, 256, 26083, 256, 26360, 256, 26185, 256, 15129, 256,
+ 26257, 256, 15112, 256, 15076, 256, 20882, 256, 20885, 256, 26368, 256,
+ 26268, 256, 32941, 256, 17369, 256, 26391, 256, 26395, 256, 26401, 256,
+ 26462, 256, 26451, 256, 144323, 256, 15177, 256, 26618, 256, 26501, 256,
+ 26706, 256, 26757, 256, 144493, 256, 26766, 256, 26655, 256, 26900, 256,
+ 15261, 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256,
+ 27355, 256, 15384, 256, 27425, 256, 145575, 256, 27476, 256, 15438, 256,
+ 27506, 256, 27551, 256, 27578, 256, 27579, 256, 146061, 256, 138507, 256,
+ 146170, 256, 27726, 256, 146620, 256, 27839, 256, 27853, 256, 27751, 256,
+ 27926, 256, 27966, 256, 28023, 256, 27969, 256, 28009, 256, 28024, 256,
+ 28037, 256, 146718, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256,
+ 28363, 256, 28359, 256, 147153, 256, 28153, 256, 28526, 256, 147294, 256,
+ 147342, 256, 28614, 256, 28729, 256, 28702, 256, 28699, 256, 15766, 256,
+ 28746, 256, 28797, 256, 28791, 256, 28845, 256, 132389, 256, 28997, 256,
+ 148067, 256, 29084, 256, 148395, 256, 29224, 256, 29237, 256, 29264, 256,
+ 149000, 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562,
+ 256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, 16056, 256, 29767,
+ 256, 29788, 256, 29809, 256, 29829, 256, 29898, 256, 16155, 256, 29988,
+ 256, 150582, 256, 30014, 256, 150674, 256, 30064, 256, 139679, 256,
+ 30224, 256, 151457, 256, 151480, 256, 151620, 256, 16380, 256, 16392,
+ 256, 30452, 256, 151795, 256, 151794, 256, 151833, 256, 151859, 256,
+ 30494, 256, 30495, 256, 30495, 256, 30538, 256, 16441, 256, 30603, 256,
+ 16454, 256, 16534, 256, 152605, 256, 30798, 256, 30860, 256, 30924, 256,
+ 16611, 256, 153126, 256, 31062, 256, 153242, 256, 153285, 256, 31119,
+ 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, 31311, 256, 153980,
+ 256, 154279, 256, 154279, 256, 31470, 256, 16898, 256, 154539, 256,
+ 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, 256, 17056, 256,
+ 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, 256, 17153, 256,
+ 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, 256, 156231, 256,
+ 17241, 256, 156377, 256, 32634, 256, 156478, 256, 32661, 256, 32762, 256,
+ 32773, 256, 156890, 256, 156963, 256, 32864, 256, 157096, 256, 32880,
+ 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, 17419, 256, 33086,
+ 256, 23221, 256, 157607, 256, 157621, 256, 144275, 256, 144284, 256,
+ 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, 256, 33419, 256,
+ 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, 256, 33510, 256,
+ 158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, 256, 33571, 256,
+ 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, 256, 33740, 256,
+ 33756, 256, 158774, 256, 159083, 256, 158933, 256, 17707, 256, 34033,
+ 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, 159532, 256, 17757,
+ 256, 17761, 256, 159665, 256, 159954, 256, 17771, 256, 34384, 256, 34396,
+ 256, 34407, 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530,
+ 256, 34681, 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785,
+ 256, 34817, 256, 17913, 256, 34912, 256, 34915, 256, 161383, 256, 35031,
+ 256, 35038, 256, 17973, 256, 35066, 256, 13499, 256, 161966, 256, 162150,
+ 256, 18110, 256, 18119, 256, 35488, 256, 35565, 256, 35722, 256, 35925,
+ 256, 162984, 256, 36011, 256, 36033, 256, 36123, 256, 36215, 256, 163631,
+ 256, 133124, 256, 36299, 256, 36284, 256, 36336, 256, 133342, 256, 36564,
+ 256, 36664, 256, 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137,
+ 256, 165678, 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500,
+ 256, 37881, 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327,
+ 256, 167287, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261,
+ 256, 168474, 256, 19054, 256, 19062, 256, 38880, 256, 168970, 256, 19122,
+ 256, 169110, 256, 38923, 256, 38923, 256, 38953, 256, 169398, 256, 39138,
+ 256, 19251, 256, 39209, 256, 39335, 256, 39362, 256, 39422, 256, 19406,
+ 256, 170800, 256, 39698, 256, 40000, 256, 40189, 256, 19662, 256, 19693,
+ 256, 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256,
+ 172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256,
+ 40719, 256, 40726, 256, 40763, 256, 173568,
+};
+
+/* index tables for the decomposition data */
+#define DECOMP_SHIFT 8
+static unsigned char decomp_index1[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 16, 17, 18, 19, 20, 21, 22, 23, 7, 7, 7, 7, 7, 24,
+ 7, 7, 25, 26, 27, 28, 29, 30, 31, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 32, 33, 34, 35, 36, 37,
+ 38, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 39, 7, 7, 40, 41,
+ 42, 43, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 44, 45, 46, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+static unsigned short decomp_index2[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27,
+ 31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81,
+ 0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120,
+ 123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0,
+ 162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198,
+ 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240,
+ 243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279,
+ 282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318,
+ 321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357,
+ 360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0,
+ 396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432,
+ 435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471,
+ 474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513,
+ 516, 519, 522, 525, 528, 531, 534, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 542,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572,
+ 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614,
+ 617, 620, 623, 0, 626, 629, 632, 635, 638, 641, 0, 0, 644, 647, 650, 653,
+ 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 0, 0, 692,
+ 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734,
+ 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776,
+ 779, 782, 785, 788, 791, 794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806,
+ 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 866,
+ 869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 890, 892, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0,
+ 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927,
+ 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966,
+ 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0,
+ 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0,
+ 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0,
+ 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087,
+ 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0,
+ 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153,
+ 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174,
+ 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0,
+ 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210,
+ 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243,
+ 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1285, 1288, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0,
+ 1306, 1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0,
+ 1356, 0, 0, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1365, 0, 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0,
+ 0, 0, 0, 1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0,
+ 0, 0, 0, 1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1409, 1411, 1413, 0, 1415, 1417, 1419, 1421, 1423,
+ 1425, 1427, 1429, 1431, 1433, 1435, 0, 1437, 1439, 1441, 1443, 1445,
+ 1447, 1449, 1451, 1453, 1455, 1457, 1459, 1461, 1463, 1465, 1467, 1469,
+ 1471, 0, 1473, 1475, 1477, 1479, 1481, 1483, 1485, 1487, 1489, 1491,
+ 1493, 1495, 1497, 1499, 1501, 1503, 1505, 1507, 1509, 1511, 1513, 1515,
+ 1517, 1519, 1521, 1523, 1525, 1527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1531, 1533, 1535, 1537, 1539,
+ 1541, 1543, 1545, 1547, 1549, 1551, 1553, 1555, 1557, 1559, 1561, 1563,
+ 1565, 1567, 1569, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585, 1587,
+ 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1605, 1608, 1611, 1614, 1617, 1620, 1623, 1626,
+ 1629, 1632, 1635, 1638, 1641, 1644, 1647, 1650, 1653, 1656, 1659, 1662,
+ 1665, 1668, 1671, 1674, 1677, 1680, 1683, 1686, 1689, 1692, 1695, 1698,
+ 1701, 1704, 1707, 1710, 1713, 1716, 1719, 1722, 1725, 1728, 1731, 1734,
+ 1737, 1740, 1743, 1746, 1749, 1752, 1755, 1758, 1761, 1764, 1767, 1770,
+ 1773, 1776, 1779, 1782, 1785, 1788, 1791, 1794, 1797, 1800, 1803, 1806,
+ 1809, 1812, 1815, 1818, 1821, 1824, 1827, 1830, 1833, 1836, 1839, 1842,
+ 1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878,
+ 1881, 1884, 1887, 1890, 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914,
+ 1917, 1920, 1923, 1926, 1929, 1932, 1935, 1938, 1941, 1944, 1947, 1950,
+ 1953, 1956, 1959, 1962, 1965, 1968, 1971, 1974, 1977, 1980, 1983, 1986,
+ 1989, 1992, 1995, 1998, 2001, 2004, 2007, 2010, 2013, 2016, 2019, 2022,
+ 2025, 2028, 2031, 2034, 2037, 2040, 2043, 2046, 2049, 2052, 2055, 2058,
+ 2061, 2064, 2067, 2070, 0, 0, 0, 0, 2073, 2076, 2079, 2082, 2085, 2088,
+ 2091, 2094, 2097, 2100, 2103, 2106, 2109, 2112, 2115, 2118, 2121, 2124,
+ 2127, 2130, 2133, 2136, 2139, 2142, 2145, 2148, 2151, 2154, 2157, 2160,
+ 2163, 2166, 2169, 2172, 2175, 2178, 2181, 2184, 2187, 2190, 2193, 2196,
+ 2199, 2202, 2205, 2208, 2211, 2214, 2217, 2220, 2223, 2226, 2229, 2232,
+ 2235, 2238, 2241, 2244, 2247, 2250, 2253, 2256, 2259, 2262, 2265, 2268,
+ 2271, 2274, 2277, 2280, 2283, 2286, 2289, 2292, 2295, 2298, 2301, 2304,
+ 2307, 2310, 2313, 2316, 2319, 2322, 2325, 2328, 2331, 2334, 2337, 2340,
+ 0, 0, 0, 0, 0, 0, 2343, 2346, 2349, 2352, 2355, 2358, 2361, 2364, 2367,
+ 2370, 2373, 2376, 2379, 2382, 2385, 2388, 2391, 2394, 2397, 2400, 2403,
+ 2406, 0, 0, 2409, 2412, 2415, 2418, 2421, 2424, 0, 0, 2427, 2430, 2433,
+ 2436, 2439, 2442, 2445, 2448, 2451, 2454, 2457, 2460, 2463, 2466, 2469,
+ 2472, 2475, 2478, 2481, 2484, 2487, 2490, 2493, 2496, 2499, 2502, 2505,
+ 2508, 2511, 2514, 2517, 2520, 2523, 2526, 2529, 2532, 2535, 2538, 0, 0,
+ 2541, 2544, 2547, 2550, 2553, 2556, 0, 0, 2559, 2562, 2565, 2568, 2571,
+ 2574, 2577, 2580, 0, 2583, 0, 2586, 0, 2589, 0, 2592, 2595, 2598, 2601,
+ 2604, 2607, 2610, 2613, 2616, 2619, 2622, 2625, 2628, 2631, 2634, 2637,
+ 2640, 2643, 2646, 2648, 2651, 2653, 2656, 2658, 2661, 2663, 2666, 2668,
+ 2671, 2673, 2676, 0, 0, 2678, 2681, 2684, 2687, 2690, 2693, 2696, 2699,
+ 2702, 2705, 2708, 2711, 2714, 2717, 2720, 2723, 2726, 2729, 2732, 2735,
+ 2738, 2741, 2744, 2747, 2750, 2753, 2756, 2759, 2762, 2765, 2768, 2771,
+ 2774, 2777, 2780, 2783, 2786, 2789, 2792, 2795, 2798, 2801, 2804, 2807,
+ 2810, 2813, 2816, 2819, 2822, 2825, 2828, 2831, 2834, 0, 2837, 2840,
+ 2843, 2846, 2849, 2852, 2854, 2857, 2860, 2862, 2865, 2868, 2871, 2874,
+ 2877, 0, 2880, 2883, 2886, 2889, 2891, 2894, 2896, 2899, 2902, 2905,
+ 2908, 2911, 2914, 2917, 0, 0, 2919, 2922, 2925, 2928, 2931, 2934, 0,
+ 2936, 2939, 2942, 2945, 2948, 2951, 2954, 2956, 2959, 2962, 2965, 2968,
+ 2971, 2974, 2977, 2979, 2982, 2985, 2987, 0, 0, 2989, 2992, 2995, 0,
+ 2998, 3001, 3004, 3007, 3009, 3012, 3014, 3017, 3019, 0, 3022, 3024,
+ 3026, 3028, 3030, 3032, 3034, 3036, 3038, 3040, 3042, 0, 0, 0, 0, 0, 0,
+ 3044, 0, 0, 0, 0, 0, 3046, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3049,
+ 3051, 3054, 0, 0, 0, 0, 0, 0, 0, 0, 3058, 0, 0, 0, 3060, 3063, 0, 3067,
+ 3070, 0, 0, 0, 0, 3074, 0, 3077, 0, 0, 0, 0, 0, 0, 0, 0, 3080, 3083,
+ 3086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3089, 0, 0, 0, 0, 0, 0, 0,
+ 3094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3096, 3098, 0, 0,
+ 3100, 3102, 3104, 3106, 3108, 3110, 3112, 3114, 3116, 3118, 3120, 3122,
+ 3124, 3126, 3128, 3130, 3132, 3134, 3136, 3138, 3140, 3142, 3144, 3146,
+ 3148, 3150, 3152, 0, 3154, 3156, 3158, 3160, 3162, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3167, 3171, 3175, 3177, 0, 3180, 3184, 3188, 0, 3190,
+ 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 3213,
+ 3215, 0, 0, 3218, 3220, 3222, 3224, 3226, 0, 0, 3228, 3231, 3235, 0,
+ 3238, 0, 3240, 0, 3242, 0, 3244, 3246, 3248, 3250, 0, 3252, 3254, 3256,
+ 0, 3258, 3260, 3262, 3264, 3266, 3268, 3270, 0, 3272, 3276, 3278, 3280,
+ 3282, 3284, 0, 0, 0, 0, 3286, 3288, 3290, 3292, 3294, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3296, 3300, 3304, 3308, 3312, 3316, 3320, 3324, 3328, 3332,
+ 3336, 3340, 3344, 3347, 3349, 3352, 3356, 3359, 3361, 3364, 3368, 3373,
+ 3376, 3378, 3381, 3385, 3387, 3389, 3391, 3393, 3395, 3398, 3402, 3405,
+ 3407, 3410, 3414, 3419, 3422, 3424, 3427, 3431, 3433, 3435, 3437, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3439, 3442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3445,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3448, 3451, 3454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3457, 0, 0, 0, 0, 3460,
+ 0, 0, 3463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3466, 0, 3469, 0, 0, 0, 0, 0, 3472, 3475, 0, 3479, 3482, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3486, 0, 0, 3489, 0, 0, 3492,
+ 0, 3495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3498, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3504, 3507, 3510, 3513,
+ 3516, 0, 0, 3519, 3522, 0, 0, 3525, 3528, 0, 0, 0, 0, 0, 0, 3531, 3534,
+ 0, 0, 3537, 3540, 0, 0, 3543, 3546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3549,
+ 3552, 3555, 3558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3561, 3564, 3567, 3570, 0, 0, 0, 0, 0, 0, 3573, 3576,
+ 3579, 3582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3585, 3587, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3589, 3591, 3593, 3595,
+ 3597, 3599, 3601, 3603, 3605, 3607, 3610, 3613, 3616, 3619, 3622, 3625,
+ 3628, 3631, 3634, 3637, 3640, 3644, 3648, 3652, 3656, 3660, 3664, 3668,
+ 3672, 3676, 3681, 3686, 3691, 3696, 3701, 3706, 3711, 3716, 3721, 3726,
+ 3731, 3734, 3737, 3740, 3743, 3746, 3749, 3752, 3755, 3758, 3762, 3766,
+ 3770, 3774, 3778, 3782, 3786, 3790, 3794, 3798, 3802, 3806, 3810, 3814,
+ 3818, 3822, 3826, 3830, 3834, 3838, 3842, 3846, 3850, 3854, 3858, 3862,
+ 3866, 3870, 3874, 3878, 3882, 3886, 3890, 3894, 3898, 3902, 3906, 3908,
+ 3910, 3912, 3914, 3916, 3918, 3920, 3922, 3924, 3926, 3928, 3930, 3932,
+ 3934, 3936, 3938, 3940, 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956,
+ 3958, 3960, 3962, 3964, 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980,
+ 3982, 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004,
+ 4006, 4008, 4010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4012, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4017, 4021, 4024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4031, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4035, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4037, 4039, 4041, 4043, 4045, 4047,
+ 4049, 4051, 4053, 4055, 4057, 4059, 4061, 4063, 4065, 4067, 4069, 4071,
+ 4073, 4075, 4077, 4079, 4081, 4083, 4085, 4087, 4089, 4091, 4093, 4095,
+ 4097, 4099, 4101, 4103, 4105, 4107, 4109, 4111, 4113, 4115, 4117, 4119,
+ 4121, 4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, 4139, 4141, 4143,
+ 4145, 4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, 4163, 4165, 4167,
+ 4169, 4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, 4187, 4189, 4191,
+ 4193, 4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, 4211, 4213, 4215,
+ 4217, 4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, 4235, 4237, 4239,
+ 4241, 4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, 4259, 4261, 4263,
+ 4265, 4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, 4283, 4285, 4287,
+ 4289, 4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, 4307, 4309, 4311,
+ 4313, 4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, 4331, 4333, 4335,
+ 4337, 4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, 4355, 4357, 4359,
+ 4361, 4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, 4379, 4381, 4383,
+ 4385, 4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, 4403, 4405, 4407,
+ 4409, 4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, 4427, 4429, 4431,
+ 4433, 4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, 4451, 4453, 4455,
+ 4457, 4459, 4461, 4463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4467, 0, 4469, 4471, 4473, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4475, 0, 4478, 0, 4481, 0, 4484, 0,
+ 4487, 0, 4490, 0, 4493, 0, 4496, 0, 4499, 0, 4502, 0, 4505, 0, 4508, 0,
+ 0, 4511, 0, 4514, 0, 4517, 0, 0, 0, 0, 0, 0, 4520, 4523, 0, 4526, 4529,
+ 0, 4532, 4535, 0, 4538, 4541, 0, 4544, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4550, 0, 0, 0, 0, 0, 0, 4553,
+ 4556, 0, 4559, 4562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4565, 0, 4568,
+ 0, 4571, 0, 4574, 0, 4577, 0, 4580, 0, 4583, 0, 4586, 0, 4589, 0, 4592,
+ 0, 4595, 0, 4598, 0, 0, 4601, 0, 4604, 0, 4607, 0, 0, 0, 0, 0, 0, 4610,
+ 4613, 0, 4616, 4619, 0, 4622, 4625, 0, 4628, 4631, 0, 4634, 4637, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4640, 0, 0,
+ 4643, 4646, 4649, 4652, 0, 0, 0, 4655, 4658, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4661, 4663, 4665, 4667,
+ 4669, 4671, 4673, 4675, 4677, 4679, 4681, 4683, 4685, 4687, 4689, 4691,
+ 4693, 4695, 4697, 4699, 4701, 4703, 4705, 4707, 4709, 4711, 4713, 4715,
+ 4717, 4719, 4721, 4723, 4725, 4727, 4729, 4731, 4733, 4735, 4737, 4739,
+ 4741, 4743, 4745, 4747, 4749, 4751, 4753, 4755, 4757, 4759, 4761, 4763,
+ 4765, 4767, 4769, 4771, 4773, 4775, 4777, 4779, 4781, 4783, 4785, 4787,
+ 4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, 4805, 4807, 4809, 4811,
+ 4813, 4815, 4817, 4819, 4821, 4823, 4825, 4827, 4829, 4831, 4833, 4835,
+ 4837, 4839, 4841, 4843, 4845, 4847, 0, 0, 0, 4849, 4851, 4853, 4855,
+ 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, 4873, 4875, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4877, 4881,
+ 4885, 4889, 4893, 4897, 4901, 4905, 4909, 4913, 4917, 4921, 4925, 4929,
+ 4933, 4938, 4943, 4948, 4953, 4958, 4963, 4968, 4973, 4978, 4983, 4988,
+ 4993, 4998, 5003, 5008, 5016, 0, 5023, 5027, 5031, 5035, 5039, 5043,
+ 5047, 5051, 5055, 5059, 5063, 5067, 5071, 5075, 5079, 5083, 5087, 5091,
+ 5095, 5099, 5103, 5107, 5111, 5115, 5119, 5123, 5127, 5131, 5135, 5139,
+ 5143, 5147, 5151, 5155, 5159, 5163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5167, 5171, 5174, 5177, 5180, 5183, 5186, 5189, 5192, 5195, 5198, 5201,
+ 5204, 5207, 5210, 5213, 5216, 5218, 5220, 5222, 5224, 5226, 5228, 5230,
+ 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 5253, 5256, 5259,
+ 5262, 5265, 5268, 5271, 5274, 5277, 5280, 5283, 5286, 5292, 5297, 0,
+ 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, 5320, 5322,
+ 5324, 5326, 5328, 5330, 5332, 5334, 5336, 5338, 5340, 5342, 5344, 5346,
+ 5348, 5350, 5352, 5354, 5356, 5358, 5360, 5362, 5364, 5366, 5368, 5370,
+ 5372, 5374, 5376, 5378, 5380, 5382, 5384, 5386, 5388, 5390, 5392, 5394,
+ 5396, 5398, 5401, 5404, 5407, 5410, 5413, 5416, 5419, 5422, 5425, 5428,
+ 5431, 5434, 5437, 5440, 5443, 5446, 5449, 5452, 5455, 5458, 5461, 5464,
+ 5467, 5470, 5474, 5478, 5482, 5485, 5489, 5492, 5496, 5498, 5500, 5502,
+ 5504, 5506, 5508, 5510, 5512, 5514, 5516, 5518, 5520, 5522, 5524, 5526,
+ 5528, 5530, 5532, 5534, 5536, 5538, 5540, 5542, 5544, 5546, 5548, 5550,
+ 5552, 5554, 5556, 5558, 5560, 5562, 5564, 5566, 5568, 5570, 5572, 5574,
+ 5576, 5578, 5580, 5582, 5584, 5586, 5588, 0, 5590, 5595, 5600, 5605,
+ 5609, 5614, 5618, 5622, 5628, 5633, 5637, 5641, 5645, 5650, 5655, 5659,
+ 5663, 5666, 5670, 5675, 5680, 5683, 5689, 5696, 5702, 5706, 5712, 5718,
+ 5723, 5727, 5731, 5735, 5740, 5746, 5751, 5755, 5759, 5763, 5766, 5769,
+ 5772, 5775, 5779, 5783, 5789, 5793, 5798, 5804, 5808, 5811, 5814, 5820,
+ 5825, 5831, 5835, 5841, 5844, 5848, 5852, 5856, 5860, 5864, 5869, 5873,
+ 5876, 5880, 5884, 5888, 5893, 5897, 5901, 5905, 5911, 5916, 5919, 5925,
+ 5928, 5933, 5938, 5942, 5946, 5950, 5955, 5958, 5962, 5967, 5970, 5976,
+ 5980, 5983, 5986, 5989, 5992, 5995, 5998, 6001, 6004, 6007, 6010, 6014,
+ 6018, 6022, 6026, 6030, 6034, 6038, 6042, 6046, 6050, 6054, 6058, 6062,
+ 6066, 6070, 6074, 6077, 6080, 6084, 6087, 6090, 6093, 6097, 6101, 6104,
+ 6107, 6110, 6113, 6116, 6121, 6124, 6127, 6130, 6133, 6136, 6139, 6142,
+ 6145, 6149, 6154, 6157, 6160, 6163, 6166, 6169, 6172, 6175, 6179, 6183,
+ 6187, 6191, 6194, 6197, 6200, 6203, 6206, 6209, 6212, 6215, 6218, 6221,
+ 6225, 6229, 6232, 6236, 6240, 6244, 6247, 6251, 6255, 6260, 6263, 6267,
+ 6271, 6275, 6279, 6285, 6292, 6295, 6298, 6301, 6304, 6307, 6310, 6313,
+ 6316, 6319, 6322, 6325, 6328, 6331, 6334, 6337, 6340, 6343, 6346, 6351,
+ 6354, 6357, 6360, 6365, 6369, 6372, 6375, 6378, 6381, 6384, 6387, 6390,
+ 6393, 6396, 6399, 6403, 6406, 6409, 6413, 6417, 6420, 6425, 6429, 6432,
+ 6435, 6438, 6441, 6445, 6449, 6452, 6455, 6458, 6461, 6464, 6467, 6470,
+ 6473, 6476, 6480, 6484, 6488, 6492, 6496, 6500, 6504, 6508, 6512, 6516,
+ 6520, 6524, 6528, 6532, 6536, 6540, 6544, 6548, 6552, 6556, 6560, 6564,
+ 6568, 6570, 6572, 6574, 6576, 6578, 6580, 6582, 6584, 6586, 6588, 6590,
+ 6592, 6594, 6596, 6598, 6600, 6602, 6604, 6606, 6608, 6610, 6612, 6614,
+ 6616, 6618, 6620, 6622, 6624, 6626, 6628, 6630, 6632, 6634, 6636, 6638,
+ 6640, 6642, 6644, 6646, 6648, 6650, 6652, 6654, 6656, 6658, 6660, 6662,
+ 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, 6686,
+ 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, 6710,
+ 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, 6734,
+ 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, 6758,
+ 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, 6782,
+ 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, 6806,
+ 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, 6830,
+ 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, 6854,
+ 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, 6878,
+ 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, 6902,
+ 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, 6926,
+ 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, 6950,
+ 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, 6974,
+ 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, 6998,
+ 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, 7022,
+ 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, 7046,
+ 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, 7070,
+ 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, 7094,
+ 7096, 7098, 7100, 7102, 7104, 7106, 0, 0, 7108, 0, 7110, 0, 0, 7112,
+ 7114, 7116, 7118, 7120, 7122, 7124, 7126, 7128, 7130, 0, 7132, 0, 7134,
+ 0, 0, 7136, 7138, 0, 0, 0, 7140, 7142, 7144, 7146, 0, 0, 7148, 7150,
+ 7152, 7154, 7156, 7158, 7160, 7162, 7164, 7166, 7168, 7170, 7172, 7174,
+ 7176, 7178, 7180, 7182, 7184, 7186, 7188, 7190, 7192, 7194, 7196, 7198,
+ 7200, 7202, 7204, 7206, 7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222,
+ 7224, 7226, 7228, 7230, 7232, 7234, 7236, 7238, 7240, 7242, 7244, 7246,
+ 7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, 0, 0, 0, 0, 0,
+ 7266, 7268, 7270, 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288,
+ 7290, 7292, 7294, 7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312,
+ 7314, 7316, 7318, 7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336,
+ 7338, 7340, 7342, 7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360,
+ 7362, 7364, 7366, 7368, 7370, 7372, 7374, 7376, 7378, 7380, 7382, 7384,
+ 7386, 7388, 7390, 7392, 7394, 7396, 7398, 7400, 7402, 7404, 7406, 7408,
+ 7410, 7412, 7414, 7416, 7418, 7420, 7422, 7424, 7426, 7428, 7430, 7432,
+ 7434, 7436, 7438, 7440, 7442, 7444, 7446, 7448, 7450, 7452, 7454, 7456,
+ 7458, 7460, 7462, 7464, 7466, 7468, 7470, 7472, 7474, 7476, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7478, 7481, 7484, 7487, 7491, 7495, 7498,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7501, 7504, 7507, 7510, 7513, 0, 0,
+ 0, 0, 0, 7516, 0, 7519, 7522, 7524, 7526, 7528, 7530, 7532, 7534, 7536,
+ 7538, 7540, 7542, 7545, 7548, 7551, 7554, 7557, 7560, 7563, 7566, 7569,
+ 7572, 7575, 7578, 0, 7581, 7584, 7587, 7590, 7593, 0, 7596, 0, 7599,
+ 7602, 0, 7605, 7608, 0, 7611, 7614, 7617, 7620, 7623, 7626, 7629, 7632,
+ 7635, 7638, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7655, 7657, 7659,
+ 7661, 7663, 7665, 7667, 7669, 7671, 7673, 7675, 7677, 7679, 7681, 7683,
+ 7685, 7687, 7689, 7691, 7693, 7695, 7697, 7699, 7701, 7703, 7705, 7707,
+ 7709, 7711, 7713, 7715, 7717, 7719, 7721, 7723, 7725, 7727, 7729, 7731,
+ 7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751, 7753, 7755,
+ 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779,
+ 7781, 7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803,
+ 7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827,
+ 7829, 7831, 7833, 7835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7837, 7839, 7841,
+ 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865,
+ 7867, 7869, 7871, 7873, 7875, 7877, 7879, 7881, 7883, 7886, 7889, 7892,
+ 7895, 7898, 7901, 7904, 7907, 7910, 7913, 7916, 7919, 7922, 7925, 7928,
+ 7931, 7934, 7937, 7939, 7941, 7943, 7945, 7948, 7951, 7954, 7957, 7960,
+ 7963, 7966, 7969, 7972, 7975, 7978, 7981, 7984, 7987, 7990, 7993, 7996,
+ 7999, 8002, 8005, 8008, 8011, 8014, 8017, 8020, 8023, 8026, 8029, 8032,
+ 8035, 8038, 8041, 8044, 8047, 8050, 8053, 8056, 8059, 8062, 8065, 8068,
+ 8071, 8074, 8077, 8080, 8083, 8086, 8089, 8092, 8095, 8098, 8101, 8104,
+ 8107, 8110, 8113, 8116, 8119, 8122, 8125, 8128, 8131, 8134, 8137, 8140,
+ 8143, 8146, 8149, 8152, 8155, 8158, 8161, 8164, 8167, 8170, 8173, 8176,
+ 8179, 8182, 8185, 8188, 8191, 8194, 8197, 8200, 8203, 8206, 8209, 8212,
+ 8215, 8218, 8221, 8224, 8227, 8231, 8235, 8239, 8243, 8247, 8251, 8254,
+ 8257, 8260, 8263, 8266, 8269, 8272, 8275, 8278, 8281, 8284, 8287, 8290,
+ 8293, 8296, 8299, 8302, 8305, 8308, 8311, 8314, 8317, 8320, 8323, 8326,
+ 8329, 8332, 8335, 8338, 8341, 8344, 8347, 8350, 8353, 8356, 8359, 8362,
+ 8365, 8368, 8371, 8374, 8377, 8380, 8383, 8386, 8389, 8392, 8395, 8398,
+ 8401, 8404, 8407, 8410, 8413, 8416, 8419, 8422, 8425, 8428, 8431, 8434,
+ 8437, 8440, 8443, 8446, 8449, 8452, 8455, 8458, 8461, 8464, 8467, 8470,
+ 8473, 8476, 8479, 8482, 8485, 8488, 8491, 8494, 8497, 8500, 8503, 8506,
+ 8509, 8512, 8515, 8518, 8521, 8524, 8527, 8530, 8533, 8536, 8539, 8542,
+ 8545, 8548, 8551, 8554, 8557, 8560, 8563, 8566, 8569, 8572, 8575, 8578,
+ 8581, 8584, 8587, 8590, 8593, 8596, 8599, 8602, 8605, 8608, 8611, 8614,
+ 8617, 8620, 8623, 8626, 8629, 8632, 8635, 8638, 8641, 8644, 8647, 8650,
+ 8653, 8656, 8659, 8662, 8665, 8668, 8671, 8674, 8677, 8681, 8685, 8689,
+ 8692, 8695, 8698, 8701, 8704, 8707, 8710, 8713, 8716, 8719, 8722, 8725,
+ 8728, 8731, 8734, 8737, 8740, 8743, 8746, 8749, 8752, 8755, 8758, 8761,
+ 8764, 8767, 8770, 8773, 8776, 8779, 8782, 8785, 8788, 8791, 8794, 8797,
+ 8800, 8803, 8806, 8809, 8812, 8815, 8818, 8821, 8824, 8827, 8830, 8833,
+ 8836, 8839, 8842, 8845, 8848, 8851, 8854, 8857, 8860, 8863, 8866, 8869,
+ 8872, 8875, 8878, 8881, 8884, 8887, 8890, 8893, 8896, 8899, 8902, 8905,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8908, 8912, 8916,
+ 8920, 8924, 8928, 8932, 8936, 8940, 8944, 8948, 8952, 8956, 8960, 8964,
+ 8968, 8972, 8976, 8980, 8984, 8988, 8992, 8996, 9000, 9004, 9008, 9012,
+ 9016, 9020, 9024, 9028, 9032, 9036, 9040, 9044, 9048, 9052, 9056, 9060,
+ 9064, 9068, 9072, 9076, 9080, 9084, 9088, 9092, 9096, 9100, 9104, 9108,
+ 9112, 9116, 9120, 9124, 9128, 9132, 9136, 9140, 9144, 9148, 9152, 9156,
+ 9160, 0, 0, 9164, 9168, 9172, 9176, 9180, 9184, 9188, 9192, 9196, 9200,
+ 9204, 9208, 9212, 9216, 9220, 9224, 9228, 9232, 9236, 9240, 9244, 9248,
+ 9252, 9256, 9260, 9264, 9268, 9272, 9276, 9280, 9284, 9288, 9292, 9296,
+ 9300, 9304, 9308, 9312, 9316, 9320, 9324, 9328, 9332, 9336, 9340, 9344,
+ 9348, 9352, 9356, 9360, 9364, 9368, 9372, 9376, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 9380, 9384, 9388, 9393, 9398, 9403, 9408, 9413,
+ 9418, 9423, 9427, 9446, 9455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9460, 9462, 9464, 9466, 9468, 9470, 9472, 9474, 9476,
+ 9478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 9480, 9482, 9484, 9486, 9488, 9490, 9492, 9494, 9496, 9498, 9500, 9502,
+ 9504, 9506, 9508, 9510, 9512, 9514, 9516, 9518, 9520, 0, 0, 9522, 9524,
+ 9526, 9528, 9530, 9532, 9534, 9536, 9538, 9540, 9542, 9544, 0, 9546,
+ 9548, 9550, 9552, 9554, 9556, 9558, 9560, 9562, 9564, 9566, 9568, 9570,
+ 9572, 9574, 9576, 9578, 9580, 9582, 0, 9584, 9586, 9588, 9590, 0, 0, 0,
+ 0, 9592, 9595, 9598, 0, 9601, 0, 9604, 9607, 9610, 9613, 9616, 9619,
+ 9622, 9625, 9628, 9631, 9634, 9636, 9638, 9640, 9642, 9644, 9646, 9648,
+ 9650, 9652, 9654, 9656, 9658, 9660, 9662, 9664, 9666, 9668, 9670, 9672,
+ 9674, 9676, 9678, 9680, 9682, 9684, 9686, 9688, 9690, 9692, 9694, 9696,
+ 9698, 9700, 9702, 9704, 9706, 9708, 9710, 9712, 9714, 9716, 9718, 9720,
+ 9722, 9724, 9726, 9728, 9730, 9732, 9734, 9736, 9738, 9740, 9742, 9744,
+ 9746, 9748, 9750, 9752, 9754, 9756, 9758, 9760, 9762, 9764, 9766, 9768,
+ 9770, 9772, 9774, 9776, 9778, 9780, 9782, 9784, 9786, 9788, 9790, 9792,
+ 9794, 9796, 9798, 9800, 9802, 9804, 9806, 9808, 9810, 9812, 9814, 9816,
+ 9818, 9820, 9822, 9824, 9826, 9828, 9830, 9832, 9834, 9836, 9838, 9840,
+ 9842, 9844, 9846, 9848, 9850, 9852, 9854, 9856, 9858, 9860, 9862, 9864,
+ 9866, 9868, 9871, 9874, 9877, 9880, 9883, 9886, 9889, 0, 0, 0, 0, 9892,
+ 9894, 9896, 9898, 9900, 9902, 9904, 9906, 9908, 9910, 9912, 9914, 9916,
+ 9918, 9920, 9922, 9924, 9926, 9928, 9930, 9932, 9934, 9936, 9938, 9940,
+ 9942, 9944, 9946, 9948, 9950, 9952, 9954, 9956, 9958, 9960, 9962, 9964,
+ 9966, 9968, 9970, 9972, 9974, 9976, 9978, 9980, 9982, 9984, 9986, 9988,
+ 9990, 9992, 9994, 9996, 9998, 10000, 10002, 10004, 10006, 10008, 10010,
+ 10012, 10014, 10016, 10018, 10020, 10022, 10024, 10026, 10028, 10030,
+ 10032, 10034, 10036, 10038, 10040, 10042, 10044, 10046, 10048, 10050,
+ 10052, 10054, 10056, 10058, 10060, 10062, 10064, 10066, 10068, 10070,
+ 10072, 10074, 10076, 10078, 10080, 10082, 10084, 10086, 10088, 10090,
+ 10092, 10094, 10096, 10098, 10100, 10102, 10104, 10106, 10108, 10110,
+ 10112, 10114, 10116, 10118, 10120, 10122, 10124, 10126, 10128, 10130,
+ 10132, 10134, 10136, 10138, 10140, 10142, 10144, 10146, 10148, 10150,
+ 10152, 10154, 10156, 10158, 10160, 10162, 10164, 10166, 10168, 10170,
+ 10172, 10174, 10176, 10178, 10180, 10182, 10184, 10186, 10188, 10190,
+ 10192, 10194, 10196, 10198, 10200, 10202, 10204, 10206, 10208, 10210,
+ 10212, 10214, 10216, 10218, 10220, 10222, 10224, 10226, 10228, 10230,
+ 10232, 10234, 10236, 10238, 10240, 10242, 10244, 10246, 10248, 10250,
+ 10252, 10254, 10256, 10258, 10260, 10262, 10264, 10266, 10268, 10270, 0,
+ 0, 0, 10272, 10274, 10276, 10278, 10280, 10282, 0, 0, 10284, 10286,
+ 10288, 10290, 10292, 10294, 0, 0, 10296, 10298, 10300, 10302, 10304,
+ 10306, 0, 0, 10308, 10310, 10312, 0, 0, 0, 10314, 10316, 10318, 10320,
+ 10322, 10324, 10326, 0, 10328, 10330, 10332, 10334, 10336, 10338, 10340,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10342, 10345, 10348, 10351,
+ 10354, 10357, 10360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10363,
+ 10366, 10369, 10372, 10375, 10378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10381, 10383, 10385, 10387, 10389, 10391, 10393, 10395, 10397,
+ 10399, 10401, 10403, 10405, 10407, 10409, 10411, 10413, 10415, 10417,
+ 10419, 10421, 10423, 10425, 10427, 10429, 10431, 10433, 10435, 10437,
+ 10439, 10441, 10443, 10445, 10447, 10449, 10451, 10453, 10455, 10457,
+ 10459, 10461, 10463, 10465, 10467, 10469, 10471, 10473, 10475, 10477,
+ 10479, 10481, 10483, 10485, 10487, 10489, 10491, 10493, 10495, 10497,
+ 10499, 10501, 10503, 10505, 10507, 10509, 10511, 10513, 10515, 10517,
+ 10519, 10521, 10523, 10525, 10527, 10529, 10531, 10533, 10535, 10537,
+ 10539, 10541, 10543, 10545, 10547, 10549, 0, 10551, 10553, 10555, 10557,
+ 10559, 10561, 10563, 10565, 10567, 10569, 10571, 10573, 10575, 10577,
+ 10579, 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, 10597,
+ 10599, 10601, 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617,
+ 10619, 10621, 10623, 10625, 10627, 10629, 10631, 10633, 10635, 10637,
+ 10639, 10641, 10643, 10645, 10647, 10649, 10651, 10653, 10655, 10657,
+ 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677,
+ 10679, 10681, 10683, 10685, 10687, 10689, 10691, 0, 10693, 10695, 0, 0,
+ 10697, 0, 0, 10699, 10701, 0, 0, 10703, 10705, 10707, 10709, 0, 10711,
+ 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, 10729, 10731,
+ 10733, 0, 10735, 0, 10737, 10739, 10741, 10743, 10745, 10747, 10749, 0,
+ 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, 10769,
+ 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, 10789,
+ 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, 10809,
+ 10811, 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, 10829,
+ 10831, 10833, 10835, 10837, 10839, 10841, 10843, 10845, 10847, 10849,
+ 10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, 10869,
+ 10871, 10873, 10875, 10877, 10879, 0, 10881, 10883, 10885, 10887, 0, 0,
+ 10889, 10891, 10893, 10895, 10897, 10899, 10901, 10903, 0, 10905, 10907,
+ 10909, 10911, 10913, 10915, 10917, 0, 10919, 10921, 10923, 10925, 10927,
+ 10929, 10931, 10933, 10935, 10937, 10939, 10941, 10943, 10945, 10947,
+ 10949, 10951, 10953, 10955, 10957, 10959, 10961, 10963, 10965, 10967,
+ 10969, 10971, 10973, 0, 10975, 10977, 10979, 10981, 0, 10983, 10985,
+ 10987, 10989, 10991, 0, 10993, 0, 0, 0, 10995, 10997, 10999, 11001,
+ 11003, 11005, 11007, 0, 11009, 11011, 11013, 11015, 11017, 11019, 11021,
+ 11023, 11025, 11027, 11029, 11031, 11033, 11035, 11037, 11039, 11041,
+ 11043, 11045, 11047, 11049, 11051, 11053, 11055, 11057, 11059, 11061,
+ 11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, 11079, 11081,
+ 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, 11099, 11101,
+ 11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, 11119, 11121,
+ 11123, 11125, 11127, 11129, 11131, 11133, 11135, 11137, 11139, 11141,
+ 11143, 11145, 11147, 11149, 11151, 11153, 11155, 11157, 11159, 11161,
+ 11163, 11165, 11167, 11169, 11171, 11173, 11175, 11177, 11179, 11181,
+ 11183, 11185, 11187, 11189, 11191, 11193, 11195, 11197, 11199, 11201,
+ 11203, 11205, 11207, 11209, 11211, 11213, 11215, 11217, 11219, 11221,
+ 11223, 11225, 11227, 11229, 11231, 11233, 11235, 11237, 11239, 11241,
+ 11243, 11245, 11247, 11249, 11251, 11253, 11255, 11257, 11259, 11261,
+ 11263, 11265, 11267, 11269, 11271, 11273, 11275, 11277, 11279, 11281,
+ 11283, 11285, 11287, 11289, 11291, 11293, 11295, 11297, 11299, 11301,
+ 11303, 11305, 11307, 11309, 11311, 11313, 11315, 11317, 11319, 11321,
+ 11323, 11325, 11327, 11329, 11331, 11333, 11335, 11337, 11339, 11341,
+ 11343, 11345, 11347, 11349, 11351, 11353, 11355, 11357, 11359, 11361,
+ 11363, 11365, 11367, 11369, 11371, 11373, 11375, 11377, 11379, 11381,
+ 11383, 11385, 11387, 11389, 11391, 11393, 11395, 11397, 11399, 11401,
+ 11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421,
+ 11423, 11425, 11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441,
+ 11443, 11445, 11447, 11449, 11451, 11453, 11455, 11457, 11459, 11461,
+ 11463, 11465, 11467, 11469, 11471, 11473, 11475, 11477, 11479, 11481,
+ 11483, 11485, 11487, 11489, 11491, 11493, 11495, 11497, 11499, 11501,
+ 11503, 11505, 11507, 11509, 11511, 11513, 11515, 11517, 11519, 11521,
+ 11523, 11525, 11527, 11529, 11531, 11533, 11535, 11537, 11539, 11541,
+ 11543, 11545, 11547, 11549, 11551, 11553, 11555, 11557, 11559, 11561,
+ 11563, 11565, 11567, 11569, 11571, 11573, 11575, 11577, 11579, 11581,
+ 11583, 11585, 11587, 11589, 11591, 11593, 11595, 11597, 11599, 11601,
+ 11603, 11605, 11607, 11609, 11611, 11613, 11615, 11617, 11619, 11621,
+ 11623, 11625, 11627, 11629, 11631, 11633, 11635, 11637, 11639, 11641,
+ 11643, 11645, 11647, 11649, 11651, 11653, 11655, 11657, 11659, 11661,
+ 11663, 11665, 11667, 11669, 11671, 11673, 11675, 11677, 11679, 11681,
+ 11683, 11685, 11687, 0, 0, 11689, 11691, 11693, 11695, 11697, 11699,
+ 11701, 11703, 11705, 11707, 11709, 11711, 11713, 11715, 11717, 11719,
+ 11721, 11723, 11725, 11727, 11729, 11731, 11733, 11735, 11737, 11739,
+ 11741, 11743, 11745, 11747, 11749, 11751, 11753, 11755, 11757, 11759,
+ 11761, 11763, 11765, 11767, 11769, 11771, 11773, 11775, 11777, 11779,
+ 11781, 11783, 11785, 11787, 11789, 11791, 11793, 11795, 11797, 11799,
+ 11801, 11803, 11805, 11807, 11809, 11811, 11813, 11815, 11817, 11819,
+ 11821, 11823, 11825, 11827, 11829, 11831, 11833, 11835, 11837, 11839,
+ 11841, 11843, 11845, 11847, 11849, 11851, 11853, 11855, 11857, 11859,
+ 11861, 11863, 11865, 11867, 11869, 11871, 11873, 11875, 11877, 11879,
+ 11881, 11883, 11885, 11887, 11889, 11891, 11893, 11895, 11897, 11899,
+ 11901, 11903, 11905, 11907, 11909, 11911, 11913, 11915, 11917, 11919,
+ 11921, 11923, 11925, 11927, 11929, 11931, 11933, 11935, 11937, 11939,
+ 11941, 11943, 11945, 11947, 11949, 11951, 11953, 11955, 11957, 11959,
+ 11961, 11963, 11965, 11967, 11969, 11971, 11973, 11975, 11977, 11979,
+ 11981, 11983, 11985, 11987, 11989, 11991, 11993, 11995, 11997, 11999,
+ 12001, 12003, 12005, 12007, 12009, 12011, 12013, 12015, 12017, 12019,
+ 12021, 12023, 12025, 12027, 12029, 12031, 12033, 12035, 12037, 12039,
+ 12041, 12043, 12045, 12047, 12049, 12051, 12053, 12055, 12057, 12059,
+ 12061, 12063, 12065, 12067, 12069, 12071, 12073, 12075, 12077, 12079,
+ 12081, 12083, 12085, 12087, 12089, 12091, 12093, 12095, 12097, 12099,
+ 12101, 12103, 12105, 12107, 12109, 12111, 12113, 12115, 12117, 12119,
+ 12121, 12123, 12125, 12127, 12129, 12131, 12133, 12135, 12137, 12139,
+ 12141, 12143, 12145, 12147, 12149, 12151, 12153, 12155, 12157, 12159,
+ 12161, 12163, 12165, 12167, 12169, 12171, 12173, 12175, 12177, 12179,
+ 12181, 12183, 12185, 12187, 12189, 12191, 12193, 12195, 12197, 12199,
+ 12201, 12203, 12205, 12207, 12209, 12211, 12213, 12215, 12217, 12219,
+ 12221, 12223, 12225, 12227, 12229, 12231, 12233, 12235, 12237, 12239,
+ 12241, 12243, 12245, 12247, 12249, 12251, 12253, 12255, 12257, 12259,
+ 12261, 12263, 12265, 12267, 0, 0, 0, 0, 12269, 12271, 12273, 12275,
+ 12277, 12279, 12281, 12283, 12285, 12287, 12289, 12291, 12293, 12295,
+ 12297, 12299, 12301, 12303, 12305, 12307, 12309, 12311, 12313, 12315,
+ 12317, 12319, 12321, 12323, 12325, 12327, 12329, 12331, 12333, 12335,
+ 12337, 12339, 12341, 12343, 12345, 12347, 12349, 12351, 12353, 12355,
+ 12357, 12359, 12361, 12363, 12365, 12367, 12369, 12371, 12373, 12375,
+ 12377, 12379, 12381, 12383, 12385, 12387, 12389, 12391, 12393, 12395,
+ 12397, 12399, 12401, 12403, 12405, 12407, 12409, 12411, 12413, 12415,
+ 12417, 12419, 12421, 12423, 12425, 12427, 12429, 12431, 12433, 12435,
+ 12437, 12439, 12441, 12443, 12445, 12447, 12449, 12451, 12453, 12455,
+ 12457, 12459, 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475,
+ 12477, 12479, 12481, 12483, 12485, 12487, 12489, 12491, 12493, 12495,
+ 12497, 12499, 12501, 12503, 12505, 12507, 12509, 12511, 12513, 12515,
+ 12517, 12519, 12521, 12523, 12525, 12527, 12529, 12531, 12533, 12535,
+ 12537, 12539, 12541, 12543, 12545, 12547, 12549, 12551, 12553, 12555,
+ 12557, 12559, 12561, 12563, 12565, 12567, 12569, 12571, 12573, 12575,
+ 12577, 12579, 12581, 12583, 12585, 12587, 12589, 12591, 12593, 12595,
+ 12597, 12599, 12601, 12603, 12605, 12607, 12609, 12611, 12613, 12615,
+ 12617, 12619, 12621, 12623, 12625, 12627, 12629, 12631, 12633, 12635,
+ 12637, 12639, 12641, 12643, 12645, 12647, 12649, 12651, 12653, 12655,
+ 12657, 12659, 12661, 12663, 12665, 12667, 12669, 12671, 12673, 12675,
+ 12677, 12679, 12681, 12683, 12685, 12687, 12689, 12691, 12693, 12695,
+ 12697, 12699, 12701, 12703, 12705, 12707, 12709, 12711, 12713, 12715,
+ 12717, 12719, 12721, 12723, 12725, 12727, 12729, 12731, 12733, 12735,
+ 12737, 12739, 12741, 12743, 12745, 12747, 12749, 12751, 12753, 12755,
+ 12757, 12759, 12761, 12763, 12765, 12767, 12769, 12771, 12773, 12775,
+ 12777, 12779, 12781, 12783, 12785, 12787, 12789, 12791, 12793, 12795,
+ 12797, 12799, 12801, 12803, 12805, 12807, 12809, 12811, 12813, 12815,
+ 12817, 12819, 12821, 12823, 12825, 12827, 12829, 12831, 12833, 12835,
+ 12837, 12839, 12841, 12843, 12845, 12847, 12849, 12851, 12853, 12855,
+ 12857, 12859, 12861, 12863, 12865, 12867, 12869, 12871, 12873, 12875,
+ 12877, 12879, 12881, 12883, 12885, 12887, 12889, 12891, 12893, 12895,
+ 12897, 12899, 12901, 12903, 12905, 12907, 12909, 12911, 12913, 12915,
+ 12917, 12919, 12921, 12923, 12925, 12927, 12929, 12931, 12933, 12935,
+ 12937, 12939, 12941, 12943, 12945, 12947, 12949, 12951, 12953, 12955,
+ 12957, 12959, 12961, 12963, 12965, 12967, 12969, 12971, 12973, 12975,
+ 12977, 12979, 12981, 12983, 12985, 12987, 12989, 12991, 12993, 12995,
+ 12997, 12999, 13001, 13003, 13005, 13007, 13009, 13011, 13013, 13015,
+ 13017, 13019, 13021, 13023, 13025, 13027, 13029, 13031, 13033, 13035,
+ 13037, 13039, 13041, 13043, 13045, 13047, 13049, 13051, 13053, 13055,
+ 13057, 13059, 13061, 13063, 13065, 13067, 13069, 13071, 13073, 13075,
+ 13077, 13079, 13081, 13083, 13085, 13087, 13089, 13091, 13093, 13095,
+ 13097, 13099, 13101, 13103, 13105, 13107, 13109, 13111, 13113, 13115,
+ 13117, 13119, 13121, 13123, 13125, 13127, 13129, 13131, 13133, 13135,
+ 13137, 13139, 13141, 13143, 13145, 13147, 13149, 13151, 13153, 13155,
+ 13157, 13159, 13161, 13163, 13165, 13167, 13169, 13171, 13173, 13175,
+ 13177, 13179, 13181, 13183, 13185, 13187, 13189, 13191, 13193, 13195,
+ 13197, 13199, 13201, 13203, 13205, 13207, 13209, 13211, 13213, 13215,
+ 13217, 13219, 13221, 13223, 13225, 13227, 13229, 13231, 13233, 13235,
+ 13237, 13239, 13241, 13243, 13245, 13247, 13249, 13251, 13253, 13255,
+ 13257, 13259, 13261, 13263, 13265, 13267, 13269, 13271, 13273, 13275,
+ 13277, 13279, 13281, 13283, 13285, 13287, 13289, 13291, 13293, 13295,
+ 13297, 13299, 13301, 13303, 13305, 13307, 13309, 13311, 13313, 13315,
+ 13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, 13335,
+ 13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, 13355,
+ 13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, 13375,
+ 13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, 13395,
+ 13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, 13415,
+ 13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, 13435,
+ 13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+
+/* NFC pairs */
+#define COMP_SHIFT 3
+static unsigned short comp_index[] = {
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 4, 5, 6, 7, 0,
+ 0, 0, 0, 8, 9, 10, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0,
+ 18, 19, 20, 21, 0, 0, 0, 22, 0, 0, 0, 0, 0, 23, 24, 25, 26, 0, 0, 0, 27,
+ 28, 29, 30, 0, 0, 31, 32, 33, 34, 35, 0, 0, 36, 0, 0, 0, 0, 0, 0, 37, 38,
+ 39, 40, 0, 0, 41, 0, 42, 43, 44, 0, 0, 45, 46, 47, 0, 0, 0, 0, 48, 49,
+ 50, 51, 0, 0, 52, 53, 54, 55, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 58, 59, 60,
+ 61, 0, 0, 62, 63, 64, 65, 0, 0, 0, 66, 67, 68, 69, 0, 0, 70, 71, 72, 73,
+ 0, 0, 0, 74, 0, 75, 0, 0, 0, 0, 76, 0, 77, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0,
+ 79, 80, 81, 0, 0, 0, 0, 82, 83, 84, 85, 0, 0, 86, 87, 88, 89, 0, 0, 0,
+ 90, 0, 91, 92, 0, 0, 93, 94, 95, 96, 0, 0, 0, 0, 97, 98, 99, 0, 0, 0,
+ 100, 101, 102, 103, 0, 0, 0, 104, 0, 0, 0, 0, 0, 105, 106, 107, 0, 0, 0,
+ 0, 108, 109, 110, 111, 0, 0, 112, 113, 114, 115, 0, 0, 0, 116, 117, 0, 0,
+ 0, 0, 118, 0, 119, 120, 121, 0, 0, 122, 123, 124, 125, 0, 0, 0, 126, 0,
+ 127, 0, 0, 0, 128, 129, 130, 131, 0, 0, 0, 132, 133, 134, 135, 0, 0, 0,
+ 136, 0, 0, 0, 0, 0, 137, 138, 139, 140, 0, 0, 0, 141, 142, 143, 0, 0, 0,
+ 0, 144, 145, 146, 147, 0, 0, 148, 149, 150, 151, 0, 0, 0, 152, 0, 153, 0,
+ 0, 0, 154, 155, 156, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 158, 159, 160, 161,
+ 0, 0, 0, 162, 163, 164, 165, 0, 0, 0, 166, 0, 0, 167, 0, 0, 168, 169, 0,
+ 0, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 172, 173, 0, 0, 0,
+ 0, 0, 174, 0, 0, 0, 0, 0, 175, 176, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0,
+ 178, 179, 0, 0, 0, 0, 180, 181, 0, 0, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0,
+ 183, 0, 0, 0, 0, 0, 184, 185, 186, 0, 0, 0, 0, 187, 188, 0, 0, 0, 0, 0,
+ 189, 0, 0, 0, 0, 0, 190, 0, 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, 0, 192, 0, 0,
+ 0, 0, 0, 0, 193, 194, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 196, 197, 0, 0,
+ 0, 0, 0, 198, 199, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0,
+ 0, 202, 203, 0, 0, 0, 0, 204, 205, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0,
+ 0, 208, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 211,
+ 212, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 215, 0,
+ 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 218, 0, 0, 0, 0,
+ 0, 0, 0, 219, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 221, 0, 0, 0, 0, 0,
+ 222, 223, 224, 0, 0, 0, 225, 226, 227, 0, 0, 0, 0, 228, 229, 230, 0, 0,
+ 0, 0, 231, 232, 233, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 235, 0, 0, 0, 0, 0,
+ 0, 236, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 239,
+ 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 242, 0, 0,
+ 0, 0, 0, 0, 243, 0, 0, 0, 0, 244, 245, 246, 0, 247, 0, 0, 248, 0, 249, 0,
+ 0, 0, 0, 250, 251, 252, 253, 0, 0, 254, 255, 256, 0, 0, 0, 0, 257, 0,
+ 258, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 260, 261, 262, 0, 0, 0, 0, 263, 0,
+ 264, 265, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 267, 0, 0, 268, 269,
+ 270, 271, 0, 0, 272, 0, 273, 0, 0, 0, 0, 274, 0, 275, 276, 277, 0, 0,
+ 278, 279, 0, 280, 0, 0, 281, 0, 282, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, 284,
+ 285, 286, 0, 287, 0, 0, 288, 0, 289, 0, 290, 0, 0, 291, 0, 0, 292, 0, 0,
+ 293, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 295, 0, 0, 296, 0, 0, 0, 0, 0, 0,
+ 297, 0, 0, 0, 0, 0, 298, 299, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 301,
+ 302, 0, 0, 0, 0, 0, 303, 304, 0, 0, 0, 0, 0, 305, 0, 0, 0, 0, 0, 306,
+ 307, 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 310, 311,
+ 0, 0, 0, 0, 0, 312, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 314, 0, 0,
+ 0, 0, 0, 315, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 317, 0, 0, 0, 0, 0,
+ 0, 318, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 320, 321, 0, 0, 0, 0, 0, 322,
+ 0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, 0, 0, 324, 325, 0, 0, 0, 0, 0, 326, 0,
+ 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0,
+ 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0,
+ 333, 0, 0, 0, 0, 0, 0, 334, 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 336, 0, 0, 0, 0, 0, 0, 337, 0, 0, 0, 0, 0, 338, 0, 0, 0, 0, 0, 0, 339,
+ 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0,
+ 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 345, 0, 0, 0, 0,
+ 0, 0, 346, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0,
+ 349, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 352,
+ 353, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 356, 0,
+ 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 358, 0, 0, 0, 0, 0, 0, 359, 360, 0, 0,
+ 0, 0, 0, 0, 361, 0, 0, 0, 0, 0, 362, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0,
+ 0, 0, 364, 0, 0, 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 367,
+ 368, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 371, 0, 0,
+ 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 373, 0, 0, 0, 374, 0, 0, 375, 0, 0, 376,
+ 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 379, 0, 0,
+ 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 382, 0, 0, 383, 0,
+ 0, 0, 384, 0, 0, 385, 0, 0, 386, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0,
+ 388, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 391, 0, 0,
+ 0, 0, 0, 0, 392, 0, 0, 393, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 395, 0,
+ 0, 0, 0, 0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 398, 0, 0, 399, 0, 0, 0,
+ 400, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, 403, 0,
+ 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 405, 0, 0, 0, 0, 0, 0, 406, 0, 0, 407,
+ 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0,
+ 412, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 415, 0,
+ 0, 0, 0, 0, 0, 416, 0, 0, 417, 0, 0, 418, 0, 0, 419, 0, 0, 0, 420, 0, 0,
+ 421, 0, 0, 422, 0, 0, 423, 424, 0, 0, 425, 0, 0, 426, 0, 0, 0, 0, 0, 0,
+ 427, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 429, 0, 0, 0, 0, 0, 0, 430, 0,
+ 0, 431, 0, 0, 432, 0, 0, 0, 433, 0, 0, 434, 0, 0, 435, 0, 0, 436, 437, 0,
+ 0, 438, 0, 0, 439, 0, 0, 0, 440, 0, 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0,
+ 442, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, 445, 0,
+ 0, 0, 0, 0, 446, 0, 0, 447, 448, 0, 0, 449, 0, 0, 450, 0, 0, 0, 451, 0,
+ 0, 0, 0, 0, 452, 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 454, 0, 0, 0,
+ 0, 0, 455, 0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0,
+ 458, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 460, 0, 0, 0, 0, 0, 0, 461, 0,
+ 0, 462, 0, 0, 463, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 465, 0, 0,
+ 466, 0, 0, 467, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0,
+ 0, 470, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 473,
+ 0, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 476, 0, 0,
+ 0, 0, 0, 477, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0,
+ 0, 480, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 483,
+ 0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0,
+ 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 488, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, 0,
+ 0, 0, 490, 0, 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 493,
+ 0, 0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 496, 0, 0,
+ 0, 0, 0, 0, 497, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0,
+ 0, 0, 500, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, 0,
+ 503, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, 0, 0, 0, 506, 0,
+ 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0,
+ 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 512, 0, 0, 0,
+ 0, 0, 0, 513, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0,
+ 0, 516, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 518, 0, 0, 0, 0, 0, 0, 519,
+ 0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 522, 0, 0,
+ 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 525, 526, 0, 0, 0, 0,
+ 0, 527, 0, 0, 0, 0, 0, 0, 528, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 530,
+ 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 533, 0, 0,
+ 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0,
+ 0, 537, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 540,
+ 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 543, 0, 0,
+ 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0,
+ 0, 0, 547, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 550,
+ 551, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, 554, 0, 0,
+ 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0,
+ 0, 0, 558,
+};
+
+static unsigned short comp_data[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8814, 0, 0, 0, 0, 8800, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 194, 195,
+ 256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, 0, 7680,
+ 0, 0, 260, 0, 0, 0, 0, 7682, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7684, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7686, 0, 0, 0, 262, 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 7690, 0, 0, 0, 0, 270, 0, 0,
+ 0, 0, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 200, 201, 202, 7868, 274, 276, 278, 203, 7866, 0, 0, 282, 516,
+ 518, 0, 0, 0, 7864, 0, 0, 0, 552, 280, 7704, 0, 7706, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7710, 0, 0, 0, 0, 0, 0, 0, 500, 284, 0, 7712, 286, 288, 0, 0, 0,
+ 0, 486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292,
+ 0, 0, 0, 7714, 7718, 0, 0, 0, 542, 0, 0, 0, 0, 0, 7716, 0, 0, 0, 7720, 0,
+ 0, 7722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 205, 206, 296, 298,
+ 300, 304, 207, 7880, 0, 0, 463, 520, 522, 0, 0, 0, 7882, 0, 0, 0, 0, 302,
+ 0, 0, 7724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 0, 7728, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 310, 0, 0, 0,
+ 0, 7732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 317, 0, 0, 0, 0, 0,
+ 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7742, 0, 0, 0, 0, 7744, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7746, 0, 0, 0, 504,
+ 323, 0, 209, 0, 0, 7748, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 7750, 0, 0, 0,
+ 325, 0, 7754, 0, 0, 7752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 211, 212,
+ 213, 332, 334, 558, 214, 7886, 0, 336, 465, 524, 526, 0, 0, 416, 7884, 0,
+ 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, 7764, 0, 0, 0, 0, 7766, 0, 0, 0, 0, 0,
+ 0, 0, 340, 0, 0, 0, 0, 7768, 0, 0, 0, 0, 344, 528, 530, 0, 0, 0, 7770, 0,
+ 0, 0, 342, 0, 0, 0, 0, 7774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 348,
+ 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 7778, 0, 0, 536, 350, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7786, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0,
+ 7788, 0, 0, 538, 354, 0, 7792, 0, 0, 7790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 217, 218, 219, 360, 362, 364, 0, 220, 7910, 366, 368, 467, 532, 534, 0,
+ 0, 431, 7908, 7794, 0, 0, 0, 370, 7798, 0, 7796, 0, 0, 0, 0, 0, 0, 7804,
+ 0, 0, 0, 0, 0, 7806, 0, 0, 0, 7808, 7810, 372, 0, 0, 0, 7814, 7812, 0,
+ 7816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7818, 7820, 0, 0, 0, 0, 0, 7922, 221,
+ 374, 7928, 562, 0, 7822, 376, 7926, 0, 0, 0, 0, 0, 0, 0, 0, 7924, 0, 0,
+ 0, 0, 377, 7824, 0, 0, 0, 379, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 7826, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 225, 226,
+ 227, 257, 259, 551, 228, 7843, 229, 0, 462, 513, 515, 0, 0, 0, 7841, 0,
+ 7681, 0, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7683, 0, 0, 7685, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 265, 0,
+ 0, 0, 267, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0,
+ 0, 7691, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 7693, 0, 0, 0, 7697, 0, 7699, 0,
+ 0, 7695, 0, 0, 232, 233, 234, 7869, 275, 277, 279, 235, 7867, 0, 0, 283,
+ 517, 519, 0, 0, 0, 7865, 0, 0, 0, 553, 281, 7705, 0, 7707, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7711, 0, 0, 0, 0, 0, 0, 0, 501, 285, 0, 7713, 287, 289, 0, 0,
+ 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 293, 0, 0, 0, 7715, 7719,
+ 0, 0, 0, 543, 0, 0, 0, 0, 0, 7717, 0, 0, 0, 7721, 0, 0, 7723, 0, 7830, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 237, 238, 297, 299, 301, 0, 239, 7881, 0,
+ 0, 464, 521, 523, 0, 0, 0, 7883, 0, 0, 0, 0, 303, 0, 0, 7725, 0, 0, 0, 0,
+ 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7729,
+ 0, 489, 0, 0, 0, 0, 0, 7731, 0, 0, 0, 311, 0, 0, 0, 0, 7733, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0,
+ 7735, 0, 0, 0, 316, 0, 7741, 0, 0, 7739, 0, 0, 0, 7743, 0, 0, 0, 0, 7745,
+ 0, 0, 7747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505, 324, 0, 241, 0, 0,
+ 7749, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 7751, 0, 0, 0, 326, 0, 7755, 0, 0,
+ 7753, 0, 0, 242, 243, 244, 245, 333, 335, 559, 246, 7887, 0, 337, 466,
+ 525, 527, 0, 0, 417, 7885, 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 0, 7765, 0,
+ 0, 0, 0, 7767, 0, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 7769, 0, 0, 0, 0,
+ 345, 529, 531, 0, 0, 0, 7771, 0, 0, 0, 343, 0, 0, 0, 0, 7775, 0, 0, 0,
+ 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 7779, 0, 0, 537,
+ 351, 0, 0, 0, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, 0, 0, 0, 0, 7789, 0, 0,
+ 539, 355, 0, 7793, 0, 0, 7791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 250,
+ 251, 361, 363, 365, 0, 252, 7911, 367, 369, 468, 533, 535, 0, 0, 432,
+ 7909, 7795, 0, 0, 0, 371, 7799, 0, 7797, 0, 0, 0, 0, 0, 0, 7805, 0, 0, 0,
+ 0, 0, 7807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7809, 7811, 373, 0, 0, 0,
+ 7815, 7813, 0, 7832, 0, 0, 0, 0, 0, 0, 0, 7817, 0, 7819, 7821, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7923, 253, 375, 7929, 563, 0, 7823, 255,
+ 7927, 7833, 0, 0, 0, 0, 0, 0, 0, 7925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 378, 7825, 0, 0, 0, 380, 0, 0, 0, 0, 382, 0, 0, 0, 0, 0, 7827, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7829, 0, 0, 8173, 901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8129, 0, 0, 0, 0, 0, 0, 0, 0, 7846, 7844, 0, 7850, 0, 0, 0, 0, 7848, 0,
+ 0, 0, 0, 0, 0, 0, 0, 478, 0, 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 508, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7872, 7870, 0, 7876, 0, 0, 0, 0, 7874, 0, 0, 0, 0, 0, 7726, 0,
+ 0, 0, 7890, 7888, 0, 7894, 0, 0, 0, 0, 7892, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554,
+ 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 471, 0, 0, 469, 0, 0, 0, 0,
+ 0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7847, 7845, 0, 7851, 0, 0, 0, 0,
+ 7849, 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 507, 0, 0,
+ 0, 0, 509, 0, 0, 483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7689, 0, 0, 0, 7873,
+ 7871, 0, 7877, 0, 0, 0, 0, 7875, 0, 0, 0, 0, 0, 7727, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7891, 7889, 0, 7895, 0, 0, 0, 0, 7893, 0, 0, 0, 0, 0,
+ 7757, 0, 0, 557, 0, 0, 7759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 511, 0, 0, 0, 476, 472, 0, 0, 470, 0, 0, 0, 0, 0, 0, 474,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 7856, 7854, 0, 7860, 0, 0, 0, 0, 7858, 0, 0,
+ 0, 0, 7857, 7855, 0, 7861, 0, 0, 0, 0, 7859, 0, 0, 0, 0, 7700, 7702, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7701, 7703, 0, 0, 0, 7760, 7762, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 7761, 7763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7780, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7781, 0, 0, 0, 0, 7782, 0, 0, 0, 0,
+ 7783, 0, 0, 0, 0, 0, 0, 0, 7800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7801, 0, 0, 7802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7803, 0, 0, 0,
+ 7835, 0, 0, 0, 0, 0, 0, 7900, 7898, 0, 7904, 0, 0, 0, 0, 7902, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7901, 7899, 0,
+ 7905, 0, 0, 0, 0, 7903, 0, 0, 0, 0, 0, 0, 0, 0, 7907, 0, 0, 0, 7914,
+ 7912, 0, 7918, 0, 0, 0, 0, 7916, 0, 0, 0, 0, 0, 0, 0, 0, 7920, 0, 0, 0,
+ 7915, 7913, 0, 7919, 0, 0, 0, 0, 7917, 0, 0, 0, 0, 0, 0, 0, 0, 7921, 0,
+ 0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0,
+ 0, 493, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0,
+ 0, 0, 0, 7708, 0, 0, 0, 0, 7709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 560, 0,
+ 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8122, 902, 0, 0, 8121, 8120, 0, 0, 0, 0, 0, 0, 0, 0, 7944, 7945, 0,
+ 0, 0, 0, 0, 8124, 0, 0, 0, 0, 0, 0, 0, 8136, 904, 0, 0, 0, 0, 7960, 7961,
+ 0, 0, 0, 0, 0, 8138, 905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7976, 7977,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8140, 0, 0, 0, 0, 0, 0, 0, 8154,
+ 906, 0, 0, 8153, 8152, 0, 938, 0, 0, 0, 0, 0, 0, 7992, 7993, 0, 0, 0, 0,
+ 0, 8184, 908, 0, 0, 0, 0, 8008, 8009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8172, 0, 0, 0, 0, 0, 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 0, 0,
+ 0, 0, 8025, 0, 0, 0, 0, 0, 8186, 911, 0, 0, 0, 0, 8040, 8041, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8188, 0, 0, 0, 0, 8116, 0, 0, 0, 0, 8132, 0,
+ 0, 0, 0, 0, 0, 0, 8048, 940, 0, 0, 8113, 8112, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7936, 7937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8118, 8115, 0, 0, 0, 0,
+ 0, 0, 0, 8050, 941, 0, 0, 0, 0, 7952, 7953, 0, 0, 0, 0, 0, 8052, 942, 0,
+ 0, 0, 0, 7968, 7969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8134, 8131, 0,
+ 0, 0, 0, 0, 0, 0, 8054, 943, 0, 0, 8145, 8144, 0, 970, 0, 0, 0, 0, 0, 0,
+ 7984, 7985, 0, 0, 0, 0, 8150, 0, 0, 0, 0, 0, 0, 0, 0, 8056, 972, 0, 0, 0,
+ 0, 8000, 8001, 0, 0, 0, 8164, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8058, 973, 0, 0, 8161, 8160, 0, 971, 0, 0, 0, 0, 0, 0, 8016, 8017, 0,
+ 0, 0, 0, 8166, 0, 0, 0, 0, 0, 0, 0, 0, 8060, 974, 0, 0, 0, 0, 8032, 8033,
+ 0, 0, 0, 0, 8182, 8179, 0, 0, 0, 0, 0, 0, 0, 8146, 912, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8151, 0, 0, 0, 0, 0, 0, 0, 0, 8162, 944, 0, 0, 8167, 0, 0, 0,
+ 0, 0, 8180, 0, 0, 0, 0, 0, 0, 0, 0, 979, 0, 0, 0, 0, 0, 980, 0, 0, 0, 0,
+ 1031, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1232, 0, 1234, 0, 0, 0, 0, 0, 0,
+ 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 1238, 0, 1025,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1217, 0, 1244, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1246, 0, 0, 0, 0, 0, 1037, 0, 0, 0, 1250, 1049, 0, 1252, 0, 0,
+ 0, 0, 0, 0, 1036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1254, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1262, 1038, 0, 1264, 0, 0, 1266, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1268, 0, 0, 0, 0, 1272, 0, 0, 0, 0, 1260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1233, 0, 1235, 0, 0, 0, 0, 0, 0, 1107, 0, 0, 0, 1104, 0, 0, 0, 0, 1239,
+ 0, 1105, 0, 0, 1218, 0, 1245, 0, 0, 0, 0, 1247, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1117, 0, 0, 0, 1251, 1081, 0, 1253, 0, 0, 0, 0, 0, 0,
+ 1116, 0, 0, 1255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1263, 1118, 0, 1265, 0, 0,
+ 1267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1273, 0, 0, 0, 0, 1261, 0, 0, 0, 0, 1111, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1142, 0, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, 0, 1242, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1243, 0, 0, 0, 0, 1258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1259, 0, 0, 0, 1570, 1571, 1573, 0, 0, 0, 1572, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1574, 0, 0, 0, 0, 1730, 0, 0, 0, 0, 1747, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1728, 0, 0, 0, 0, 0, 0, 2345, 0, 0, 0, 0, 2353, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2356, 0, 0, 0, 0, 0, 2507, 2508, 0, 0,
+ 0, 0, 0, 2891, 2888, 2892, 0, 0, 0, 0, 0, 0, 2964, 0, 0, 0, 3018, 3020,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3019, 0, 0, 0, 0, 0, 0, 3144, 0, 0, 0,
+ 0, 0, 0, 3264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3274, 3271, 3272, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3275, 0, 0, 0, 0, 0, 0, 3402, 3404, 0, 0, 0,
+ 3403, 0, 0, 0, 0, 0, 0, 3546, 3548, 3550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3549, 0, 0, 0, 0, 0, 0, 0, 4134, 0, 0, 0, 0, 0, 0, 7736, 0, 0, 0, 0,
+ 7737, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7772, 0, 0, 0, 0, 7773, 0, 0,
+ 0, 0, 0, 0, 7784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7785, 7852, 0, 0,
+ 7862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7853, 0, 0, 7863, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7879, 0, 0, 0, 0, 7896,
+ 0, 0, 0, 0, 7897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7938, 7940, 0, 0, 7942,
+ 8064, 0, 0, 0, 0, 0, 0, 0, 7939, 7941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7943, 8065, 0, 0, 0, 0, 8066, 0, 0, 0, 0, 8067, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8068, 0, 0, 0, 0, 8069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8070, 0, 0, 0, 0, 8071, 0, 0, 0, 0, 0, 0, 0, 7946, 7948, 0, 0, 7950,
+ 8072, 0, 0, 0, 0, 0, 0, 0, 7947, 7949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7951, 8073, 0, 0, 0, 0, 8074, 0, 0, 0, 0, 8075, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8076, 0, 0, 0, 0, 8077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8078, 0, 0, 0, 0, 8079, 0, 0, 0, 0, 0, 0, 0, 7954, 7956, 0, 0, 0, 7955,
+ 7957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7962, 7964, 0, 0, 0, 7963, 7965,
+ 0, 0, 0, 7970, 7972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7974, 8080, 0, 0, 0,
+ 0, 0, 0, 0, 7971, 7973, 0, 0, 7975, 8081, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8082, 0, 0, 0, 0, 8083, 0, 0, 0, 0, 8084, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8085, 0, 0, 0, 0, 8086, 0, 0, 0, 0, 8087, 0, 0, 0, 0, 0, 0,
+ 0, 7978, 7980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7982, 8088, 0, 0, 0, 0, 0,
+ 0, 0, 7979, 7981, 0, 0, 7983, 8089, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8090, 0, 0, 0, 0, 8091, 0, 0, 0, 0, 8092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8093, 0, 0, 0, 0, 8094, 0, 0, 0, 0, 8095, 0, 0, 0, 0, 0, 0, 0,
+ 7986, 7988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7990, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7987, 7989, 0, 0, 7991, 0, 0, 0, 0, 0, 0, 0, 0, 7994, 7996, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7998, 0, 0, 0, 0, 0, 0, 0, 0, 7995, 7997, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7999, 0, 0, 0, 0, 0, 0, 0, 0, 8002, 8004, 0, 0, 0,
+ 8003, 8005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8010, 8012, 0, 0, 0, 8011,
+ 8013, 0, 0, 0, 8018, 8020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8022, 0, 0, 0,
+ 0, 0, 0, 0, 0, 8019, 8021, 0, 0, 8023, 0, 0, 0, 0, 0, 0, 0, 0, 8027,
+ 8029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8031, 0, 0, 0, 0, 0, 0, 0, 0, 8034,
+ 8036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8038, 8096, 0, 0, 0, 0, 0, 0, 0,
+ 8035, 8037, 0, 0, 8039, 8097, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8098,
+ 0, 0, 0, 0, 8099, 0, 0, 0, 0, 8100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8101, 0, 0, 0, 0, 8102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8103, 0, 0,
+ 0, 0, 0, 0, 0, 8042, 8044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8046, 8104, 0,
+ 0, 0, 0, 0, 0, 0, 8043, 8045, 0, 0, 8047, 8105, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8106, 0, 0, 0, 0, 8107, 0, 0, 0, 0, 8108, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8109, 0, 0, 0, 0, 8110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8111, 0, 0, 0, 0, 8114, 0, 0, 0, 0, 8130, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8178, 0, 0, 0, 0, 8119, 0, 0, 0, 0, 0, 0, 0, 8141, 8142, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8143, 0, 0, 0, 0, 0, 8135, 0, 0, 0, 0, 8183,
+ 0, 0, 0, 0, 0, 0, 0, 8157, 8158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8159, 0,
+ 0, 0, 8602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8603, 0, 0, 0, 0, 8622,
+ 0, 0, 0, 0, 8653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8655, 0, 0, 0, 0,
+ 8654, 0, 0, 0, 0, 8708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8713, 0, 0,
+ 0, 0, 8716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8740, 0, 0, 0, 0, 8742,
+ 0, 0, 0, 0, 8769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8772, 0, 0, 0, 0,
+ 8775, 0, 0, 0, 0, 8777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8813, 0, 0,
+ 0, 0, 8802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8816, 0, 0, 0, 0, 8817,
+ 0, 0, 0, 0, 8820, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8821, 0, 0, 0, 0,
+ 8824, 0, 0, 0, 0, 8825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8832, 0, 0,
+ 0, 0, 8833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8928, 0, 0, 0, 0, 8929,
+ 0, 0, 0, 0, 8836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8837, 0, 0, 0, 0,
+ 8840, 0, 0, 0, 0, 8841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8930, 0, 0,
+ 0, 0, 8931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8876, 0, 0, 0, 0, 8877,
+ 0, 0, 0, 0, 8878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8879, 0, 0, 0, 0,
+ 8938, 0, 0, 0, 0, 8939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8940, 0, 0,
+ 0, 0, 8941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12436, 0, 0, 0, 0, 12364,
+ 0, 0, 0, 0, 12366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12368, 0, 0, 0, 0,
+ 12370, 0, 0, 0, 0, 12372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12374, 0,
+ 0, 0, 0, 12376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12378, 0, 0, 0, 0,
+ 12380, 0, 0, 0, 0, 12382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12384, 0,
+ 0, 0, 0, 12386, 0, 0, 0, 0, 12389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12391, 0, 0, 0, 0, 12393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12400,
+ 12401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12403, 12404, 0, 0, 0, 12406,
+ 12407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12409, 12410, 0, 0, 0, 12412,
+ 12413, 0, 0, 0, 12446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12532, 0, 0,
+ 0, 0, 12460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12462, 0, 0, 0, 0,
+ 12464, 0, 0, 0, 0, 12466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12468, 0,
+ 0, 0, 0, 12470, 0, 0, 0, 0, 12472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12474, 0, 0, 0, 0, 12476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12478, 0,
+ 0, 0, 0, 12480, 0, 0, 0, 0, 12482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12485, 0, 0, 0, 0, 12487, 0, 0, 0, 0, 12489, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12496, 12497, 0, 0, 0, 12499, 12500, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 12502, 12503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12505, 12506, 0, 0,
+ 0, 12508, 12509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12535, 0, 0, 0, 0,
+ 12536, 0, 0, 0, 0, 12537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12538, 0,
+ 0, 0, 0, 12542, 0,
+};
+
+static const change_record change_records_3_2_0[] = {
+ { 255, 255, 255, 0 },
+ { 11, 255, 255, 0 },
+ { 10, 255, 255, 0 },
+ { 19, 21, 255, 0 },
+ { 255, 255, 2, 0 },
+ { 255, 255, 3, 0 },
+ { 255, 255, 1, 0 },
+ { 255, 0, 255, 0 },
+ { 255, 29, 255, 0 },
+ { 14, 255, 255, 0 },
+ { 255, 7, 1, 0 },
+ { 255, 7, 2, 0 },
+ { 255, 7, 3, 0 },
+ { 255, 7, 4, 0 },
+ { 255, 7, 5, 0 },
+ { 255, 7, 6, 0 },
+ { 255, 7, 7, 0 },
+ { 255, 7, 8, 0 },
+ { 255, 7, 9, 0 },
+ { 255, 5, 255, 0 },
+ { 15, 14, 255, 0 },
+ { 255, 10, 255, 0 },
+ { 18, 255, 255, 0 },
+ { 19, 255, 255, 0 },
+ { 255, 255, 0, 0 },
+ { 255, 255, 4, 0 },
+ { 255, 255, 5, 0 },
+ { 255, 255, 6, 0 },
+ { 255, 255, 7, 0 },
+ { 255, 255, 8, 0 },
+ { 255, 255, 9, 0 },
+ { 9, 255, 255, 0 },
+ { 255, 20, 255, 0 },
+ { 255, 19, 255, 0 },
+ { 15, 255, 255, 0 },
+ { 255, 255, 255, -1 },
+};
+static unsigned char changes_3_2_0_index[] = {
+ 0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 2, 8, 9, 10, 11, 2, 2, 2, 12, 13, 14, 15,
+ 16, 17, 2, 18, 2, 2, 2, 2, 2, 19, 2, 20, 2, 2, 21, 22, 23, 24, 2, 2, 2,
+ 2, 2, 2, 2, 25, 26, 2, 27, 28, 29, 2, 2, 2, 2, 2, 30, 31, 2, 2, 2, 2, 32,
+ 33, 34, 2, 35, 2, 2, 36, 37, 38, 2, 2, 39, 40, 2, 41, 42, 42, 2, 2, 2, 2,
+ 43, 2, 44, 45, 46, 47, 48, 2, 2, 2, 2, 49, 2, 50, 51, 52, 53, 54, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 55, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 57, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 58, 2, 59, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 60, 61, 62, 2, 2, 2, 2, 63, 64, 2, 65, 66,
+ 67, 68, 69, 70, 2, 2, 71, 72, 73, 74, 2, 2, 2, 2, 2, 2, 75, 2, 2, 2, 76,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 77, 2, 78, 2, 2, 79, 2, 2,
+ 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 81, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+};
+
+static unsigned char changes_3_2_0_data[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+ 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 0, 0, 0, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+ 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 25, 26, 27, 28, 29, 30, 1,
+ 1, 0, 0, 0, 0, 24, 6, 4, 5, 25, 26, 27, 28, 29, 30, 1, 1, 0, 0, 0, 0, 7,
+ 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7,
+ 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7,
+ 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 0, 0, 0, 0, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 0, 0, 7,
+ 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7,
+ 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 7, 7, 7, 0, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 0,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const change_record* get_change_3_2_0(Py_UCS4 n)
+{
+ int index;
+ if (n >= 0x110000) index = 0;
+ else {
+ index = changes_3_2_0_index[n>>7];
+ index = changes_3_2_0_data[(index<<7)+(n & 127)];
+ }
+ return change_records_3_2_0+index;
+}
+
+static Py_UCS4 normalization_3_2_0(Py_UCS4 n)
+{
+ switch(n) {
+ case 0x2f868: return 0x2136A;
+ case 0x2f874: return 0x5F33;
+ case 0x2f91f: return 0x43AB;
+ case 0x2f95f: return 0x7AAE;
+ case 0x2f9bf: return 0x4D57;
+ default: return 0;
+ }
+}
+
diff --git a/sys/src/cmd/python/Modules/unicodename_db.h b/sys/src/cmd/python/Modules/unicodename_db.h
new file mode 100644
index 000000000..ee24aa976
--- /dev/null
+++ b/sys/src/cmd/python/Modules/unicodename_db.h
@@ -0,0 +1,12543 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
+
+#define NAME_MAXLEN 256
+
+/* lexicon */
+static unsigned char lexicon[] = {
+ 76, 69, 84, 84, 69, 210, 87, 73, 84, 200, 83, 77, 65, 76, 204, 83, 89,
+ 76, 76, 65, 66, 76, 197, 67, 65, 80, 73, 84, 65, 204, 89, 201, 67, 74,
+ 203, 76, 65, 84, 73, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84,
+ 217, 77, 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 65, 82, 65, 66, 73,
+ 195, 83, 89, 77, 66, 79, 204, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68,
+ 73, 65, 206, 83, 89, 76, 76, 65, 66, 73, 67, 211, 66, 79, 76, 196, 71,
+ 82, 69, 69, 203, 76, 73, 71, 65, 84, 85, 82, 197, 65, 78, 196, 77, 85,
+ 83, 73, 67, 65, 204, 83, 73, 71, 206, 69, 84, 72, 73, 79, 80, 73, 195,
+ 72, 65, 78, 71, 85, 204, 73, 84, 65, 76, 73, 195, 82, 65, 68, 73, 67, 65,
+ 204, 68, 73, 71, 73, 212, 83, 65, 78, 83, 45, 83, 69, 82, 73, 198, 70,
+ 79, 210, 67, 73, 82, 67, 76, 69, 196, 70, 73, 78, 65, 204, 83, 81, 85,
+ 65, 82, 197, 67, 89, 82, 73, 76, 76, 73, 195, 86, 79, 87, 69, 204, 86,
+ 65, 82, 73, 65, 84, 73, 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84,
+ 84, 69, 82, 206, 66, 89, 90, 65, 78, 84, 73, 78, 197, 82, 73, 71, 72,
+ 212, 73, 83, 79, 76, 65, 84, 69, 196, 76, 69, 70, 212, 194, 75, 65, 84,
+ 65, 75, 65, 78, 193, 75, 65, 78, 71, 88, 201, 76, 73, 78, 69, 65, 210,
+ 68, 79, 85, 66, 76, 197, 66, 69, 76, 79, 87, 128, 84, 73, 66, 69, 84, 65,
+ 206, 65, 66, 79, 86, 69, 128, 77, 79, 68, 73, 70, 73, 69, 210, 67, 79,
+ 77, 66, 73, 78, 73, 78, 199, 77, 69, 69, 205, 83, 73, 71, 78, 128, 68,
+ 79, 212, 73, 78, 73, 84, 73, 65, 204, 67, 65, 82, 82, 73, 69, 210, 65,
+ 82, 82, 79, 87, 128, 89, 69, 200, 77, 79, 78, 71, 79, 76, 73, 65, 206,
+ 86, 69, 82, 84, 73, 67, 65, 204, 65, 66, 79, 86, 197, 78, 85, 77, 66, 69,
+ 210, 67, 79, 80, 84, 73, 195, 75, 72, 77, 69, 210, 87, 72, 73, 84, 197,
+ 65, 82, 82, 79, 215, 66, 79, 216, 65, 128, 72, 69, 66, 82, 69, 215, 77,
+ 65, 82, 75, 128, 68, 82, 65, 87, 73, 78, 71, 211, 73, 128, 79, 128, 72,
+ 65, 76, 70, 87, 73, 68, 84, 200, 71, 69, 79, 82, 71, 73, 65, 206, 82, 73,
+ 71, 72, 84, 87, 65, 82, 68, 211, 73, 68, 69, 79, 71, 82, 65, 205, 85,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 195, 84, 65, 201, 80, 65,
+ 82, 69, 78, 84, 72, 69, 83, 73, 90, 69, 196, 65, 76, 69, 198, 83, 67, 82,
+ 73, 80, 212, 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 66, 76, 65, 67,
+ 203, 84, 79, 128, 85, 208, 70, 85, 76, 76, 87, 73, 68, 84, 200, 72, 79,
+ 79, 75, 128, 83, 89, 77, 66, 79, 76, 128, 68, 79, 87, 206, 70, 82, 65,
+ 75, 84, 85, 210, 72, 65, 200, 69, 81, 85, 65, 204, 72, 69, 65, 86, 217,
+ 84, 65, 199, 71, 76, 65, 71, 79, 76, 73, 84, 73, 195, 67, 72, 65, 82, 65,
+ 67, 84, 69, 210, 65, 82, 77, 69, 78, 73, 65, 206, 66, 69, 78, 71, 65, 76,
+ 201, 67, 72, 79, 83, 69, 79, 78, 199, 74, 69, 69, 205, 66, 82, 65, 67,
+ 75, 69, 84, 128, 72, 73, 82, 65, 71, 65, 78, 193, 87, 69, 83, 84, 45, 67,
+ 82, 69, 197, 84, 72, 65, 201, 83, 84, 82, 79, 75, 69, 128, 67, 72, 69,
+ 82, 79, 75, 69, 197, 73, 68, 69, 79, 71, 82, 65, 80, 200, 84, 87, 79,
+ 128, 71, 85, 74, 65, 82, 65, 84, 201, 77, 69, 68, 73, 65, 204, 74, 79,
+ 78, 71, 83, 69, 79, 78, 199, 75, 65, 78, 78, 65, 68, 193, 78, 69, 215,
+ 207, 79, 82, 73, 89, 193, 82, 85, 78, 73, 195, 84, 69, 84, 82, 65, 71,
+ 82, 65, 205, 68, 69, 83, 69, 82, 69, 212, 76, 85, 197, 83, 73, 78, 72,
+ 65, 76, 193, 84, 69, 76, 85, 71, 213, 66, 65, 82, 128, 78, 79, 84, 65,
+ 84, 73, 79, 206, 79, 78, 69, 128, 83, 89, 82, 73, 65, 195, 77, 65, 76,
+ 65, 89, 65, 76, 65, 205, 77, 89, 65, 78, 77, 65, 210, 71, 85, 82, 77, 85,
+ 75, 72, 201, 65, 67, 85, 84, 69, 128, 76, 73, 71, 72, 212, 72, 65, 76,
+ 198, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 76, 69, 70, 84,
+ 87, 65, 82, 68, 211, 84, 65, 77, 73, 204, 65, 80, 204, 70, 85, 78, 67,
+ 84, 73, 79, 78, 65, 204, 72, 65, 77, 90, 193, 84, 69, 76, 69, 71, 82, 65,
+ 80, 200, 74, 85, 78, 71, 83, 69, 79, 78, 199, 79, 198, 68, 65, 83, 73,
+ 193, 76, 73, 77, 66, 213, 77, 65, 75, 83, 85, 82, 193, 75, 72, 65, 82,
+ 79, 83, 72, 84, 72, 201, 76, 65, 207, 84, 207, 66, 65, 82, 194, 66, 79,
+ 80, 79, 77, 79, 70, 207, 72, 69, 88, 65, 71, 82, 65, 205, 77, 65, 82,
+ 203, 80, 83, 73, 76, 201, 77, 79, 78, 79, 83, 80, 65, 67, 197, 78, 79,
+ 212, 72, 79, 82, 73, 90, 79, 78, 84, 65, 204, 75, 72, 65, 200, 86, 79,
+ 67, 65, 76, 73, 195, 84, 72, 82, 69, 69, 128, 65, 69, 71, 69, 65, 206,
+ 76, 79, 87, 69, 210, 84, 73, 76, 68, 69, 128, 76, 79, 215, 84, 87, 207,
+ 67, 89, 80, 82, 73, 79, 212, 84, 73, 70, 73, 78, 65, 71, 200, 68, 73, 65,
+ 69, 82, 69, 83, 73, 83, 128, 70, 73, 86, 69, 128, 70, 79, 85, 82, 128,
+ 78, 85, 77, 69, 82, 65, 204, 86, 128, 65, 67, 82, 79, 80, 72, 79, 78, 73,
+ 195, 68, 79, 84, 211, 76, 79, 78, 199, 80, 69, 82, 83, 73, 65, 206, 65,
+ 78, 71, 76, 197, 72, 65, 82, 80, 79, 79, 206, 83, 73, 88, 128, 84, 79,
+ 78, 197, 85, 80, 80, 69, 210, 67, 73, 82, 67, 85, 77, 70, 76, 69, 216,
+ 71, 82, 65, 86, 69, 128, 72, 128, 65, 76, 80, 72, 193, 69, 73, 71, 72,
+ 84, 128, 77, 65, 67, 82, 79, 78, 128, 78, 79, 79, 206, 84, 72, 65, 65,
+ 78, 193, 72, 73, 71, 200, 75, 65, 128, 78, 73, 78, 69, 128, 83, 69, 86,
+ 69, 78, 128, 84, 72, 82, 69, 197, 84, 85, 82, 78, 69, 196, 83, 72, 65,
+ 86, 73, 65, 206, 83, 84, 79, 80, 128, 68, 128, 71, 128, 79, 77, 69, 71,
+ 193, 79, 88, 73, 65, 128, 83, 85, 66, 74, 79, 73, 78, 69, 196, 86, 65,
+ 82, 73, 65, 128, 89, 65, 128, 66, 128, 67, 73, 82, 67, 76, 197, 72, 65,
+ 128, 74, 128, 77, 65, 128, 82, 69, 86, 69, 82, 83, 69, 196, 82, 73, 71,
+ 72, 84, 128, 85, 80, 87, 65, 82, 68, 211, 80, 65, 83, 83, 73, 86, 69, 45,
+ 80, 85, 76, 76, 45, 68, 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, 66, 89,
+ 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, 75, 82, 65, 73, 78, 73,
+ 65, 206, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71,
+ 67, 73, 69, 85, 67, 128, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76,
+ 45, 85, 80, 45, 79, 85, 84, 80, 85, 212, 65, 78, 84, 73, 67, 76, 79, 67,
+ 75, 87, 73, 83, 69, 45, 82, 79, 84, 65, 84, 69, 196, 67, 69, 79, 78, 71,
+ 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 80, 83,
+ 73, 70, 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128,
+ 82, 73, 69, 85, 76, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85,
+ 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, 83, 65, 78, 71, 80, 73, 69,
+ 85, 80, 128, 79, 80, 69, 78, 45, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85,
+ 84, 80, 85, 212, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 67, 72, 73,
+ 69, 85, 67, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71,
+ 67, 73, 69, 85, 67, 128, 75, 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 45,
+ 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 77, 73, 69, 85, 77,
+ 45, 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 84, 73, 75, 69,
+ 85, 84, 45, 72, 73, 69, 85, 72, 128, 84, 82, 79, 77, 73, 75, 79, 80, 65,
+ 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 73, 69, 85, 80, 45, 83, 73,
+ 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, 80, 45, 83, 73,
+ 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 75, 73,
+ 89, 69, 79, 75, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 89, 69,
+ 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77,
+ 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 73, 69, 85, 78, 71, 45, 83, 83,
+ 65, 78, 71, 75, 73, 89, 69, 79, 75, 128, 76, 79, 78, 71, 45, 66, 82, 65,
+ 78, 67, 72, 45, 72, 65, 71, 65, 76, 204, 80, 65, 82, 84, 73, 65, 76, 76,
+ 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, 82, 73, 69, 85, 76, 45, 80, 73,
+ 69, 85, 80, 45, 72, 73, 69, 85, 72, 128, 83, 72, 79, 82, 84, 45, 84, 87,
+ 73, 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 73, 79, 83, 45, 80, 73, 69,
+ 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 75, 65, 84, 65, 75, 65, 78, 65,
+ 45, 72, 73, 82, 65, 71, 65, 78, 193, 82, 73, 69, 85, 76, 45, 80, 73, 69,
+ 85, 80, 45, 83, 73, 79, 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 80,
+ 65, 78, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77,
+ 67, 73, 69, 85, 67, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, 67,
+ 67, 65, 84, 79, 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 67, 73,
+ 69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 80, 73, 69,
+ 85, 80, 128, 82, 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 83, 73, 79,
+ 83, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 72, 65, 71, 65, 76,
+ 204, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206,
+ 84, 82, 79, 77, 73, 75, 79, 80, 83, 73, 70, 73, 83, 84, 79, 78, 128, 75,
+ 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, 85, 80, 72, 128, 65, 78, 84,
+ 73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, 67, 67, 69, 78,
+ 84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 78, 84, 73, 75, 69, 78,
+ 79, 75, 89, 76, 73, 83, 77, 65, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69,
+ 85, 77, 83, 73, 79, 83, 128, 67, 72, 73, 69, 85, 67, 72, 45, 75, 72, 73,
+ 69, 85, 75, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 72, 73, 69, 85,
+ 67, 72, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 49, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 50, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 57,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 65, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 66, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 51, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 52, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 66,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 67, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 68, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 53, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 54, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 68,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 69, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 70, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 55, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 56, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 70,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 48, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 49, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 57, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 65, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 49,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 50, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 51, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 66, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 67, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 52, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 53, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 68, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 69, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 53,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 54, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 55, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 70, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 48, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 55,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 56, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 57, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 49, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 50, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 57,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 65, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 66, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 51, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 52, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 66,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 67, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 68, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 53, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 54, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 68,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 69, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 70, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 55, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 56, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 70,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 48, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 49, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 57, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 65, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 49,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 50, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 51, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 66, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 67, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 52, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 53, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 56, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 56, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 56, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56,
+ 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 68, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 69, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 53,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 54, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 55, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 70, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 48, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 55,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 56, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 57, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 49, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 50, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 57,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 65, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 66, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 51, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 52, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 66,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 67, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 68, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 53, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 54, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 68,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 69, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 70, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 55, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 56, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 70,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 48, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 49, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 57, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 65, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 49,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 50, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 51, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 66, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 67, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 52, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 53, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 68, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 69, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 53,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 54, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 55, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 70, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 48, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 55,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 56, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 57, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 49, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 50, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 57,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 65, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 66, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 51, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 52, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 66,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 67, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 68, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 53, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 54, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 68,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 69, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 70, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 55, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 56, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 70,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 48, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 49, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57,
+ 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 57, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 65, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65,
+ 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 49,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 50, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 51, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65,
+ 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 66, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 67, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65,
+ 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 52, 128, 73,
+ 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 53, 128, 73, 68, 69,
+ 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65,
+ 80, 72, 45, 50, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72,
+ 45, 50, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50,
+ 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65,
+ 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 68, 128, 74,
+ 65, 76, 76, 65, 74, 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 75, 82, 65,
+ 84, 73, 77, 79, 75, 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73,
+ 77, 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 76, 79, 78, 71, 45, 66, 82,
+ 65, 78, 67, 72, 45, 77, 65, 68, 210, 77, 73, 69, 85, 77, 45, 83, 83, 65,
+ 78, 71, 83, 73, 79, 83, 128, 80, 69, 84, 65, 83, 84, 79, 75, 79, 85, 70,
+ 73, 83, 77, 65, 128, 80, 73, 69, 85, 80, 45, 83, 83, 65, 78, 71, 83, 73,
+ 79, 83, 128, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65,
+ 128, 80, 83, 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, 71, 77, 65, 128, 82,
+ 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 84, 69, 65,
+ 82, 68, 82, 79, 80, 45, 83, 72, 65, 78, 75, 69, 196, 80, 82, 79, 83, 71,
+ 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 84, 69, 65, 82, 68, 82, 79, 80,
+ 45, 83, 80, 79, 75, 69, 196, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72,
+ 69, 82, 69, 196, 84, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69,
+ 196, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, 128, 72, 73,
+ 71, 72, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 65, 70, 79, 82, 69,
+ 77, 69, 78, 84, 73, 79, 78, 69, 68, 128, 65, 82, 79, 85, 78, 68, 45, 80,
+ 82, 79, 70, 73, 76, 69, 128, 67, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73,
+ 78, 84, 69, 196, 71, 79, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78,
+ 128, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 69,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 52,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 65,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 48,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 54,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 67,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 50,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 56,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 52, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 57,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 65, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 70,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 48, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 53,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 54, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 66,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 67, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 49,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 50, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 55,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 56, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 68,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 69, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 52, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 57,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 65, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 70,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 48, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 53,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 54, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 66,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 67, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 49,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 50, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 55,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 56, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 68,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 69, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 51,
+ 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 52, 128, 73, 68,
+ 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, 71,
+ 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80,
+ 72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70,
+ 65, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 57,
+ 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, 83, 211, 76, 79,
+ 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 83, 79, 204, 76, 79, 78, 71, 45,
+ 66, 82, 65, 78, 67, 72, 45, 89, 82, 128, 77, 85, 76, 84, 73, 80, 76, 73,
+ 67, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 76, 73, 90, 65, 84,
+ 73, 79, 78, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 77, 65, 68,
+ 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 73,
+ 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 84, 69, 65, 82, 68,
+ 82, 79, 80, 45, 66, 65, 82, 66, 69, 196, 84, 82, 79, 77, 73, 75, 79, 76,
+ 89, 71, 73, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 83, 89, 78, 65,
+ 71, 77, 65, 128, 87, 72, 73, 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69,
+ 196, 89, 80, 79, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 82, 73, 71,
+ 72, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 77, 85, 76, 84, 73, 80, 76,
+ 73, 67, 65, 84, 73, 79, 206, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 79,
+ 87, 69, 196, 66, 65, 76, 76, 79, 79, 78, 45, 83, 80, 79, 75, 69, 196, 75,
+ 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76,
+ 45, 80, 72, 73, 69, 85, 80, 72, 128, 82, 73, 69, 85, 76, 45, 84, 72, 73,
+ 69, 85, 84, 72, 128, 65, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78,
+ 128, 65, 83, 89, 77, 80, 84, 79, 84, 73, 67, 65, 76, 76, 217, 77, 73, 69,
+ 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 80,
+ 65, 78, 83, 73, 79, 83, 128, 80, 65, 82, 65, 76, 76, 69, 76, 79, 71, 82,
+ 65, 77, 128, 80, 69, 82, 80, 69, 78, 68, 73, 67, 85, 76, 65, 82, 128, 80,
+ 72, 73, 69, 85, 80, 72, 45, 80, 73, 69, 85, 80, 128, 80, 73, 69, 85, 80,
+ 45, 80, 72, 73, 69, 85, 80, 72, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73,
+ 69, 85, 84, 72, 128, 80, 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, 67, 69,
+ 128, 82, 73, 69, 85, 76, 45, 80, 65, 78, 83, 73, 79, 83, 128, 84, 69, 84,
+ 65, 82, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 73, 75, 69, 85, 84, 45,
+ 75, 73, 89, 69, 79, 75, 128, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79,
+ 85, 78, 196, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 65,
+ 86, 65, 75, 82, 65, 72, 65, 83, 65, 78, 89, 65, 128, 66, 79, 84, 84, 79,
+ 77, 45, 76, 73, 71, 72, 84, 69, 196, 67, 72, 73, 69, 85, 67, 72, 45, 72,
+ 73, 69, 85, 72, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 73, 69, 85, 67,
+ 128, 67, 79, 78, 84, 69, 77, 80, 76, 65, 84, 73, 79, 78, 128, 68, 79, 84,
+ 83, 45, 49, 50, 51, 52, 53, 54, 55, 56, 128, 69, 77, 66, 69, 76, 76, 73,
+ 83, 72, 77, 69, 78, 84, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85,
+ 67, 72, 128, 73, 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 73,
+ 69, 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, 73, 69, 85, 78, 71,
+ 45, 84, 72, 73, 69, 85, 84, 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 82,
+ 73, 69, 85, 76, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65,
+ 210, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, 72, 128, 78, 73, 69,
+ 85, 78, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, 69, 85, 80, 45, 67,
+ 72, 73, 69, 85, 67, 72, 128, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85,
+ 75, 72, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83,
+ 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, 79, 204, 83, 72, 79, 82, 84,
+ 45, 84, 87, 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73,
+ 71, 45, 89, 82, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79,
+ 128, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, 128, 84, 72, 69,
+ 82, 77, 79, 68, 89, 78, 65, 77, 73, 67, 128, 89, 85, 85, 75, 65, 76, 69,
+ 65, 80, 73, 78, 84, 85, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65,
+ 78, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 197, 76, 69, 70,
+ 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 73, 78, 84, 69, 82, 83, 69, 67,
+ 84, 73, 79, 78, 128, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 217,
+ 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, 65, 76, 128, 68, 79, 87, 78, 45,
+ 80, 79, 73, 78, 84, 73, 78, 199, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69,
+ 78, 79, 206, 67, 82, 89, 80, 84, 79, 71, 82, 65, 77, 77, 73, 195, 72, 89,
+ 80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, 67, 79, 78, 67, 65, 86, 69,
+ 45, 83, 73, 68, 69, 196, 76, 69, 70, 84, 45, 84, 79, 45, 82, 73, 71, 72,
+ 212, 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85,
+ 76, 45, 75, 73, 89, 69, 79, 75, 128, 82, 73, 71, 72, 84, 45, 84, 79, 45,
+ 76, 69, 70, 212, 84, 82, 65, 78, 83, 80, 79, 83, 73, 84, 73, 79, 206, 67,
+ 82, 79, 83, 83, 69, 68, 45, 84, 65, 73, 76, 128, 68, 73, 77, 73, 78, 85,
+ 84, 73, 79, 78, 45, 49, 128, 68, 82, 79, 80, 45, 83, 72, 65, 68, 79, 87,
+ 69, 196, 71, 65, 69, 84, 84, 65, 45, 80, 73, 76, 76, 65, 128, 71, 69, 79,
+ 77, 69, 84, 82, 73, 67, 65, 76, 76, 217, 73, 69, 85, 78, 71, 45, 75, 73,
+ 89, 69, 79, 75, 128, 73, 78, 84, 69, 82, 80, 79, 76, 65, 84, 73, 79, 206,
+ 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, 80,
+ 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 84, 73, 75, 69,
+ 85, 84, 128, 84, 72, 73, 82, 84, 89, 45, 83, 69, 67, 79, 78, 196, 84, 87,
+ 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, 84, 89, 45,
+ 84, 72, 82, 69, 69, 128, 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78,
+ 128, 65, 78, 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, 85, 82, 65,
+ 77, 65, 90, 68, 65, 65, 45, 50, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65,
+ 65, 72, 65, 128, 66, 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, 72, 128, 67,
+ 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, 67, 89, 76, 73, 78, 68,
+ 82, 73, 67, 73, 84, 89, 128, 68, 69, 67, 73, 83, 73, 86, 69, 78, 69, 83,
+ 83, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, 211, 68, 73, 70,
+ 70, 73, 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, 77, 73, 78, 73, 83, 72,
+ 77, 69, 78, 84, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, 128,
+ 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 51, 128, 68, 73, 83, 67, 79,
+ 78, 84, 73, 78, 85, 79, 85, 211, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53,
+ 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 56, 128, 68, 79,
+ 84, 83, 45, 49, 50, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50,
+ 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 55, 56,
+ 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83,
+ 45, 49, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53,
+ 54, 55, 56, 128, 69, 85, 82, 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 70,
+ 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, 71, 82, 79, 78, 84, 72,
+ 73, 83, 77, 65, 84, 65, 128, 72, 89, 80, 79, 68, 73, 65, 83, 84, 79, 76,
+ 69, 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 69, 85,
+ 78, 71, 45, 84, 73, 75, 69, 85, 84, 128, 73, 78, 84, 69, 82, 83, 89, 76,
+ 76, 65, 66, 73, 195, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200,
+ 75, 73, 89, 69, 79, 75, 45, 82, 73, 69, 85, 76, 128, 76, 65, 66, 73, 65,
+ 76, 73, 90, 65, 84, 73, 79, 206, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80,
+ 76, 85, 211, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, 79, 80,
+ 69, 78, 45, 79, 85, 84, 76, 73, 78, 69, 196, 80, 69, 82, 80, 69, 78, 68,
+ 73, 67, 85, 76, 65, 210, 82, 85, 76, 69, 45, 68, 69, 76, 65, 89, 69, 68,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 48, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 49, 48, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 49, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 51, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 52, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 49, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48,
+ 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 55, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 49, 48, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 48, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 49, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 49, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49,
+ 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 52, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 49, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 55,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 56, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 49, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 49, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 49, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 50, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 49, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50,
+ 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 53, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 49, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 56, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 57, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 49, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49,
+ 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 50, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 49, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 53,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 54, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 49, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 49, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 57, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 48, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 49, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52,
+ 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 51, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 49, 52, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 54, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 55, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 49, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49,
+ 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 48, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 49, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 51,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 52, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 49, 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 49, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 55, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 56, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 49, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54,
+ 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 49, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 49, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 54, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 52, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 53, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 49, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49,
+ 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 56, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 49, 55, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 49,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 50, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 49, 55, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 49, 55, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 53, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 54, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 49, 55, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55,
+ 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 57, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 49, 56, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 50, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 51, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 49, 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49,
+ 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 54, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 56, 55, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 49, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 57,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 48, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 49, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 49, 57, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 51, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 52, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 49, 57, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57,
+ 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 55, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 49, 57, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 57, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 48, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 49, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 50, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50,
+ 48, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 52, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 50, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 50, 48, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 55,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 56, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 50, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 50, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 49, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 50, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 50, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49,
+ 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 53, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 50, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 50, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 56, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 57, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 50, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50,
+ 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 50, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 50, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 50, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 53,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 54, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 50, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 50, 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 57, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 48, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 50, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51,
+ 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 51, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 50, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 50, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 54, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 55, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 50, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50,
+ 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 48, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 50, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 50, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 51,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 52, 128, 83, 69, 76, 69,
+ 67, 84, 79, 82, 45, 50, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45,
+ 50, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 55, 128, 83,
+ 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 56, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 50, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53,
+ 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 49, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 50, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 50, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 52, 128,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 53, 128, 83, 69, 76, 69, 67,
+ 84, 79, 82, 45, 50, 53, 54, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71,
+ 45, 65, 210, 83, 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73,
+ 79, 83, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 73, 79, 83, 45, 80, 72,
+ 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72,
+ 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, 84, 72, 85, 78,
+ 68, 69, 82, 83, 84, 79, 82, 77, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73,
+ 69, 85, 76, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, 73, 79, 78, 128, 84,
+ 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89,
+ 45, 83, 69, 86, 69, 78, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73,
+ 69, 210, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 89, 79, 85,
+ 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, 45,
+ 84, 72, 65, 206, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, 65, 204, 80, 82,
+ 69, 83, 69, 78, 84, 65, 84, 73, 79, 206, 80, 69, 82, 73, 83, 80, 79, 77,
+ 69, 78, 73, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 65, 82,
+ 65, 66, 73, 67, 45, 73, 78, 68, 73, 195, 80, 65, 82, 69, 78, 84, 72, 69,
+ 83, 73, 83, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 128, 73, 78,
+ 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 67, 65, 78, 68, 82, 65, 66, 73,
+ 78, 68, 85, 128, 69, 82, 82, 79, 82, 45, 66, 65, 82, 82, 69, 196, 83, 85,
+ 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 66, 76, 65, 67, 75, 45, 76, 69,
+ 84, 84, 69, 210, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 128, 67, 65,
+ 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 69, 75, 70, 79, 78, 73, 84, 73,
+ 75, 79, 78, 128, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 82, 73,
+ 69, 85, 76, 45, 72, 73, 69, 85, 72, 128, 83, 79, 85, 84, 72, 45, 83, 76,
+ 65, 86, 69, 217, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, 65, 83,
+ 84, 82, 79, 76, 79, 71, 73, 67, 65, 204, 71, 65, 89, 65, 78, 85, 75, 73,
+ 84, 84, 65, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, 85, 80, 128, 78, 73,
+ 69, 85, 78, 45, 67, 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 72, 73,
+ 69, 85, 72, 128, 80, 65, 82, 65, 71, 82, 65, 80, 72, 79, 83, 128, 82, 73,
+ 69, 85, 76, 45, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 45, 80, 73,
+ 69, 85, 80, 128, 83, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 210, 83, 83,
+ 65, 78, 71, 84, 73, 75, 69, 85, 84, 128, 65, 67, 75, 78, 79, 87, 76, 69,
+ 68, 71, 69, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 73, 78,
+ 84, 69, 82, 83, 69, 67, 84, 73, 78, 199, 80, 73, 69, 85, 80, 45, 67, 73,
+ 69, 85, 67, 128, 81, 85, 73, 78, 68, 73, 67, 69, 83, 73, 77, 193, 82, 73,
+ 69, 85, 76, 45, 78, 73, 69, 85, 78, 128, 83, 73, 88, 84, 89, 45, 70, 79,
+ 85, 82, 84, 200, 84, 82, 73, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 87,
+ 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 87, 69, 68, 71, 69, 45, 84, 65,
+ 73, 76, 69, 196, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, 128, 65, 71,
+ 71, 82, 65, 86, 65, 84, 73, 79, 78, 128, 65, 77, 65, 76, 71, 65, 77, 65,
+ 84, 73, 79, 206, 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 65, 85,
+ 71, 77, 69, 78, 84, 65, 84, 73, 79, 206, 67, 65, 78, 67, 69, 76, 76, 65,
+ 84, 73, 79, 206, 67, 73, 69, 85, 67, 45, 73, 69, 85, 78, 71, 128, 67, 79,
+ 78, 74, 85, 78, 67, 84, 73, 79, 78, 128, 67, 79, 78, 84, 82, 65, 67, 84,
+ 73, 79, 78, 128, 67, 79, 78, 84, 82, 65, 82, 73, 69, 84, 89, 128, 67, 79,
+ 82, 80, 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 85, 78, 84, 69, 82, 66,
+ 79, 82, 69, 128, 67, 79, 85, 78, 84, 69, 82, 83, 73, 78, 75, 128, 68, 65,
+ 72, 89, 65, 65, 85, 83, 72, 45, 50, 128, 68, 69, 67, 82, 69, 83, 67, 69,
+ 78, 68, 79, 128, 68, 69, 76, 73, 86, 69, 82, 65, 78, 67, 69, 128, 68, 69,
+ 78, 79, 77, 73, 78, 65, 84, 79, 82, 128, 68, 69, 82, 69, 84, 45, 72, 73,
+ 68, 69, 84, 128, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, 128, 68, 73,
+ 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 79, 65, 67, 72, 65, 83, 72,
+ 77, 69, 69, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 128, 68, 79,
+ 84, 83, 45, 49, 50, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51,
+ 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 55, 128, 68, 79,
+ 84, 83, 45, 49, 50, 51, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51,
+ 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 55, 128, 68, 79,
+ 84, 83, 45, 49, 50, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51,
+ 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 55, 56, 128, 68, 79,
+ 84, 83, 45, 49, 50, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52,
+ 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 55, 56, 128, 68, 79,
+ 84, 83, 45, 49, 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53,
+ 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 54, 55, 128, 68, 79,
+ 84, 83, 45, 49, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52,
+ 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 55, 56, 128, 68, 79,
+ 84, 83, 45, 49, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 53,
+ 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 54, 55, 128, 68, 79,
+ 84, 83, 45, 50, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52,
+ 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 55, 56, 128, 68, 79,
+ 84, 83, 45, 50, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53,
+ 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79,
+ 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 69, 65, 77, 72, 65, 78, 67, 72,
+ 79, 76, 76, 128, 69, 78, 76, 65, 82, 71, 69, 77, 69, 78, 84, 128, 70, 73,
+ 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 82, 79, 78, 84, 45, 84, 73,
+ 76, 84, 69, 196, 71, 85, 65, 82, 68, 69, 68, 78, 69, 83, 83, 128, 72, 65,
+ 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 73, 69, 85, 72, 45, 77, 73,
+ 69, 85, 77, 128, 72, 73, 69, 85, 72, 45, 78, 73, 69, 85, 78, 128, 72, 73,
+ 69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, 72, 45, 82, 73,
+ 69, 85, 76, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 73, 69,
+ 85, 78, 71, 45, 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 77, 73,
+ 69, 85, 77, 128, 73, 69, 85, 78, 71, 45, 80, 73, 69, 85, 80, 128, 73, 78,
+ 84, 69, 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 82, 67, 65, 76,
+ 65, 84, 69, 128, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, 128, 75, 73,
+ 82, 79, 77, 69, 69, 84, 79, 82, 85, 128, 76, 65, 75, 75, 72, 65, 78, 71,
+ 89, 65, 79, 128, 77, 73, 69, 85, 77, 45, 72, 73, 69, 85, 72, 128, 77, 73,
+ 69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 85, 85, 83, 73, 75, 65, 84,
+ 79, 65, 78, 128, 78, 65, 65, 75, 83, 73, 75, 89, 65, 89, 65, 128, 78, 69,
+ 66, 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, 73, 69, 85, 78, 45, 80, 73,
+ 69, 85, 80, 128, 78, 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 79, 66,
+ 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 80, 65, 82, 65, 75, 76, 73, 84,
+ 73, 75, 73, 128, 80, 69, 78, 69, 84, 82, 65, 84, 73, 79, 78, 128, 80, 69,
+ 82, 83, 80, 69, 67, 84, 73, 86, 69, 128, 80, 73, 69, 85, 80, 45, 78, 73,
+ 69, 85, 78, 128, 80, 73, 69, 85, 80, 45, 82, 73, 69, 85, 76, 128, 80, 79,
+ 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 82, 69, 83, 67, 82, 73, 80,
+ 84, 73, 79, 206, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 65, 204, 82, 73,
+ 71, 72, 84, 45, 83, 72, 65, 68, 69, 196, 82, 73, 78, 70, 79, 82, 90, 65,
+ 78, 68, 79, 128, 82, 79, 85, 78, 68, 45, 84, 73, 80, 80, 69, 196, 83, 65,
+ 71, 73, 84, 84, 65, 82, 73, 85, 83, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 50, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 54, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 57, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 50, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 53, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 51, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 56, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 49, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 52, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 55, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 48, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 51, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 54, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 53, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 53, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 57, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 54, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 50, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 54, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 54, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 53, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 56, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 55, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 49, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 55, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 52, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 55, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 55, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 55, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 48, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 51, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 54, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 56, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 57, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 50, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 57, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 53, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 57, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82,
+ 45, 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 56, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 57, 57, 128, 83, 80, 82, 69, 67, 72, 71, 69,
+ 83, 65, 78, 199, 83, 85, 80, 69, 82, 73, 77, 80, 79, 83, 69, 196, 84, 69,
+ 84, 82, 65, 70, 79, 78, 73, 65, 83, 128, 84, 72, 65, 78, 84, 72, 65, 75,
+ 72, 65, 84, 128, 84, 72, 82, 69, 69, 45, 80, 69, 82, 45, 69, 205, 84, 79,
+ 65, 78, 68, 65, 75, 72, 73, 65, 84, 128, 84, 82, 65, 78, 83, 77, 73, 83,
+ 83, 73, 79, 206, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, 69, 128, 84, 87,
+ 69, 78, 84, 89, 45, 78, 73, 78, 69, 128, 85, 78, 65, 83, 80, 73, 82, 65,
+ 84, 69, 68, 128, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 128, 83, 85, 80,
+ 69, 82, 83, 67, 82, 73, 80, 212, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76,
+ 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 206, 73, 78, 68, 69, 80, 69,
+ 78, 68, 69, 78, 212, 80, 69, 82, 73, 83, 80, 79, 77, 69, 78, 201, 69, 88,
+ 67, 76, 65, 77, 65, 84, 73, 79, 206, 68, 69, 83, 67, 82, 73, 80, 84, 73,
+ 79, 206, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 68, 79, 85, 66, 76,
+ 69, 45, 76, 73, 78, 197, 77, 65, 72, 65, 65, 80, 82, 65, 65, 78, 193, 65,
+ 80, 79, 83, 84, 82, 79, 80, 72, 69, 128, 85, 80, 45, 80, 79, 73, 78, 84,
+ 73, 78, 199, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, 197, 73, 77, 80, 69,
+ 82, 70, 69, 67, 84, 85, 205, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 128,
+ 65, 82, 82, 79, 87, 45, 84, 65, 73, 76, 128, 68, 79, 65, 67, 72, 65, 83,
+ 72, 77, 69, 197, 65, 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 76, 84,
+ 69, 82, 78, 65, 84, 73, 86, 197, 67, 79, 77, 80, 76, 69, 84, 73, 79, 78,
+ 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76,
+ 73, 78, 69, 65, 210, 79, 80, 69, 78, 45, 72, 69, 65, 68, 69, 196, 79, 80,
+ 80, 79, 83, 73, 84, 73, 79, 78, 128, 82, 73, 69, 85, 76, 45, 83, 73, 79,
+ 83, 128, 83, 69, 77, 73, 45, 86, 79, 73, 67, 69, 196, 83, 83, 65, 78, 71,
+ 73, 69, 85, 78, 71, 128, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 65,
+ 69, 68, 65, 45, 80, 73, 76, 76, 65, 128, 67, 79, 78, 83, 69, 67, 85, 84,
+ 73, 86, 197, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 69, 78, 84, 69,
+ 82, 80, 82, 73, 83, 69, 128, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 128,
+ 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, 78, 79, 71, 82, 65,
+ 77, 77, 79, 211, 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, 73, 69,
+ 85, 78, 45, 83, 73, 79, 83, 128, 79, 86, 69, 82, 76, 65, 80, 80, 73, 78,
+ 199, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, 80, 65, 82, 65, 75, 76,
+ 73, 84, 73, 75, 201, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, 80, 69,
+ 82, 67, 85, 83, 83, 73, 86, 69, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79,
+ 78, 128, 82, 69, 67, 84, 65, 78, 71, 85, 76, 65, 210, 82, 69, 67, 84, 73,
+ 76, 73, 78, 69, 65, 210, 82, 69, 80, 76, 65, 67, 69, 77, 69, 78, 212, 83,
+ 65, 76, 76, 65, 76, 76, 65, 72, 79, 213, 83, 73, 79, 83, 45, 78, 73, 69,
+ 85, 78, 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78,
+ 71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128,
+ 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 128, 84, 65, 66, 85, 76, 65, 84,
+ 73, 79, 78, 128, 84, 69, 84, 82, 65, 83, 73, 77, 79, 85, 128, 84, 72, 69,
+ 77, 65, 84, 73, 83, 77, 79, 211, 84, 87, 69, 78, 84, 89, 45, 79, 78, 69,
+ 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 79, 128, 65, 76, 84, 69, 82, 78,
+ 65, 84, 73, 79, 206, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78,
+ 84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89,
+ 65, 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 83, 128, 65, 83, 84, 69, 82,
+ 73, 83, 67, 85, 83, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 128, 66,
+ 65, 67, 75, 45, 84, 73, 76, 84, 69, 196, 66, 65, 82, 73, 89, 79, 79, 83,
+ 65, 78, 128, 66, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 67, 73, 82, 67,
+ 85, 76, 65, 84, 73, 79, 206, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196,
+ 67, 79, 77, 80, 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, 76, 73, 65,
+ 78, 67, 69, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 206, 67, 79, 78,
+ 84, 69, 78, 84, 73, 79, 78, 128, 67, 79, 82, 82, 69, 83, 80, 79, 78, 68,
+ 211, 67, 82, 79, 83, 83, 66, 79, 78, 69, 83, 128, 68, 69, 70, 73, 78, 73,
+ 84, 73, 79, 78, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 73,
+ 65, 69, 82, 69, 83, 73, 90, 69, 196, 68, 73, 77, 69, 78, 83, 73, 79, 78,
+ 65, 204, 68, 73, 82, 69, 67, 84, 73, 79, 78, 65, 204, 68, 73, 83, 80, 69,
+ 82, 83, 73, 79, 78, 128, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, 128, 68,
+ 73, 86, 69, 82, 71, 69, 78, 67, 69, 128, 68, 79, 84, 83, 45, 49, 50, 51,
+ 52, 53, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 128, 68, 79, 84, 83,
+ 45, 49, 50, 51, 52, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 56, 128,
+ 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 128, 68, 79, 84, 83, 45, 49, 50,
+ 51, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 56, 128, 68, 79, 84,
+ 83, 45, 49, 50, 51, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 56,
+ 128, 68, 79, 84, 83, 45, 49, 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49,
+ 50, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 55, 128, 68, 79,
+ 84, 83, 45, 49, 50, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 54,
+ 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 56, 128, 68, 79, 84, 83, 45,
+ 49, 50, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53, 54, 55, 128, 68,
+ 79, 84, 83, 45, 49, 50, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53,
+ 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 54, 55, 56, 128, 68, 79, 84, 83,
+ 45, 49, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 55, 128,
+ 68, 79, 84, 83, 45, 49, 51, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 51,
+ 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 56, 128, 68, 79, 84,
+ 83, 45, 49, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 55,
+ 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49,
+ 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 54, 55, 56, 128, 68, 79,
+ 84, 83, 45, 49, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 52, 53, 54,
+ 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45,
+ 49, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 53, 54, 55, 56, 128, 68,
+ 79, 84, 83, 45, 50, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, 50, 51, 52,
+ 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 56, 128, 68, 79, 84, 83,
+ 45, 50, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 56, 128,
+ 68, 79, 84, 83, 45, 50, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51,
+ 53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 56, 128, 68, 79, 84,
+ 83, 45, 50, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 54, 55, 56,
+ 128, 68, 79, 84, 83, 45, 50, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 50,
+ 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, 55, 56, 128, 68, 79,
+ 84, 83, 45, 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, 54, 55,
+ 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45,
+ 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68,
+ 79, 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54,
+ 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 56, 128, 69, 75, 83, 84,
+ 82, 69, 80, 84, 79, 78, 128, 69, 77, 66, 82, 79, 73, 68, 69, 82, 89, 128,
+ 69, 78, 67, 79, 85, 78, 84, 69, 82, 83, 128, 69, 78, 84, 72, 85, 83, 73,
+ 65, 83, 77, 128, 69, 81, 85, 73, 65, 78, 71, 85, 76, 65, 210, 69, 88, 72,
+ 65, 85, 83, 84, 73, 79, 78, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84,
+ 128, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, 128, 70, 79, 82, 77, 65, 84,
+ 84, 73, 78, 71, 128, 70, 79, 85, 82, 45, 80, 69, 82, 45, 69, 205, 70, 79,
+ 85, 82, 45, 83, 84, 82, 73, 78, 199, 72, 66, 65, 83, 65, 45, 69, 83, 65,
+ 83, 193, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, 128, 72, 89, 80, 72, 69,
+ 78, 65, 84, 73, 79, 206, 73, 77, 73, 68, 73, 65, 82, 71, 79, 78, 128, 73,
+ 77, 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 78, 70, 79, 82, 77, 65, 84,
+ 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, 196, 75, 73, 82, 79,
+ 71, 85, 82, 65, 77, 85, 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, 128,
+ 76, 69, 70, 84, 45, 83, 72, 65, 68, 69, 196, 76, 73, 77, 73, 84, 65, 84,
+ 73, 79, 78, 128, 77, 69, 77, 66, 69, 82, 83, 72, 73, 80, 128, 78, 65, 78,
+ 71, 77, 79, 78, 84, 72, 79, 128, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82,
+ 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, 128, 79, 80, 80, 82, 69, 83,
+ 83, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65,
+ 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 79, 83, 83, 69, 83, 83, 73, 79,
+ 78, 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, 79, 74, 69,
+ 67, 84, 73, 86, 69, 128, 82, 65, 68, 73, 79, 65, 67, 84, 73, 86, 197, 82,
+ 65, 72, 77, 65, 84, 85, 76, 76, 65, 200, 82, 69, 83, 73, 83, 84, 65, 78,
+ 67, 69, 128, 82, 69, 83, 79, 76, 85, 84, 73, 79, 78, 128, 82, 69, 86, 79,
+ 76, 85, 84, 73, 79, 78, 128, 83, 65, 67, 82, 73, 70, 73, 67, 73, 65, 204,
+ 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 128, 83, 69, 76, 69, 67, 84, 79,
+ 82, 45, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 128, 83, 69, 76,
+ 69, 67, 84, 79, 82, 45, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53,
+ 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 128, 83, 69, 76, 69, 67, 84,
+ 79, 82, 45, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 128, 83, 69,
+ 76, 69, 67, 84, 79, 82, 45, 57, 128, 83, 72, 65, 76, 83, 72, 69, 76, 69,
+ 84, 128, 83, 73, 79, 83, 45, 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45,
+ 73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, 77, 73, 69, 85, 77, 128, 83,
+ 83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 84, 65, 78, 68, 83, 84, 73,
+ 76, 76, 128, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 83,
+ 84, 73, 84, 85, 84, 69, 128, 83, 89, 78, 67, 72, 82, 79, 78, 79, 85, 211,
+ 84, 69, 82, 77, 73, 78, 65, 84, 79, 82, 128, 84, 72, 73, 82, 84, 89, 45,
+ 79, 78, 69, 128, 84, 79, 80, 45, 76, 73, 71, 72, 84, 69, 196, 84, 82, 65,
+ 78, 83, 86, 69, 82, 83, 65, 204, 84, 87, 69, 78, 84, 89, 45, 83, 73, 88,
+ 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 89, 128, 87, 73, 68, 69, 45, 72,
+ 69, 65, 68, 69, 196, 68, 69, 83, 67, 69, 78, 68, 69, 82, 128, 76, 69, 83,
+ 83, 45, 84, 72, 65, 78, 128, 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 69,
+ 81, 85, 73, 86, 65, 76, 69, 78, 212, 83, 69, 80, 65, 82, 65, 84, 79, 82,
+ 128, 65, 82, 82, 79, 87, 72, 69, 65, 68, 128, 65, 76, 80, 65, 80, 82, 65,
+ 65, 78, 193, 68, 79, 87, 78, 87, 65, 82, 68, 83, 128, 69, 88, 84, 69, 78,
+ 83, 73, 79, 78, 128, 76, 69, 78, 84, 73, 67, 85, 76, 65, 210, 80, 72, 65,
+ 82, 89, 78, 71, 69, 65, 204, 80, 82, 79, 76, 65, 84, 73, 79, 78, 197, 83,
+ 69, 77, 73, 67, 79, 76, 79, 78, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69,
+ 128, 84, 87, 79, 45, 72, 69, 65, 68, 69, 196, 65, 77, 80, 69, 82, 83, 65,
+ 78, 68, 128, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 84, 82, 79, 69, 90,
+ 69, 78, 73, 65, 206, 67, 79, 77, 77, 69, 82, 67, 73, 65, 204, 83, 69, 77,
+ 73, 68, 73, 82, 69, 67, 212, 83, 69, 86, 69, 78, 84, 69, 69, 78, 128, 87,
+ 79, 79, 68, 83, 45, 67, 82, 69, 197, 66, 65, 67, 75, 83, 76, 65, 83, 72,
+ 128, 68, 73, 65, 76, 89, 84, 73, 75, 65, 128, 69, 88, 84, 82, 65, 45, 72,
+ 73, 71, 200, 70, 73, 88, 69, 68, 45, 70, 79, 82, 205, 73, 77, 80, 69, 82,
+ 70, 69, 67, 84, 193, 73, 78, 68, 73, 67, 65, 84, 79, 82, 128, 82, 69, 67,
+ 84, 65, 78, 71, 76, 69, 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 217, 67,
+ 79, 78, 84, 65, 73, 78, 73, 78, 199, 68, 69, 76, 73, 77, 73, 84, 69, 82,
+ 128, 69, 78, 67, 76, 79, 83, 85, 82, 69, 128, 69, 80, 73, 68, 65, 85, 82,
+ 69, 65, 206, 72, 69, 82, 77, 73, 79, 78, 73, 65, 206, 72, 79, 85, 82, 71,
+ 76, 65, 83, 83, 128, 83, 69, 77, 73, 66, 82, 69, 86, 73, 211, 83, 69, 77,
+ 73, 77, 73, 78, 73, 77, 193, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 84,
+ 82, 73, 65, 78, 71, 85, 76, 65, 210, 65, 80, 79, 83, 84, 82, 79, 70, 79,
+ 201, 65, 80, 79, 83, 84, 82, 79, 70, 79, 211, 65, 82, 80, 69, 71, 71, 73,
+ 65, 84, 207, 65, 84, 72, 65, 80, 65, 83, 67, 65, 206, 67, 69, 78, 84, 82,
+ 69, 76, 73, 78, 197, 67, 72, 65, 82, 65, 67, 84, 69, 82, 128, 67, 79, 80,
+ 82, 79, 68, 85, 67, 84, 128, 67, 82, 79, 83, 83, 72, 65, 84, 67, 200, 69,
+ 77, 66, 69, 68, 68, 73, 78, 71, 128, 70, 73, 78, 65, 78, 67, 73, 65, 76,
+ 128, 70, 79, 76, 76, 79, 87, 73, 78, 71, 128, 70, 82, 69, 84, 66, 79, 65,
+ 82, 68, 128, 71, 69, 82, 83, 72, 65, 89, 73, 77, 128, 71, 79, 82, 84, 72,
+ 77, 73, 75, 79, 206, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 75, 72, 65,
+ 75, 65, 83, 83, 73, 65, 206, 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80,
+ 65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 69, 78, 84, 65, 83, 69, 77, 69,
+ 128, 80, 72, 73, 76, 73, 80, 80, 73, 78, 197, 83, 69, 77, 73, 67, 73, 82,
+ 67, 76, 197, 83, 85, 77, 77, 65, 84, 73, 79, 78, 128, 83, 85, 80, 69, 82,
+ 86, 73, 83, 69, 128, 83, 89, 77, 66, 79, 76, 45, 49, 49, 128, 83, 89, 77,
+ 66, 79, 76, 45, 49, 50, 128, 83, 89, 77, 66, 79, 76, 45, 49, 51, 128, 83,
+ 89, 77, 66, 79, 76, 45, 49, 52, 128, 83, 89, 77, 66, 79, 76, 45, 49, 55,
+ 128, 83, 89, 77, 66, 79, 76, 45, 49, 56, 128, 83, 89, 77, 66, 79, 76, 45,
+ 49, 57, 128, 83, 89, 77, 66, 79, 76, 45, 50, 51, 128, 83, 89, 77, 66, 79,
+ 76, 45, 50, 52, 128, 83, 89, 77, 66, 79, 76, 45, 53, 48, 128, 83, 89, 77,
+ 66, 79, 76, 45, 53, 49, 128, 83, 89, 77, 66, 79, 76, 45, 53, 50, 128, 83,
+ 89, 77, 66, 79, 76, 45, 53, 51, 128, 83, 89, 77, 66, 79, 76, 45, 53, 52,
+ 128, 84, 69, 76, 69, 80, 72, 79, 78, 69, 128, 84, 69, 84, 82, 65, 83, 69,
+ 77, 69, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 77, 79,
+ 76, 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, 82, 73,
+ 71, 82, 65, 77, 77, 79, 211, 84, 82, 79, 75, 85, 84, 65, 83, 84, 201, 65,
+ 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 66, 85, 78, 68, 65, 78, 67, 69,
+ 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 78, 84, 73, 70, 79, 78,
+ 73, 65, 128, 65, 80, 80, 82, 79, 65, 67, 72, 69, 211, 65, 82, 45, 82, 65,
+ 72, 69, 69, 77, 128, 65, 83, 83, 69, 82, 84, 73, 79, 78, 128, 65, 84, 84,
+ 69, 78, 84, 73, 79, 78, 128, 66, 65, 67, 75, 83, 80, 65, 67, 69, 128, 66,
+ 69, 71, 73, 78, 78, 73, 78, 71, 128, 66, 73, 66, 76, 69, 45, 67, 82, 69,
+ 197, 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 72, 65, 86, 73, 89, 65,
+ 78, 73, 128, 67, 76, 79, 83, 69, 78, 69, 83, 83, 128, 67, 79, 77, 80, 76,
+ 69, 84, 69, 68, 128, 67, 79, 78, 83, 84, 65, 78, 67, 89, 128, 67, 79, 80,
+ 89, 82, 73, 71, 72, 84, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68,
+ 65, 82, 75, 69, 78, 73, 78, 71, 128, 68, 69, 80, 65, 82, 84, 85, 82, 69,
+ 128, 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 73, 70, 70, 69, 82, 69,
+ 78, 67, 197, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 79, 84, 83, 45,
+ 49, 50, 51, 52, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 128, 68, 79, 84,
+ 83, 45, 49, 50, 51, 54, 128, 68, 79, 84, 83, 45, 49, 50, 51, 55, 128, 68,
+ 79, 84, 83, 45, 49, 50, 51, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53,
+ 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 128, 68, 79, 84, 83, 45, 49, 50,
+ 52, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 56, 128, 68, 79, 84, 83, 45,
+ 49, 50, 53, 54, 128, 68, 79, 84, 83, 45, 49, 50, 53, 55, 128, 68, 79, 84,
+ 83, 45, 49, 50, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 54, 55, 128, 68,
+ 79, 84, 83, 45, 49, 50, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 55, 56,
+ 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 128, 68, 79, 84, 83, 45, 49, 51,
+ 52, 54, 128, 68, 79, 84, 83, 45, 49, 51, 52, 55, 128, 68, 79, 84, 83, 45,
+ 49, 51, 52, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 128, 68, 79, 84,
+ 83, 45, 49, 51, 53, 55, 128, 68, 79, 84, 83, 45, 49, 51, 53, 56, 128, 68,
+ 79, 84, 83, 45, 49, 51, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 54, 56,
+ 128, 68, 79, 84, 83, 45, 49, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52,
+ 53, 54, 128, 68, 79, 84, 83, 45, 49, 52, 53, 55, 128, 68, 79, 84, 83, 45,
+ 49, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 52, 54, 55, 128, 68, 79, 84,
+ 83, 45, 49, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, 52, 55, 56, 128, 68,
+ 79, 84, 83, 45, 49, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 53, 54, 56,
+ 128, 68, 79, 84, 83, 45, 49, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 54,
+ 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 128, 68, 79, 84, 83, 45,
+ 50, 51, 52, 54, 128, 68, 79, 84, 83, 45, 50, 51, 52, 55, 128, 68, 79, 84,
+ 83, 45, 50, 51, 52, 56, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 128, 68,
+ 79, 84, 83, 45, 50, 51, 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 53, 56,
+ 128, 68, 79, 84, 83, 45, 50, 51, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51,
+ 54, 56, 128, 68, 79, 84, 83, 45, 50, 51, 55, 56, 128, 68, 79, 84, 83, 45,
+ 50, 52, 53, 54, 128, 68, 79, 84, 83, 45, 50, 52, 53, 55, 128, 68, 79, 84,
+ 83, 45, 50, 52, 53, 56, 128, 68, 79, 84, 83, 45, 50, 52, 54, 55, 128, 68,
+ 79, 84, 83, 45, 50, 52, 54, 56, 128, 68, 79, 84, 83, 45, 50, 52, 55, 56,
+ 128, 68, 79, 84, 83, 45, 50, 53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 53,
+ 54, 56, 128, 68, 79, 84, 83, 45, 50, 53, 55, 56, 128, 68, 79, 84, 83, 45,
+ 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84,
+ 83, 45, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 56, 128, 68,
+ 79, 84, 83, 45, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56,
+ 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53,
+ 54, 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45,
+ 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84,
+ 83, 45, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68,
+ 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, 55, 56,
+ 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 69, 69, 66, 69, 69, 70, 73,
+ 76, 73, 128, 69, 78, 65, 82, 77, 79, 78, 73, 79, 211, 69, 78, 68, 69, 65,
+ 86, 79, 85, 82, 128, 69, 78, 68, 79, 70, 79, 78, 79, 78, 128, 69, 83, 84,
+ 73, 77, 65, 84, 69, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, 128, 69,
+ 89, 66, 69, 89, 70, 73, 76, 73, 128, 70, 79, 79, 84, 83, 84, 79, 79, 76,
+ 128, 70, 79, 83, 84, 69, 82, 73, 78, 71, 128, 70, 82, 73, 67, 65, 84, 73,
+ 86, 69, 128, 71, 65, 84, 72, 69, 82, 73, 78, 71, 128, 71, 69, 77, 73, 78,
+ 65, 84, 73, 79, 206, 71, 78, 65, 86, 73, 89, 65, 78, 73, 128, 71, 79, 82,
+ 71, 79, 84, 69, 82, 73, 128, 71, 82, 69, 65, 84, 78, 69, 83, 83, 128, 71,
+ 85, 82, 65, 77, 85, 84, 79, 78, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85,
+ 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 89, 83, 84, 69, 82, 69,
+ 83, 73, 211, 73, 76, 85, 85, 89, 65, 78, 78, 65, 128, 73, 77, 73, 70, 84,
+ 72, 79, 82, 65, 128, 73, 78, 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67,
+ 82, 69, 77, 69, 78, 84, 128, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73,
+ 78, 70, 76, 85, 69, 78, 67, 69, 128, 73, 78, 78, 79, 67, 69, 78, 67, 69,
+ 128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 74, 69, 82, 85, 83, 65, 76,
+ 69, 77, 128, 75, 65, 84, 65, 86, 65, 83, 77, 65, 128, 75, 69, 77, 80, 72,
+ 82, 69, 78, 71, 128, 75, 69, 78, 84, 73, 77, 65, 84, 65, 128, 75, 73, 82,
+ 79, 87, 65, 84, 84, 79, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, 128, 75,
+ 85, 82, 85, 90, 69, 73, 82, 79, 128, 76, 65, 66, 79, 85, 82, 73, 78, 71,
+ 128, 76, 72, 65, 86, 73, 89, 65, 78, 73, 128, 76, 73, 71, 72, 84, 78, 73,
+ 78, 71, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 84, 69, 82,
+ 73, 65, 76, 83, 128, 77, 69, 84, 79, 66, 69, 76, 85, 83, 128, 77, 73, 82,
+ 73, 66, 65, 65, 82, 85, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77,
+ 79, 79, 83, 69, 45, 67, 82, 69, 197, 77, 85, 75, 80, 72, 82, 69, 78, 71,
+ 128, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 79, 65, 66, 79, 65, 70, 73,
+ 76, 73, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, 79, 82, 84, 72, 79,
+ 71, 79, 78, 65, 204, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 82,
+ 65, 71, 82, 65, 80, 72, 128, 80, 73, 65, 83, 85, 84, 79, 82, 85, 128, 80,
+ 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 90, 90, 73, 67, 65, 84, 79,
+ 128, 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 79, 82, 82, 69, 67, 84,
+ 85, 83, 128, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, 77, 45,
+ 77, 85, 79, 89, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, 211, 81, 85, 65,
+ 84, 69, 82, 78, 73, 79, 206, 81, 85, 69, 83, 84, 73, 79, 78, 69, 196, 81,
+ 85, 83, 72, 83, 72, 65, 89, 65, 128, 82, 69, 71, 73, 83, 84, 69, 82, 69,
+ 196, 82, 69, 76, 65, 84, 73, 79, 78, 65, 204, 82, 69, 80, 82, 69, 83, 69,
+ 78, 84, 128, 82, 69, 83, 73, 68, 69, 78, 67, 69, 128, 82, 69, 83, 85, 80,
+ 73, 78, 85, 83, 128, 82, 73, 71, 72, 84, 45, 83, 73, 68, 197, 83, 67, 65,
+ 78, 68, 73, 67, 85, 83, 128, 83, 69, 80, 84, 69, 77, 66, 69, 82, 128, 83,
+ 69, 86, 69, 82, 65, 78, 67, 69, 128, 83, 72, 65, 86, 73, 89, 65, 78, 73,
+ 128, 83, 72, 79, 82, 84, 69, 78, 69, 82, 128, 83, 72, 79, 85, 76, 68, 69,
+ 82, 69, 196, 83, 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 83,
+ 84, 82, 73, 78, 199, 83, 84, 82, 79, 75, 69, 45, 49, 48, 128, 83, 84, 82,
+ 79, 75, 69, 45, 49, 49, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83,
+ 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 89, 77, 66, 79, 76, 45, 49, 48,
+ 128, 83, 89, 77, 66, 79, 76, 45, 49, 53, 128, 83, 89, 77, 66, 79, 76, 45,
+ 49, 54, 128, 83, 89, 77, 66, 79, 76, 45, 50, 48, 128, 83, 89, 77, 66, 79,
+ 76, 45, 50, 49, 128, 83, 89, 77, 66, 79, 76, 45, 50, 50, 128, 83, 89, 77,
+ 66, 79, 76, 45, 50, 53, 128, 83, 89, 77, 66, 79, 76, 45, 50, 54, 128, 83,
+ 89, 77, 66, 79, 76, 45, 50, 55, 128, 83, 89, 77, 66, 79, 76, 45, 50, 57,
+ 128, 83, 89, 77, 66, 79, 76, 45, 51, 48, 128, 83, 89, 77, 66, 79, 76, 45,
+ 51, 50, 128, 83, 89, 77, 66, 79, 76, 45, 51, 54, 128, 83, 89, 77, 66, 79,
+ 76, 45, 51, 55, 128, 83, 89, 77, 66, 79, 76, 45, 51, 56, 128, 83, 89, 77,
+ 66, 79, 76, 45, 51, 57, 128, 83, 89, 77, 66, 79, 76, 45, 52, 48, 128, 83,
+ 89, 77, 66, 79, 76, 45, 52, 50, 128, 83, 89, 77, 66, 79, 76, 45, 52, 51,
+ 128, 83, 89, 77, 66, 79, 76, 45, 52, 53, 128, 83, 89, 77, 66, 79, 76, 45,
+ 52, 55, 128, 83, 89, 77, 66, 79, 76, 45, 52, 56, 128, 83, 89, 77, 66, 79,
+ 76, 45, 52, 57, 128, 83, 89, 82, 77, 65, 84, 73, 75, 73, 128, 84, 65, 75,
+ 72, 65, 76, 76, 85, 83, 128, 84, 65, 87, 69, 76, 76, 69, 77, 69, 212, 84,
+ 72, 69, 82, 69, 70, 79, 82, 69, 128, 84, 72, 82, 69, 69, 45, 76, 73, 78,
+ 197, 84, 82, 73, 70, 79, 76, 73, 65, 84, 197, 84, 82, 73, 70, 79, 78, 73,
+ 65, 83, 128, 84, 82, 73, 71, 79, 82, 71, 79, 78, 128, 84, 85, 84, 69, 89,
+ 65, 83, 65, 84, 128, 86, 73, 83, 65, 82, 71, 65, 89, 65, 128, 87, 65, 83,
+ 83, 65, 76, 76, 65, 77, 128, 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87,
+ 79, 82, 68, 83, 80, 65, 67, 69, 128, 89, 80, 79, 75, 82, 73, 83, 73, 83,
+ 128, 76, 69, 83, 83, 45, 84, 72, 65, 206, 68, 79, 87, 78, 87, 65, 82, 68,
+ 211, 84, 82, 73, 65, 78, 71, 76, 69, 128, 79, 80, 69, 82, 65, 84, 79, 82,
+ 128, 83, 85, 66, 83, 67, 82, 73, 80, 212, 84, 72, 79, 85, 83, 65, 78, 68,
+ 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 81, 85, 79, 84, 65, 84, 73, 79,
+ 206, 65, 83, 84, 69, 82, 73, 83, 75, 128, 79, 82, 78, 65, 77, 69, 78, 84,
+ 128, 82, 69, 84, 82, 79, 70, 76, 69, 216, 65, 82, 67, 72, 65, 73, 79, 78,
+ 128, 68, 73, 65, 69, 82, 69, 83, 73, 211, 66, 76, 65, 67, 75, 70, 79, 79,
+ 212, 68, 69, 78, 84, 73, 83, 84, 82, 217, 68, 73, 65, 76, 89, 84, 73, 75,
+ 193, 73, 78, 84, 69, 71, 82, 65, 76, 128, 65, 78, 85, 83, 86, 65, 82, 65,
+ 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, 76, 69, 70, 84, 45, 83, 84, 69,
+ 205, 82, 69, 67, 89, 67, 76, 73, 78, 199, 65, 66, 75, 72, 65, 83, 73, 65,
+ 206, 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 79, 68, 69, 75, 65, 84, 65,
+ 128, 69, 76, 76, 73, 80, 83, 73, 83, 128, 81, 85, 65, 68, 82, 65, 78, 84,
+ 128, 81, 85, 65, 68, 82, 85, 80, 76, 197, 68, 73, 65, 84, 79, 78, 73, 75,
+ 201, 69, 78, 67, 76, 79, 83, 73, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69,
+ 128, 80, 76, 65, 83, 84, 73, 67, 83, 128, 65, 82, 82, 79, 87, 72, 69, 65,
+ 196, 73, 84, 69, 82, 65, 84, 73, 79, 206, 78, 79, 84, 69, 72, 69, 65, 68,
+ 128, 78, 85, 77, 69, 82, 65, 84, 79, 210, 65, 86, 65, 71, 82, 65, 72, 65,
+ 128, 69, 73, 71, 72, 84, 69, 69, 78, 128, 70, 79, 85, 82, 84, 69, 69, 78,
+ 128, 78, 73, 78, 69, 84, 69, 69, 78, 128, 83, 85, 80, 69, 82, 83, 69, 84,
+ 128, 84, 72, 73, 82, 84, 69, 69, 78, 128, 68, 73, 65, 71, 79, 78, 65, 76,
+ 128, 69, 88, 84, 82, 65, 45, 76, 79, 215, 70, 76, 79, 82, 69, 84, 84, 69,
+ 128, 73, 68, 69, 78, 84, 73, 67, 65, 204, 75, 69, 78, 84, 73, 77, 65, 84,
+ 193, 80, 65, 82, 65, 71, 82, 65, 80, 200, 82, 69, 76, 65, 84, 73, 79, 78,
+ 128, 83, 67, 73, 83, 83, 79, 82, 83, 128, 83, 69, 66, 65, 84, 66, 69, 73,
+ 212, 83, 69, 80, 65, 82, 65, 84, 79, 210, 65, 76, 84, 69, 82, 78, 65, 84,
+ 197, 68, 68, 65, 89, 65, 78, 78, 65, 128, 68, 69, 80, 65, 82, 84, 73, 78,
+ 199, 70, 65, 78, 69, 82, 79, 83, 73, 211, 70, 73, 83, 72, 72, 79, 79, 75,
+ 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 77, 79, 85, 78, 84, 65, 73, 78,
+ 128, 77, 85, 76, 84, 73, 77, 65, 80, 128, 77, 85, 85, 82, 68, 72, 65, 74,
+ 193, 80, 65, 82, 65, 76, 76, 69, 76, 128, 80, 82, 69, 67, 69, 68, 69, 83,
+ 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, 80, 72, 69, 82, 73, 67, 65,
+ 204, 83, 85, 66, 76, 73, 78, 69, 65, 210, 83, 85, 67, 67, 69, 69, 68, 83,
+ 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 84, 69, 76, 69, 80, 72, 79, 78,
+ 197, 84, 72, 79, 85, 83, 65, 78, 68, 211, 89, 69, 83, 73, 69, 85, 78, 71,
+ 128, 65, 76, 76, 73, 65, 78, 67, 69, 128, 67, 65, 85, 76, 68, 82, 79, 78,
+ 128, 67, 79, 78, 83, 84, 65, 78, 84, 128, 68, 73, 70, 79, 78, 73, 65, 83,
+ 128, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 82, 65, 67, 72, 77, 65, 83,
+ 128, 70, 76, 65, 84, 84, 69, 78, 69, 196, 71, 65, 82, 83, 72, 85, 78, 73,
+ 128, 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 76, 73, 83, 83, 65, 78, 68,
+ 207, 71, 82, 69, 71, 79, 82, 73, 65, 206, 73, 78, 67, 82, 69, 65, 83, 69,
+ 128, 73, 78, 83, 69, 82, 84, 73, 79, 206, 73, 78, 86, 73, 83, 73, 66, 76,
+ 197, 73, 83, 45, 80, 73, 76, 76, 65, 128, 79, 86, 69, 82, 82, 73, 68, 69,
+ 128, 79, 89, 82, 65, 78, 73, 83, 77, 193, 80, 69, 68, 69, 83, 84, 65, 76,
+ 128, 80, 78, 69, 85, 77, 65, 84, 65, 128, 80, 82, 65, 77, 45, 66, 85, 79,
+ 206, 80, 82, 65, 77, 45, 77, 85, 79, 217, 80, 82, 79, 76, 79, 78, 71, 69,
+ 196, 80, 82, 79, 80, 69, 76, 76, 69, 210, 82, 69, 83, 79, 85, 82, 67, 69,
+ 128, 82, 69, 83, 80, 79, 78, 83, 69, 128, 82, 69, 86, 69, 82, 83, 69, 68,
+ 128, 83, 69, 77, 73, 86, 79, 87, 69, 204, 83, 85, 66, 71, 82, 79, 85, 80,
+ 128, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, 89, 77, 66, 79, 76, 45, 49,
+ 128, 83, 89, 77, 66, 79, 76, 45, 50, 128, 83, 89, 77, 66, 79, 76, 45, 52,
+ 128, 83, 89, 77, 66, 79, 76, 45, 53, 128, 83, 89, 77, 66, 79, 76, 45, 55,
+ 128, 83, 89, 77, 66, 79, 76, 45, 56, 128, 83, 89, 77, 77, 69, 84, 82, 73,
+ 195, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 82, 73, 83, 73, 77, 79, 85,
+ 128, 84, 84, 65, 89, 65, 78, 78, 65, 128, 85, 78, 68, 69, 82, 76, 73, 78,
+ 197, 85, 78, 68, 69, 82, 84, 73, 69, 128, 85, 78, 73, 86, 69, 82, 83, 65,
+ 204, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 69, 69, 89, 65, 78, 78, 65,
+ 128, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, 78, 85, 68, 65, 84, 84, 65,
+ 128, 65, 80, 79, 68, 69, 88, 73, 65, 128, 65, 80, 79, 84, 72, 69, 77, 65,
+ 128, 65, 80, 80, 82, 79, 65, 67, 72, 128, 65, 81, 85, 65, 82, 73, 85, 83,
+ 128, 65, 82, 45, 82, 65, 72, 77, 65, 206, 65, 82, 65, 69, 65, 45, 69, 79,
+ 128, 65, 82, 71, 79, 84, 69, 82, 73, 128, 65, 82, 73, 83, 84, 69, 82, 65,
+ 128, 65, 83, 67, 69, 78, 68, 73, 78, 199, 65, 83, 84, 69, 82, 73, 83, 75,
+ 211, 65, 83, 84, 69, 82, 73, 83, 77, 128, 65, 84, 84, 72, 65, 67, 65, 78,
+ 128, 66, 65, 67, 75, 83, 76, 65, 83, 200, 66, 69, 86, 69, 82, 65, 71, 69,
+ 128, 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, 83, 69, 67, 84, 73, 78,
+ 199, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 82, 65, 78, 67, 72, 73, 78,
+ 199, 66, 85, 76, 76, 83, 69, 89, 69, 128, 66, 85, 83, 83, 89, 69, 82, 85,
+ 128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 82, 89, 83, 84, 73, 65,
+ 206, 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 84, 84, 65, 87, 65,
+ 128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 76, 73, 77, 65, 67, 85, 83,
+ 128, 67, 79, 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 71, 82, 85, 69, 78,
+ 212, 67, 79, 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 84, 79, 85, 82, 69,
+ 196, 67, 79, 80, 89, 82, 73, 71, 72, 212, 67, 82, 69, 83, 67, 69, 78, 84,
+ 128, 68, 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 82, 75, 69, 78, 73, 78,
+ 199, 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 69, 67, 69, 77, 66, 69, 82,
+ 128, 68, 69, 67, 82, 69, 65, 83, 69, 128, 68, 69, 76, 73, 77, 73, 84, 69,
+ 210, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 71, 79, 82, 71, 79, 78,
+ 128, 68, 73, 77, 69, 78, 83, 73, 79, 206, 68, 79, 84, 83, 45, 49, 50, 51,
+ 128, 68, 79, 84, 83, 45, 49, 50, 52, 128, 68, 79, 84, 83, 45, 49, 50, 53,
+ 128, 68, 79, 84, 83, 45, 49, 50, 54, 128, 68, 79, 84, 83, 45, 49, 50, 55,
+ 128, 68, 79, 84, 83, 45, 49, 50, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52,
+ 128, 68, 79, 84, 83, 45, 49, 51, 53, 128, 68, 79, 84, 83, 45, 49, 51, 54,
+ 128, 68, 79, 84, 83, 45, 49, 51, 55, 128, 68, 79, 84, 83, 45, 49, 51, 56,
+ 128, 68, 79, 84, 83, 45, 49, 52, 53, 128, 68, 79, 84, 83, 45, 49, 52, 54,
+ 128, 68, 79, 84, 83, 45, 49, 52, 55, 128, 68, 79, 84, 83, 45, 49, 52, 56,
+ 128, 68, 79, 84, 83, 45, 49, 53, 54, 128, 68, 79, 84, 83, 45, 49, 53, 55,
+ 128, 68, 79, 84, 83, 45, 49, 53, 56, 128, 68, 79, 84, 83, 45, 49, 54, 55,
+ 128, 68, 79, 84, 83, 45, 49, 54, 56, 128, 68, 79, 84, 83, 45, 49, 55, 56,
+ 128, 68, 79, 84, 83, 45, 50, 51, 52, 128, 68, 79, 84, 83, 45, 50, 51, 53,
+ 128, 68, 79, 84, 83, 45, 50, 51, 54, 128, 68, 79, 84, 83, 45, 50, 51, 55,
+ 128, 68, 79, 84, 83, 45, 50, 51, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53,
+ 128, 68, 79, 84, 83, 45, 50, 52, 54, 128, 68, 79, 84, 83, 45, 50, 52, 55,
+ 128, 68, 79, 84, 83, 45, 50, 52, 56, 128, 68, 79, 84, 83, 45, 50, 53, 54,
+ 128, 68, 79, 84, 83, 45, 50, 53, 55, 128, 68, 79, 84, 83, 45, 50, 53, 56,
+ 128, 68, 79, 84, 83, 45, 50, 54, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56,
+ 128, 68, 79, 84, 83, 45, 50, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53,
+ 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, 52, 55,
+ 128, 68, 79, 84, 83, 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54,
+ 128, 68, 79, 84, 83, 45, 51, 53, 55, 128, 68, 79, 84, 83, 45, 51, 53, 56,
+ 128, 68, 79, 84, 83, 45, 51, 54, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56,
+ 128, 68, 79, 84, 83, 45, 51, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54,
+ 128, 68, 79, 84, 83, 45, 52, 53, 55, 128, 68, 79, 84, 83, 45, 52, 53, 56,
+ 128, 68, 79, 84, 83, 45, 52, 54, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56,
+ 128, 68, 79, 84, 83, 45, 52, 55, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55,
+ 128, 68, 79, 84, 83, 45, 53, 54, 56, 128, 68, 79, 84, 83, 45, 53, 55, 56,
+ 128, 68, 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 84, 69, 68, 45, 76,
+ 128, 68, 79, 84, 84, 69, 68, 45, 78, 128, 68, 79, 84, 84, 69, 68, 45, 80,
+ 128, 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 86, 73, 83, 86, 65, 82, 65,
+ 128, 69, 68, 73, 84, 79, 82, 73, 65, 204, 69, 78, 86, 69, 76, 79, 80, 69,
+ 128, 69, 80, 69, 71, 69, 82, 77, 65, 128, 69, 83, 84, 73, 77, 65, 84, 69,
+ 196, 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 84, 69, 82, 78, 73, 84, 89,
+ 128, 70, 65, 67, 83, 73, 77, 73, 76, 197, 70, 65, 84, 72, 65, 84, 65, 78,
+ 128, 70, 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, 83, 84, 73, 86, 65, 76,
+ 128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, 73, 71, 85, 82, 69, 45, 50,
+ 128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, 73, 86, 69, 45, 76, 73, 78,
+ 197, 70, 79, 85, 82, 45, 76, 73, 78, 197, 70, 82, 65, 71, 77, 69, 78, 84,
+ 128, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 85, 76, 76, 78, 69, 83, 83,
+ 128, 70, 85, 78, 67, 84, 73, 79, 78, 128, 71, 69, 78, 73, 84, 73, 86, 69,
+ 128, 71, 69, 79, 77, 69, 84, 82, 73, 195, 72, 65, 78, 45, 65, 75, 65, 84,
+ 128, 72, 65, 82, 68, 78, 69, 83, 83, 128, 72, 65, 82, 77, 79, 78, 73, 67,
+ 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 85, 65, 82, 65, 68, 68, 79,
+ 128, 73, 76, 85, 89, 65, 78, 78, 65, 128, 73, 77, 73, 70, 79, 78, 79, 78,
+ 128, 73, 78, 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 82, 69, 65, 83, 69,
+ 211, 73, 82, 85, 89, 65, 78, 78, 65, 128, 74, 65, 86, 73, 89, 65, 78, 73,
+ 128, 75, 65, 83, 82, 65, 84, 65, 78, 128, 75, 65, 84, 72, 73, 83, 84, 73,
+ 128, 75, 69, 89, 66, 79, 65, 82, 68, 128, 75, 79, 78, 84, 69, 86, 77, 65,
+ 128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 76, 65, 82, 89, 78, 71, 69, 65,
+ 204, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, 73, 65, 66, 73, 76, 73, 84,
+ 217, 76, 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 82, 82, 65, 73, 78, 69,
+ 128, 77, 65, 72, 65, 80, 65, 75, 72, 128, 77, 65, 73, 77, 65, 76, 65, 73,
+ 128, 77, 65, 73, 89, 65, 77, 79, 75, 128, 77, 65, 78, 71, 65, 76, 65, 77,
+ 128, 77, 65, 83, 67, 85, 76, 73, 78, 197, 77, 69, 68, 73, 67, 73, 78, 69,
+ 128, 77, 69, 83, 83, 69, 78, 73, 65, 206, 77, 73, 78, 73, 83, 84, 69, 82,
+ 128, 77, 85, 76, 84, 73, 83, 69, 84, 128, 78, 73, 75, 72, 65, 72, 73, 84,
+ 128, 78, 79, 82, 84, 72, 87, 69, 83, 212, 78, 79, 86, 69, 77, 66, 69, 82,
+ 128, 79, 86, 69, 82, 76, 65, 73, 68, 128, 80, 65, 65, 83, 69, 78, 84, 79,
+ 128, 80, 65, 73, 82, 84, 72, 82, 65, 128, 80, 65, 76, 79, 67, 72, 75, 65,
+ 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 82, 73, 67, 72, 79, 78,
+ 128, 80, 65, 86, 73, 89, 65, 78, 73, 128, 80, 69, 76, 65, 83, 84, 79, 78,
+ 128, 80, 69, 82, 77, 65, 78, 69, 78, 212, 80, 73, 84, 67, 72, 70, 79, 82,
+ 203, 80, 76, 69, 84, 72, 82, 79, 78, 128, 80, 79, 82, 82, 69, 67, 84, 85,
+ 211, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 80, 73, 73,
+ 128, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, 71, 82, 69, 83, 83,
+ 128, 80, 83, 73, 70, 73, 83, 84, 79, 206, 81, 65, 73, 82, 84, 72, 82, 65,
+ 128, 81, 85, 65, 82, 84, 69, 82, 83, 128, 81, 85, 69, 83, 84, 73, 79, 78,
+ 128, 82, 69, 67, 69, 80, 84, 73, 86, 197, 82, 69, 67, 79, 82, 68, 69, 82,
+ 128, 82, 69, 67, 79, 82, 68, 73, 78, 199, 82, 69, 67, 84, 65, 78, 71, 76,
+ 197, 82, 69, 70, 69, 82, 69, 78, 67, 197, 82, 69, 76, 73, 71, 73, 79, 78,
+ 128, 82, 69, 78, 84, 79, 71, 69, 78, 128, 82, 73, 71, 72, 84, 72, 65, 78,
+ 196, 82, 85, 75, 75, 65, 75, 72, 65, 128, 83, 65, 78, 84, 73, 73, 77, 85,
+ 128, 83, 65, 88, 73, 77, 65, 84, 65, 128, 83, 67, 65, 78, 68, 73, 67, 85,
+ 211, 83, 67, 79, 82, 80, 73, 85, 83, 128, 83, 69, 77, 73, 67, 79, 76, 79,
+ 206, 83, 69, 86, 69, 78, 84, 69, 69, 206, 83, 72, 65, 77, 82, 79, 67, 75,
+ 128, 83, 72, 69, 45, 71, 79, 65, 84, 128, 83, 73, 67, 75, 78, 69, 83, 83,
+ 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 84, 65, 76, 76, 73, 79, 78,
+ 128, 83, 84, 79, 80, 80, 65, 71, 69, 128, 83, 84, 79, 80, 80, 73, 78, 71,
+ 128, 83, 84, 82, 69, 78, 71, 84, 72, 128, 83, 84, 82, 69, 84, 67, 72, 69,
+ 196, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, 75, 69, 45, 50,
+ 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, 45, 52,
+ 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, 45, 54,
+ 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, 45, 56,
+ 128, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 85, 73, 84, 65, 66, 76, 69,
+ 128, 83, 85, 82, 82, 79, 85, 78, 68, 128, 83, 89, 77, 66, 79, 76, 45, 51,
+ 128, 83, 89, 77, 66, 79, 76, 45, 54, 128, 83, 89, 77, 66, 79, 76, 45, 57,
+ 128, 83, 89, 77, 77, 69, 84, 82, 89, 128, 83, 89, 78, 68, 69, 83, 77, 79,
+ 211, 84, 65, 86, 73, 89, 65, 78, 73, 128, 84, 69, 84, 82, 65, 80, 76, 73,
+ 128, 84, 79, 82, 67, 85, 76, 85, 83, 128, 84, 82, 69, 65, 68, 73, 78, 71,
+ 128, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 78,
+ 128, 84, 82, 85, 78, 67, 65, 84, 69, 196, 85, 73, 76, 76, 69, 65, 78, 78,
+ 128, 85, 77, 66, 82, 69, 76, 76, 65, 128, 85, 78, 68, 69, 82, 68, 79, 84,
+ 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 86, 69, 82, 83, 73, 67, 76, 69,
+ 128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 83, 65, 76, 76, 65, 77,
+ 128, 89, 65, 77, 65, 75, 75, 65, 78, 128, 89, 80, 79, 75, 82, 73, 83, 73,
+ 211, 90, 65, 86, 73, 89, 65, 78, 73, 128, 90, 87, 65, 82, 65, 75, 65, 89,
+ 128, 73, 78, 86, 69, 82, 84, 69, 196, 78, 69, 71, 65, 84, 73, 86, 197,
+ 85, 71, 65, 82, 73, 84, 73, 195, 66, 85, 71, 73, 78, 69, 83, 197, 72, 85,
+ 78, 68, 82, 69, 68, 128, 67, 69, 68, 73, 76, 76, 65, 128, 84, 82, 73, 65,
+ 78, 71, 76, 197, 78, 79, 84, 69, 72, 69, 65, 196, 83, 85, 80, 69, 82, 83,
+ 69, 212, 70, 82, 65, 67, 84, 73, 79, 206, 81, 85, 69, 83, 84, 73, 79,
+ 206, 84, 65, 71, 66, 65, 78, 87, 193, 81, 85, 65, 68, 82, 65, 78, 212,
+ 68, 73, 65, 71, 79, 78, 65, 204, 85, 80, 83, 73, 76, 79, 78, 128, 79, 86,
+ 69, 82, 76, 65, 89, 128, 77, 65, 82, 84, 89, 82, 73, 193, 79, 86, 69, 82,
+ 66, 65, 82, 128, 68, 73, 65, 77, 79, 78, 68, 128, 69, 80, 83, 73, 76, 79,
+ 78, 128, 72, 65, 78, 71, 90, 72, 79, 213, 73, 78, 84, 69, 71, 82, 65,
+ 204, 77, 69, 65, 83, 85, 82, 69, 196, 79, 77, 73, 67, 82, 79, 78, 128,
+ 84, 79, 82, 84, 79, 73, 83, 197, 79, 82, 78, 65, 77, 69, 78, 212, 86, 73,
+ 83, 65, 82, 71, 65, 128, 69, 88, 84, 69, 78, 68, 69, 196, 72, 65, 82, 80,
+ 79, 79, 78, 128, 80, 82, 69, 67, 69, 68, 69, 211, 83, 79, 76, 73, 68, 85,
+ 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 84, 72, 69, 83, 80, 73, 65,
+ 206, 67, 79, 78, 84, 65, 73, 78, 211, 68, 73, 71, 82, 65, 80, 72, 128,
+ 77, 69, 84, 82, 73, 67, 65, 204, 77, 79, 78, 79, 71, 82, 65, 205, 67, 82,
+ 79, 83, 83, 73, 78, 199, 83, 73, 77, 65, 78, 83, 73, 211, 83, 84, 65, 84,
+ 69, 82, 83, 128, 83, 85, 66, 85, 78, 73, 84, 128, 83, 73, 68, 69, 87, 65,
+ 89, 211, 83, 81, 85, 65, 82, 69, 68, 128, 84, 65, 76, 69, 78, 84, 83,
+ 128, 84, 72, 79, 85, 83, 65, 78, 196, 66, 65, 82, 76, 73, 78, 69, 128,
+ 68, 73, 86, 73, 83, 73, 79, 206, 73, 79, 84, 73, 70, 73, 69, 196, 80, 65,
+ 82, 65, 76, 76, 69, 204, 83, 73, 88, 84, 69, 69, 78, 128, 83, 85, 66, 71,
+ 82, 79, 85, 208, 83, 85, 82, 82, 79, 85, 78, 196, 85, 80, 87, 65, 82, 68,
+ 83, 128, 70, 73, 70, 84, 69, 69, 78, 128, 79, 80, 69, 82, 65, 84, 79,
+ 210, 79, 82, 73, 71, 73, 78, 65, 204, 68, 73, 65, 83, 84, 79, 76, 201,
+ 68, 73, 86, 73, 68, 69, 82, 128, 70, 65, 84, 72, 65, 84, 65, 206, 73, 90,
+ 72, 73, 84, 83, 65, 128, 77, 89, 83, 76, 73, 84, 69, 128, 80, 79, 73, 78,
+ 84, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, 212, 65, 83, 84, 69, 82, 73,
+ 83, 203, 66, 65, 89, 65, 78, 78, 65, 128, 67, 72, 82, 79, 78, 79, 78,
+ 128, 68, 73, 71, 79, 82, 71, 79, 206, 69, 73, 71, 72, 84, 72, 83, 128,
+ 70, 73, 78, 71, 69, 82, 69, 196, 71, 65, 89, 65, 78, 78, 65, 128, 72, 65,
+ 82, 75, 76, 69, 65, 206, 74, 65, 89, 65, 78, 78, 65, 128, 75, 79, 82, 79,
+ 78, 73, 83, 128, 76, 69, 65, 84, 72, 69, 82, 128, 76, 79, 90, 69, 78, 71,
+ 69, 128, 77, 65, 75, 83, 85, 82, 65, 128, 78, 79, 45, 66, 82, 69, 65,
+ 203, 80, 73, 78, 87, 72, 69, 69, 204, 81, 85, 65, 82, 84, 69, 82, 211,
+ 82, 69, 80, 69, 65, 84, 69, 196, 83, 65, 89, 65, 78, 78, 65, 128, 83, 69,
+ 76, 69, 67, 84, 79, 210, 83, 81, 85, 73, 71, 71, 76, 197, 84, 69, 84, 65,
+ 82, 84, 79, 211, 84, 82, 79, 77, 73, 75, 79, 206, 65, 67, 84, 73, 86, 65,
+ 84, 197, 65, 67, 84, 85, 65, 76, 76, 217, 65, 75, 72, 77, 73, 77, 73,
+ 195, 65, 80, 79, 68, 69, 82, 77, 193, 65, 82, 73, 83, 84, 69, 82, 193,
+ 66, 69, 84, 87, 69, 69, 78, 128, 66, 73, 76, 65, 66, 73, 65, 204, 67, 65,
+ 89, 65, 78, 78, 65, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 72, 65, 82,
+ 73, 79, 84, 128, 67, 72, 79, 82, 69, 86, 77, 193, 67, 72, 82, 79, 78, 79,
+ 85, 128, 67, 76, 79, 84, 72, 69, 83, 128, 67, 79, 82, 78, 69, 82, 83,
+ 128, 68, 65, 77, 77, 65, 84, 65, 206, 68, 65, 80, 45, 66, 85, 79, 206,
+ 68, 65, 80, 45, 77, 85, 79, 217, 68, 65, 80, 45, 80, 82, 65, 205, 68, 69,
+ 89, 84, 69, 82, 79, 211, 68, 73, 71, 65, 77, 77, 65, 128, 68, 73, 83, 73,
+ 77, 79, 85, 128, 69, 77, 80, 72, 65, 83, 73, 211, 70, 69, 77, 73, 78, 73,
+ 78, 197, 70, 69, 82, 77, 65, 84, 65, 128, 70, 73, 83, 72, 72, 79, 79,
+ 203, 71, 76, 65, 71, 79, 76, 73, 128, 73, 78, 72, 69, 82, 69, 78, 212,
+ 73, 78, 84, 69, 82, 73, 79, 210, 75, 65, 83, 82, 65, 84, 65, 206, 75, 65,
+ 89, 65, 78, 78, 65, 128, 75, 79, 77, 66, 85, 86, 65, 128, 76, 45, 83, 72,
+ 65, 80, 69, 196, 76, 65, 84, 73, 78, 65, 84, 197, 76, 65, 89, 65, 78, 78,
+ 65, 128, 76, 74, 85, 68, 73, 74, 69, 128, 76, 79, 71, 79, 84, 89, 80,
+ 197, 77, 69, 65, 83, 85, 82, 69, 128, 77, 85, 76, 84, 73, 83, 69, 212,
+ 78, 65, 89, 65, 78, 78, 65, 128, 79, 77, 73, 83, 83, 73, 79, 206, 80, 65,
+ 89, 65, 78, 78, 65, 128, 80, 69, 68, 69, 83, 84, 65, 204, 80, 69, 84, 65,
+ 76, 76, 69, 196, 80, 82, 65, 77, 45, 66, 69, 201, 80, 82, 65, 77, 45, 80,
+ 73, 201, 81, 85, 65, 82, 84, 69, 82, 128, 82, 71, 89, 73, 78, 71, 83,
+ 128, 83, 45, 83, 72, 65, 80, 69, 196, 83, 69, 77, 73, 83, 79, 70, 212,
+ 83, 69, 77, 75, 65, 84, 72, 128, 83, 69, 86, 69, 78, 84, 89, 128, 83, 72,
+ 65, 80, 73, 78, 71, 128, 83, 72, 84, 65, 80, 73, 67, 128, 83, 79, 67, 73,
+ 69, 84, 89, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 69, 67, 73, 65,
+ 76, 128, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 82, 79, 75, 69, 83,
+ 128, 84, 72, 69, 83, 69, 79, 83, 128, 84, 72, 85, 78, 68, 69, 82, 128,
+ 84, 82, 73, 83, 69, 77, 69, 128, 85, 66, 65, 68, 65, 77, 65, 128, 87, 65,
+ 73, 84, 73, 78, 71, 128, 90, 72, 73, 86, 69, 84, 69, 128, 65, 65, 89, 65,
+ 78, 78, 65, 128, 65, 66, 65, 70, 73, 76, 73, 128, 65, 68, 86, 65, 78, 67,
+ 69, 128, 65, 69, 89, 65, 78, 78, 65, 128, 65, 73, 89, 65, 78, 78, 65,
+ 128, 65, 76, 69, 77, 66, 73, 67, 128, 65, 76, 86, 69, 79, 76, 65, 210,
+ 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78,
+ 85, 83, 86, 65, 82, 193, 65, 80, 79, 84, 72, 69, 83, 128, 65, 82, 65, 69,
+ 65, 45, 73, 128, 65, 82, 65, 69, 65, 45, 85, 128, 65, 82, 67, 72, 65, 73,
+ 79, 206, 65, 82, 79, 85, 83, 73, 78, 199, 65, 85, 89, 65, 78, 78, 65,
+ 128, 66, 65, 65, 82, 69, 82, 85, 128, 66, 65, 73, 82, 75, 65, 78, 128,
+ 66, 65, 82, 82, 69, 75, 72, 128, 66, 65, 82, 82, 73, 69, 82, 128, 66, 65,
+ 84, 72, 84, 85, 66, 128, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, 76, 71,
+ 84, 72, 79, 210, 66, 69, 82, 75, 65, 78, 65, 206, 66, 73, 68, 69, 78, 84,
+ 65, 204, 66, 79, 85, 78, 68, 65, 82, 217, 66, 82, 65, 75, 67, 69, 84,
+ 128, 66, 82, 73, 83, 84, 76, 69, 128, 66, 85, 85, 77, 73, 83, 72, 128,
+ 67, 65, 69, 83, 85, 82, 65, 128, 67, 65, 80, 73, 84, 65, 76, 128, 67, 65,
+ 82, 82, 73, 65, 71, 197, 67, 69, 76, 83, 73, 85, 83, 128, 67, 72, 65, 77,
+ 73, 76, 73, 128, 67, 76, 73, 78, 71, 73, 78, 199, 67, 79, 77, 80, 65, 82,
+ 69, 128, 67, 79, 78, 83, 84, 65, 78, 212, 67, 79, 78, 84, 65, 67, 84,
+ 128, 67, 79, 82, 79, 78, 73, 83, 128, 67, 79, 82, 82, 69, 67, 84, 128,
+ 67, 82, 69, 65, 84, 73, 86, 197, 67, 82, 69, 83, 67, 69, 78, 212, 67, 82,
+ 85, 90, 69, 73, 82, 207, 67, 85, 83, 84, 79, 77, 69, 210, 67, 87, 69, 79,
+ 82, 84, 72, 128, 67, 89, 80, 69, 82, 85, 83, 128, 67, 89, 82, 69, 78, 65,
+ 73, 195, 68, 65, 71, 65, 76, 71, 65, 128, 68, 69, 67, 65, 89, 69, 68,
+ 128, 68, 69, 89, 84, 69, 82, 79, 213, 68, 72, 65, 76, 65, 84, 72, 128,
+ 68, 73, 65, 77, 69, 84, 69, 210, 68, 73, 65, 84, 79, 78, 79, 206, 68, 73,
+ 71, 82, 65, 77, 77, 193, 68, 73, 77, 77, 73, 78, 71, 128, 68, 73, 80, 76,
+ 79, 85, 78, 128, 68, 73, 82, 69, 67, 84, 76, 217, 68, 73, 86, 73, 68, 69,
+ 83, 128, 68, 79, 84, 83, 45, 49, 50, 128, 68, 79, 84, 83, 45, 49, 51,
+ 128, 68, 79, 84, 83, 45, 49, 52, 128, 68, 79, 84, 83, 45, 49, 53, 128,
+ 68, 79, 84, 83, 45, 49, 54, 128, 68, 79, 84, 83, 45, 49, 55, 128, 68, 79,
+ 84, 83, 45, 49, 56, 128, 68, 79, 84, 83, 45, 50, 51, 128, 68, 79, 84, 83,
+ 45, 50, 52, 128, 68, 79, 84, 83, 45, 50, 53, 128, 68, 79, 84, 83, 45, 50,
+ 54, 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 56,
+ 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, 45, 51, 53, 128,
+ 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79,
+ 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83,
+ 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52,
+ 56, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, 55,
+ 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128,
+ 68, 79, 84, 83, 45, 54, 56, 128, 68, 79, 84, 83, 45, 55, 56, 128, 68, 82,
+ 65, 67, 72, 77, 65, 128, 68, 82, 65, 70, 84, 73, 78, 199, 69, 65, 66, 72,
+ 65, 68, 72, 128, 69, 65, 68, 72, 65, 68, 72, 128, 69, 66, 69, 70, 73, 76,
+ 73, 128, 69, 73, 71, 72, 84, 69, 69, 206, 69, 76, 65, 70, 82, 79, 78,
+ 128, 69, 76, 69, 67, 84, 82, 73, 195, 69, 78, 81, 85, 73, 82, 89, 128,
+ 69, 78, 84, 69, 82, 73, 78, 199, 69, 84, 78, 65, 72, 84, 65, 128, 69, 86,
+ 69, 78, 73, 78, 71, 128, 70, 65, 73, 76, 85, 82, 69, 128, 70, 65, 89, 65,
+ 78, 78, 65, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, 73, 83, 72, 69, 89,
+ 69, 128, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, 79, 84, 78, 79, 84,
+ 197, 70, 79, 85, 82, 84, 69, 69, 206, 70, 82, 79, 87, 78, 73, 78, 199,
+ 71, 65, 82, 77, 69, 78, 84, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 82,
+ 65, 80, 72, 69, 77, 197, 72, 65, 70, 85, 75, 72, 65, 128, 72, 65, 76, 65,
+ 78, 84, 65, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, 83, 65, 78, 84,
+ 65, 128, 72, 65, 89, 65, 78, 78, 65, 128, 72, 69, 65, 68, 73, 78, 71,
+ 128, 72, 69, 65, 86, 69, 78, 76, 217, 73, 45, 65, 82, 65, 69, 65, 128,
+ 73, 66, 73, 70, 73, 76, 73, 128, 73, 67, 72, 65, 68, 73, 78, 128, 73, 73,
+ 89, 65, 78, 78, 65, 128, 73, 78, 68, 73, 82, 69, 67, 212, 73, 78, 70, 73,
+ 78, 73, 84, 217, 73, 78, 84, 69, 82, 69, 83, 212, 73, 79, 68, 72, 65, 68,
+ 72, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 80, 65, 78, 69, 83,
+ 197, 74, 85, 80, 73, 84, 69, 82, 128, 75, 65, 75, 65, 66, 65, 84, 128,
+ 75, 65, 82, 65, 84, 84, 79, 128, 75, 65, 82, 79, 82, 73, 73, 128, 75, 73,
+ 78, 83, 72, 73, 80, 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 79, 77,
+ 85, 85, 84, 128, 75, 85, 82, 79, 79, 78, 69, 128, 76, 65, 78, 71, 85, 65,
+ 71, 197, 76, 79, 67, 65, 84, 73, 79, 206, 77, 65, 73, 75, 85, 82, 79,
+ 128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, 78, 83, 89, 79, 78, 128,
+ 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65,
+ 82, 82, 73, 65, 71, 197, 77, 65, 82, 82, 89, 73, 78, 199, 77, 65, 83, 83,
+ 73, 78, 71, 128, 77, 65, 89, 65, 78, 78, 65, 128, 77, 69, 71, 65, 84, 79,
+ 78, 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 84, 82, 69, 84, 69,
+ 211, 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, 76, 76, 73, 79, 78, 211,
+ 77, 79, 68, 69, 83, 84, 89, 128, 77, 79, 72, 65, 77, 77, 65, 196, 77, 79,
+ 82, 78, 73, 78, 71, 128, 77, 85, 76, 84, 73, 80, 76, 197, 78, 65, 84, 73,
+ 79, 78, 65, 204, 78, 69, 71, 65, 84, 73, 79, 206, 78, 69, 80, 84, 85, 78,
+ 69, 128, 78, 69, 87, 76, 73, 78, 69, 128, 78, 71, 69, 65, 68, 65, 76,
+ 128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 78, 69, 84, 69, 69, 206,
+ 79, 66, 79, 70, 73, 76, 73, 128, 79, 67, 84, 79, 66, 69, 82, 128, 79, 78,
+ 69, 45, 76, 73, 78, 197, 79, 78, 69, 83, 69, 76, 70, 128, 79, 79, 89, 65,
+ 78, 78, 65, 128, 79, 82, 84, 72, 79, 68, 79, 216, 79, 85, 84, 76, 73, 78,
+ 69, 128, 80, 65, 67, 75, 73, 78, 71, 128, 80, 65, 76, 76, 65, 87, 65,
+ 128, 80, 65, 84, 84, 69, 82, 78, 128, 80, 69, 76, 65, 83, 84, 79, 206,
+ 80, 69, 84, 65, 83, 77, 65, 128, 80, 69, 84, 65, 83, 84, 73, 128, 80, 72,
+ 73, 78, 84, 72, 85, 128, 80, 72, 85, 84, 72, 65, 79, 128, 80, 79, 68, 65,
+ 84, 85, 83, 128, 80, 82, 69, 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68,
+ 69, 196, 80, 82, 69, 86, 73, 79, 85, 211, 80, 82, 73, 86, 65, 84, 69,
+ 128, 80, 82, 79, 80, 69, 82, 84, 217, 82, 65, 75, 72, 65, 78, 71, 128,
+ 82, 65, 80, 73, 83, 77, 65, 128, 82, 65, 89, 65, 78, 78, 65, 128, 82, 69,
+ 65, 72, 77, 85, 75, 128, 82, 69, 76, 69, 65, 83, 69, 128, 82, 69, 84, 82,
+ 69, 65, 84, 128, 82, 73, 84, 84, 79, 82, 85, 128, 82, 85, 85, 66, 85, 82,
+ 85, 128, 83, 65, 73, 75, 85, 82, 85, 128, 83, 65, 76, 84, 73, 82, 69,
+ 128, 83, 65, 77, 80, 72, 65, 79, 128, 83, 65, 78, 89, 79, 79, 71, 193,
+ 83, 67, 72, 79, 76, 65, 82, 128, 83, 67, 82, 85, 80, 76, 69, 128, 83, 69,
+ 71, 77, 69, 78, 84, 128, 83, 73, 77, 73, 76, 65, 82, 128, 83, 73, 78, 75,
+ 73, 78, 71, 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 88, 45, 76, 73,
+ 78, 197, 83, 78, 79, 87, 77, 65, 78, 128, 83, 80, 73, 82, 65, 78, 84,
+ 128, 83, 80, 82, 73, 78, 71, 83, 128, 83, 81, 85, 65, 82, 69, 83, 128,
+ 83, 84, 65, 85, 82, 79, 83, 128, 83, 84, 65, 86, 82, 79, 83, 128, 83, 84,
+ 65, 86, 82, 79, 85, 128, 83, 84, 82, 65, 84, 73, 65, 206, 83, 84, 82, 73,
+ 67, 84, 76, 217, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 67, 67, 69, 69,
+ 68, 128, 83, 89, 78, 69, 86, 77, 65, 128, 84, 65, 73, 83, 89, 79, 85,
+ 128, 84, 65, 84, 87, 69, 69, 76, 128, 84, 67, 72, 69, 72, 69, 72, 128,
+ 84, 69, 83, 83, 65, 82, 79, 206, 84, 69, 83, 83, 69, 82, 65, 128, 84, 72,
+ 73, 82, 84, 69, 69, 206, 84, 72, 85, 82, 73, 83, 65, 218, 84, 73, 78, 65,
+ 71, 77, 65, 128, 84, 73, 82, 79, 78, 73, 65, 206, 84, 79, 82, 67, 85, 76,
+ 85, 211, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 89, 66, 76, 73, 79,
+ 206, 84, 86, 73, 77, 65, 68, 85, 210, 84, 87, 79, 45, 76, 73, 78, 197,
+ 85, 45, 69, 79, 45, 69, 85, 128, 85, 66, 85, 70, 73, 76, 73, 128, 85, 77,
+ 66, 82, 69, 76, 76, 193, 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 89, 65,
+ 78, 78, 65, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 76, 76, 65, 71,
+ 69, 128, 86, 79, 73, 67, 73, 78, 71, 128, 87, 65, 83, 65, 76, 76, 65,
+ 205, 87, 65, 83, 84, 73, 78, 71, 128, 89, 65, 89, 65, 78, 78, 65, 128,
+ 89, 79, 85, 84, 72, 70, 85, 204, 89, 80, 79, 82, 82, 79, 73, 128, 79, 83,
+ 77, 65, 78, 89, 193, 67, 73, 82, 67, 76, 69, 128, 66, 82, 65, 67, 75, 69,
+ 212, 85, 80, 83, 73, 76, 79, 206, 65, 67, 67, 69, 78, 84, 128, 68, 73,
+ 78, 71, 66, 65, 212, 69, 80, 83, 73, 76, 79, 206, 83, 76, 65, 78, 84, 69,
+ 196, 83, 81, 85, 65, 82, 69, 128, 72, 65, 78, 85, 78, 79, 207, 68, 65,
+ 71, 69, 83, 72, 128, 71, 76, 79, 84, 84, 65, 204, 84, 65, 71, 65, 76, 79,
+ 199, 79, 77, 73, 67, 82, 79, 206, 80, 65, 76, 65, 84, 65, 204, 78, 65,
+ 83, 75, 65, 80, 201, 67, 79, 82, 78, 69, 82, 128, 69, 76, 69, 77, 69, 78,
+ 212, 66, 85, 76, 76, 69, 84, 128, 68, 79, 84, 76, 69, 83, 211, 79, 71,
+ 79, 78, 69, 75, 128, 86, 73, 82, 65, 77, 65, 128, 75, 73, 82, 71, 72, 73,
+ 218, 82, 69, 86, 69, 82, 83, 197, 68, 73, 65, 77, 79, 78, 196, 84, 87,
+ 69, 78, 84, 89, 128, 68, 79, 85, 66, 76, 69, 128, 78, 69, 73, 84, 72, 69,
+ 210, 81, 85, 65, 82, 84, 69, 210, 83, 73, 77, 73, 76, 65, 210, 83, 73,
+ 78, 71, 76, 69, 128, 83, 79, 76, 73, 68, 85, 211, 83, 81, 85, 65, 82, 69,
+ 196, 67, 72, 73, 78, 69, 83, 197, 78, 85, 78, 65, 86, 73, 203, 83, 85,
+ 66, 83, 69, 84, 128, 84, 72, 45, 67, 82, 69, 197, 84, 82, 73, 71, 82, 65,
+ 205, 65, 82, 75, 84, 73, 75, 207, 69, 76, 69, 86, 69, 78, 128, 72, 85,
+ 78, 68, 82, 69, 196, 72, 89, 80, 72, 69, 78, 128, 73, 78, 83, 73, 68, 69,
+ 128, 77, 65, 82, 75, 69, 82, 128, 79, 80, 69, 78, 73, 78, 199, 84, 87,
+ 69, 76, 86, 69, 128, 69, 73, 71, 72, 84, 72, 211, 80, 65, 82, 84, 73, 65,
+ 204, 84, 72, 73, 82, 84, 89, 128, 86, 82, 65, 67, 72, 89, 128, 65, 82,
+ 82, 79, 87, 83, 128, 70, 65, 76, 76, 73, 78, 199, 79, 66, 76, 73, 81, 85,
+ 197, 80, 69, 82, 67, 69, 78, 212, 84, 72, 82, 79, 85, 71, 200, 67, 69,
+ 68, 73, 76, 76, 193, 67, 79, 78, 84, 82, 79, 204, 67, 85, 82, 86, 73, 78,
+ 199, 68, 73, 71, 82, 65, 80, 200, 69, 81, 85, 65, 76, 83, 128, 70, 73,
+ 76, 76, 69, 82, 128, 71, 65, 78, 71, 73, 65, 128, 73, 78, 86, 69, 82, 83,
+ 197, 73, 79, 84, 65, 84, 69, 196, 75, 69, 78, 84, 73, 77, 193, 77, 69,
+ 65, 83, 85, 82, 197, 82, 79, 85, 78, 68, 69, 196, 83, 65, 78, 89, 65, 75,
+ 193, 84, 67, 72, 69, 72, 69, 200, 84, 79, 80, 66, 65, 82, 128, 84, 85,
+ 82, 84, 76, 69, 128, 89, 73, 68, 68, 73, 83, 200, 45, 75, 72, 89, 73, 76,
+ 128, 66, 79, 84, 84, 79, 77, 128, 67, 69, 78, 84, 82, 69, 128, 67, 69,
+ 78, 84, 82, 69, 196, 67, 79, 78, 84, 65, 73, 206, 67, 79, 78, 84, 79, 85,
+ 210, 67, 82, 79, 83, 83, 69, 196, 68, 65, 78, 84, 65, 74, 193, 68, 73,
+ 86, 73, 68, 69, 196, 68, 79, 84, 84, 69, 68, 128, 68, 82, 65, 71, 79, 78,
+ 128, 70, 73, 70, 84, 72, 83, 128, 72, 69, 65, 86, 69, 78, 128, 75, 79,
+ 77, 66, 85, 86, 193, 75, 82, 65, 84, 73, 77, 193, 76, 69, 65, 68, 69, 82,
+ 128, 77, 65, 82, 66, 85, 84, 193, 77, 69, 77, 66, 69, 82, 128, 78, 65,
+ 84, 85, 82, 65, 204, 78, 73, 78, 69, 84, 89, 128, 80, 69, 78, 67, 73, 76,
+ 128, 81, 65, 77, 65, 84, 83, 128, 83, 75, 76, 73, 82, 79, 206, 83, 79,
+ 71, 68, 73, 65, 206, 83, 84, 73, 71, 77, 65, 128, 83, 89, 78, 65, 71, 77,
+ 193, 84, 65, 65, 76, 85, 74, 193, 84, 72, 69, 83, 69, 79, 211, 84, 79,
+ 78, 71, 85, 69, 128, 65, 67, 65, 68, 69, 77, 217, 65, 67, 67, 79, 85, 78,
+ 212, 65, 78, 67, 72, 79, 82, 128, 65, 78, 67, 79, 82, 65, 128, 65, 80,
+ 76, 79, 85, 78, 128, 65, 82, 67, 72, 65, 73, 195, 66, 65, 76, 85, 68, 65,
+ 128, 66, 65, 77, 66, 79, 79, 128, 66, 65, 83, 72, 75, 73, 210, 66, 73,
+ 78, 68, 73, 78, 199, 66, 73, 83, 72, 79, 80, 128, 66, 79, 87, 84, 73, 69,
+ 128, 67, 72, 73, 69, 85, 67, 200, 67, 72, 82, 73, 86, 73, 128, 67, 76,
+ 85, 83, 84, 69, 210, 68, 65, 71, 71, 69, 82, 128, 68, 65, 80, 45, 66, 69,
+ 201, 68, 65, 80, 45, 80, 73, 201, 68, 69, 67, 73, 77, 65, 204, 68, 73,
+ 86, 73, 68, 69, 128, 68, 74, 69, 82, 86, 73, 128, 68, 79, 85, 66, 76, 69,
+ 196, 68, 82, 65, 67, 72, 77, 193, 69, 65, 82, 84, 72, 76, 217, 69, 73,
+ 71, 72, 84, 89, 128, 69, 83, 67, 65, 80, 69, 128, 70, 69, 65, 84, 72, 69,
+ 210, 70, 76, 69, 88, 85, 83, 128, 71, 69, 82, 69, 83, 72, 128, 71, 72,
+ 85, 78, 78, 65, 128, 71, 82, 69, 65, 84, 69, 210, 72, 79, 76, 68, 73, 78,
+ 199, 73, 78, 72, 73, 66, 73, 212, 73, 83, 83, 72, 65, 82, 128, 73, 90,
+ 72, 73, 84, 83, 193, 75, 69, 69, 80, 73, 78, 199, 75, 72, 73, 69, 85, 75,
+ 200, 75, 76, 65, 83, 77, 65, 128, 75, 78, 73, 71, 72, 84, 128, 75, 79,
+ 82, 65, 78, 73, 195, 76, 69, 71, 69, 84, 79, 211, 77, 65, 76, 65, 75, 79,
+ 206, 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 75, 45, 50, 128, 77, 79,
+ 82, 84, 65, 82, 128, 78, 69, 71, 65, 84, 69, 196, 78, 79, 84, 67, 72, 69,
+ 196, 79, 82, 68, 73, 78, 65, 204, 80, 72, 73, 69, 85, 80, 200, 80, 72,
+ 82, 65, 83, 69, 128, 80, 73, 76, 67, 82, 79, 215, 80, 76, 65, 71, 73, 79,
+ 211, 80, 79, 75, 79, 74, 73, 128, 82, 69, 84, 85, 82, 78, 128, 82, 73,
+ 75, 82, 73, 75, 128, 83, 69, 82, 73, 70, 83, 128, 83, 72, 65, 80, 69, 83,
+ 128, 83, 73, 88, 84, 69, 69, 206, 83, 76, 79, 80, 73, 78, 199, 83, 77,
+ 65, 76, 76, 69, 210, 83, 77, 73, 76, 73, 78, 199, 83, 80, 69, 69, 67, 72,
+ 128, 83, 80, 73, 68, 69, 82, 217, 84, 65, 77, 73, 78, 71, 128, 84, 69,
+ 76, 69, 73, 65, 128, 84, 69, 76, 73, 83, 72, 193, 84, 69, 83, 83, 69, 82,
+ 193, 84, 72, 69, 84, 72, 69, 128, 84, 72, 73, 69, 85, 84, 200, 84, 72,
+ 82, 69, 65, 68, 128, 84, 72, 82, 69, 69, 45, 196, 84, 86, 82, 73, 68, 79,
+ 128, 85, 80, 84, 85, 82, 78, 128, 89, 69, 76, 76, 79, 87, 128, 89, 79,
+ 45, 89, 65, 69, 128, 89, 85, 45, 89, 69, 79, 128, 90, 69, 77, 76, 74, 65,
+ 128, 65, 66, 89, 83, 77, 65, 204, 65, 70, 71, 72, 65, 78, 201, 65, 70,
+ 82, 73, 67, 65, 206, 65, 72, 65, 71, 71, 65, 210, 65, 73, 72, 86, 85, 83,
+ 128, 65, 73, 86, 73, 76, 73, 203, 65, 76, 65, 89, 72, 69, 128, 65, 76,
+ 73, 71, 78, 69, 196, 65, 78, 78, 85, 73, 84, 217, 65, 80, 65, 65, 84, 79,
+ 128, 65, 82, 65, 69, 65, 69, 128, 65, 82, 77, 79, 85, 82, 128, 65, 82,
+ 82, 73, 86, 69, 128, 65, 82, 83, 69, 79, 83, 128, 65, 82, 85, 72, 85, 65,
+ 128, 65, 83, 67, 69, 78, 84, 128, 65, 85, 71, 85, 83, 84, 128, 65, 85,
+ 83, 84, 82, 65, 204, 65, 86, 69, 82, 65, 71, 197, 66, 65, 68, 71, 69, 82,
+ 128, 66, 65, 73, 77, 65, 73, 128, 66, 65, 78, 84, 79, 67, 128, 66, 65,
+ 82, 76, 69, 89, 128, 66, 65, 82, 82, 69, 69, 128, 66, 69, 78, 90, 69, 78,
+ 197, 66, 69, 84, 87, 69, 69, 206, 66, 69, 89, 89, 65, 76, 128, 66, 73,
+ 84, 84, 69, 82, 128, 66, 79, 82, 85, 84, 79, 128, 66, 82, 65, 78, 67, 72,
+ 128, 66, 82, 69, 86, 73, 83, 128, 66, 82, 79, 78, 90, 69, 128, 66, 85,
+ 67, 75, 76, 69, 128, 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, 67, 69, 82,
+ 128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 85, 84, 73, 79, 206, 67, 72,
+ 65, 77, 75, 79, 128, 67, 72, 65, 78, 71, 69, 128, 67, 72, 65, 82, 73, 79,
+ 212, 67, 72, 69, 86, 82, 79, 206, 67, 72, 73, 82, 69, 84, 128, 67, 72,
+ 85, 82, 67, 72, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 45, 50,
+ 128, 67, 76, 73, 86, 73, 83, 128, 67, 76, 79, 83, 69, 68, 128, 67, 79,
+ 70, 70, 73, 78, 128, 67, 79, 78, 73, 67, 65, 204, 67, 79, 82, 80, 83, 69,
+ 128, 67, 85, 82, 82, 69, 78, 212, 68, 65, 65, 68, 72, 85, 128, 68, 65,
+ 76, 65, 84, 72, 128, 68, 65, 77, 65, 82, 85, 128, 68, 65, 83, 69, 73, 65,
+ 128, 68, 68, 65, 72, 65, 76, 128, 68, 69, 76, 69, 84, 69, 128, 68, 69,
+ 76, 80, 72, 73, 195, 68, 72, 65, 65, 76, 85, 128, 68, 72, 65, 82, 77, 65,
+ 128, 68, 73, 69, 83, 73, 83, 128, 68, 73, 80, 80, 69, 82, 128, 68, 73,
+ 86, 79, 82, 67, 197, 68, 79, 84, 83, 45, 49, 128, 68, 79, 84, 83, 45, 50,
+ 128, 68, 79, 84, 83, 45, 51, 128, 68, 79, 84, 83, 45, 52, 128, 68, 79,
+ 84, 83, 45, 53, 128, 68, 79, 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 55,
+ 128, 68, 79, 84, 83, 45, 56, 128, 68, 85, 84, 73, 69, 83, 128, 69, 73,
+ 71, 72, 84, 72, 128, 69, 78, 65, 82, 88, 73, 211, 69, 88, 67, 69, 83, 83,
+ 128, 69, 88, 73, 83, 84, 83, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65,
+ 67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, 67, 69, 45, 52,
+ 128, 70, 65, 67, 69, 45, 53, 128, 70, 65, 67, 69, 45, 54, 128, 70, 65,
+ 77, 73, 76, 89, 128, 70, 65, 84, 72, 69, 82, 128, 70, 69, 77, 65, 76, 69,
+ 128, 70, 69, 82, 77, 65, 84, 193, 70, 73, 70, 84, 69, 69, 206, 70, 76,
+ 65, 71, 45, 49, 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 51,
+ 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, 45, 53, 128, 70, 76,
+ 73, 71, 72, 84, 128, 70, 76, 79, 87, 69, 82, 128, 70, 79, 82, 67, 69, 83,
+ 128, 70, 85, 78, 69, 82, 65, 204, 71, 69, 68, 79, 76, 65, 128, 71, 69,
+ 77, 73, 78, 73, 128, 71, 69, 78, 69, 82, 73, 195, 71, 72, 65, 73, 78, 85,
+ 128, 71, 72, 65, 77, 65, 76, 128, 71, 82, 79, 85, 78, 68, 128, 71, 85,
+ 65, 82, 65, 78, 201, 72, 65, 70, 85, 75, 72, 128, 72, 69, 73, 83, 69, 73,
+ 128, 72, 69, 76, 77, 69, 84, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69,
+ 82, 77, 69, 83, 128, 72, 69, 82, 85, 84, 85, 128, 72, 82, 89, 86, 78, 73,
+ 193, 72, 85, 73, 73, 84, 79, 128, 73, 45, 66, 69, 65, 77, 128, 73, 77,
+ 73, 83, 69, 79, 211, 73, 78, 71, 87, 65, 90, 128, 73, 78, 73, 78, 71, 85,
+ 128, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, 85, 76, 65, 210, 74, 79,
+ 73, 78, 69, 68, 128, 75, 65, 78, 65, 75, 79, 128, 75, 65, 78, 84, 65, 74,
+ 193, 75, 69, 70, 85, 76, 65, 128, 75, 69, 89, 67, 65, 80, 128, 75, 72,
+ 79, 77, 85, 84, 128, 75, 76, 73, 84, 79, 78, 128, 75, 79, 82, 85, 78, 65,
+ 128, 75, 89, 65, 84, 72, 79, 211, 75, 89, 85, 82, 73, 73, 128, 76, 65,
+ 77, 65, 68, 72, 128, 76, 65, 84, 69, 82, 65, 204, 76, 69, 71, 73, 79, 78,
+ 128, 76, 69, 73, 77, 77, 65, 128, 76, 69, 84, 84, 69, 82, 128, 76, 73,
+ 77, 73, 84, 69, 196, 76, 73, 78, 69, 45, 49, 128, 76, 73, 78, 69, 45, 51,
+ 128, 76, 73, 78, 69, 45, 55, 128, 76, 73, 78, 69, 45, 57, 128, 76, 73,
+ 78, 75, 73, 78, 199, 76, 79, 90, 69, 78, 71, 197, 77, 65, 73, 68, 69, 78,
+ 128, 77, 65, 76, 84, 69, 83, 197, 77, 65, 82, 75, 45, 51, 128, 77, 65,
+ 82, 75, 45, 52, 128, 77, 65, 82, 85, 75, 85, 128, 77, 65, 84, 82, 73, 88,
+ 128, 77, 65, 88, 73, 77, 65, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69,
+ 71, 65, 76, 73, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 84, 82, 73, 65,
+ 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 76, 76, 69, 84, 128, 77, 73,
+ 78, 73, 77, 65, 128, 77, 79, 68, 69, 76, 83, 128, 77, 79, 84, 72, 69, 82,
+ 128, 77, 85, 81, 68, 65, 77, 128, 78, 65, 85, 84, 72, 83, 128, 78, 69,
+ 78, 65, 78, 79, 128, 78, 73, 82, 85, 71, 85, 128, 78, 79, 75, 72, 85, 75,
+ 128, 78, 79, 77, 73, 78, 65, 204, 78, 85, 77, 66, 69, 82, 128, 78, 85,
+ 78, 65, 86, 85, 212, 79, 66, 69, 76, 79, 83, 128, 79, 77, 65, 76, 79, 78,
+ 128, 79, 80, 69, 78, 45, 80, 128, 79, 80, 80, 79, 83, 69, 128, 79, 82,
+ 73, 71, 73, 78, 128, 79, 84, 72, 65, 76, 65, 206, 80, 65, 76, 85, 84, 65,
+ 128, 80, 65, 83, 72, 84, 65, 128, 80, 69, 78, 73, 72, 73, 128, 80, 69,
+ 82, 83, 79, 78, 128, 80, 73, 75, 85, 82, 85, 128, 80, 73, 80, 73, 78, 71,
+ 128, 80, 73, 83, 67, 69, 83, 128, 80, 79, 73, 78, 84, 79, 128, 80, 82,
+ 69, 67, 69, 68, 197, 80, 82, 69, 70, 65, 67, 197, 80, 82, 79, 68, 85, 67,
+ 212, 80, 85, 82, 73, 84, 89, 128, 80, 85, 83, 72, 73, 78, 199, 81, 69,
+ 84, 65, 78, 65, 128, 81, 85, 66, 85, 84, 83, 128, 82, 69, 80, 69, 65, 84,
+ 128, 82, 73, 84, 85, 65, 76, 128, 82, 85, 78, 79, 85, 84, 128, 83, 65,
+ 65, 68, 72, 85, 128, 83, 65, 74, 68, 65, 72, 128, 83, 65, 77, 69, 75, 72,
+ 128, 83, 65, 78, 78, 89, 65, 128, 83, 65, 84, 85, 82, 78, 128, 83, 67,
+ 65, 76, 69, 83, 128, 83, 67, 82, 69, 69, 78, 128, 83, 67, 82, 73, 80, 84,
+ 128, 83, 69, 65, 71, 85, 76, 204, 83, 69, 67, 79, 78, 68, 128, 83, 69,
+ 67, 82, 69, 84, 128, 83, 69, 67, 84, 79, 82, 128, 83, 69, 73, 83, 77, 65,
+ 128, 83, 69, 82, 86, 73, 67, 197, 83, 69, 86, 69, 78, 84, 217, 83, 72,
+ 65, 68, 68, 65, 128, 83, 72, 65, 75, 84, 73, 128, 83, 72, 69, 69, 78, 85,
+ 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 85, 70, 70, 76, 197, 83, 73,
+ 67, 75, 76, 69, 128, 83, 73, 88, 84, 72, 83, 128, 83, 76, 79, 87, 76, 89,
+ 128, 83, 80, 65, 84, 72, 73, 128, 83, 80, 73, 82, 73, 84, 128, 83, 80,
+ 82, 79, 85, 84, 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 82, 65, 73, 70,
+ 128, 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 79, 75, 69, 211, 83, 85,
+ 66, 73, 84, 79, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 82, 70, 65, 67,
+ 197, 83, 87, 79, 82, 68, 83, 128, 83, 89, 78, 65, 70, 73, 128, 83, 89,
+ 79, 85, 87, 65, 128, 84, 65, 84, 87, 69, 69, 204, 84, 65, 85, 82, 85, 83,
+ 128, 84, 69, 78, 85, 84, 79, 128, 84, 72, 65, 65, 76, 85, 128, 84, 72,
+ 65, 72, 65, 78, 128, 84, 72, 65, 78, 78, 65, 128, 84, 72, 73, 82, 68, 83,
+ 128, 84, 72, 73, 85, 84, 72, 128, 84, 73, 80, 69, 72, 65, 128, 84, 79,
+ 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 51, 128, 84, 79, 78, 69, 45, 52,
+ 128, 84, 79, 78, 69, 45, 53, 128, 84, 79, 78, 69, 45, 54, 128, 84, 82,
+ 73, 80, 76, 73, 128, 84, 82, 73, 80, 79, 68, 128, 84, 83, 72, 85, 71, 83,
+ 128, 84, 84, 69, 72, 69, 72, 128, 84, 85, 82, 66, 65, 78, 128, 85, 80,
+ 82, 73, 71, 72, 212, 85, 80, 87, 65, 82, 68, 128, 85, 82, 65, 78, 85, 83,
+ 128, 86, 65, 76, 76, 69, 89, 128, 86, 65, 82, 69, 73, 65, 201, 86, 65,
+ 82, 73, 65, 78, 212, 86, 65, 82, 73, 75, 65, 128, 86, 73, 67, 84, 79, 82,
+ 217, 86, 73, 82, 73, 65, 77, 128, 86, 73, 83, 65, 82, 71, 193, 86, 79,
+ 76, 84, 65, 71, 197, 87, 65, 82, 78, 73, 78, 199, 87, 69, 65, 80, 79, 78,
+ 128, 87, 72, 69, 69, 76, 69, 196, 87, 82, 73, 84, 73, 78, 199, 89, 70,
+ 69, 83, 73, 83, 128, 89, 79, 45, 89, 69, 79, 128, 89, 80, 83, 73, 76, 73,
+ 128, 83, 89, 76, 79, 84, 201, 67, 65, 82, 79, 78, 128, 66, 82, 69, 86,
+ 69, 128, 66, 76, 65, 67, 75, 128, 77, 73, 68, 68, 76, 197, 65, 67, 67,
+ 69, 78, 212, 84, 82, 73, 80, 76, 197, 68, 79, 84, 84, 69, 196, 83, 84,
+ 82, 79, 75, 197, 86, 69, 83, 83, 69, 204, 69, 81, 85, 65, 76, 211, 71,
+ 79, 84, 72, 73, 195, 72, 69, 65, 86, 89, 128, 83, 73, 78, 71, 76, 197,
+ 66, 76, 79, 67, 75, 128, 77, 65, 78, 67, 72, 213, 84, 79, 78, 79, 83,
+ 128, 66, 79, 84, 84, 79, 205, 70, 84, 72, 79, 82, 193, 77, 69, 68, 73,
+ 85, 205, 79, 77, 69, 71, 65, 128, 83, 73, 71, 77, 65, 128, 65, 76, 80,
+ 72, 65, 128, 67, 76, 79, 83, 69, 196, 68, 65, 83, 73, 65, 128, 83, 85,
+ 66, 83, 69, 212, 67, 79, 77, 77, 65, 128, 68, 69, 76, 84, 65, 128, 86,
+ 85, 76, 71, 65, 210, 67, 79, 82, 78, 69, 210, 69, 81, 85, 65, 76, 128,
+ 76, 65, 77, 68, 65, 128, 67, 82, 79, 83, 83, 128, 73, 67, 72, 79, 83,
+ 128, 83, 65, 89, 73, 83, 201, 84, 72, 69, 84, 65, 128, 87, 72, 73, 84,
+ 69, 128, 65, 76, 77, 79, 83, 212, 75, 65, 80, 80, 65, 128, 77, 65, 67,
+ 82, 79, 206, 78, 85, 66, 73, 65, 206, 89, 45, 67, 82, 69, 197, 66, 69,
+ 83, 73, 68, 197, 67, 69, 78, 84, 82, 197, 83, 72, 65, 68, 68, 193, 84,
+ 87, 69, 78, 84, 217, 69, 65, 82, 84, 72, 128, 70, 73, 70, 84, 89, 128,
+ 76, 69, 78, 71, 84, 200, 78, 79, 82, 77, 65, 204, 84, 72, 73, 82, 84,
+ 217, 68, 65, 83, 72, 69, 196, 68, 73, 71, 82, 65, 205, 80, 82, 73, 77,
+ 69, 128, 85, 78, 73, 79, 78, 128, 67, 65, 78, 68, 82, 193, 82, 69, 80,
+ 69, 65, 212, 84, 69, 77, 80, 85, 211, 84, 85, 65, 82, 69, 199, 76, 85,
+ 78, 65, 84, 197, 82, 73, 83, 73, 78, 199, 82, 84, 65, 71, 83, 128, 68,
+ 73, 69, 83, 73, 211, 68, 73, 80, 76, 73, 128, 73, 78, 68, 69, 88, 128,
+ 75, 79, 80, 80, 65, 128, 78, 65, 66, 76, 65, 128, 78, 85, 75, 84, 65,
+ 128, 79, 84, 84, 65, 86, 193, 82, 65, 73, 83, 69, 196, 83, 67, 72, 87,
+ 65, 128, 83, 72, 73, 77, 65, 128, 83, 84, 65, 70, 70, 128, 89, 70, 69,
+ 83, 73, 211, 66, 65, 76, 76, 79, 212, 66, 65, 82, 82, 69, 197, 67, 76,
+ 73, 67, 75, 128, 67, 85, 66, 69, 68, 128, 67, 85, 82, 86, 69, 196, 70,
+ 69, 77, 65, 76, 197, 70, 69, 78, 67, 69, 128, 75, 79, 82, 69, 65, 206,
+ 76, 69, 73, 77, 77, 193, 76, 73, 84, 84, 76, 197, 78, 69, 83, 84, 69,
+ 196, 85, 73, 71, 72, 85, 210, 87, 65, 84, 69, 82, 128, 87, 69, 73, 71,
+ 72, 212, 65, 76, 65, 89, 72, 197, 66, 65, 83, 83, 65, 128, 66, 82, 73,
+ 68, 71, 197, 67, 72, 82, 79, 77, 193, 68, 65, 78, 68, 65, 128, 68, 69,
+ 71, 82, 69, 197, 68, 69, 86, 73, 67, 197, 68, 79, 76, 76, 65, 210, 80,
+ 65, 73, 82, 69, 196, 80, 65, 84, 65, 72, 128, 80, 73, 69, 67, 69, 128,
+ 80, 79, 69, 84, 82, 217, 83, 65, 77, 80, 73, 128, 83, 75, 69, 87, 69,
+ 196, 84, 73, 77, 69, 83, 128, 84, 84, 69, 72, 69, 200, 87, 73, 71, 71,
+ 76, 217, 90, 73, 71, 90, 65, 199, 65, 82, 79, 85, 78, 196, 65, 82, 83,
+ 69, 79, 211, 66, 82, 79, 75, 69, 206, 67, 65, 82, 69, 84, 128, 67, 76,
+ 73, 70, 70, 128, 67, 76, 79, 84, 72, 128, 68, 65, 71, 69, 83, 200, 68,
+ 65, 77, 77, 65, 128, 70, 76, 79, 82, 65, 204, 70, 79, 82, 84, 89, 128,
+ 72, 69, 65, 82, 84, 128, 76, 65, 77, 69, 68, 128, 77, 65, 80, 73, 81,
+ 128, 78, 45, 67, 82, 69, 197, 80, 79, 83, 84, 65, 204, 80, 84, 72, 65,
+ 72, 193, 83, 67, 72, 69, 77, 193, 83, 69, 71, 79, 76, 128, 83, 72, 65,
+ 68, 69, 128, 83, 77, 65, 76, 76, 128, 83, 84, 82, 69, 83, 211, 84, 72,
+ 79, 82, 78, 128, 84, 73, 84, 76, 79, 128, 84, 79, 79, 84, 72, 128, 86,
+ 65, 82, 69, 73, 193, 87, 72, 69, 65, 84, 128, 90, 81, 65, 80, 72, 193,
+ 65, 76, 65, 80, 72, 128, 66, 69, 65, 77, 69, 196, 66, 69, 82, 66, 69,
+ 210, 66, 73, 78, 65, 82, 217, 66, 73, 78, 68, 73, 128, 66, 79, 87, 84,
+ 73, 197, 67, 72, 69, 67, 75, 128, 67, 85, 82, 86, 69, 128, 68, 65, 76,
+ 68, 65, 128, 68, 65, 76, 69, 84, 128, 68, 68, 65, 72, 65, 204, 68, 69,
+ 65, 84, 72, 128, 68, 79, 66, 82, 79, 128, 68, 90, 69, 76, 79, 128, 69,
+ 84, 69, 82, 79, 206, 70, 65, 67, 84, 79, 210, 70, 73, 71, 85, 82, 197,
+ 70, 76, 79, 79, 82, 128, 70, 79, 82, 75, 69, 196, 70, 82, 73, 84, 85,
+ 128, 71, 65, 80, 80, 69, 196, 71, 69, 78, 73, 75, 201, 71, 72, 65, 73,
+ 78, 128, 71, 72, 79, 83, 84, 128, 71, 72, 85, 78, 78, 193, 71, 78, 89,
+ 73, 83, 128, 71, 79, 82, 71, 73, 128, 72, 65, 77, 77, 69, 210, 72, 65,
+ 77, 90, 65, 128, 72, 73, 82, 73, 81, 128, 72, 79, 76, 65, 77, 128, 72,
+ 79, 82, 83, 69, 128, 72, 87, 65, 73, 82, 128, 73, 65, 85, 68, 65, 128,
+ 75, 65, 90, 65, 75, 200, 75, 73, 89, 69, 79, 203, 75, 76, 65, 83, 77,
+ 193, 76, 65, 66, 79, 82, 128, 76, 65, 82, 71, 69, 210, 76, 65, 85, 76,
+ 65, 128, 76, 69, 83, 83, 69, 210, 77, 69, 84, 65, 76, 128, 77, 79, 85,
+ 84, 72, 128, 78, 65, 83, 72, 73, 128, 78, 79, 84, 69, 83, 128, 79, 71,
+ 79, 78, 69, 203, 79, 76, 73, 71, 79, 206, 79, 82, 78, 65, 84, 197, 80,
+ 73, 65, 83, 77, 193, 80, 76, 65, 78, 67, 203, 80, 79, 73, 78, 84, 128,
+ 80, 79, 87, 69, 82, 128, 80, 82, 79, 84, 79, 211, 81, 65, 84, 65, 78,
+ 128, 81, 85, 69, 69, 78, 128, 81, 85, 73, 76, 76, 128, 82, 69, 65, 67,
+ 72, 128, 82, 71, 89, 65, 78, 128, 82, 73, 84, 83, 73, 128, 83, 67, 82,
+ 69, 69, 206, 83, 69, 71, 78, 79, 128, 83, 69, 82, 73, 70, 211, 83, 69,
+ 83, 65, 77, 197, 83, 72, 65, 78, 71, 128, 83, 72, 65, 82, 80, 128, 83,
+ 72, 67, 72, 65, 128, 83, 72, 69, 69, 80, 128, 83, 72, 69, 76, 70, 128,
+ 83, 72, 69, 76, 76, 128, 83, 72, 79, 82, 84, 211, 83, 72, 87, 65, 65,
+ 128, 83, 72, 87, 73, 73, 128, 83, 72, 87, 79, 79, 128, 83, 73, 71, 78,
+ 83, 128, 83, 73, 78, 68, 72, 201, 83, 73, 88, 84, 89, 128, 83, 76, 79,
+ 86, 79, 128, 83, 80, 69, 65, 82, 128, 83, 80, 73, 82, 73, 212, 83, 84,
+ 79, 67, 75, 128, 83, 84, 85, 68, 89, 128, 83, 85, 75, 85, 78, 128, 84,
+ 65, 78, 78, 69, 196, 84, 69, 76, 79, 85, 211, 84, 72, 87, 65, 65, 128,
+ 84, 73, 71, 69, 82, 128, 84, 73, 75, 69, 85, 212, 84, 82, 85, 78, 75,
+ 128, 84, 83, 65, 68, 73, 128, 84, 83, 72, 69, 71, 128, 84, 83, 72, 69,
+ 83, 128, 84, 87, 69, 76, 86, 197, 87, 65, 84, 67, 72, 128, 87, 79, 77,
+ 65, 78, 128, 89, 69, 83, 84, 85, 128, 89, 79, 45, 89, 65, 128, 89, 85,
+ 45, 89, 69, 128, 90, 90, 73, 69, 84, 128, 45, 67, 72, 65, 76, 128, 45,
+ 75, 72, 89, 85, 196, 45, 80, 72, 82, 85, 128, 65, 68, 68, 65, 75, 128,
+ 65, 71, 65, 73, 78, 128, 65, 72, 83, 68, 65, 128, 65, 76, 73, 70, 85,
+ 128, 65, 77, 79, 85, 78, 212, 65, 78, 80, 69, 65, 128, 65, 80, 65, 82,
+ 84, 128, 65, 80, 82, 73, 76, 128, 65, 82, 69, 80, 65, 128, 65, 82, 73,
+ 69, 83, 128, 65, 82, 76, 65, 85, 199, 65, 82, 79, 85, 82, 193, 65, 82,
+ 82, 65, 89, 128, 65, 82, 84, 65, 66, 197, 66, 66, 73, 69, 80, 128, 66,
+ 66, 73, 69, 84, 128, 66, 66, 73, 69, 88, 128, 66, 66, 85, 79, 80, 128,
+ 66, 66, 85, 79, 88, 128, 66, 66, 85, 82, 88, 128, 66, 69, 69, 84, 65,
+ 128, 66, 69, 70, 79, 82, 197, 66, 69, 72, 69, 72, 128, 66, 69, 73, 84,
+ 72, 128, 66, 72, 69, 84, 72, 128, 66, 73, 82, 71, 65, 128, 66, 73, 84,
+ 73, 78, 199, 66, 76, 65, 78, 75, 128, 66, 76, 79, 79, 68, 128, 66, 82,
+ 65, 67, 69, 128, 66, 82, 65, 78, 67, 200, 66, 82, 69, 65, 84, 200, 66,
+ 82, 85, 83, 72, 128, 66, 83, 84, 65, 82, 128, 66, 85, 76, 76, 69, 212,
+ 67, 65, 77, 78, 85, 195, 67, 65, 78, 67, 69, 204, 67, 65, 85, 68, 65,
+ 128, 67, 67, 72, 65, 65, 128, 67, 67, 72, 69, 69, 128, 67, 69, 65, 76,
+ 67, 128, 67, 69, 73, 82, 84, 128, 67, 72, 65, 68, 65, 128, 67, 72, 65,
+ 73, 82, 128, 67, 72, 65, 78, 71, 128, 67, 72, 73, 76, 68, 128, 67, 72,
+ 73, 78, 71, 128, 67, 72, 79, 75, 69, 128, 67, 72, 85, 76, 65, 128, 67,
+ 72, 85, 79, 80, 128, 67, 72, 85, 79, 84, 128, 67, 72, 85, 79, 88, 128,
+ 67, 72, 85, 82, 88, 128, 67, 72, 89, 82, 88, 128, 67, 76, 79, 85, 68,
+ 128, 67, 79, 69, 78, 71, 128, 67, 79, 76, 79, 82, 128, 67, 79, 77, 69,
+ 84, 128, 67, 79, 77, 73, 78, 199, 67, 79, 77, 77, 79, 206, 67, 79, 86,
+ 69, 82, 128, 67, 82, 69, 68, 73, 212, 67, 82, 79, 73, 88, 128, 68, 65,
+ 65, 83, 85, 128, 68, 65, 76, 65, 84, 200, 68, 65, 82, 71, 65, 128, 68,
+ 65, 86, 73, 68, 128, 68, 68, 68, 72, 65, 128, 68, 68, 73, 69, 80, 128,
+ 68, 68, 73, 69, 88, 128, 68, 68, 85, 79, 80, 128, 68, 68, 85, 79, 88,
+ 128, 68, 68, 85, 82, 88, 128, 68, 69, 76, 69, 84, 197, 68, 69, 82, 69,
+ 84, 128, 68, 73, 70, 65, 84, 128, 68, 73, 80, 84, 69, 128, 68, 73, 86,
+ 73, 68, 197, 68, 79, 77, 65, 73, 206, 68, 79, 85, 66, 84, 128, 68, 82,
+ 73, 86, 69, 128, 68, 82, 79, 80, 83, 128, 69, 69, 75, 65, 65, 128, 69,
+ 73, 71, 72, 84, 217, 69, 76, 69, 86, 69, 206, 69, 76, 73, 70, 73, 128,
+ 69, 78, 84, 69, 82, 128, 69, 79, 76, 72, 88, 128, 69, 81, 85, 73, 68,
+ 128, 69, 85, 45, 69, 85, 128, 69, 88, 73, 83, 84, 128, 70, 65, 65, 70,
+ 85, 128, 70, 65, 73, 72, 85, 128, 70, 65, 84, 72, 65, 128, 70, 69, 65,
+ 82, 78, 128, 70, 72, 84, 79, 82, 193, 70, 73, 69, 76, 68, 128, 70, 73,
+ 70, 84, 72, 128, 70, 73, 71, 72, 84, 128, 70, 73, 76, 76, 69, 196, 70,
+ 73, 78, 73, 84, 197, 70, 76, 79, 87, 69, 210, 70, 76, 85, 84, 69, 128,
+ 70, 79, 76, 76, 89, 128, 70, 79, 82, 67, 69, 128, 70, 79, 82, 84, 69,
+ 128, 70, 82, 65, 77, 69, 128, 70, 82, 69, 78, 67, 200, 70, 82, 79, 87,
+ 78, 128, 71, 65, 65, 70, 85, 128, 71, 65, 68, 79, 76, 128, 71, 65, 77,
+ 65, 76, 128, 71, 65, 77, 76, 65, 128, 71, 65, 78, 77, 65, 128, 71, 65,
+ 82, 79, 78, 128, 71, 69, 78, 84, 76, 197, 71, 69, 82, 69, 83, 200, 71,
+ 69, 82, 77, 65, 206, 71, 71, 73, 69, 80, 128, 71, 71, 73, 69, 88, 128,
+ 71, 71, 85, 79, 80, 128, 71, 71, 85, 79, 84, 128, 71, 71, 85, 79, 88,
+ 128, 71, 71, 85, 82, 88, 128, 71, 71, 87, 65, 65, 128, 71, 71, 87, 69,
+ 69, 128, 71, 73, 77, 69, 76, 128, 71, 73, 78, 73, 73, 128, 71, 76, 69,
+ 73, 67, 200, 71, 82, 65, 67, 69, 128, 71, 82, 65, 73, 78, 128, 71, 82,
+ 65, 83, 83, 128, 72, 45, 84, 89, 80, 197, 72, 65, 45, 72, 65, 128, 72,
+ 65, 71, 76, 65, 218, 72, 65, 73, 84, 85, 128, 72, 65, 78, 68, 83, 128,
+ 72, 69, 65, 86, 69, 206, 72, 73, 68, 73, 78, 199, 72, 76, 73, 69, 80,
+ 128, 72, 76, 73, 69, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, 79,
+ 88, 128, 72, 76, 85, 82, 88, 128, 72, 76, 89, 82, 88, 128, 72, 77, 73,
+ 69, 80, 128, 72, 77, 73, 69, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77,
+ 85, 79, 88, 128, 72, 77, 85, 82, 88, 128, 72, 77, 89, 82, 88, 128, 72,
+ 78, 73, 69, 80, 128, 72, 78, 73, 69, 84, 128, 72, 78, 73, 69, 88, 128,
+ 72, 78, 85, 79, 88, 128, 72, 79, 79, 82, 85, 128, 72, 79, 85, 83, 69,
+ 128, 72, 85, 77, 65, 78, 128, 72, 85, 82, 65, 78, 128, 72, 88, 73, 69,
+ 80, 128, 72, 88, 73, 69, 84, 128, 72, 88, 73, 69, 88, 128, 72, 88, 85,
+ 79, 80, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 88, 128, 72, 89,
+ 80, 72, 69, 206, 73, 67, 72, 79, 85, 128, 73, 71, 71, 87, 83, 128, 73,
+ 78, 78, 69, 82, 128, 73, 83, 65, 75, 73, 193, 74, 74, 73, 69, 80, 128,
+ 74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 88, 128, 74, 74, 85, 79, 80,
+ 128, 74, 74, 85, 79, 88, 128, 74, 74, 85, 82, 88, 128, 74, 79, 89, 79,
+ 85, 211, 74, 85, 68, 71, 69, 128, 74, 85, 69, 85, 73, 128, 75, 65, 65,
+ 70, 85, 128, 75, 65, 73, 82, 73, 128, 75, 65, 83, 82, 65, 128, 75, 65,
+ 84, 65, 86, 193, 75, 65, 85, 78, 65, 128, 75, 69, 69, 83, 85, 128, 75,
+ 69, 72, 69, 72, 128, 75, 69, 76, 86, 73, 206, 75, 69, 78, 65, 84, 128,
+ 75, 72, 65, 78, 68, 193, 75, 72, 65, 80, 72, 128, 75, 72, 85, 65, 84,
+ 128, 75, 72, 87, 65, 73, 128, 75, 78, 73, 70, 69, 128, 75, 79, 79, 80,
+ 79, 128, 75, 85, 83, 77, 65, 128, 75, 88, 87, 65, 65, 128, 75, 88, 87,
+ 69, 69, 128, 76, 45, 84, 89, 80, 197, 76, 65, 65, 77, 85, 128, 76, 65,
+ 71, 85, 83, 128, 76, 65, 77, 66, 68, 193, 76, 65, 85, 75, 65, 218, 76,
+ 69, 77, 79, 73, 128, 76, 73, 66, 82, 65, 128, 76, 73, 77, 73, 84, 128,
+ 76, 73, 78, 69, 83, 128, 76, 73, 81, 85, 73, 196, 76, 79, 78, 71, 65,
+ 128, 76, 79, 84, 85, 83, 128, 76, 79, 85, 82, 69, 128, 77, 65, 68, 68,
+ 65, 128, 77, 65, 68, 68, 65, 200, 77, 65, 72, 72, 65, 128, 77, 65, 73,
+ 82, 85, 128, 77, 65, 78, 78, 65, 128, 77, 65, 78, 78, 65, 218, 77, 65,
+ 81, 65, 70, 128, 77, 65, 82, 67, 72, 128, 77, 65, 83, 79, 82, 193, 77,
+ 69, 69, 77, 85, 128, 77, 69, 73, 90, 73, 128, 77, 69, 76, 79, 78, 128,
+ 77, 69, 77, 66, 69, 210, 77, 69, 82, 75, 72, 193, 77, 69, 84, 69, 71,
+ 128, 77, 69, 90, 90, 79, 128, 77, 71, 73, 69, 88, 128, 77, 71, 85, 79,
+ 80, 128, 77, 71, 85, 79, 88, 128, 77, 71, 85, 82, 88, 128, 77, 73, 75,
+ 82, 73, 128, 77, 73, 75, 82, 79, 206, 77, 73, 82, 69, 68, 128, 77, 73,
+ 83, 82, 65, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 85, 76, 207, 77,
+ 79, 78, 84, 72, 128, 77, 79, 85, 78, 68, 128, 77, 85, 78, 65, 72, 128,
+ 77, 85, 83, 73, 67, 128, 78, 65, 82, 82, 79, 215, 78, 65, 85, 68, 73,
+ 218, 78, 65, 88, 73, 65, 206, 78, 66, 73, 69, 80, 128, 78, 66, 73, 69,
+ 88, 128, 78, 66, 85, 82, 88, 128, 78, 66, 89, 82, 88, 128, 78, 68, 73,
+ 69, 88, 128, 78, 68, 85, 82, 88, 128, 78, 71, 65, 65, 73, 128, 78, 71,
+ 73, 69, 80, 128, 78, 71, 73, 69, 88, 128, 78, 71, 79, 69, 72, 128, 78,
+ 71, 85, 79, 84, 128, 78, 71, 85, 79, 88, 128, 78, 73, 78, 69, 84, 217,
+ 78, 74, 73, 69, 80, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 88,
+ 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 82, 88, 128, 78, 74, 89, 82,
+ 88, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 73, 73, 128, 78, 78, 71,
+ 79, 79, 128, 78, 79, 79, 78, 85, 128, 78, 79, 84, 67, 72, 128, 78, 79,
+ 84, 84, 79, 128, 78, 82, 85, 82, 88, 128, 78, 82, 89, 82, 88, 128, 78,
+ 85, 77, 69, 82, 207, 78, 89, 73, 69, 80, 128, 78, 89, 73, 69, 84, 128,
+ 78, 89, 73, 69, 88, 128, 78, 89, 85, 79, 80, 128, 78, 89, 85, 79, 88,
+ 128, 78, 90, 73, 69, 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 85, 79,
+ 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, 89, 82, 88, 128, 79, 66, 74,
+ 69, 67, 212, 79, 74, 69, 79, 78, 128, 79, 76, 73, 86, 69, 128, 79, 78,
+ 75, 65, 82, 128, 79, 80, 84, 73, 79, 206, 79, 84, 72, 65, 76, 128, 79,
+ 85, 78, 75, 73, 193, 79, 88, 69, 73, 65, 201, 80, 65, 65, 84, 85, 128,
+ 80, 65, 83, 69, 81, 128, 80, 65, 83, 85, 81, 128, 80, 65, 84, 65, 75,
+ 128, 80, 65, 90, 69, 82, 128, 80, 69, 65, 67, 69, 128, 80, 69, 69, 90,
+ 73, 128, 80, 69, 72, 69, 72, 128, 80, 69, 73, 84, 72, 128, 80, 69, 78,
+ 83, 85, 128, 80, 69, 79, 82, 84, 200, 80, 69, 82, 84, 72, 207, 80, 69,
+ 83, 69, 84, 193, 80, 72, 78, 65, 69, 203, 80, 72, 85, 78, 71, 128, 80,
+ 73, 65, 78, 79, 128, 80, 76, 85, 84, 79, 128, 80, 79, 69, 84, 73, 195,
+ 80, 79, 78, 68, 79, 128, 80, 82, 73, 78, 84, 128, 80, 82, 79, 79, 70,
+ 128, 80, 82, 79, 86, 69, 128, 81, 65, 65, 70, 85, 128, 81, 65, 68, 77,
+ 65, 128, 81, 65, 77, 65, 84, 211, 81, 65, 82, 78, 69, 217, 81, 72, 87,
+ 65, 65, 128, 81, 72, 87, 69, 69, 128, 82, 45, 67, 82, 69, 197, 82, 65,
+ 73, 68, 65, 128, 82, 65, 83, 72, 65, 128, 82, 65, 83, 79, 85, 204, 82,
+ 65, 84, 73, 79, 128, 82, 69, 67, 79, 82, 196, 82, 69, 84, 85, 82, 206,
+ 82, 69, 86, 73, 65, 128, 82, 69, 86, 77, 65, 128, 82, 72, 79, 84, 73,
+ 195, 82, 73, 86, 69, 82, 128, 82, 78, 79, 79, 78, 128, 82, 79, 66, 65,
+ 84, 128, 82, 82, 85, 79, 88, 128, 82, 82, 85, 82, 88, 128, 82, 82, 89,
+ 82, 88, 128, 82, 85, 80, 73, 73, 128, 82, 87, 65, 72, 65, 128, 83, 65,
+ 68, 72, 69, 128, 83, 65, 70, 72, 65, 128, 83, 65, 77, 69, 75, 200, 83,
+ 65, 77, 75, 65, 128, 83, 65, 77, 89, 79, 203, 83, 65, 78, 65, 72, 128,
+ 83, 65, 85, 73, 76, 128, 83, 69, 69, 78, 85, 128, 83, 69, 73, 83, 77,
+ 193, 83, 69, 78, 84, 73, 128, 83, 72, 69, 69, 78, 128, 83, 72, 69, 81,
+ 69, 204, 83, 72, 69, 86, 65, 128, 83, 72, 73, 73, 78, 128, 83, 72, 79,
+ 79, 84, 128, 83, 72, 79, 82, 84, 128, 83, 72, 85, 79, 80, 128, 83, 72,
+ 85, 79, 88, 128, 83, 72, 85, 82, 88, 128, 83, 72, 89, 82, 88, 128, 83,
+ 73, 88, 84, 72, 128, 83, 76, 65, 86, 69, 128, 83, 76, 73, 67, 69, 128,
+ 83, 76, 79, 80, 69, 128, 83, 77, 69, 65, 82, 128, 83, 77, 73, 76, 69,
+ 128, 83, 78, 65, 75, 69, 128, 83, 78, 79, 85, 84, 128, 83, 79, 85, 78,
+ 68, 128, 83, 79, 87, 73, 76, 207, 83, 80, 73, 67, 69, 128, 83, 80, 79,
+ 79, 78, 128, 83, 80, 85, 78, 71, 211, 83, 81, 85, 73, 83, 200, 83, 83,
+ 73, 69, 80, 128, 83, 83, 73, 69, 88, 128, 83, 83, 89, 82, 88, 128, 83,
+ 84, 65, 78, 68, 128, 83, 84, 65, 82, 75, 128, 83, 84, 69, 65, 77, 128,
+ 83, 84, 79, 78, 69, 128, 83, 84, 79, 86, 69, 128, 83, 87, 69, 69, 84,
+ 128, 83, 87, 79, 82, 68, 128, 83, 89, 82, 77, 65, 128, 84, 65, 76, 69,
+ 78, 212, 84, 65, 80, 69, 82, 128, 84, 67, 72, 69, 72, 128, 84, 69, 73,
+ 87, 83, 128, 84, 69, 86, 73, 82, 128, 84, 72, 73, 71, 72, 128, 84, 72,
+ 73, 82, 68, 128, 84, 72, 73, 82, 68, 211, 84, 72, 73, 84, 65, 128, 84,
+ 72, 79, 78, 71, 128, 84, 72, 85, 78, 71, 128, 84, 73, 78, 78, 69, 128,
+ 84, 73, 80, 80, 73, 128, 84, 76, 72, 69, 69, 128, 84, 82, 65, 67, 75,
+ 128, 84, 82, 73, 84, 79, 211, 84, 82, 85, 84, 72, 128, 84, 83, 69, 82,
+ 69, 128, 84, 84, 83, 69, 69, 128, 84, 84, 84, 72, 65, 128, 84, 85, 71,
+ 82, 73, 203, 84, 85, 82, 79, 50, 128, 84, 89, 80, 69, 45, 177, 84, 89,
+ 80, 69, 45, 178, 84, 89, 80, 69, 45, 179, 84, 89, 80, 69, 45, 180, 84,
+ 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, 182, 84, 89, 80, 69, 45, 183,
+ 85, 78, 73, 84, 89, 128, 85, 80, 87, 65, 82, 196, 86, 65, 65, 86, 85,
+ 128, 86, 65, 83, 73, 83, 128, 86, 65, 84, 72, 89, 128, 86, 69, 67, 84,
+ 79, 210, 86, 69, 82, 71, 69, 128, 86, 73, 82, 71, 65, 128, 86, 73, 82,
+ 71, 79, 128, 86, 79, 76, 85, 77, 197, 87, 65, 65, 86, 85, 128, 87, 65,
+ 83, 76, 65, 128, 87, 72, 69, 69, 76, 128, 87, 73, 78, 74, 65, 128, 87,
+ 82, 69, 65, 84, 200, 87, 82, 79, 78, 71, 128, 88, 69, 83, 84, 69, 211,
+ 89, 65, 45, 89, 79, 128, 89, 65, 65, 68, 79, 128, 89, 65, 65, 82, 85,
+ 128, 89, 65, 68, 68, 72, 128, 89, 65, 71, 72, 72, 128, 89, 65, 75, 72,
+ 72, 128, 89, 69, 79, 45, 79, 128, 89, 69, 79, 45, 85, 128, 89, 69, 84,
+ 73, 86, 128, 89, 73, 90, 69, 84, 128, 89, 85, 45, 69, 79, 128, 90, 65,
+ 82, 81, 65, 128, 90, 65, 89, 73, 78, 128, 90, 72, 65, 73, 78, 128, 90,
+ 72, 85, 79, 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, 82, 88, 128,
+ 90, 72, 89, 82, 88, 128, 90, 73, 76, 68, 69, 128, 90, 73, 78, 79, 82,
+ 128, 90, 89, 71, 79, 83, 128, 90, 90, 73, 69, 80, 128, 90, 90, 73, 69,
+ 88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 89, 82, 88, 128, 78, 65, 71,
+ 82, 201, 83, 72, 79, 82, 212, 83, 72, 69, 69, 206, 90, 69, 82, 79, 128,
+ 82, 79, 77, 65, 206, 84, 73, 76, 68, 197, 76, 69, 70, 84, 128, 79, 71,
+ 72, 65, 205, 86, 79, 67, 65, 204, 78, 79, 82, 84, 200, 67, 85, 82, 76,
+ 217, 65, 84, 84, 73, 195, 83, 79, 85, 84, 200, 66, 69, 76, 79, 215, 66,
+ 85, 72, 73, 196, 80, 79, 73, 78, 212, 84, 65, 67, 75, 128, 68, 65, 83,
+ 72, 128, 68, 79, 87, 78, 128, 73, 79, 84, 65, 128, 78, 45, 65, 82, 217,
+ 82, 69, 83, 84, 128, 71, 72, 65, 73, 206, 65, 67, 85, 84, 197, 66, 69,
+ 84, 65, 128, 66, 82, 69, 86, 197, 67, 79, 77, 77, 193, 71, 82, 65, 86,
+ 197, 75, 79, 69, 84, 128, 86, 65, 82, 73, 193, 90, 69, 84, 65, 128, 67,
+ 72, 69, 83, 211, 67, 85, 82, 76, 128, 83, 72, 69, 76, 204, 84, 72, 69,
+ 84, 193, 83, 79, 85, 78, 196, 85, 78, 73, 79, 206, 65, 76, 69, 70, 128,
+ 65, 84, 84, 65, 203, 68, 79, 84, 83, 128, 70, 79, 82, 84, 217, 72, 65,
+ 76, 70, 128, 78, 79, 84, 69, 128, 84, 79, 78, 65, 204, 73, 77, 65, 71,
+ 197, 80, 76, 85, 83, 128, 65, 71, 79, 71, 201, 69, 77, 80, 84, 217, 72,
+ 69, 65, 82, 212, 83, 85, 73, 84, 128, 70, 73, 70, 84, 217, 70, 73, 76,
+ 76, 128, 75, 65, 84, 79, 128, 75, 69, 72, 69, 200, 76, 65, 82, 71, 197,
+ 83, 72, 65, 68, 128, 66, 69, 71, 73, 206, 67, 65, 82, 69, 212, 70, 65,
+ 82, 83, 201, 70, 73, 82, 69, 128, 72, 79, 82, 73, 128, 75, 65, 80, 80,
+ 193, 77, 79, 79, 78, 128, 83, 69, 86, 69, 206, 83, 72, 69, 73, 128, 83,
+ 72, 73, 78, 128, 83, 85, 78, 71, 128, 84, 73, 67, 75, 128, 67, 76, 69,
+ 70, 128, 67, 82, 79, 83, 211, 70, 65, 84, 72, 193, 70, 73, 82, 83, 212,
+ 77, 65, 68, 68, 193, 81, 85, 65, 68, 128, 82, 85, 80, 69, 197, 83, 73,
+ 71, 77, 193, 83, 84, 69, 77, 128, 84, 67, 72, 69, 200, 84, 73, 77, 69,
+ 211, 84, 83, 72, 69, 199, 89, 65, 78, 71, 128, 65, 76, 84, 65, 128, 66,
+ 69, 72, 69, 200, 67, 72, 69, 67, 203, 67, 82, 79, 80, 128, 68, 65, 77,
+ 77, 193, 70, 73, 84, 65, 128, 71, 82, 69, 65, 212, 72, 65, 78, 68, 128,
+ 73, 90, 72, 69, 128, 74, 79, 73, 78, 128, 75, 65, 80, 65, 128, 75, 65,
+ 83, 82, 193, 75, 72, 69, 73, 128, 75, 87, 65, 65, 128, 76, 79, 78, 71,
+ 128, 78, 71, 79, 69, 200, 79, 66, 79, 76, 211, 80, 69, 72, 69, 200, 82,
+ 65, 70, 69, 128, 82, 78, 79, 79, 206, 82, 84, 65, 71, 211, 83, 67, 72,
+ 87, 193, 83, 72, 65, 82, 208, 84, 72, 65, 65, 128, 84, 72, 69, 69, 128,
+ 86, 65, 78, 69, 128, 87, 65, 86, 69, 128, 87, 73, 78, 68, 128, 65, 76,
+ 76, 79, 128, 66, 73, 82, 68, 128, 67, 65, 82, 79, 206, 67, 72, 65, 82,
+ 128, 67, 72, 73, 78, 128, 67, 72, 82, 79, 193, 67, 73, 69, 85, 195, 67,
+ 87, 65, 65, 128, 68, 69, 76, 84, 193, 70, 79, 79, 84, 128, 71, 72, 65,
+ 78, 128, 71, 79, 76, 68, 128, 71, 82, 65, 83, 211, 72, 65, 84, 65, 198,
+ 73, 69, 85, 78, 199, 74, 72, 65, 78, 128, 75, 69, 84, 84, 201, 75, 72,
+ 65, 82, 128, 76, 76, 76, 65, 128, 76, 79, 79, 80, 128, 77, 78, 65, 83,
+ 128, 77, 85, 83, 73, 195, 77, 87, 65, 65, 128, 78, 87, 65, 65, 128, 79,
+ 85, 84, 69, 210, 79, 88, 69, 73, 193, 80, 65, 80, 69, 210, 80, 69, 68,
+ 65, 204, 80, 72, 65, 82, 128, 80, 79, 76, 69, 128, 80, 82, 73, 77, 197,
+ 80, 87, 65, 65, 128, 82, 79, 79, 84, 128, 83, 69, 69, 78, 128, 83, 72,
+ 87, 65, 128, 83, 73, 76, 75, 128, 83, 73, 77, 65, 128, 83, 84, 65, 82,
+ 212, 83, 87, 65, 65, 128, 83, 87, 65, 83, 200, 84, 72, 73, 73, 128, 84,
+ 72, 73, 82, 196, 84, 83, 72, 65, 128, 84, 84, 72, 79, 128, 84, 87, 65,
+ 65, 128, 87, 73, 78, 69, 128, 89, 65, 71, 72, 128, 89, 65, 90, 72, 128,
+ 89, 73, 87, 78, 128, 89, 87, 65, 65, 128, 90, 72, 65, 82, 128, 90, 72,
+ 69, 69, 128, 45, 68, 90, 85, 196, 65, 76, 70, 65, 128, 65, 80, 69, 83,
+ 207, 65, 82, 71, 73, 128, 66, 66, 85, 84, 128, 66, 69, 65, 84, 128, 66,
+ 76, 65, 68, 197, 66, 76, 85, 69, 128, 66, 79, 78, 69, 128, 66, 82, 85,
+ 83, 200, 66, 85, 75, 89, 128, 66, 90, 85, 78, 199, 67, 65, 82, 84, 128,
+ 67, 85, 79, 80, 128, 67, 85, 82, 86, 197, 67, 87, 73, 73, 128, 67, 87,
+ 79, 79, 128, 68, 65, 76, 69, 212, 68, 68, 85, 82, 128, 68, 69, 69, 82,
+ 128, 68, 90, 72, 65, 128, 68, 90, 72, 69, 128, 68, 90, 74, 69, 128, 69,
+ 65, 82, 84, 200, 69, 82, 65, 83, 197, 70, 69, 69, 68, 128, 70, 73, 83,
+ 72, 128, 70, 76, 65, 71, 128, 70, 76, 65, 84, 128, 70, 82, 79, 71, 128,
+ 70, 87, 65, 65, 128, 71, 65, 84, 69, 128, 71, 67, 73, 71, 128, 71, 71,
+ 79, 80, 128, 71, 71, 85, 79, 128, 71, 72, 65, 68, 128, 71, 72, 72, 65,
+ 128, 71, 73, 77, 69, 204, 71, 79, 65, 76, 128, 71, 82, 65, 67, 197, 71,
+ 83, 85, 77, 128, 71, 89, 65, 83, 128, 71, 89, 79, 78, 128, 72, 65, 84,
+ 69, 128, 72, 65, 86, 69, 128, 72, 66, 65, 83, 193, 72, 69, 82, 85, 128,
+ 72, 72, 65, 65, 128, 72, 73, 69, 85, 200, 72, 88, 73, 84, 128, 72, 88,
+ 79, 80, 128, 72, 88, 85, 79, 128, 74, 65, 68, 69, 128, 74, 69, 69, 77,
+ 128, 74, 72, 69, 72, 128, 74, 74, 73, 69, 128, 74, 74, 85, 84, 128, 75,
+ 65, 75, 79, 128, 75, 72, 65, 72, 128, 75, 72, 65, 78, 199, 75, 72, 72,
+ 65, 128, 75, 78, 73, 70, 197, 75, 83, 83, 65, 128, 75, 87, 73, 73, 128,
+ 75, 87, 79, 79, 128, 76, 69, 65, 70, 128, 76, 73, 87, 78, 128, 76, 79,
+ 78, 71, 193, 76, 79, 87, 45, 185, 76, 87, 65, 65, 128, 76, 87, 73, 73,
+ 128, 76, 87, 79, 79, 128, 77, 69, 65, 84, 128, 77, 69, 69, 77, 128, 77,
+ 69, 69, 84, 128, 77, 69, 83, 79, 128, 77, 73, 69, 85, 205, 77, 79, 85,
+ 78, 196, 77, 87, 73, 73, 128, 77, 87, 79, 79, 128, 78, 65, 77, 69, 128,
+ 78, 65, 78, 65, 128, 78, 66, 73, 69, 128, 78, 73, 69, 85, 206, 78, 78,
+ 78, 65, 128, 78, 79, 68, 69, 128, 78, 89, 73, 80, 128, 78, 89, 79, 80,
+ 128, 78, 90, 85, 80, 128, 80, 65, 87, 78, 128, 80, 73, 69, 85, 208, 80,
+ 73, 87, 82, 128, 80, 76, 65, 67, 197, 80, 79, 85, 78, 196, 80, 87, 73,
+ 73, 128, 80, 87, 79, 79, 128, 81, 85, 79, 84, 197, 82, 65, 89, 83, 128,
+ 82, 66, 65, 83, 193, 82, 73, 69, 85, 204, 82, 73, 83, 72, 128, 82, 79,
+ 79, 75, 128, 82, 87, 65, 65, 128, 83, 65, 76, 76, 193, 83, 65, 76, 84,
+ 128, 83, 69, 65, 76, 128, 83, 72, 65, 65, 128, 83, 72, 65, 84, 128, 83,
+ 72, 69, 69, 128, 83, 72, 72, 65, 128, 83, 72, 73, 70, 212, 83, 72, 79,
+ 71, 201, 83, 72, 85, 82, 128, 83, 72, 87, 69, 128, 83, 72, 87, 73, 128,
+ 83, 72, 87, 79, 128, 83, 76, 85, 82, 128, 83, 77, 65, 83, 200, 83, 78,
+ 79, 85, 212, 83, 80, 65, 68, 197, 83, 81, 85, 65, 212, 83, 84, 65, 70,
+ 198, 83, 85, 75, 85, 206, 83, 87, 73, 73, 128, 83, 87, 79, 79, 128, 84,
+ 69, 88, 84, 128, 84, 72, 69, 82, 197, 84, 72, 79, 79, 128, 84, 73, 77,
+ 69, 128, 84, 73, 87, 78, 128, 84, 76, 72, 65, 128, 84, 76, 72, 69, 128,
+ 84, 76, 72, 73, 128, 84, 76, 72, 79, 128, 84, 82, 69, 69, 128, 84, 82,
+ 85, 69, 128, 84, 83, 72, 69, 128, 84, 87, 73, 73, 128, 84, 87, 79, 79,
+ 128, 85, 78, 68, 69, 210, 86, 69, 68, 69, 128, 86, 73, 68, 65, 128, 87,
+ 65, 76, 75, 128, 87, 65, 83, 76, 193, 87, 65, 84, 69, 210, 87, 72, 79,
+ 76, 197, 87, 79, 79, 68, 128, 87, 79, 79, 76, 128, 87, 89, 78, 78, 128,
+ 89, 65, 75, 72, 128, 89, 65, 84, 73, 128, 89, 69, 82, 73, 128, 89, 79,
+ 45, 73, 128, 89, 79, 71, 72, 128, 89, 85, 45, 73, 128, 89, 87, 73, 73,
+ 128, 89, 87, 79, 79, 128, 90, 65, 73, 78, 128, 90, 65, 81, 69, 198, 90,
+ 65, 84, 65, 128, 90, 76, 65, 77, 193, 45, 67, 72, 65, 210, 65, 69, 83,
+ 67, 128, 65, 70, 84, 69, 210, 65, 72, 83, 65, 128, 65, 73, 76, 77, 128,
+ 65, 73, 78, 78, 128, 65, 75, 66, 65, 210, 65, 76, 71, 73, 218, 65, 76,
+ 76, 65, 200, 65, 76, 80, 65, 128, 65, 77, 80, 83, 128, 65, 78, 72, 85,
+ 128, 65, 78, 75, 72, 128, 65, 78, 83, 85, 218, 65, 82, 77, 89, 128, 65,
+ 84, 78, 65, 200, 65, 85, 78, 78, 128, 65, 89, 65, 72, 128, 66, 48, 49,
+ 56, 128, 66, 48, 49, 57, 128, 66, 48, 50, 50, 128, 66, 48, 51, 52, 128,
+ 66, 48, 52, 55, 128, 66, 48, 52, 57, 128, 66, 48, 53, 54, 128, 66, 48,
+ 54, 51, 128, 66, 48, 54, 52, 128, 66, 48, 55, 57, 128, 66, 48, 56, 50,
+ 128, 66, 48, 56, 51, 128, 66, 48, 56, 54, 128, 66, 48, 56, 57, 128, 66,
+ 49, 48, 53, 198, 66, 49, 48, 53, 205, 66, 49, 48, 54, 198, 66, 49, 48,
+ 54, 205, 66, 49, 48, 55, 198, 66, 49, 48, 55, 205, 66, 49, 48, 56, 198,
+ 66, 49, 48, 56, 205, 66, 49, 48, 57, 198, 66, 49, 48, 57, 205, 66, 49,
+ 51, 50, 128, 66, 49, 52, 50, 128, 66, 49, 52, 54, 128, 66, 49, 53, 48,
+ 128, 66, 49, 53, 50, 128, 66, 49, 53, 51, 128, 66, 49, 53, 52, 128, 66,
+ 49, 53, 53, 128, 66, 49, 53, 55, 128, 66, 49, 53, 56, 128, 66, 49, 54,
+ 48, 128, 66, 49, 54, 49, 128, 66, 49, 54, 52, 128, 66, 49, 54, 53, 128,
+ 66, 49, 54, 54, 128, 66, 49, 54, 55, 128, 66, 49, 54, 56, 128, 66, 49,
+ 54, 57, 128, 66, 49, 55, 48, 128, 66, 49, 55, 49, 128, 66, 49, 55, 50,
+ 128, 66, 49, 55, 52, 128, 66, 49, 55, 55, 128, 66, 49, 55, 56, 128, 66,
+ 49, 55, 57, 128, 66, 49, 56, 48, 128, 66, 49, 56, 49, 128, 66, 49, 56,
+ 50, 128, 66, 49, 56, 51, 128, 66, 49, 56, 52, 128, 66, 49, 56, 53, 128,
+ 66, 49, 56, 57, 128, 66, 49, 57, 48, 128, 66, 50, 48, 48, 128, 66, 50,
+ 48, 49, 128, 66, 50, 48, 50, 128, 66, 50, 48, 51, 128, 66, 50, 48, 52,
+ 128, 66, 50, 48, 53, 128, 66, 50, 48, 54, 128, 66, 50, 48, 55, 128, 66,
+ 50, 48, 56, 128, 66, 50, 48, 57, 128, 66, 50, 49, 48, 128, 66, 50, 49,
+ 49, 128, 66, 50, 49, 50, 128, 66, 50, 49, 51, 128, 66, 50, 49, 52, 128,
+ 66, 50, 49, 53, 128, 66, 50, 49, 54, 128, 66, 50, 49, 55, 128, 66, 50,
+ 49, 56, 128, 66, 50, 49, 57, 128, 66, 50, 50, 49, 128, 66, 50, 50, 50,
+ 128, 66, 50, 50, 54, 128, 66, 50, 50, 55, 128, 66, 50, 50, 56, 128, 66,
+ 50, 50, 57, 128, 66, 50, 51, 50, 128, 66, 50, 51, 52, 128, 66, 50, 51,
+ 54, 128, 66, 50, 52, 53, 128, 66, 50, 52, 54, 128, 66, 50, 52, 56, 128,
+ 66, 50, 52, 57, 128, 66, 50, 53, 48, 128, 66, 50, 53, 49, 128, 66, 50,
+ 53, 50, 128, 66, 50, 53, 51, 128, 66, 50, 53, 53, 128, 66, 50, 53, 54,
+ 128, 66, 50, 53, 55, 128, 66, 50, 53, 56, 128, 66, 50, 53, 57, 128, 66,
+ 51, 48, 53, 128, 66, 65, 67, 75, 128, 66, 65, 71, 65, 128, 66, 65, 72,
+ 84, 128, 66, 65, 82, 83, 128, 66, 65, 83, 69, 128, 66, 66, 65, 80, 128,
+ 66, 66, 65, 84, 128, 66, 66, 65, 88, 128, 66, 66, 69, 80, 128, 66, 66,
+ 69, 88, 128, 66, 66, 73, 69, 128, 66, 66, 73, 80, 128, 66, 66, 73, 84,
+ 128, 66, 66, 73, 88, 128, 66, 66, 79, 80, 128, 66, 66, 79, 84, 128, 66,
+ 66, 79, 88, 128, 66, 66, 85, 79, 128, 66, 66, 85, 80, 128, 66, 66, 85,
+ 82, 128, 66, 66, 85, 88, 128, 66, 66, 89, 80, 128, 66, 66, 89, 84, 128,
+ 66, 66, 89, 88, 128, 66, 67, 65, 68, 128, 66, 69, 65, 78, 128, 66, 69,
+ 69, 72, 128, 66, 69, 76, 76, 128, 66, 69, 76, 84, 128, 66, 69, 78, 68,
+ 128, 66, 69, 79, 82, 195, 66, 69, 84, 72, 128, 66, 73, 82, 85, 128, 66,
+ 76, 65, 78, 203, 66, 79, 65, 82, 128, 66, 79, 65, 84, 128, 66, 79, 68,
+ 89, 128, 66, 83, 68, 85, 211, 66, 83, 75, 65, 173, 66, 83, 75, 85, 210,
+ 66, 85, 76, 76, 128, 66, 85, 77, 80, 217, 66, 87, 69, 69, 128, 67, 65,
+ 65, 73, 128, 67, 65, 76, 67, 128, 67, 65, 76, 76, 128, 67, 65, 80, 79,
+ 128, 67, 65, 86, 69, 128, 67, 65, 89, 78, 128, 67, 67, 65, 65, 128, 67,
+ 67, 69, 69, 128, 67, 67, 72, 65, 128, 67, 67, 72, 69, 128, 67, 67, 72,
+ 73, 128, 67, 67, 72, 79, 128, 67, 67, 72, 85, 128, 67, 72, 65, 78, 128,
+ 67, 72, 65, 80, 128, 67, 72, 65, 84, 128, 67, 72, 65, 88, 128, 67, 72,
+ 69, 80, 128, 67, 72, 69, 84, 128, 67, 72, 69, 88, 128, 67, 72, 79, 65,
+ 128, 67, 72, 79, 69, 128, 67, 72, 79, 80, 128, 67, 72, 79, 84, 128, 67,
+ 72, 79, 88, 128, 67, 72, 85, 79, 128, 67, 72, 85, 80, 128, 67, 72, 85,
+ 82, 128, 67, 72, 85, 88, 128, 67, 72, 89, 80, 128, 67, 72, 89, 82, 128,
+ 67, 72, 89, 84, 128, 67, 72, 89, 88, 128, 67, 73, 69, 80, 128, 67, 73,
+ 69, 84, 128, 67, 73, 69, 88, 128, 67, 76, 65, 78, 128, 67, 76, 65, 87,
+ 128, 67, 76, 69, 65, 210, 67, 76, 79, 83, 197, 67, 79, 68, 65, 128, 67,
+ 79, 76, 76, 128, 67, 79, 80, 89, 128, 67, 85, 79, 88, 128, 67, 85, 82,
+ 88, 128, 67, 89, 82, 88, 128, 68, 65, 71, 65, 218, 68, 65, 71, 83, 128,
+ 68, 65, 73, 82, 128, 68, 65, 77, 80, 128, 68, 65, 82, 84, 128, 68, 68,
+ 65, 65, 128, 68, 68, 65, 76, 128, 68, 68, 65, 80, 128, 68, 68, 65, 84,
+ 128, 68, 68, 65, 88, 128, 68, 68, 69, 69, 128, 68, 68, 69, 80, 128, 68,
+ 68, 69, 88, 128, 68, 68, 72, 79, 128, 68, 68, 73, 69, 128, 68, 68, 73,
+ 80, 128, 68, 68, 73, 84, 128, 68, 68, 73, 88, 128, 68, 68, 79, 65, 128,
+ 68, 68, 79, 80, 128, 68, 68, 79, 84, 128, 68, 68, 79, 88, 128, 68, 68,
+ 85, 79, 128, 68, 68, 85, 80, 128, 68, 68, 85, 84, 128, 68, 68, 85, 88,
+ 128, 68, 68, 87, 65, 128, 68, 69, 65, 68, 128, 68, 69, 66, 73, 212, 68,
+ 69, 69, 76, 128, 68, 69, 72, 73, 128, 68, 69, 75, 65, 128, 68, 69, 83,
+ 73, 128, 68, 72, 65, 76, 128, 68, 73, 80, 76, 201, 68, 73, 83, 72, 128,
+ 68, 73, 84, 84, 207, 68, 76, 69, 69, 128, 68, 79, 73, 84, 128, 68, 79,
+ 79, 82, 128, 68, 79, 82, 85, 128, 68, 82, 85, 77, 128, 68, 89, 69, 72,
+ 128, 68, 90, 69, 69, 128, 69, 72, 87, 65, 218, 69, 74, 69, 67, 212, 69,
+ 78, 84, 69, 210, 69, 84, 72, 69, 204, 69, 85, 45, 85, 128, 69, 85, 76,
+ 69, 210, 70, 65, 65, 73, 128, 70, 65, 78, 71, 128, 70, 76, 73, 80, 128,
+ 70, 79, 82, 77, 211, 70, 82, 65, 78, 195, 70, 85, 82, 88, 128, 70, 85,
+ 83, 69, 128, 70, 87, 69, 69, 128, 71, 65, 77, 65, 204, 71, 68, 65, 78,
+ 128, 71, 69, 65, 82, 128, 71, 71, 65, 65, 128, 71, 71, 65, 80, 128, 71,
+ 71, 65, 84, 128, 71, 71, 65, 88, 128, 71, 71, 69, 69, 128, 71, 71, 69,
+ 80, 128, 71, 71, 69, 84, 128, 71, 71, 69, 88, 128, 71, 71, 73, 69, 128,
+ 71, 71, 73, 84, 128, 71, 71, 73, 88, 128, 71, 71, 79, 84, 128, 71, 71,
+ 79, 88, 128, 71, 71, 85, 80, 128, 71, 71, 85, 82, 128, 71, 71, 85, 84,
+ 128, 71, 71, 85, 88, 128, 71, 71, 87, 65, 128, 71, 71, 87, 69, 128, 71,
+ 71, 87, 73, 128, 71, 72, 69, 69, 128, 71, 73, 66, 65, 128, 71, 73, 69,
+ 84, 128, 71, 73, 71, 65, 128, 71, 79, 73, 78, 199, 71, 79, 82, 84, 128,
+ 71, 85, 69, 72, 128, 71, 89, 65, 65, 128, 71, 89, 69, 69, 128, 72, 65,
+ 69, 71, 204, 72, 65, 71, 76, 128, 72, 69, 77, 80, 128, 72, 72, 69, 69,
+ 128, 72, 72, 87, 65, 128, 72, 73, 69, 88, 128, 72, 73, 90, 66, 128, 72,
+ 76, 65, 80, 128, 72, 76, 65, 84, 128, 72, 76, 65, 88, 128, 72, 76, 69,
+ 80, 128, 72, 76, 69, 88, 128, 72, 76, 73, 69, 128, 72, 76, 73, 80, 128,
+ 72, 76, 73, 84, 128, 72, 76, 73, 88, 128, 72, 76, 79, 80, 128, 72, 76,
+ 79, 88, 128, 72, 76, 85, 79, 128, 72, 76, 85, 80, 128, 72, 76, 85, 82,
+ 128, 72, 76, 85, 84, 128, 72, 76, 85, 88, 128, 72, 76, 89, 80, 128, 72,
+ 76, 89, 82, 128, 72, 76, 89, 84, 128, 72, 76, 89, 88, 128, 72, 77, 65,
+ 80, 128, 72, 77, 65, 84, 128, 72, 77, 65, 88, 128, 72, 77, 73, 69, 128,
+ 72, 77, 73, 80, 128, 72, 77, 73, 84, 128, 72, 77, 73, 88, 128, 72, 77,
+ 79, 80, 128, 72, 77, 79, 84, 128, 72, 77, 79, 88, 128, 72, 77, 85, 79,
+ 128, 72, 77, 85, 80, 128, 72, 77, 85, 82, 128, 72, 77, 85, 84, 128, 72,
+ 77, 85, 88, 128, 72, 77, 89, 80, 128, 72, 77, 89, 82, 128, 72, 77, 89,
+ 88, 128, 72, 78, 65, 80, 128, 72, 78, 65, 84, 128, 72, 78, 65, 88, 128,
+ 72, 78, 69, 80, 128, 72, 78, 69, 88, 128, 72, 78, 73, 69, 128, 72, 78,
+ 73, 80, 128, 72, 78, 73, 84, 128, 72, 78, 73, 88, 128, 72, 78, 79, 80,
+ 128, 72, 78, 79, 84, 128, 72, 78, 79, 88, 128, 72, 78, 85, 79, 128, 72,
+ 78, 85, 84, 128, 72, 79, 79, 78, 128, 72, 79, 84, 65, 128, 72, 80, 87,
+ 71, 128, 72, 85, 77, 65, 206, 72, 88, 65, 80, 128, 72, 88, 65, 84, 128,
+ 72, 88, 65, 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 88, 128, 72, 88,
+ 73, 69, 128, 72, 88, 73, 80, 128, 72, 88, 73, 88, 128, 72, 88, 79, 84,
+ 128, 72, 88, 79, 88, 128, 72, 90, 87, 71, 128, 72, 90, 90, 80, 128, 72,
+ 90, 90, 90, 128, 73, 45, 69, 85, 128, 73, 45, 89, 65, 128, 73, 68, 76,
+ 69, 128, 73, 70, 73, 78, 128, 73, 76, 85, 89, 128, 73, 78, 67, 72, 128,
+ 73, 78, 78, 69, 210, 73, 78, 78, 78, 128, 73, 78, 84, 73, 128, 73, 83,
+ 79, 78, 128, 73, 84, 69, 77, 128, 73, 85, 74, 65, 128, 74, 69, 82, 65,
+ 206, 74, 74, 69, 69, 128, 74, 74, 73, 80, 128, 74, 74, 73, 84, 128, 74,
+ 74, 73, 88, 128, 74, 74, 79, 80, 128, 74, 74, 79, 84, 128, 74, 74, 79,
+ 88, 128, 74, 74, 85, 79, 128, 74, 74, 85, 80, 128, 74, 74, 85, 82, 128,
+ 74, 74, 85, 88, 128, 74, 74, 89, 80, 128, 74, 74, 89, 84, 128, 74, 74,
+ 89, 88, 128, 74, 85, 76, 89, 128, 74, 85, 78, 69, 128, 74, 85, 79, 84,
+ 128, 75, 65, 65, 70, 128, 75, 65, 65, 73, 128, 75, 65, 80, 72, 128, 75,
+ 65, 80, 79, 128, 75, 67, 65, 76, 128, 75, 72, 65, 65, 128, 75, 72, 65,
+ 73, 128, 75, 72, 65, 78, 128, 75, 72, 69, 69, 128, 75, 72, 79, 78, 128,
+ 75, 73, 67, 75, 128, 75, 73, 69, 80, 128, 75, 73, 69, 88, 128, 75, 73,
+ 82, 79, 128, 75, 75, 69, 69, 128, 75, 79, 77, 66, 213, 75, 79, 84, 79,
+ 128, 75, 85, 79, 80, 128, 75, 85, 79, 88, 128, 75, 85, 82, 84, 128, 75,
+ 85, 82, 88, 128, 75, 85, 85, 72, 128, 75, 87, 69, 69, 128, 75, 88, 65,
+ 65, 128, 75, 88, 69, 69, 128, 75, 88, 87, 65, 128, 75, 88, 87, 69, 128,
+ 75, 88, 87, 73, 128, 75, 89, 65, 65, 128, 75, 89, 69, 69, 128, 76, 65,
+ 65, 73, 128, 76, 65, 65, 78, 128, 76, 65, 69, 86, 128, 76, 65, 77, 69,
+ 128, 76, 65, 77, 69, 196, 76, 68, 65, 78, 128, 76, 69, 69, 75, 128, 76,
+ 69, 71, 83, 128, 76, 69, 86, 69, 204, 76, 69, 90, 72, 128, 76, 72, 65,
+ 65, 128, 76, 72, 73, 73, 128, 76, 72, 79, 79, 128, 76, 73, 69, 84, 128,
+ 76, 73, 70, 69, 128, 76, 73, 84, 82, 193, 76, 79, 76, 76, 128, 76, 79,
+ 79, 84, 128, 76, 85, 73, 83, 128, 76, 85, 79, 84, 128, 77, 65, 65, 73,
+ 128, 77, 65, 82, 69, 128, 77, 69, 82, 73, 128, 77, 69, 83, 72, 128, 77,
+ 69, 83, 73, 128, 77, 71, 65, 80, 128, 77, 71, 65, 84, 128, 77, 71, 65,
+ 88, 128, 77, 71, 69, 80, 128, 77, 71, 69, 88, 128, 77, 71, 73, 69, 128,
+ 77, 71, 79, 80, 128, 77, 71, 79, 84, 128, 77, 71, 79, 88, 128, 77, 71,
+ 85, 79, 128, 77, 71, 85, 80, 128, 77, 71, 85, 82, 128, 77, 71, 85, 84,
+ 128, 77, 71, 85, 88, 128, 77, 73, 67, 82, 207, 77, 73, 73, 78, 128, 77,
+ 73, 76, 76, 197, 77, 73, 77, 69, 128, 77, 73, 78, 89, 128, 77, 73, 82,
+ 73, 128, 77, 78, 89, 65, 205, 77, 79, 78, 84, 200, 77, 79, 85, 84, 200,
+ 77, 79, 86, 69, 196, 77, 85, 73, 78, 128, 77, 85, 76, 84, 201, 77, 85,
+ 79, 84, 128, 77, 87, 69, 69, 128, 78, 65, 65, 73, 128, 78, 65, 73, 82,
+ 193, 78, 65, 78, 68, 128, 78, 66, 65, 80, 128, 78, 66, 65, 84, 128, 78,
+ 66, 65, 88, 128, 78, 66, 73, 80, 128, 78, 66, 73, 84, 128, 78, 66, 73,
+ 88, 128, 78, 66, 79, 80, 128, 78, 66, 79, 84, 128, 78, 66, 79, 88, 128,
+ 78, 66, 85, 80, 128, 78, 66, 85, 82, 128, 78, 66, 85, 84, 128, 78, 66,
+ 85, 88, 128, 78, 66, 89, 80, 128, 78, 66, 89, 82, 128, 78, 66, 89, 84,
+ 128, 78, 66, 89, 88, 128, 78, 68, 65, 80, 128, 78, 68, 65, 84, 128, 78,
+ 68, 65, 88, 128, 78, 68, 69, 80, 128, 78, 68, 73, 69, 128, 78, 68, 73,
+ 80, 128, 78, 68, 73, 84, 128, 78, 68, 73, 88, 128, 78, 68, 79, 80, 128,
+ 78, 68, 79, 84, 128, 78, 68, 79, 88, 128, 78, 68, 85, 80, 128, 78, 68,
+ 85, 82, 128, 78, 68, 85, 84, 128, 78, 68, 85, 88, 128, 78, 71, 65, 73,
+ 128, 78, 71, 65, 80, 128, 78, 71, 65, 84, 128, 78, 71, 65, 88, 128, 78,
+ 71, 69, 80, 128, 78, 71, 69, 88, 128, 78, 71, 73, 69, 128, 78, 71, 75,
+ 65, 128, 78, 71, 79, 80, 128, 78, 71, 79, 84, 128, 78, 71, 79, 88, 128,
+ 78, 71, 85, 79, 128, 78, 74, 73, 69, 128, 78, 74, 73, 80, 128, 78, 74,
+ 73, 84, 128, 78, 74, 73, 88, 128, 78, 74, 79, 80, 128, 78, 74, 79, 84,
+ 128, 78, 74, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 80, 128, 78,
+ 74, 85, 82, 128, 78, 74, 85, 88, 128, 78, 74, 89, 80, 128, 78, 74, 89,
+ 82, 128, 78, 74, 89, 84, 128, 78, 74, 89, 88, 128, 78, 78, 71, 65, 128,
+ 78, 78, 71, 73, 128, 78, 78, 71, 79, 128, 78, 79, 83, 69, 128, 78, 82,
+ 65, 80, 128, 78, 82, 65, 84, 128, 78, 82, 65, 88, 128, 78, 82, 69, 80,
+ 128, 78, 82, 69, 84, 128, 78, 82, 69, 88, 128, 78, 82, 79, 80, 128, 78,
+ 82, 79, 88, 128, 78, 82, 85, 80, 128, 78, 82, 85, 82, 128, 78, 82, 85,
+ 84, 128, 78, 82, 85, 88, 128, 78, 82, 89, 80, 128, 78, 82, 89, 82, 128,
+ 78, 82, 89, 84, 128, 78, 82, 89, 88, 128, 78, 85, 76, 76, 128, 78, 85,
+ 79, 80, 128, 78, 85, 82, 88, 128, 78, 85, 85, 78, 128, 78, 89, 65, 65,
+ 128, 78, 89, 67, 65, 128, 78, 89, 69, 69, 128, 78, 89, 69, 72, 128, 78,
+ 89, 73, 69, 128, 78, 89, 73, 84, 128, 78, 89, 73, 88, 128, 78, 89, 79,
+ 65, 128, 78, 89, 79, 84, 128, 78, 89, 79, 88, 128, 78, 89, 85, 79, 128,
+ 78, 89, 85, 80, 128, 78, 89, 85, 84, 128, 78, 89, 85, 88, 128, 78, 89,
+ 87, 65, 128, 78, 90, 65, 80, 128, 78, 90, 65, 84, 128, 78, 90, 65, 88,
+ 128, 78, 90, 69, 88, 128, 78, 90, 73, 69, 128, 78, 90, 73, 80, 128, 78,
+ 90, 73, 84, 128, 78, 90, 73, 88, 128, 78, 90, 79, 80, 128, 78, 90, 79,
+ 88, 128, 78, 90, 85, 79, 128, 78, 90, 85, 82, 128, 78, 90, 85, 88, 128,
+ 78, 90, 89, 80, 128, 78, 90, 89, 82, 128, 78, 90, 89, 84, 128, 78, 90,
+ 89, 88, 128, 79, 45, 69, 79, 128, 79, 45, 89, 69, 128, 79, 78, 83, 85,
+ 128, 79, 79, 77, 85, 128, 79, 79, 90, 69, 128, 79, 85, 78, 67, 197, 80,
+ 65, 65, 73, 128, 80, 65, 68, 77, 193, 80, 65, 82, 65, 128, 80, 69, 65,
+ 67, 197, 80, 69, 69, 80, 128, 80, 69, 78, 78, 217, 80, 69, 83, 79, 128,
+ 80, 72, 65, 65, 128, 80, 72, 65, 78, 128, 80, 72, 69, 69, 128, 80, 72,
+ 79, 65, 128, 80, 72, 87, 65, 128, 80, 73, 67, 75, 128, 80, 73, 69, 80,
+ 128, 80, 73, 69, 88, 128, 80, 73, 75, 79, 128, 80, 76, 79, 87, 128, 80,
+ 82, 65, 77, 128, 80, 82, 73, 78, 212, 80, 85, 79, 80, 128, 80, 85, 79,
+ 88, 128, 80, 85, 82, 88, 128, 80, 87, 69, 69, 128, 80, 89, 82, 88, 128,
+ 81, 65, 65, 70, 128, 81, 65, 65, 73, 128, 81, 65, 80, 72, 128, 81, 72,
+ 65, 65, 128, 81, 72, 69, 69, 128, 81, 72, 87, 65, 128, 81, 72, 87, 69,
+ 128, 81, 72, 87, 73, 128, 81, 73, 69, 80, 128, 81, 73, 69, 84, 128, 81,
+ 73, 69, 88, 128, 81, 79, 80, 65, 128, 81, 85, 79, 80, 128, 81, 85, 79,
+ 84, 128, 81, 85, 79, 88, 128, 81, 85, 82, 88, 128, 81, 85, 85, 86, 128,
+ 81, 87, 65, 65, 128, 81, 87, 69, 69, 128, 81, 89, 65, 65, 128, 81, 89,
+ 69, 69, 128, 81, 89, 82, 88, 128, 82, 65, 65, 73, 128, 82, 65, 73, 68,
+ 207, 82, 65, 78, 71, 197, 82, 69, 77, 85, 128, 82, 73, 67, 69, 128, 82,
+ 73, 69, 76, 128, 82, 73, 82, 65, 128, 82, 79, 65, 82, 128, 82, 82, 65,
+ 88, 128, 82, 82, 69, 72, 128, 82, 82, 69, 80, 128, 82, 82, 69, 84, 128,
+ 82, 82, 69, 88, 128, 82, 82, 79, 80, 128, 82, 82, 79, 84, 128, 82, 82,
+ 79, 88, 128, 82, 82, 85, 79, 128, 82, 82, 85, 80, 128, 82, 82, 85, 82,
+ 128, 82, 82, 85, 84, 128, 82, 82, 85, 88, 128, 82, 82, 89, 80, 128, 82,
+ 82, 89, 82, 128, 82, 82, 89, 84, 128, 82, 82, 89, 88, 128, 82, 85, 73,
+ 83, 128, 82, 85, 76, 69, 128, 82, 85, 79, 80, 128, 82, 85, 83, 73, 128,
+ 83, 65, 45, 73, 128, 83, 65, 65, 73, 128, 83, 65, 68, 69, 128, 83, 65,
+ 73, 76, 128, 83, 65, 76, 65, 128, 83, 65, 76, 65, 205, 83, 66, 82, 85,
+ 204, 83, 67, 87, 65, 128, 83, 68, 79, 78, 199, 83, 72, 65, 80, 128, 83,
+ 72, 65, 88, 128, 83, 72, 69, 80, 128, 83, 72, 69, 84, 128, 83, 72, 69,
+ 88, 128, 83, 72, 73, 73, 128, 83, 72, 73, 77, 193, 83, 72, 79, 65, 128,
+ 83, 72, 79, 79, 128, 83, 72, 79, 84, 128, 83, 72, 79, 88, 128, 83, 72,
+ 85, 79, 128, 83, 72, 85, 80, 128, 83, 72, 85, 84, 128, 83, 72, 85, 88,
+ 128, 83, 72, 89, 80, 128, 83, 72, 89, 82, 128, 83, 72, 89, 84, 128, 83,
+ 72, 89, 88, 128, 83, 73, 71, 69, 204, 83, 73, 88, 84, 217, 83, 75, 73,
+ 78, 128, 83, 75, 85, 76, 204, 83, 75, 87, 65, 128, 83, 78, 65, 75, 197,
+ 83, 80, 79, 84, 128, 83, 80, 87, 65, 128, 83, 83, 65, 65, 128, 83, 83,
+ 65, 80, 128, 83, 83, 65, 84, 128, 83, 83, 65, 88, 128, 83, 83, 69, 69,
+ 128, 83, 83, 69, 80, 128, 83, 83, 69, 88, 128, 83, 83, 73, 69, 128, 83,
+ 83, 73, 80, 128, 83, 83, 73, 84, 128, 83, 83, 73, 88, 128, 83, 83, 79,
+ 80, 128, 83, 83, 79, 84, 128, 83, 83, 79, 88, 128, 83, 83, 85, 80, 128,
+ 83, 83, 85, 84, 128, 83, 83, 85, 88, 128, 83, 83, 89, 80, 128, 83, 83,
+ 89, 82, 128, 83, 83, 89, 84, 128, 83, 83, 89, 88, 128, 83, 84, 65, 78,
+ 128, 83, 84, 69, 80, 128, 83, 84, 73, 76, 197, 83, 84, 73, 76, 204, 83,
+ 84, 87, 65, 128, 83, 85, 79, 80, 128, 83, 85, 79, 88, 128, 83, 85, 82,
+ 88, 128, 83, 87, 85, 78, 199, 83, 90, 65, 65, 128, 83, 90, 69, 69, 128,
+ 83, 90, 87, 65, 128, 83, 90, 87, 71, 128, 84, 65, 65, 73, 128, 84, 65,
+ 75, 69, 128, 84, 65, 76, 76, 128, 84, 69, 45, 85, 128, 84, 69, 78, 84,
+ 128, 84, 69, 84, 72, 128, 84, 72, 69, 72, 128, 84, 72, 69, 77, 193, 84,
+ 72, 69, 89, 128, 84, 72, 79, 65, 128, 84, 72, 85, 82, 211, 84, 72, 87,
+ 65, 128, 84, 73, 69, 80, 128, 84, 73, 69, 88, 128, 84, 73, 71, 72, 212,
+ 84, 73, 78, 89, 128, 84, 73, 87, 65, 218, 84, 76, 69, 69, 128, 84, 76,
+ 72, 85, 128, 84, 79, 84, 65, 204, 84, 82, 65, 68, 197, 84, 82, 73, 79,
+ 206, 84, 83, 65, 65, 128, 84, 83, 65, 68, 201, 84, 83, 87, 65, 128, 84,
+ 84, 65, 65, 128, 84, 84, 69, 69, 128, 84, 84, 69, 72, 128, 84, 84, 72,
+ 69, 128, 84, 84, 72, 73, 128, 84, 84, 83, 65, 128, 84, 84, 83, 69, 128,
+ 84, 84, 83, 73, 128, 84, 84, 83, 79, 128, 84, 84, 83, 85, 128, 84, 85,
+ 79, 80, 128, 84, 85, 79, 84, 128, 84, 85, 79, 88, 128, 84, 85, 82, 88,
+ 128, 84, 90, 65, 65, 128, 84, 90, 69, 69, 128, 84, 90, 79, 65, 128, 85,
+ 45, 65, 69, 128, 85, 65, 84, 72, 128, 86, 73, 69, 80, 128, 86, 73, 69,
+ 84, 128, 86, 73, 69, 88, 128, 86, 85, 82, 88, 128, 86, 89, 82, 88, 128,
+ 87, 65, 69, 78, 128, 87, 65, 76, 76, 128, 87, 69, 76, 76, 128, 87, 69,
+ 83, 84, 128, 87, 79, 82, 75, 128, 87, 82, 65, 80, 128, 87, 85, 78, 74,
+ 207, 87, 85, 79, 80, 128, 87, 85, 79, 88, 128, 88, 73, 82, 79, 206, 88,
+ 89, 65, 65, 128, 88, 89, 69, 69, 128, 88, 89, 82, 88, 128, 89, 65, 45,
+ 79, 128, 89, 65, 65, 73, 128, 89, 65, 66, 72, 128, 89, 65, 67, 72, 128,
+ 89, 65, 68, 68, 128, 89, 65, 68, 72, 128, 89, 65, 71, 78, 128, 89, 65,
+ 72, 72, 128, 89, 65, 82, 82, 128, 89, 65, 83, 72, 128, 89, 65, 83, 83,
+ 128, 89, 65, 84, 72, 128, 89, 65, 84, 84, 128, 89, 65, 90, 90, 128, 89,
+ 69, 82, 65, 200, 89, 73, 45, 85, 128, 89, 73, 78, 71, 128, 89, 79, 45,
+ 79, 128, 89, 79, 77, 79, 128, 89, 79, 82, 73, 128, 89, 85, 45, 65, 128,
+ 89, 85, 45, 69, 128, 89, 85, 45, 85, 128, 89, 85, 65, 78, 128, 89, 85,
+ 68, 72, 128, 89, 85, 79, 84, 128, 89, 85, 82, 88, 128, 89, 89, 82, 88,
+ 128, 90, 65, 89, 73, 206, 90, 72, 65, 65, 128, 90, 72, 65, 80, 128, 90,
+ 72, 65, 84, 128, 90, 72, 65, 88, 128, 90, 72, 69, 80, 128, 90, 72, 69,
+ 84, 128, 90, 72, 69, 88, 128, 90, 72, 79, 80, 128, 90, 72, 79, 84, 128,
+ 90, 72, 79, 88, 128, 90, 72, 85, 79, 128, 90, 72, 85, 80, 128, 90, 72,
+ 85, 82, 128, 90, 72, 85, 84, 128, 90, 72, 85, 88, 128, 90, 72, 87, 65,
+ 128, 90, 72, 89, 80, 128, 90, 72, 89, 82, 128, 90, 72, 89, 84, 128, 90,
+ 72, 89, 88, 128, 90, 85, 79, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65,
+ 80, 128, 90, 90, 65, 84, 128, 90, 90, 65, 88, 128, 90, 90, 69, 69, 128,
+ 90, 90, 69, 80, 128, 90, 90, 69, 88, 128, 90, 90, 73, 69, 128, 90, 90,
+ 73, 80, 128, 90, 90, 73, 84, 128, 90, 90, 73, 88, 128, 90, 90, 79, 80,
+ 128, 90, 90, 79, 88, 128, 90, 90, 85, 80, 128, 90, 90, 85, 82, 128, 90,
+ 90, 85, 88, 128, 90, 90, 89, 80, 128, 90, 90, 89, 82, 128, 90, 90, 89,
+ 84, 128, 90, 90, 89, 88, 128, 79, 80, 69, 206, 70, 85, 76, 204, 83, 69,
+ 69, 206, 73, 79, 84, 193, 69, 65, 83, 212, 70, 82, 79, 205, 84, 79, 68,
+ 207, 70, 73, 86, 197, 72, 79, 85, 210, 84, 69, 78, 128, 83, 73, 66, 197,
+ 70, 79, 85, 210, 79, 86, 69, 210, 72, 79, 82, 206, 81, 85, 65, 196, 68,
+ 65, 83, 200, 78, 69, 79, 128, 80, 72, 73, 128, 80, 83, 73, 128, 84, 72,
+ 69, 200, 75, 79, 77, 201, 82, 72, 79, 128, 89, 85, 83, 128, 71, 72, 65,
+ 128, 79, 88, 73, 193, 82, 79, 67, 128, 66, 72, 65, 128, 83, 65, 82, 193,
+ 84, 65, 67, 203, 84, 65, 85, 128, 68, 79, 69, 211, 74, 72, 65, 128, 82,
+ 82, 65, 128, 87, 73, 68, 197, 82, 68, 69, 204, 83, 72, 73, 206, 87, 65,
+ 86, 217, 90, 65, 73, 206, 68, 73, 71, 193, 83, 72, 79, 128, 65, 82, 67,
+ 128, 75, 65, 70, 128, 76, 69, 71, 128, 83, 84, 79, 208, 84, 65, 77, 128,
+ 89, 65, 78, 199, 68, 90, 69, 128, 71, 72, 69, 128, 71, 79, 65, 204, 71,
+ 84, 69, 210, 78, 85, 78, 128, 78, 89, 79, 128, 83, 84, 65, 210, 83, 85,
+ 78, 128, 84, 65, 73, 204, 87, 65, 86, 197, 87, 65, 87, 128, 87, 79, 82,
+ 196, 90, 69, 82, 207, 65, 80, 76, 201, 66, 69, 69, 200, 67, 76, 69, 198,
+ 68, 74, 69, 128, 68, 75, 65, 210, 68, 89, 69, 200, 68, 90, 65, 128, 69,
+ 73, 69, 128, 70, 69, 72, 128, 70, 73, 83, 200, 71, 65, 78, 128, 71, 85,
+ 69, 200, 72, 73, 69, 128, 75, 83, 73, 128, 76, 65, 77, 197, 76, 74, 69,
+ 128, 77, 69, 77, 128, 77, 71, 79, 128, 77, 85, 67, 200, 77, 87, 65, 128,
+ 78, 65, 77, 197, 78, 65, 82, 128, 78, 74, 69, 128, 78, 79, 87, 128, 78,
+ 87, 65, 128, 78, 89, 69, 200, 78, 89, 73, 128, 79, 79, 85, 128, 80, 69,
+ 69, 128, 82, 65, 65, 128, 84, 72, 69, 206, 84, 73, 67, 203, 84, 84, 69,
+ 200, 89, 79, 68, 128, 66, 65, 83, 197, 66, 69, 69, 128, 66, 79, 87, 128,
+ 66, 90, 72, 201, 67, 79, 87, 128, 68, 79, 78, 128, 70, 76, 65, 212, 70,
+ 82, 69, 197, 72, 65, 69, 128, 74, 73, 76, 128, 75, 69, 72, 128, 75, 72,
+ 73, 128, 75, 72, 79, 128, 75, 87, 69, 128, 75, 87, 73, 128, 76, 65, 83,
+ 128, 76, 79, 79, 128, 76, 87, 65, 128, 77, 69, 78, 128, 77, 87, 69, 128,
+ 77, 87, 73, 128, 78, 65, 65, 128, 78, 89, 73, 211, 80, 65, 82, 128, 80,
+ 69, 72, 128, 80, 72, 79, 128, 80, 87, 69, 128, 80, 87, 73, 128, 81, 65,
+ 65, 128, 81, 65, 82, 128, 82, 65, 69, 128, 82, 72, 65, 128, 83, 72, 79,
+ 197, 83, 72, 85, 128, 83, 83, 73, 128, 83, 83, 79, 128, 83, 83, 85, 128,
+ 84, 72, 65, 204, 84, 79, 79, 128, 84, 87, 69, 128, 86, 69, 69, 128, 86,
+ 73, 78, 128, 87, 65, 69, 128, 87, 65, 76, 203, 87, 69, 79, 128, 88, 65,
+ 78, 128, 88, 69, 72, 128, 89, 65, 75, 128, 89, 65, 84, 128, 89, 89, 65,
+ 128, 90, 69, 78, 128, 65, 76, 76, 201, 65, 89, 66, 128, 65, 90, 85, 128,
+ 66, 65, 65, 128, 66, 69, 72, 128, 66, 69, 78, 128, 66, 79, 76, 212, 66,
+ 87, 65, 128, 67, 73, 80, 128, 67, 76, 85, 194, 67, 79, 79, 128, 67, 85,
+ 80, 128, 67, 87, 69, 128, 67, 87, 73, 128, 67, 87, 79, 128, 67, 89, 80,
+ 128, 67, 89, 84, 128, 68, 68, 65, 204, 68, 68, 69, 128, 68, 68, 73, 128,
+ 68, 68, 85, 128, 68, 69, 73, 128, 68, 74, 65, 128, 68, 76, 65, 128, 68,
+ 79, 71, 128, 68, 82, 85, 205, 69, 87, 69, 128, 70, 65, 65, 128, 70, 69,
+ 69, 128, 70, 69, 73, 128, 70, 76, 89, 128, 70, 85, 82, 128, 70, 85, 83,
+ 193, 70, 87, 65, 128, 71, 65, 89, 128, 71, 71, 65, 128, 71, 71, 69, 128,
+ 71, 71, 73, 128, 71, 71, 79, 128, 71, 71, 85, 128, 71, 72, 79, 128, 71,
+ 73, 77, 128, 71, 74, 69, 128, 72, 65, 82, 196, 72, 77, 79, 128, 72, 78,
+ 65, 128, 73, 83, 79, 206, 74, 74, 73, 128, 74, 74, 79, 128, 74, 74, 85,
+ 128, 74, 74, 89, 128, 75, 65, 73, 128, 75, 69, 78, 128, 75, 72, 69, 128,
+ 75, 73, 84, 128, 75, 74, 69, 128, 75, 75, 65, 128, 75, 79, 79, 128, 75,
+ 86, 65, 128, 75, 87, 79, 128, 76, 65, 65, 128, 76, 87, 69, 128, 76, 87,
+ 73, 128, 76, 87, 79, 128, 77, 65, 65, 128, 77, 79, 79, 128, 77, 79, 79,
+ 206, 77, 80, 65, 128, 77, 87, 79, 128, 78, 69, 69, 128, 78, 71, 65, 211,
+ 78, 73, 66, 128, 78, 79, 79, 128, 78, 82, 65, 128, 78, 87, 69, 128, 78,
+ 89, 85, 128, 79, 72, 77, 128, 79, 73, 76, 128, 79, 75, 84, 207, 79, 78,
+ 78, 128, 79, 84, 85, 128, 80, 65, 65, 128, 80, 65, 82, 212, 80, 65, 84,
+ 200, 80, 72, 85, 210, 80, 79, 76, 201, 80, 79, 79, 128, 80, 85, 84, 128,
+ 80, 87, 79, 128, 80, 89, 84, 128, 81, 65, 73, 128, 81, 73, 73, 128, 81,
+ 79, 84, 128, 81, 85, 79, 128, 81, 85, 85, 128, 82, 71, 89, 193, 82, 78,
+ 65, 205, 82, 82, 69, 200, 82, 82, 79, 128, 83, 69, 72, 128, 83, 72, 65,
+ 196, 83, 72, 79, 199, 83, 72, 89, 128, 83, 73, 79, 211, 83, 74, 69, 128,
+ 83, 79, 79, 128, 83, 79, 85, 128, 83, 83, 69, 128, 83, 87, 69, 128, 83,
+ 87, 73, 128, 83, 87, 79, 128, 84, 65, 71, 128, 84, 65, 84, 128, 84, 65,
+ 86, 128, 84, 69, 84, 128, 84, 74, 69, 128, 84, 76, 65, 128, 84, 76, 73,
+ 128, 84, 76, 85, 128, 84, 79, 84, 128, 84, 82, 69, 197, 84, 84, 73, 128,
+ 84, 87, 73, 128, 85, 83, 69, 196, 86, 65, 86, 128, 86, 69, 80, 128, 86,
+ 69, 82, 217, 86, 69, 87, 128, 86, 79, 85, 128, 86, 85, 82, 128, 87, 65,
+ 85, 128, 88, 86, 65, 128, 89, 65, 74, 128, 89, 65, 81, 128, 89, 65, 90,
+ 128, 89, 69, 65, 210, 89, 69, 82, 213, 89, 70, 69, 206, 89, 79, 79, 128,
+ 89, 87, 69, 128, 89, 87, 73, 128, 89, 87, 79, 128, 90, 72, 73, 128, 90,
+ 72, 79, 128, 90, 72, 85, 128, 90, 79, 84, 128, 90, 90, 65, 128, 90, 90,
+ 69, 128, 90, 90, 73, 128, 90, 90, 85, 128, 65, 65, 89, 128, 65, 68, 65,
+ 203, 65, 77, 66, 193, 65, 82, 67, 200, 65, 84, 79, 205, 65, 85, 69, 128,
+ 65, 87, 69, 128, 65, 88, 69, 128, 65, 89, 69, 210, 66, 48, 48, 177, 66,
+ 48, 48, 178, 66, 48, 48, 179, 66, 48, 48, 180, 66, 48, 48, 181, 66, 48,
+ 48, 182, 66, 48, 48, 183, 66, 48, 48, 184, 66, 48, 48, 185, 66, 48, 49,
+ 176, 66, 48, 49, 177, 66, 48, 49, 178, 66, 48, 49, 179, 66, 48, 49, 180,
+ 66, 48, 49, 181, 66, 48, 49, 182, 66, 48, 49, 183, 66, 48, 50, 176, 66,
+ 48, 50, 177, 66, 48, 50, 179, 66, 48, 50, 180, 66, 48, 50, 181, 66, 48,
+ 50, 182, 66, 48, 50, 183, 66, 48, 50, 184, 66, 48, 50, 185, 66, 48, 51,
+ 176, 66, 48, 51, 177, 66, 48, 51, 178, 66, 48, 51, 179, 66, 48, 51, 182,
+ 66, 48, 51, 183, 66, 48, 51, 184, 66, 48, 51, 185, 66, 48, 52, 176, 66,
+ 48, 52, 177, 66, 48, 52, 178, 66, 48, 52, 179, 66, 48, 52, 180, 66, 48,
+ 52, 181, 66, 48, 52, 182, 66, 48, 52, 184, 66, 48, 53, 176, 66, 48, 53,
+ 177, 66, 48, 53, 178, 66, 48, 53, 179, 66, 48, 53, 180, 66, 48, 53, 181,
+ 66, 48, 53, 183, 66, 48, 53, 184, 66, 48, 53, 185, 66, 48, 54, 176, 66,
+ 48, 54, 177, 66, 48, 54, 178, 66, 48, 54, 181, 66, 48, 54, 182, 66, 48,
+ 54, 183, 66, 48, 54, 184, 66, 48, 54, 185, 66, 48, 55, 176, 66, 48, 55,
+ 177, 66, 48, 55, 178, 66, 48, 55, 179, 66, 48, 55, 180, 66, 48, 55, 181,
+ 66, 48, 55, 182, 66, 48, 55, 183, 66, 48, 55, 184, 66, 48, 56, 176, 66,
+ 48, 56, 177, 66, 48, 56, 181, 66, 48, 56, 183, 66, 48, 57, 176, 66, 48,
+ 57, 177, 66, 49, 48, 176, 66, 49, 48, 178, 66, 49, 48, 180, 66, 49, 48,
+ 181, 66, 49, 50, 176, 66, 49, 50, 177, 66, 49, 50, 178, 66, 49, 50, 179,
+ 66, 49, 50, 181, 66, 49, 50, 183, 66, 49, 50, 184, 66, 49, 51, 176, 66,
+ 49, 51, 177, 66, 49, 51, 179, 66, 49, 51, 181, 66, 49, 52, 176, 66, 49,
+ 52, 177, 66, 49, 52, 181, 66, 49, 53, 177, 66, 49, 53, 182, 66, 49, 53,
+ 185, 66, 49, 54, 178, 66, 49, 54, 179, 66, 49, 55, 179, 66, 49, 55, 182,
+ 66, 49, 57, 177, 66, 50, 50, 176, 66, 50, 50, 181, 66, 50, 51, 176, 66,
+ 50, 51, 177, 66, 50, 51, 179, 66, 50, 52, 176, 66, 50, 52, 177, 66, 50,
+ 52, 178, 66, 50, 52, 179, 66, 50, 52, 183, 66, 50, 53, 180, 66, 65, 78,
+ 203, 66, 66, 65, 128, 66, 66, 69, 128, 66, 66, 73, 128, 66, 66, 79, 128,
+ 66, 66, 85, 128, 66, 66, 89, 128, 66, 67, 65, 196, 66, 69, 76, 204, 66,
+ 69, 76, 212, 66, 69, 84, 128, 66, 69, 84, 193, 66, 72, 79, 128, 66, 73,
+ 66, 128, 66, 73, 71, 128, 66, 75, 65, 173, 66, 79, 65, 128, 66, 87, 69,
+ 128, 66, 87, 73, 128, 66, 88, 71, 128, 67, 65, 68, 193, 67, 65, 78, 199,
+ 67, 65, 82, 197, 67, 65, 84, 128, 67, 65, 88, 128, 67, 67, 65, 128, 67,
+ 67, 69, 128, 67, 67, 73, 128, 67, 67, 79, 128, 67, 67, 85, 128, 67, 69,
+ 68, 201, 67, 69, 78, 128, 67, 69, 80, 128, 67, 69, 88, 128, 67, 72, 65,
+ 196, 67, 72, 69, 206, 67, 73, 69, 128, 67, 73, 73, 128, 67, 73, 84, 128,
+ 67, 73, 88, 128, 67, 79, 65, 128, 67, 79, 80, 128, 67, 79, 84, 128, 67,
+ 79, 88, 128, 67, 85, 66, 197, 67, 85, 79, 128, 67, 85, 82, 128, 67, 85,
+ 84, 128, 67, 85, 88, 128, 67, 89, 65, 128, 67, 89, 82, 128, 67, 89, 88,
+ 128, 68, 65, 68, 128, 68, 65, 69, 199, 68, 65, 77, 208, 68, 65, 82, 203,
+ 68, 65, 84, 197, 68, 69, 75, 128, 68, 69, 90, 200, 68, 76, 73, 128, 68,
+ 76, 79, 128, 68, 76, 85, 128, 68, 82, 73, 204, 68, 82, 89, 128, 68, 85,
+ 76, 128, 68, 87, 69, 128, 68, 87, 79, 128, 68, 89, 79, 128, 68, 90, 73,
+ 128, 68, 90, 79, 128, 68, 90, 85, 128, 69, 71, 71, 128, 69, 73, 83, 128,
+ 69, 75, 83, 128, 69, 78, 78, 128, 69, 78, 79, 211, 69, 79, 72, 128, 69,
+ 82, 71, 128, 69, 82, 82, 128, 69, 85, 82, 207, 69, 88, 79, 128, 70, 65,
+ 78, 128, 70, 65, 80, 128, 70, 65, 88, 128, 70, 69, 69, 196, 70, 69, 72,
+ 213, 70, 69, 78, 199, 70, 69, 79, 200, 70, 70, 73, 128, 70, 70, 76, 128,
+ 70, 73, 73, 128, 70, 73, 76, 197, 70, 73, 76, 204, 70, 73, 80, 128, 70,
+ 73, 84, 128, 70, 73, 88, 128, 70, 79, 79, 128, 70, 79, 80, 128, 70, 79,
+ 88, 128, 70, 85, 80, 128, 70, 85, 84, 128, 70, 85, 88, 128, 70, 87, 69,
+ 128, 70, 87, 73, 128, 70, 89, 65, 128, 70, 89, 80, 128, 70, 89, 84, 128,
+ 70, 89, 88, 128, 71, 65, 70, 128, 71, 65, 71, 128, 71, 65, 76, 128, 71,
+ 65, 82, 128, 71, 67, 65, 206, 71, 69, 66, 207, 71, 69, 84, 193, 71, 72,
+ 73, 128, 71, 72, 85, 128, 71, 72, 90, 128, 71, 73, 80, 128, 71, 79, 65,
+ 128, 71, 80, 65, 128, 71, 83, 85, 205, 71, 89, 65, 128, 71, 89, 69, 128,
+ 71, 89, 70, 213, 71, 89, 73, 128, 71, 89, 79, 128, 71, 89, 85, 128, 72,
+ 69, 76, 205, 72, 69, 78, 199, 72, 72, 69, 128, 72, 72, 73, 128, 72, 72,
+ 79, 128, 72, 72, 85, 128, 72, 76, 65, 128, 72, 76, 69, 128, 72, 76, 73,
+ 128, 72, 76, 79, 128, 72, 76, 85, 128, 72, 76, 89, 128, 72, 77, 73, 128,
+ 72, 77, 85, 128, 72, 77, 89, 128, 72, 78, 69, 128, 72, 78, 73, 128, 72,
+ 80, 65, 128, 72, 87, 85, 128, 72, 88, 65, 128, 72, 88, 69, 128, 72, 88,
+ 73, 128, 72, 88, 79, 128, 72, 90, 71, 128, 72, 90, 84, 128, 72, 90, 87,
+ 128, 72, 90, 90, 128, 73, 45, 65, 128, 73, 45, 79, 128, 73, 79, 82, 128,
+ 74, 65, 65, 128, 74, 65, 82, 128, 74, 69, 72, 128, 74, 69, 82, 128, 74,
+ 72, 79, 128, 74, 73, 65, 128, 74, 74, 65, 128, 74, 74, 69, 128, 74, 79,
+ 65, 128, 74, 79, 89, 128, 74, 87, 65, 128, 75, 65, 72, 128, 75, 65, 80,
+ 128, 75, 65, 85, 206, 75, 65, 88, 128, 75, 69, 80, 128, 75, 69, 88, 128,
+ 75, 69, 89, 128, 75, 72, 90, 128, 75, 73, 69, 128, 75, 73, 72, 128, 75,
+ 73, 73, 128, 75, 73, 80, 128, 75, 73, 88, 128, 75, 75, 69, 128, 75, 75,
+ 73, 128, 75, 75, 79, 128, 75, 75, 85, 128, 75, 79, 65, 128, 75, 79, 72,
+ 128, 75, 79, 80, 128, 75, 79, 84, 128, 75, 79, 88, 128, 75, 80, 65, 128,
+ 75, 82, 65, 128, 75, 85, 79, 128, 75, 85, 80, 128, 75, 85, 82, 128, 75,
+ 85, 84, 128, 75, 85, 88, 128, 75, 88, 65, 128, 75, 88, 69, 128, 75, 88,
+ 73, 128, 75, 88, 79, 128, 75, 88, 85, 128, 75, 89, 65, 128, 75, 89, 69,
+ 128, 75, 89, 73, 128, 75, 89, 79, 128, 75, 89, 85, 128, 76, 65, 69, 128,
+ 76, 65, 71, 213, 76, 65, 83, 212, 76, 65, 90, 217, 76, 69, 79, 128, 76,
+ 72, 65, 199, 76, 73, 68, 128, 76, 73, 73, 128, 76, 73, 78, 203, 76, 73,
+ 82, 193, 76, 79, 65, 128, 76, 79, 71, 128, 76, 79, 71, 210, 76, 79, 84,
+ 128, 76, 89, 89, 128, 77, 65, 83, 213, 77, 65, 89, 128, 77, 67, 72, 213,
+ 77, 68, 85, 206, 77, 69, 84, 193, 77, 69, 88, 128, 77, 71, 65, 128, 77,
+ 71, 69, 128, 77, 71, 85, 128, 77, 72, 90, 128, 77, 73, 73, 128, 77, 73,
+ 76, 128, 77, 73, 76, 204, 77, 73, 77, 128, 77, 79, 65, 128, 77, 79, 76,
+ 128, 77, 89, 65, 128, 77, 89, 84, 128, 78, 65, 71, 128, 78, 65, 79, 211,
+ 78, 66, 65, 128, 78, 66, 73, 128, 78, 66, 79, 128, 78, 66, 85, 128, 78,
+ 66, 89, 128, 78, 68, 69, 128, 78, 69, 78, 128, 78, 69, 84, 128, 78, 69,
+ 88, 212, 78, 71, 71, 128, 78, 74, 73, 128, 78, 74, 79, 128, 78, 74, 85,
+ 128, 78, 74, 89, 128, 78, 78, 71, 128, 78, 78, 79, 128, 78, 79, 65, 128,
+ 78, 82, 69, 128, 78, 82, 79, 128, 78, 82, 85, 128, 78, 82, 89, 128, 78,
+ 85, 76, 204, 78, 85, 80, 128, 78, 85, 82, 128, 78, 85, 88, 128, 78, 89,
+ 69, 128, 78, 90, 65, 128, 78, 90, 73, 128, 78, 90, 85, 128, 78, 90, 89,
+ 128, 79, 45, 69, 128, 79, 65, 75, 128, 79, 65, 89, 128, 79, 66, 79, 204,
+ 80, 65, 80, 128, 80, 65, 84, 128, 80, 65, 88, 128, 80, 72, 85, 128, 80,
+ 73, 69, 128, 80, 73, 71, 128, 80, 73, 80, 128, 80, 73, 84, 128, 80, 73,
+ 88, 128, 80, 76, 65, 128, 80, 79, 65, 128, 80, 79, 80, 128, 80, 79, 88,
+ 128, 80, 80, 77, 128, 80, 85, 50, 128, 80, 85, 79, 128, 80, 85, 80, 128,
+ 80, 85, 82, 128, 80, 85, 88, 128, 80, 89, 80, 128, 80, 89, 82, 128, 80,
+ 89, 88, 128, 81, 65, 76, 193, 81, 65, 81, 128, 81, 65, 85, 128, 81, 69,
+ 69, 128, 81, 72, 65, 128, 81, 72, 69, 128, 81, 72, 73, 128, 81, 72, 79,
+ 128, 81, 72, 85, 128, 81, 73, 69, 128, 81, 73, 80, 128, 81, 73, 84, 128,
+ 81, 73, 88, 128, 81, 79, 65, 128, 81, 79, 70, 128, 81, 79, 79, 128, 81,
+ 79, 80, 128, 81, 79, 88, 128, 81, 85, 65, 128, 81, 85, 69, 128, 81, 85,
+ 73, 128, 81, 85, 75, 128, 81, 85, 80, 128, 81, 85, 82, 128, 81, 85, 84,
+ 128, 81, 85, 86, 128, 81, 85, 88, 128, 81, 87, 65, 128, 81, 87, 69, 128,
+ 81, 87, 73, 128, 81, 89, 65, 128, 81, 89, 69, 128, 81, 89, 73, 128, 81,
+ 89, 79, 128, 81, 89, 80, 128, 81, 89, 82, 128, 81, 89, 84, 128, 81, 89,
+ 85, 128, 81, 89, 88, 128, 82, 65, 50, 128, 82, 65, 51, 128, 82, 65, 68,
+ 128, 82, 65, 68, 201, 82, 65, 73, 206, 82, 65, 77, 211, 82, 69, 73, 196,
+ 82, 73, 80, 128, 82, 74, 69, 128, 82, 74, 69, 211, 82, 79, 65, 128, 82,
+ 79, 79, 128, 82, 82, 69, 128, 82, 82, 85, 128, 82, 82, 89, 128, 82, 85,
+ 65, 128, 82, 85, 78, 128, 82, 87, 65, 128, 82, 89, 65, 128, 82, 89, 89,
+ 128, 83, 45, 87, 128, 83, 65, 68, 128, 83, 65, 89, 128, 83, 66, 85, 194,
+ 83, 71, 65, 194, 83, 71, 79, 210, 83, 71, 82, 193, 83, 73, 73, 128, 83,
+ 73, 78, 197, 83, 75, 87, 128, 83, 78, 65, 208, 83, 79, 65, 128, 83, 79,
+ 87, 128, 83, 83, 89, 128, 83, 85, 65, 128, 83, 85, 79, 128, 83, 85, 82,
+ 128, 83, 90, 65, 128, 83, 90, 69, 128, 83, 90, 73, 128, 83, 90, 79, 128,
+ 83, 90, 85, 128, 84, 65, 50, 128, 84, 65, 79, 128, 84, 65, 80, 128, 84,
+ 65, 80, 197, 84, 65, 87, 128, 84, 65, 88, 128, 84, 69, 83, 200, 84, 69,
+ 84, 200, 84, 69, 88, 128, 84, 72, 69, 211, 84, 72, 73, 206, 84, 72, 90,
+ 128, 84, 73, 73, 128, 84, 73, 80, 128, 84, 73, 84, 128, 84, 73, 88, 128,
+ 84, 76, 86, 128, 84, 79, 65, 128, 84, 79, 88, 128, 84, 82, 73, 128, 84,
+ 83, 86, 128, 84, 84, 72, 128, 84, 84, 85, 128, 84, 85, 79, 128, 84, 85,
+ 80, 128, 84, 85, 82, 128, 84, 85, 84, 128, 84, 85, 88, 128, 84, 89, 65,
+ 128, 84, 89, 69, 128, 84, 89, 73, 128, 84, 89, 79, 128, 84, 90, 65, 128,
+ 84, 90, 69, 128, 84, 90, 73, 128, 84, 90, 79, 128, 84, 90, 85, 128, 85,
+ 69, 69, 128, 85, 69, 89, 128, 85, 78, 68, 207, 85, 78, 73, 212, 85, 82,
+ 85, 218, 86, 65, 65, 128, 86, 65, 80, 128, 86, 65, 84, 128, 86, 65, 88,
+ 128, 86, 69, 72, 128, 86, 69, 88, 128, 86, 73, 69, 128, 86, 73, 80, 128,
+ 86, 73, 84, 128, 86, 73, 88, 128, 86, 79, 73, 196, 86, 79, 80, 128, 86,
+ 79, 84, 128, 86, 79, 87, 128, 86, 79, 88, 128, 86, 85, 80, 128, 86, 85,
+ 84, 128, 86, 85, 88, 128, 86, 87, 65, 128, 86, 89, 80, 128, 86, 89, 82,
+ 128, 86, 89, 84, 128, 86, 89, 88, 128, 87, 65, 80, 128, 87, 65, 84, 128,
+ 87, 65, 88, 128, 87, 69, 80, 128, 87, 69, 88, 128, 87, 79, 65, 128, 87,
+ 79, 69, 128, 87, 79, 80, 128, 87, 79, 82, 203, 87, 79, 88, 128, 87, 85,
+ 79, 128, 87, 89, 78, 206, 88, 79, 65, 128, 88, 79, 82, 128, 88, 89, 65,
+ 128, 88, 89, 69, 128, 88, 89, 73, 128, 88, 89, 79, 128, 88, 89, 80, 128,
+ 88, 89, 82, 128, 88, 89, 84, 128, 88, 89, 85, 128, 88, 89, 88, 128, 89,
+ 65, 66, 128, 89, 65, 68, 128, 89, 65, 70, 128, 89, 65, 71, 128, 89, 65,
+ 77, 128, 89, 65, 80, 128, 89, 65, 82, 128, 89, 65, 86, 128, 89, 65, 87,
+ 128, 89, 65, 89, 128, 89, 69, 65, 128, 89, 69, 87, 128, 89, 69, 89, 128,
+ 89, 73, 73, 128, 89, 85, 68, 200, 89, 85, 82, 128, 89, 89, 80, 128, 89,
+ 89, 82, 128, 89, 89, 84, 128, 89, 89, 88, 128, 90, 65, 72, 128, 90, 72,
+ 89, 128, 90, 76, 65, 128, 90, 79, 79, 128, 90, 82, 65, 128, 90, 85, 84,
+ 128, 90, 90, 89, 128, 75, 65, 198, 66, 69, 200, 68, 65, 217, 84, 72, 197,
+ 70, 69, 200, 68, 65, 196, 83, 65, 196, 69, 78, 196, 81, 65, 198, 84, 65,
+ 200, 65, 82, 195, 78, 79, 210, 76, 69, 203, 77, 65, 201, 79, 67, 210, 66,
+ 73, 199, 82, 72, 207, 84, 69, 206, 87, 65, 215, 89, 73, 199, 67, 72, 197,
+ 77, 71, 207, 65, 82, 205, 66, 85, 212, 67, 85, 205, 71, 72, 197, 78, 69,
+ 207, 80, 85, 128, 84, 73, 208, 71, 65, 198, 75, 72, 207, 90, 65, 200, 68,
+ 73, 197, 80, 72, 201, 90, 72, 197, 80, 72, 207, 81, 73, 128, 81, 85, 128,
+ 83, 73, 216, 67, 72, 207, 77, 69, 206, 77, 73, 196, 78, 69, 212, 80, 69,
+ 200, 81, 79, 128, 86, 69, 200, 89, 79, 196, 66, 65, 199, 66, 69, 212, 68,
+ 89, 207, 70, 79, 128, 72, 65, 193, 75, 65, 201, 78, 65, 199, 81, 69, 128,
+ 82, 65, 196, 83, 73, 206, 86, 65, 214, 45, 85, 205, 67, 72, 201, 68, 65,
+ 208, 68, 85, 204, 68, 90, 128, 69, 88, 207, 71, 82, 213, 71, 85, 199, 72,
+ 79, 212, 72, 80, 128, 72, 86, 128, 73, 74, 128, 73, 85, 128, 73, 89, 128,
+ 74, 69, 200, 74, 79, 212, 75, 69, 217, 75, 71, 128, 75, 75, 128, 76, 74,
+ 128, 77, 73, 199, 78, 74, 128, 78, 85, 206, 78, 86, 128, 78, 89, 201, 79,
+ 72, 205, 80, 65, 215, 81, 79, 207, 82, 68, 207, 83, 85, 206, 83, 87, 128,
+ 87, 79, 206, 89, 69, 206, 89, 85, 211, 65, 78, 207, 66, 69, 206, 66, 79,
+ 215, 66, 81, 128, 67, 77, 128, 67, 85, 212, 68, 76, 128, 68, 77, 128, 68,
+ 82, 217, 68, 86, 128, 69, 67, 200, 70, 77, 128, 70, 89, 128, 71, 66, 128,
+ 71, 86, 128, 71, 89, 128, 72, 71, 128, 72, 75, 128, 73, 83, 211, 75, 66,
+ 128, 75, 73, 208, 75, 76, 128, 75, 77, 128, 75, 84, 128, 75, 86, 128, 76,
+ 65, 215, 76, 67, 197, 76, 67, 201, 76, 72, 128, 76, 78, 128, 76, 88, 128,
+ 77, 66, 128, 77, 69, 205, 77, 71, 128, 77, 72, 128, 77, 76, 128, 77, 77,
+ 128, 77, 83, 128, 77, 86, 128, 77, 87, 128, 78, 65, 193, 78, 70, 128, 78,
+ 71, 207, 78, 72, 128, 78, 77, 128, 78, 87, 128, 78, 89, 196, 79, 86, 128,
+ 80, 67, 128, 80, 69, 211, 80, 70, 128, 80, 79, 208, 80, 82, 128, 80, 86,
+ 128, 80, 87, 128, 81, 79, 198, 81, 89, 128, 82, 73, 206, 82, 74, 197, 82,
+ 85, 194, 83, 78, 193, 83, 79, 198, 83, 82, 128, 84, 65, 213, 84, 65, 214,
+ 84, 69, 197, 84, 69, 212, 84, 73, 210, 84, 82, 128, 86, 69, 197, 86, 69,
+ 215, 87, 66, 128, 87, 86, 128, 88, 89, 128, 89, 65, 210, 89, 86, 128, 90,
+ 76, 193, 66, 217, 77, 213, 65, 197, 89, 213, 68, 218, 90, 197, 75, 205,
+ 67, 205, 68, 205, 75, 213, 77, 205, 68, 194, 76, 218, 77, 194, 77, 207,
+ 77, 214, 77, 215, 80, 207, 81, 208, 84, 195, 202, 209,
+};
+
+static unsigned short lexicon_offset[] = {
+ 0, 0, 6, 10, 15, 23, 30, 32, 35, 40, 53, 65, 71, 77, 82, 90, 99, 103,
+ 108, 116, 119, 126, 130, 138, 144, 150, 157, 162, 172, 175, 182, 187,
+ 193, 201, 206, 215, 222, 229, 238, 243, 251, 255, 256, 264, 270, 276,
+ 282, 288, 295, 301, 309, 318, 322, 327, 330, 337, 344, 350, 353, 362,
+ 370, 375, 381, 387, 392, 397, 402, 405, 407, 413, 418, 426, 299, 428,
+ 430, 439, 100, 447, 457, 465, 467, 478, 481, 494, 498, 504, 514, 519,
+ 522, 524, 533, 538, 545, 549, 556, 559, 564, 569, 572, 582, 591, 599,
+ 606, 614, 618, 626, 634, 643, 647, 654, 662, 671, 675, 683, 689, 698,
+ 705, 708, 709, 714, 719, 728, 735, 738, 745, 751, 755, 763, 173, 767,
+ 773, 782, 750, 789, 263, 797, 803, 808, 812, 825, 834, 839, 842, 852,
+ 753, 857, 866, 875, 877, 882, 887, 894, 904, 907, 909, 913, 921, 22, 929,
+ 933, 938, 947, 543, 950, 960, 964, 971, 977, 983, 988, 994, 997, 1000,
+ 80, 1007, 1015, 1025, 1030, 1035, 1042, 1044, 1054, 779, 1058, 1062,
+ 1069, 1074, 1081, 1085, 1089, 1094, 1104, 1110, 1023, 1112, 1117, 1123,
+ 325, 1130, 1134, 1140, 1144, 1147, 1152, 1158, 1163, 1083, 1169, 1176,
+ 1181, 1183, 1185, 1190, 1195, 624, 1204, 1210, 1213, 1215, 1221, 31,
+ 1224, 1226, 1179, 1229, 1237, 1243, 1250, 1274, 1296, 1318, 1340, 1361,
+ 1382, 1402, 1422, 1441, 1460, 1479, 1498, 1517, 1536, 1555, 1574, 1592,
+ 1610, 1628, 1646, 1664, 1682, 1700, 1718, 1736, 1754, 1772, 1789, 1806,
+ 1823, 1840, 1857, 1874, 1891, 1908, 1925, 1942, 1959, 1975, 1991, 2007,
+ 2023, 2039, 2055, 2071, 2087, 2103, 2119, 2135, 2151, 2167, 2183, 2199,
+ 2215, 2231, 2247, 2263, 2279, 2295, 2311, 2327, 2343, 2359, 2375, 2391,
+ 2407, 2423, 2439, 2455, 2471, 2487, 2503, 2519, 2535, 2551, 2567, 2583,
+ 2599, 2615, 2631, 2647, 2663, 2679, 2695, 2711, 2727, 2743, 2759, 2775,
+ 2791, 2807, 2823, 2839, 2855, 2871, 2887, 2903, 2919, 2935, 2951, 2967,
+ 2983, 2999, 3015, 3031, 3047, 3063, 3079, 3095, 3111, 3127, 3143, 3159,
+ 3175, 3191, 3207, 3223, 3239, 3255, 3271, 3287, 3303, 3319, 3335, 3351,
+ 3367, 3383, 3399, 3415, 3431, 3447, 3463, 3479, 3495, 3511, 3527, 3543,
+ 3559, 3575, 3591, 3607, 3623, 3639, 3655, 3671, 3687, 3703, 3719, 3735,
+ 3751, 3767, 3783, 3799, 3815, 3831, 3847, 3863, 3879, 3895, 3911, 3927,
+ 3943, 3959, 3975, 3991, 4007, 4023, 4039, 4055, 4071, 4087, 4103, 4119,
+ 4135, 4151, 4167, 4183, 4199, 4215, 4231, 4247, 4263, 4279, 4295, 4311,
+ 4327, 4343, 4359, 4375, 4391, 4407, 4423, 4439, 4455, 4471, 4487, 4503,
+ 4519, 4535, 4551, 4567, 4583, 4599, 4615, 4631, 4647, 4663, 4679, 4695,
+ 4711, 4727, 4743, 4759, 4775, 4791, 4807, 4823, 4839, 4855, 4871, 4887,
+ 4903, 4919, 4935, 4951, 4967, 4983, 4999, 5015, 5031, 5047, 5063, 5079,
+ 5095, 5111, 5127, 5143, 5159, 5175, 5191, 5207, 5223, 5239, 5255, 5271,
+ 5287, 5303, 5319, 5335, 5351, 5367, 5383, 5399, 5415, 5431, 5447, 5463,
+ 5479, 5495, 5511, 5527, 5543, 5559, 5575, 5591, 5607, 5623, 5639, 5655,
+ 5671, 5687, 5703, 5719, 5735, 5751, 5767, 5783, 5799, 5815, 5831, 5847,
+ 5863, 5879, 5895, 5911, 5927, 5943, 5959, 5975, 5991, 6007, 6023, 6039,
+ 6055, 6071, 6087, 6103, 6119, 6135, 6151, 6167, 6183, 6199, 6215, 6231,
+ 6247, 6263, 6279, 6295, 6311, 6327, 6343, 6359, 6375, 6391, 6407, 6423,
+ 6439, 6455, 6471, 6487, 6503, 6519, 6535, 6551, 6567, 6583, 6599, 6615,
+ 6631, 6647, 6663, 6679, 6695, 6711, 6727, 6743, 6759, 6775, 6791, 6807,
+ 6823, 6839, 6855, 6871, 6887, 6903, 6919, 6935, 6951, 6967, 6983, 6999,
+ 7015, 7031, 7047, 7063, 7079, 7095, 7111, 7127, 7143, 7159, 7175, 7191,
+ 7207, 7223, 7239, 7255, 7271, 7287, 7303, 7319, 7335, 7351, 7367, 7383,
+ 7399, 7415, 7431, 7447, 7463, 7479, 7495, 7511, 7527, 7543, 7559, 7575,
+ 7591, 7607, 7623, 7639, 7655, 7671, 7687, 7703, 7719, 7735, 7751, 7767,
+ 7783, 7799, 7815, 7831, 7847, 7863, 7879, 7895, 7911, 7927, 7943, 7959,
+ 7975, 7991, 8007, 8023, 8039, 8055, 8071, 8087, 8103, 8119, 8135, 8151,
+ 8167, 8183, 8199, 8215, 8231, 8247, 8263, 8279, 8295, 8311, 8327, 8343,
+ 8359, 8375, 8391, 8407, 8423, 8439, 8455, 8471, 8487, 8503, 8519, 8535,
+ 8551, 8567, 8583, 8599, 8615, 8631, 8647, 8663, 8679, 8695, 8711, 8727,
+ 8743, 8759, 8775, 8791, 8807, 8823, 8839, 8855, 8871, 8887, 8903, 8919,
+ 8935, 8951, 8967, 8983, 8999, 9015, 9031, 9047, 9063, 9079, 9095, 9111,
+ 9127, 9143, 9159, 9175, 9191, 9207, 9223, 9239, 9255, 9271, 9287, 9303,
+ 9319, 9335, 9351, 9367, 9383, 9399, 9415, 9431, 9447, 9463, 9479, 9495,
+ 9511, 9527, 9543, 9559, 9575, 9591, 9607, 9623, 9639, 9655, 9671, 9687,
+ 9703, 9719, 9735, 9751, 9767, 9783, 9799, 9815, 9831, 9847, 9863, 9879,
+ 9895, 9911, 9927, 9943, 9959, 9975, 9991, 10007, 10023, 10039, 10055,
+ 10071, 10087, 10103, 10119, 10135, 10151, 10167, 10183, 10199, 10215,
+ 10231, 10247, 10263, 10279, 10295, 10311, 10327, 10343, 10359, 10375,
+ 10391, 10407, 10423, 10439, 10455, 10471, 10487, 10503, 10519, 10535,
+ 10551, 10567, 10583, 10599, 10615, 10631, 10647, 10663, 10679, 10695,
+ 10711, 10727, 10743, 10759, 10775, 10791, 10807, 10823, 10839, 10855,
+ 10871, 10887, 10903, 10919, 10934, 10949, 10964, 10979, 10994, 11009,
+ 11024, 11039, 11054, 11069, 11084, 11099, 11114, 11129, 11144, 11159,
+ 11174, 11189, 11204, 11219, 11234, 11249, 11264, 11279, 11294, 11309,
+ 11324, 11339, 11354, 11369, 11384, 11399, 11414, 11429, 11444, 11459,
+ 11474, 11489, 11504, 11519, 11534, 11549, 11564, 11579, 11594, 11609,
+ 11624, 11639, 11654, 11669, 11684, 11699, 11714, 11729, 11744, 11759,
+ 11774, 11789, 11804, 11819, 11834, 11849, 11864, 11879, 11894, 11909,
+ 11924, 11939, 11954, 11969, 11984, 11999, 12014, 12029, 12044, 12059,
+ 12074, 12089, 12104, 12119, 12134, 12149, 12164, 12179, 12194, 12209,
+ 12224, 12239, 12254, 12269, 12284, 12299, 12314, 12329, 12344, 12359,
+ 12374, 12389, 12404, 12419, 12434, 12449, 12464, 12479, 12494, 12509,
+ 12524, 12539, 12554, 12569, 12584, 12599, 12614, 12629, 12644, 12659,
+ 12674, 12689, 12704, 12719, 12734, 12749, 12764, 12779, 12794, 12809,
+ 12824, 12839, 12854, 12869, 12884, 12899, 12914, 12929, 12944, 12959,
+ 12974, 12989, 13004, 13019, 13034, 13049, 13064, 13079, 13094, 13109,
+ 13124, 13139, 13154, 13169, 13184, 13199, 13214, 13229, 13244, 13259,
+ 13274, 13289, 13304, 13319, 13334, 13349, 13364, 13379, 13394, 13409,
+ 13424, 13439, 13454, 13469, 13484, 13499, 13514, 13529, 13544, 13559,
+ 13574, 13589, 13604, 13619, 13634, 13649, 13664, 13679, 13694, 13709,
+ 13724, 13739, 13754, 13769, 13784, 13799, 13814, 13829, 13844, 13859,
+ 13874, 13889, 13904, 13919, 13934, 13949, 13964, 13979, 13994, 14009,
+ 14024, 14039, 14054, 14069, 14084, 14099, 14114, 14129, 14144, 14159,
+ 14174, 14189, 14204, 14219, 14234, 14249, 14264, 14279, 14294, 14309,
+ 14324, 14339, 14354, 14369, 14384, 14399, 14414, 14429, 14444, 14459,
+ 14474, 14489, 14504, 14519, 14534, 14549, 14564, 14579, 14594, 14609,
+ 14624, 14639, 14654, 14669, 14684, 14699, 14714, 14729, 14744, 14759,
+ 14774, 14789, 14804, 14819, 14834, 14849, 14864, 14879, 14894, 14909,
+ 14924, 14939, 14954, 14969, 14984, 14999, 15014, 15029, 15044, 15059,
+ 15074, 15089, 15104, 15119, 15134, 15149, 15164, 15179, 15194, 15209,
+ 15224, 15239, 15254, 15269, 15284, 15299, 15314, 15329, 15344, 15359,
+ 15374, 15389, 15404, 15419, 15434, 15449, 15464, 15479, 15494, 15509,
+ 15524, 15539, 15554, 15569, 15584, 15599, 15614, 15629, 15644, 15659,
+ 15674, 15689, 15704, 15719, 15734, 15749, 15764, 15779, 15794, 15809,
+ 15824, 15839, 15854, 15869, 15884, 15899, 15914, 15929, 15944, 15959,
+ 15974, 15989, 16004, 16019, 16034, 16049, 16064, 16079, 16094, 16109,
+ 16124, 16139, 16154, 16169, 16184, 16199, 16214, 16229, 16244, 16259,
+ 16274, 16289, 16304, 16319, 16334, 16349, 16364, 16379, 16394, 16409,
+ 16424, 16439, 16454, 16469, 16484, 16499, 16514, 16529, 16544, 16559,
+ 16574, 16589, 16604, 16619, 16634, 16649, 16664, 16679, 16694, 16709,
+ 16724, 16739, 16754, 16769, 16784, 16799, 16814, 16829, 16844, 16859,
+ 16874, 16889, 16904, 16919, 16934, 16949, 16964, 16979, 16994, 17009,
+ 17024, 17039, 17054, 17069, 17084, 17099, 17114, 17129, 17144, 17159,
+ 17174, 17189, 17204, 17219, 17234, 17249, 17264, 17279, 17294, 17309,
+ 17324, 17339, 17354, 17369, 17384, 17399, 17414, 17429, 17444, 17459,
+ 17474, 17489, 17504, 17519, 17534, 17549, 17564, 17579, 17594, 17609,
+ 17624, 17639, 17654, 17669, 17684, 17699, 17714, 17729, 17744, 17759,
+ 17774, 17789, 17804, 17819, 17834, 17849, 17864, 17879, 17894, 17909,
+ 17924, 17939, 17954, 17969, 17984, 17999, 18014, 18029, 18044, 18059,
+ 18074, 18089, 18104, 18119, 18134, 18149, 18164, 18179, 18194, 18209,
+ 18224, 18239, 18254, 18269, 18283, 18297, 18311, 18325, 18339, 1408,
+ 18353, 18367, 18381, 18395, 18409, 18423, 18437, 18451, 18465, 18479,
+ 18493, 18507, 18521, 18535, 18549, 18563, 18577, 18591, 18605, 18619,
+ 18633, 18647, 18661, 18675, 18689, 18703, 1809, 18717, 18731, 18745,
+ 18759, 18773, 18787, 18801, 18815, 18829, 18843, 18857, 18871, 18885,
+ 18899, 18913, 18927, 18941, 18954, 18967, 18980, 18993, 19006, 19019,
+ 19032, 19045, 19058, 19071, 19084, 19097, 19110, 19123, 19136, 19149,
+ 19162, 19175, 19188, 19201, 19214, 19227, 19240, 1759, 19253, 19266,
+ 19279, 19292, 19305, 19318, 19331, 19344, 19357, 19370, 19383, 19396,
+ 19409, 19422, 19435, 19448, 19461, 19474, 19487, 19500, 19513, 19526,
+ 19539, 19552, 19565, 19578, 19591, 19604, 19617, 19630, 19643, 19656,
+ 19669, 19682, 19695, 19708, 19721, 1523, 19734, 19747, 19760, 19773,
+ 19786, 19799, 19812, 19825, 19838, 19851, 19864, 19877, 19890, 19903,
+ 19916, 19929, 19942, 19955, 19968, 19981, 19994, 20007, 20020, 20033,
+ 20046, 20059, 20072, 20085, 20098, 20111, 20124, 20137, 20150, 20163,
+ 20176, 20189, 20202, 20215, 20228, 20241, 20254, 20267, 20280, 20293,
+ 20306, 20319, 20332, 20345, 20358, 20371, 20384, 20397, 20410, 20423,
+ 20436, 20449, 20462, 20475, 20488, 20501, 20514, 20527, 20540, 20553,
+ 20566, 20579, 20592, 20605, 20618, 20631, 20644, 20657, 20670, 20683,
+ 20696, 20709, 20722, 20735, 20748, 20761, 20774, 20787, 20800, 20813,
+ 20826, 20839, 20852, 20865, 20878, 20891, 20904, 20917, 20930, 20943,
+ 20956, 20969, 20982, 20995, 21008, 21021, 21034, 21047, 21060, 21073,
+ 21086, 21099, 21112, 21125, 21138, 21151, 21164, 21177, 21190, 21203,
+ 21216, 21229, 21242, 21255, 21268, 21281, 21294, 21307, 21320, 21333,
+ 21346, 21359, 21372, 21385, 21398, 21411, 21424, 21437, 21450, 21463,
+ 21476, 21489, 21502, 21515, 21528, 21541, 21554, 21567, 21580, 21593,
+ 21606, 21619, 21632, 21645, 21658, 21671, 21684, 21697, 21710, 21723,
+ 21736, 21749, 21762, 21775, 21788, 21801, 21814, 21827, 21840, 21853,
+ 21866, 21879, 21892, 21905, 21918, 21931, 21944, 21957, 21970, 21983,
+ 21996, 22009, 22022, 22034, 22046, 22058, 22070, 22082, 22094, 22106,
+ 22118, 22130, 22142, 22154, 22166, 22178, 22190, 22202, 22214, 22226,
+ 22238, 1670, 22250, 22262, 22274, 1616, 22286, 22298, 22310, 22322,
+ 22334, 22346, 22358, 1505, 1598, 22370, 1634, 22382, 22394, 22406, 22418,
+ 22430, 22442, 22454, 22466, 22478, 22490, 22502, 22514, 22526, 22538,
+ 22550, 22562, 22574, 22586, 22598, 22610, 22622, 22634, 22646, 22658,
+ 22670, 22682, 22694, 22706, 22718, 22730, 22742, 22754, 22766, 22778,
+ 22790, 22802, 22814, 22826, 22838, 22850, 22862, 22874, 22886, 22898,
+ 22910, 22922, 22934, 22946, 22958, 22970, 22982, 22994, 23006, 23018,
+ 23030, 23042, 23054, 23066, 23078, 23090, 23102, 23114, 23126, 23138,
+ 23150, 23162, 23174, 23186, 23198, 23210, 23222, 23234, 23246, 23258,
+ 23270, 23282, 23294, 23306, 23318, 23330, 23342, 23354, 23366, 23378,
+ 23390, 23402, 23414, 1390, 23426, 23438, 23450, 1724, 23462, 23474,
+ 23486, 23498, 23510, 23522, 23534, 23546, 23558, 23570, 23582, 23594,
+ 23606, 23618, 23630, 23642, 23654, 23666, 23678, 23690, 23702, 23714,
+ 23726, 23738, 23750, 23762, 23774, 23786, 23798, 23810, 23822, 23834,
+ 23846, 23858, 23870, 23882, 23894, 23906, 23918, 23930, 23942, 23954,
+ 23966, 23978, 23990, 24002, 24014, 24026, 24038, 24050, 24062, 24074,
+ 24086, 24098, 24110, 24122, 24134, 24146, 24158, 24170, 24182, 24194,
+ 24206, 24218, 24230, 24242, 24254, 24266, 24278, 24290, 24302, 24314,
+ 24326, 24338, 24350, 24362, 24374, 24386, 24398, 24410, 24422, 24434,
+ 24446, 24458, 24470, 24482, 24494, 24506, 24518, 24530, 24542, 24554,
+ 24566, 24578, 24590, 24602, 24614, 24626, 24638, 24650, 24662, 24674,
+ 24686, 24698, 24710, 24722, 24734, 24746, 24758, 24770, 24781, 24792,
+ 24803, 24814, 24825, 24836, 24847, 24858, 24869, 24880, 24891, 24902,
+ 24913, 24924, 24935, 24946, 24957, 1795, 24968, 24979, 24990, 25001,
+ 25012, 25023, 25034, 25045, 25056, 1880, 1307, 25067, 1430, 25078, 25089,
+ 25100, 25111, 25122, 25133, 1897, 25144, 25155, 25166, 25177, 25188,
+ 25199, 25210, 25221, 25232, 25243, 25254, 25265, 25276, 25287, 1863,
+ 25298, 25309, 25320, 25331, 25342, 25353, 25364, 25375, 25386, 25397,
+ 25408, 25419, 25430, 25441, 25452, 25463, 25474, 25485, 25496, 25507,
+ 25518, 25529, 25540, 25551, 25562, 25573, 25584, 25595, 25606, 25617,
+ 25628, 25639, 25650, 25661, 25672, 25683, 25694, 25705, 25716, 25727,
+ 25738, 25749, 25760, 25771, 25782, 25793, 25804, 25815, 25826, 25837,
+ 25848, 25859, 25870, 25881, 25892, 25903, 25914, 25925, 25936, 25947,
+ 25958, 25969, 25980, 25991, 26002, 26013, 26024, 26035, 26046, 26057,
+ 26068, 26079, 26090, 26101, 26112, 26123, 26134, 26145, 26156, 26167,
+ 26178, 26189, 26200, 26211, 26222, 26233, 26244, 26255, 26266, 26277,
+ 26288, 26299, 26310, 26321, 26332, 26343, 26354, 26365, 26376, 26387,
+ 26398, 26409, 26420, 26431, 26442, 26453, 18580, 26464, 26475, 26486,
+ 26497, 26508, 26519, 26530, 26541, 26552, 26563, 26574, 26585, 26596,
+ 26607, 26618, 26629, 26640, 26651, 26662, 26673, 26684, 26695, 26706,
+ 26717, 26728, 26739, 26750, 26761, 26772, 26783, 26794, 26805, 26816,
+ 26827, 26838, 26849, 26860, 26871, 26882, 26893, 26904, 26915, 26926,
+ 26937, 26948, 26959, 26970, 26981, 26992, 27003, 27013, 27023, 27033,
+ 27043, 27053, 27063, 27073, 27083, 27093, 27103, 27113, 27123, 27133,
+ 27143, 27153, 27163, 27173, 27183, 27193, 27203, 22072, 27213, 27223,
+ 27233, 27243, 27253, 27263, 27273, 27283, 1372, 27293, 27303, 27313,
+ 27323, 27333, 27343, 27353, 27363, 27373, 27383, 27393, 27403, 27413,
+ 27423, 27433, 27443, 27453, 27463, 27473, 27483, 27493, 27503, 27513,
+ 27523, 27533, 27543, 27553, 27563, 27573, 27583, 27593, 27603, 27613,
+ 27623, 27633, 27643, 27653, 27663, 27673, 27683, 27693, 27703, 27713,
+ 27723, 27733, 27743, 27753, 27763, 27773, 27783, 27793, 27803, 27813,
+ 27823, 27833, 27843, 27853, 27863, 27873, 27883, 27893, 27903, 27913,
+ 27923, 27933, 27943, 27953, 27963, 27973, 27983, 27993, 19490, 28003,
+ 22672, 28013, 28023, 28033, 28043, 28053, 28063, 28073, 28083, 28093,
+ 28103, 28113, 28123, 28133, 28143, 28153, 28163, 28173, 28183, 28193,
+ 28203, 28213, 28223, 28233, 28243, 28253, 28263, 28273, 28283, 28293,
+ 28303, 28313, 28323, 28333, 28343, 28353, 28363, 28373, 28383, 28393,
+ 28403, 28413, 28423, 28433, 28443, 28453, 28463, 28473, 28483, 28493,
+ 28503, 28513, 28523, 28533, 28543, 28553, 28563, 28573, 28583, 28593,
+ 28603, 28613, 28623, 28633, 28643, 28653, 28663, 28673, 28683, 28693,
+ 28703, 28713, 28723, 28733, 28743, 28753, 28763, 28773, 28783, 28793,
+ 28803, 28813, 28823, 28833, 28843, 28853, 28863, 28873, 28883, 28893,
+ 28903, 28913, 28923, 28933, 28943, 28953, 28963, 28973, 28983, 28993,
+ 29003, 29013, 29023, 29033, 29043, 29053, 29063, 29073, 29083, 29093,
+ 29103, 29113, 29123, 29133, 29143, 29153, 29163, 29173, 29183, 29193,
+ 29203, 29213, 29223, 29233, 29243, 29253, 29263, 29273, 29283, 29293,
+ 29303, 29313, 29323, 29333, 29343, 1949, 29353, 29363, 29373, 29383,
+ 29393, 29403, 29413, 29423, 29433, 29443, 29453, 29463, 29473, 29483,
+ 29493, 29503, 29513, 29523, 29533, 29543, 29553, 29563, 29573, 29583,
+ 29593, 29603, 29613, 29623, 29633, 29643, 29653, 29663, 29673, 29683,
+ 29693, 29703, 29713, 29723, 29733, 29743, 29753, 29763, 29773, 29783,
+ 29793, 29803, 29813, 29823, 29833, 29843, 29853, 29863, 29873, 29883,
+ 29893, 29903, 29913, 29923, 29933, 29942, 29951, 29960, 29969, 29978,
+ 29987, 29996, 30005, 30014, 30023, 30032, 30041, 30050, 30059, 30068,
+ 30077, 30086, 18958, 30095, 30104, 30113, 30122, 30131, 30140, 30149,
+ 30158, 30167, 30176, 30185, 30194, 30203, 30212, 30221, 30230, 30239,
+ 30248, 30257, 30266, 30275, 30284, 30293, 30302, 30311, 30320, 30329,
+ 30338, 30347, 30356, 30365, 30374, 30383, 30392, 30401, 30410, 30419,
+ 30428, 30437, 30446, 30455, 30464, 30473, 24926, 30482, 30491, 30500,
+ 30509, 30518, 30527, 30536, 30545, 30554, 30563, 30572, 30581, 30590,
+ 30599, 30608, 30617, 30626, 30635, 30644, 30653, 30662, 30671, 30680,
+ 30689, 30698, 30707, 30716, 25135, 30725, 30734, 30743, 30752, 30761,
+ 30770, 30779, 30788, 30797, 30806, 30815, 30824, 30833, 30842, 30851,
+ 30860, 30869, 30878, 30887, 30896, 30905, 1287, 30914, 30923, 30932,
+ 30941, 30950, 30959, 30968, 30977, 30986, 30995, 31004, 31013, 31022,
+ 31031, 31040, 31049, 29894, 31058, 31067, 31076, 31085, 31094, 31103,
+ 31112, 31121, 31130, 31139, 31148, 31157, 31166, 31175, 31184, 31193,
+ 31202, 31211, 31220, 31229, 31238, 31247, 31256, 31265, 31274, 31283,
+ 31292, 31301, 31310, 31319, 31328, 31337, 31346, 31355, 31364, 31373,
+ 31382, 31391, 31400, 31409, 31418, 31427, 31436, 31445, 31454, 31463,
+ 31472, 31481, 31490, 31499, 31508, 31517, 31526, 31535, 31544, 31553,
+ 31562, 31571, 31580, 31589, 31598, 31607, 31616, 31625, 31634, 31643,
+ 31652, 31661, 31670, 31679, 31688, 31697, 31706, 31715, 31724, 31733,
+ 31742, 31751, 31760, 31769, 31778, 31787, 31796, 31805, 31814, 31823,
+ 31832, 31841, 31850, 31859, 31868, 31877, 31886, 31895, 31904, 31913,
+ 31922, 31931, 31940, 31949, 31958, 31967, 31976, 31985, 31994, 32003,
+ 32012, 32021, 32030, 32039, 32048, 32057, 32066, 32075, 32084, 32093,
+ 32102, 32111, 32120, 32129, 32138, 32147, 32156, 32165, 32174, 32183,
+ 32192, 32201, 32210, 10766, 32219, 32228, 32237, 32246, 32255, 32264,
+ 32273, 32282, 32291, 32300, 32309, 32318, 32327, 32336, 32345, 32354,
+ 32363, 32372, 32381, 32390, 32399, 32408, 32417, 32426, 32435, 32444,
+ 32453, 32462, 32471, 32480, 32489, 32498, 32507, 32516, 32525, 32534,
+ 32543, 32552, 32561, 32570, 32579, 32588, 32597, 32606, 32615, 32624,
+ 32633, 32642, 32651, 32660, 32669, 32678, 32687, 32696, 32705, 32714,
+ 32723, 1848, 32732, 32741, 32750, 32759, 32768, 32777, 32786, 32795,
+ 32804, 32813, 32822, 32831, 32840, 32849, 32858, 32867, 32876, 32885,
+ 32894, 32903, 32912, 32921, 32930, 32939, 32948, 32957, 32966, 32975,
+ 32984, 32993, 33002, 33011, 33020, 33029, 33038, 33047, 33056, 33065,
+ 33074, 33083, 33091, 33099, 33107, 33115, 18289, 33123, 33131, 33139,
+ 33147, 33155, 33163, 33171, 33179, 33187, 33195, 33203, 33211, 33219,
+ 33227, 33235, 33243, 33251, 33259, 33267, 27465, 33275, 33283, 33291,
+ 33299, 33307, 33315, 33323, 33331, 33339, 33347, 19609, 33355, 33363,
+ 33371, 33379, 33387, 33395, 33403, 18317, 33411, 33419, 33427, 33435,
+ 33443, 1471, 33451, 33459, 2047, 19765, 33467, 1967, 33475, 33483, 33491,
+ 18373, 33499, 33507, 33515, 33523, 18985, 22362, 33531, 33539, 33547,
+ 33555, 33563, 33571, 33579, 33587, 33595, 33603, 30402, 33611, 33619,
+ 33627, 33635, 33643, 33651, 33659, 33667, 33675, 33683, 33691, 1815,
+ 33699, 33707, 33715, 33723, 33731, 33739, 33747, 33755, 33763, 33771,
+ 33779, 33787, 33795, 33803, 33811, 33819, 33827, 33835, 33843, 33851,
+ 33859, 33867, 33875, 33883, 33891, 33899, 33907, 33915, 33923, 33931,
+ 33939, 33947, 33955, 33963, 33971, 33979, 33987, 33995, 34003, 34011,
+ 34019, 34027, 34035, 34043, 34051, 34059, 34067, 34075, 34083, 34091,
+ 27265, 34099, 34107, 34115, 34123, 34131, 34139, 34147, 34155, 34163,
+ 34171, 34179, 34187, 34195, 34203, 34211, 34219, 30906, 34227, 34235,
+ 34243, 34251, 34259, 34267, 34275, 34283, 34291, 34299, 34307, 34315,
+ 34323, 34331, 34339, 34347, 34355, 34363, 34371, 34379, 34387, 34395,
+ 34403, 34411, 34419, 34427, 34435, 34443, 34451, 34459, 34467, 34475,
+ 34483, 34491, 34499, 34507, 34515, 34523, 34531, 34539, 34547, 27325,
+ 34555, 34563, 34571, 34579, 34587, 34595, 34603, 34611, 34619, 34627,
+ 34635, 34643, 34651, 34659, 34667, 34675, 34683, 26467, 34691, 34699,
+ 34707, 34715, 34723, 34731, 34739, 34747, 34755, 34763, 34771, 34779,
+ 34787, 34795, 34803, 34811, 34819, 34827, 34835, 34843, 34851, 34859,
+ 34867, 34875, 34883, 34891, 34899, 34907, 34915, 34923, 34931, 34939,
+ 34947, 34955, 34963, 34971, 34979, 34987, 34995, 30951, 35003, 35011,
+ 35019, 35027, 35035, 35043, 35051, 35059, 35067, 35075, 35083, 35091,
+ 35099, 26588, 35107, 35115, 1934, 35123, 35131, 35139, 35147, 35155,
+ 35163, 35171, 35179, 32706, 35187, 35195, 35203, 35211, 35219, 35227,
+ 35235, 35243, 35251, 35259, 35267, 35275, 35283, 35291, 35299, 35307,
+ 35315, 35323, 35331, 35339, 2015, 35347, 35355, 10863, 35363, 35371,
+ 35379, 35387, 35395, 35403, 35411, 35419, 35427, 23310, 35435, 35443,
+ 35451, 35459, 35467, 35475, 35483, 35491, 35499, 35507, 35515, 35523,
+ 35531, 35539, 35547, 35555, 35563, 35571, 35579, 35587, 35595, 35603,
+ 35611, 35619, 35627, 35635, 35643, 35651, 35659, 35667, 35675, 35683,
+ 19141, 35691, 35699, 35707, 35715, 35723, 35731, 35739, 35747, 35755,
+ 1710, 35763, 35771, 35779, 35787, 35795, 35803, 35811, 35819, 35827,
+ 35835, 35843, 35851, 35859, 35867, 35875, 35883, 35891, 35899, 35907,
+ 35915, 35923, 35931, 35939, 35947, 35955, 35963, 35971, 35979, 35987,
+ 35995, 36003, 36011, 36019, 18905, 36027, 36035, 36043, 36051, 36059,
+ 36067, 36075, 36083, 36091, 36099, 36107, 28965, 36115, 36123, 36131,
+ 36139, 36147, 36155, 36163, 36171, 36179, 36187, 36195, 36202, 36209,
+ 36216, 36223, 36230, 19753, 36237, 36244, 36251, 36258, 36265, 36272,
+ 36279, 36286, 36293, 36300, 36307, 36314, 36321, 36328, 36335, 36342,
+ 36349, 11047, 36356, 36363, 36370, 36377, 36384, 36391, 36398, 36405,
+ 36412, 36419, 36426, 36433, 36440, 36447, 36454, 36461, 36468, 36475,
+ 36482, 36489, 36496, 36503, 36510, 36517, 1510, 36524, 36531, 1603,
+ 36538, 36545, 36552, 36559, 36566, 36573, 36580, 36587, 36594, 36601,
+ 36608, 36615, 36622, 36629, 36636, 36643, 36650, 1354, 36657, 36664,
+ 36671, 36678, 36685, 36692, 36699, 36706, 36713, 36720, 36727, 36734,
+ 36741, 36748, 36755, 36762, 36769, 36776, 36783, 26578, 36790, 36797,
+ 36804, 36811, 36818, 36825, 36832, 36839, 36846, 36853, 36860, 36867,
+ 36874, 36881, 36888, 36895, 36902, 36909, 36916, 36923, 36930, 36937,
+ 36944, 36951, 36958, 36965, 36972, 36979, 36986, 36993, 30187, 37000,
+ 37007, 37014, 37021, 37028, 37035, 37042, 37049, 37056, 37063, 37070,
+ 37077, 37084, 37091, 37098, 37105, 37112, 37119, 37126, 37133, 37140,
+ 37147, 37154, 37161, 37168, 37175, 37182, 37189, 37196, 37203, 37210,
+ 37217, 37224, 37231, 37238, 37245, 37252, 37259, 37266, 37273, 37280,
+ 22123, 37287, 37294, 37301, 37308, 37315, 37322, 37329, 37336, 37343,
+ 37350, 37357, 37364, 37371, 37378, 37385, 37392, 37399, 37406, 37413,
+ 37420, 37427, 37434, 37441, 37448, 37455, 37462, 37469, 37476, 37483,
+ 37490, 25291, 37497, 37504, 37511, 37518, 37525, 37532, 37539, 37546,
+ 37553, 37560, 37567, 30403, 37574, 37581, 37588, 37595, 37602, 37609,
+ 37616, 37623, 37630, 1747, 37637, 37644, 37651, 37658, 37665, 37672,
+ 37679, 37686, 37693, 37700, 37707, 37714, 37721, 37728, 37735, 37742,
+ 37749, 37756, 37763, 37770, 37777, 37784, 37791, 37798, 37805, 37812,
+ 37819, 37826, 37833, 37840, 37847, 37854, 37861, 37868, 37875, 37882,
+ 37889, 37896, 37903, 37910, 37917, 37924, 37931, 37938, 37945, 37952,
+ 37959, 37966, 30952, 37973, 37980, 37987, 37994, 38001, 38008, 38015,
+ 38022, 38029, 38036, 38043, 38050, 38057, 38064, 38071, 38078, 38085,
+ 38092, 38099, 38106, 38113, 38120, 38127, 38134, 38141, 38148, 38155,
+ 26512, 38162, 38169, 38176, 38183, 38190, 38197, 38204, 38211, 38218,
+ 38225, 38232, 38239, 38246, 38253, 34308, 38260, 38267, 38274, 38281,
+ 38288, 38295, 38302, 38309, 38316, 38323, 38330, 38337, 38344, 38351,
+ 38358, 38365, 38372, 38379, 38386, 38393, 38400, 38407, 38414, 38421,
+ 38428, 38435, 38442, 38449, 38456, 38463, 38470, 38477, 38484, 38491,
+ 38498, 38505, 38512, 38519, 38526, 38533, 38540, 38547, 38554, 38561,
+ 38568, 38575, 38582, 29166, 38589, 38596, 38603, 38610, 38617, 35596,
+ 38624, 38631, 38638, 38645, 38652, 38659, 38666, 38673, 38680, 38687,
+ 38694, 33196, 38701, 38708, 38715, 38722, 38729, 38736, 38743, 38750,
+ 38757, 38764, 38771, 38778, 38785, 38792, 38799, 38806, 38813, 38820,
+ 38827, 38834, 38841, 38848, 38855, 38862, 38869, 38876, 38883, 38890,
+ 38897, 38904, 30772, 38911, 38918, 38925, 38932, 23167, 38939, 38946,
+ 38953, 38960, 38967, 38974, 38981, 38988, 38995, 39002, 39009, 39016,
+ 39023, 39030, 39037, 39044, 39051, 39058, 39065, 39072, 39079, 39086,
+ 39093, 39100, 39107, 39114, 39121, 39128, 30970, 39135, 39142, 39149,
+ 28966, 39156, 39163, 39170, 39177, 39184, 39191, 39198, 39205, 39212,
+ 39219, 39226, 39233, 39240, 39247, 39254, 39261, 39267, 39273, 39279,
+ 39285, 39291, 39297, 39303, 39309, 39315, 39321, 39327, 38086, 33917,
+ 39333, 39339, 39345, 39351, 27927, 39357, 39363, 39369, 39375, 39381,
+ 39387, 39393, 39399, 27127, 39405, 39411, 39417, 39423, 39255, 39429,
+ 39435, 39441, 39447, 39453, 39459, 39465, 27227, 39471, 39477, 39483,
+ 39489, 39495, 39501, 39507, 39513, 39519, 39525, 39531, 39537, 39543,
+ 39549, 39555, 39561, 27287, 39567, 39573, 39579, 39585, 25061, 22148,
+ 39591, 19299, 28047, 39597, 39603, 39609, 39615, 19065, 39621, 39627,
+ 1312, 39633, 39639, 1549, 22580, 39645, 39651, 18347, 39657, 22448,
+ 39663, 39669, 1416, 39675, 18753, 39681, 19286, 39687, 39693, 39699,
+ 39705, 39711, 39717, 39723, 39729, 39735, 39741, 33613, 39747, 39753,
+ 39759, 39765, 27137, 39771, 39777, 39783, 39789, 39795, 39801, 39807,
+ 39813, 39819, 39825, 39831, 10973, 1198, 39837, 39843, 39849, 39855,
+ 39861, 39867, 39873, 39879, 39885, 39891, 39897, 39903, 39909, 39915,
+ 39921, 39927, 39933, 39939, 39945, 39951, 22460, 39957, 39963, 39969,
+ 39975, 39981, 39987, 39993, 39999, 40005, 40011, 40017, 40023, 40029,
+ 40035, 40041, 40047, 40053, 40059, 26876, 40065, 40071, 40077, 40083,
+ 40089, 40095, 40101, 40107, 40113, 40119, 40125, 30980, 27197, 40131,
+ 40137, 40143, 40149, 40155, 40161, 40167, 40173, 40179, 40185, 40191,
+ 40197, 40203, 40209, 40215, 40221, 40227, 40233, 40239, 40245, 40251,
+ 40257, 40263, 40269, 40275, 40281, 40287, 40293, 40299, 40305, 27377,
+ 40311, 40317, 40323, 40329, 40335, 40341, 40347, 40353, 40359, 40365,
+ 40371, 40377, 40383, 40389, 40395, 40401, 40407, 40413, 40419, 40425,
+ 40431, 40437, 40443, 40449, 40455, 40461, 40467, 40473, 40479, 40485,
+ 40491, 40497, 40503, 40509, 40515, 40521, 40527, 40533, 40539, 40545,
+ 32861, 40551, 40557, 40563, 40569, 40575, 40581, 40587, 40593, 40599,
+ 40605, 40611, 40617, 40623, 40629, 40635, 40641, 40647, 40653, 40659,
+ 40665, 40671, 40677, 40683, 40689, 40695, 40701, 40707, 40713, 26469,
+ 40719, 40725, 40731, 40737, 40743, 40749, 40755, 40761, 40767, 40773,
+ 40779, 40785, 40791, 40797, 40803, 40809, 40815, 40821, 40827, 40833,
+ 40839, 40845, 40851, 27367, 40857, 40863, 40869, 40875, 40881, 40887,
+ 40893, 40899, 40905, 40911, 40917, 40923, 40929, 40935, 40941, 40947,
+ 40953, 40959, 40965, 40971, 40977, 40983, 40989, 40995, 41001, 41007,
+ 41013, 41019, 41025, 41031, 41037, 41043, 37827, 41049, 41055, 41061,
+ 41067, 41073, 41079, 41085, 41091, 41097, 41103, 34469, 41109, 41115,
+ 41121, 41127, 41133, 41139, 41145, 41151, 41157, 41163, 41169, 41175,
+ 41181, 36093, 41187, 41193, 41199, 41205, 41211, 41217, 41223, 41229,
+ 41235, 41241, 41247, 41253, 41259, 41265, 41271, 41277, 41283, 41289,
+ 41295, 41301, 41307, 41313, 41319, 41325, 41331, 41337, 41343, 41349,
+ 41355, 41361, 41367, 41373, 41379, 41385, 41391, 41397, 41403, 41409,
+ 41415, 41421, 41427, 41433, 41439, 41445, 34701, 41451, 41457, 41463,
+ 41469, 41475, 41481, 41487, 22712, 41493, 41499, 41505, 41511, 41517,
+ 41523, 41529, 41535, 41541, 41547, 41553, 41559, 41565, 41571, 41577,
+ 41583, 41589, 41595, 41601, 41607, 41613, 41619, 41625, 41631, 41637,
+ 41643, 41649, 41655, 41661, 41667, 41673, 41679, 41685, 41691, 41697,
+ 41703, 41709, 41715, 41721, 41727, 41733, 41739, 41745, 41751, 41757,
+ 41763, 41769, 41775, 41781, 41787, 41793, 41799, 41805, 41811, 41817,
+ 41823, 41829, 41835, 41841, 41847, 41853, 41859, 41865, 41871, 41877,
+ 41883, 41889, 41895, 41901, 41907, 41913, 41919, 41925, 41931, 41937,
+ 41943, 41949, 41955, 41961, 41967, 41973, 41979, 41985, 41991, 41997,
+ 42003, 42009, 42015, 42021, 42027, 42033, 42039, 42045, 42051, 42057,
+ 42063, 42069, 42075, 42081, 42087, 42093, 42099, 42105, 42111, 42117,
+ 42123, 42129, 42135, 42141, 42147, 42153, 42159, 42165, 42171, 42177,
+ 42183, 42189, 37169, 42195, 42201, 42207, 42213, 42219, 42225, 42231,
+ 42237, 42243, 42249, 42255, 42261, 42267, 42273, 42279, 42285, 42291,
+ 42297, 42303, 42309, 42315, 42321, 42327, 42333, 42339, 42345, 42351,
+ 42357, 42363, 42369, 42375, 42381, 42387, 42393, 42399, 42405, 42411,
+ 42417, 42423, 42429, 42435, 42441, 42447, 42453, 42459, 42465, 42471,
+ 42477, 42483, 42489, 42495, 42501, 42507, 42513, 42519, 42525, 42531,
+ 42537, 42543, 42549, 42555, 42561, 42567, 42573, 42579, 42585, 42591,
+ 42597, 42603, 42609, 42615, 42621, 42627, 42633, 42639, 42645, 42651,
+ 42657, 42663, 42669, 42675, 42681, 42687, 42693, 42699, 42705, 42711,
+ 42717, 42723, 42729, 32393, 42735, 42741, 42747, 42753, 42759, 42765,
+ 42771, 42777, 42783, 42789, 42795, 42801, 42807, 42813, 42819, 42825,
+ 42831, 42837, 42843, 42849, 42855, 10943, 42861, 42867, 42873, 42879,
+ 42885, 42891, 42897, 42903, 42909, 42915, 42921, 42927, 42933, 42939,
+ 22496, 42945, 42951, 42957, 39122, 42963, 42969, 30989, 42975, 42981,
+ 42987, 42993, 42999, 43005, 43011, 43017, 43023, 43029, 43035, 43041,
+ 43047, 43053, 43059, 43065, 43071, 43077, 43083, 43089, 43095, 43101,
+ 43107, 43113, 43119, 43125, 43131, 43137, 43143, 43149, 43155, 43161,
+ 43167, 43173, 43179, 43185, 29087, 43191, 43197, 43203, 43209, 43215,
+ 43221, 43227, 43233, 43239, 43245, 43251, 43257, 43263, 43269, 43275,
+ 43281, 43287, 43293, 43299, 43305, 43311, 43317, 43323, 43329, 43335,
+ 43341, 43347, 43353, 43359, 43365, 43371, 43376, 43381, 43386, 43391,
+ 43396, 43401, 43406, 43411, 43416, 30198, 43421, 19157, 43426, 43431,
+ 40864, 43436, 43441, 43446, 28858, 43451, 43456, 43461, 43466, 43471,
+ 43476, 43481, 43486, 43491, 43496, 43501, 43506, 43511, 43060, 43516,
+ 41068, 29308, 43521, 43526, 43531, 39784, 43536, 43541, 43546, 43551,
+ 43556, 43561, 43566, 43571, 43576, 40024, 43581, 43586, 43591, 43596,
+ 43601, 32682, 43606, 43611, 43616, 43621, 43626, 43631, 43636, 43641,
+ 43646, 43651, 43656, 43661, 43666, 43671, 43676, 43681, 43686, 43691,
+ 43696, 1377, 43701, 43706, 43711, 43716, 17919, 43721, 43726, 43731,
+ 43736, 43741, 43746, 43751, 43756, 43761, 43766, 43771, 43776, 43781,
+ 43786, 40900, 43791, 43796, 43801, 43806, 43811, 43816, 43821, 43826,
+ 43831, 43836, 43841, 43846, 43851, 43856, 43861, 43866, 43871, 43876,
+ 43881, 43886, 39880, 43891, 43896, 42916, 43901, 43906, 434, 43911,
+ 31152, 43916, 43921, 43926, 43931, 43936, 43941, 43946, 43951, 43956,
+ 1153, 43961, 43966, 43971, 43976, 43981, 27058, 43986, 43991, 43996,
+ 44001, 44006, 44011, 39382, 44016, 44021, 44026, 44031, 44036, 44041,
+ 44046, 44051, 44056, 44061, 44066, 44071, 44076, 44081, 44086, 44091,
+ 44096, 44101, 44106, 44111, 18949, 44116, 44121, 44126, 44131, 44136,
+ 44141, 44146, 44151, 44156, 44161, 44166, 44171, 44176, 44181, 44186,
+ 44191, 43294, 44196, 38220, 44201, 44206, 44211, 44216, 44221, 44226,
+ 44231, 44236, 42958, 19404, 44241, 44246, 44251, 44256, 40120, 44261,
+ 44266, 44271, 44276, 44281, 44286, 44291, 44296, 26437, 44301, 44306,
+ 44311, 44316, 29288, 44321, 44326, 44331, 44336, 44341, 44346, 44351,
+ 44356, 44361, 44366, 44371, 44376, 44381, 44386, 44391, 44396, 44401,
+ 44406, 44411, 44416, 44421, 44426, 44431, 44436, 44441, 44446, 44451,
+ 44456, 44461, 44466, 44471, 44476, 26591, 44481, 44486, 44491, 44496,
+ 27388, 44501, 33830, 44506, 44511, 44516, 44521, 44526, 44531, 44536,
+ 44541, 44546, 44551, 44556, 44561, 44566, 44571, 44576, 44581, 44586,
+ 44591, 44596, 44601, 42634, 44606, 44611, 44616, 32745, 44621, 44626,
+ 30819, 44631, 44636, 44641, 44646, 44651, 44656, 41446, 44661, 44666,
+ 37100, 44671, 44676, 44681, 18572, 44686, 44691, 44696, 44701, 35590,
+ 44706, 44711, 44716, 44721, 44726, 44731, 36974, 38633, 44736, 44741,
+ 44746, 44751, 44756, 44761, 44766, 44771, 44776, 44781, 44786, 44791,
+ 44796, 44801, 44806, 44811, 44816, 44821, 44826, 44831, 44836, 44841,
+ 44846, 44851, 43054, 44856, 37275, 44861, 44866, 44871, 44876, 36358,
+ 44881, 44886, 44891, 44896, 44901, 44906, 44911, 44916, 44921, 44926,
+ 44931, 44936, 44941, 44946, 44951, 44956, 44961, 44966, 44971, 44976,
+ 44981, 28938, 44986, 44991, 44996, 45001, 45006, 38136, 45011, 45016,
+ 45021, 45026, 45031, 45036, 45041, 45046, 32934, 45051, 45056, 45061,
+ 45066, 45071, 45076, 45081, 45086, 45091, 45096, 45101, 45106, 45111,
+ 45116, 45121, 45126, 45131, 45136, 45141, 45146, 45151, 45156, 45161,
+ 45166, 45171, 45176, 45181, 45186, 45191, 45196, 45201, 45206, 45211,
+ 45216, 45221, 45226, 45231, 45236, 45241, 45246, 45251, 45256, 45261,
+ 45266, 45271, 45276, 45281, 45286, 45291, 45296, 45301, 45306, 45311,
+ 45316, 45321, 45326, 45331, 45336, 45341, 45346, 45351, 45356, 45361,
+ 45366, 45371, 45376, 45381, 45386, 45391, 45396, 45401, 45406, 45411,
+ 45416, 45421, 45426, 45431, 45436, 45441, 45446, 45451, 45456, 45461,
+ 45466, 45471, 45476, 45481, 45486, 45491, 45496, 45501, 45506, 45511,
+ 45516, 45521, 45526, 45531, 45536, 45541, 45546, 45551, 45556, 45561,
+ 45566, 45571, 45576, 45581, 45586, 45591, 45596, 45601, 45606, 45611,
+ 45616, 45621, 45626, 45631, 45636, 45641, 45646, 45651, 45656, 45661,
+ 45666, 45671, 45676, 45681, 45686, 45691, 45696, 45701, 45706, 45711,
+ 45716, 45721, 45726, 40750, 40756, 40762, 45731, 45736, 45741, 45746,
+ 45751, 45756, 45761, 45766, 45771, 45776, 29328, 40768, 40774, 40780,
+ 45781, 42142, 45786, 45791, 45796, 45801, 45806, 45811, 45816, 45821,
+ 45826, 45831, 45836, 45841, 45846, 40894, 45851, 45856, 45861, 45866,
+ 45871, 45876, 45881, 45886, 45891, 45896, 45901, 45906, 45911, 45916,
+ 45921, 45926, 39682, 45931, 45936, 45941, 45946, 45951, 45956, 45961,
+ 45966, 45971, 45976, 45981, 45986, 45991, 45996, 46001, 46006, 46011,
+ 46016, 46021, 46026, 46031, 46036, 46041, 46046, 46051, 46056, 46061,
+ 46066, 46071, 46076, 46081, 46086, 46091, 46096, 46101, 46106, 46111,
+ 46116, 46121, 46126, 46131, 46136, 46141, 46146, 46151, 46156, 46161,
+ 46166, 46171, 46176, 46181, 41074, 41080, 46186, 46191, 46196, 46201,
+ 46206, 46211, 46216, 46221, 41092, 41098, 46226, 46231, 30666, 46236,
+ 46241, 46246, 43258, 43264, 46251, 46256, 46261, 46266, 46271, 46276,
+ 46281, 46286, 46291, 46296, 46301, 46306, 46311, 46316, 46321, 46326,
+ 46331, 46336, 46341, 46346, 46351, 46356, 46361, 46366, 46371, 46376,
+ 46381, 46386, 46391, 46396, 46401, 46406, 46411, 46416, 46421, 46426,
+ 41374, 46431, 41380, 46436, 46441, 46446, 18446, 33486, 46451, 41386,
+ 41392, 41398, 41404, 41410, 41416, 46456, 46461, 46466, 46471, 40924,
+ 46476, 40810, 46481, 46486, 46491, 42976, 46496, 46501, 46506, 46511,
+ 46516, 46521, 46526, 46531, 46536, 46541, 46546, 46551, 46556, 46561,
+ 46566, 46571, 46576, 46581, 46586, 46591, 46596, 46601, 46606, 46611,
+ 46616, 46621, 46626, 46631, 46636, 46641, 46646, 46651, 46656, 46661,
+ 46666, 46671, 46676, 46681, 46686, 46691, 46696, 46701, 46706, 46711,
+ 46716, 46721, 46726, 46731, 46736, 46741, 46746, 46751, 46756, 46761,
+ 46766, 46771, 46776, 42484, 40960, 40966, 40972, 42562, 46781, 46786,
+ 46791, 46796, 46801, 46806, 46811, 46816, 46821, 46826, 46831, 46836,
+ 46841, 46846, 46851, 46856, 46861, 46866, 46871, 46876, 46881, 46886,
+ 46891, 46896, 46901, 46906, 41686, 41692, 41698, 46911, 46916, 46921,
+ 46926, 46931, 46936, 46941, 46946, 46951, 46956, 46961, 46966, 46971,
+ 46976, 46981, 46986, 41704, 46991, 41710, 41716, 42232, 46996, 47001,
+ 47006, 47011, 47016, 47021, 47026, 47031, 47036, 47041, 47046, 47051,
+ 47056, 47061, 47066, 47071, 47076, 47081, 47086, 47091, 47096, 47101,
+ 47106, 47111, 47116, 47121, 47126, 47131, 47136, 47141, 47146, 47151,
+ 39280, 47156, 47161, 47166, 47171, 47176, 47181, 47186, 47191, 47196,
+ 43024, 47201, 47206, 41500, 47211, 41506, 47216, 47221, 47226, 47231,
+ 47236, 41512, 47241, 41518, 41524, 41530, 47246, 38031, 47251, 47256,
+ 47261, 47266, 47271, 47276, 47281, 47286, 47291, 47296, 47301, 47306,
+ 47311, 47316, 47321, 47326, 47331, 47336, 47341, 41536, 41542, 47346,
+ 47351, 47356, 47361, 47366, 47371, 47376, 47381, 47386, 35374, 47391,
+ 47396, 41548, 47401, 41554, 29338, 41560, 47406, 47411, 47416, 47421,
+ 38542, 47426, 47431, 47436, 47441, 47446, 47451, 47456, 47461, 47466,
+ 47471, 47476, 47481, 47486, 47491, 47496, 47501, 47506, 47511, 47516,
+ 47521, 47526, 39646, 47531, 47536, 47541, 47546, 47551, 47556, 47561,
+ 47566, 47571, 47576, 47581, 42238, 47586, 47591, 47596, 47601, 47606,
+ 47611, 47616, 42244, 47621, 42250, 47626, 47631, 47636, 47641, 41572,
+ 41584, 39586, 47646, 47651, 47656, 47661, 47666, 47671, 47676, 47681,
+ 47686, 47691, 47696, 47701, 47706, 47711, 47716, 47721, 47726, 47731,
+ 38773, 47736, 47741, 47746, 47751, 47756, 47761, 47766, 47771, 47776,
+ 47781, 47786, 47791, 47796, 47801, 47806, 47811, 47816, 47821, 47826,
+ 41590, 47831, 47836, 47841, 47846, 47851, 47856, 47861, 47866, 47871,
+ 47876, 47881, 47886, 47891, 47896, 47901, 47906, 47911, 47916, 47921,
+ 47926, 47931, 47936, 47941, 47946, 47951, 47956, 47961, 47966, 47971,
+ 47976, 47981, 47986, 47991, 47996, 48001, 48006, 48011, 48016, 48021,
+ 48026, 48031, 48036, 48041, 48046, 48051, 48056, 48061, 48066, 48071,
+ 48076, 48081, 48086, 48091, 48096, 48101, 48106, 48111, 48116, 48121,
+ 48126, 48131, 48136, 48141, 48146, 48151, 48156, 48161, 48166, 48171,
+ 48176, 48181, 48186, 48191, 48196, 48201, 48206, 48211, 48216, 48221,
+ 48226, 48231, 48236, 48241, 48246, 48251, 48256, 48261, 48266, 48271,
+ 48276, 48281, 48286, 48291, 48296, 42520, 48301, 48306, 48311, 48316,
+ 48321, 48326, 48331, 48336, 48341, 48346, 48351, 48356, 48361, 48366,
+ 48371, 48376, 48381, 48386, 48391, 48396, 42646, 42274, 48401, 42280,
+ 48406, 48411, 48416, 48421, 48426, 48431, 48436, 48441, 48446, 48451,
+ 48456, 48461, 48466, 48471, 48476, 48481, 48486, 48491, 48496, 48501,
+ 48506, 48511, 48516, 48521, 48526, 48531, 48536, 48541, 42880, 42886,
+ 48546, 48551, 48556, 48561, 48566, 31089, 48571, 942, 48576, 48581,
+ 48586, 48591, 48596, 48601, 48606, 48611, 48616, 48621, 48626, 48631,
+ 48636, 48641, 48646, 48651, 48656, 48661, 48666, 48671, 48676, 48681,
+ 48686, 48691, 48696, 48701, 48706, 48711, 48716, 48721, 27328, 48726,
+ 48731, 42892, 48736, 48741, 48746, 48751, 48756, 48761, 48766, 48771,
+ 48776, 48781, 42382, 48786, 48791, 48796, 48801, 48806, 48811, 48816,
+ 48821, 48826, 27138, 48831, 48836, 48841, 48846, 48851, 48856, 38486,
+ 48861, 48866, 48871, 48876, 48881, 48886, 48891, 48896, 48901, 48906,
+ 48911, 48916, 48921, 48926, 48931, 48936, 48941, 48946, 48951, 48956,
+ 48961, 48966, 40636, 48971, 33406, 39011, 29348, 48976, 48981, 48986,
+ 48991, 48996, 49001, 49006, 49011, 49016, 33702, 49021, 49026, 49031,
+ 49036, 49041, 41620, 41626, 41632, 49046, 41650, 41836, 41842, 49051,
+ 49056, 49061, 49066, 49071, 49076, 49081, 49086, 49091, 49096, 49101,
+ 49106, 49111, 49116, 49121, 49126, 49131, 49136, 49141, 42292, 42298,
+ 42304, 49146, 49151, 49156, 49161, 49166, 49171, 49176, 49181, 49186,
+ 42310, 49191, 42316, 49196, 49201, 49206, 49211, 49216, 49221, 49226,
+ 49231, 49236, 49241, 49246, 49251, 49256, 49261, 49266, 49271, 49276,
+ 49281, 49286, 49291, 49296, 49301, 49306, 42322, 42328, 49311, 42334,
+ 42340, 42346, 49316, 49321, 49326, 49331, 49336, 49341, 49346, 49351,
+ 49356, 49361, 49366, 49371, 49376, 49381, 49386, 49391, 49396, 49401,
+ 49406, 49411, 49416, 602, 49420, 27259, 49424, 33007, 24876, 49428,
+ 49432, 49436, 33959, 42581, 49440, 49444, 19743, 41909, 26427, 49448,
+ 49452, 49456, 41225, 32368, 40451, 49460, 49464, 49468, 32638, 49472,
+ 49476, 49480, 39395, 39797, 45837, 49484, 49488, 49492, 22282, 49496,
+ 49500, 49504, 38858, 41069, 49508, 18601, 49512, 49516, 49520, 28969,
+ 49524, 49528, 49532, 49536, 39473, 45832, 49540, 33559, 27159, 45652,
+ 36268, 19197, 39737, 49544, 26570, 49548, 44277, 31081, 49552, 49556,
+ 49560, 49564, 30451, 38543, 49568, 29069, 40811, 49572, 37374, 48912,
+ 49576, 40895, 46937, 49580, 49584, 44857, 49588, 49592, 38914, 49596,
+ 43817, 23302, 45842, 49600, 49604, 49608, 49612, 260, 35095, 49616,
+ 49620, 25503, 49624, 49628, 39845, 49632, 30928, 40409, 49636, 49640,
+ 49644, 46227, 49648, 49652, 49656, 49660, 46067, 49664, 49668, 49672,
+ 49676, 49680, 47192, 49684, 49688, 49692, 49696, 49700, 46912, 33052,
+ 49704, 49708, 49712, 49716, 49720, 49724, 49728, 49732, 49736, 47732,
+ 33943, 49740, 49744, 49748, 49752, 49756, 49760, 49764, 48582, 49768,
+ 27439, 43055, 40319, 34151, 49772, 49776, 49780, 40481, 46457, 46462,
+ 49784, 46232, 39131, 49788, 49792, 49796, 49800, 45847, 36842, 49804,
+ 48442, 32125, 49808, 40523, 35775, 37332, 49812, 49816, 42239, 49820,
+ 37136, 24694, 45892, 38123, 49824, 49828, 49832, 49836, 48567, 49840,
+ 49844, 49848, 44827, 49852, 49856, 49860, 49864, 49868, 49872, 47727,
+ 46742, 49876, 38746, 49880, 49884, 49888, 49892, 49896, 49900, 49904,
+ 49908, 47742, 48307, 49912, 49916, 49920, 49924, 49928, 49932, 48877,
+ 31270, 37213, 48887, 49936, 22030, 49940, 1177, 48922, 48927, 29089,
+ 48712, 49944, 34047, 49948, 49952, 49956, 49960, 49964, 40493, 49968,
+ 49972, 37423, 45067, 49976, 49980, 37430, 43295, 49984, 49988, 40013,
+ 49992, 49996, 50000, 50004, 50008, 50012, 50016, 30739, 45667, 50020,
+ 45817, 38291, 34607, 50024, 50028, 50032, 50036, 50040, 50044, 50048,
+ 50052, 50056, 50060, 50064, 50068, 50072, 50076, 50080, 50084, 50088,
+ 50092, 50096, 31144, 50100, 50104, 50108, 50112, 50116, 50120, 50124,
+ 50128, 46342, 46347, 50132, 50136, 50140, 50144, 50148, 50152, 50156,
+ 50160, 46377, 50164, 40901, 43692, 50168, 50172, 42809, 50176, 50180,
+ 50184, 50188, 50192, 41159, 50196, 33079, 50200, 50204, 50208, 50212,
+ 50216, 50220, 50224, 50228, 50232, 46202, 44837, 44842, 46527, 50236,
+ 50240, 50244, 46587, 50248, 22750, 50252, 50256, 46637, 50260, 30748,
+ 50264, 50268, 50272, 50276, 50280, 35103, 50284, 50288, 50292, 50296,
+ 50300, 50304, 43972, 50308, 42257, 50312, 50316, 50320, 50324, 24898,
+ 50328, 32503, 50332, 50336, 33903, 50340, 50344, 50348, 41963, 50352,
+ 50356, 50360, 50364, 50368, 18447, 47747, 973, 50372, 50376, 50380,
+ 50384, 48587, 50388, 30289, 50392, 50396, 50400, 50404, 50408, 50412,
+ 50416, 50420, 50424, 50428, 50432, 48882, 50436, 50440, 50444, 50448,
+ 35671, 50452, 50456, 34495, 50460, 40031, 50464, 50468, 50472, 30325,
+ 50476, 42605, 50480, 38445, 50484, 50488, 50492, 50496, 50500, 50504,
+ 50508, 50512, 41417, 40487, 50516, 50520, 40403, 50524, 50528, 50532,
+ 50536, 50540, 47867, 50544, 47882, 47912, 50548, 50552, 50556, 48737,
+ 50560, 50564, 50568, 44287, 50572, 44617, 47972, 50576, 50580, 50584,
+ 42017, 50588, 49067, 34375, 42161, 50592, 50596, 43229, 31099, 40253,
+ 50600, 32989, 50604, 34559, 27229, 50608, 50612, 50616, 50620, 50624,
+ 50628, 50632, 50636, 50640, 50644, 50648, 50652, 50656, 50660, 50664,
+ 50668, 50672, 50676, 50680, 50684, 50688, 50692, 50696, 50700, 50704,
+ 50708, 50712, 50716, 50720, 50724, 50728, 50732, 50736, 50740, 50744,
+ 50748, 50752, 50756, 50760, 50764, 50768, 50772, 50776, 50780, 50784,
+ 50788, 50792, 50796, 50800, 50804, 50808, 50812, 50816, 50820, 50824,
+ 50828, 50832, 50836, 50840, 50844, 50848, 50852, 50856, 50860, 50864,
+ 50868, 50872, 50876, 50880, 50884, 50888, 50892, 50896, 50900, 50904,
+ 50908, 50912, 50916, 50920, 50924, 50928, 50932, 50936, 50940, 50944,
+ 50948, 50952, 50956, 50960, 50964, 50968, 50972, 50976, 50980, 50984,
+ 50988, 50992, 50996, 51000, 51004, 51008, 51012, 51016, 51020, 51024,
+ 51028, 51032, 51036, 51040, 51044, 51048, 51052, 51056, 51060, 51064,
+ 51068, 51072, 45597, 35295, 45607, 51076, 51080, 51084, 51088, 51092,
+ 51096, 51100, 32494, 51104, 51108, 45612, 51112, 51116, 45617, 51120,
+ 51124, 44587, 51128, 45627, 45632, 45637, 51132, 51136, 45642, 45647,
+ 45657, 45662, 44197, 45672, 51140, 51144, 51148, 45677, 47497, 45682,
+ 45687, 51152, 30100, 51156, 51160, 51164, 51168, 51172, 51176, 51180,
+ 51184, 51188, 51192, 45822, 51196, 51200, 51204, 51208, 51212, 36541,
+ 51216, 51220, 51224, 51228, 51232, 51236, 51240, 51244, 51248, 51252,
+ 51256, 51260, 51264, 51268, 51272, 51276, 25481, 51280, 51284, 35543,
+ 51288, 46052, 51292, 46057, 36135, 51296, 46062, 51300, 42071, 46072,
+ 39647, 51304, 46082, 46087, 46092, 46097, 46102, 46857, 51308, 51312,
+ 51316, 46107, 48447, 46112, 46122, 51320, 51324, 51328, 46127, 46132,
+ 44267, 46137, 46142, 46147, 51332, 51336, 51340, 51344, 51348, 51352,
+ 51356, 51360, 51364, 51368, 51372, 51376, 51380, 51384, 26339, 44552,
+ 51388, 51392, 51396, 51400, 41117, 51404, 51408, 51412, 51416, 51420,
+ 51424, 51428, 51432, 51436, 51440, 51444, 51448, 51452, 51456, 51460,
+ 51464, 51468, 51472, 51476, 51480, 51484, 51488, 51492, 51496, 51500,
+ 51504, 51508, 51512, 46327, 51516, 46332, 46337, 51520, 51524, 37010,
+ 46352, 51528, 46357, 51532, 51536, 51540, 46362, 51544, 46367, 46372,
+ 51548, 44342, 46382, 51552, 461, 51556, 44347, 46387, 46392, 46397,
+ 46402, 46407, 46412, 46417, 51560, 51564, 51568, 51572, 51576, 51580,
+ 44467, 29909, 45857, 45867, 30217, 35999, 51584, 51588, 45872, 45877,
+ 45882, 41939, 51592, 51596, 51600, 51604, 44117, 26394, 32359, 51608,
+ 51612, 51616, 51620, 51624, 51628, 34967, 51632, 51636, 51640, 51644,
+ 51648, 45887, 32431, 44812, 36975, 45902, 45907, 51652, 45912, 39683,
+ 44742, 44747, 44752, 51656, 51660, 51664, 51668, 51672, 51676, 51680,
+ 51684, 51688, 51692, 51696, 49142, 31198, 40751, 40643, 40763, 26405,
+ 45007, 51700, 41747, 36031, 48837, 51704, 51708, 51712, 51716, 51720,
+ 51724, 44452, 46917, 46922, 46927, 51728, 51732, 51736, 46932, 46942,
+ 51740, 46947, 46952, 46957, 44457, 46962, 51744, 46967, 47707, 46972,
+ 46977, 51748, 51752, 32089, 51756, 51760, 47067, 51764, 622, 51768,
+ 51772, 25426, 51776, 51780, 51784, 51788, 51792, 51796, 51800, 51804,
+ 51808, 51812, 51816, 51820, 22210, 51824, 51828, 51832, 51836, 51840,
+ 51844, 51848, 51852, 51856, 51860, 51864, 51868, 51872, 51876, 51880,
+ 51884, 51888, 51892, 51896, 51900, 51904, 51908, 29899, 46502, 51912,
+ 44317, 46512, 51916, 51920, 46517, 36331, 24777, 51924, 44832, 48847,
+ 51928, 51932, 51936, 46277, 51940, 46537, 46542, 51944, 51948, 51952,
+ 46547, 51956, 284, 46552, 46557, 46562, 44757, 46572, 46577, 46582,
+ 46592, 46597, 51960, 30460, 51964, 46607, 46612, 51968, 51972, 51976,
+ 51980, 51984, 51988, 51992, 51996, 52000, 46617, 52004, 52008, 52012,
+ 52016, 46622, 41891, 46632, 52020, 52024, 46642, 46647, 46652, 46657,
+ 46662, 38298, 46672, 52028, 46677, 52032, 46687, 52036, 42095, 52040,
+ 46692, 18190, 46702, 52044, 52048, 52052, 52056, 52060, 39815, 52064,
+ 40085, 22678, 22138, 52068, 46707, 52072, 46712, 52076, 33679, 52080,
+ 35871, 27879, 46717, 41429, 46722, 33407, 46732, 52084, 52088, 52092,
+ 52096, 52100, 52104, 52108, 46737, 43337, 46747, 52112, 52116, 52120,
+ 52124, 52128, 46752, 52132, 52136, 46757, 52140, 52144, 52148, 37661,
+ 52152, 52156, 52160, 52164, 43259, 43265, 52168, 52172, 52176, 19652,
+ 43001, 52180, 52184, 52188, 44187, 52192, 52196, 52200, 52204, 52208,
+ 52212, 52216, 52220, 52224, 48577, 52228, 52232, 41123, 52236, 52240,
+ 52244, 52248, 52252, 52256, 52260, 52264, 52268, 52272, 52276, 52280,
+ 52284, 52288, 52292, 52296, 52300, 52304, 52308, 52312, 52316, 52320,
+ 52324, 52328, 52332, 52336, 52340, 52344, 52348, 52352, 52356, 52360,
+ 52364, 52368, 52372, 52376, 52380, 52384, 52388, 52392, 52396, 52400,
+ 52404, 52408, 52412, 52416, 52420, 52424, 52428, 52432, 52436, 52440,
+ 52444, 47752, 33119, 52448, 47757, 41363, 47767, 29009, 35311, 52452,
+ 52456, 52460, 43073, 52464, 52468, 43792, 48332, 47777, 52472, 52476,
+ 52480, 52484, 52488, 48342, 47782, 47787, 47792, 47797, 52492, 52496,
+ 47802, 47807, 47812, 47817, 52500, 52504, 52508, 36063, 25514, 48602,
+ 52512, 52516, 48612, 48617, 52520, 52524, 52528, 48622, 52532, 52536,
+ 48627, 48632, 52540, 52544, 52548, 38648, 48642, 48647, 52552, 48652,
+ 52556, 30109, 52560, 44377, 52564, 48657, 52568, 48662, 48667, 48672,
+ 48677, 48682, 48687, 52572, 52576, 52580, 52584, 52588, 52592, 52596,
+ 52600, 52604, 52608, 52612, 48892, 48697, 52616, 52620, 52624, 52628,
+ 52632, 52636, 52640, 52644, 52648, 52652, 52656, 52660, 1955, 52664,
+ 52668, 52672, 52676, 52680, 52684, 52688, 52692, 52696, 52700, 52704,
+ 52708, 52712, 52716, 52720, 52724, 52728, 52732, 52736, 49167, 46257,
+ 52740, 52744, 27869, 52748, 52752, 45062, 29329, 40769, 40775, 33687,
+ 37276, 52756, 34447, 52760, 52764, 52768, 52772, 52776, 52780, 52784,
+ 52788, 52792, 52796, 52800, 52804, 52808, 52812, 52816, 52820, 52824,
+ 52828, 52832, 52836, 52840, 52844, 52848, 52852, 52856, 52860, 52864,
+ 52868, 52872, 52876, 52880, 52884, 52888, 52892, 52896, 47112, 47117,
+ 46807, 46812, 44422, 46817, 52900, 44427, 52904, 46822, 46827, 44432,
+ 47122, 47127, 47132, 52908, 52912, 52916, 52920, 52924, 52928, 52932,
+ 52936, 52940, 52944, 52948, 52952, 52956, 37626, 52960, 52964, 52968,
+ 44382, 52972, 52976, 52980, 52984, 52988, 52992, 47862, 52996, 44607,
+ 47872, 47877, 44612, 47887, 53000, 47892, 47897, 53004, 47902, 47907,
+ 53008, 53012, 53016, 53020, 53024, 47917, 47922, 47927, 49342, 47932,
+ 53028, 47937, 47942, 47947, 47952, 53032, 48962, 53036, 47957, 47962,
+ 53040, 47967, 53044, 47977, 48747, 47982, 47987, 47992, 47997, 53048,
+ 42474, 36675, 1086, 19640, 49781, 603, 39492, 28980, 27870, 33560, 5572,
+ 19198, 53052, 53055, 53058, 31190, 33296, 4804, 5060, 32504, 50381,
+ 45013, 53061, 37438, 39864, 50369, 32288, 38138, 49533, 5316, 53064,
+ 26516, 53067, 36955, 53070, 36731, 49589, 29110, 50293, 43224, 40230,
+ 974, 53073, 10931, 53076, 24899, 53079, 44743, 34008, 651, 38544, 42522,
+ 31910, 1419, 672, 4868, 6084, 51633, 18896, 49108, 53082, 26571, 23315,
+ 44553, 44748, 51669, 49757, 37704, 23111, 53085, 45893, 22643, 800,
+ 18938, 764, 40410, 44053, 991, 40086, 1155, 38446, 53088, 53091, 23171,
+ 53094, 41826, 28910, 25130, 41046, 32198, 53097, 38642, 23435, 40032,
+ 43290, 53100, 53103, 53106, 53109, 42018, 53112, 51185, 22679, 53115,
+ 22703, 37662, 53118, 53121, 53124, 22139, 53127, 43170, 35872, 25427,
+ 30929, 53130, 53133, 42468, 53136, 5124, 51093, 51305, 38992, 53139,
+ 30452, 50185, 53142, 11036, 27850, 36899, 51661, 31145, 53145, 38761,
+ 51089, 53148, 30479, 26582, 22391, 40218, 37270, 37851, 1127, 10756,
+ 53151, 298, 40518, 51657, 49208, 53154, 41988, 50001, 18951, 24695, 5908,
+ 27900, 19445, 34040, 50189, 22583, 53157, 53160, 53163, 33152, 53166,
+ 18448, 33080, 51085, 53169, 36000, 33800, 39936, 53172, 53175, 53178,
+ 29260, 36710, 53181, 53184, 18378, 53187, 36997, 43134, 53190, 12, 53193,
+ 53196, 5380, 51181, 49553, 53199, 39600, 31028, 623, 36096, 6148, 53202,
+ 53205, 53208, 53211, 33008, 1091, 34120, 53214, 53217, 22739, 53220,
+ 37543, 22451, 53223, 51961, 49168, 53226, 24659, 34112, 51097, 53229,
+ 51189, 28000, 53232, 53235, 53238, 32495, 36339, 50501, 53241, 40686,
+ 53244, 53247, 53250, 53253, 53256, 53259, 42594, 53262, 53265, 53268,
+ 53271, 53274, 53277, 53280, 52541, 53283, 26989, 31019, 53286, 53289,
+ 53292, 53295, 53298, 45888, 51377, 53301, 1178, 285, 53304, 53307, 53310,
+ 26329, 53313, 52673, 53316, 37144, 35760, 53319, 50621, 51393, 53322,
+ 18131, 53325, 4676, 4692, 48873, 53328, 30461, 50525, 24683, 45608,
+ 53331, 53334, 53337, 27440, 5348, 5364, 1476, 53340, 53343, 5588, 53346,
+ 53349, 53352, 53355, 53358, 47158, 24778, 6164, 51429, 53361, 53364,
+ 53367, 51357, 324, 53370, 53373, 53376, 53379, 51541, 38943, 27530,
+ 26395, 40254, 53382, 26384, 1082, 50193, 53385, 42006, 794, 53388, 53391,
+ 53394, 53397, 53400, 53403, 53406, 53409, 53412, 45003, 53415, 52657,
+ 53418, 786, 53421, 40068, 53424, 53427, 53430, 53433, 53436, 53439,
+ 53442, 53445, 45053, 53448, 53451, 44513, 53454, 53457, 53460, 40500,
+ 53463, 53466, 53469, 40776, 29340, 53472, 53475, 53478, 1972, 52233,
+ 53481, 53484, 41154, 53487, 53490, 45998, 53493, 53496, 53499, 53502,
+ 53505, 30011, 53508, 53511, 53514, 37557, 52557, 53517, 53520, 53523,
+ 53526, 40092, 53529, 53532, 18868, 44348, 1032, 46868, 53535, 53538,
+ 39336, 53541, 46773, 53544, 51149, 51881, 53547, 53550, 45813, 53553,
+ 44153, 53556, 52161, 19407, 416, 286, 38237, 1316, 2325, 39973, 21, 38,
+ 32694, 50274, 53559, 30075, 53561, 320, 36305, 53563, 36235, 42469,
+ 49918, 213, 44189, 53565, 479, 34049, 53518, 53567, 919, 40093, 42079,
+ 316, 395, 53569, 885, 30651, 204, 53571, 53329, 53573, 53575, 4, 27891,
+ 1102, 43604, 1115, 36466, 53577, 53579, 24834, 892, 50538, 373, 53200,
+ 771, 88, 51526, 703, 53581, 351, 106, 44484, 53116, 39793, 24867, 39325,
+ 53583, 53585, 35145, 49498, 53587, 53589, 53591, 25164, 43679, 53593,
+ 53595, 34617, 51966, 53597, 8, 1056, 554, 998, 36034, 39, 98, 14, 5, 161,
+ 102, 317, 70, 9, 52, 321, 34, 53225, 401, 171, 404, 523, 53599, 53600,
+};
+
+/* code->name phrasebook */
+#define phrasebook_shift 7
+#define phrasebook_short 226
+static unsigned char phrasebook[] = {
+ 0, 240, 15, 233, 54, 69, 235, 51, 69, 61, 52, 240, 114, 52, 238, 107, 52,
+ 234, 17, 233, 59, 40, 232, 74, 38, 232, 74, 235, 52, 248, 49, 52, 240,
+ 27, 231, 94, 248, 37, 208, 236, 177, 26, 242, 217, 26, 127, 26, 111, 26,
+ 166, 26, 177, 26, 176, 26, 187, 26, 203, 26, 195, 26, 202, 240, 24, 234,
+ 14, 235, 44, 52, 240, 7, 52, 232, 68, 52, 236, 156, 69, 234, 20, 254, 20,
+ 8, 5, 1, 67, 8, 5, 1, 217, 8, 5, 1, 255, 18, 8, 5, 1, 209, 8, 5, 1, 72,
+ 8, 5, 1, 255, 19, 8, 5, 1, 210, 8, 5, 1, 192, 8, 5, 1, 71, 8, 5, 1, 221,
+ 8, 5, 1, 255, 15, 8, 5, 1, 162, 8, 5, 1, 173, 8, 5, 1, 197, 8, 5, 1, 73,
+ 8, 5, 1, 223, 8, 5, 1, 255, 20, 8, 5, 1, 144, 8, 5, 1, 193, 8, 5, 1, 214,
+ 8, 5, 1, 79, 8, 5, 1, 179, 8, 5, 1, 255, 16, 8, 5, 1, 206, 8, 5, 1, 255,
+ 14, 8, 5, 1, 255, 17, 40, 31, 104, 238, 75, 236, 177, 38, 31, 104, 190,
+ 238, 54, 170, 242, 224, 242, 245, 238, 54, 8, 3, 1, 67, 8, 3, 1, 217, 8,
+ 3, 1, 255, 18, 8, 3, 1, 209, 8, 3, 1, 72, 8, 3, 1, 255, 19, 8, 3, 1, 210,
+ 8, 3, 1, 192, 8, 3, 1, 71, 8, 3, 1, 221, 8, 3, 1, 255, 15, 8, 3, 1, 162,
+ 8, 3, 1, 173, 8, 3, 1, 197, 8, 3, 1, 73, 8, 3, 1, 223, 8, 3, 1, 255, 20,
+ 8, 3, 1, 144, 8, 3, 1, 193, 8, 3, 1, 214, 8, 3, 1, 79, 8, 3, 1, 179, 8,
+ 3, 1, 255, 16, 8, 3, 1, 206, 8, 3, 1, 255, 14, 8, 3, 1, 255, 17, 40, 242,
+ 225, 104, 59, 242, 224, 38, 242, 225, 104, 169, 236, 233, 240, 15, 236,
+ 145, 233, 54, 69, 249, 39, 52, 243, 246, 52, 236, 181, 52, 254, 134, 52,
+ 240, 129, 125, 238, 213, 52, 175, 235, 195, 52, 237, 9, 238, 205, 234,
+ 30, 231, 87, 45, 185, 235, 51, 69, 161, 52, 248, 186, 238, 93, 234, 245,
+ 52, 196, 240, 112, 52, 234, 236, 52, 233, 49, 111, 233, 49, 166, 242,
+ 241, 238, 54, 246, 81, 52, 238, 208, 52, 240, 1, 248, 40, 236, 151, 233,
+ 49, 127, 236, 58, 238, 205, 234, 30, 231, 36, 45, 185, 235, 51, 69, 240,
+ 30, 236, 155, 253, 125, 237, 33, 240, 30, 236, 155, 253, 125, 243, 7,
+ 240, 30, 236, 155, 204, 236, 84, 236, 145, 236, 156, 69, 8, 5, 1, 134, 2,
+ 191, 8, 5, 1, 134, 2, 135, 8, 5, 1, 134, 2, 233, 48, 8, 5, 1, 134, 2,
+ 169, 8, 5, 1, 134, 2, 175, 8, 5, 1, 134, 2, 248, 51, 48, 8, 5, 1, 253,
+ 178, 8, 5, 1, 255, 105, 2, 236, 151, 8, 5, 1, 157, 2, 191, 8, 5, 1, 157,
+ 2, 135, 8, 5, 1, 157, 2, 233, 48, 8, 5, 1, 157, 2, 175, 8, 5, 1, 220, 2,
+ 191, 8, 5, 1, 220, 2, 135, 8, 5, 1, 220, 2, 233, 48, 8, 5, 1, 220, 2,
+ 175, 8, 5, 1, 248, 109, 8, 5, 1, 255, 98, 2, 169, 8, 5, 1, 117, 2, 191,
+ 8, 5, 1, 117, 2, 135, 8, 5, 1, 117, 2, 233, 48, 8, 5, 1, 117, 2, 169, 8,
+ 5, 1, 117, 2, 175, 231, 37, 52, 8, 5, 1, 117, 2, 108, 8, 5, 1, 132, 2,
+ 191, 8, 5, 1, 132, 2, 135, 8, 5, 1, 132, 2, 233, 48, 8, 5, 1, 132, 2,
+ 175, 8, 5, 1, 255, 107, 2, 135, 8, 5, 1, 240, 149, 8, 3, 1, 243, 74, 193,
+ 8, 3, 1, 134, 2, 191, 8, 3, 1, 134, 2, 135, 8, 3, 1, 134, 2, 233, 48, 8,
+ 3, 1, 134, 2, 169, 8, 3, 1, 134, 2, 175, 8, 3, 1, 134, 2, 248, 51, 48, 8,
+ 3, 1, 253, 178, 8, 3, 1, 255, 105, 2, 236, 151, 8, 3, 1, 157, 2, 191, 8,
+ 3, 1, 157, 2, 135, 8, 3, 1, 157, 2, 233, 48, 8, 3, 1, 157, 2, 175, 8, 3,
+ 1, 220, 2, 191, 8, 3, 1, 220, 2, 135, 8, 3, 1, 220, 2, 233, 48, 8, 3, 1,
+ 220, 2, 175, 8, 3, 1, 248, 109, 8, 3, 1, 255, 98, 2, 169, 8, 3, 1, 117,
+ 2, 191, 8, 3, 1, 117, 2, 135, 8, 3, 1, 117, 2, 233, 48, 8, 3, 1, 117, 2,
+ 169, 8, 3, 1, 117, 2, 175, 236, 196, 52, 8, 3, 1, 117, 2, 108, 8, 3, 1,
+ 132, 2, 191, 8, 3, 1, 132, 2, 135, 8, 3, 1, 132, 2, 233, 48, 8, 3, 1,
+ 132, 2, 175, 8, 3, 1, 255, 107, 2, 135, 8, 3, 1, 240, 149, 8, 3, 1, 255,
+ 107, 2, 175, 8, 5, 1, 134, 2, 196, 8, 3, 1, 134, 2, 196, 8, 5, 1, 134, 2,
+ 239, 255, 8, 3, 1, 134, 2, 239, 255, 8, 5, 1, 134, 2, 238, 71, 8, 3, 1,
+ 134, 2, 238, 71, 8, 5, 1, 255, 105, 2, 135, 8, 3, 1, 255, 105, 2, 135, 8,
+ 5, 1, 255, 105, 2, 233, 48, 8, 3, 1, 255, 105, 2, 233, 48, 8, 5, 1, 255,
+ 105, 2, 53, 48, 8, 3, 1, 255, 105, 2, 53, 48, 8, 5, 1, 255, 105, 2, 239,
+ 254, 8, 3, 1, 255, 105, 2, 239, 254, 8, 5, 1, 255, 103, 2, 239, 254, 8,
+ 3, 1, 255, 103, 2, 239, 254, 8, 5, 1, 255, 103, 2, 108, 8, 3, 1, 255,
+ 103, 2, 108, 8, 5, 1, 157, 2, 196, 8, 3, 1, 157, 2, 196, 8, 5, 1, 157, 2,
+ 239, 255, 8, 3, 1, 157, 2, 239, 255, 8, 5, 1, 157, 2, 53, 48, 8, 3, 1,
+ 157, 2, 53, 48, 8, 5, 1, 157, 2, 238, 71, 8, 3, 1, 157, 2, 238, 71, 8, 5,
+ 1, 157, 2, 239, 254, 8, 3, 1, 157, 2, 239, 254, 8, 5, 1, 255, 104, 2,
+ 233, 48, 8, 3, 1, 255, 104, 2, 233, 48, 8, 5, 1, 255, 104, 2, 239, 255,
+ 8, 3, 1, 255, 104, 2, 239, 255, 8, 5, 1, 255, 104, 2, 53, 48, 8, 3, 1,
+ 255, 104, 2, 53, 48, 8, 5, 1, 255, 104, 2, 236, 151, 8, 3, 1, 255, 104,
+ 2, 236, 151, 8, 5, 1, 255, 106, 2, 233, 48, 8, 3, 1, 255, 106, 2, 233,
+ 48, 8, 5, 1, 255, 106, 2, 108, 8, 3, 1, 255, 106, 2, 108, 8, 5, 1, 220,
+ 2, 169, 8, 3, 1, 220, 2, 169, 8, 5, 1, 220, 2, 196, 8, 3, 1, 220, 2, 196,
+ 8, 5, 1, 220, 2, 239, 255, 8, 3, 1, 220, 2, 239, 255, 8, 5, 1, 220, 2,
+ 238, 71, 8, 3, 1, 220, 2, 238, 71, 8, 5, 1, 220, 2, 53, 48, 8, 3, 1, 238,
+ 70, 71, 8, 5, 18, 254, 99, 8, 3, 18, 254, 99, 8, 5, 1, 255, 115, 2, 233,
+ 48, 8, 3, 1, 255, 115, 2, 233, 48, 8, 5, 1, 255, 109, 2, 236, 151, 8, 3,
+ 1, 255, 109, 2, 236, 151, 8, 3, 1, 251, 164, 8, 5, 1, 255, 100, 2, 135,
+ 8, 3, 1, 255, 100, 2, 135, 8, 5, 1, 255, 100, 2, 236, 151, 8, 3, 1, 255,
+ 100, 2, 236, 151, 8, 5, 1, 255, 100, 2, 239, 254, 8, 3, 1, 255, 100, 2,
+ 239, 254, 8, 5, 1, 255, 100, 2, 240, 1, 248, 40, 8, 3, 1, 255, 100, 2,
+ 240, 1, 248, 40, 8, 5, 1, 255, 100, 2, 108, 8, 3, 1, 255, 100, 2, 108, 8,
+ 5, 1, 255, 98, 2, 135, 8, 3, 1, 255, 98, 2, 135, 8, 5, 1, 255, 98, 2,
+ 236, 151, 8, 3, 1, 255, 98, 2, 236, 151, 8, 5, 1, 255, 98, 2, 239, 254,
+ 8, 3, 1, 255, 98, 2, 239, 254, 8, 3, 1, 255, 98, 237, 241, 255, 25, 233,
+ 59, 8, 5, 1, 248, 108, 8, 3, 1, 248, 108, 8, 5, 1, 117, 2, 196, 8, 3, 1,
+ 117, 2, 196, 8, 5, 1, 117, 2, 239, 255, 8, 3, 1, 117, 2, 239, 255, 8, 5,
+ 1, 117, 2, 45, 135, 8, 3, 1, 117, 2, 45, 135, 8, 5, 18, 253, 193, 8, 3,
+ 18, 253, 193, 8, 5, 1, 255, 101, 2, 135, 8, 3, 1, 255, 101, 2, 135, 8, 5,
+ 1, 255, 101, 2, 236, 151, 8, 3, 1, 255, 101, 2, 236, 151, 8, 5, 1, 255,
+ 101, 2, 239, 254, 8, 3, 1, 255, 101, 2, 239, 254, 8, 5, 1, 255, 99, 2,
+ 135, 8, 3, 1, 255, 99, 2, 135, 8, 5, 1, 255, 99, 2, 233, 48, 8, 3, 1,
+ 255, 99, 2, 233, 48, 8, 5, 1, 255, 99, 2, 236, 151, 8, 3, 1, 255, 99, 2,
+ 236, 151, 8, 5, 1, 255, 99, 2, 239, 254, 8, 3, 1, 255, 99, 2, 239, 254,
+ 8, 5, 1, 255, 102, 2, 236, 151, 8, 3, 1, 255, 102, 2, 236, 151, 8, 5, 1,
+ 255, 102, 2, 239, 254, 8, 3, 1, 255, 102, 2, 239, 254, 8, 5, 1, 255, 102,
+ 2, 108, 8, 3, 1, 255, 102, 2, 108, 8, 5, 1, 132, 2, 169, 8, 3, 1, 132, 2,
+ 169, 8, 5, 1, 132, 2, 196, 8, 3, 1, 132, 2, 196, 8, 5, 1, 132, 2, 239,
+ 255, 8, 3, 1, 132, 2, 239, 255, 8, 5, 1, 132, 2, 248, 51, 48, 8, 3, 1,
+ 132, 2, 248, 51, 48, 8, 5, 1, 132, 2, 45, 135, 8, 3, 1, 132, 2, 45, 135,
+ 8, 5, 1, 132, 2, 238, 71, 8, 3, 1, 132, 2, 238, 71, 8, 5, 1, 255, 111, 2,
+ 233, 48, 8, 3, 1, 255, 111, 2, 233, 48, 8, 5, 1, 255, 107, 2, 233, 48, 8,
+ 3, 1, 255, 107, 2, 233, 48, 8, 5, 1, 255, 107, 2, 175, 8, 5, 1, 255, 97,
+ 2, 135, 8, 3, 1, 255, 97, 2, 135, 8, 5, 1, 255, 97, 2, 53, 48, 8, 3, 1,
+ 255, 97, 2, 53, 48, 8, 5, 1, 255, 97, 2, 239, 254, 8, 3, 1, 255, 97, 2,
+ 239, 254, 8, 3, 1, 183, 193, 8, 3, 1, 41, 2, 108, 8, 5, 1, 41, 2, 90, 8,
+ 5, 1, 41, 2, 238, 124, 8, 3, 1, 41, 2, 238, 124, 8, 5, 1, 188, 187, 8, 3,
+ 1, 188, 187, 8, 5, 1, 248, 35, 73, 8, 5, 1, 255, 105, 2, 90, 8, 3, 1,
+ 255, 105, 2, 90, 8, 5, 1, 238, 238, 209, 8, 5, 1, 255, 103, 2, 90, 8, 5,
+ 1, 255, 103, 2, 238, 124, 8, 3, 1, 255, 103, 2, 238, 124, 8, 3, 1, 205,
+ 240, 28, 8, 5, 1, 224, 72, 8, 5, 1, 240, 86, 8, 5, 1, 248, 35, 72, 8, 5,
+ 1, 255, 112, 2, 90, 8, 3, 1, 255, 112, 2, 90, 8, 5, 1, 255, 104, 2, 90,
+ 8, 5, 1, 240, 10, 8, 3, 1, 254, 98, 8, 5, 1, 242, 237, 8, 5, 1, 220, 2,
+ 108, 8, 5, 1, 255, 109, 2, 90, 8, 3, 1, 255, 109, 2, 90, 8, 3, 1, 255,
+ 100, 2, 125, 8, 3, 1, 241, 212, 2, 108, 8, 5, 1, 205, 173, 8, 5, 1, 255,
+ 98, 2, 40, 90, 8, 3, 1, 255, 98, 2, 183, 38, 248, 117, 8, 5, 1, 117, 2,
+ 240, 1, 169, 8, 5, 1, 117, 2, 243, 8, 8, 3, 1, 117, 2, 243, 8, 8, 5, 1,
+ 254, 42, 8, 3, 1, 254, 42, 8, 5, 1, 255, 114, 2, 90, 8, 3, 1, 255, 114,
+ 2, 90, 8, 1, 254, 135, 8, 5, 1, 188, 111, 8, 3, 1, 188, 111, 8, 5, 1,
+ 248, 93, 8, 1, 224, 254, 38, 243, 105, 8, 3, 1, 255, 102, 2, 238, 65, 90,
+ 8, 5, 1, 255, 102, 2, 90, 8, 3, 1, 255, 102, 2, 90, 8, 5, 1, 255, 102, 2,
+ 235, 54, 90, 8, 5, 1, 132, 2, 243, 8, 8, 3, 1, 132, 2, 243, 8, 8, 5, 1,
+ 236, 160, 8, 5, 1, 255, 110, 2, 90, 8, 5, 1, 255, 107, 2, 90, 8, 3, 1,
+ 255, 107, 2, 90, 8, 5, 1, 255, 97, 2, 108, 8, 3, 1, 255, 97, 2, 108, 8,
+ 5, 1, 248, 155, 8, 5, 1, 253, 244, 235, 142, 8, 3, 1, 253, 244, 235, 142,
+ 8, 3, 1, 253, 244, 2, 242, 226, 8, 1, 171, 2, 108, 8, 5, 1, 188, 176, 8,
+ 3, 1, 188, 176, 8, 1, 236, 145, 238, 62, 248, 119, 2, 108, 8, 1, 244, 54,
+ 8, 1, 241, 82, 240, 93, 8, 1, 239, 114, 240, 93, 8, 1, 237, 59, 240, 93,
+ 8, 1, 235, 54, 240, 93, 8, 5, 1, 255, 40, 2, 239, 254, 8, 5, 1, 255, 103,
+ 2, 3, 1, 255, 97, 2, 239, 254, 8, 3, 1, 255, 40, 2, 239, 254, 8, 5, 1,
+ 254, 109, 8, 5, 1, 255, 100, 2, 3, 1, 221, 8, 3, 1, 254, 109, 8, 5, 1,
+ 254, 113, 8, 5, 1, 255, 98, 2, 3, 1, 221, 8, 3, 1, 254, 113, 8, 5, 1,
+ 134, 2, 239, 254, 8, 3, 1, 134, 2, 239, 254, 8, 5, 1, 220, 2, 239, 254,
+ 8, 3, 1, 220, 2, 239, 254, 8, 5, 1, 117, 2, 239, 254, 8, 3, 1, 117, 2,
+ 239, 254, 8, 5, 1, 132, 2, 239, 254, 8, 3, 1, 132, 2, 239, 254, 8, 5, 1,
+ 132, 2, 235, 56, 19, 196, 8, 3, 1, 132, 2, 235, 56, 19, 196, 8, 5, 1,
+ 132, 2, 235, 56, 19, 135, 8, 3, 1, 132, 2, 235, 56, 19, 135, 8, 5, 1,
+ 132, 2, 235, 56, 19, 239, 254, 8, 3, 1, 132, 2, 235, 56, 19, 239, 254, 8,
+ 5, 1, 132, 2, 235, 56, 19, 191, 8, 3, 1, 132, 2, 235, 56, 19, 191, 8, 3,
+ 1, 205, 72, 8, 5, 1, 134, 2, 235, 56, 19, 196, 8, 3, 1, 134, 2, 235, 56,
+ 19, 196, 8, 5, 1, 134, 2, 53, 60, 19, 196, 8, 3, 1, 134, 2, 53, 60, 19,
+ 196, 8, 5, 1, 255, 30, 2, 196, 8, 3, 1, 255, 30, 2, 196, 8, 5, 1, 255,
+ 104, 2, 108, 8, 3, 1, 255, 104, 2, 108, 8, 5, 1, 255, 104, 2, 239, 254,
+ 8, 3, 1, 255, 104, 2, 239, 254, 8, 5, 1, 255, 109, 2, 239, 254, 8, 3, 1,
+ 255, 109, 2, 239, 254, 8, 5, 1, 117, 2, 238, 71, 8, 3, 1, 117, 2, 238,
+ 71, 8, 5, 1, 117, 2, 240, 204, 19, 196, 8, 3, 1, 117, 2, 240, 204, 19,
+ 196, 8, 5, 1, 253, 244, 2, 239, 254, 8, 3, 1, 253, 244, 2, 239, 254, 8,
+ 3, 1, 255, 115, 2, 239, 254, 8, 5, 1, 254, 88, 8, 5, 1, 255, 103, 2, 3,
+ 1, 255, 17, 8, 3, 1, 254, 88, 8, 5, 1, 255, 104, 2, 135, 8, 3, 1, 255,
+ 104, 2, 135, 8, 5, 1, 240, 190, 8, 5, 1, 244, 54, 8, 5, 1, 255, 98, 2,
+ 191, 8, 3, 1, 255, 98, 2, 191, 8, 5, 1, 134, 2, 248, 51, 60, 19, 135, 8,
+ 3, 1, 134, 2, 248, 51, 60, 19, 135, 8, 5, 1, 255, 30, 2, 135, 8, 3, 1,
+ 255, 30, 2, 135, 8, 5, 1, 117, 2, 240, 5, 19, 135, 8, 3, 1, 117, 2, 240,
+ 5, 19, 135, 8, 5, 1, 134, 2, 45, 191, 8, 3, 1, 134, 2, 45, 191, 8, 5, 1,
+ 134, 2, 236, 145, 239, 255, 8, 3, 1, 134, 2, 236, 145, 239, 255, 8, 5, 1,
+ 157, 2, 45, 191, 8, 3, 1, 157, 2, 45, 191, 8, 5, 1, 157, 2, 236, 145,
+ 239, 255, 8, 3, 1, 157, 2, 236, 145, 239, 255, 8, 5, 1, 220, 2, 45, 191,
+ 8, 3, 1, 220, 2, 45, 191, 8, 5, 1, 220, 2, 236, 145, 239, 255, 8, 3, 1,
+ 220, 2, 236, 145, 239, 255, 8, 5, 1, 117, 2, 45, 191, 8, 3, 1, 117, 2,
+ 45, 191, 8, 5, 1, 117, 2, 236, 145, 239, 255, 8, 3, 1, 117, 2, 236, 145,
+ 239, 255, 8, 5, 1, 255, 101, 2, 45, 191, 8, 3, 1, 255, 101, 2, 45, 191,
+ 8, 5, 1, 255, 101, 2, 236, 145, 239, 255, 8, 3, 1, 255, 101, 2, 236, 145,
+ 239, 255, 8, 5, 1, 132, 2, 45, 191, 8, 3, 1, 132, 2, 45, 191, 8, 5, 1,
+ 132, 2, 236, 145, 239, 255, 8, 3, 1, 132, 2, 236, 145, 239, 255, 8, 5, 1,
+ 255, 99, 2, 242, 244, 46, 8, 3, 1, 255, 99, 2, 242, 244, 46, 8, 5, 1,
+ 255, 102, 2, 242, 244, 46, 8, 3, 1, 255, 102, 2, 242, 244, 46, 8, 5, 1,
+ 244, 59, 8, 3, 1, 244, 59, 8, 5, 1, 255, 106, 2, 239, 254, 8, 3, 1, 255,
+ 106, 2, 239, 254, 8, 5, 1, 255, 98, 2, 183, 38, 248, 117, 8, 3, 1, 255,
+ 103, 2, 242, 253, 8, 5, 1, 254, 10, 8, 3, 1, 254, 10, 8, 5, 1, 255, 97,
+ 2, 90, 8, 3, 1, 255, 97, 2, 90, 8, 5, 1, 134, 2, 53, 48, 8, 3, 1, 134, 2,
+ 53, 48, 8, 5, 1, 157, 2, 236, 151, 8, 3, 1, 157, 2, 236, 151, 8, 5, 1,
+ 117, 2, 235, 56, 19, 196, 8, 3, 1, 117, 2, 235, 56, 19, 196, 8, 5, 1,
+ 117, 2, 242, 219, 19, 196, 8, 3, 1, 117, 2, 242, 219, 19, 196, 8, 5, 1,
+ 117, 2, 53, 48, 8, 3, 1, 117, 2, 53, 48, 8, 5, 1, 117, 2, 53, 60, 19,
+ 196, 8, 3, 1, 117, 2, 53, 60, 19, 196, 8, 5, 1, 255, 107, 2, 196, 8, 3,
+ 1, 255, 107, 2, 196, 8, 3, 1, 255, 100, 2, 242, 253, 8, 3, 1, 255, 98, 2,
+ 242, 253, 8, 3, 1, 255, 102, 2, 242, 253, 8, 3, 1, 238, 70, 221, 8, 3, 1,
+ 255, 71, 236, 182, 8, 3, 1, 255, 89, 236, 182, 8, 5, 1, 134, 2, 108, 8,
+ 5, 1, 255, 105, 2, 108, 8, 3, 1, 255, 105, 2, 108, 8, 5, 1, 255, 100, 2,
+ 125, 8, 5, 1, 255, 102, 2, 236, 159, 108, 8, 3, 1, 255, 99, 2, 243, 126,
+ 242, 226, 8, 3, 1, 255, 97, 2, 243, 126, 242, 226, 8, 5, 1, 238, 62, 208,
+ 8, 3, 1, 205, 67, 8, 3, 1, 240, 22, 8, 3, 1, 205, 240, 22, 8, 3, 1, 41,
+ 2, 90, 8, 3, 1, 248, 35, 73, 8, 3, 1, 255, 105, 2, 242, 253, 8, 3, 1,
+ 255, 103, 2, 242, 226, 8, 3, 1, 255, 103, 2, 90, 8, 3, 1, 224, 72, 8, 3,
+ 1, 240, 86, 8, 3, 1, 243, 73, 2, 90, 8, 3, 1, 248, 35, 72, 8, 3, 1, 224,
+ 248, 35, 72, 8, 3, 1, 224, 248, 35, 157, 2, 90, 8, 3, 1, 240, 23, 224,
+ 248, 35, 72, 8, 3, 1, 238, 70, 255, 115, 2, 108, 8, 3, 1, 255, 104, 2,
+ 90, 8, 3, 1, 84, 210, 8, 1, 3, 5, 210, 8, 3, 1, 240, 10, 8, 3, 1, 252,
+ 129, 243, 8, 8, 3, 1, 205, 192, 8, 3, 1, 255, 106, 2, 90, 8, 3, 1, 251,
+ 52, 2, 90, 8, 3, 1, 220, 2, 108, 8, 3, 1, 242, 237, 8, 1, 3, 5, 71, 8, 3,
+ 1, 255, 100, 2, 240, 1, 169, 8, 3, 1, 255, 100, 2, 244, 216, 8, 3, 1,
+ 255, 100, 2, 235, 54, 90, 8, 3, 1, 246, 43, 8, 3, 1, 205, 173, 8, 3, 1,
+ 205, 255, 108, 2, 183, 248, 117, 8, 3, 1, 255, 108, 2, 90, 8, 3, 1, 255,
+ 98, 2, 40, 90, 8, 3, 1, 255, 98, 2, 235, 54, 90, 8, 1, 3, 5, 197, 8, 3,
+ 1, 240, 60, 73, 8, 1, 3, 5, 253, 193, 8, 3, 1, 240, 23, 240, 20, 8, 3, 1,
+ 248, 68, 8, 3, 1, 205, 144, 8, 3, 1, 205, 255, 101, 2, 183, 248, 117, 8,
+ 3, 1, 205, 255, 101, 2, 90, 8, 3, 1, 255, 101, 2, 183, 248, 117, 8, 3, 1,
+ 255, 101, 2, 242, 226, 8, 3, 1, 255, 101, 2, 235, 100, 8, 3, 1, 224, 255,
+ 101, 2, 235, 100, 8, 1, 3, 5, 144, 8, 1, 3, 5, 236, 145, 144, 8, 3, 1,
+ 255, 99, 2, 90, 8, 3, 1, 248, 93, 8, 3, 1, 238, 70, 255, 115, 2, 240, 5,
+ 19, 90, 8, 3, 1, 244, 23, 224, 248, 93, 8, 3, 1, 254, 38, 2, 242, 253, 8,
+ 3, 1, 205, 214, 8, 3, 1, 255, 102, 2, 235, 54, 90, 8, 3, 1, 132, 125, 8,
+ 3, 1, 236, 160, 8, 3, 1, 255, 110, 2, 90, 8, 3, 1, 205, 179, 8, 3, 1,
+ 205, 255, 16, 8, 3, 1, 205, 255, 14, 8, 1, 3, 5, 255, 14, 8, 3, 1, 255,
+ 97, 2, 235, 54, 90, 8, 3, 1, 255, 97, 2, 242, 253, 8, 3, 1, 248, 155, 8,
+ 3, 1, 253, 244, 2, 242, 253, 8, 1, 238, 62, 208, 8, 1, 234, 12, 240, 59,
+ 234, 192, 8, 1, 236, 145, 238, 62, 208, 8, 1, 236, 110, 255, 18, 8, 1,
+ 236, 249, 240, 93, 8, 1, 3, 5, 217, 8, 3, 1, 240, 23, 248, 35, 72, 8, 1,
+ 3, 5, 255, 104, 2, 90, 8, 1, 3, 5, 192, 8, 3, 1, 255, 115, 2, 231, 101,
+ 8, 3, 1, 205, 255, 15, 8, 1, 3, 5, 162, 8, 3, 1, 255, 116, 2, 90, 8, 1,
+ 238, 62, 248, 119, 2, 108, 8, 1, 224, 238, 62, 248, 119, 2, 108, 8, 3, 1,
+ 255, 40, 236, 182, 8, 3, 1, 250, 192, 236, 182, 8, 3, 1, 255, 40, 238,
+ 112, 2, 242, 253, 8, 3, 1, 255, 94, 236, 182, 8, 3, 1, 252, 215, 236,
+ 182, 8, 3, 1, 255, 92, 238, 112, 2, 242, 253, 8, 3, 1, 250, 239, 236,
+ 182, 8, 3, 1, 255, 78, 236, 182, 8, 3, 1, 255, 79, 236, 182, 8, 1, 236,
+ 249, 233, 95, 8, 1, 237, 77, 233, 95, 8, 3, 1, 205, 255, 106, 2, 235,
+ 100, 8, 3, 1, 205, 255, 106, 2, 237, 11, 19, 242, 226, 49, 1, 3, 192, 49,
+ 1, 3, 255, 106, 2, 90, 49, 1, 3, 221, 49, 1, 3, 144, 49, 1, 3, 205, 144,
+ 49, 1, 3, 205, 255, 101, 2, 90, 49, 1, 3, 5, 236, 145, 144, 49, 1, 3,
+ 255, 16, 49, 1, 3, 255, 14, 49, 1, 240, 57, 49, 1, 45, 240, 57, 49, 1,
+ 205, 240, 27, 49, 1, 233, 59, 49, 1, 224, 240, 27, 49, 1, 38, 137, 242,
+ 233, 49, 1, 40, 137, 242, 233, 49, 1, 238, 62, 208, 49, 1, 224, 238, 62,
+ 208, 49, 1, 40, 234, 7, 49, 1, 38, 234, 7, 49, 1, 88, 234, 7, 49, 1, 92,
+ 234, 7, 49, 1, 190, 238, 54, 239, 254, 49, 1, 59, 242, 224, 49, 1, 196,
+ 49, 1, 242, 241, 238, 54, 49, 1, 242, 245, 238, 54, 49, 1, 170, 59, 242,
+ 224, 49, 1, 170, 196, 49, 1, 170, 242, 245, 238, 54, 49, 1, 170, 242,
+ 241, 238, 54, 49, 1, 234, 43, 240, 24, 49, 1, 137, 234, 43, 240, 24, 49,
+ 1, 238, 130, 38, 137, 242, 233, 49, 1, 238, 130, 40, 137, 242, 233, 49,
+ 1, 88, 242, 234, 49, 1, 92, 242, 234, 49, 1, 248, 49, 52, 49, 1, 242,
+ 250, 52, 239, 255, 53, 48, 248, 51, 48, 238, 71, 3, 169, 45, 242, 241,
+ 238, 54, 49, 1, 242, 83, 90, 49, 1, 243, 38, 238, 54, 49, 1, 3, 240, 10,
+ 49, 1, 3, 162, 49, 1, 3, 193, 49, 1, 3, 206, 49, 1, 3, 224, 238, 62, 208,
+ 49, 1, 234, 27, 188, 125, 49, 1, 200, 188, 125, 49, 1, 254, 40, 188, 125,
+ 49, 1, 170, 188, 125, 49, 1, 235, 87, 188, 125, 49, 1, 254, 15, 235, 98,
+ 188, 69, 49, 1, 248, 122, 235, 98, 188, 69, 49, 1, 238, 44, 49, 1, 233,
+ 47, 49, 1, 45, 233, 59, 49, 1, 170, 92, 234, 7, 49, 1, 170, 88, 234, 7,
+ 49, 1, 170, 40, 234, 7, 49, 1, 170, 38, 234, 7, 49, 1, 170, 242, 233, 49,
+ 1, 240, 1, 242, 245, 238, 54, 49, 1, 240, 1, 45, 242, 245, 238, 54, 49,
+ 1, 240, 1, 45, 242, 241, 238, 54, 49, 1, 170, 169, 49, 1, 240, 84, 240,
+ 24, 49, 1, 243, 24, 200, 243, 78, 49, 1, 253, 165, 200, 243, 78, 49, 1,
+ 243, 24, 170, 243, 78, 49, 1, 253, 165, 170, 243, 78, 49, 1, 240, 226,
+ 49, 1, 248, 35, 240, 226, 49, 1, 170, 40, 56, 50, 242, 245, 238, 54, 50,
+ 242, 241, 238, 54, 50, 190, 238, 54, 50, 169, 50, 196, 50, 235, 74, 50,
+ 239, 255, 50, 53, 48, 50, 175, 50, 248, 45, 48, 50, 248, 51, 48, 50, 45,
+ 242, 241, 238, 54, 50, 239, 254, 50, 59, 248, 41, 48, 50, 45, 59, 248,
+ 41, 48, 50, 45, 242, 245, 238, 54, 50, 232, 77, 50, 236, 145, 239, 255,
+ 50, 205, 242, 244, 48, 50, 242, 244, 48, 50, 224, 242, 244, 48, 50, 242,
+ 244, 60, 225, 50, 242, 245, 240, 2, 46, 50, 242, 241, 240, 2, 46, 50, 40,
+ 248, 84, 46, 50, 38, 248, 84, 46, 50, 40, 185, 48, 50, 243, 8, 50, 40,
+ 137, 248, 51, 46, 50, 88, 248, 84, 46, 50, 92, 248, 84, 46, 50, 248, 49,
+ 21, 46, 50, 242, 250, 21, 46, 50, 233, 222, 248, 45, 46, 50, 235, 54,
+ 248, 45, 46, 50, 53, 46, 50, 235, 56, 46, 50, 248, 51, 46, 50, 242, 244,
+ 46, 50, 236, 151, 50, 238, 71, 50, 59, 248, 41, 46, 50, 240, 109, 46, 50,
+ 236, 145, 45, 249, 239, 46, 50, 243, 86, 46, 50, 190, 240, 2, 46, 50,
+ 242, 243, 46, 50, 236, 145, 242, 243, 46, 50, 242, 219, 46, 50, 240, 42,
+ 46, 50, 170, 242, 224, 50, 45, 170, 242, 224, 50, 242, 219, 236, 161, 50,
+ 242, 215, 240, 5, 236, 161, 50, 183, 240, 5, 236, 161, 50, 242, 215, 238,
+ 83, 236, 161, 50, 183, 238, 83, 236, 161, 50, 38, 137, 248, 51, 46, 50,
+ 236, 145, 240, 109, 46, 50, 31, 46, 50, 239, 184, 46, 50, 255, 113, 48,
+ 50, 59, 169, 50, 45, 235, 74, 50, 242, 245, 188, 69, 50, 242, 241, 188,
+ 69, 50, 17, 232, 71, 50, 17, 236, 229, 50, 17, 235, 59, 240, 16, 50, 17,
+ 231, 35, 50, 240, 109, 48, 50, 240, 7, 21, 46, 50, 45, 59, 248, 41, 46,
+ 50, 40, 185, 46, 50, 161, 242, 219, 48, 50, 234, 200, 48, 50, 240, 40,
+ 95, 153, 48, 50, 40, 38, 65, 46, 50, 226, 226, 65, 46, 50, 237, 166, 238,
+ 140, 50, 38, 235, 76, 48, 50, 40, 137, 248, 51, 48, 50, 237, 10, 50, 255,
+ 113, 46, 50, 40, 235, 76, 46, 50, 38, 235, 76, 46, 50, 38, 235, 76, 19,
+ 88, 235, 76, 46, 50, 38, 137, 248, 51, 48, 50, 53, 60, 225, 50, 236, 219,
+ 46, 50, 45, 248, 51, 46, 50, 240, 126, 48, 50, 45, 242, 243, 46, 50, 45,
+ 239, 255, 50, 45, 196, 50, 45, 240, 42, 46, 50, 45, 169, 50, 45, 236,
+ 145, 239, 255, 50, 45, 77, 65, 46, 50, 8, 3, 1, 67, 50, 8, 3, 1, 72, 50,
+ 8, 3, 1, 71, 50, 8, 3, 1, 73, 50, 8, 3, 1, 79, 50, 8, 3, 1, 255, 18, 50,
+ 8, 3, 1, 209, 50, 8, 3, 1, 192, 50, 8, 3, 1, 173, 50, 8, 3, 1, 144, 50,
+ 8, 3, 1, 214, 50, 8, 3, 1, 179, 50, 8, 3, 1, 206, 17, 178, 52, 17, 168,
+ 178, 52, 17, 231, 35, 17, 236, 156, 69, 17, 240, 16, 17, 235, 59, 240,
+ 16, 17, 5, 1, 194, 2, 240, 16, 17, 254, 140, 238, 223, 17, 5, 1, 238, 57,
+ 2, 240, 16, 17, 5, 1, 253, 123, 2, 240, 16, 17, 5, 1, 248, 42, 2, 240,
+ 16, 17, 5, 1, 238, 64, 2, 240, 16, 17, 5, 1, 238, 53, 2, 240, 16, 17, 5,
+ 1, 211, 2, 240, 16, 17, 3, 1, 248, 42, 2, 235, 59, 19, 240, 16, 17, 5, 1,
+ 240, 22, 17, 5, 1, 242, 242, 17, 5, 1, 240, 10, 17, 5, 1, 240, 28, 17, 5,
+ 1, 236, 165, 17, 5, 1, 242, 251, 17, 5, 1, 248, 87, 17, 5, 1, 240, 38,
+ 17, 5, 1, 242, 237, 17, 5, 1, 240, 41, 17, 5, 1, 240, 33, 17, 5, 1, 253,
+ 154, 17, 5, 1, 253, 150, 17, 5, 1, 253, 188, 17, 5, 1, 236, 169, 17, 5,
+ 1, 253, 147, 17, 5, 1, 248, 73, 17, 5, 1, 240, 21, 17, 5, 1, 248, 85, 17,
+ 5, 1, 236, 160, 17, 5, 1, 248, 68, 17, 5, 1, 248, 67, 17, 5, 1, 248, 69,
+ 17, 5, 1, 240, 20, 17, 5, 1, 248, 42, 2, 234, 26, 17, 5, 1, 238, 53, 2,
+ 234, 26, 17, 3, 1, 194, 2, 240, 16, 17, 3, 1, 238, 57, 2, 240, 16, 17, 3,
+ 1, 253, 123, 2, 240, 16, 17, 3, 1, 248, 42, 2, 240, 16, 17, 3, 1, 238,
+ 53, 2, 235, 59, 19, 240, 16, 17, 3, 1, 240, 22, 17, 3, 1, 242, 242, 17,
+ 3, 1, 240, 10, 17, 3, 1, 240, 28, 17, 3, 1, 236, 165, 17, 3, 1, 242, 251,
+ 17, 3, 1, 248, 87, 17, 3, 1, 240, 38, 17, 3, 1, 242, 237, 17, 3, 1, 240,
+ 41, 17, 3, 1, 240, 33, 17, 3, 1, 253, 154, 17, 3, 1, 253, 150, 17, 3, 1,
+ 253, 188, 17, 3, 1, 236, 169, 17, 3, 1, 253, 147, 17, 3, 1, 248, 73, 17,
+ 3, 1, 30, 240, 21, 17, 3, 1, 240, 21, 17, 3, 1, 248, 85, 17, 3, 1, 236,
+ 160, 17, 3, 1, 248, 68, 17, 3, 1, 248, 67, 17, 3, 1, 248, 69, 17, 3, 1,
+ 240, 20, 17, 3, 1, 248, 42, 2, 234, 26, 17, 3, 1, 238, 53, 2, 234, 26,
+ 17, 3, 1, 238, 64, 2, 240, 16, 17, 3, 1, 238, 53, 2, 240, 16, 17, 3, 1,
+ 211, 2, 240, 16, 17, 250, 118, 91, 17, 243, 0, 91, 17, 238, 53, 2, 248,
+ 45, 91, 17, 238, 53, 2, 242, 241, 19, 248, 45, 91, 17, 238, 53, 2, 235,
+ 56, 19, 248, 45, 91, 17, 254, 11, 91, 17, 255, 29, 91, 17, 254, 65, 91,
+ 17, 1, 238, 162, 240, 77, 17, 3, 1, 238, 162, 240, 77, 17, 1, 238, 152,
+ 17, 3, 1, 238, 152, 17, 1, 237, 6, 17, 3, 1, 237, 6, 17, 1, 240, 77, 17,
+ 3, 1, 240, 77, 17, 1, 240, 121, 17, 3, 1, 240, 121, 62, 5, 1, 243, 32,
+ 62, 3, 1, 243, 32, 62, 5, 1, 249, 62, 62, 3, 1, 249, 62, 62, 5, 1, 243,
+ 64, 62, 3, 1, 243, 64, 62, 5, 1, 243, 28, 62, 3, 1, 243, 28, 62, 5, 1,
+ 238, 115, 62, 3, 1, 238, 115, 62, 5, 1, 240, 88, 62, 3, 1, 240, 88, 62,
+ 5, 1, 249, 53, 62, 3, 1, 249, 53, 17, 243, 29, 91, 17, 253, 218, 91, 17,
+ 240, 67, 243, 45, 91, 17, 1, 249, 211, 17, 5, 243, 0, 91, 17, 240, 67,
+ 238, 57, 91, 17, 224, 240, 67, 238, 57, 91, 17, 5, 1, 248, 110, 17, 3, 1,
+ 248, 110, 17, 5, 240, 67, 243, 45, 91, 17, 5, 1, 248, 134, 17, 3, 1, 248,
+ 134, 17, 253, 218, 2, 240, 5, 91, 17, 5, 224, 240, 67, 243, 45, 91, 17,
+ 5, 240, 4, 240, 67, 243, 45, 91, 17, 5, 224, 240, 4, 240, 67, 243, 45,
+ 91, 32, 5, 1, 255, 42, 2, 191, 32, 5, 1, 254, 100, 32, 5, 1, 248, 150,
+ 32, 5, 1, 249, 77, 32, 5, 1, 235, 156, 253, 237, 32, 5, 1, 248, 126, 32,
+ 5, 1, 226, 228, 71, 32, 5, 1, 253, 189, 32, 5, 1, 254, 24, 32, 5, 1, 248,
+ 165, 32, 5, 1, 248, 174, 32, 5, 1, 244, 40, 32, 5, 1, 249, 96, 32, 5, 1,
+ 220, 2, 191, 32, 5, 1, 242, 215, 79, 32, 5, 1, 243, 166, 32, 5, 1, 67,
+ 32, 5, 1, 253, 242, 32, 5, 1, 254, 12, 32, 5, 1, 248, 127, 32, 5, 1, 253,
+ 200, 32, 5, 1, 253, 237, 32, 5, 1, 248, 123, 32, 5, 1, 253, 228, 32, 5,
+ 1, 71, 32, 5, 1, 242, 215, 71, 32, 5, 1, 201, 32, 5, 1, 254, 3, 32, 5, 1,
+ 254, 22, 32, 5, 1, 253, 202, 32, 5, 1, 73, 32, 5, 1, 253, 175, 32, 5, 1,
+ 254, 4, 32, 5, 1, 254, 23, 32, 5, 1, 253, 195, 32, 5, 1, 79, 32, 5, 1,
+ 254, 21, 32, 5, 1, 219, 32, 5, 1, 248, 112, 32, 5, 1, 248, 88, 32, 5, 1,
+ 248, 46, 32, 5, 1, 240, 224, 32, 5, 1, 249, 79, 52, 32, 5, 1, 243, 83,
+ 32, 5, 1, 248, 186, 52, 32, 5, 1, 72, 32, 5, 1, 253, 161, 32, 5, 1, 216,
+ 32, 3, 1, 67, 32, 3, 1, 253, 242, 32, 3, 1, 254, 12, 32, 3, 1, 248, 127,
+ 32, 3, 1, 253, 200, 32, 3, 1, 253, 237, 32, 3, 1, 248, 123, 32, 3, 1,
+ 253, 228, 32, 3, 1, 71, 32, 3, 1, 242, 215, 71, 32, 3, 1, 201, 32, 3, 1,
+ 254, 3, 32, 3, 1, 254, 22, 32, 3, 1, 253, 202, 32, 3, 1, 73, 32, 3, 1,
+ 253, 175, 32, 3, 1, 254, 4, 32, 3, 1, 254, 23, 32, 3, 1, 253, 195, 32, 3,
+ 1, 79, 32, 3, 1, 254, 21, 32, 3, 1, 219, 32, 3, 1, 248, 112, 32, 3, 1,
+ 248, 88, 32, 3, 1, 248, 46, 32, 3, 1, 240, 224, 32, 3, 1, 249, 79, 52,
+ 32, 3, 1, 243, 83, 32, 3, 1, 248, 186, 52, 32, 3, 1, 72, 32, 3, 1, 253,
+ 161, 32, 3, 1, 216, 32, 3, 1, 255, 42, 2, 191, 32, 3, 1, 254, 100, 32, 3,
+ 1, 248, 150, 32, 3, 1, 249, 77, 32, 3, 1, 235, 156, 253, 237, 32, 3, 1,
+ 248, 126, 32, 3, 1, 226, 228, 71, 32, 3, 1, 253, 189, 32, 3, 1, 254, 24,
+ 32, 3, 1, 248, 165, 32, 3, 1, 248, 174, 32, 3, 1, 244, 40, 32, 3, 1, 249,
+ 96, 32, 3, 1, 220, 2, 191, 32, 3, 1, 242, 215, 79, 32, 3, 1, 243, 166,
+ 32, 5, 1, 240, 20, 32, 3, 1, 240, 20, 32, 5, 1, 249, 21, 32, 3, 1, 249,
+ 21, 32, 5, 1, 236, 197, 72, 32, 3, 1, 236, 197, 72, 32, 5, 1, 240, 101,
+ 248, 74, 32, 3, 1, 240, 101, 248, 74, 32, 5, 1, 236, 197, 240, 101, 248,
+ 74, 32, 3, 1, 236, 197, 240, 101, 248, 74, 32, 5, 1, 253, 213, 248, 74,
+ 32, 3, 1, 253, 213, 248, 74, 32, 5, 1, 236, 197, 253, 213, 248, 74, 32,
+ 3, 1, 236, 197, 253, 213, 248, 74, 32, 5, 1, 248, 163, 32, 3, 1, 248,
+ 163, 32, 5, 1, 248, 69, 32, 3, 1, 248, 69, 32, 5, 1, 243, 57, 32, 3, 1,
+ 243, 57, 32, 5, 1, 236, 215, 32, 3, 1, 236, 215, 32, 5, 1, 238, 192, 2,
+ 45, 242, 245, 238, 54, 32, 3, 1, 238, 192, 2, 45, 242, 245, 238, 54, 32,
+ 5, 1, 254, 130, 32, 3, 1, 254, 130, 32, 5, 1, 244, 1, 240, 20, 32, 3, 1,
+ 244, 1, 240, 20, 32, 5, 1, 211, 2, 240, 150, 32, 3, 1, 211, 2, 240, 150,
+ 32, 5, 1, 254, 67, 32, 3, 1, 254, 67, 32, 5, 1, 240, 77, 32, 3, 1, 240,
+ 77, 32, 235, 114, 52, 50, 32, 240, 150, 50, 32, 231, 27, 50, 32, 148,
+ 235, 135, 50, 32, 159, 235, 135, 50, 32, 238, 92, 235, 114, 52, 50, 32,
+ 237, 211, 52, 32, 5, 1, 242, 215, 220, 2, 242, 226, 32, 3, 1, 242, 215,
+ 220, 2, 242, 226, 32, 5, 1, 237, 36, 52, 32, 3, 1, 237, 36, 52, 32, 5, 1,
+ 255, 54, 2, 243, 36, 32, 3, 1, 255, 54, 2, 243, 36, 32, 5, 1, 253, 233,
+ 2, 238, 231, 32, 3, 1, 253, 233, 2, 238, 231, 32, 5, 1, 253, 233, 2, 108,
+ 32, 3, 1, 253, 233, 2, 108, 32, 5, 1, 253, 233, 2, 240, 1, 90, 32, 3, 1,
+ 253, 233, 2, 240, 1, 90, 32, 5, 1, 254, 16, 2, 234, 2, 32, 3, 1, 254, 16,
+ 2, 234, 2, 32, 5, 1, 255, 46, 2, 234, 2, 32, 3, 1, 255, 46, 2, 234, 2,
+ 32, 5, 1, 255, 26, 2, 234, 2, 32, 3, 1, 255, 26, 2, 234, 2, 32, 5, 1,
+ 255, 26, 2, 59, 108, 32, 3, 1, 255, 26, 2, 59, 108, 32, 5, 1, 255, 26, 2,
+ 108, 32, 3, 1, 255, 26, 2, 108, 32, 5, 1, 238, 165, 201, 32, 3, 1, 238,
+ 165, 201, 32, 5, 1, 255, 23, 2, 234, 2, 32, 3, 1, 255, 23, 2, 234, 2, 32,
+ 5, 18, 255, 23, 248, 127, 32, 3, 18, 255, 23, 248, 127, 32, 5, 1, 255,
+ 38, 2, 240, 1, 90, 32, 3, 1, 255, 38, 2, 240, 1, 90, 32, 5, 1, 235, 66,
+ 219, 32, 3, 1, 235, 66, 219, 32, 5, 1, 255, 55, 2, 234, 2, 32, 3, 1, 255,
+ 55, 2, 234, 2, 32, 5, 1, 255, 45, 2, 234, 2, 32, 3, 1, 255, 45, 2, 234,
+ 2, 32, 5, 1, 236, 218, 79, 32, 3, 1, 236, 218, 79, 32, 5, 1, 236, 218,
+ 132, 2, 108, 32, 3, 1, 236, 218, 132, 2, 108, 32, 5, 1, 255, 58, 2, 234,
+ 2, 32, 3, 1, 255, 58, 2, 234, 2, 32, 5, 18, 255, 45, 248, 112, 32, 3, 18,
+ 255, 45, 248, 112, 32, 5, 1, 253, 223, 2, 234, 2, 32, 3, 1, 253, 223, 2,
+ 234, 2, 32, 5, 1, 253, 223, 2, 59, 108, 32, 3, 1, 253, 223, 2, 59, 108,
+ 32, 5, 1, 244, 10, 32, 3, 1, 244, 10, 32, 5, 1, 235, 66, 248, 88, 32, 3,
+ 1, 235, 66, 248, 88, 32, 5, 1, 235, 66, 253, 223, 2, 234, 2, 32, 3, 1,
+ 235, 66, 253, 223, 2, 234, 2, 32, 1, 236, 69, 32, 5, 1, 254, 16, 2, 239,
+ 255, 32, 3, 1, 254, 16, 2, 239, 255, 32, 5, 1, 255, 26, 2, 90, 32, 3, 1,
+ 255, 26, 2, 90, 32, 5, 1, 255, 49, 2, 242, 226, 32, 3, 1, 255, 49, 2,
+ 242, 226, 32, 5, 1, 255, 23, 2, 90, 32, 3, 1, 255, 23, 2, 90, 32, 5, 1,
+ 255, 23, 2, 242, 226, 32, 3, 1, 255, 23, 2, 242, 226, 32, 5, 1, 234, 59,
+ 248, 88, 32, 3, 1, 234, 59, 248, 88, 32, 5, 1, 255, 28, 2, 242, 226, 32,
+ 3, 1, 255, 28, 2, 242, 226, 32, 5, 1, 134, 2, 239, 255, 32, 3, 1, 134, 2,
+ 239, 255, 32, 5, 1, 134, 2, 175, 32, 3, 1, 134, 2, 175, 32, 5, 18, 134,
+ 253, 237, 32, 3, 18, 134, 253, 237, 32, 5, 1, 255, 42, 2, 239, 255, 32,
+ 3, 1, 255, 42, 2, 239, 255, 32, 5, 1, 240, 86, 32, 3, 1, 240, 86, 32, 5,
+ 1, 243, 73, 2, 175, 32, 3, 1, 243, 73, 2, 175, 32, 5, 1, 254, 16, 2, 175,
+ 32, 3, 1, 254, 16, 2, 175, 32, 5, 1, 255, 46, 2, 175, 32, 3, 1, 255, 46,
+ 2, 175, 32, 5, 1, 235, 66, 248, 126, 32, 3, 1, 235, 66, 248, 126, 32, 5,
+ 1, 220, 2, 196, 32, 3, 1, 220, 2, 196, 32, 5, 1, 220, 2, 175, 32, 3, 1,
+ 220, 2, 175, 32, 5, 1, 117, 2, 175, 32, 3, 1, 117, 2, 175, 32, 5, 1, 240,
+ 60, 73, 32, 3, 1, 240, 60, 73, 32, 5, 1, 240, 60, 117, 2, 175, 32, 3, 1,
+ 240, 60, 117, 2, 175, 32, 5, 1, 157, 2, 175, 32, 3, 1, 157, 2, 175, 32,
+ 5, 1, 132, 2, 196, 32, 3, 1, 132, 2, 196, 32, 5, 1, 132, 2, 175, 32, 3,
+ 1, 132, 2, 175, 32, 5, 1, 132, 2, 45, 135, 32, 3, 1, 132, 2, 45, 135, 32,
+ 5, 1, 253, 223, 2, 175, 32, 3, 1, 253, 223, 2, 175, 32, 5, 1, 253, 233,
+ 2, 234, 2, 32, 3, 1, 253, 233, 2, 234, 2, 32, 5, 1, 249, 207, 2, 175, 32,
+ 3, 1, 249, 207, 2, 175, 32, 5, 1, 248, 72, 253, 200, 32, 3, 1, 248, 72,
+ 253, 200, 32, 5, 1, 248, 72, 248, 150, 32, 3, 1, 248, 72, 248, 150, 32,
+ 5, 1, 248, 72, 249, 220, 32, 3, 1, 248, 72, 249, 220, 32, 5, 1, 248, 72,
+ 243, 167, 32, 3, 1, 248, 72, 243, 167, 32, 5, 1, 248, 72, 248, 165, 32,
+ 3, 1, 248, 72, 248, 165, 32, 5, 1, 248, 72, 248, 174, 32, 3, 1, 248, 72,
+ 248, 174, 32, 5, 1, 248, 72, 249, 165, 32, 3, 1, 248, 72, 249, 165, 32,
+ 5, 1, 248, 72, 249, 178, 32, 3, 1, 248, 72, 249, 178, 100, 5, 1, 249, 28,
+ 100, 5, 1, 249, 32, 100, 5, 1, 249, 76, 100, 5, 1, 253, 133, 100, 5, 1,
+ 248, 208, 100, 5, 1, 253, 163, 100, 5, 1, 254, 36, 100, 5, 1, 254, 60,
+ 100, 5, 1, 87, 100, 5, 1, 248, 123, 100, 5, 1, 248, 216, 100, 5, 1, 243,
+ 216, 100, 5, 1, 249, 17, 100, 5, 1, 253, 152, 100, 5, 1, 249, 93, 100, 5,
+ 1, 253, 184, 100, 5, 1, 253, 146, 100, 5, 1, 243, 182, 100, 5, 1, 243,
+ 155, 100, 5, 1, 248, 228, 100, 5, 1, 253, 189, 100, 5, 1, 248, 175, 100,
+ 5, 1, 248, 46, 100, 5, 1, 254, 13, 100, 5, 1, 248, 57, 100, 5, 1, 248,
+ 237, 100, 5, 1, 243, 201, 100, 5, 1, 253, 130, 100, 5, 1, 249, 159, 100,
+ 5, 1, 249, 195, 100, 5, 1, 244, 32, 100, 5, 1, 248, 245, 100, 5, 1, 253,
+ 224, 100, 5, 1, 243, 136, 100, 5, 1, 243, 244, 100, 5, 1, 248, 218, 100,
+ 5, 1, 254, 118, 100, 5, 1, 248, 156, 100, 49, 1, 40, 137, 242, 233, 100,
+ 233, 59, 100, 237, 8, 69, 100, 233, 54, 69, 100, 240, 27, 100, 236, 156,
+ 69, 100, 232, 88, 69, 100, 3, 1, 249, 28, 100, 3, 1, 249, 32, 100, 3, 1,
+ 249, 76, 100, 3, 1, 253, 133, 100, 3, 1, 248, 208, 100, 3, 1, 253, 163,
+ 100, 3, 1, 254, 36, 100, 3, 1, 254, 60, 100, 3, 1, 87, 100, 3, 1, 248,
+ 123, 100, 3, 1, 248, 216, 100, 3, 1, 243, 216, 100, 3, 1, 249, 17, 100,
+ 3, 1, 253, 152, 100, 3, 1, 249, 93, 100, 3, 1, 253, 184, 100, 3, 1, 253,
+ 146, 100, 3, 1, 243, 182, 100, 3, 1, 243, 155, 100, 3, 1, 248, 228, 100,
+ 3, 1, 253, 189, 100, 3, 1, 248, 175, 100, 3, 1, 248, 46, 100, 3, 1, 254,
+ 13, 100, 3, 1, 248, 57, 100, 3, 1, 248, 237, 100, 3, 1, 243, 201, 100, 3,
+ 1, 253, 130, 100, 3, 1, 249, 159, 100, 3, 1, 249, 195, 100, 3, 1, 244,
+ 32, 100, 3, 1, 248, 245, 100, 3, 1, 253, 224, 100, 3, 1, 243, 136, 100,
+ 3, 1, 243, 244, 100, 3, 1, 248, 218, 100, 3, 1, 254, 118, 100, 3, 1, 248,
+ 156, 100, 3, 18, 254, 159, 243, 136, 100, 248, 37, 208, 100, 238, 93, 68,
+ 240, 2, 237, 152, 68, 240, 2, 240, 145, 68, 240, 2, 233, 242, 68, 240, 2,
+ 244, 64, 240, 212, 68, 240, 2, 244, 64, 241, 120, 68, 240, 2, 239, 222,
+ 68, 240, 2, 242, 81, 68, 240, 2, 242, 200, 68, 240, 2, 239, 158, 68, 240,
+ 2, 242, 197, 68, 240, 2, 242, 145, 68, 240, 2, 238, 186, 68, 240, 2, 241,
+ 126, 239, 141, 68, 240, 2, 234, 56, 68, 240, 2, 242, 71, 246, 238, 68,
+ 240, 2, 238, 224, 239, 80, 68, 240, 2, 242, 50, 68, 240, 2, 244, 85, 239,
+ 88, 68, 240, 2, 241, 250, 68, 240, 2, 236, 54, 68, 240, 2, 239, 134, 68,
+ 240, 2, 241, 235, 239, 106, 68, 240, 2, 241, 73, 68, 240, 2, 242, 69, 68,
+ 240, 2, 238, 224, 239, 171, 68, 240, 2, 247, 225, 254, 145, 247, 232, 68,
+ 240, 2, 252, 58, 68, 240, 2, 245, 226, 68, 240, 2, 245, 61, 68, 240, 2,
+ 242, 208, 68, 158, 241, 230, 238, 51, 68, 242, 232, 242, 105, 68, 242,
+ 232, 243, 98, 240, 145, 68, 242, 232, 243, 98, 240, 118, 68, 242, 232,
+ 243, 98, 238, 149, 68, 242, 232, 240, 187, 68, 242, 232, 242, 159, 68,
+ 242, 232, 240, 145, 68, 242, 232, 240, 118, 68, 242, 232, 238, 149, 68,
+ 242, 232, 240, 188, 68, 242, 232, 239, 172, 68, 242, 232, 240, 133, 128,
+ 240, 140, 68, 242, 232, 241, 236, 68, 233, 51, 241, 228, 68, 242, 232,
+ 243, 70, 68, 233, 51, 242, 47, 68, 242, 232, 248, 102, 248, 40, 68, 242,
+ 232, 254, 73, 248, 40, 68, 233, 51, 254, 240, 242, 48, 68, 158, 189, 248,
+ 40, 68, 158, 168, 248, 40, 68, 233, 51, 254, 114, 237, 167, 68, 242, 232,
+ 242, 70, 240, 212, 68, 1, 243, 3, 68, 1, 250, 117, 68, 1, 241, 136, 68,
+ 1, 240, 165, 68, 1, 253, 168, 68, 1, 249, 192, 68, 1, 242, 201, 68, 1,
+ 251, 54, 68, 1, 249, 176, 68, 1, 248, 193, 68, 1, 30, 248, 116, 68, 1,
+ 248, 116, 68, 1, 240, 139, 68, 1, 30, 248, 166, 68, 1, 248, 166, 68, 1,
+ 30, 248, 132, 68, 1, 248, 132, 68, 1, 239, 178, 68, 1, 243, 144, 68, 1,
+ 30, 253, 175, 68, 1, 253, 175, 68, 1, 30, 240, 248, 68, 1, 240, 248, 68,
+ 1, 252, 99, 68, 1, 243, 253, 68, 1, 243, 33, 68, 1, 249, 175, 68, 18,
+ 238, 126, 45, 249, 192, 68, 18, 238, 126, 254, 76, 248, 193, 68, 18, 238,
+ 126, 45, 248, 193, 68, 233, 51, 238, 186, 68, 233, 51, 234, 56, 11, 61,
+ 52, 11, 21, 242, 97, 11, 237, 159, 238, 95, 11, 21, 242, 93, 238, 237,
+ 52, 11, 240, 27, 11, 250, 186, 234, 6, 11, 242, 63, 244, 46, 52, 11, 21,
+ 241, 245, 11, 21, 233, 100, 240, 107, 235, 40, 11, 21, 240, 107, 235,
+ 173, 11, 21, 233, 228, 238, 242, 11, 21, 252, 127, 238, 244, 244, 80, 11,
+ 21, 235, 31, 11, 3, 200, 248, 137, 11, 234, 14, 11, 240, 3, 53, 233, 51,
+ 69, 11, 236, 156, 69, 11, 1, 240, 186, 11, 1, 83, 2, 243, 42, 48, 11, 1,
+ 83, 2, 143, 48, 11, 1, 253, 220, 2, 143, 48, 11, 1, 83, 2, 143, 46, 11,
+ 1, 57, 2, 143, 48, 11, 1, 243, 3, 11, 1, 249, 31, 11, 1, 253, 127, 237,
+ 200, 11, 1, 252, 213, 11, 1, 247, 142, 11, 1, 243, 200, 11, 1, 251, 45,
+ 11, 1, 243, 205, 11, 1, 250, 180, 11, 1, 247, 141, 11, 1, 248, 245, 11,
+ 1, 244, 63, 11, 1, 243, 120, 11, 1, 242, 103, 11, 1, 252, 165, 11, 1,
+ 250, 178, 11, 1, 248, 137, 11, 1, 253, 97, 11, 1, 248, 105, 11, 1, 240,
+ 180, 11, 238, 22, 11, 1, 248, 156, 11, 1, 249, 145, 11, 1, 248, 116, 11,
+ 1, 251, 182, 11, 1, 243, 223, 11, 1, 243, 236, 11, 1, 251, 50, 11, 1,
+ 248, 142, 11, 1, 83, 236, 232, 11, 1, 248, 144, 11, 236, 18, 11, 235,
+ 197, 11, 236, 43, 11, 241, 103, 11, 240, 134, 11, 241, 193, 11, 239, 191,
+ 11, 240, 240, 11, 241, 223, 48, 11, 143, 48, 11, 143, 46, 11, 235, 48,
+ 243, 3, 11, 236, 145, 240, 134, 11, 158, 198, 238, 187, 11, 236, 144, 11,
+ 33, 21, 3, 255, 110, 48, 11, 33, 21, 236, 145, 3, 255, 110, 48, 11, 33,
+ 21, 53, 46, 11, 224, 240, 134, 11, 243, 40, 2, 171, 243, 5, 232, 73, 26,
+ 242, 217, 232, 73, 26, 127, 232, 73, 26, 111, 232, 73, 26, 166, 232, 73,
+ 26, 177, 232, 73, 26, 176, 232, 73, 26, 187, 232, 73, 26, 203, 232, 73,
+ 26, 195, 232, 73, 26, 202, 11, 238, 107, 52, 11, 238, 176, 234, 6, 11,
+ 235, 114, 234, 6, 11, 248, 48, 238, 74, 242, 229, 11, 1, 238, 70, 249,
+ 31, 11, 1, 238, 70, 249, 145, 11, 1, 233, 49, 243, 3, 11, 1, 83, 242,
+ 182, 11, 1, 83, 2, 248, 103, 143, 48, 11, 1, 83, 2, 248, 103, 143, 46,
+ 11, 1, 200, 240, 186, 11, 1, 200, 143, 243, 3, 11, 1, 200, 143, 248, 142,
+ 11, 1, 132, 2, 143, 48, 11, 1, 200, 143, 248, 144, 11, 1, 247, 165, 11,
+ 1, 239, 231, 11, 1, 244, 214, 11, 1, 253, 127, 2, 242, 233, 11, 1, 253,
+ 127, 2, 204, 181, 60, 234, 9, 11, 1, 248, 237, 11, 1, 242, 143, 11, 1,
+ 241, 28, 11, 1, 94, 2, 143, 48, 11, 1, 94, 2, 171, 181, 59, 48, 11, 1,
+ 246, 201, 11, 1, 245, 77, 11, 1, 94, 2, 204, 181, 48, 11, 1, 242, 142,
+ 11, 1, 238, 23, 11, 1, 245, 37, 11, 1, 253, 199, 2, 242, 233, 11, 1, 253,
+ 199, 2, 53, 46, 11, 1, 253, 199, 2, 53, 242, 230, 19, 3, 248, 137, 11, 1,
+ 241, 71, 11, 1, 239, 38, 11, 1, 250, 208, 11, 1, 253, 199, 2, 204, 181,
+ 60, 234, 9, 11, 1, 253, 199, 2, 248, 58, 181, 48, 11, 1, 247, 36, 11, 1,
+ 253, 143, 2, 3, 179, 11, 1, 253, 143, 2, 242, 233, 11, 1, 253, 143, 2,
+ 53, 46, 11, 1, 253, 143, 2, 3, 255, 110, 46, 11, 1, 253, 143, 2, 53, 242,
+ 230, 19, 53, 48, 11, 1, 253, 143, 2, 171, 181, 48, 11, 1, 251, 112, 11,
+ 1, 253, 143, 2, 248, 58, 181, 48, 11, 1, 248, 39, 2, 53, 242, 230, 19,
+ 53, 48, 11, 1, 248, 39, 2, 204, 181, 46, 11, 1, 248, 39, 2, 204, 181,
+ 242, 230, 19, 204, 181, 48, 11, 1, 253, 157, 2, 171, 181, 46, 11, 1, 253,
+ 157, 2, 204, 181, 48, 11, 1, 253, 169, 2, 204, 181, 48, 11, 1, 253, 158,
+ 2, 204, 181, 48, 11, 1, 238, 70, 248, 156, 11, 1, 253, 153, 2, 53, 246,
+ 92, 46, 11, 1, 253, 153, 2, 53, 46, 11, 1, 253, 10, 11, 1, 253, 153, 2,
+ 204, 181, 46, 11, 1, 242, 53, 11, 1, 253, 167, 2, 53, 48, 11, 1, 253,
+ 167, 2, 204, 181, 48, 11, 1, 241, 197, 11, 1, 243, 126, 248, 116, 11, 1,
+ 253, 135, 2, 242, 233, 11, 1, 253, 135, 2, 53, 48, 11, 1, 254, 26, 11, 1,
+ 253, 135, 2, 204, 181, 46, 11, 1, 251, 5, 11, 1, 253, 246, 2, 242, 233,
+ 11, 1, 242, 8, 11, 1, 253, 246, 2, 171, 181, 46, 11, 1, 245, 129, 11, 1,
+ 253, 246, 2, 204, 181, 48, 11, 1, 182, 2, 3, 179, 11, 1, 182, 2, 53, 48,
+ 11, 1, 182, 2, 204, 181, 48, 11, 1, 182, 2, 204, 181, 46, 11, 1, 198, 2,
+ 53, 46, 11, 1, 198, 238, 187, 11, 1, 242, 85, 11, 1, 198, 2, 242, 233,
+ 11, 1, 198, 2, 204, 181, 48, 11, 1, 253, 124, 232, 133, 11, 1, 243, 47,
+ 2, 53, 48, 11, 1, 253, 124, 2, 57, 48, 11, 1, 253, 124, 243, 185, 11, 1,
+ 253, 124, 248, 128, 2, 143, 48, 11, 1, 253, 127, 238, 144, 243, 185, 11,
+ 1, 253, 220, 2, 242, 233, 11, 1, 238, 73, 253, 193, 11, 1, 253, 193, 11,
+ 1, 79, 11, 1, 253, 161, 11, 1, 238, 73, 253, 161, 11, 1, 253, 220, 2,
+ 171, 181, 48, 11, 1, 254, 12, 11, 1, 243, 26, 248, 144, 11, 1, 57, 2,
+ 242, 226, 11, 1, 57, 2, 3, 179, 11, 1, 253, 220, 2, 53, 48, 11, 1, 72,
+ 11, 1, 57, 2, 204, 181, 46, 11, 1, 57, 239, 5, 11, 1, 57, 240, 92, 2,
+ 143, 48, 11, 248, 37, 208, 11, 1, 253, 178, 11, 3, 200, 18, 253, 157, 2,
+ 182, 2, 83, 236, 232, 11, 3, 200, 18, 253, 167, 2, 182, 2, 83, 236, 232,
+ 11, 3, 200, 51, 54, 13, 11, 3, 200, 182, 243, 3, 11, 3, 200, 243, 200,
+ 11, 3, 200, 204, 243, 5, 11, 3, 200, 243, 120, 11, 253, 165, 147, 244,
+ 87, 11, 243, 124, 147, 254, 237, 255, 49, 245, 147, 11, 3, 200, 238, 121,
+ 242, 217, 11, 3, 200, 239, 234, 233, 97, 242, 217, 11, 3, 200, 238, 70,
+ 251, 49, 147, 243, 205, 11, 3, 200, 51, 39, 13, 11, 3, 170, 243, 120, 11,
+ 3, 200, 241, 222, 11, 3, 248, 142, 11, 3, 248, 144, 11, 3, 200, 248, 144,
+ 11, 3, 200, 243, 236, 11, 243, 245, 147, 239, 177, 11, 243, 15, 240, 46,
+ 170, 208, 11, 243, 15, 240, 46, 200, 208, 11, 238, 121, 200, 248, 119, 2,
+ 241, 109, 238, 129, 11, 3, 170, 243, 223, 11, 1, 253, 199, 2, 236, 145,
+ 179, 11, 1, 253, 143, 2, 236, 145, 179, 236, 174, 232, 73, 26, 242, 217,
+ 236, 174, 232, 73, 26, 127, 236, 174, 232, 73, 26, 111, 236, 174, 232,
+ 73, 26, 166, 236, 174, 232, 73, 26, 177, 236, 174, 232, 73, 26, 176, 236,
+ 174, 232, 73, 26, 187, 236, 174, 232, 73, 26, 203, 236, 174, 232, 73, 26,
+ 195, 236, 174, 232, 73, 26, 202, 11, 1, 242, 216, 2, 53, 46, 11, 1, 253,
+ 155, 2, 53, 46, 11, 1, 242, 240, 2, 53, 46, 11, 21, 240, 233, 234, 17,
+ 11, 21, 240, 233, 232, 197, 248, 228, 11, 1, 253, 124, 2, 236, 145, 179,
+ 129, 253, 165, 147, 234, 232, 129, 233, 80, 248, 37, 208, 129, 235, 110,
+ 248, 37, 208, 129, 233, 80, 240, 24, 129, 235, 110, 240, 24, 129, 163,
+ 240, 24, 129, 243, 14, 240, 122, 242, 220, 129, 243, 14, 240, 122, 225,
+ 129, 233, 80, 243, 14, 240, 122, 242, 220, 129, 235, 110, 243, 14, 240,
+ 122, 225, 129, 232, 121, 129, 236, 227, 239, 150, 129, 236, 227, 234,
+ 222, 129, 236, 227, 233, 117, 129, 232, 88, 69, 129, 1, 240, 155, 129, 1,
+ 233, 49, 240, 155, 129, 1, 244, 219, 129, 1, 241, 121, 129, 1, 245, 96,
+ 235, 123, 129, 1, 239, 35, 129, 1, 238, 70, 241, 72, 243, 255, 129, 1,
+ 253, 168, 129, 1, 248, 142, 129, 1, 244, 63, 129, 1, 245, 142, 129, 1,
+ 247, 140, 129, 1, 252, 216, 235, 123, 129, 1, 247, 238, 129, 1, 253, 87,
+ 253, 168, 129, 1, 246, 5, 129, 1, 239, 113, 129, 1, 251, 235, 129, 1,
+ 248, 132, 129, 1, 237, 37, 129, 1, 30, 237, 37, 129, 1, 72, 129, 1, 253,
+ 175, 129, 1, 224, 253, 175, 129, 1, 242, 92, 129, 1, 247, 6, 129, 1, 243,
+ 255, 129, 1, 243, 33, 129, 1, 252, 211, 129, 1, 184, 241, 30, 129, 1,
+ 184, 239, 84, 129, 1, 184, 237, 104, 129, 240, 143, 48, 129, 240, 143,
+ 46, 129, 240, 143, 238, 136, 129, 240, 154, 48, 129, 240, 154, 46, 129,
+ 240, 154, 238, 136, 129, 243, 252, 48, 129, 243, 252, 46, 129, 240, 4,
+ 244, 66, 233, 50, 129, 240, 4, 244, 66, 237, 61, 129, 243, 192, 48, 129,
+ 243, 192, 46, 129, 233, 205, 238, 136, 129, 243, 170, 48, 129, 243, 170,
+ 46, 129, 242, 91, 129, 237, 9, 248, 40, 129, 234, 244, 129, 236, 94, 129,
+ 171, 59, 181, 48, 129, 171, 59, 181, 46, 129, 204, 181, 48, 129, 204,
+ 181, 46, 129, 238, 106, 248, 41, 48, 129, 238, 106, 248, 41, 46, 129,
+ 241, 251, 129, 237, 71, 129, 1, 238, 151, 242, 202, 129, 1, 238, 151,
+ 241, 201, 129, 1, 238, 151, 254, 62, 11, 1, 253, 136, 2, 204, 181, 232,
+ 173, 46, 11, 1, 253, 136, 2, 53, 242, 230, 19, 204, 181, 48, 11, 1, 253,
+ 136, 2, 204, 181, 236, 150, 226, 226, 46, 11, 1, 253, 136, 2, 204, 181,
+ 236, 150, 226, 226, 242, 230, 19, 171, 181, 48, 11, 1, 253, 136, 2, 171,
+ 181, 242, 230, 19, 53, 48, 11, 1, 253, 136, 2, 236, 145, 3, 255, 110, 46,
+ 11, 1, 253, 136, 2, 3, 179, 11, 1, 94, 2, 171, 181, 48, 11, 1, 94, 2,
+ 204, 181, 236, 150, 226, 226, 46, 11, 1, 253, 199, 2, 171, 181, 234, 33,
+ 242, 230, 19, 3, 248, 137, 11, 1, 253, 199, 2, 236, 145, 3, 255, 110, 46,
+ 11, 1, 253, 143, 2, 108, 11, 1, 248, 39, 2, 248, 58, 181, 48, 11, 1, 253,
+ 158, 2, 171, 181, 48, 11, 1, 253, 158, 2, 204, 181, 236, 150, 235, 45,
+ 48, 11, 1, 253, 158, 2, 171, 181, 234, 33, 48, 11, 1, 253, 153, 2, 171,
+ 181, 46, 11, 1, 253, 153, 2, 204, 181, 236, 150, 226, 226, 46, 11, 1,
+ 243, 21, 2, 53, 48, 11, 1, 243, 21, 2, 204, 181, 48, 11, 1, 243, 21, 2,
+ 204, 181, 236, 150, 226, 226, 46, 11, 1, 51, 2, 53, 48, 11, 1, 51, 2, 53,
+ 46, 11, 1, 198, 2, 171, 181, 46, 11, 1, 198, 2, 3, 248, 137, 11, 1, 198,
+ 2, 3, 179, 11, 1, 182, 2, 125, 11, 1, 253, 143, 2, 171, 181, 234, 33, 48,
+ 11, 1, 253, 143, 2, 143, 48, 11, 1, 248, 39, 2, 171, 181, 234, 33, 48,
+ 199, 1, 248, 114, 199, 1, 234, 254, 199, 1, 242, 22, 199, 1, 248, 182,
+ 199, 1, 249, 30, 199, 1, 234, 218, 199, 1, 241, 191, 199, 1, 241, 8, 199,
+ 1, 242, 173, 199, 1, 241, 231, 199, 1, 241, 101, 199, 1, 239, 41, 199, 1,
+ 243, 76, 199, 1, 241, 210, 199, 1, 241, 119, 199, 1, 234, 195, 199, 1,
+ 242, 99, 199, 1, 235, 199, 199, 1, 236, 143, 199, 1, 236, 127, 199, 1,
+ 248, 191, 199, 1, 236, 72, 199, 1, 236, 42, 199, 1, 234, 100, 199, 1,
+ 247, 163, 199, 1, 243, 194, 199, 1, 246, 8, 199, 1, 239, 217, 199, 1,
+ 249, 216, 199, 1, 239, 193, 199, 1, 239, 176, 199, 1, 239, 34, 199, 1,
+ 87, 199, 1, 253, 222, 199, 1, 244, 74, 199, 1, 239, 83, 199, 1, 242, 68,
+ 199, 1, 242, 181, 199, 237, 54, 199, 234, 88, 199, 237, 176, 199, 234,
+ 183, 199, 238, 37, 199, 234, 229, 199, 237, 145, 199, 234, 189, 199, 237,
+ 223, 199, 234, 228, 199, 240, 240, 199, 1, 248, 231, 85, 21, 232, 77, 85,
+ 21, 235, 61, 85, 21, 236, 173, 85, 1, 242, 215, 67, 85, 1, 67, 85, 1,
+ 253, 140, 85, 1, 71, 85, 1, 253, 142, 85, 1, 79, 85, 1, 253, 148, 85, 1,
+ 165, 144, 85, 1, 165, 162, 85, 1, 240, 61, 72, 85, 1, 242, 215, 72, 85,
+ 1, 72, 85, 1, 253, 149, 85, 1, 240, 61, 73, 85, 1, 242, 215, 73, 85, 1,
+ 73, 85, 1, 253, 151, 85, 1, 201, 85, 1, 248, 61, 85, 1, 253, 139, 85, 1,
+ 248, 77, 85, 1, 248, 50, 85, 1, 253, 152, 85, 1, 248, 57, 85, 1, 253,
+ 146, 85, 1, 248, 89, 85, 1, 248, 78, 85, 1, 248, 71, 85, 1, 242, 247, 85,
+ 1, 248, 75, 85, 1, 242, 249, 85, 1, 248, 82, 85, 1, 253, 126, 85, 1, 248,
+ 55, 85, 1, 253, 133, 85, 1, 248, 76, 85, 1, 253, 131, 85, 1, 243, 234,
+ 85, 1, 253, 129, 85, 1, 248, 65, 85, 1, 253, 141, 85, 1, 248, 81, 85, 1,
+ 222, 85, 1, 216, 85, 1, 253, 130, 85, 1, 248, 96, 85, 1, 253, 134, 85, 1,
+ 248, 94, 85, 1, 243, 104, 85, 1, 253, 171, 85, 1, 248, 46, 85, 1, 248,
+ 66, 85, 1, 253, 132, 85, 1, 219, 85, 21, 240, 81, 85, 21, 235, 80, 85,
+ 33, 21, 253, 140, 85, 33, 21, 71, 85, 33, 21, 253, 142, 85, 33, 21, 79,
+ 85, 33, 21, 253, 148, 85, 33, 21, 165, 144, 85, 33, 21, 165, 253, 182,
+ 85, 33, 21, 240, 61, 72, 85, 33, 21, 242, 215, 72, 85, 33, 21, 72, 85,
+ 33, 21, 253, 149, 85, 33, 21, 240, 61, 73, 85, 33, 21, 242, 215, 73, 85,
+ 33, 21, 73, 85, 33, 21, 253, 151, 85, 21, 238, 72, 85, 254, 43, 85, 240,
+ 148, 21, 239, 233, 85, 240, 148, 21, 235, 163, 85, 242, 245, 238, 54, 85,
+ 242, 241, 238, 54, 85, 1, 253, 217, 85, 1, 243, 207, 85, 1, 243, 183, 85,
+ 1, 253, 163, 85, 1, 241, 75, 85, 1, 248, 246, 85, 1, 253, 179, 85, 1,
+ 249, 24, 85, 1, 165, 253, 182, 85, 1, 165, 253, 191, 85, 33, 21, 165,
+ 162, 85, 33, 21, 165, 253, 191, 85, 240, 111, 85, 45, 240, 111, 85, 26,
+ 242, 217, 85, 26, 127, 85, 26, 111, 85, 26, 166, 85, 26, 177, 85, 26,
+ 176, 85, 26, 187, 85, 26, 203, 85, 26, 195, 85, 26, 202, 85, 232, 88, 52,
+ 85, 1, 238, 62, 208, 101, 21, 232, 77, 101, 21, 235, 61, 101, 21, 236,
+ 173, 101, 1, 67, 101, 1, 253, 140, 101, 1, 71, 101, 1, 253, 142, 101, 1,
+ 79, 101, 1, 253, 148, 101, 1, 165, 144, 101, 1, 165, 162, 101, 1, 72,
+ 101, 1, 253, 149, 101, 1, 73, 101, 1, 253, 151, 101, 1, 201, 101, 1, 248,
+ 61, 101, 1, 253, 139, 101, 1, 248, 77, 101, 1, 248, 50, 101, 1, 253, 152,
+ 101, 1, 248, 57, 101, 1, 253, 146, 101, 1, 248, 89, 101, 1, 248, 78, 101,
+ 1, 248, 71, 101, 1, 242, 247, 101, 1, 248, 75, 101, 1, 242, 249, 101, 1,
+ 248, 82, 101, 1, 253, 126, 101, 1, 248, 55, 101, 1, 253, 133, 101, 1,
+ 248, 76, 101, 1, 253, 131, 101, 1, 253, 129, 101, 1, 248, 65, 101, 1,
+ 253, 141, 101, 1, 248, 81, 101, 1, 222, 101, 1, 216, 101, 1, 253, 130,
+ 101, 1, 253, 134, 101, 1, 248, 46, 101, 1, 248, 66, 101, 1, 253, 132,
+ 101, 1, 219, 101, 21, 240, 81, 101, 21, 235, 80, 101, 33, 21, 253, 140,
+ 101, 33, 21, 71, 101, 33, 21, 253, 142, 101, 33, 21, 79, 101, 33, 21,
+ 253, 148, 101, 33, 21, 165, 144, 101, 33, 21, 165, 253, 182, 101, 33, 21,
+ 72, 101, 33, 21, 253, 149, 101, 33, 21, 73, 101, 33, 21, 253, 151, 101,
+ 21, 238, 72, 101, 1, 241, 200, 253, 126, 101, 255, 39, 240, 51, 69, 101,
+ 1, 248, 96, 101, 1, 248, 246, 101, 1, 249, 24, 101, 1, 165, 253, 182,
+ 101, 1, 165, 253, 191, 101, 33, 21, 165, 162, 101, 33, 21, 165, 253, 191,
+ 101, 26, 242, 217, 101, 26, 127, 101, 26, 111, 101, 26, 166, 101, 26,
+ 177, 101, 26, 176, 101, 26, 187, 101, 26, 203, 101, 26, 195, 101, 26,
+ 202, 101, 1, 255, 63, 2, 240, 1, 235, 86, 101, 1, 255, 63, 2, 168, 235,
+ 86, 101, 243, 44, 69, 101, 243, 44, 52, 101, 236, 181, 235, 79, 127, 101,
+ 236, 181, 235, 79, 111, 101, 236, 181, 235, 79, 166, 101, 236, 181, 235,
+ 79, 177, 101, 236, 181, 235, 79, 253, 125, 251, 190, 249, 1, 253, 145,
+ 232, 129, 101, 236, 181, 233, 131, 236, 202, 101, 238, 191, 133, 21, 249,
+ 233, 240, 160, 133, 21, 240, 160, 133, 21, 236, 173, 133, 1, 67, 133, 1,
+ 253, 140, 133, 1, 71, 133, 1, 253, 142, 133, 1, 79, 133, 1, 253, 148,
+ 133, 1, 253, 164, 133, 1, 253, 149, 133, 1, 253, 156, 133, 1, 253, 151,
+ 133, 1, 201, 133, 1, 248, 61, 133, 1, 253, 139, 133, 1, 248, 77, 133, 1,
+ 248, 50, 133, 1, 253, 152, 133, 1, 248, 57, 133, 1, 253, 146, 133, 1,
+ 248, 89, 133, 1, 248, 78, 133, 1, 248, 71, 133, 1, 242, 247, 133, 1, 248,
+ 75, 133, 1, 242, 249, 133, 1, 248, 82, 133, 1, 253, 126, 133, 1, 248, 55,
+ 133, 1, 253, 133, 133, 1, 248, 76, 133, 1, 253, 131, 133, 1, 253, 129,
+ 133, 1, 248, 65, 133, 1, 253, 141, 133, 1, 248, 81, 133, 1, 222, 133, 1,
+ 216, 133, 1, 253, 130, 133, 1, 253, 134, 133, 1, 248, 94, 133, 1, 253,
+ 171, 133, 1, 248, 46, 133, 1, 253, 132, 133, 1, 219, 133, 21, 240, 81,
+ 133, 33, 21, 253, 140, 133, 33, 21, 71, 133, 33, 21, 253, 142, 133, 33,
+ 21, 79, 133, 33, 21, 253, 148, 133, 33, 21, 253, 164, 133, 33, 21, 253,
+ 149, 133, 33, 21, 253, 156, 133, 33, 21, 253, 151, 133, 21, 238, 72, 133,
+ 1, 243, 207, 133, 1, 243, 183, 133, 1, 253, 163, 133, 1, 248, 96, 133, 1,
+ 253, 179, 133, 26, 242, 217, 133, 26, 127, 133, 26, 111, 133, 26, 166,
+ 133, 26, 177, 133, 26, 176, 133, 26, 187, 133, 26, 203, 133, 26, 195,
+ 133, 26, 202, 133, 242, 154, 133, 241, 5, 133, 251, 107, 133, 253, 2,
+ 133, 255, 73, 242, 41, 112, 21, 232, 77, 112, 21, 235, 61, 112, 21, 236,
+ 173, 112, 1, 67, 112, 1, 253, 140, 112, 1, 71, 112, 1, 253, 142, 112, 1,
+ 79, 112, 1, 253, 148, 112, 1, 165, 144, 112, 1, 165, 162, 112, 33, 240,
+ 61, 72, 112, 1, 72, 112, 1, 253, 149, 112, 33, 240, 61, 73, 112, 1, 73,
+ 112, 1, 253, 151, 112, 1, 201, 112, 1, 248, 61, 112, 1, 253, 139, 112, 1,
+ 248, 77, 112, 1, 248, 50, 112, 1, 253, 152, 112, 1, 248, 57, 112, 1, 253,
+ 146, 112, 1, 248, 89, 112, 1, 248, 78, 112, 1, 248, 71, 112, 1, 242, 247,
+ 112, 1, 248, 75, 112, 1, 242, 249, 112, 1, 248, 82, 112, 1, 253, 126,
+ 112, 1, 248, 55, 112, 1, 253, 133, 112, 1, 248, 76, 112, 1, 253, 131,
+ 112, 1, 253, 129, 112, 1, 248, 65, 112, 1, 253, 141, 112, 1, 248, 81,
+ 112, 1, 222, 112, 1, 216, 112, 1, 253, 130, 112, 1, 253, 134, 112, 1,
+ 248, 94, 112, 1, 253, 171, 112, 1, 248, 46, 112, 1, 248, 66, 112, 1, 253,
+ 132, 112, 1, 219, 112, 21, 240, 81, 112, 21, 235, 80, 112, 33, 21, 253,
+ 140, 112, 33, 21, 71, 112, 33, 21, 253, 142, 112, 33, 21, 79, 112, 33,
+ 21, 253, 148, 112, 33, 21, 165, 144, 112, 33, 21, 165, 253, 182, 112, 33,
+ 21, 240, 61, 72, 112, 33, 21, 72, 112, 33, 21, 253, 149, 112, 33, 21,
+ 240, 61, 73, 112, 33, 21, 73, 112, 33, 21, 253, 151, 112, 21, 238, 72,
+ 112, 254, 43, 112, 1, 165, 253, 182, 112, 1, 165, 253, 191, 112, 33, 21,
+ 165, 162, 112, 33, 21, 165, 253, 191, 112, 26, 242, 217, 112, 26, 127,
+ 112, 26, 111, 112, 26, 166, 112, 26, 177, 112, 26, 176, 112, 26, 187,
+ 112, 26, 203, 112, 26, 195, 112, 26, 202, 112, 243, 44, 52, 118, 21, 232,
+ 77, 118, 21, 235, 61, 118, 21, 236, 173, 118, 1, 67, 118, 1, 253, 140,
+ 118, 1, 71, 118, 1, 253, 142, 118, 1, 79, 118, 1, 253, 148, 118, 1, 165,
+ 144, 118, 1, 165, 162, 118, 1, 72, 118, 1, 253, 149, 118, 1, 73, 118, 1,
+ 253, 151, 118, 1, 201, 118, 1, 248, 61, 118, 1, 253, 139, 118, 1, 248,
+ 77, 118, 1, 248, 50, 118, 1, 253, 152, 118, 1, 248, 57, 118, 1, 253, 146,
+ 118, 1, 248, 89, 118, 1, 248, 78, 118, 1, 248, 71, 118, 1, 242, 247, 118,
+ 1, 248, 75, 118, 1, 242, 249, 118, 1, 248, 82, 118, 1, 253, 126, 118, 1,
+ 248, 55, 118, 1, 253, 133, 118, 1, 248, 76, 118, 1, 253, 131, 118, 1,
+ 253, 129, 118, 1, 248, 65, 118, 1, 253, 141, 118, 1, 248, 81, 118, 1,
+ 222, 118, 1, 216, 118, 1, 253, 130, 118, 1, 253, 134, 118, 1, 248, 94,
+ 118, 1, 253, 171, 118, 1, 248, 46, 118, 1, 248, 66, 118, 1, 253, 132,
+ 118, 1, 219, 118, 21, 240, 81, 118, 21, 235, 80, 118, 33, 21, 253, 140,
+ 118, 33, 21, 71, 118, 33, 21, 253, 142, 118, 33, 21, 79, 118, 33, 21,
+ 253, 148, 118, 33, 21, 165, 144, 118, 33, 21, 72, 118, 33, 21, 253, 149,
+ 118, 33, 21, 73, 118, 33, 21, 253, 151, 118, 21, 238, 72, 118, 255, 37,
+ 240, 51, 69, 118, 255, 39, 240, 51, 69, 118, 1, 248, 96, 118, 1, 248,
+ 246, 118, 1, 249, 24, 118, 1, 165, 253, 182, 118, 1, 165, 253, 191, 118,
+ 26, 242, 217, 118, 26, 127, 118, 26, 111, 118, 26, 166, 118, 26, 177,
+ 118, 26, 176, 118, 26, 187, 118, 26, 203, 118, 26, 195, 118, 26, 202,
+ 118, 238, 191, 118, 1, 253, 138, 140, 21, 235, 61, 140, 21, 236, 173,
+ 140, 1, 67, 140, 1, 253, 140, 140, 1, 71, 140, 1, 253, 142, 140, 1, 79,
+ 140, 1, 253, 148, 140, 1, 72, 140, 1, 253, 164, 140, 1, 253, 149, 140, 1,
+ 73, 140, 1, 253, 156, 140, 1, 253, 151, 140, 1, 201, 140, 1, 248, 50,
+ 140, 1, 253, 152, 140, 1, 253, 146, 140, 1, 248, 78, 140, 1, 248, 71,
+ 140, 1, 248, 82, 140, 1, 253, 126, 140, 1, 253, 131, 140, 1, 243, 234,
+ 140, 1, 253, 129, 140, 1, 222, 140, 1, 216, 140, 1, 253, 130, 140, 1,
+ 248, 96, 140, 1, 253, 134, 140, 1, 248, 94, 140, 1, 243, 104, 140, 1,
+ 253, 171, 140, 1, 248, 46, 140, 1, 248, 66, 140, 1, 253, 132, 140, 1,
+ 219, 140, 33, 21, 253, 140, 140, 33, 21, 71, 140, 33, 21, 253, 142, 140,
+ 33, 21, 79, 140, 33, 21, 253, 148, 140, 33, 21, 72, 140, 33, 21, 253,
+ 164, 140, 33, 21, 253, 149, 140, 33, 21, 73, 140, 33, 21, 253, 156, 140,
+ 33, 21, 253, 151, 140, 21, 238, 72, 140, 255, 39, 240, 51, 69, 140, 26,
+ 242, 217, 140, 26, 127, 140, 26, 111, 140, 26, 166, 140, 26, 177, 140,
+ 26, 176, 140, 26, 187, 140, 26, 203, 140, 26, 195, 140, 26, 202, 140, 61,
+ 248, 53, 140, 61, 253, 125, 236, 149, 140, 61, 253, 125, 235, 49, 140,
+ 253, 137, 52, 140, 246, 90, 52, 140, 249, 206, 52, 140, 245, 59, 52, 140,
+ 241, 68, 52, 140, 255, 24, 60, 52, 140, 243, 44, 52, 140, 61, 52, 124,
+ 21, 232, 77, 124, 21, 235, 61, 124, 21, 236, 173, 124, 1, 67, 124, 1,
+ 253, 140, 124, 1, 71, 124, 1, 253, 142, 124, 1, 79, 124, 1, 253, 148,
+ 124, 1, 165, 144, 124, 1, 165, 162, 124, 1, 72, 124, 1, 253, 164, 124, 1,
+ 253, 149, 124, 1, 73, 124, 1, 253, 156, 124, 1, 253, 151, 124, 1, 201,
+ 124, 1, 248, 61, 124, 1, 253, 139, 124, 1, 248, 77, 124, 1, 248, 50, 124,
+ 1, 253, 152, 124, 1, 248, 57, 124, 1, 253, 146, 124, 1, 248, 89, 124, 1,
+ 248, 78, 124, 1, 248, 71, 124, 1, 242, 247, 124, 1, 248, 75, 124, 1, 242,
+ 249, 124, 1, 248, 82, 124, 1, 253, 126, 124, 1, 248, 55, 124, 1, 253,
+ 133, 124, 1, 248, 76, 124, 1, 253, 131, 124, 1, 253, 129, 124, 1, 248,
+ 65, 124, 1, 253, 141, 124, 1, 248, 81, 124, 1, 222, 124, 1, 216, 124, 1,
+ 253, 130, 124, 1, 248, 96, 124, 1, 253, 134, 124, 1, 248, 94, 124, 1,
+ 253, 171, 124, 1, 248, 46, 124, 1, 248, 66, 124, 1, 253, 132, 124, 1,
+ 219, 124, 33, 21, 253, 140, 124, 33, 21, 71, 124, 33, 21, 253, 142, 124,
+ 33, 21, 79, 124, 33, 21, 253, 148, 124, 33, 21, 165, 144, 124, 33, 21,
+ 165, 253, 182, 124, 33, 21, 72, 124, 33, 21, 253, 164, 124, 33, 21, 253,
+ 149, 124, 33, 21, 73, 124, 33, 21, 253, 156, 124, 33, 21, 253, 151, 124,
+ 21, 238, 72, 124, 240, 51, 69, 124, 255, 37, 240, 51, 69, 124, 1, 165,
+ 253, 182, 124, 1, 165, 253, 191, 124, 26, 242, 217, 124, 26, 127, 124,
+ 26, 111, 124, 26, 166, 124, 26, 177, 124, 26, 176, 124, 26, 187, 124, 26,
+ 203, 124, 26, 195, 124, 26, 202, 115, 21, 235, 61, 115, 21, 236, 173,
+ 115, 1, 67, 115, 1, 253, 140, 115, 1, 71, 115, 1, 253, 142, 115, 1, 79,
+ 115, 1, 253, 148, 115, 1, 165, 144, 115, 1, 165, 162, 115, 1, 72, 115, 1,
+ 253, 164, 115, 1, 253, 149, 115, 1, 73, 115, 1, 253, 156, 115, 1, 253,
+ 151, 115, 1, 201, 115, 1, 248, 61, 115, 1, 253, 139, 115, 1, 248, 77,
+ 115, 1, 248, 50, 115, 1, 253, 152, 115, 1, 248, 57, 115, 1, 253, 146,
+ 115, 1, 248, 89, 115, 1, 248, 78, 115, 1, 248, 71, 115, 1, 242, 247, 115,
+ 1, 248, 75, 115, 1, 242, 249, 115, 1, 248, 82, 115, 1, 253, 126, 115, 1,
+ 248, 55, 115, 1, 253, 133, 115, 1, 248, 76, 115, 1, 253, 131, 115, 1,
+ 253, 129, 115, 1, 248, 65, 115, 1, 253, 141, 115, 1, 248, 81, 115, 1,
+ 222, 115, 1, 216, 115, 1, 253, 130, 115, 1, 248, 96, 115, 1, 253, 134,
+ 115, 1, 248, 94, 115, 1, 253, 171, 115, 1, 248, 46, 115, 1, 248, 66, 115,
+ 1, 253, 132, 115, 1, 219, 115, 21, 240, 81, 115, 21, 235, 80, 115, 33,
+ 21, 253, 140, 115, 33, 21, 71, 115, 33, 21, 253, 142, 115, 33, 21, 79,
+ 115, 33, 21, 253, 148, 115, 33, 21, 165, 144, 115, 33, 21, 165, 253, 182,
+ 115, 33, 21, 72, 115, 33, 21, 253, 164, 115, 33, 21, 253, 149, 115, 33,
+ 21, 73, 115, 33, 21, 253, 156, 115, 33, 21, 253, 151, 115, 21, 238, 72,
+ 115, 240, 51, 69, 115, 255, 37, 240, 51, 69, 115, 1, 253, 179, 115, 1,
+ 165, 253, 182, 115, 1, 165, 253, 191, 115, 26, 242, 217, 115, 26, 127,
+ 115, 26, 111, 115, 26, 166, 115, 26, 177, 115, 26, 176, 115, 26, 187,
+ 115, 26, 203, 115, 26, 195, 115, 26, 202, 130, 21, 235, 61, 130, 21, 236,
+ 173, 130, 1, 67, 130, 1, 253, 140, 130, 1, 71, 130, 1, 253, 142, 130, 1,
+ 79, 130, 1, 253, 148, 130, 1, 165, 144, 130, 1, 165, 162, 130, 1, 72,
+ 130, 1, 253, 164, 130, 1, 253, 149, 130, 1, 73, 130, 1, 253, 156, 130, 1,
+ 253, 151, 130, 1, 201, 130, 1, 248, 61, 130, 1, 253, 139, 130, 1, 248,
+ 77, 130, 1, 248, 50, 130, 1, 253, 152, 130, 1, 248, 57, 130, 1, 253, 146,
+ 130, 1, 248, 89, 130, 1, 248, 78, 130, 1, 248, 71, 130, 1, 242, 247, 130,
+ 1, 248, 75, 130, 1, 242, 249, 130, 1, 248, 82, 130, 1, 253, 126, 130, 1,
+ 248, 55, 130, 1, 253, 133, 130, 1, 248, 76, 130, 1, 253, 131, 130, 1,
+ 253, 129, 130, 1, 248, 65, 130, 1, 253, 141, 130, 1, 248, 81, 130, 1,
+ 222, 130, 1, 216, 130, 1, 253, 130, 130, 1, 248, 96, 130, 1, 253, 134,
+ 130, 1, 248, 94, 130, 1, 243, 104, 130, 1, 253, 171, 130, 1, 248, 46,
+ 130, 1, 248, 66, 130, 1, 253, 132, 130, 1, 219, 130, 33, 21, 253, 140,
+ 130, 33, 21, 71, 130, 33, 21, 253, 142, 130, 33, 21, 79, 130, 33, 21,
+ 253, 148, 130, 33, 21, 165, 144, 130, 33, 21, 72, 130, 33, 21, 253, 164,
+ 130, 33, 21, 253, 149, 130, 33, 21, 73, 130, 33, 21, 253, 156, 130, 33,
+ 21, 253, 151, 130, 21, 238, 72, 130, 255, 39, 240, 51, 69, 130, 1, 165,
+ 253, 182, 130, 1, 165, 253, 191, 130, 26, 242, 217, 130, 26, 127, 130,
+ 26, 111, 130, 26, 166, 130, 26, 177, 130, 26, 176, 130, 26, 187, 130, 26,
+ 203, 130, 26, 195, 130, 26, 202, 123, 21, 233, 115, 123, 21, 235, 39,
+ 123, 1, 239, 0, 123, 1, 237, 53, 123, 1, 237, 56, 123, 1, 235, 161, 123,
+ 1, 239, 102, 123, 1, 237, 178, 123, 1, 239, 237, 123, 1, 238, 39, 123, 1,
+ 236, 41, 123, 1, 234, 209, 123, 1, 236, 37, 123, 1, 234, 202, 123, 1,
+ 239, 59, 123, 1, 237, 146, 123, 1, 237, 57, 123, 1, 239, 156, 123, 1,
+ 237, 227, 123, 1, 237, 68, 123, 1, 234, 8, 237, 16, 123, 1, 233, 58, 237,
+ 16, 123, 1, 234, 8, 236, 226, 123, 1, 233, 58, 236, 226, 123, 1, 239,
+ 105, 233, 89, 123, 1, 238, 122, 236, 226, 123, 1, 234, 8, 236, 250, 123,
+ 1, 233, 58, 236, 250, 123, 1, 234, 8, 236, 228, 123, 1, 233, 58, 236,
+ 228, 123, 1, 238, 154, 233, 89, 123, 1, 238, 154, 238, 1, 232, 185, 123,
+ 1, 238, 122, 236, 228, 123, 1, 234, 8, 235, 155, 123, 1, 233, 58, 235,
+ 155, 123, 1, 234, 8, 235, 97, 123, 1, 233, 58, 235, 97, 123, 1, 235, 104,
+ 237, 25, 123, 1, 238, 122, 235, 97, 123, 1, 234, 8, 237, 46, 123, 1, 233,
+ 58, 237, 46, 123, 1, 234, 8, 236, 222, 123, 1, 233, 58, 236, 222, 123, 1,
+ 238, 134, 237, 25, 123, 1, 238, 122, 236, 222, 123, 1, 234, 8, 237, 27,
+ 123, 1, 233, 58, 237, 27, 123, 1, 234, 8, 236, 220, 123, 1, 233, 58, 236,
+ 220, 123, 1, 237, 205, 123, 1, 249, 237, 236, 220, 123, 1, 238, 47, 123,
+ 1, 237, 247, 123, 1, 238, 134, 237, 20, 123, 1, 238, 41, 123, 1, 238,
+ 154, 236, 238, 123, 1, 235, 104, 236, 238, 123, 1, 238, 134, 236, 238,
+ 123, 1, 237, 171, 123, 1, 235, 104, 237, 20, 123, 1, 237, 155, 123, 21,
+ 234, 90, 123, 33, 21, 233, 67, 123, 33, 21, 243, 102, 233, 81, 123, 33,
+ 21, 248, 107, 233, 81, 123, 33, 21, 243, 102, 235, 130, 123, 33, 21, 248,
+ 107, 235, 130, 123, 33, 21, 243, 102, 234, 60, 123, 33, 21, 248, 107,
+ 234, 60, 123, 33, 21, 231, 104, 123, 33, 21, 237, 17, 123, 33, 21, 248,
+ 107, 237, 17, 123, 33, 21, 246, 18, 245, 62, 123, 33, 21, 238, 141, 254,
+ 64, 233, 67, 123, 33, 21, 238, 141, 254, 64, 248, 107, 233, 67, 123, 33,
+ 21, 238, 141, 254, 64, 232, 90, 123, 33, 21, 232, 90, 123, 33, 21, 248,
+ 107, 231, 104, 123, 33, 21, 248, 107, 232, 90, 123, 233, 51, 233, 214,
+ 107, 99, 255, 59, 249, 91, 107, 99, 253, 249, 246, 9, 107, 99, 253, 249,
+ 241, 202, 107, 99, 253, 249, 241, 203, 107, 99, 253, 249, 246, 12, 107,
+ 99, 253, 249, 237, 245, 107, 99, 254, 213, 252, 19, 107, 99, 254, 35,
+ 244, 253, 107, 99, 254, 35, 241, 53, 107, 99, 254, 35, 241, 51, 107, 99,
+ 255, 35, 253, 186, 107, 99, 254, 35, 245, 5, 107, 99, 255, 66, 247, 230,
+ 107, 99, 255, 48, 241, 49, 107, 99, 153, 242, 49, 107, 99, 253, 240, 243,
+ 127, 107, 99, 253, 240, 233, 218, 107, 99, 253, 240, 237, 237, 107, 99,
+ 255, 51, 252, 12, 107, 99, 255, 48, 250, 188, 107, 99, 153, 252, 208,
+ 107, 99, 253, 240, 242, 152, 107, 99, 253, 240, 239, 218, 107, 99, 253,
+ 240, 242, 151, 107, 99, 255, 51, 253, 150, 107, 99, 255, 69, 239, 2, 107,
+ 99, 255, 88, 252, 70, 107, 99, 254, 27, 242, 60, 107, 99, 255, 41, 253,
+ 179, 107, 99, 254, 27, 246, 244, 107, 99, 255, 41, 250, 233, 107, 99,
+ 254, 27, 238, 0, 107, 99, 255, 83, 222, 107, 99, 255, 66, 249, 20, 107,
+ 99, 255, 90, 252, 150, 107, 99, 253, 185, 107, 99, 255, 43, 243, 215,
+ 107, 99, 254, 8, 107, 99, 255, 96, 247, 191, 107, 99, 255, 35, 247, 63,
+ 107, 99, 255, 35, 247, 57, 107, 99, 255, 35, 252, 191, 107, 99, 255, 32,
+ 251, 62, 107, 99, 255, 43, 241, 55, 107, 99, 117, 248, 124, 107, 99, 255,
+ 32, 239, 145, 107, 99, 234, 231, 107, 99, 248, 83, 67, 107, 99, 253, 205,
+ 236, 32, 107, 99, 248, 83, 253, 140, 107, 99, 248, 83, 254, 32, 107, 99,
+ 248, 83, 71, 107, 99, 248, 83, 253, 142, 107, 99, 248, 83, 253, 252, 107,
+ 99, 248, 83, 252, 249, 107, 99, 248, 83, 79, 107, 99, 248, 83, 253, 148,
+ 107, 99, 237, 236, 107, 236, 181, 12, 244, 190, 107, 99, 248, 83, 72,
+ 107, 99, 248, 83, 253, 178, 107, 99, 248, 83, 73, 107, 99, 248, 83, 255,
+ 37, 237, 198, 107, 99, 248, 83, 255, 37, 236, 55, 107, 99, 232, 181, 107,
+ 99, 236, 56, 107, 99, 234, 220, 107, 99, 253, 205, 254, 90, 107, 99, 253,
+ 205, 248, 97, 107, 99, 253, 205, 252, 229, 107, 99, 253, 205, 235, 188,
+ 107, 99, 233, 41, 107, 99, 236, 63, 107, 99, 236, 141, 107, 99, 237, 158,
+ 107, 26, 242, 217, 107, 26, 127, 107, 26, 111, 107, 26, 166, 107, 26,
+ 177, 107, 26, 176, 107, 26, 187, 107, 26, 203, 107, 26, 195, 107, 26,
+ 202, 107, 99, 233, 113, 107, 99, 239, 108, 152, 1, 253, 190, 152, 1, 253,
+ 249, 243, 35, 152, 1, 253, 249, 248, 120, 152, 1, 248, 172, 152, 1, 253,
+ 224, 152, 1, 255, 35, 248, 120, 152, 1, 248, 133, 152, 1, 253, 225, 152,
+ 1, 87, 152, 1, 253, 240, 243, 35, 152, 1, 253, 240, 248, 120, 152, 1,
+ 253, 173, 152, 1, 254, 1, 152, 1, 253, 208, 152, 1, 254, 27, 243, 35,
+ 152, 1, 255, 41, 248, 120, 152, 1, 254, 27, 248, 120, 152, 1, 255, 41,
+ 243, 35, 152, 1, 253, 181, 152, 1, 253, 162, 152, 1, 255, 43, 243, 215,
+ 152, 1, 255, 43, 246, 54, 152, 1, 253, 177, 152, 1, 255, 35, 243, 35,
+ 152, 1, 255, 32, 243, 35, 152, 1, 73, 152, 1, 255, 32, 248, 120, 152,
+ 235, 69, 152, 33, 21, 67, 152, 33, 21, 253, 205, 248, 162, 152, 33, 21,
+ 253, 140, 152, 33, 21, 254, 32, 152, 33, 21, 71, 152, 33, 21, 253, 142,
+ 152, 33, 21, 255, 14, 152, 33, 21, 254, 77, 152, 33, 21, 79, 152, 33, 21,
+ 253, 148, 152, 33, 21, 253, 205, 251, 159, 152, 235, 143, 21, 253, 216,
+ 152, 235, 143, 21, 248, 133, 152, 33, 21, 72, 152, 33, 21, 254, 89, 152,
+ 33, 21, 73, 152, 33, 21, 254, 33, 152, 33, 21, 253, 149, 152, 255, 59,
+ 253, 134, 152, 188, 253, 205, 254, 90, 152, 188, 253, 205, 248, 97, 152,
+ 188, 253, 205, 253, 212, 152, 188, 253, 205, 239, 18, 152, 232, 118, 69,
+ 152, 234, 227, 152, 26, 242, 217, 152, 26, 127, 152, 26, 111, 152, 26,
+ 166, 152, 26, 177, 152, 26, 176, 152, 26, 187, 152, 26, 203, 152, 26,
+ 195, 152, 26, 202, 152, 255, 32, 253, 173, 152, 255, 32, 253, 181, 47, 4,
+ 254, 43, 47, 158, 248, 129, 253, 221, 253, 226, 236, 133, 67, 47, 158,
+ 248, 129, 253, 221, 253, 226, 254, 79, 249, 155, 250, 112, 222, 47, 158,
+ 248, 129, 253, 221, 253, 226, 254, 79, 248, 129, 243, 49, 222, 47, 158,
+ 54, 253, 221, 253, 226, 251, 224, 222, 47, 158, 238, 171, 253, 221, 253,
+ 226, 252, 173, 222, 47, 158, 243, 25, 253, 221, 253, 226, 249, 137, 249,
+ 161, 222, 47, 158, 253, 221, 253, 226, 243, 49, 249, 161, 222, 47, 158,
+ 247, 65, 243, 23, 47, 158, 244, 230, 253, 221, 248, 167, 47, 158, 250,
+ 127, 249, 162, 253, 221, 248, 167, 47, 158, 231, 143, 240, 249, 47, 158,
+ 235, 202, 243, 49, 241, 40, 47, 158, 243, 23, 47, 158, 248, 234, 243, 23,
+ 47, 158, 243, 49, 243, 23, 47, 158, 248, 234, 243, 49, 243, 23, 47, 158,
+ 254, 235, 250, 159, 242, 126, 243, 23, 47, 158, 249, 154, 251, 29, 243,
+ 23, 47, 158, 243, 25, 243, 140, 243, 72, 255, 81, 183, 248, 100, 47, 158,
+ 248, 129, 240, 249, 47, 237, 22, 21, 250, 158, 240, 70, 47, 237, 22, 21,
+ 251, 192, 240, 70, 47, 232, 89, 21, 252, 175, 251, 12, 244, 67, 240, 70,
+ 47, 232, 89, 21, 241, 3, 253, 129, 47, 232, 89, 21, 247, 67, 239, 230,
+ 47, 21, 248, 101, 248, 151, 243, 179, 47, 21, 248, 101, 248, 151, 240,
+ 183, 47, 21, 248, 101, 248, 151, 243, 187, 47, 21, 248, 101, 254, 66,
+ 243, 179, 47, 21, 248, 101, 254, 66, 240, 183, 47, 21, 248, 101, 248,
+ 151, 248, 101, 251, 252, 47, 26, 242, 217, 47, 26, 127, 47, 26, 111, 47,
+ 26, 166, 47, 26, 177, 47, 26, 176, 47, 26, 187, 47, 26, 203, 47, 26, 195,
+ 47, 26, 202, 47, 26, 137, 127, 47, 26, 137, 111, 47, 26, 137, 166, 47,
+ 26, 137, 177, 47, 26, 137, 176, 47, 26, 137, 187, 47, 26, 137, 203, 47,
+ 26, 137, 195, 47, 26, 137, 202, 47, 26, 137, 242, 217, 47, 158, 244, 228,
+ 240, 70, 47, 158, 249, 119, 243, 153, 254, 116, 253, 108, 47, 158, 243,
+ 25, 243, 140, 243, 72, 248, 199, 254, 112, 248, 100, 47, 158, 249, 119,
+ 243, 153, 252, 174, 240, 70, 47, 158, 253, 223, 248, 167, 47, 158, 254,
+ 129, 241, 4, 47, 158, 254, 95, 243, 72, 243, 189, 47, 158, 254, 95, 243,
+ 72, 243, 188, 47, 158, 254, 80, 243, 206, 243, 189, 47, 158, 254, 80,
+ 243, 206, 243, 188, 47, 21, 255, 8, 240, 250, 47, 21, 254, 198, 240, 250,
+ 47, 1, 201, 47, 1, 248, 61, 47, 1, 253, 139, 47, 1, 248, 77, 47, 1, 248,
+ 50, 47, 1, 253, 152, 47, 1, 248, 57, 47, 1, 253, 146, 47, 1, 248, 78, 47,
+ 1, 248, 71, 47, 1, 242, 247, 47, 1, 248, 75, 47, 1, 242, 249, 47, 1, 248,
+ 82, 47, 1, 253, 126, 47, 1, 248, 55, 47, 1, 253, 133, 47, 1, 248, 76, 47,
+ 1, 253, 131, 47, 1, 253, 129, 47, 1, 248, 65, 47, 1, 253, 141, 47, 1,
+ 248, 81, 47, 1, 222, 47, 1, 248, 90, 47, 1, 243, 130, 47, 1, 248, 153,
+ 47, 1, 243, 165, 47, 1, 253, 138, 47, 1, 248, 99, 47, 1, 253, 163, 47, 1,
+ 254, 78, 47, 1, 216, 47, 1, 253, 130, 47, 1, 253, 134, 47, 1, 248, 46,
+ 47, 1, 248, 66, 47, 1, 253, 132, 47, 1, 219, 47, 1, 67, 47, 1, 243, 210,
+ 47, 1, 234, 28, 253, 130, 47, 33, 21, 253, 140, 47, 33, 21, 71, 47, 33,
+ 21, 253, 142, 47, 33, 21, 79, 47, 33, 21, 253, 148, 47, 33, 21, 165, 144,
+ 47, 33, 21, 165, 253, 182, 47, 33, 21, 165, 162, 47, 33, 21, 165, 253,
+ 191, 47, 33, 21, 72, 47, 33, 21, 253, 164, 47, 33, 21, 73, 47, 33, 21,
+ 253, 156, 47, 21, 252, 140, 255, 91, 254, 212, 253, 160, 47, 21, 249,
+ 155, 244, 212, 47, 33, 21, 224, 71, 47, 33, 21, 224, 253, 142, 47, 21,
+ 254, 116, 255, 12, 254, 210, 253, 133, 47, 21, 254, 239, 246, 39, 47,
+ 158, 237, 168, 47, 158, 239, 157, 47, 21, 254, 192, 240, 70, 47, 21, 248,
+ 122, 240, 70, 47, 21, 254, 191, 254, 129, 248, 100, 47, 21, 251, 223,
+ 248, 100, 47, 21, 254, 94, 254, 148, 237, 34, 47, 21, 254, 94, 254, 200,
+ 237, 34, 47, 213, 1, 201, 47, 213, 1, 248, 61, 47, 213, 1, 253, 139, 47,
+ 213, 1, 248, 77, 47, 213, 1, 248, 50, 47, 213, 1, 253, 152, 47, 213, 1,
+ 248, 57, 47, 213, 1, 253, 146, 47, 213, 1, 248, 78, 47, 213, 1, 248, 71,
+ 47, 213, 1, 242, 247, 47, 213, 1, 248, 75, 47, 213, 1, 242, 249, 47, 213,
+ 1, 248, 82, 47, 213, 1, 253, 126, 47, 213, 1, 248, 55, 47, 213, 1, 253,
+ 133, 47, 213, 1, 248, 76, 47, 213, 1, 253, 131, 47, 213, 1, 253, 129, 47,
+ 213, 1, 248, 65, 47, 213, 1, 253, 141, 47, 213, 1, 248, 81, 47, 213, 1,
+ 222, 47, 213, 1, 248, 90, 47, 213, 1, 243, 130, 47, 213, 1, 248, 153, 47,
+ 213, 1, 243, 165, 47, 213, 1, 253, 138, 47, 213, 1, 248, 99, 47, 213, 1,
+ 253, 163, 47, 213, 1, 254, 78, 47, 213, 1, 216, 47, 213, 1, 253, 130, 47,
+ 213, 1, 253, 134, 47, 213, 1, 248, 46, 47, 213, 1, 248, 66, 47, 213, 1,
+ 253, 132, 47, 213, 1, 219, 47, 213, 1, 67, 47, 213, 1, 243, 210, 47, 213,
+ 1, 234, 28, 253, 138, 47, 213, 1, 234, 28, 216, 47, 213, 1, 234, 28, 253,
+ 130, 47, 255, 60, 255, 64, 248, 61, 47, 255, 60, 255, 64, 254, 183, 248,
+ 199, 254, 112, 248, 100, 47, 232, 82, 21, 96, 243, 147, 47, 232, 82, 21,
+ 136, 243, 147, 47, 232, 82, 21, 250, 144, 247, 138, 47, 232, 82, 21, 252,
+ 170, 241, 2, 47, 12, 250, 206, 253, 243, 47, 12, 254, 124, 252, 139, 47,
+ 12, 246, 237, 245, 97, 47, 12, 254, 124, 254, 236, 249, 154, 245, 127,
+ 47, 12, 249, 137, 253, 129, 47, 12, 253, 192, 253, 243, 47, 12, 253, 192,
+ 255, 47, 248, 234, 238, 127, 47, 12, 253, 192, 255, 47, 251, 30, 238,
+ 127, 47, 12, 253, 192, 255, 47, 248, 199, 238, 127, 47, 21, 248, 101,
+ 254, 66, 243, 187, 47, 158, 244, 229, 249, 162, 255, 57, 253, 226, 240,
+ 216, 47, 158, 246, 89, 253, 221, 255, 57, 253, 226, 240, 216, 131, 1,
+ 201, 131, 1, 248, 61, 131, 1, 253, 139, 131, 1, 248, 77, 131, 1, 248, 50,
+ 131, 1, 253, 152, 131, 1, 248, 57, 131, 1, 253, 146, 131, 1, 248, 89,
+ 131, 1, 248, 78, 131, 1, 246, 175, 131, 1, 248, 71, 131, 1, 242, 247,
+ 131, 1, 248, 75, 131, 1, 242, 249, 131, 1, 248, 82, 131, 1, 253, 126,
+ 131, 1, 248, 55, 131, 1, 253, 133, 131, 1, 248, 76, 131, 1, 253, 131,
+ 131, 1, 253, 129, 131, 1, 248, 65, 131, 1, 253, 141, 131, 1, 248, 81,
+ 131, 1, 222, 131, 1, 216, 131, 1, 253, 130, 131, 1, 253, 134, 131, 1,
+ 253, 138, 131, 1, 253, 132, 131, 1, 219, 131, 1, 248, 94, 131, 1, 67,
+ 131, 1, 71, 131, 1, 253, 142, 131, 1, 79, 131, 1, 253, 148, 131, 1, 72,
+ 131, 1, 73, 131, 1, 253, 151, 131, 33, 21, 253, 140, 131, 33, 21, 71,
+ 131, 33, 21, 253, 142, 131, 33, 21, 79, 131, 33, 21, 253, 148, 131, 33,
+ 21, 72, 131, 33, 21, 253, 149, 131, 21, 235, 61, 131, 21, 53, 46, 131,
+ 21, 236, 173, 131, 21, 238, 72, 131, 26, 242, 217, 131, 26, 127, 131, 26,
+ 111, 131, 26, 166, 131, 26, 177, 131, 26, 176, 131, 26, 187, 131, 26,
+ 203, 131, 26, 195, 131, 26, 202, 131, 21, 240, 101, 236, 210, 131, 21,
+ 236, 210, 131, 12, 236, 52, 131, 12, 234, 102, 131, 12, 229, 63, 131, 12,
+ 236, 30, 131, 1, 248, 46, 131, 1, 248, 66, 131, 1, 165, 144, 131, 1, 165,
+ 253, 182, 131, 1, 165, 162, 131, 1, 165, 253, 191, 131, 33, 21, 165, 144,
+ 131, 33, 21, 165, 253, 182, 131, 33, 21, 165, 162, 131, 33, 21, 165, 253,
+ 191, 75, 5, 1, 254, 19, 75, 5, 1, 248, 195, 75, 5, 1, 248, 158, 75, 5, 1,
+ 248, 205, 75, 5, 1, 253, 202, 75, 5, 1, 249, 11, 75, 5, 1, 249, 25, 75,
+ 5, 1, 248, 253, 75, 5, 1, 253, 247, 75, 5, 1, 248, 162, 75, 5, 1, 248,
+ 224, 75, 5, 1, 248, 131, 75, 5, 1, 248, 171, 75, 5, 1, 254, 9, 75, 5, 1,
+ 248, 236, 75, 5, 1, 243, 138, 75, 5, 1, 248, 243, 75, 5, 1, 248, 134, 75,
+ 5, 1, 248, 254, 75, 5, 1, 254, 75, 75, 5, 1, 243, 115, 75, 5, 1, 243,
+ 103, 75, 5, 1, 243, 95, 75, 5, 1, 248, 242, 75, 5, 1, 243, 33, 75, 5, 1,
+ 243, 88, 75, 5, 1, 248, 100, 75, 5, 1, 248, 217, 75, 5, 1, 248, 201, 75,
+ 5, 1, 243, 87, 75, 5, 1, 249, 16, 75, 5, 1, 243, 101, 75, 5, 1, 248, 212,
+ 75, 5, 1, 253, 168, 75, 5, 1, 248, 160, 75, 5, 1, 253, 170, 75, 5, 1,
+ 248, 213, 75, 5, 1, 248, 215, 75, 1, 254, 19, 75, 1, 248, 195, 75, 1,
+ 248, 158, 75, 1, 248, 205, 75, 1, 253, 202, 75, 1, 249, 11, 75, 1, 249,
+ 25, 75, 1, 248, 253, 75, 1, 253, 247, 75, 1, 248, 162, 75, 1, 248, 224,
+ 75, 1, 248, 131, 75, 1, 248, 171, 75, 1, 254, 9, 75, 1, 248, 236, 75, 1,
+ 243, 138, 75, 1, 248, 243, 75, 1, 248, 134, 75, 1, 248, 254, 75, 1, 254,
+ 75, 75, 1, 243, 115, 75, 1, 243, 103, 75, 1, 243, 95, 75, 1, 248, 242,
+ 75, 1, 243, 33, 75, 1, 243, 88, 75, 1, 248, 100, 75, 1, 248, 217, 75, 1,
+ 248, 201, 75, 1, 243, 87, 75, 1, 249, 16, 75, 1, 243, 101, 75, 1, 248,
+ 212, 75, 1, 253, 168, 75, 1, 248, 160, 75, 1, 253, 170, 75, 1, 248, 213,
+ 75, 1, 248, 215, 75, 1, 253, 245, 75, 1, 255, 9, 75, 1, 241, 94, 75, 1,
+ 205, 248, 158, 75, 1, 248, 105, 75, 235, 91, 234, 6, 49, 1, 75, 248, 171,
+ 23, 102, 238, 99, 23, 102, 232, 87, 23, 102, 240, 80, 23, 102, 238, 102,
+ 23, 102, 232, 101, 23, 102, 240, 85, 23, 102, 240, 78, 23, 102, 240, 83,
+ 23, 102, 233, 79, 23, 102, 243, 34, 23, 102, 234, 32, 23, 102, 240, 75,
+ 23, 102, 240, 71, 23, 102, 233, 77, 23, 102, 236, 195, 23, 102, 236, 198,
+ 23, 102, 236, 205, 23, 102, 236, 201, 23, 102, 240, 74, 23, 102, 231,
+ 108, 23, 102, 233, 105, 23, 102, 231, 97, 23, 102, 232, 187, 23, 102,
+ 231, 56, 23, 102, 232, 108, 23, 102, 233, 106, 23, 102, 232, 85, 23, 102,
+ 231, 71, 23, 102, 232, 92, 23, 102, 231, 40, 23, 102, 231, 109, 23, 102,
+ 232, 195, 23, 102, 231, 110, 23, 102, 233, 66, 23, 102, 226, 243, 23,
+ 102, 226, 244, 23, 102, 227, 4, 23, 102, 229, 52, 23, 102, 227, 3, 23,
+ 102, 232, 106, 23, 102, 231, 75, 23, 102, 231, 52, 23, 102, 231, 51, 23,
+ 102, 231, 41, 23, 102, 226, 235, 23, 102, 232, 99, 23, 102, 233, 102, 23,
+ 102, 232, 100, 23, 102, 233, 103, 23, 102, 233, 245, 23, 102, 233, 76,
+ 23, 102, 226, 253, 23, 102, 231, 30, 23, 102, 233, 244, 23, 102, 233,
+ 101, 23, 102, 232, 55, 23, 102, 232, 56, 23, 102, 232, 58, 23, 102, 232,
+ 57, 23, 102, 233, 243, 23, 102, 231, 120, 23, 102, 226, 247, 23, 102,
+ 227, 13, 23, 102, 226, 232, 23, 102, 236, 234, 23, 102, 231, 106, 23,
+ 102, 231, 142, 23, 102, 232, 175, 23, 102, 232, 176, 23, 102, 233, 208,
+ 23, 102, 231, 68, 23, 102, 233, 78, 23, 102, 232, 174, 23, 102, 231, 66,
+ 23, 102, 231, 70, 23, 102, 231, 69, 23, 102, 235, 115, 23, 102, 232, 119,
+ 23, 102, 231, 62, 23, 102, 226, 238, 23, 102, 227, 1, 23, 102, 226, 229,
+ 23, 102, 227, 14, 23, 102, 231, 61, 23, 102, 227, 15, 23, 102, 226, 237,
+ 23, 102, 231, 50, 23, 102, 227, 9, 23, 102, 233, 104, 23, 102, 232, 102,
+ 23, 102, 238, 114, 23, 146, 238, 114, 23, 146, 67, 23, 146, 253, 178, 23,
+ 146, 216, 23, 146, 249, 18, 23, 146, 254, 59, 23, 146, 72, 23, 146, 249,
+ 22, 23, 146, 253, 254, 23, 146, 73, 23, 146, 253, 138, 23, 146, 249, 12,
+ 23, 146, 253, 193, 23, 146, 253, 162, 23, 146, 79, 23, 146, 249, 14, 23,
+ 146, 253, 170, 23, 146, 253, 187, 23, 146, 253, 161, 23, 146, 254, 61,
+ 23, 146, 253, 189, 23, 146, 71, 23, 146, 249, 229, 23, 146, 249, 230, 23,
+ 146, 247, 211, 23, 146, 242, 189, 23, 146, 245, 83, 23, 146, 245, 84, 23,
+ 146, 241, 96, 23, 146, 242, 195, 23, 146, 242, 196, 23, 146, 246, 230,
+ 23, 146, 252, 52, 23, 146, 246, 231, 23, 146, 252, 53, 23, 146, 252, 54,
+ 23, 146, 240, 255, 23, 146, 238, 233, 23, 146, 239, 251, 23, 146, 247,
+ 231, 23, 146, 244, 58, 23, 146, 252, 247, 23, 146, 247, 180, 23, 146,
+ 238, 36, 23, 146, 247, 181, 23, 146, 252, 248, 23, 146, 247, 234, 23,
+ 146, 242, 199, 23, 146, 247, 235, 23, 146, 238, 234, 23, 146, 241, 0, 23,
+ 146, 247, 236, 23, 146, 244, 60, 23, 146, 245, 86, 23, 146, 241, 99, 23,
+ 146, 247, 226, 23, 146, 251, 97, 23, 146, 245, 223, 23, 146, 251, 98, 23,
+ 146, 251, 99, 23, 146, 245, 222, 23, 146, 237, 175, 23, 146, 240, 156,
+ 23, 146, 235, 169, 23, 146, 237, 65, 23, 146, 237, 64, 23, 146, 233, 246,
+ 23, 114, 238, 99, 23, 114, 232, 87, 23, 114, 232, 91, 23, 114, 240, 80,
+ 23, 114, 232, 93, 23, 114, 232, 94, 23, 114, 238, 102, 23, 114, 240, 85,
+ 23, 114, 231, 98, 23, 114, 232, 96, 23, 114, 232, 97, 23, 114, 233, 74,
+ 23, 114, 231, 43, 23, 114, 231, 42, 23, 114, 232, 85, 23, 114, 240, 78,
+ 23, 114, 240, 83, 23, 114, 233, 66, 23, 114, 243, 34, 23, 114, 234, 32,
+ 23, 114, 240, 75, 23, 114, 240, 71, 23, 114, 236, 195, 23, 114, 236, 198,
+ 23, 114, 236, 205, 23, 114, 236, 201, 23, 114, 240, 74, 23, 114, 231,
+ 145, 23, 114, 226, 239, 23, 114, 231, 108, 23, 114, 231, 97, 23, 114,
+ 233, 90, 23, 114, 231, 47, 23, 114, 231, 74, 23, 114, 231, 56, 23, 114,
+ 232, 61, 23, 114, 226, 245, 23, 114, 232, 108, 23, 114, 231, 111, 23,
+ 114, 226, 241, 23, 114, 233, 106, 23, 114, 226, 240, 23, 114, 227, 5, 23,
+ 114, 226, 255, 23, 114, 226, 251, 23, 114, 226, 234, 23, 114, 229, 55,
+ 23, 114, 231, 54, 23, 114, 231, 76, 23, 114, 226, 246, 23, 114, 231, 147,
+ 23, 114, 232, 183, 23, 114, 232, 92, 23, 114, 233, 86, 23, 114, 229, 50,
+ 23, 114, 231, 46, 23, 114, 231, 73, 23, 114, 232, 182, 23, 114, 231, 40,
+ 23, 114, 232, 196, 23, 114, 231, 51, 23, 114, 232, 194, 23, 114, 231, 41,
+ 23, 114, 232, 99, 23, 114, 232, 100, 23, 114, 233, 103, 23, 114, 233, 76,
+ 23, 114, 236, 234, 23, 114, 231, 106, 23, 114, 226, 248, 23, 114, 233,
+ 78, 23, 114, 231, 67, 23, 114, 235, 115, 23, 114, 231, 58, 23, 114, 227,
+ 0, 23, 114, 231, 50, 23, 114, 227, 9, 23, 114, 232, 170, 23, 114, 232,
+ 172, 23, 114, 232, 169, 23, 114, 232, 171, 23, 114, 232, 102, 22, 4, 219,
+ 22, 4, 253, 236, 22, 4, 253, 214, 22, 4, 248, 114, 22, 4, 249, 80, 22, 4,
+ 253, 168, 22, 4, 253, 184, 22, 4, 251, 76, 22, 4, 253, 134, 22, 4, 254,
+ 8, 22, 4, 253, 251, 22, 4, 249, 101, 22, 4, 249, 102, 22, 4, 253, 250,
+ 22, 4, 253, 216, 22, 4, 248, 227, 22, 4, 251, 56, 22, 4, 251, 60, 22, 4,
+ 251, 58, 22, 4, 243, 194, 22, 4, 245, 143, 22, 4, 251, 57, 22, 4, 251,
+ 59, 22, 4, 245, 144, 22, 4, 222, 22, 4, 253, 154, 22, 4, 253, 180, 22, 4,
+ 249, 110, 22, 4, 249, 111, 22, 4, 253, 206, 22, 4, 253, 181, 22, 4, 248,
+ 169, 22, 4, 252, 202, 22, 4, 252, 206, 22, 4, 252, 204, 22, 4, 247, 131,
+ 22, 4, 247, 132, 22, 4, 252, 203, 22, 4, 252, 205, 22, 4, 247, 133, 22,
+ 4, 253, 130, 22, 4, 253, 185, 22, 4, 253, 209, 22, 4, 248, 182, 22, 4,
+ 249, 153, 22, 4, 253, 194, 22, 4, 253, 160, 22, 4, 252, 157, 22, 4, 253,
+ 132, 22, 4, 253, 211, 22, 4, 253, 198, 22, 4, 249, 158, 22, 4, 248, 184,
+ 22, 4, 253, 210, 22, 4, 253, 186, 22, 4, 248, 252, 22, 4, 248, 46, 22, 4,
+ 248, 248, 22, 4, 248, 185, 22, 4, 244, 7, 22, 4, 244, 9, 22, 4, 248, 118,
+ 22, 4, 248, 110, 22, 4, 243, 121, 22, 4, 253, 217, 22, 4, 254, 29, 22, 4,
+ 254, 28, 22, 4, 248, 241, 22, 4, 252, 88, 22, 4, 254, 70, 22, 4, 254, 45,
+ 22, 4, 252, 98, 22, 4, 252, 112, 22, 4, 252, 114, 22, 4, 247, 21, 22, 4,
+ 247, 22, 22, 4, 252, 113, 22, 4, 252, 89, 22, 4, 252, 93, 22, 4, 252, 91,
+ 22, 4, 247, 7, 22, 4, 247, 8, 22, 4, 252, 90, 22, 4, 252, 92, 22, 4, 247,
+ 9, 22, 4, 247, 11, 22, 4, 242, 72, 22, 4, 242, 73, 22, 4, 247, 10, 22, 4,
+ 253, 141, 22, 4, 253, 243, 22, 4, 254, 34, 22, 4, 249, 30, 22, 4, 248,
+ 197, 22, 4, 253, 242, 22, 4, 254, 1, 22, 4, 249, 36, 22, 4, 253, 171, 22,
+ 4, 254, 49, 22, 4, 254, 48, 22, 4, 253, 6, 22, 4, 249, 10, 22, 4, 254,
+ 12, 22, 4, 254, 13, 22, 4, 253, 24, 22, 4, 253, 126, 22, 4, 253, 196, 22,
+ 4, 253, 212, 22, 4, 249, 172, 22, 4, 248, 255, 22, 4, 253, 195, 22, 4,
+ 87, 22, 4, 249, 7, 22, 4, 253, 152, 22, 4, 254, 84, 22, 4, 254, 55, 22,
+ 4, 249, 37, 22, 4, 250, 154, 22, 4, 254, 54, 22, 4, 253, 224, 22, 4, 248,
+ 203, 22, 4, 253, 253, 22, 4, 255, 6, 22, 4, 253, 188, 22, 4, 253, 41, 22,
+ 4, 253, 42, 22, 4, 254, 132, 22, 4, 254, 133, 22, 4, 253, 47, 22, 4, 253,
+ 53, 22, 4, 253, 55, 22, 4, 247, 206, 22, 4, 247, 207, 22, 4, 253, 54, 22,
+ 4, 253, 131, 22, 4, 253, 150, 22, 4, 253, 166, 22, 4, 248, 231, 22, 4,
+ 249, 118, 22, 4, 253, 197, 22, 4, 253, 173, 22, 4, 248, 176, 22, 4, 248,
+ 78, 22, 4, 249, 125, 22, 4, 248, 178, 22, 4, 246, 198, 22, 4, 246, 200,
+ 22, 4, 252, 46, 22, 4, 248, 133, 22, 4, 246, 212, 22, 4, 238, 62, 67, 22,
+ 4, 238, 62, 79, 22, 4, 238, 62, 71, 22, 4, 238, 62, 253, 140, 22, 4, 238,
+ 62, 253, 164, 22, 4, 238, 62, 72, 22, 4, 238, 62, 73, 22, 4, 238, 62,
+ 253, 138, 22, 4, 201, 22, 4, 253, 203, 22, 4, 253, 215, 22, 4, 249, 90,
+ 22, 4, 251, 141, 22, 4, 253, 172, 22, 4, 253, 190, 22, 4, 251, 157, 22,
+ 4, 248, 221, 22, 4, 248, 223, 22, 4, 243, 65, 22, 4, 246, 25, 22, 4, 248,
+ 222, 22, 4, 251, 170, 22, 4, 251, 174, 22, 4, 251, 172, 22, 4, 246, 26,
+ 22, 4, 246, 27, 22, 4, 251, 171, 22, 4, 251, 173, 22, 4, 246, 28, 22, 4,
+ 246, 30, 22, 4, 241, 207, 22, 4, 241, 208, 22, 4, 246, 29, 22, 4, 253,
+ 138, 22, 4, 254, 14, 22, 4, 253, 187, 22, 4, 248, 190, 22, 4, 249, 199,
+ 22, 4, 253, 170, 22, 4, 253, 177, 22, 4, 253, 34, 22, 4, 234, 12, 67, 22,
+ 4, 234, 12, 79, 22, 4, 234, 12, 71, 22, 4, 234, 12, 253, 140, 22, 4, 234,
+ 12, 253, 164, 22, 4, 234, 12, 72, 22, 4, 234, 12, 73, 22, 4, 253, 163,
+ 22, 4, 254, 18, 22, 4, 254, 17, 22, 4, 249, 216, 22, 4, 248, 194, 22, 4,
+ 253, 228, 22, 4, 253, 222, 22, 4, 253, 117, 22, 4, 248, 99, 22, 4, 249,
+ 219, 22, 4, 249, 217, 22, 4, 247, 245, 22, 4, 243, 139, 22, 4, 248, 123,
+ 22, 4, 249, 218, 22, 4, 248, 4, 22, 4, 216, 22, 4, 253, 161, 22, 4, 253,
+ 189, 22, 4, 248, 191, 22, 4, 248, 192, 22, 4, 253, 254, 22, 4, 253, 162,
+ 22, 4, 253, 84, 22, 4, 253, 133, 22, 4, 253, 232, 22, 4, 253, 201, 22, 4,
+ 250, 177, 22, 4, 248, 149, 22, 4, 253, 200, 22, 4, 253, 225, 22, 4, 250,
+ 214, 22, 4, 248, 75, 22, 4, 249, 52, 22, 4, 249, 51, 22, 4, 245, 36, 22,
+ 4, 245, 41, 22, 4, 249, 50, 22, 4, 248, 204, 22, 4, 245, 57, 22, 4, 253,
+ 146, 22, 4, 254, 25, 22, 4, 254, 7, 22, 4, 251, 110, 22, 4, 248, 161, 22,
+ 4, 254, 24, 22, 4, 253, 248, 22, 4, 251, 131, 22, 4, 253, 139, 22, 4,
+ 253, 235, 22, 4, 254, 6, 22, 4, 248, 211, 22, 4, 249, 68, 22, 4, 254, 5,
+ 22, 4, 253, 234, 22, 4, 251, 25, 22, 4, 251, 36, 22, 4, 251, 38, 22, 4,
+ 245, 134, 22, 4, 245, 135, 22, 4, 251, 37, 22, 4, 249, 70, 22, 4, 249,
+ 74, 22, 4, 249, 72, 22, 4, 245, 99, 22, 4, 245, 103, 22, 4, 249, 71, 22,
+ 4, 249, 73, 22, 4, 241, 134, 22, 4, 248, 55, 22, 4, 249, 177, 22, 4, 248,
+ 121, 22, 4, 243, 76, 22, 4, 243, 77, 22, 4, 248, 111, 22, 4, 248, 97, 22,
+ 4, 247, 147, 22, 4, 248, 57, 22, 4, 248, 200, 22, 4, 248, 67, 22, 4, 244,
+ 252, 22, 4, 243, 54, 22, 4, 248, 88, 22, 4, 248, 125, 22, 4, 245, 13, 22,
+ 4, 248, 65, 22, 4, 252, 64, 22, 4, 248, 68, 22, 4, 246, 243, 22, 4, 246,
+ 245, 22, 4, 249, 136, 22, 4, 248, 238, 22, 4, 246, 247, 22, 4, 248, 90,
+ 22, 4, 249, 5, 22, 4, 248, 140, 22, 4, 247, 160, 22, 4, 244, 39, 22, 4,
+ 248, 112, 22, 4, 249, 4, 22, 4, 247, 162, 22, 4, 252, 242, 22, 4, 252,
+ 246, 22, 4, 252, 244, 22, 4, 247, 177, 22, 4, 247, 178, 22, 4, 252, 243,
+ 22, 4, 252, 245, 22, 4, 247, 179, 22, 4, 253, 179, 22, 4, 254, 93, 22, 4,
+ 253, 245, 22, 4, 249, 60, 22, 4, 249, 61, 22, 4, 254, 62, 22, 4, 254, 63,
+ 22, 4, 249, 66, 22, 4, 253, 129, 22, 4, 253, 239, 22, 4, 253, 147, 22, 4,
+ 249, 133, 22, 4, 248, 180, 22, 4, 253, 175, 22, 4, 253, 208, 22, 4, 248,
+ 181, 22, 4, 252, 158, 22, 4, 251, 248, 22, 4, 251, 1, 22, 50, 234, 194,
+ 69, 22, 238, 213, 69, 22, 235, 42, 22, 248, 37, 208, 22, 240, 27, 22,
+ 234, 14, 22, 240, 24, 22, 239, 166, 240, 24, 22, 236, 156, 69, 22, 235,
+ 91, 234, 6, 22, 26, 127, 22, 26, 111, 22, 26, 166, 22, 26, 177, 22, 26,
+ 176, 22, 26, 187, 22, 26, 203, 22, 26, 195, 22, 26, 202, 22, 61, 248, 53,
+ 22, 61, 238, 77, 22, 61, 238, 101, 22, 61, 240, 136, 22, 61, 240, 50, 22,
+ 61, 240, 234, 22, 61, 237, 38, 22, 61, 238, 182, 22, 61, 238, 147, 22,
+ 61, 236, 149, 22, 61, 253, 219, 235, 49, 22, 4, 235, 94, 248, 169, 22, 4,
+ 248, 230, 22, 4, 246, 101, 22, 4, 248, 229, 22, 4, 235, 94, 249, 36, 22,
+ 4, 250, 136, 22, 4, 244, 237, 22, 4, 250, 135, 22, 4, 235, 94, 249, 66,
+ 22, 4, 251, 0, 22, 4, 245, 95, 22, 4, 250, 255, 22, 4, 235, 94, 248, 181,
+ 22, 4, 248, 240, 22, 4, 247, 2, 22, 4, 248, 239, 22, 243, 10, 158, 242,
+ 198, 22, 243, 10, 158, 241, 83, 22, 243, 10, 158, 238, 212, 22, 243, 10,
+ 158, 242, 215, 238, 212, 22, 243, 10, 158, 241, 84, 22, 243, 10, 158,
+ 241, 199, 22, 243, 10, 158, 239, 24, 22, 243, 10, 158, 241, 149, 22, 243,
+ 10, 158, 232, 130, 22, 243, 10, 158, 246, 22, 109, 1, 67, 109, 1, 72,
+ 109, 1, 71, 109, 1, 73, 109, 1, 79, 109, 1, 179, 109, 1, 253, 139, 109,
+ 1, 201, 109, 1, 254, 5, 109, 1, 254, 6, 109, 1, 253, 234, 109, 1, 253,
+ 235, 109, 1, 254, 169, 109, 1, 219, 109, 1, 253, 168, 109, 1, 253, 214,
+ 109, 1, 253, 184, 109, 1, 253, 236, 109, 1, 254, 98, 109, 1, 253, 134,
+ 109, 1, 253, 250, 109, 1, 253, 251, 109, 1, 253, 216, 109, 1, 254, 8,
+ 109, 1, 254, 196, 109, 1, 222, 109, 1, 253, 206, 109, 1, 253, 180, 109,
+ 1, 253, 181, 109, 1, 253, 154, 109, 1, 253, 131, 109, 1, 249, 83, 109, 1,
+ 251, 253, 109, 1, 253, 197, 109, 1, 253, 166, 109, 1, 253, 173, 109, 1,
+ 253, 150, 109, 1, 254, 115, 109, 1, 252, 103, 109, 1, 252, 104, 109, 1,
+ 252, 105, 109, 1, 249, 149, 109, 1, 249, 150, 109, 1, 252, 110, 109, 1,
+ 253, 132, 109, 1, 193, 109, 1, 253, 210, 109, 1, 253, 198, 109, 1, 253,
+ 186, 109, 1, 253, 211, 109, 1, 254, 127, 109, 1, 253, 133, 109, 1, 253,
+ 126, 109, 1, 253, 200, 109, 1, 253, 195, 109, 1, 253, 201, 109, 1, 253,
+ 212, 109, 1, 253, 225, 109, 1, 253, 232, 109, 1, 254, 158, 109, 1, 249,
+ 55, 109, 1, 249, 179, 109, 1, 249, 180, 109, 1, 249, 181, 109, 1, 249,
+ 182, 109, 1, 249, 183, 109, 1, 252, 225, 109, 1, 248, 90, 109, 1, 248,
+ 112, 109, 1, 248, 140, 109, 1, 249, 4, 109, 1, 249, 5, 109, 1, 252, 230,
+ 109, 1, 253, 138, 109, 1, 253, 170, 109, 1, 253, 187, 109, 1, 253, 177,
+ 109, 1, 254, 14, 109, 1, 255, 4, 109, 1, 216, 109, 1, 253, 254, 109, 1,
+ 253, 189, 109, 1, 253, 162, 109, 1, 253, 161, 109, 1, 255, 10, 14, 15,
+ 72, 14, 15, 249, 231, 14, 15, 71, 14, 15, 253, 142, 14, 15, 73, 14, 15,
+ 253, 156, 14, 15, 240, 44, 253, 156, 14, 15, 55, 253, 164, 14, 15, 55,
+ 71, 14, 15, 67, 14, 15, 253, 140, 14, 15, 253, 170, 14, 15, 106, 253,
+ 170, 14, 15, 253, 187, 14, 15, 106, 253, 187, 14, 15, 249, 200, 14, 15,
+ 106, 249, 200, 14, 15, 253, 177, 14, 15, 106, 253, 177, 14, 15, 249, 15,
+ 14, 15, 106, 249, 15, 14, 15, 238, 66, 249, 15, 14, 15, 253, 138, 14, 15,
+ 106, 253, 138, 14, 15, 248, 190, 14, 15, 106, 248, 190, 14, 15, 238, 66,
+ 248, 190, 14, 15, 253, 149, 14, 15, 240, 44, 255, 16, 14, 15, 238, 62,
+ 208, 14, 15, 30, 135, 14, 15, 30, 191, 14, 15, 30, 240, 17, 137, 242,
+ 233, 14, 15, 30, 253, 159, 137, 242, 233, 14, 15, 30, 38, 137, 242, 233,
+ 14, 15, 30, 242, 233, 14, 15, 30, 45, 135, 14, 15, 30, 45, 242, 215, 59,
+ 237, 45, 14, 15, 30, 240, 1, 248, 40, 14, 15, 30, 242, 215, 163, 108, 14,
+ 15, 30, 243, 12, 14, 15, 30, 92, 242, 234, 14, 15, 253, 202, 14, 15, 253,
+ 247, 14, 15, 254, 9, 14, 15, 254, 19, 14, 15, 253, 175, 14, 15, 246, 236,
+ 14, 15, 253, 147, 14, 15, 249, 138, 14, 15, 253, 208, 14, 15, 249, 140,
+ 14, 15, 240, 44, 249, 140, 14, 15, 55, 249, 80, 14, 15, 55, 253, 214, 14,
+ 15, 253, 129, 14, 15, 249, 133, 14, 15, 248, 239, 14, 15, 106, 248, 239,
+ 14, 15, 248, 240, 14, 15, 106, 248, 240, 14, 15, 243, 247, 14, 15, 106,
+ 243, 247, 14, 15, 249, 143, 14, 15, 106, 249, 143, 14, 15, 243, 248, 14,
+ 15, 106, 243, 248, 14, 15, 248, 181, 14, 15, 106, 248, 181, 14, 15, 243,
+ 118, 14, 15, 106, 243, 118, 14, 15, 240, 44, 243, 118, 14, 15, 223, 14,
+ 15, 106, 223, 14, 15, 55, 192, 14, 15, 253, 195, 14, 15, 247, 135, 14,
+ 15, 253, 212, 14, 15, 252, 221, 14, 15, 87, 14, 15, 249, 2, 14, 15, 240,
+ 44, 249, 2, 14, 15, 55, 248, 149, 14, 15, 55, 253, 201, 14, 15, 253, 126,
+ 14, 15, 249, 172, 14, 15, 249, 8, 14, 15, 106, 249, 8, 14, 15, 249, 189,
+ 14, 15, 106, 249, 189, 14, 15, 244, 42, 14, 15, 106, 244, 42, 14, 15,
+ 111, 14, 15, 106, 111, 14, 15, 244, 43, 14, 15, 106, 244, 43, 14, 15,
+ 249, 7, 14, 15, 106, 249, 7, 14, 15, 243, 132, 14, 15, 106, 243, 132, 14,
+ 15, 238, 66, 243, 132, 14, 15, 214, 14, 15, 249, 186, 14, 15, 249, 187,
+ 14, 15, 249, 6, 14, 15, 248, 71, 14, 15, 253, 172, 14, 15, 246, 4, 14,
+ 15, 253, 215, 14, 15, 251, 150, 14, 15, 253, 190, 14, 15, 249, 98, 14,
+ 15, 240, 44, 249, 98, 14, 15, 201, 14, 15, 249, 90, 14, 15, 248, 222, 14,
+ 15, 106, 248, 222, 14, 15, 248, 223, 14, 15, 106, 248, 223, 14, 15, 243,
+ 211, 14, 15, 106, 243, 211, 14, 15, 249, 100, 14, 15, 106, 249, 100, 14,
+ 15, 243, 212, 14, 15, 106, 243, 212, 14, 15, 248, 221, 14, 15, 106, 248,
+ 221, 14, 15, 243, 65, 14, 15, 106, 243, 65, 14, 15, 238, 66, 243, 65, 14,
+ 15, 255, 15, 14, 15, 254, 108, 14, 15, 232, 86, 248, 218, 14, 15, 232,
+ 86, 251, 149, 14, 15, 232, 86, 251, 158, 14, 15, 232, 86, 251, 136, 14,
+ 15, 254, 54, 14, 15, 244, 239, 14, 15, 254, 55, 14, 15, 250, 162, 14, 15,
+ 253, 224, 14, 15, 249, 42, 14, 15, 240, 44, 249, 42, 14, 15, 253, 152,
+ 14, 15, 249, 37, 14, 15, 249, 44, 14, 15, 106, 249, 44, 14, 15, 249, 45,
+ 14, 15, 106, 249, 45, 14, 15, 243, 159, 14, 15, 106, 243, 159, 14, 15,
+ 249, 46, 14, 15, 106, 249, 46, 14, 15, 243, 160, 14, 15, 106, 243, 160,
+ 14, 15, 248, 203, 14, 15, 106, 248, 203, 14, 15, 243, 91, 14, 15, 106,
+ 243, 91, 14, 15, 238, 66, 243, 91, 14, 15, 255, 18, 14, 15, 240, 36, 254,
+ 46, 14, 15, 253, 206, 14, 15, 246, 61, 14, 15, 253, 180, 14, 15, 251,
+ 232, 14, 15, 253, 181, 14, 15, 249, 112, 14, 15, 240, 44, 249, 112, 14,
+ 15, 222, 14, 15, 249, 110, 14, 15, 248, 229, 14, 15, 106, 248, 229, 14,
+ 15, 248, 230, 14, 15, 106, 248, 230, 14, 15, 243, 228, 14, 15, 106, 243,
+ 228, 14, 15, 249, 117, 14, 15, 106, 249, 117, 14, 15, 243, 229, 14, 15,
+ 106, 243, 229, 14, 15, 248, 169, 14, 15, 106, 248, 169, 14, 15, 243, 109,
+ 14, 15, 106, 243, 109, 14, 15, 238, 66, 243, 109, 14, 15, 173, 14, 15,
+ 106, 173, 14, 15, 254, 203, 14, 15, 234, 47, 173, 14, 15, 240, 36, 173,
+ 14, 15, 253, 197, 14, 15, 246, 102, 14, 15, 253, 166, 14, 15, 252, 22,
+ 14, 15, 253, 173, 14, 15, 249, 121, 14, 15, 240, 44, 249, 121, 14, 15,
+ 253, 131, 14, 15, 248, 231, 14, 15, 249, 124, 14, 15, 106, 249, 124, 14,
+ 15, 248, 176, 14, 15, 106, 248, 176, 14, 15, 243, 110, 14, 15, 106, 243,
+ 110, 14, 15, 238, 66, 243, 110, 14, 15, 197, 14, 15, 55, 254, 26, 14, 15,
+ 254, 214, 14, 15, 253, 250, 14, 15, 246, 33, 14, 15, 253, 251, 14, 15,
+ 251, 196, 14, 15, 253, 216, 14, 15, 248, 226, 14, 15, 240, 44, 248, 226,
+ 14, 15, 253, 134, 14, 15, 249, 101, 14, 15, 249, 106, 14, 15, 106, 249,
+ 106, 14, 15, 249, 107, 14, 15, 106, 249, 107, 14, 15, 243, 220, 14, 15,
+ 106, 243, 220, 14, 15, 249, 108, 14, 15, 106, 249, 108, 14, 15, 243, 221,
+ 14, 15, 106, 243, 221, 14, 15, 248, 227, 14, 15, 106, 248, 227, 14, 15,
+ 243, 219, 14, 15, 106, 243, 219, 14, 15, 162, 14, 15, 106, 162, 14, 15,
+ 113, 162, 14, 15, 253, 210, 14, 15, 247, 60, 14, 15, 253, 198, 14, 15,
+ 252, 177, 14, 15, 253, 186, 14, 15, 249, 166, 14, 15, 240, 44, 249, 166,
+ 14, 15, 253, 132, 14, 15, 249, 158, 14, 15, 249, 169, 14, 15, 106, 249,
+ 169, 14, 15, 249, 170, 14, 15, 106, 249, 170, 14, 15, 244, 26, 14, 15,
+ 106, 244, 26, 14, 15, 249, 171, 14, 15, 106, 249, 171, 14, 15, 244, 27,
+ 14, 15, 106, 244, 27, 14, 15, 248, 252, 14, 15, 106, 248, 252, 14, 15,
+ 243, 125, 14, 15, 106, 243, 125, 14, 15, 238, 66, 243, 125, 14, 15, 193,
+ 14, 15, 234, 47, 193, 14, 15, 254, 128, 14, 15, 235, 57, 193, 14, 15,
+ 234, 225, 254, 238, 14, 15, 238, 66, 252, 181, 14, 15, 238, 66, 252, 164,
+ 14, 15, 238, 66, 247, 98, 14, 15, 238, 66, 247, 124, 14, 15, 238, 66,
+ 247, 93, 14, 15, 238, 66, 247, 66, 14, 15, 248, 118, 14, 15, 248, 185,
+ 14, 15, 247, 73, 14, 15, 248, 110, 14, 15, 247, 76, 14, 15, 248, 46, 14,
+ 15, 244, 7, 14, 15, 244, 16, 14, 15, 106, 244, 16, 14, 15, 244, 17, 14,
+ 15, 106, 244, 17, 14, 15, 240, 230, 14, 15, 106, 240, 230, 14, 15, 244,
+ 18, 14, 15, 106, 244, 18, 14, 15, 240, 231, 14, 15, 106, 240, 231, 14,
+ 15, 243, 121, 14, 15, 106, 243, 121, 14, 15, 240, 229, 14, 15, 106, 240,
+ 229, 14, 15, 254, 72, 14, 15, 253, 254, 14, 15, 247, 212, 14, 15, 253,
+ 189, 14, 15, 253, 81, 14, 15, 253, 162, 14, 15, 249, 210, 14, 15, 240,
+ 44, 249, 210, 14, 15, 216, 14, 15, 248, 191, 14, 15, 249, 213, 14, 15,
+ 106, 249, 213, 14, 15, 249, 214, 14, 15, 106, 249, 214, 14, 15, 244, 61,
+ 14, 15, 106, 244, 61, 14, 15, 249, 215, 14, 15, 106, 249, 215, 14, 15,
+ 244, 62, 14, 15, 106, 244, 62, 14, 15, 249, 212, 14, 15, 106, 249, 212,
+ 14, 15, 243, 137, 14, 15, 106, 243, 137, 14, 15, 238, 66, 243, 137, 14,
+ 15, 255, 14, 14, 15, 234, 98, 255, 14, 14, 15, 106, 255, 14, 14, 15, 240,
+ 36, 253, 189, 14, 15, 253, 194, 14, 15, 242, 74, 253, 194, 14, 15, 106,
+ 253, 250, 14, 15, 247, 26, 14, 15, 253, 209, 14, 15, 252, 137, 14, 15,
+ 253, 160, 14, 15, 252, 143, 14, 15, 106, 253, 216, 14, 15, 253, 130, 14,
+ 15, 248, 182, 14, 15, 106, 253, 134, 14, 15, 244, 2, 14, 15, 106, 244, 2,
+ 14, 15, 144, 14, 15, 106, 144, 14, 15, 113, 144, 14, 15, 254, 62, 14, 15,
+ 245, 88, 14, 15, 253, 245, 14, 15, 250, 243, 14, 15, 254, 63, 14, 15,
+ 250, 249, 14, 15, 253, 179, 14, 15, 249, 60, 14, 15, 243, 177, 14, 15,
+ 106, 243, 177, 14, 15, 255, 19, 14, 15, 248, 111, 14, 15, 240, 141, 248,
+ 111, 14, 15, 248, 121, 14, 15, 240, 141, 248, 121, 14, 15, 243, 128, 14,
+ 15, 240, 141, 243, 128, 14, 15, 248, 97, 14, 15, 244, 30, 14, 15, 248,
+ 55, 14, 15, 243, 76, 14, 15, 240, 244, 14, 15, 106, 240, 244, 14, 15,
+ 254, 46, 14, 15, 247, 166, 14, 15, 247, 167, 14, 15, 243, 131, 14, 15,
+ 242, 247, 14, 15, 252, 231, 14, 15, 252, 239, 14, 15, 252, 240, 14, 15,
+ 252, 241, 14, 15, 252, 238, 14, 15, 238, 86, 253, 168, 14, 15, 238, 86,
+ 253, 214, 14, 15, 238, 86, 251, 61, 14, 15, 238, 86, 253, 184, 14, 15,
+ 238, 86, 251, 78, 14, 15, 238, 86, 219, 14, 15, 238, 86, 248, 114, 14,
+ 15, 238, 86, 192, 14, 15, 239, 148, 192, 14, 15, 254, 172, 14, 15, 247,
+ 5, 14, 15, 254, 28, 14, 15, 249, 147, 14, 15, 254, 45, 14, 15, 252, 100,
+ 14, 15, 253, 217, 14, 15, 248, 241, 14, 15, 255, 20, 14, 15, 244, 34, 14,
+ 15, 244, 35, 14, 15, 244, 36, 14, 15, 244, 33, 14, 15, 106, 253, 194, 14,
+ 15, 106, 253, 209, 14, 15, 106, 253, 160, 14, 15, 106, 253, 130, 14, 15,
+ 242, 5, 14, 15, 248, 232, 14, 15, 246, 147, 14, 15, 248, 172, 14, 15,
+ 246, 149, 14, 15, 248, 50, 14, 15, 246, 139, 14, 15, 254, 26, 14, 15,
+ 252, 30, 14, 15, 240, 36, 248, 118, 14, 15, 240, 36, 248, 185, 14, 15,
+ 240, 36, 248, 110, 14, 15, 240, 36, 248, 46, 14, 15, 234, 24, 248, 111,
+ 14, 15, 234, 24, 248, 121, 14, 15, 234, 24, 248, 97, 14, 15, 234, 24,
+ 248, 55, 14, 15, 234, 24, 254, 46, 14, 15, 249, 103, 14, 15, 246, 46, 14,
+ 15, 249, 104, 14, 15, 246, 47, 14, 15, 248, 225, 14, 15, 246, 44, 14, 15,
+ 254, 193, 14, 15, 238, 88, 248, 111, 14, 15, 238, 88, 248, 121, 14, 15,
+ 238, 88, 243, 128, 14, 15, 238, 88, 248, 97, 14, 15, 238, 88, 244, 30,
+ 14, 15, 238, 88, 248, 55, 14, 15, 238, 88, 243, 76, 14, 15, 238, 88, 254,
+ 46, 14, 15, 238, 241, 217, 14, 15, 235, 57, 72, 14, 15, 235, 57, 71, 14,
+ 15, 235, 57, 73, 14, 15, 235, 57, 67, 14, 15, 235, 57, 253, 170, 14, 15,
+ 235, 57, 253, 187, 14, 15, 235, 57, 253, 177, 14, 15, 235, 57, 253, 138,
+ 14, 15, 235, 57, 253, 197, 14, 15, 235, 57, 253, 166, 14, 15, 235, 57,
+ 253, 173, 14, 15, 235, 57, 253, 131, 14, 15, 235, 57, 253, 172, 14, 15,
+ 235, 57, 253, 215, 14, 15, 235, 57, 253, 190, 14, 15, 235, 57, 201, 14,
+ 15, 240, 36, 253, 168, 14, 15, 240, 36, 253, 214, 14, 15, 240, 36, 253,
+ 184, 14, 15, 240, 36, 219, 14, 15, 55, 251, 19, 14, 15, 55, 249, 75, 14,
+ 15, 55, 248, 127, 14, 15, 55, 245, 119, 14, 15, 55, 251, 18, 14, 15, 55,
+ 248, 77, 14, 15, 55, 253, 185, 14, 15, 55, 253, 160, 14, 15, 55, 253,
+ 194, 14, 15, 55, 249, 153, 14, 15, 55, 253, 209, 14, 15, 55, 253, 130,
+ 14, 15, 55, 254, 14, 14, 15, 55, 253, 177, 14, 15, 55, 253, 170, 14, 15,
+ 55, 249, 199, 14, 15, 55, 253, 187, 14, 15, 55, 253, 138, 14, 15, 55,
+ 251, 88, 14, 15, 55, 251, 87, 14, 15, 55, 251, 85, 14, 15, 55, 245, 208,
+ 14, 15, 55, 251, 86, 14, 15, 55, 251, 84, 14, 15, 55, 249, 177, 14, 15,
+ 55, 248, 97, 14, 15, 55, 248, 111, 14, 15, 55, 243, 77, 14, 15, 55, 248,
+ 121, 14, 15, 55, 248, 55, 14, 15, 55, 252, 232, 14, 15, 55, 249, 6, 14,
+ 15, 55, 249, 186, 14, 15, 55, 247, 164, 14, 15, 55, 249, 187, 14, 15, 55,
+ 248, 71, 14, 15, 55, 253, 239, 14, 15, 55, 253, 208, 14, 15, 55, 253,
+ 175, 14, 15, 55, 248, 180, 14, 15, 55, 253, 147, 14, 15, 55, 253, 129,
+ 14, 15, 55, 223, 14, 15, 55, 253, 235, 14, 15, 55, 253, 234, 14, 15, 55,
+ 254, 5, 14, 15, 55, 249, 68, 14, 15, 55, 254, 6, 14, 15, 55, 253, 139,
+ 14, 15, 55, 251, 146, 14, 15, 55, 248, 220, 14, 15, 55, 249, 94, 14, 15,
+ 55, 246, 11, 14, 15, 55, 248, 219, 14, 15, 55, 248, 61, 14, 15, 55, 251,
+ 156, 14, 15, 55, 251, 155, 14, 15, 55, 251, 153, 14, 15, 55, 246, 17, 14,
+ 15, 55, 251, 154, 14, 15, 55, 249, 97, 14, 15, 55, 254, 107, 14, 15, 55,
+ 253, 150, 14, 15, 55, 253, 173, 14, 15, 55, 253, 197, 14, 15, 55, 249,
+ 118, 14, 15, 55, 253, 166, 14, 15, 55, 253, 131, 14, 15, 55, 253, 154,
+ 14, 15, 55, 253, 181, 14, 15, 55, 253, 206, 14, 15, 55, 249, 111, 14, 15,
+ 55, 253, 180, 14, 15, 55, 222, 14, 15, 55, 253, 161, 14, 15, 55, 253,
+ 162, 14, 15, 55, 253, 254, 14, 15, 55, 248, 192, 14, 15, 55, 253, 189,
+ 14, 15, 55, 216, 14, 15, 55, 254, 25, 14, 15, 240, 36, 254, 25, 14, 15,
+ 55, 253, 248, 14, 15, 55, 254, 24, 14, 15, 55, 248, 161, 14, 15, 55, 254,
+ 7, 14, 15, 240, 36, 254, 7, 14, 15, 55, 253, 146, 14, 15, 55, 249, 88,
+ 14, 15, 55, 249, 87, 14, 15, 55, 251, 121, 14, 15, 55, 245, 238, 14, 15,
+ 55, 249, 86, 14, 15, 55, 251, 120, 14, 15, 55, 254, 8, 14, 15, 55, 253,
+ 216, 14, 15, 55, 253, 250, 14, 15, 55, 249, 102, 14, 15, 55, 253, 251,
+ 14, 15, 55, 253, 134, 14, 15, 55, 250, 201, 14, 15, 55, 250, 200, 14, 15,
+ 55, 250, 198, 14, 15, 55, 245, 70, 14, 15, 55, 250, 199, 14, 15, 55, 249,
+ 55, 14, 15, 55, 251, 194, 14, 15, 55, 249, 104, 14, 15, 55, 251, 193, 14,
+ 15, 55, 246, 45, 14, 15, 55, 249, 103, 14, 15, 55, 248, 225, 14, 15, 55,
+ 247, 155, 14, 15, 55, 244, 36, 14, 15, 55, 244, 34, 14, 15, 55, 242, 155,
+ 14, 15, 55, 244, 35, 14, 15, 55, 244, 33, 14, 15, 55, 249, 183, 14, 15,
+ 55, 249, 182, 14, 15, 55, 249, 180, 14, 15, 55, 247, 154, 14, 15, 55,
+ 249, 181, 14, 15, 55, 249, 179, 14, 15, 55, 254, 18, 14, 15, 55, 253,
+ 222, 14, 15, 55, 253, 228, 14, 15, 55, 248, 194, 14, 15, 55, 254, 17, 14,
+ 15, 55, 253, 163, 14, 15, 55, 255, 17, 14, 15, 55, 54, 255, 17, 14, 15,
+ 55, 250, 220, 14, 15, 55, 250, 219, 14, 15, 55, 248, 126, 14, 15, 55,
+ 245, 78, 14, 15, 55, 250, 218, 14, 15, 55, 248, 153, 14, 15, 55, 253,
+ 211, 14, 15, 55, 253, 186, 14, 15, 55, 253, 210, 14, 15, 55, 248, 184,
+ 14, 15, 55, 253, 198, 14, 15, 55, 253, 132, 14, 15, 55, 248, 248, 14, 15,
+ 55, 248, 110, 14, 15, 55, 248, 118, 14, 15, 55, 244, 9, 14, 15, 55, 248,
+ 185, 14, 15, 55, 248, 46, 14, 15, 55, 254, 72, 14, 15, 55, 249, 5, 14,
+ 15, 55, 249, 4, 14, 15, 55, 248, 112, 14, 15, 55, 244, 39, 14, 15, 55,
+ 248, 140, 14, 15, 55, 248, 90, 14, 15, 55, 248, 200, 14, 15, 55, 248,
+ 125, 14, 15, 55, 248, 88, 14, 15, 55, 243, 54, 14, 15, 55, 248, 67, 14,
+ 15, 55, 248, 57, 14, 15, 55, 247, 172, 14, 15, 55, 247, 171, 14, 15, 55,
+ 247, 169, 14, 15, 55, 242, 160, 14, 15, 55, 247, 170, 14, 15, 55, 247,
+ 168, 14, 15, 254, 83, 52, 14, 15, 248, 37, 208, 14, 15, 249, 146, 14, 15,
+ 246, 140, 14, 15, 246, 173, 14, 15, 242, 20, 14, 15, 246, 174, 14, 15,
+ 242, 21, 14, 15, 246, 172, 14, 15, 242, 19, 242, 221, 247, 96, 69, 242,
+ 221, 1, 241, 29, 242, 221, 1, 246, 55, 242, 221, 1, 241, 104, 242, 221,
+ 1, 247, 62, 242, 221, 1, 246, 156, 242, 221, 1, 247, 182, 242, 221, 1,
+ 245, 33, 242, 221, 1, 242, 153, 242, 221, 1, 245, 26, 242, 221, 1, 241,
+ 48, 242, 221, 1, 246, 94, 242, 221, 1, 245, 126, 242, 221, 1, 237, 220,
+ 242, 221, 1, 239, 205, 242, 221, 1, 247, 52, 242, 221, 1, 244, 72, 242,
+ 221, 1, 249, 130, 242, 221, 1, 254, 253, 242, 221, 1, 237, 144, 242, 221,
+ 1, 237, 182, 242, 221, 1, 237, 143, 242, 221, 1, 253, 227, 242, 221, 1,
+ 236, 134, 242, 221, 1, 245, 225, 242, 221, 1, 232, 163, 242, 221, 1, 242,
+ 54, 242, 221, 238, 184, 69, 242, 221, 224, 238, 184, 69, 119, 1, 250,
+ 238, 250, 240, 255, 74, 255, 19, 119, 1, 179, 119, 1, 253, 4, 255, 95,
+ 79, 119, 1, 254, 135, 119, 1, 255, 14, 119, 1, 255, 16, 119, 1, 238, 28,
+ 247, 146, 240, 149, 119, 1, 248, 109, 119, 1, 244, 82, 67, 119, 1, 255,
+ 86, 73, 119, 1, 255, 67, 67, 119, 1, 244, 69, 119, 1, 231, 23, 73, 119,
+ 1, 231, 77, 73, 119, 1, 73, 119, 1, 253, 193, 119, 1, 254, 9, 119, 1,
+ 247, 27, 254, 71, 252, 132, 144, 119, 1, 241, 195, 119, 1, 250, 155, 119,
+ 1, 251, 139, 255, 15, 119, 1, 210, 119, 1, 248, 108, 119, 1, 251, 13,
+ 251, 41, 210, 119, 1, 251, 9, 119, 1, 247, 198, 253, 40, 255, 16, 119, 1,
+ 241, 145, 192, 119, 1, 245, 138, 192, 119, 1, 226, 249, 192, 119, 1, 227,
+ 6, 192, 119, 1, 241, 253, 254, 218, 252, 0, 197, 119, 1, 231, 29, 197,
+ 119, 1, 236, 7, 119, 1, 251, 108, 255, 77, 254, 178, 71, 119, 1, 72, 119,
+ 1, 245, 234, 221, 119, 1, 251, 14, 119, 1, 231, 72, 253, 178, 119, 1,
+ 232, 54, 67, 119, 1, 251, 109, 250, 226, 119, 1, 242, 57, 242, 56, 223,
+ 119, 1, 244, 76, 241, 97, 119, 1, 242, 122, 193, 119, 1, 247, 89, 231,
+ 24, 193, 119, 1, 231, 78, 193, 119, 1, 255, 18, 119, 1, 255, 17, 119, 1,
+ 247, 153, 254, 249, 254, 251, 214, 119, 1, 231, 79, 214, 119, 1, 209,
+ 119, 1, 237, 76, 244, 218, 239, 10, 217, 119, 1, 226, 252, 217, 119, 1,
+ 236, 8, 119, 1, 239, 152, 119, 1, 245, 80, 255, 72, 72, 119, 1, 241, 227,
+ 254, 111, 173, 119, 1, 229, 49, 173, 119, 1, 231, 28, 173, 119, 1, 241,
+ 213, 251, 181, 251, 204, 162, 119, 1, 236, 6, 119, 1, 239, 98, 119, 1,
+ 251, 104, 119, 1, 245, 31, 250, 179, 209, 119, 1, 239, 155, 245, 85, 73,
+ 119, 1, 248, 206, 119, 1, 251, 106, 119, 1, 237, 98, 119, 1, 244, 240,
+ 119, 1, 241, 47, 119, 1, 247, 120, 119, 1, 231, 25, 119, 1, 231, 80, 119,
+ 1, 231, 141, 119, 1, 255, 20, 119, 1, 206, 119, 240, 12, 232, 75, 119,
+ 237, 215, 232, 75, 119, 243, 38, 232, 75, 119, 241, 16, 91, 119, 238, 34,
+ 91, 119, 237, 75, 91, 238, 63, 1, 67, 238, 63, 1, 71, 238, 63, 1, 79,
+ 238, 63, 1, 201, 238, 63, 1, 253, 139, 238, 63, 1, 248, 50, 238, 63, 1,
+ 253, 126, 238, 63, 1, 253, 133, 238, 63, 1, 253, 131, 238, 63, 1, 253,
+ 129, 238, 63, 1, 253, 141, 238, 63, 1, 222, 238, 63, 1, 216, 238, 63, 1,
+ 253, 134, 238, 63, 1, 253, 138, 238, 63, 1, 253, 132, 238, 63, 1, 219,
+ 238, 63, 33, 21, 71, 238, 63, 33, 21, 79, 238, 63, 21, 238, 72, 238, 60,
+ 1, 67, 238, 60, 1, 71, 238, 60, 1, 79, 238, 60, 1, 201, 238, 60, 1, 253,
+ 139, 238, 60, 1, 248, 50, 238, 60, 1, 253, 126, 238, 60, 1, 253, 133,
+ 238, 60, 1, 253, 131, 238, 60, 1, 253, 129, 238, 60, 1, 253, 141, 238,
+ 60, 1, 222, 238, 60, 1, 216, 238, 60, 1, 253, 130, 238, 60, 1, 253, 134,
+ 238, 60, 1, 253, 138, 238, 60, 1, 253, 132, 238, 60, 1, 219, 238, 60, 33,
+ 21, 71, 238, 60, 33, 21, 79, 238, 60, 21, 236, 70, 234, 63, 240, 12, 232,
+ 75, 234, 63, 45, 232, 75, 242, 231, 1, 67, 242, 231, 1, 71, 242, 231, 1,
+ 79, 242, 231, 1, 201, 242, 231, 1, 253, 139, 242, 231, 1, 248, 50, 242,
+ 231, 1, 253, 126, 242, 231, 1, 253, 133, 242, 231, 1, 253, 131, 242, 231,
+ 1, 253, 129, 242, 231, 1, 253, 141, 242, 231, 1, 222, 242, 231, 1, 216,
+ 242, 231, 1, 253, 130, 242, 231, 1, 253, 134, 242, 231, 1, 253, 138, 242,
+ 231, 1, 253, 132, 242, 231, 1, 219, 242, 231, 33, 21, 71, 242, 231, 33,
+ 21, 79, 236, 157, 1, 67, 236, 157, 1, 71, 236, 157, 1, 79, 236, 157, 1,
+ 201, 236, 157, 1, 253, 139, 236, 157, 1, 248, 50, 236, 157, 1, 253, 126,
+ 236, 157, 1, 253, 133, 236, 157, 1, 253, 131, 236, 157, 1, 253, 129, 236,
+ 157, 1, 253, 141, 236, 157, 1, 222, 236, 157, 1, 216, 236, 157, 1, 253,
+ 134, 236, 157, 1, 253, 138, 236, 157, 1, 253, 132, 236, 157, 33, 21, 71,
+ 236, 157, 33, 21, 79, 63, 1, 201, 63, 1, 248, 61, 63, 1, 253, 190, 63, 1,
+ 248, 220, 63, 1, 248, 172, 63, 1, 253, 152, 63, 1, 248, 57, 63, 1, 253,
+ 224, 63, 1, 248, 125, 63, 1, 248, 133, 63, 1, 253, 133, 63, 1, 242, 247,
+ 63, 1, 253, 225, 63, 1, 243, 131, 63, 1, 252, 31, 63, 1, 253, 126, 63, 1,
+ 248, 55, 63, 1, 87, 63, 1, 248, 97, 63, 1, 253, 173, 63, 1, 253, 141, 63,
+ 1, 248, 65, 63, 1, 253, 208, 63, 1, 248, 238, 63, 1, 253, 181, 63, 1,
+ 253, 162, 63, 1, 253, 160, 63, 1, 253, 216, 63, 1, 254, 13, 63, 1, 248,
+ 46, 63, 1, 248, 250, 63, 1, 253, 132, 63, 1, 219, 63, 1, 253, 134, 63, 1,
+ 253, 217, 63, 233, 52, 33, 252, 86, 63, 233, 52, 33, 248, 241, 63, 233,
+ 52, 33, 254, 28, 63, 233, 52, 33, 249, 147, 63, 233, 52, 33, 254, 29, 63,
+ 233, 52, 33, 252, 106, 63, 233, 52, 33, 249, 150, 63, 233, 52, 33, 247,
+ 20, 63, 233, 52, 33, 254, 125, 63, 233, 52, 33, 252, 163, 63, 233, 52,
+ 33, 254, 110, 63, 233, 52, 33, 251, 217, 63, 233, 52, 33, 254, 70, 63,
+ 233, 52, 33, 249, 146, 63, 233, 52, 33, 254, 123, 249, 9, 127, 63, 233,
+ 52, 33, 254, 123, 249, 9, 111, 63, 233, 52, 33, 252, 87, 63, 33, 237, 13,
+ 254, 142, 63, 33, 237, 13, 253, 140, 63, 33, 21, 253, 140, 63, 33, 21,
+ 71, 63, 33, 21, 253, 142, 63, 33, 21, 255, 14, 63, 33, 21, 254, 77, 63,
+ 33, 21, 79, 63, 33, 21, 253, 148, 63, 33, 21, 254, 74, 63, 33, 21, 253,
+ 193, 63, 33, 21, 216, 63, 33, 21, 253, 237, 63, 33, 21, 72, 63, 33, 21,
+ 253, 178, 63, 33, 21, 253, 149, 63, 33, 21, 253, 156, 63, 33, 21, 253,
+ 151, 63, 21, 237, 221, 63, 21, 237, 248, 63, 21, 231, 84, 63, 21, 232,
+ 184, 63, 21, 238, 32, 63, 21, 239, 3, 63, 21, 242, 86, 63, 21, 233, 43,
+ 63, 21, 237, 186, 63, 21, 241, 7, 63, 21, 242, 96, 239, 179, 63, 21, 239,
+ 243, 63, 21, 241, 62, 63, 21, 233, 121, 63, 21, 246, 10, 63, 21, 233,
+ 120, 63, 21, 241, 42, 254, 69, 246, 24, 63, 21, 253, 204, 249, 2, 63, 21,
+ 239, 8, 63, 21, 242, 59, 246, 93, 63, 21, 237, 191, 63, 236, 181, 12,
+ 247, 31, 63, 21, 231, 59, 63, 21, 235, 176, 63, 26, 242, 217, 63, 26,
+ 127, 63, 26, 111, 63, 26, 166, 63, 26, 177, 63, 26, 176, 63, 26, 187, 63,
+ 26, 203, 63, 26, 195, 63, 26, 202, 63, 12, 253, 204, 243, 4, 252, 184,
+ 63, 12, 253, 204, 243, 4, 246, 99, 63, 12, 253, 204, 243, 4, 249, 138,
+ 63, 12, 253, 204, 243, 4, 250, 113, 63, 12, 253, 204, 243, 4, 244, 233,
+ 63, 12, 253, 204, 243, 4, 246, 253, 63, 12, 253, 204, 243, 4, 234, 239,
+ 63, 12, 253, 204, 243, 4, 236, 79, 63, 12, 253, 204, 243, 4, 236, 78, 63,
+ 12, 253, 204, 243, 4, 234, 238, 58, 241, 31, 58, 235, 69, 58, 240, 27,
+ 58, 248, 37, 208, 58, 240, 24, 58, 248, 58, 243, 5, 58, 248, 47, 248,
+ 186, 238, 93, 58, 248, 54, 4, 237, 78, 238, 95, 58, 240, 14, 240, 27, 58,
+ 240, 14, 248, 37, 208, 58, 239, 144, 58, 248, 210, 34, 236, 239, 127, 58,
+ 248, 210, 34, 236, 239, 111, 58, 248, 210, 34, 236, 239, 166, 58, 33,
+ 234, 6, 58, 26, 242, 217, 58, 26, 127, 58, 26, 111, 58, 26, 166, 58, 26,
+ 177, 58, 26, 176, 58, 26, 187, 58, 26, 203, 58, 26, 195, 58, 26, 202, 58,
+ 1, 67, 58, 1, 72, 58, 1, 71, 58, 1, 73, 58, 1, 79, 58, 1, 253, 193, 58,
+ 1, 253, 252, 58, 1, 253, 164, 58, 1, 253, 131, 58, 1, 248, 124, 58, 1,
+ 253, 141, 58, 1, 253, 129, 58, 1, 253, 217, 58, 1, 253, 139, 58, 1, 222,
+ 58, 1, 253, 134, 58, 1, 253, 132, 58, 1, 248, 46, 58, 1, 253, 126, 58, 1,
+ 253, 133, 58, 1, 248, 57, 58, 1, 253, 146, 58, 1, 216, 58, 1, 253, 130,
+ 58, 1, 253, 138, 58, 1, 253, 179, 58, 1, 201, 58, 1, 248, 61, 58, 1, 248,
+ 90, 58, 1, 253, 163, 58, 1, 248, 114, 58, 1, 253, 113, 58, 1, 248, 225,
+ 58, 1, 249, 217, 58, 1, 248, 67, 58, 1, 248, 47, 183, 33, 52, 58, 1, 248,
+ 47, 72, 58, 1, 248, 47, 71, 58, 1, 248, 47, 73, 58, 1, 248, 47, 79, 58,
+ 1, 248, 47, 253, 193, 58, 1, 248, 47, 253, 252, 58, 1, 248, 47, 248, 124,
+ 58, 1, 248, 47, 253, 141, 58, 1, 248, 47, 253, 129, 58, 1, 248, 47, 253,
+ 217, 58, 1, 248, 47, 253, 139, 58, 1, 248, 47, 222, 58, 1, 248, 47, 253,
+ 126, 58, 1, 248, 47, 253, 133, 58, 1, 248, 47, 248, 57, 58, 1, 248, 47,
+ 253, 146, 58, 1, 248, 47, 248, 90, 58, 1, 248, 47, 216, 58, 1, 248, 47,
+ 253, 138, 58, 1, 248, 47, 201, 58, 1, 248, 47, 248, 211, 58, 1, 248, 47,
+ 248, 114, 58, 1, 248, 47, 251, 115, 58, 1, 248, 47, 252, 20, 58, 1, 248,
+ 47, 248, 153, 58, 1, 248, 54, 72, 58, 1, 248, 54, 71, 58, 1, 248, 54,
+ 254, 102, 58, 1, 248, 54, 253, 252, 58, 1, 248, 54, 79, 58, 1, 248, 54,
+ 248, 124, 58, 1, 248, 54, 201, 58, 1, 248, 54, 253, 139, 58, 1, 248, 54,
+ 219, 58, 1, 248, 54, 253, 129, 58, 1, 248, 54, 248, 46, 58, 1, 248, 54,
+ 253, 126, 58, 1, 248, 54, 253, 133, 58, 1, 248, 54, 253, 146, 58, 1, 248,
+ 54, 253, 179, 58, 1, 248, 54, 248, 211, 58, 1, 248, 54, 248, 114, 58, 1,
+ 248, 54, 248, 90, 58, 1, 248, 54, 253, 163, 58, 1, 248, 54, 248, 182, 58,
+ 1, 248, 54, 248, 57, 58, 1, 248, 54, 248, 99, 58, 1, 240, 14, 71, 58, 1,
+ 240, 14, 201, 58, 1, 240, 14, 253, 130, 58, 1, 240, 14, 253, 179, 58, 1,
+ 240, 14, 248, 99, 58, 1, 253, 128, 248, 36, 237, 62, 127, 58, 1, 253,
+ 128, 248, 36, 239, 244, 127, 58, 1, 253, 128, 248, 36, 239, 36, 58, 1,
+ 253, 128, 248, 36, 237, 50, 58, 1, 253, 128, 248, 36, 236, 145, 237, 50,
+ 58, 1, 253, 128, 248, 36, 238, 163, 58, 1, 253, 128, 248, 36, 204, 238,
+ 163, 58, 1, 253, 128, 248, 36, 67, 58, 1, 253, 128, 248, 36, 71, 58, 1,
+ 253, 128, 248, 36, 201, 58, 1, 253, 128, 248, 36, 248, 50, 58, 1, 253,
+ 128, 248, 36, 253, 152, 58, 1, 253, 128, 248, 36, 248, 71, 58, 1, 253,
+ 128, 248, 36, 242, 247, 58, 1, 253, 128, 248, 36, 248, 75, 58, 1, 253,
+ 128, 248, 36, 248, 82, 58, 1, 253, 128, 248, 36, 253, 126, 58, 1, 253,
+ 128, 248, 36, 253, 133, 58, 1, 253, 128, 248, 36, 253, 129, 58, 1, 253,
+ 128, 248, 36, 248, 65, 58, 1, 253, 128, 248, 36, 248, 66, 58, 1, 253,
+ 128, 248, 36, 248, 99, 58, 1, 253, 128, 248, 36, 253, 163, 58, 1, 253,
+ 128, 248, 36, 254, 0, 58, 1, 248, 47, 253, 128, 248, 36, 253, 126, 58, 1,
+ 248, 47, 253, 128, 248, 36, 248, 99, 58, 1, 240, 14, 253, 128, 248, 36,
+ 248, 77, 58, 1, 240, 14, 253, 128, 248, 36, 248, 50, 58, 1, 240, 14, 253,
+ 128, 248, 36, 253, 152, 58, 1, 240, 14, 253, 128, 248, 36, 248, 89, 58,
+ 1, 240, 14, 253, 128, 248, 36, 248, 71, 58, 1, 240, 14, 253, 128, 248,
+ 36, 242, 249, 58, 1, 240, 14, 253, 128, 248, 36, 253, 126, 58, 1, 240,
+ 14, 253, 128, 248, 36, 248, 76, 58, 1, 240, 14, 253, 128, 248, 36, 248,
+ 66, 58, 1, 240, 14, 253, 128, 248, 36, 250, 174, 58, 1, 240, 14, 253,
+ 128, 248, 36, 248, 99, 58, 1, 240, 14, 253, 128, 248, 36, 253, 163, 58,
+ 1, 253, 128, 248, 36, 137, 79, 58, 1, 253, 128, 248, 36, 137, 216, 58, 1,
+ 240, 14, 253, 128, 248, 36, 248, 81, 58, 1, 253, 128, 248, 36, 237, 101,
+ 149, 232, 65, 239, 117, 149, 1, 201, 149, 1, 248, 61, 149, 1, 253, 139,
+ 149, 1, 248, 77, 149, 1, 248, 50, 149, 1, 253, 152, 149, 1, 248, 57, 149,
+ 1, 253, 146, 149, 1, 248, 89, 149, 1, 249, 203, 149, 1, 253, 126, 149, 1,
+ 248, 55, 149, 1, 253, 133, 149, 1, 248, 76, 149, 1, 253, 131, 149, 1,
+ 253, 129, 149, 1, 248, 65, 149, 1, 253, 141, 149, 1, 248, 81, 149, 1,
+ 222, 149, 1, 216, 149, 1, 253, 130, 149, 1, 253, 134, 149, 1, 253, 138,
+ 149, 1, 248, 46, 149, 1, 248, 66, 149, 1, 253, 132, 149, 1, 219, 149, 33,
+ 21, 67, 149, 33, 21, 71, 149, 33, 21, 79, 149, 33, 21, 253, 164, 149, 33,
+ 21, 253, 149, 149, 33, 21, 253, 156, 149, 33, 21, 253, 151, 149, 33, 21,
+ 72, 149, 33, 21, 73, 149, 213, 1, 216, 149, 213, 1, 253, 130, 149, 213,
+ 1, 253, 138, 149, 3, 1, 201, 149, 3, 1, 248, 50, 149, 3, 1, 235, 61, 149,
+ 3, 1, 253, 126, 149, 3, 1, 253, 131, 149, 3, 1, 253, 129, 149, 3, 1, 222,
+ 149, 3, 1, 253, 130, 149, 3, 1, 253, 134, 149, 21, 234, 226, 149, 21,
+ 234, 212, 149, 21, 247, 59, 149, 21, 248, 226, 149, 233, 54, 69, 149,
+ 236, 156, 69, 149, 26, 242, 217, 149, 26, 127, 149, 26, 111, 149, 26,
+ 166, 149, 26, 177, 149, 26, 176, 149, 26, 187, 149, 26, 203, 149, 26,
+ 195, 149, 26, 202, 81, 255, 21, 1, 201, 81, 255, 21, 1, 253, 253, 81,
+ 255, 21, 1, 248, 50, 81, 255, 21, 1, 248, 90, 81, 255, 21, 1, 253, 132,
+ 81, 255, 21, 1, 216, 81, 255, 21, 1, 253, 126, 81, 255, 21, 1, 248, 55,
+ 81, 255, 21, 1, 253, 134, 81, 255, 21, 1, 253, 129, 81, 255, 21, 1, 248,
+ 65, 81, 255, 21, 1, 222, 81, 255, 21, 1, 253, 179, 81, 255, 21, 1, 253,
+ 171, 81, 255, 21, 1, 219, 81, 255, 21, 1, 253, 217, 81, 255, 21, 1, 248,
+ 61, 81, 255, 21, 1, 243, 130, 81, 255, 21, 1, 253, 131, 81, 255, 21, 1,
+ 67, 81, 255, 21, 1, 71, 81, 255, 21, 1, 253, 164, 81, 255, 21, 1, 254,
+ 36, 81, 255, 21, 1, 79, 81, 255, 21, 1, 253, 156, 81, 255, 21, 1, 73, 81,
+ 255, 21, 1, 253, 252, 81, 255, 21, 1, 72, 81, 255, 21, 1, 249, 243, 81,
+ 255, 21, 1, 253, 149, 81, 255, 21, 1, 239, 223, 81, 255, 21, 1, 239, 224,
+ 81, 255, 21, 1, 239, 225, 81, 255, 21, 1, 239, 226, 81, 255, 21, 1, 239,
+ 227, 116, 81, 122, 1, 200, 253, 217, 116, 81, 122, 1, 170, 253, 217, 116,
+ 81, 122, 1, 200, 201, 116, 81, 122, 1, 200, 253, 253, 116, 81, 122, 1,
+ 200, 248, 50, 116, 81, 122, 1, 170, 201, 116, 81, 122, 1, 170, 253, 253,
+ 116, 81, 122, 1, 170, 248, 50, 116, 81, 122, 1, 200, 248, 90, 116, 81,
+ 122, 1, 200, 253, 132, 116, 81, 122, 1, 200, 216, 116, 81, 122, 1, 170,
+ 248, 90, 116, 81, 122, 1, 170, 253, 132, 116, 81, 122, 1, 170, 216, 116,
+ 81, 122, 1, 200, 253, 126, 116, 81, 122, 1, 200, 248, 55, 116, 81, 122,
+ 1, 200, 253, 131, 116, 81, 122, 1, 170, 253, 126, 116, 81, 122, 1, 170,
+ 248, 55, 116, 81, 122, 1, 170, 253, 131, 116, 81, 122, 1, 200, 253, 129,
+ 116, 81, 122, 1, 200, 248, 65, 116, 81, 122, 1, 200, 222, 116, 81, 122,
+ 1, 170, 253, 129, 116, 81, 122, 1, 170, 248, 65, 116, 81, 122, 1, 170,
+ 222, 116, 81, 122, 1, 200, 253, 179, 116, 81, 122, 1, 200, 253, 171, 116,
+ 81, 122, 1, 200, 253, 134, 116, 81, 122, 1, 170, 253, 179, 116, 81, 122,
+ 1, 170, 253, 171, 116, 81, 122, 1, 170, 253, 134, 116, 81, 122, 1, 200,
+ 219, 116, 81, 122, 1, 200, 253, 133, 116, 81, 122, 1, 200, 253, 141, 116,
+ 81, 122, 1, 170, 219, 116, 81, 122, 1, 170, 253, 133, 116, 81, 122, 1,
+ 170, 253, 141, 116, 81, 122, 1, 200, 249, 99, 116, 81, 122, 1, 200, 249,
+ 201, 116, 81, 122, 1, 170, 249, 99, 116, 81, 122, 1, 170, 249, 201, 116,
+ 81, 122, 33, 21, 33, 234, 255, 116, 81, 122, 33, 21, 253, 140, 116, 81,
+ 122, 33, 21, 253, 142, 116, 81, 122, 33, 21, 79, 116, 81, 122, 33, 21,
+ 253, 148, 116, 81, 122, 33, 21, 72, 116, 81, 122, 33, 21, 253, 178, 116,
+ 81, 122, 33, 21, 73, 116, 81, 122, 33, 21, 254, 117, 116, 81, 122, 33,
+ 21, 253, 252, 116, 81, 122, 33, 21, 254, 33, 116, 81, 122, 33, 21, 249,
+ 232, 116, 81, 122, 33, 21, 254, 254, 116, 81, 122, 33, 21, 254, 221, 116,
+ 81, 122, 33, 21, 252, 56, 116, 81, 122, 33, 21, 252, 250, 116, 81, 122,
+ 33, 21, 254, 102, 116, 81, 122, 1, 30, 179, 116, 81, 122, 1, 30, 254, 26,
+ 116, 81, 122, 1, 30, 197, 116, 81, 122, 1, 30, 173, 116, 81, 122, 1, 30,
+ 255, 15, 116, 81, 122, 1, 30, 209, 116, 81, 122, 1, 30, 217, 116, 81,
+ 122, 188, 238, 200, 116, 81, 122, 188, 238, 201, 116, 81, 122, 26, 242,
+ 217, 116, 81, 122, 26, 127, 116, 81, 122, 26, 111, 116, 81, 122, 26, 166,
+ 116, 81, 122, 26, 177, 116, 81, 122, 26, 176, 116, 81, 122, 26, 187, 116,
+ 81, 122, 26, 203, 116, 81, 122, 26, 195, 116, 81, 122, 26, 202, 116, 81,
+ 122, 21, 251, 180, 116, 81, 122, 21, 246, 36, 63, 12, 233, 223, 63, 12,
+ 249, 116, 242, 246, 63, 12, 254, 69, 242, 246, 63, 12, 254, 81, 242, 246,
+ 63, 12, 249, 34, 242, 246, 63, 12, 249, 141, 242, 246, 63, 12, 235, 137,
+ 242, 246, 63, 12, 237, 32, 242, 246, 63, 12, 237, 31, 242, 246, 63, 12,
+ 235, 136, 242, 246, 63, 12, 254, 86, 242, 246, 63, 12, 237, 3, 242, 246,
+ 63, 12, 238, 175, 242, 246, 63, 12, 238, 174, 242, 246, 63, 12, 237, 2,
+ 242, 246, 63, 12, 237, 4, 242, 246, 63, 12, 235, 38, 63, 12, 249, 116,
+ 248, 80, 63, 12, 254, 69, 248, 80, 63, 12, 254, 81, 248, 80, 63, 12, 249,
+ 34, 248, 80, 63, 12, 249, 141, 248, 80, 63, 12, 235, 137, 248, 80, 63,
+ 12, 237, 32, 248, 80, 63, 12, 237, 31, 248, 80, 63, 12, 235, 136, 248,
+ 80, 63, 12, 254, 86, 248, 80, 63, 12, 237, 3, 248, 80, 63, 12, 238, 175,
+ 248, 80, 63, 12, 238, 174, 248, 80, 63, 12, 237, 2, 248, 80, 63, 12, 237,
+ 4, 248, 80, 236, 148, 1, 201, 236, 148, 1, 253, 139, 236, 148, 1, 248,
+ 50, 236, 148, 1, 246, 148, 236, 148, 1, 253, 129, 236, 148, 1, 253, 141,
+ 236, 148, 1, 222, 236, 148, 1, 249, 115, 236, 148, 1, 253, 126, 236, 148,
+ 1, 253, 133, 236, 148, 1, 253, 131, 236, 148, 1, 249, 123, 236, 148, 1,
+ 253, 152, 236, 148, 1, 253, 146, 236, 148, 1, 248, 78, 236, 148, 1, 246,
+ 199, 236, 148, 1, 216, 236, 148, 1, 253, 130, 236, 148, 1, 253, 134, 236,
+ 148, 1, 253, 171, 236, 148, 1, 253, 132, 236, 148, 1, 67, 236, 148, 1,
+ 219, 236, 148, 33, 21, 71, 236, 148, 33, 21, 79, 236, 148, 33, 21, 72,
+ 236, 148, 33, 21, 73, 236, 148, 33, 21, 253, 178, 236, 148, 237, 231,
+ 236, 148, 253, 165, 147, 236, 210, 8, 1, 3, 5, 67, 8, 1, 3, 5, 253, 178,
+ 8, 3, 1, 205, 253, 178, 8, 1, 3, 5, 240, 60, 217, 8, 1, 3, 5, 255, 18, 8,
+ 1, 3, 5, 209, 8, 1, 3, 5, 248, 109, 8, 1, 3, 5, 72, 8, 3, 1, 205, 248,
+ 35, 72, 8, 3, 1, 205, 71, 8, 1, 3, 5, 221, 8, 1, 3, 5, 255, 15, 8, 1, 3,
+ 5, 255, 100, 2, 108, 8, 1, 3, 5, 173, 8, 1, 3, 5, 224, 197, 8, 1, 3, 5,
+ 73, 8, 1, 3, 5, 248, 35, 73, 8, 3, 1, 236, 190, 73, 8, 3, 1, 236, 190,
+ 248, 35, 73, 8, 3, 1, 236, 190, 117, 2, 108, 8, 3, 1, 205, 253, 193, 8,
+ 1, 3, 5, 254, 10, 8, 3, 1, 253, 159, 137, 73, 8, 3, 1, 240, 17, 137, 73,
+ 8, 1, 3, 5, 223, 8, 1, 3, 5, 224, 144, 8, 1, 3, 5, 205, 144, 8, 1, 3, 5,
+ 214, 8, 1, 3, 5, 79, 8, 3, 1, 236, 190, 79, 8, 3, 1, 236, 190, 233, 132,
+ 79, 8, 3, 1, 236, 190, 205, 173, 8, 1, 3, 5, 179, 8, 1, 3, 5, 255, 16, 8,
+ 1, 3, 5, 255, 17, 8, 1, 3, 5, 248, 155, 8, 1, 240, 59, 236, 49, 238, 10,
+ 8, 1, 248, 105, 17, 1, 3, 5, 240, 10, 17, 1, 3, 5, 240, 33, 17, 1, 3, 5,
+ 253, 147, 17, 1, 3, 5, 248, 73, 17, 1, 3, 5, 248, 69, 32, 1, 3, 5, 254,
+ 3, 49, 1, 5, 67, 49, 1, 5, 253, 178, 49, 1, 5, 217, 49, 1, 5, 240, 60,
+ 217, 49, 1, 5, 209, 49, 1, 5, 72, 49, 1, 5, 224, 72, 49, 1, 5, 210, 49,
+ 1, 5, 192, 49, 1, 5, 71, 49, 1, 5, 221, 49, 1, 5, 255, 15, 49, 1, 5, 162,
+ 49, 1, 5, 173, 49, 1, 5, 197, 49, 1, 5, 224, 197, 49, 1, 5, 73, 49, 1, 5,
+ 254, 10, 49, 1, 5, 223, 49, 1, 5, 144, 49, 1, 5, 214, 49, 1, 5, 79, 49,
+ 1, 5, 255, 16, 49, 1, 3, 67, 49, 1, 3, 205, 67, 49, 1, 3, 240, 22, 49, 1,
+ 3, 205, 253, 178, 49, 1, 3, 217, 49, 1, 3, 209, 49, 1, 3, 72, 49, 1, 3,
+ 240, 86, 49, 1, 3, 248, 35, 72, 49, 1, 3, 205, 248, 35, 72, 49, 1, 3,
+ 210, 49, 1, 3, 205, 71, 49, 1, 3, 255, 15, 49, 1, 3, 173, 49, 1, 3, 248,
+ 108, 49, 1, 3, 73, 49, 1, 3, 248, 35, 73, 49, 1, 3, 253, 159, 137, 73,
+ 49, 1, 3, 240, 17, 137, 73, 49, 1, 3, 223, 49, 1, 3, 214, 49, 1, 3, 79,
+ 49, 1, 3, 236, 190, 79, 49, 1, 3, 205, 173, 49, 1, 3, 179, 49, 1, 3, 248,
+ 105, 49, 1, 3, 242, 242, 49, 1, 3, 17, 240, 10, 49, 1, 3, 240, 28, 49, 1,
+ 3, 17, 248, 68, 49, 1, 3, 248, 67, 8, 235, 48, 3, 1, 71, 8, 235, 48, 3,
+ 1, 144, 8, 235, 48, 3, 1, 79, 8, 235, 48, 3, 1, 179, 17, 235, 48, 3, 1,
+ 242, 242, 17, 235, 48, 3, 1, 240, 10, 17, 235, 48, 3, 1, 248, 73, 17,
+ 235, 48, 3, 1, 248, 68, 17, 235, 48, 3, 1, 248, 67, 8, 3, 1, 253, 252, 8,
+ 3, 1, 41, 2, 240, 1, 169, 8, 3, 1, 255, 103, 2, 240, 1, 169, 8, 3, 1,
+ 255, 112, 2, 240, 1, 169, 8, 3, 1, 255, 108, 2, 240, 1, 169, 8, 3, 1,
+ 255, 98, 2, 240, 1, 169, 8, 3, 1, 255, 114, 2, 240, 1, 169, 8, 3, 1, 255,
+ 101, 2, 240, 1, 169, 8, 3, 1, 255, 101, 2, 237, 11, 19, 240, 1, 169, 8,
+ 3, 1, 255, 99, 2, 240, 1, 169, 8, 3, 1, 255, 102, 2, 240, 1, 169, 8, 3,
+ 1, 255, 97, 2, 240, 1, 169, 8, 3, 1, 205, 210, 49, 1, 32, 253, 202, 8, 3,
+ 1, 239, 101, 210, 8, 3, 1, 255, 93, 2, 231, 82, 8, 3, 5, 1, 220, 2, 108,
+ 8, 3, 1, 248, 42, 2, 108, 8, 3, 1, 255, 114, 2, 108, 8, 3, 5, 1, 132, 2,
+ 108, 8, 3, 1, 238, 53, 2, 108, 8, 3, 1, 41, 2, 238, 65, 90, 8, 3, 1, 255,
+ 103, 2, 238, 65, 90, 8, 3, 1, 255, 112, 2, 238, 65, 90, 8, 3, 1, 255,
+ 104, 2, 238, 65, 90, 8, 3, 1, 255, 109, 2, 238, 65, 90, 8, 3, 1, 255,
+ 100, 2, 238, 65, 90, 8, 3, 1, 255, 108, 2, 238, 65, 90, 8, 3, 1, 255, 98,
+ 2, 238, 65, 90, 8, 3, 1, 255, 114, 2, 238, 65, 90, 8, 3, 1, 255, 101, 2,
+ 238, 65, 90, 8, 3, 1, 255, 99, 2, 238, 65, 90, 8, 3, 1, 254, 38, 2, 238,
+ 65, 90, 8, 3, 1, 255, 110, 2, 238, 65, 90, 8, 3, 1, 255, 113, 2, 238, 65,
+ 90, 8, 3, 1, 255, 97, 2, 238, 65, 90, 8, 3, 1, 134, 2, 235, 54, 90, 8, 3,
+ 1, 194, 2, 235, 54, 90, 8, 3, 1, 255, 103, 2, 248, 45, 19, 242, 226, 8,
+ 3, 1, 157, 2, 235, 54, 90, 8, 3, 1, 248, 35, 157, 2, 235, 54, 90, 8, 3,
+ 1, 224, 248, 35, 157, 2, 235, 54, 90, 8, 3, 1, 243, 73, 2, 235, 54, 90,
+ 8, 3, 1, 220, 2, 235, 54, 90, 8, 3, 1, 248, 35, 117, 2, 235, 54, 90, 8,
+ 3, 1, 254, 38, 2, 235, 54, 90, 8, 3, 1, 132, 2, 235, 54, 90, 8, 3, 1,
+ 253, 244, 2, 235, 54, 90, 49, 1, 3, 205, 240, 22, 49, 1, 3, 255, 18, 49,
+ 1, 3, 255, 105, 2, 242, 253, 49, 1, 3, 248, 109, 49, 1, 3, 224, 248, 35,
+ 72, 49, 1, 3, 255, 19, 49, 1, 3, 238, 70, 255, 115, 2, 108, 49, 1, 3, 84,
+ 210, 49, 1, 3, 205, 192, 49, 1, 3, 220, 2, 108, 49, 1, 3, 242, 237, 49,
+ 1, 3, 5, 71, 49, 1, 3, 5, 220, 2, 108, 49, 1, 3, 255, 115, 2, 231, 101,
+ 49, 1, 3, 255, 100, 2, 235, 54, 90, 49, 1, 3, 255, 100, 2, 238, 65, 90,
+ 49, 1, 3, 5, 162, 49, 1, 3, 255, 108, 2, 90, 49, 1, 3, 205, 255, 108, 2,
+ 183, 248, 117, 49, 1, 3, 255, 98, 2, 40, 90, 49, 1, 3, 255, 98, 2, 235,
+ 54, 90, 49, 1, 3, 5, 197, 49, 1, 3, 240, 60, 73, 49, 1, 3, 248, 68, 49,
+ 1, 3, 255, 99, 2, 90, 49, 1, 3, 248, 93, 49, 1, 3, 255, 102, 2, 238, 65,
+ 90, 49, 1, 3, 132, 125, 49, 1, 3, 236, 160, 49, 1, 3, 5, 79, 49, 1, 3,
+ 255, 110, 2, 90, 49, 1, 3, 205, 179, 49, 1, 3, 255, 17, 49, 1, 3, 255,
+ 97, 2, 235, 54, 90, 49, 1, 3, 255, 97, 2, 242, 253, 49, 1, 3, 248, 155,
+ 49, 1, 3, 240, 38, 50, 240, 4, 242, 245, 238, 54, 50, 240, 4, 242, 241,
+ 238, 54, 50, 247, 95, 46, 50, 235, 6, 69, 8, 5, 1, 134, 2, 248, 51, 46,
+ 8, 3, 1, 134, 2, 248, 51, 46, 8, 5, 1, 41, 2, 53, 48, 8, 3, 1, 41, 2, 53,
+ 48, 8, 5, 1, 41, 2, 53, 46, 8, 3, 1, 41, 2, 53, 46, 8, 5, 1, 41, 2, 248,
+ 41, 46, 8, 3, 1, 41, 2, 248, 41, 46, 8, 5, 1, 255, 105, 2, 238, 109, 19,
+ 135, 8, 3, 1, 255, 105, 2, 238, 109, 19, 135, 8, 5, 1, 255, 103, 2, 53,
+ 48, 8, 3, 1, 255, 103, 2, 53, 48, 8, 5, 1, 255, 103, 2, 53, 46, 8, 3, 1,
+ 255, 103, 2, 53, 46, 8, 5, 1, 255, 103, 2, 248, 41, 46, 8, 3, 1, 255,
+ 103, 2, 248, 41, 46, 8, 5, 1, 255, 103, 2, 236, 151, 8, 3, 1, 255, 103,
+ 2, 236, 151, 8, 5, 1, 255, 103, 2, 190, 46, 8, 3, 1, 255, 103, 2, 190,
+ 46, 8, 5, 1, 157, 2, 240, 42, 19, 191, 8, 3, 1, 157, 2, 240, 42, 19, 191,
+ 8, 5, 1, 157, 2, 240, 42, 19, 135, 8, 3, 1, 157, 2, 240, 42, 19, 135, 8,
+ 5, 1, 157, 2, 190, 46, 8, 3, 1, 157, 2, 190, 46, 8, 5, 1, 157, 2, 242,
+ 219, 46, 8, 3, 1, 157, 2, 242, 219, 46, 8, 5, 1, 157, 2, 238, 109, 19,
+ 239, 255, 8, 3, 1, 157, 2, 238, 109, 19, 239, 255, 8, 5, 1, 255, 112, 2,
+ 53, 48, 8, 3, 1, 255, 112, 2, 53, 48, 8, 5, 1, 255, 104, 2, 196, 8, 3, 1,
+ 255, 104, 2, 196, 8, 5, 1, 255, 106, 2, 53, 48, 8, 3, 1, 255, 106, 2, 53,
+ 48, 8, 5, 1, 255, 106, 2, 53, 46, 8, 3, 1, 255, 106, 2, 53, 46, 8, 5, 1,
+ 255, 106, 2, 175, 8, 3, 1, 255, 106, 2, 175, 8, 5, 1, 255, 106, 2, 236,
+ 151, 8, 3, 1, 255, 106, 2, 236, 151, 8, 5, 1, 255, 106, 2, 242, 243, 46,
+ 8, 3, 1, 255, 106, 2, 242, 243, 46, 8, 5, 1, 220, 2, 242, 219, 46, 8, 3,
+ 1, 220, 2, 242, 219, 46, 8, 5, 1, 220, 2, 235, 56, 19, 135, 8, 3, 1, 220,
+ 2, 235, 56, 19, 135, 8, 5, 1, 255, 109, 2, 135, 8, 3, 1, 255, 109, 2,
+ 135, 8, 5, 1, 255, 109, 2, 53, 46, 8, 3, 1, 255, 109, 2, 53, 46, 8, 5, 1,
+ 255, 109, 2, 248, 41, 46, 8, 3, 1, 255, 109, 2, 248, 41, 46, 8, 5, 1,
+ 255, 100, 2, 53, 46, 8, 3, 1, 255, 100, 2, 53, 46, 8, 5, 1, 255, 100, 2,
+ 53, 242, 230, 19, 196, 8, 3, 1, 255, 100, 2, 53, 242, 230, 19, 196, 8, 5,
+ 1, 255, 100, 2, 248, 41, 46, 8, 3, 1, 255, 100, 2, 248, 41, 46, 8, 5, 1,
+ 255, 100, 2, 190, 46, 8, 3, 1, 255, 100, 2, 190, 46, 8, 5, 1, 255, 108,
+ 2, 135, 8, 3, 1, 255, 108, 2, 135, 8, 5, 1, 255, 108, 2, 53, 48, 8, 3, 1,
+ 255, 108, 2, 53, 48, 8, 5, 1, 255, 108, 2, 53, 46, 8, 3, 1, 255, 108, 2,
+ 53, 46, 8, 5, 1, 255, 98, 2, 53, 48, 8, 3, 1, 255, 98, 2, 53, 48, 8, 5,
+ 1, 255, 98, 2, 53, 46, 8, 3, 1, 255, 98, 2, 53, 46, 8, 5, 1, 255, 98, 2,
+ 248, 41, 46, 8, 3, 1, 255, 98, 2, 248, 41, 46, 8, 5, 1, 255, 98, 2, 190,
+ 46, 8, 3, 1, 255, 98, 2, 190, 46, 8, 5, 1, 117, 2, 242, 219, 19, 135, 8,
+ 3, 1, 117, 2, 242, 219, 19, 135, 8, 5, 1, 117, 2, 242, 219, 19, 175, 8,
+ 3, 1, 117, 2, 242, 219, 19, 175, 8, 5, 1, 117, 2, 240, 42, 19, 191, 8, 3,
+ 1, 117, 2, 240, 42, 19, 191, 8, 5, 1, 117, 2, 240, 42, 19, 135, 8, 3, 1,
+ 117, 2, 240, 42, 19, 135, 8, 5, 1, 255, 114, 2, 135, 8, 3, 1, 255, 114,
+ 2, 135, 8, 5, 1, 255, 114, 2, 53, 48, 8, 3, 1, 255, 114, 2, 53, 48, 8, 5,
+ 1, 255, 101, 2, 53, 48, 8, 3, 1, 255, 101, 2, 53, 48, 8, 5, 1, 255, 101,
+ 2, 53, 46, 8, 3, 1, 255, 101, 2, 53, 46, 8, 5, 1, 255, 101, 2, 53, 242,
+ 230, 19, 196, 8, 3, 1, 255, 101, 2, 53, 242, 230, 19, 196, 8, 5, 1, 255,
+ 101, 2, 248, 41, 46, 8, 3, 1, 255, 101, 2, 248, 41, 46, 8, 5, 1, 255, 99,
+ 2, 53, 48, 8, 3, 1, 255, 99, 2, 53, 48, 8, 5, 1, 255, 99, 2, 53, 46, 8,
+ 3, 1, 255, 99, 2, 53, 46, 8, 5, 1, 255, 99, 2, 242, 241, 19, 53, 48, 8,
+ 3, 1, 255, 99, 2, 242, 241, 19, 53, 48, 8, 5, 1, 255, 99, 2, 243, 86, 19,
+ 53, 48, 8, 3, 1, 255, 99, 2, 243, 86, 19, 53, 48, 8, 5, 1, 255, 99, 2,
+ 53, 242, 230, 19, 53, 48, 8, 3, 1, 255, 99, 2, 53, 242, 230, 19, 53, 48,
+ 8, 5, 1, 255, 102, 2, 53, 48, 8, 3, 1, 255, 102, 2, 53, 48, 8, 5, 1, 255,
+ 102, 2, 53, 46, 8, 3, 1, 255, 102, 2, 53, 46, 8, 5, 1, 255, 102, 2, 248,
+ 41, 46, 8, 3, 1, 255, 102, 2, 248, 41, 46, 8, 5, 1, 255, 102, 2, 190, 46,
+ 8, 3, 1, 255, 102, 2, 190, 46, 8, 5, 1, 132, 2, 235, 56, 46, 8, 3, 1,
+ 132, 2, 235, 56, 46, 8, 5, 1, 132, 2, 242, 219, 46, 8, 3, 1, 132, 2, 242,
+ 219, 46, 8, 5, 1, 132, 2, 190, 46, 8, 3, 1, 132, 2, 190, 46, 8, 5, 1,
+ 132, 2, 242, 219, 19, 135, 8, 3, 1, 132, 2, 242, 219, 19, 135, 8, 5, 1,
+ 132, 2, 240, 42, 19, 175, 8, 3, 1, 132, 2, 240, 42, 19, 175, 8, 5, 1,
+ 255, 110, 2, 169, 8, 3, 1, 255, 110, 2, 169, 8, 5, 1, 255, 110, 2, 53,
+ 46, 8, 3, 1, 255, 110, 2, 53, 46, 8, 5, 1, 255, 111, 2, 191, 8, 3, 1,
+ 255, 111, 2, 191, 8, 5, 1, 255, 111, 2, 135, 8, 3, 1, 255, 111, 2, 135,
+ 8, 5, 1, 255, 111, 2, 175, 8, 3, 1, 255, 111, 2, 175, 8, 5, 1, 255, 111,
+ 2, 53, 48, 8, 3, 1, 255, 111, 2, 53, 48, 8, 5, 1, 255, 111, 2, 53, 46, 8,
+ 3, 1, 255, 111, 2, 53, 46, 8, 5, 1, 255, 113, 2, 53, 48, 8, 3, 1, 255,
+ 113, 2, 53, 48, 8, 5, 1, 255, 113, 2, 175, 8, 3, 1, 255, 113, 2, 175, 8,
+ 5, 1, 255, 107, 2, 53, 48, 8, 3, 1, 255, 107, 2, 53, 48, 8, 5, 1, 255,
+ 97, 2, 233, 48, 8, 3, 1, 255, 97, 2, 233, 48, 8, 5, 1, 255, 97, 2, 53,
+ 46, 8, 3, 1, 255, 97, 2, 53, 46, 8, 5, 1, 255, 97, 2, 248, 41, 46, 8, 3,
+ 1, 255, 97, 2, 248, 41, 46, 8, 3, 1, 255, 106, 2, 248, 41, 46, 8, 3, 1,
+ 255, 102, 2, 175, 8, 3, 1, 255, 111, 2, 248, 51, 48, 8, 3, 1, 255, 107,
+ 2, 248, 51, 48, 8, 3, 1, 134, 2, 38, 137, 242, 233, 8, 3, 1, 183, 255,
+ 99, 2, 53, 48, 8, 5, 1, 134, 2, 53, 46, 8, 3, 1, 134, 2, 53, 46, 8, 5, 1,
+ 134, 2, 248, 45, 48, 8, 3, 1, 134, 2, 248, 45, 48, 8, 5, 1, 134, 2, 190,
+ 19, 135, 8, 3, 1, 134, 2, 190, 19, 135, 8, 5, 1, 134, 2, 190, 19, 191, 8,
+ 3, 1, 134, 2, 190, 19, 191, 8, 5, 1, 134, 2, 190, 19, 248, 45, 48, 8, 3,
+ 1, 134, 2, 190, 19, 248, 45, 48, 8, 5, 1, 134, 2, 190, 19, 169, 8, 3, 1,
+ 134, 2, 190, 19, 169, 8, 5, 1, 134, 2, 190, 19, 53, 46, 8, 3, 1, 134, 2,
+ 190, 19, 53, 46, 8, 5, 1, 134, 2, 242, 243, 19, 135, 8, 3, 1, 134, 2,
+ 242, 243, 19, 135, 8, 5, 1, 134, 2, 242, 243, 19, 191, 8, 3, 1, 134, 2,
+ 242, 243, 19, 191, 8, 5, 1, 134, 2, 242, 243, 19, 248, 45, 48, 8, 3, 1,
+ 134, 2, 242, 243, 19, 248, 45, 48, 8, 5, 1, 134, 2, 242, 243, 19, 169, 8,
+ 3, 1, 134, 2, 242, 243, 19, 169, 8, 5, 1, 134, 2, 242, 243, 19, 53, 46,
+ 8, 3, 1, 134, 2, 242, 243, 19, 53, 46, 8, 5, 1, 157, 2, 53, 46, 8, 3, 1,
+ 157, 2, 53, 46, 8, 5, 1, 157, 2, 248, 45, 48, 8, 3, 1, 157, 2, 248, 45,
+ 48, 8, 5, 1, 157, 2, 169, 8, 3, 1, 157, 2, 169, 8, 5, 1, 157, 2, 190, 19,
+ 135, 8, 3, 1, 157, 2, 190, 19, 135, 8, 5, 1, 157, 2, 190, 19, 191, 8, 3,
+ 1, 157, 2, 190, 19, 191, 8, 5, 1, 157, 2, 190, 19, 248, 45, 48, 8, 3, 1,
+ 157, 2, 190, 19, 248, 45, 48, 8, 5, 1, 157, 2, 190, 19, 169, 8, 3, 1,
+ 157, 2, 190, 19, 169, 8, 5, 1, 157, 2, 190, 19, 53, 46, 8, 3, 1, 157, 2,
+ 190, 19, 53, 46, 8, 5, 1, 220, 2, 248, 45, 48, 8, 3, 1, 220, 2, 248, 45,
+ 48, 8, 5, 1, 220, 2, 53, 46, 8, 3, 1, 220, 2, 53, 46, 8, 5, 1, 117, 2,
+ 53, 46, 8, 3, 1, 117, 2, 53, 46, 8, 5, 1, 117, 2, 248, 45, 48, 8, 3, 1,
+ 117, 2, 248, 45, 48, 8, 5, 1, 117, 2, 190, 19, 135, 8, 3, 1, 117, 2, 190,
+ 19, 135, 8, 5, 1, 117, 2, 190, 19, 191, 8, 3, 1, 117, 2, 190, 19, 191, 8,
+ 5, 1, 117, 2, 190, 19, 248, 45, 48, 8, 3, 1, 117, 2, 190, 19, 248, 45,
+ 48, 8, 5, 1, 117, 2, 190, 19, 169, 8, 3, 1, 117, 2, 190, 19, 169, 8, 5,
+ 1, 117, 2, 190, 19, 53, 46, 8, 3, 1, 117, 2, 190, 19, 53, 46, 8, 5, 1,
+ 117, 2, 248, 60, 19, 135, 8, 3, 1, 117, 2, 248, 60, 19, 135, 8, 5, 1,
+ 117, 2, 248, 60, 19, 191, 8, 3, 1, 117, 2, 248, 60, 19, 191, 8, 5, 1,
+ 117, 2, 248, 60, 19, 248, 45, 48, 8, 3, 1, 117, 2, 248, 60, 19, 248, 45,
+ 48, 8, 5, 1, 117, 2, 248, 60, 19, 169, 8, 3, 1, 117, 2, 248, 60, 19, 169,
+ 8, 5, 1, 117, 2, 248, 60, 19, 53, 46, 8, 3, 1, 117, 2, 248, 60, 19, 53,
+ 46, 8, 5, 1, 132, 2, 53, 46, 8, 3, 1, 132, 2, 53, 46, 8, 5, 1, 132, 2,
+ 248, 45, 48, 8, 3, 1, 132, 2, 248, 45, 48, 8, 5, 1, 132, 2, 248, 60, 19,
+ 135, 8, 3, 1, 132, 2, 248, 60, 19, 135, 8, 5, 1, 132, 2, 248, 60, 19,
+ 191, 8, 3, 1, 132, 2, 248, 60, 19, 191, 8, 5, 1, 132, 2, 248, 60, 19,
+ 248, 45, 48, 8, 3, 1, 132, 2, 248, 60, 19, 248, 45, 48, 8, 5, 1, 132, 2,
+ 248, 60, 19, 169, 8, 3, 1, 132, 2, 248, 60, 19, 169, 8, 5, 1, 132, 2,
+ 248, 60, 19, 53, 46, 8, 3, 1, 132, 2, 248, 60, 19, 53, 46, 8, 5, 1, 255,
+ 107, 2, 191, 8, 3, 1, 255, 107, 2, 191, 8, 5, 1, 255, 107, 2, 53, 46, 8,
+ 3, 1, 255, 107, 2, 53, 46, 8, 5, 1, 255, 107, 2, 248, 45, 48, 8, 3, 1,
+ 255, 107, 2, 248, 45, 48, 8, 5, 1, 255, 107, 2, 169, 8, 3, 1, 255, 107,
+ 2, 169, 17, 3, 1, 194, 2, 240, 29, 17, 3, 1, 194, 2, 240, 25, 17, 3, 1,
+ 194, 2, 159, 19, 215, 17, 3, 1, 194, 2, 148, 19, 215, 17, 3, 1, 194, 2,
+ 159, 19, 212, 17, 3, 1, 194, 2, 148, 19, 212, 17, 3, 1, 194, 2, 159, 19,
+ 232, 71, 17, 3, 1, 194, 2, 148, 19, 232, 71, 17, 5, 1, 194, 2, 240, 29,
+ 17, 5, 1, 194, 2, 240, 25, 17, 5, 1, 194, 2, 159, 19, 215, 17, 5, 1, 194,
+ 2, 148, 19, 215, 17, 5, 1, 194, 2, 159, 19, 212, 17, 5, 1, 194, 2, 148,
+ 19, 212, 17, 5, 1, 194, 2, 159, 19, 232, 71, 17, 5, 1, 194, 2, 148, 19,
+ 232, 71, 17, 3, 1, 238, 57, 2, 240, 29, 17, 3, 1, 238, 57, 2, 240, 25,
+ 17, 3, 1, 238, 57, 2, 159, 19, 215, 17, 3, 1, 238, 57, 2, 148, 19, 215,
+ 17, 3, 1, 238, 57, 2, 159, 19, 212, 17, 3, 1, 238, 57, 2, 148, 19, 212,
+ 17, 5, 1, 238, 57, 2, 240, 29, 17, 5, 1, 238, 57, 2, 240, 25, 17, 5, 1,
+ 238, 57, 2, 159, 19, 215, 17, 5, 1, 238, 57, 2, 148, 19, 215, 17, 5, 1,
+ 238, 57, 2, 159, 19, 212, 17, 5, 1, 238, 57, 2, 148, 19, 212, 17, 3, 1,
+ 253, 123, 2, 240, 29, 17, 3, 1, 253, 123, 2, 240, 25, 17, 3, 1, 253, 123,
+ 2, 159, 19, 215, 17, 3, 1, 253, 123, 2, 148, 19, 215, 17, 3, 1, 253, 123,
+ 2, 159, 19, 212, 17, 3, 1, 253, 123, 2, 148, 19, 212, 17, 3, 1, 253, 123,
+ 2, 159, 19, 232, 71, 17, 3, 1, 253, 123, 2, 148, 19, 232, 71, 17, 5, 1,
+ 253, 123, 2, 240, 29, 17, 5, 1, 253, 123, 2, 240, 25, 17, 5, 1, 253, 123,
+ 2, 159, 19, 215, 17, 5, 1, 253, 123, 2, 148, 19, 215, 17, 5, 1, 253, 123,
+ 2, 159, 19, 212, 17, 5, 1, 253, 123, 2, 148, 19, 212, 17, 5, 1, 253, 123,
+ 2, 159, 19, 232, 71, 17, 5, 1, 253, 123, 2, 148, 19, 232, 71, 17, 3, 1,
+ 248, 42, 2, 240, 29, 17, 3, 1, 248, 42, 2, 240, 25, 17, 3, 1, 248, 42, 2,
+ 159, 19, 215, 17, 3, 1, 248, 42, 2, 148, 19, 215, 17, 3, 1, 248, 42, 2,
+ 159, 19, 212, 17, 3, 1, 248, 42, 2, 148, 19, 212, 17, 3, 1, 248, 42, 2,
+ 159, 19, 232, 71, 17, 3, 1, 248, 42, 2, 148, 19, 232, 71, 17, 5, 1, 248,
+ 42, 2, 240, 29, 17, 5, 1, 248, 42, 2, 240, 25, 17, 5, 1, 248, 42, 2, 159,
+ 19, 215, 17, 5, 1, 248, 42, 2, 148, 19, 215, 17, 5, 1, 248, 42, 2, 159,
+ 19, 212, 17, 5, 1, 248, 42, 2, 148, 19, 212, 17, 5, 1, 248, 42, 2, 159,
+ 19, 232, 71, 17, 5, 1, 248, 42, 2, 148, 19, 232, 71, 17, 3, 1, 238, 64,
+ 2, 240, 29, 17, 3, 1, 238, 64, 2, 240, 25, 17, 3, 1, 238, 64, 2, 159, 19,
+ 215, 17, 3, 1, 238, 64, 2, 148, 19, 215, 17, 3, 1, 238, 64, 2, 159, 19,
+ 212, 17, 3, 1, 238, 64, 2, 148, 19, 212, 17, 5, 1, 238, 64, 2, 240, 29,
+ 17, 5, 1, 238, 64, 2, 240, 25, 17, 5, 1, 238, 64, 2, 159, 19, 215, 17, 5,
+ 1, 238, 64, 2, 148, 19, 215, 17, 5, 1, 238, 64, 2, 159, 19, 212, 17, 5,
+ 1, 238, 64, 2, 148, 19, 212, 17, 3, 1, 238, 53, 2, 240, 29, 17, 3, 1,
+ 238, 53, 2, 240, 25, 17, 3, 1, 238, 53, 2, 159, 19, 215, 17, 3, 1, 238,
+ 53, 2, 148, 19, 215, 17, 3, 1, 238, 53, 2, 159, 19, 212, 17, 3, 1, 238,
+ 53, 2, 148, 19, 212, 17, 3, 1, 238, 53, 2, 159, 19, 232, 71, 17, 3, 1,
+ 238, 53, 2, 148, 19, 232, 71, 17, 5, 1, 238, 53, 2, 240, 25, 17, 5, 1,
+ 238, 53, 2, 148, 19, 215, 17, 5, 1, 238, 53, 2, 148, 19, 212, 17, 5, 1,
+ 238, 53, 2, 148, 19, 232, 71, 17, 3, 1, 211, 2, 240, 29, 17, 3, 1, 211,
+ 2, 240, 25, 17, 3, 1, 211, 2, 159, 19, 215, 17, 3, 1, 211, 2, 148, 19,
+ 215, 17, 3, 1, 211, 2, 159, 19, 212, 17, 3, 1, 211, 2, 148, 19, 212, 17,
+ 3, 1, 211, 2, 159, 19, 232, 71, 17, 3, 1, 211, 2, 148, 19, 232, 71, 17,
+ 5, 1, 211, 2, 240, 29, 17, 5, 1, 211, 2, 240, 25, 17, 5, 1, 211, 2, 159,
+ 19, 215, 17, 5, 1, 211, 2, 148, 19, 215, 17, 5, 1, 211, 2, 159, 19, 212,
+ 17, 5, 1, 211, 2, 148, 19, 212, 17, 5, 1, 211, 2, 159, 19, 232, 71, 17,
+ 5, 1, 211, 2, 148, 19, 232, 71, 17, 3, 1, 194, 2, 215, 17, 3, 1, 194, 2,
+ 212, 17, 3, 1, 238, 57, 2, 215, 17, 3, 1, 238, 57, 2, 212, 17, 3, 1, 253,
+ 123, 2, 215, 17, 3, 1, 253, 123, 2, 212, 17, 3, 1, 248, 42, 2, 215, 17,
+ 3, 1, 248, 42, 2, 212, 17, 3, 1, 238, 64, 2, 215, 17, 3, 1, 238, 64, 2,
+ 212, 17, 3, 1, 238, 53, 2, 215, 17, 3, 1, 238, 53, 2, 212, 17, 3, 1, 211,
+ 2, 215, 17, 3, 1, 211, 2, 212, 17, 3, 1, 194, 2, 159, 19, 231, 35, 17, 3,
+ 1, 194, 2, 148, 19, 231, 35, 17, 3, 1, 194, 2, 159, 19, 242, 248, 19,
+ 231, 35, 17, 3, 1, 194, 2, 148, 19, 242, 248, 19, 231, 35, 17, 3, 1, 194,
+ 2, 159, 19, 248, 79, 19, 231, 35, 17, 3, 1, 194, 2, 148, 19, 248, 79, 19,
+ 231, 35, 17, 3, 1, 194, 2, 159, 19, 233, 53, 19, 231, 35, 17, 3, 1, 194,
+ 2, 148, 19, 233, 53, 19, 231, 35, 17, 5, 1, 194, 2, 159, 19, 229, 57, 17,
+ 5, 1, 194, 2, 148, 19, 229, 57, 17, 5, 1, 194, 2, 159, 19, 242, 248, 19,
+ 229, 57, 17, 5, 1, 194, 2, 148, 19, 242, 248, 19, 229, 57, 17, 5, 1, 194,
+ 2, 159, 19, 248, 79, 19, 229, 57, 17, 5, 1, 194, 2, 148, 19, 248, 79, 19,
+ 229, 57, 17, 5, 1, 194, 2, 159, 19, 233, 53, 19, 229, 57, 17, 5, 1, 194,
+ 2, 148, 19, 233, 53, 19, 229, 57, 17, 3, 1, 253, 123, 2, 159, 19, 231,
+ 35, 17, 3, 1, 253, 123, 2, 148, 19, 231, 35, 17, 3, 1, 253, 123, 2, 159,
+ 19, 242, 248, 19, 231, 35, 17, 3, 1, 253, 123, 2, 148, 19, 242, 248, 19,
+ 231, 35, 17, 3, 1, 253, 123, 2, 159, 19, 248, 79, 19, 231, 35, 17, 3, 1,
+ 253, 123, 2, 148, 19, 248, 79, 19, 231, 35, 17, 3, 1, 253, 123, 2, 159,
+ 19, 233, 53, 19, 231, 35, 17, 3, 1, 253, 123, 2, 148, 19, 233, 53, 19,
+ 231, 35, 17, 5, 1, 253, 123, 2, 159, 19, 229, 57, 17, 5, 1, 253, 123, 2,
+ 148, 19, 229, 57, 17, 5, 1, 253, 123, 2, 159, 19, 242, 248, 19, 229, 57,
+ 17, 5, 1, 253, 123, 2, 148, 19, 242, 248, 19, 229, 57, 17, 5, 1, 253,
+ 123, 2, 159, 19, 248, 79, 19, 229, 57, 17, 5, 1, 253, 123, 2, 148, 19,
+ 248, 79, 19, 229, 57, 17, 5, 1, 253, 123, 2, 159, 19, 233, 53, 19, 229,
+ 57, 17, 5, 1, 253, 123, 2, 148, 19, 233, 53, 19, 229, 57, 17, 3, 1, 211,
+ 2, 159, 19, 231, 35, 17, 3, 1, 211, 2, 148, 19, 231, 35, 17, 3, 1, 211,
+ 2, 159, 19, 242, 248, 19, 231, 35, 17, 3, 1, 211, 2, 148, 19, 242, 248,
+ 19, 231, 35, 17, 3, 1, 211, 2, 159, 19, 248, 79, 19, 231, 35, 17, 3, 1,
+ 211, 2, 148, 19, 248, 79, 19, 231, 35, 17, 3, 1, 211, 2, 159, 19, 233,
+ 53, 19, 231, 35, 17, 3, 1, 211, 2, 148, 19, 233, 53, 19, 231, 35, 17, 5,
+ 1, 211, 2, 159, 19, 229, 57, 17, 5, 1, 211, 2, 148, 19, 229, 57, 17, 5,
+ 1, 211, 2, 159, 19, 242, 248, 19, 229, 57, 17, 5, 1, 211, 2, 148, 19,
+ 242, 248, 19, 229, 57, 17, 5, 1, 211, 2, 159, 19, 248, 79, 19, 229, 57,
+ 17, 5, 1, 211, 2, 148, 19, 248, 79, 19, 229, 57, 17, 5, 1, 211, 2, 159,
+ 19, 233, 53, 19, 229, 57, 17, 5, 1, 211, 2, 148, 19, 233, 53, 19, 229,
+ 57, 17, 3, 1, 194, 2, 238, 103, 17, 3, 1, 194, 2, 196, 17, 3, 1, 194, 2,
+ 242, 248, 19, 231, 35, 17, 3, 1, 194, 2, 231, 35, 17, 3, 1, 194, 2, 248,
+ 79, 19, 231, 35, 17, 3, 1, 194, 2, 232, 71, 17, 3, 1, 194, 2, 233, 53,
+ 19, 231, 35, 17, 5, 1, 194, 2, 238, 103, 17, 5, 1, 194, 2, 196, 17, 5, 1,
+ 194, 2, 215, 17, 5, 1, 194, 2, 212, 17, 5, 1, 194, 2, 229, 57, 17, 236,
+ 229, 17, 229, 57, 17, 240, 29, 17, 232, 71, 17, 235, 59, 19, 232, 71, 17,
+ 3, 1, 253, 123, 2, 242, 248, 19, 231, 35, 17, 3, 1, 253, 123, 2, 231, 35,
+ 17, 3, 1, 253, 123, 2, 248, 79, 19, 231, 35, 17, 3, 1, 253, 123, 2, 232,
+ 71, 17, 3, 1, 253, 123, 2, 233, 53, 19, 231, 35, 17, 5, 1, 238, 57, 2,
+ 215, 17, 5, 1, 238, 57, 2, 212, 17, 5, 1, 253, 123, 2, 215, 17, 5, 1,
+ 253, 123, 2, 212, 17, 5, 1, 253, 123, 2, 229, 57, 17, 159, 19, 215, 17,
+ 159, 19, 212, 17, 159, 19, 232, 71, 17, 3, 1, 248, 42, 2, 238, 103, 17,
+ 3, 1, 248, 42, 2, 196, 17, 3, 1, 248, 42, 2, 235, 59, 19, 215, 17, 3, 1,
+ 248, 42, 2, 235, 59, 19, 212, 17, 3, 1, 248, 42, 2, 232, 71, 17, 3, 1,
+ 248, 42, 2, 235, 59, 19, 232, 71, 17, 5, 1, 248, 42, 2, 238, 103, 17, 5,
+ 1, 248, 42, 2, 196, 17, 5, 1, 248, 42, 2, 215, 17, 5, 1, 248, 42, 2, 212,
+ 17, 148, 19, 215, 17, 148, 19, 212, 17, 148, 19, 232, 71, 17, 3, 1, 238,
+ 53, 2, 238, 103, 17, 3, 1, 238, 53, 2, 196, 17, 3, 1, 238, 53, 2, 235,
+ 59, 19, 215, 17, 3, 1, 238, 53, 2, 235, 59, 19, 212, 17, 3, 1, 253, 218,
+ 2, 240, 29, 17, 3, 1, 253, 218, 2, 240, 25, 17, 3, 1, 238, 53, 2, 232,
+ 71, 17, 3, 1, 238, 53, 2, 235, 59, 19, 232, 71, 17, 5, 1, 238, 53, 2,
+ 238, 103, 17, 5, 1, 238, 53, 2, 196, 17, 5, 1, 238, 53, 2, 215, 17, 5, 1,
+ 238, 53, 2, 212, 17, 5, 1, 253, 218, 2, 240, 25, 17, 235, 59, 19, 215,
+ 17, 235, 59, 19, 212, 17, 215, 17, 3, 1, 211, 2, 242, 248, 19, 231, 35,
+ 17, 3, 1, 211, 2, 231, 35, 17, 3, 1, 211, 2, 248, 79, 19, 231, 35, 17, 3,
+ 1, 211, 2, 232, 71, 17, 3, 1, 211, 2, 233, 53, 19, 231, 35, 17, 5, 1,
+ 238, 64, 2, 215, 17, 5, 1, 238, 64, 2, 212, 17, 5, 1, 211, 2, 215, 17, 5,
+ 1, 211, 2, 212, 17, 5, 1, 211, 2, 229, 57, 17, 212, 17, 240, 25, 255, 23,
+ 243, 43, 255, 28, 243, 43, 255, 23, 240, 15, 255, 28, 240, 15, 233, 42,
+ 240, 15, 233, 203, 240, 15, 235, 1, 240, 15, 240, 174, 240, 15, 233, 51,
+ 240, 15, 252, 219, 240, 15, 251, 46, 240, 15, 248, 145, 243, 81, 240, 15,
+ 248, 145, 243, 81, 233, 219, 248, 145, 243, 81, 238, 140, 231, 96, 69,
+ 231, 99, 69, 238, 93, 232, 188, 238, 93, 240, 174, 242, 235, 255, 23,
+ 242, 235, 255, 28, 242, 235, 163, 125, 45, 59, 242, 224, 45, 170, 242,
+ 224, 40, 240, 12, 235, 51, 69, 38, 240, 12, 235, 51, 69, 240, 12, 243,
+ 218, 235, 51, 69, 240, 12, 229, 62, 235, 51, 69, 40, 45, 235, 51, 69, 38,
+ 45, 235, 51, 69, 45, 243, 218, 235, 51, 69, 45, 229, 62, 235, 51, 69,
+ 238, 173, 45, 238, 173, 238, 69, 234, 43, 238, 69, 253, 125, 53, 238,
+ 143, 171, 53, 238, 143, 163, 235, 69, 233, 207, 240, 209, 248, 41, 234,
+ 6, 235, 91, 234, 6, 231, 96, 234, 52, 231, 99, 234, 52, 254, 227, 233,
+ 134, 233, 202, 231, 96, 235, 131, 231, 99, 235, 131, 241, 252, 236, 233,
+ 240, 15, 254, 68, 246, 85, 52, 254, 68, 253, 219, 236, 193, 52, 240, 57,
+ 45, 240, 57, 240, 3, 240, 57, 224, 240, 57, 224, 45, 240, 57, 224, 240,
+ 3, 240, 57, 240, 130, 240, 12, 231, 87, 185, 235, 51, 69, 240, 12, 231,
+ 36, 185, 235, 51, 69, 236, 90, 69, 45, 233, 54, 69, 232, 179, 235, 74,
+ 235, 158, 99, 248, 139, 243, 25, 235, 128, 240, 209, 235, 175, 241, 177,
+ 238, 69, 236, 155, 240, 37, 40, 31, 238, 52, 2, 240, 214, 38, 31, 238,
+ 52, 2, 240, 214, 45, 236, 156, 69, 236, 156, 233, 54, 69, 233, 54, 236,
+ 156, 69, 238, 30, 21, 254, 60, 224, 238, 208, 52, 86, 139, 238, 69, 86,
+ 77, 238, 69, 170, 235, 52, 224, 234, 14, 245, 24, 253, 176, 171, 235,
+ 174, 238, 243, 234, 0, 234, 20, 242, 250, 52, 247, 129, 242, 235, 236,
+ 145, 235, 158, 241, 111, 233, 51, 69, 204, 53, 232, 75, 235, 71, 240, 57,
+ 248, 58, 53, 232, 75, 248, 48, 53, 232, 75, 171, 53, 232, 75, 248, 58,
+ 53, 69, 240, 4, 240, 34, 236, 131, 59, 248, 58, 243, 5, 240, 19, 10, 240,
+ 15, 248, 143, 238, 140, 237, 163, 232, 116, 235, 129, 240, 123, 235, 129,
+ 234, 6, 238, 190, 235, 152, 235, 145, 236, 243, 235, 152, 235, 145, 238,
+ 190, 11, 248, 38, 237, 39, 236, 243, 11, 248, 38, 237, 39, 237, 216, 26,
+ 238, 215, 239, 146, 26, 238, 215, 233, 49, 242, 217, 233, 49, 8, 3, 1,
+ 71, 233, 49, 177, 233, 49, 176, 233, 49, 187, 233, 49, 203, 233, 49, 195,
+ 233, 49, 202, 233, 49, 248, 49, 52, 233, 49, 240, 68, 233, 49, 240, 7,
+ 52, 233, 49, 40, 232, 74, 233, 49, 38, 232, 74, 233, 49, 8, 3, 1, 197,
+ 235, 48, 242, 217, 235, 48, 127, 235, 48, 111, 235, 48, 166, 235, 48,
+ 177, 235, 48, 176, 235, 48, 187, 235, 48, 203, 235, 48, 195, 235, 48,
+ 202, 235, 48, 248, 49, 52, 235, 48, 240, 68, 235, 48, 240, 7, 52, 235,
+ 48, 40, 232, 74, 235, 48, 38, 232, 74, 8, 235, 48, 3, 1, 67, 8, 235, 48,
+ 3, 1, 72, 8, 235, 48, 3, 1, 73, 8, 235, 48, 3, 1, 206, 8, 235, 48, 3, 1,
+ 240, 86, 231, 137, 52, 243, 14, 52, 237, 96, 52, 241, 117, 245, 92, 52,
+ 251, 199, 52, 251, 234, 52, 246, 103, 52, 242, 58, 52, 243, 44, 52, 254,
+ 131, 52, 116, 242, 104, 52, 250, 203, 52, 250, 231, 52, 254, 185, 52,
+ 242, 162, 52, 238, 180, 52, 241, 127, 246, 241, 52, 252, 63, 52, 239, 86,
+ 52, 238, 254, 52, 239, 94, 52, 250, 153, 52, 50, 40, 186, 48, 50, 38,
+ 186, 48, 50, 183, 59, 248, 41, 236, 161, 50, 242, 215, 59, 248, 41, 236,
+ 161, 50, 231, 86, 65, 48, 50, 235, 62, 65, 48, 50, 40, 65, 48, 50, 38,
+ 65, 48, 50, 248, 51, 236, 161, 50, 235, 62, 248, 51, 236, 161, 50, 231,
+ 86, 248, 51, 236, 161, 50, 204, 181, 48, 50, 248, 58, 181, 48, 50, 235,
+ 73, 238, 51, 50, 235, 73, 238, 59, 50, 235, 73, 236, 164, 50, 235, 73,
+ 218, 234, 25, 50, 40, 38, 65, 48, 50, 235, 73, 239, 182, 50, 235, 73,
+ 239, 107, 50, 235, 73, 242, 172, 236, 150, 235, 46, 50, 238, 75, 238, 83,
+ 236, 161, 50, 45, 59, 240, 5, 236, 161, 50, 238, 245, 91, 50, 240, 3,
+ 236, 136, 50, 248, 98, 240, 109, 48, 50, 139, 65, 236, 161, 50, 183, 45,
+ 238, 83, 236, 161, 238, 158, 253, 174, 235, 160, 153, 253, 145, 238, 18,
+ 138, 5, 255, 18, 240, 112, 237, 85, 240, 46, 248, 41, 91, 250, 145, 253,
+ 174, 250, 142, 252, 251, 245, 87, 235, 118, 238, 3, 240, 112, 233, 200,
+ 84, 3, 210, 84, 5, 192, 232, 80, 5, 192, 138, 5, 192, 240, 208, 235, 118,
+ 240, 208, 237, 90, 248, 59, 171, 253, 147, 84, 5, 71, 232, 80, 5, 71, 84,
+ 5, 162, 84, 3, 162, 255, 100, 41, 253, 144, 91, 138, 5, 197, 242, 27, 52,
+ 243, 1, 236, 88, 234, 105, 84, 5, 223, 138, 5, 223, 138, 5, 255, 20, 84,
+ 5, 144, 232, 80, 5, 144, 138, 5, 144, 232, 198, 247, 136, 235, 141, 239,
+ 189, 69, 235, 113, 52, 247, 157, 158, 52, 236, 138, 138, 5, 255, 17, 246,
+ 235, 52, 254, 119, 52, 236, 145, 254, 119, 52, 232, 80, 5, 255, 17, 205,
+ 17, 3, 1, 242, 237, 241, 198, 52, 237, 60, 52, 84, 5, 217, 232, 80, 5,
+ 255, 18, 236, 14, 91, 84, 3, 72, 84, 5, 72, 84, 5, 255, 19, 205, 5, 255,
+ 19, 84, 5, 173, 84, 3, 73, 83, 91, 254, 53, 91, 243, 184, 91, 243, 162,
+ 91, 233, 211, 239, 199, 238, 120, 5, 255, 20, 236, 17, 52, 138, 3, 253,
+ 147, 138, 3, 240, 10, 138, 5, 240, 10, 138, 5, 253, 147, 138, 242, 238,
+ 234, 65, 205, 27, 5, 210, 205, 27, 5, 162, 224, 27, 5, 162, 205, 27, 5,
+ 255, 14, 138, 24, 5, 209, 138, 24, 3, 209, 138, 24, 3, 72, 138, 24, 3,
+ 71, 138, 24, 3, 221, 237, 244, 242, 224, 205, 234, 17, 254, 68, 52, 240,
+ 30, 236, 155, 253, 125, 242, 148, 240, 30, 236, 155, 171, 239, 220, 240,
+ 30, 236, 155, 253, 125, 241, 107, 240, 30, 236, 155, 171, 238, 138, 240,
+ 30, 236, 155, 204, 238, 138, 240, 30, 236, 155, 248, 58, 238, 138, 240,
+ 30, 236, 155, 253, 125, 242, 113, 240, 30, 236, 155, 248, 48, 239, 197,
+ 240, 30, 236, 155, 253, 125, 239, 55, 240, 30, 236, 155, 204, 236, 224,
+ 240, 30, 236, 155, 248, 48, 236, 224, 240, 30, 236, 155, 243, 31, 236,
+ 224, 236, 155, 235, 79, 127, 242, 218, 178, 127, 242, 218, 178, 111, 242,
+ 218, 178, 166, 242, 218, 178, 177, 242, 218, 178, 176, 242, 218, 178,
+ 187, 242, 218, 178, 203, 242, 218, 178, 195, 242, 218, 178, 202, 242,
+ 218, 178, 248, 53, 242, 218, 178, 238, 91, 242, 218, 178, 238, 97, 242,
+ 218, 178, 240, 50, 242, 218, 178, 253, 125, 236, 149, 242, 218, 178, 248,
+ 48, 236, 149, 242, 218, 178, 253, 125, 235, 49, 3, 242, 218, 178, 127, 3,
+ 242, 218, 178, 111, 3, 242, 218, 178, 166, 3, 242, 218, 178, 177, 3, 242,
+ 218, 178, 176, 3, 242, 218, 178, 187, 3, 242, 218, 178, 203, 3, 242, 218,
+ 178, 195, 3, 242, 218, 178, 202, 3, 242, 218, 178, 248, 53, 3, 242, 218,
+ 178, 238, 91, 3, 242, 218, 178, 238, 97, 3, 242, 218, 178, 240, 50, 3,
+ 242, 218, 178, 253, 125, 236, 149, 3, 242, 218, 178, 248, 48, 236, 149,
+ 3, 242, 218, 178, 253, 125, 235, 49, 242, 218, 178, 253, 125, 236, 193,
+ 255, 105, 209, 242, 218, 178, 248, 48, 235, 49, 242, 218, 178, 253, 219,
+ 235, 49, 242, 218, 178, 224, 253, 125, 236, 149, 139, 56, 226, 226, 56,
+ 77, 56, 235, 45, 56, 40, 38, 56, 88, 92, 56, 242, 223, 248, 56, 56, 242,
+ 223, 248, 43, 56, 242, 228, 248, 43, 56, 242, 228, 248, 56, 56, 139, 65,
+ 2, 108, 77, 65, 2, 108, 139, 248, 141, 56, 77, 248, 141, 56, 139, 171,
+ 240, 115, 56, 226, 226, 171, 240, 115, 56, 77, 171, 240, 115, 56, 235,
+ 45, 171, 240, 115, 56, 139, 65, 2, 242, 226, 77, 65, 2, 242, 226, 139,
+ 65, 248, 44, 125, 226, 226, 65, 248, 44, 125, 77, 65, 248, 44, 125, 235,
+ 45, 65, 248, 44, 125, 88, 92, 65, 2, 244, 192, 139, 65, 2, 90, 77, 65, 2,
+ 90, 139, 65, 2, 243, 105, 77, 65, 2, 243, 105, 40, 38, 248, 141, 56, 40,
+ 38, 65, 2, 108, 235, 45, 240, 126, 56, 226, 226, 65, 2, 253, 241, 234,
+ 18, 226, 226, 65, 2, 253, 241, 233, 63, 235, 45, 65, 2, 253, 241, 234,
+ 18, 235, 45, 65, 2, 253, 241, 233, 63, 77, 65, 2, 240, 31, 234, 9, 235,
+ 45, 65, 2, 240, 31, 234, 18, 231, 86, 253, 159, 234, 64, 56, 235, 62,
+ 253, 159, 234, 64, 56, 242, 223, 248, 56, 65, 153, 183, 125, 139, 65,
+ 153, 253, 144, 248, 59, 77, 65, 153, 125, 231, 86, 248, 35, 218, 56, 235,
+ 62, 248, 35, 218, 56, 139, 186, 2, 154, 236, 206, 139, 186, 2, 154, 234,
+ 9, 226, 226, 186, 2, 154, 233, 63, 226, 226, 186, 2, 154, 234, 18, 77,
+ 186, 2, 154, 236, 206, 77, 186, 2, 154, 234, 9, 235, 45, 186, 2, 154,
+ 233, 63, 235, 45, 186, 2, 154, 234, 18, 77, 65, 248, 59, 139, 56, 226,
+ 226, 65, 139, 147, 235, 45, 56, 139, 65, 248, 59, 77, 56, 139, 240, 117,
+ 238, 104, 226, 226, 240, 117, 238, 104, 77, 240, 117, 238, 104, 235, 45,
+ 240, 117, 238, 104, 139, 186, 248, 59, 77, 236, 175, 77, 186, 248, 59,
+ 139, 236, 175, 139, 45, 65, 2, 108, 40, 38, 45, 65, 2, 108, 77, 45, 65,
+ 2, 108, 139, 45, 56, 226, 226, 45, 56, 77, 45, 56, 235, 45, 45, 56, 40,
+ 38, 45, 56, 88, 92, 45, 56, 242, 223, 248, 56, 45, 56, 242, 223, 248, 43,
+ 45, 56, 242, 228, 248, 43, 45, 56, 242, 228, 248, 56, 45, 56, 139, 240,
+ 3, 56, 77, 240, 3, 56, 139, 236, 240, 56, 77, 236, 240, 56, 226, 226, 65,
+ 2, 45, 108, 235, 45, 65, 2, 45, 108, 139, 240, 55, 56, 226, 226, 240, 55,
+ 56, 77, 240, 55, 56, 235, 45, 240, 55, 56, 139, 65, 153, 125, 77, 65,
+ 153, 125, 139, 64, 56, 226, 226, 64, 56, 77, 64, 56, 235, 45, 64, 56,
+ 226, 226, 64, 65, 248, 44, 125, 226, 226, 64, 65, 255, 34, 235, 133, 226,
+ 226, 64, 65, 255, 34, 237, 28, 2, 163, 125, 226, 226, 64, 65, 255, 34,
+ 237, 28, 2, 59, 125, 226, 226, 64, 45, 56, 226, 226, 64, 45, 65, 255, 34,
+ 235, 133, 77, 64, 65, 248, 44, 247, 192, 242, 223, 248, 56, 65, 153, 238,
+ 67, 242, 228, 248, 43, 65, 153, 238, 67, 88, 92, 64, 56, 38, 65, 2, 3,
+ 238, 51, 235, 45, 65, 139, 147, 226, 226, 56, 204, 77, 238, 104, 139, 65,
+ 2, 59, 108, 77, 65, 2, 59, 108, 40, 38, 65, 2, 59, 108, 139, 65, 2, 45,
+ 59, 108, 77, 65, 2, 45, 59, 108, 40, 38, 65, 2, 45, 59, 108, 139, 233,
+ 72, 56, 77, 233, 72, 56, 40, 38, 233, 72, 56, 28, 249, 26, 233, 124, 238,
+ 100, 231, 90, 244, 29, 239, 58, 244, 29, 248, 86, 161, 241, 100, 243, 15,
+ 249, 160, 234, 205, 240, 79, 238, 68, 253, 174, 161, 255, 68, 238, 68,
+ 253, 174, 3, 238, 68, 253, 174, 236, 180, 255, 24, 238, 145, 248, 86,
+ 161, 238, 131, 255, 24, 238, 145, 3, 236, 180, 255, 24, 238, 145, 253,
+ 165, 147, 242, 66, 242, 238, 236, 170, 242, 238, 234, 50, 242, 238, 234,
+ 65, 242, 250, 52, 231, 148, 52, 53, 243, 12, 236, 196, 240, 37, 254, 30,
+ 240, 68, 236, 219, 235, 47, 248, 51, 235, 47, 241, 41, 235, 47, 31, 243,
+ 119, 250, 169, 243, 119, 240, 137, 243, 119, 232, 199, 87, 235, 101, 38,
+ 240, 54, 240, 54, 236, 168, 240, 54, 235, 109, 240, 54, 237, 112, 248,
+ 86, 161, 238, 177, 236, 200, 87, 161, 236, 200, 87, 238, 56, 248, 91,
+ 238, 56, 253, 227, 231, 88, 240, 58, 235, 60, 45, 235, 60, 240, 3, 235,
+ 60, 238, 132, 235, 60, 239, 210, 235, 60, 242, 180, 235, 60, 235, 62,
+ 235, 60, 235, 62, 238, 132, 235, 60, 231, 86, 238, 132, 235, 60, 235, 33,
+ 237, 74, 242, 78, 233, 96, 53, 240, 68, 239, 57, 236, 31, 233, 96, 233,
+ 206, 242, 219, 235, 47, 224, 169, 236, 145, 251, 187, 193, 252, 178, 243,
+ 80, 242, 186, 236, 170, 161, 169, 242, 250, 169, 231, 45, 95, 87, 161,
+ 231, 45, 95, 87, 231, 89, 95, 87, 231, 89, 253, 230, 161, 236, 244, 95,
+ 87, 238, 79, 231, 89, 253, 192, 236, 244, 95, 87, 240, 40, 95, 87, 161,
+ 240, 40, 95, 87, 240, 40, 95, 128, 95, 87, 240, 3, 169, 254, 51, 95, 87,
+ 234, 5, 87, 231, 105, 234, 5, 87, 234, 111, 236, 248, 234, 92, 253, 145,
+ 241, 216, 231, 105, 95, 87, 231, 89, 95, 153, 128, 253, 145, 243, 11,
+ 253, 174, 243, 11, 147, 128, 231, 89, 95, 87, 243, 14, 238, 113, 240, 7,
+ 240, 24, 248, 51, 255, 22, 95, 87, 248, 51, 95, 87, 233, 128, 87, 234,
+ 187, 233, 198, 87, 248, 135, 238, 113, 243, 92, 95, 87, 95, 153, 255, 25,
+ 233, 130, 236, 168, 254, 82, 234, 243, 95, 87, 161, 95, 87, 235, 89, 87,
+ 161, 235, 89, 87, 238, 17, 234, 5, 87, 235, 44, 128, 95, 87, 232, 68,
+ 128, 95, 87, 235, 44, 248, 59, 95, 87, 232, 68, 248, 59, 95, 87, 235, 44,
+ 253, 230, 161, 95, 87, 232, 68, 253, 230, 161, 95, 87, 248, 168, 234, 3,
+ 248, 168, 231, 85, 236, 248, 161, 234, 5, 87, 161, 234, 3, 161, 231, 85,
+ 238, 79, 235, 44, 253, 192, 95, 87, 238, 79, 232, 68, 253, 192, 95, 87,
+ 235, 44, 128, 234, 5, 87, 232, 68, 128, 234, 5, 87, 238, 79, 235, 44,
+ 253, 192, 234, 5, 87, 238, 79, 232, 68, 253, 192, 234, 5, 87, 235, 44,
+ 128, 231, 85, 232, 68, 128, 234, 3, 238, 79, 235, 44, 253, 192, 231, 85,
+ 238, 79, 232, 68, 253, 192, 234, 3, 235, 107, 235, 111, 236, 176, 128,
+ 95, 87, 236, 178, 128, 95, 87, 236, 176, 128, 234, 5, 87, 236, 178, 128,
+ 234, 5, 87, 248, 86, 161, 237, 240, 248, 86, 161, 238, 19, 240, 26, 253,
+ 174, 236, 154, 253, 174, 161, 134, 240, 26, 253, 174, 161, 134, 236, 154,
+ 253, 174, 240, 26, 147, 128, 95, 87, 236, 154, 147, 128, 95, 87, 238, 79,
+ 134, 240, 26, 147, 253, 192, 95, 87, 238, 79, 134, 236, 154, 147, 253,
+ 192, 95, 87, 240, 26, 147, 2, 161, 95, 87, 236, 154, 147, 2, 161, 95, 87,
+ 236, 62, 237, 24, 231, 26, 237, 24, 240, 58, 31, 243, 11, 253, 174, 31,
+ 236, 209, 253, 174, 31, 243, 11, 147, 128, 95, 87, 31, 236, 209, 147,
+ 128, 95, 87, 31, 249, 38, 31, 249, 43, 29, 243, 12, 29, 240, 68, 29, 240,
+ 123, 29, 236, 196, 240, 37, 29, 53, 235, 47, 29, 248, 51, 235, 47, 29,
+ 236, 219, 235, 47, 29, 238, 113, 29, 242, 235, 238, 84, 243, 12, 238, 84,
+ 240, 68, 238, 84, 240, 123, 238, 84, 53, 235, 47, 38, 242, 234, 40, 242,
+ 234, 92, 242, 234, 88, 242, 234, 234, 94, 239, 139, 244, 38, 239, 78,
+ 240, 3, 59, 253, 144, 38, 234, 15, 45, 59, 253, 144, 45, 38, 234, 15,
+ 248, 86, 161, 242, 67, 161, 244, 38, 248, 86, 161, 241, 114, 238, 203,
+ 45, 59, 253, 144, 45, 38, 234, 15, 236, 176, 244, 44, 235, 92, 236, 178,
+ 244, 44, 235, 92, 240, 52, 236, 203, 253, 174, 236, 180, 255, 24, 240,
+ 52, 235, 144, 240, 52, 236, 203, 147, 128, 95, 87, 236, 180, 255, 24,
+ 240, 52, 236, 203, 128, 95, 87, 236, 209, 253, 174, 243, 11, 253, 174,
+ 235, 103, 236, 35, 235, 193, 239, 130, 232, 178, 253, 49, 246, 104, 252,
+ 34, 38, 185, 2, 248, 113, 38, 235, 46, 242, 238, 238, 56, 248, 91, 242,
+ 238, 238, 56, 253, 227, 242, 238, 231, 88, 242, 238, 240, 58, 238, 76,
+ 235, 47, 53, 235, 47, 248, 135, 235, 47, 236, 196, 240, 123, 238, 168,
+ 40, 240, 52, 240, 173, 234, 21, 236, 170, 38, 240, 52, 240, 173, 234, 21,
+ 236, 170, 40, 234, 21, 236, 170, 38, 234, 21, 236, 170, 224, 242, 219,
+ 238, 113, 242, 225, 238, 56, 253, 227, 242, 225, 238, 56, 248, 91, 45,
+ 238, 87, 45, 235, 84, 45, 231, 88, 45, 240, 58, 234, 234, 95, 19, 236,
+ 200, 87, 235, 44, 2, 248, 40, 232, 68, 2, 248, 40, 249, 194, 248, 168,
+ 234, 3, 249, 194, 248, 168, 231, 85, 235, 44, 95, 153, 128, 231, 85, 232,
+ 68, 95, 153, 128, 234, 3, 95, 153, 128, 234, 3, 95, 153, 128, 231, 85,
+ 95, 153, 128, 235, 107, 95, 153, 128, 235, 111, 248, 86, 161, 239, 165,
+ 128, 240, 32, 248, 86, 161, 239, 209, 128, 240, 32, 161, 31, 243, 11,
+ 147, 128, 95, 87, 161, 31, 236, 209, 147, 128, 95, 87, 31, 243, 11, 147,
+ 128, 161, 95, 87, 31, 236, 209, 147, 128, 161, 95, 87, 235, 44, 253, 230,
+ 161, 234, 5, 87, 232, 68, 253, 230, 161, 234, 5, 87, 236, 176, 253, 230,
+ 161, 234, 5, 87, 236, 178, 253, 230, 161, 234, 5, 87, 161, 240, 52, 236,
+ 203, 253, 174, 248, 86, 161, 238, 131, 255, 24, 240, 52, 235, 144, 161,
+ 240, 52, 236, 203, 147, 128, 95, 87, 248, 86, 161, 238, 131, 255, 24,
+ 240, 52, 236, 203, 128, 240, 32, 59, 235, 69, 239, 136, 163, 235, 69, 88,
+ 38, 236, 159, 235, 69, 92, 38, 236, 159, 235, 69, 238, 68, 147, 2, 183,
+ 163, 108, 238, 68, 147, 2, 59, 253, 144, 255, 31, 253, 165, 147, 163,
+ 108, 3, 238, 68, 147, 2, 59, 253, 144, 255, 31, 253, 165, 147, 163, 108,
+ 238, 68, 147, 2, 53, 48, 238, 68, 147, 2, 236, 163, 3, 238, 68, 147, 2,
+ 236, 163, 238, 68, 147, 2, 235, 50, 238, 68, 147, 2, 171, 163, 237, 45,
+ 236, 180, 2, 183, 163, 108, 236, 180, 2, 59, 253, 144, 255, 31, 253, 165,
+ 147, 163, 108, 3, 236, 180, 2, 59, 253, 144, 255, 31, 253, 165, 147, 163,
+ 108, 236, 180, 2, 236, 163, 3, 236, 180, 2, 236, 163, 255, 97, 126, 254,
+ 52, 233, 217, 237, 105, 52, 237, 149, 56, 241, 168, 88, 234, 7, 92, 234,
+ 7, 233, 226, 232, 193, 248, 103, 242, 224, 40, 236, 251, 38, 236, 251,
+ 40, 240, 175, 38, 240, 175, 240, 17, 38, 243, 55, 240, 17, 40, 243, 55,
+ 253, 159, 38, 243, 55, 253, 159, 40, 243, 55, 224, 161, 52, 31, 236, 231,
+ 248, 113, 238, 4, 239, 187, 235, 113, 236, 87, 237, 239, 234, 30, 238,
+ 42, 238, 59, 243, 245, 147, 237, 181, 52, 205, 161, 52, 240, 252, 234,
+ 39, 253, 159, 40, 238, 67, 253, 159, 38, 238, 67, 240, 17, 40, 238, 67,
+ 240, 17, 38, 238, 67, 253, 159, 137, 235, 60, 240, 17, 137, 235, 60, 241,
+ 118, 242, 118, 88, 235, 76, 239, 7, 171, 163, 244, 191, 242, 42, 251,
+ 145, 243, 169, 153, 253, 145, 225, 255, 113, 255, 22, 134, 236, 89, 248,
+ 92, 236, 45, 231, 87, 185, 104, 231, 36, 185, 104, 243, 169, 153, 253,
+ 145, 242, 220, 239, 6, 242, 233, 231, 121, 254, 51, 229, 64, 236, 125,
+ 247, 156, 239, 175, 235, 205, 239, 154, 239, 31, 242, 141, 242, 116, 232,
+ 124, 232, 125, 141, 142, 12, 239, 96, 141, 142, 12, 242, 127, 243, 43,
+ 141, 142, 12, 248, 62, 240, 32, 141, 142, 12, 248, 62, 238, 177, 141,
+ 142, 12, 248, 62, 236, 164, 141, 142, 12, 248, 62, 248, 115, 141, 142,
+ 12, 248, 62, 238, 51, 141, 142, 12, 218, 240, 103, 141, 142, 12, 218,
+ 248, 115, 141, 142, 12, 247, 94, 125, 141, 142, 12, 235, 177, 125, 141,
+ 142, 12, 248, 62, 240, 37, 141, 142, 12, 248, 62, 234, 25, 141, 142, 12,
+ 248, 62, 234, 3, 141, 142, 12, 248, 62, 231, 85, 141, 142, 12, 139, 243,
+ 79, 141, 142, 12, 77, 243, 79, 141, 142, 12, 248, 62, 139, 56, 141, 142,
+ 12, 248, 62, 77, 56, 141, 142, 12, 218, 234, 25, 141, 142, 12, 92, 248,
+ 84, 235, 50, 141, 142, 12, 243, 92, 240, 103, 141, 142, 12, 248, 62, 92,
+ 240, 130, 141, 142, 12, 248, 62, 240, 28, 141, 142, 12, 92, 248, 84, 248,
+ 115, 141, 142, 12, 226, 226, 243, 79, 141, 142, 12, 248, 62, 226, 226,
+ 56, 141, 142, 12, 88, 248, 84, 236, 163, 141, 142, 12, 254, 56, 240, 103,
+ 141, 142, 12, 248, 62, 88, 240, 130, 141, 142, 12, 248, 62, 250, 189,
+ 141, 142, 12, 88, 248, 84, 248, 115, 141, 142, 12, 235, 45, 243, 79, 141,
+ 142, 12, 248, 62, 235, 45, 56, 141, 142, 12, 243, 249, 235, 50, 141, 142,
+ 12, 243, 92, 235, 50, 141, 142, 12, 238, 76, 235, 50, 141, 142, 12, 254,
+ 104, 235, 50, 141, 142, 12, 218, 235, 50, 141, 142, 12, 88, 248, 247,
+ 248, 115, 141, 142, 12, 243, 249, 243, 43, 141, 142, 12, 218, 242, 229,
+ 141, 142, 12, 248, 62, 240, 24, 141, 142, 12, 88, 248, 84, 175, 141, 142,
+ 12, 254, 56, 175, 141, 142, 12, 248, 135, 175, 141, 142, 12, 254, 104,
+ 175, 141, 142, 12, 218, 175, 141, 142, 12, 92, 248, 247, 240, 103, 141,
+ 142, 12, 40, 248, 247, 240, 103, 141, 142, 12, 242, 219, 175, 141, 142,
+ 12, 232, 68, 175, 141, 142, 12, 242, 244, 125, 141, 142, 12, 254, 56,
+ 169, 141, 142, 12, 242, 207, 141, 142, 12, 247, 122, 169, 141, 142, 12,
+ 236, 99, 235, 50, 141, 142, 12, 248, 62, 161, 240, 32, 141, 142, 12, 248,
+ 62, 236, 85, 141, 142, 12, 92, 243, 25, 169, 141, 142, 12, 88, 243, 25,
+ 169, 141, 142, 12, 242, 237, 141, 142, 12, 248, 73, 141, 142, 12, 240,
+ 20, 141, 142, 12, 194, 235, 50, 141, 142, 12, 238, 57, 235, 50, 141, 142,
+ 12, 248, 42, 235, 50, 141, 142, 12, 211, 235, 50, 141, 142, 12, 240, 22,
+ 161, 243, 53, 69, 38, 185, 2, 235, 45, 240, 126, 56, 235, 0, 248, 35,
+ 248, 92, 250, 114, 91, 59, 248, 41, 2, 240, 1, 248, 40, 235, 128, 91,
+ 234, 104, 235, 157, 91, 231, 128, 235, 157, 91, 237, 8, 91, 233, 126, 91,
+ 64, 31, 2, 240, 46, 59, 242, 224, 245, 82, 91, 233, 68, 254, 105, 91,
+ 251, 51, 91, 29, 163, 253, 144, 2, 242, 23, 29, 236, 152, 242, 236, 240,
+ 129, 218, 2, 236, 64, 56, 252, 252, 91, 234, 224, 91, 234, 201, 91, 226,
+ 236, 241, 143, 91, 226, 236, 241, 209, 91, 226, 227, 91, 226, 230, 91,
+ 240, 169, 239, 33, 12, 248, 38, 111, 227, 7, 91, 141, 142, 12, 243, 43,
+ 238, 176, 235, 95, 254, 105, 91, 237, 242, 243, 240, 252, 16, 243, 240,
+ 246, 254, 240, 218, 91, 245, 23, 240, 218, 91, 40, 233, 56, 189, 90, 40,
+ 233, 56, 234, 10, 40, 233, 56, 168, 90, 38, 233, 56, 189, 90, 38, 233,
+ 56, 234, 10, 38, 233, 56, 168, 90, 40, 31, 238, 52, 189, 238, 67, 40, 31,
+ 238, 52, 234, 10, 40, 31, 238, 52, 168, 238, 67, 38, 31, 238, 52, 189,
+ 238, 67, 38, 31, 238, 52, 234, 10, 38, 31, 238, 52, 168, 238, 67, 40,
+ 242, 225, 238, 52, 189, 90, 40, 242, 225, 238, 52, 240, 1, 240, 119, 40,
+ 242, 225, 238, 52, 168, 90, 242, 225, 238, 52, 234, 10, 38, 242, 225,
+ 238, 52, 189, 90, 38, 242, 225, 238, 52, 240, 1, 240, 119, 38, 242, 225,
+ 238, 52, 168, 90, 236, 167, 234, 10, 163, 248, 41, 234, 10, 189, 40, 128,
+ 168, 38, 242, 225, 238, 52, 236, 210, 189, 38, 128, 168, 40, 242, 225,
+ 238, 52, 236, 210, 235, 112, 249, 3, 235, 112, 238, 128, 253, 159, 31,
+ 104, 240, 17, 31, 104, 240, 17, 31, 238, 52, 248, 59, 253, 159, 31, 104,
+ 25, 12, 238, 128, 40, 59, 66, 242, 224, 38, 59, 66, 242, 224, 163, 248,
+ 183, 239, 119, 163, 248, 183, 239, 120, 163, 248, 183, 239, 121, 163,
+ 248, 183, 239, 122, 235, 58, 12, 136, 59, 19, 253, 159, 225, 235, 58, 12,
+ 136, 59, 19, 240, 17, 225, 235, 58, 12, 136, 59, 2, 238, 51, 235, 58, 12,
+ 136, 92, 19, 163, 2, 238, 51, 235, 58, 12, 136, 88, 19, 163, 2, 238, 51,
+ 235, 58, 12, 136, 59, 2, 235, 46, 235, 58, 12, 136, 92, 19, 163, 2, 235,
+ 46, 235, 58, 12, 136, 88, 19, 163, 2, 235, 46, 235, 58, 12, 136, 59, 19,
+ 243, 80, 235, 58, 12, 136, 92, 19, 163, 2, 243, 80, 235, 58, 12, 136, 88,
+ 19, 163, 2, 243, 80, 235, 58, 12, 136, 92, 19, 233, 50, 235, 58, 12, 136,
+ 88, 19, 233, 50, 235, 58, 12, 136, 59, 19, 253, 159, 242, 220, 235, 58,
+ 12, 136, 59, 19, 240, 17, 242, 220, 31, 243, 94, 242, 80, 91, 245, 81,
+ 91, 59, 248, 41, 234, 10, 236, 183, 239, 255, 236, 183, 183, 248, 59,
+ 242, 108, 236, 183, 242, 215, 248, 59, 243, 66, 236, 183, 183, 248, 59,
+ 171, 239, 194, 236, 183, 171, 240, 228, 248, 59, 243, 66, 236, 183, 171,
+ 240, 228, 239, 103, 236, 183, 237, 49, 236, 183, 234, 82, 236, 183, 234,
+ 62, 243, 168, 239, 85, 245, 94, 12, 28, 246, 193, 12, 28, 243, 124, 147,
+ 237, 173, 12, 28, 243, 124, 147, 244, 28, 12, 28, 253, 165, 147, 244, 28,
+ 12, 28, 253, 165, 147, 232, 62, 12, 28, 237, 150, 12, 28, 232, 103, 12,
+ 28, 244, 215, 12, 28, 234, 96, 12, 28, 163, 233, 107, 12, 28, 248, 41,
+ 243, 171, 12, 28, 59, 233, 107, 12, 28, 248, 38, 243, 171, 12, 28, 237,
+ 84, 238, 211, 12, 28, 244, 11, 248, 235, 12, 28, 244, 11, 253, 247, 12,
+ 28, 250, 185, 251, 197, 238, 183, 12, 28, 240, 113, 238, 110, 127, 12,
+ 28, 240, 113, 238, 110, 111, 12, 28, 240, 113, 238, 110, 166, 12, 28,
+ 240, 113, 238, 110, 177, 12, 28, 236, 146, 232, 103, 12, 28, 233, 250,
+ 245, 224, 12, 28, 253, 165, 147, 233, 44, 240, 13, 12, 28, 239, 16, 12,
+ 28, 253, 165, 147, 239, 132, 12, 28, 233, 249, 12, 28, 238, 183, 12, 28,
+ 250, 244, 234, 6, 12, 28, 245, 128, 234, 6, 12, 28, 242, 79, 234, 6, 12,
+ 28, 252, 253, 234, 6, 12, 28, 240, 15, 12, 28, 239, 39, 244, 224, 91,
+ 248, 35, 248, 92, 12, 28, 237, 219, 12, 28, 241, 81, 248, 38, 111, 12,
+ 28, 235, 5, 248, 38, 111, 253, 207, 90, 253, 207, 241, 50, 253, 207, 243,
+ 175, 253, 207, 236, 145, 243, 175, 253, 207, 250, 115, 239, 15, 253, 207,
+ 254, 146, 248, 139, 253, 207, 241, 36, 250, 102, 229, 67, 253, 207, 241,
+ 9, 147, 240, 162, 253, 207, 242, 235, 253, 207, 237, 97, 238, 158, 239,
+ 147, 253, 207, 45, 234, 25, 29, 26, 127, 29, 26, 111, 29, 26, 166, 29,
+ 26, 177, 29, 26, 176, 29, 26, 187, 29, 26, 203, 29, 26, 195, 29, 26, 202,
+ 29, 61, 248, 53, 29, 61, 238, 91, 29, 61, 238, 97, 29, 61, 235, 85, 29,
+ 61, 235, 82, 29, 61, 236, 207, 29, 61, 236, 202, 29, 61, 234, 22, 29, 61,
+ 235, 81, 29, 61, 235, 83, 29, 61, 238, 77, 82, 26, 127, 82, 26, 111, 82,
+ 26, 166, 82, 26, 177, 82, 26, 176, 82, 26, 187, 82, 26, 203, 82, 26, 195,
+ 82, 26, 202, 82, 61, 248, 53, 82, 61, 238, 91, 82, 61, 238, 97, 82, 61,
+ 235, 85, 82, 61, 235, 82, 82, 61, 236, 207, 82, 61, 236, 202, 82, 61,
+ 234, 22, 82, 61, 235, 81, 82, 61, 235, 83, 82, 61, 238, 77, 26, 253, 125,
+ 248, 37, 208, 26, 171, 248, 37, 208, 26, 204, 248, 37, 208, 26, 248, 58,
+ 248, 37, 208, 26, 248, 48, 248, 37, 208, 26, 254, 31, 248, 37, 208, 26,
+ 243, 31, 248, 37, 208, 26, 242, 254, 248, 37, 208, 26, 248, 173, 248, 37,
+ 208, 61, 253, 219, 248, 37, 208, 61, 241, 93, 248, 37, 208, 61, 240, 251,
+ 248, 37, 208, 61, 238, 26, 248, 37, 208, 61, 237, 161, 248, 37, 208, 61,
+ 239, 70, 248, 37, 208, 61, 238, 216, 248, 37, 208, 61, 236, 100, 248, 37,
+ 208, 61, 237, 147, 248, 37, 208, 61, 237, 222, 248, 37, 208, 61, 240, 48,
+ 248, 37, 208, 82, 8, 3, 1, 67, 82, 8, 3, 1, 217, 82, 8, 3, 1, 255, 18,
+ 82, 8, 3, 1, 209, 82, 8, 3, 1, 72, 82, 8, 3, 1, 255, 19, 82, 8, 3, 1,
+ 210, 82, 8, 3, 1, 192, 82, 8, 3, 1, 71, 82, 8, 3, 1, 221, 82, 8, 3, 1,
+ 255, 15, 82, 8, 3, 1, 162, 82, 8, 3, 1, 173, 82, 8, 3, 1, 197, 82, 8, 3,
+ 1, 73, 82, 8, 3, 1, 223, 82, 8, 3, 1, 255, 20, 82, 8, 3, 1, 144, 82, 8,
+ 3, 1, 193, 82, 8, 3, 1, 214, 82, 8, 3, 1, 79, 82, 8, 3, 1, 179, 82, 8, 3,
+ 1, 255, 16, 82, 8, 3, 1, 206, 82, 8, 3, 1, 255, 14, 82, 8, 3, 1, 255, 17,
+ 29, 8, 5, 1, 67, 29, 8, 5, 1, 217, 29, 8, 5, 1, 255, 18, 29, 8, 5, 1,
+ 209, 29, 8, 5, 1, 72, 29, 8, 5, 1, 255, 19, 29, 8, 5, 1, 210, 29, 8, 5,
+ 1, 192, 29, 8, 5, 1, 71, 29, 8, 5, 1, 221, 29, 8, 5, 1, 255, 15, 29, 8,
+ 5, 1, 162, 29, 8, 5, 1, 173, 29, 8, 5, 1, 197, 29, 8, 5, 1, 73, 29, 8, 5,
+ 1, 223, 29, 8, 5, 1, 255, 20, 29, 8, 5, 1, 144, 29, 8, 5, 1, 193, 29, 8,
+ 5, 1, 214, 29, 8, 5, 1, 79, 29, 8, 5, 1, 179, 29, 8, 5, 1, 255, 16, 29,
+ 8, 5, 1, 206, 29, 8, 5, 1, 255, 14, 29, 8, 5, 1, 255, 17, 29, 8, 3, 1,
+ 67, 29, 8, 3, 1, 217, 29, 8, 3, 1, 255, 18, 29, 8, 3, 1, 209, 29, 8, 3,
+ 1, 72, 29, 8, 3, 1, 255, 19, 29, 8, 3, 1, 210, 29, 8, 3, 1, 192, 29, 8,
+ 3, 1, 71, 29, 8, 3, 1, 221, 29, 8, 3, 1, 255, 15, 29, 8, 3, 1, 162, 29,
+ 8, 3, 1, 173, 29, 8, 3, 1, 197, 29, 8, 3, 1, 73, 29, 8, 3, 1, 223, 29, 8,
+ 3, 1, 255, 20, 29, 8, 3, 1, 144, 29, 8, 3, 1, 193, 29, 8, 3, 1, 214, 29,
+ 8, 3, 1, 79, 29, 8, 3, 1, 179, 29, 8, 3, 1, 255, 16, 29, 8, 3, 1, 206,
+ 29, 8, 3, 1, 255, 14, 29, 8, 3, 1, 255, 17, 29, 26, 242, 217, 236, 146,
+ 29, 61, 238, 91, 236, 146, 29, 61, 238, 97, 236, 146, 29, 61, 235, 85,
+ 236, 146, 29, 61, 235, 82, 236, 146, 29, 61, 236, 207, 236, 146, 29, 61,
+ 236, 202, 236, 146, 29, 61, 234, 22, 236, 146, 29, 61, 235, 81, 236, 146,
+ 29, 61, 235, 83, 236, 146, 29, 61, 238, 77, 45, 29, 26, 127, 45, 29, 26,
+ 111, 45, 29, 26, 166, 45, 29, 26, 177, 45, 29, 26, 176, 45, 29, 26, 187,
+ 45, 29, 26, 203, 45, 29, 26, 195, 45, 29, 26, 202, 45, 29, 61, 248, 53,
+ 236, 146, 29, 26, 242, 217, 66, 70, 136, 233, 50, 66, 70, 96, 233, 50,
+ 66, 70, 136, 235, 63, 66, 70, 96, 235, 63, 66, 70, 136, 240, 3, 248, 63,
+ 233, 50, 66, 70, 96, 240, 3, 248, 63, 233, 50, 66, 70, 136, 240, 3, 248,
+ 63, 235, 63, 66, 70, 96, 240, 3, 248, 63, 235, 63, 66, 70, 136, 235, 71,
+ 248, 63, 233, 50, 66, 70, 96, 235, 71, 248, 63, 233, 50, 66, 70, 136,
+ 235, 71, 248, 63, 235, 63, 66, 70, 96, 235, 71, 248, 63, 235, 63, 66, 70,
+ 136, 92, 19, 225, 66, 70, 92, 136, 19, 38, 240, 11, 66, 70, 92, 96, 19,
+ 38, 240, 9, 66, 70, 96, 92, 19, 225, 66, 70, 136, 92, 19, 242, 220, 66,
+ 70, 92, 136, 19, 40, 240, 11, 66, 70, 92, 96, 19, 40, 240, 9, 66, 70, 96,
+ 92, 19, 242, 220, 66, 70, 136, 88, 19, 225, 66, 70, 88, 136, 19, 38, 240,
+ 11, 66, 70, 88, 96, 19, 38, 240, 9, 66, 70, 96, 88, 19, 225, 66, 70, 136,
+ 88, 19, 242, 220, 66, 70, 88, 136, 19, 40, 240, 11, 66, 70, 88, 96, 19,
+ 40, 240, 9, 66, 70, 96, 88, 19, 242, 220, 66, 70, 136, 59, 19, 225, 66,
+ 70, 59, 136, 19, 38, 240, 11, 66, 70, 88, 96, 19, 38, 92, 240, 9, 66, 70,
+ 92, 96, 19, 38, 88, 240, 9, 66, 70, 59, 96, 19, 38, 240, 9, 66, 70, 92,
+ 136, 19, 38, 88, 240, 11, 66, 70, 88, 136, 19, 38, 92, 240, 11, 66, 70,
+ 96, 59, 19, 225, 66, 70, 136, 59, 19, 242, 220, 66, 70, 59, 136, 19, 40,
+ 240, 11, 66, 70, 88, 96, 19, 40, 92, 240, 9, 66, 70, 92, 96, 19, 40, 88,
+ 240, 9, 66, 70, 59, 96, 19, 40, 240, 9, 66, 70, 92, 136, 19, 40, 88, 240,
+ 11, 66, 70, 88, 136, 19, 40, 92, 240, 11, 66, 70, 96, 59, 19, 242, 220,
+ 66, 70, 136, 92, 19, 233, 50, 66, 70, 40, 96, 19, 38, 92, 240, 9, 66, 70,
+ 38, 96, 19, 40, 92, 240, 9, 66, 70, 92, 136, 19, 163, 240, 11, 66, 70,
+ 92, 96, 19, 163, 240, 9, 66, 70, 38, 136, 19, 40, 92, 240, 11, 66, 70,
+ 40, 136, 19, 38, 92, 240, 11, 66, 70, 96, 92, 19, 233, 50, 66, 70, 136,
+ 88, 19, 233, 50, 66, 70, 40, 96, 19, 38, 88, 240, 9, 66, 70, 38, 96, 19,
+ 40, 88, 240, 9, 66, 70, 88, 136, 19, 163, 240, 11, 66, 70, 88, 96, 19,
+ 163, 240, 9, 66, 70, 38, 136, 19, 40, 88, 240, 11, 66, 70, 40, 136, 19,
+ 38, 88, 240, 11, 66, 70, 96, 88, 19, 233, 50, 66, 70, 136, 59, 19, 233,
+ 50, 66, 70, 40, 96, 19, 38, 59, 240, 9, 66, 70, 38, 96, 19, 40, 59, 240,
+ 9, 66, 70, 59, 136, 19, 163, 240, 11, 66, 70, 88, 96, 19, 92, 163, 240,
+ 9, 66, 70, 92, 96, 19, 88, 163, 240, 9, 66, 70, 59, 96, 19, 163, 240, 9,
+ 66, 70, 40, 88, 96, 19, 38, 92, 240, 9, 66, 70, 38, 88, 96, 19, 40, 92,
+ 240, 9, 66, 70, 40, 92, 96, 19, 38, 88, 240, 9, 66, 70, 38, 92, 96, 19,
+ 40, 88, 240, 9, 66, 70, 92, 136, 19, 88, 163, 240, 11, 66, 70, 88, 136,
+ 19, 92, 163, 240, 11, 66, 70, 38, 136, 19, 40, 59, 240, 11, 66, 70, 40,
+ 136, 19, 38, 59, 240, 11, 66, 70, 96, 59, 19, 233, 50, 66, 70, 136, 45,
+ 248, 63, 233, 50, 66, 70, 96, 45, 248, 63, 233, 50, 66, 70, 136, 45, 248,
+ 63, 235, 63, 66, 70, 96, 45, 248, 63, 235, 63, 66, 70, 45, 233, 50, 66,
+ 70, 45, 235, 63, 66, 70, 92, 240, 12, 19, 38, 238, 78, 66, 70, 92, 45,
+ 19, 38, 238, 82, 66, 70, 45, 92, 19, 225, 66, 70, 92, 240, 12, 19, 40,
+ 238, 78, 66, 70, 92, 45, 19, 40, 238, 82, 66, 70, 45, 92, 19, 242, 220,
+ 66, 70, 88, 240, 12, 19, 38, 238, 78, 66, 70, 88, 45, 19, 38, 238, 82,
+ 66, 70, 45, 88, 19, 225, 66, 70, 88, 240, 12, 19, 40, 238, 78, 66, 70,
+ 88, 45, 19, 40, 238, 82, 66, 70, 45, 88, 19, 242, 220, 66, 70, 59, 240,
+ 12, 19, 38, 238, 78, 66, 70, 59, 45, 19, 38, 238, 82, 66, 70, 45, 59, 19,
+ 225, 66, 70, 59, 240, 12, 19, 40, 238, 78, 66, 70, 59, 45, 19, 40, 238,
+ 82, 66, 70, 45, 59, 19, 242, 220, 66, 70, 92, 240, 12, 19, 163, 238, 78,
+ 66, 70, 92, 45, 19, 163, 238, 82, 66, 70, 45, 92, 19, 233, 50, 66, 70,
+ 88, 240, 12, 19, 163, 238, 78, 66, 70, 88, 45, 19, 163, 238, 82, 66, 70,
+ 45, 88, 19, 233, 50, 66, 70, 59, 240, 12, 19, 163, 238, 78, 66, 70, 59,
+ 45, 19, 163, 238, 82, 66, 70, 45, 59, 19, 233, 50, 66, 70, 136, 253, 183,
+ 92, 19, 225, 66, 70, 136, 253, 183, 92, 19, 242, 220, 66, 70, 136, 253,
+ 183, 88, 19, 242, 220, 66, 70, 136, 253, 183, 88, 19, 225, 66, 70, 136,
+ 236, 159, 189, 38, 153, 168, 242, 220, 66, 70, 136, 236, 159, 189, 40,
+ 153, 168, 225, 66, 70, 136, 236, 159, 240, 34, 66, 70, 136, 242, 220, 66,
+ 70, 136, 253, 176, 66, 70, 136, 225, 66, 70, 136, 242, 236, 66, 70, 96,
+ 242, 220, 66, 70, 96, 253, 176, 66, 70, 96, 225, 66, 70, 96, 242, 236,
+ 66, 70, 136, 40, 19, 96, 225, 66, 70, 136, 88, 19, 96, 242, 236, 66, 70,
+ 96, 40, 19, 136, 225, 66, 70, 96, 88, 19, 136, 242, 236, 189, 137, 240,
+ 13, 168, 253, 125, 240, 62, 240, 13, 168, 253, 125, 238, 80, 240, 13,
+ 168, 204, 238, 98, 240, 13, 168, 137, 240, 13, 168, 248, 48, 238, 98,
+ 240, 13, 168, 204, 236, 236, 240, 13, 168, 243, 31, 238, 98, 240, 13,
+ 248, 37, 240, 13, 40, 243, 31, 238, 98, 240, 13, 40, 204, 236, 236, 240,
+ 13, 40, 248, 48, 238, 98, 240, 13, 40, 137, 240, 13, 40, 204, 238, 98,
+ 240, 13, 40, 253, 125, 238, 80, 240, 13, 40, 253, 125, 240, 62, 240, 13,
+ 38, 137, 240, 13, 136, 240, 146, 240, 19, 240, 146, 250, 183, 240, 146,
+ 189, 253, 125, 240, 62, 240, 13, 38, 253, 125, 240, 62, 240, 13, 236,
+ 158, 168, 242, 220, 236, 158, 168, 225, 236, 158, 189, 242, 220, 236,
+ 158, 189, 40, 19, 168, 40, 19, 168, 225, 236, 158, 189, 40, 19, 168, 225,
+ 236, 158, 189, 40, 19, 189, 38, 19, 168, 242, 220, 236, 158, 189, 40, 19,
+ 189, 38, 19, 168, 225, 236, 158, 189, 225, 236, 158, 189, 38, 19, 168,
+ 242, 220, 236, 158, 189, 38, 19, 168, 40, 19, 168, 225, 86, 238, 59, 64,
+ 238, 59, 64, 31, 2, 238, 121, 237, 0, 64, 31, 234, 34, 86, 3, 238, 59,
+ 31, 2, 163, 243, 19, 31, 2, 59, 243, 19, 31, 2, 234, 230, 234, 51, 243,
+ 19, 31, 2, 189, 40, 153, 168, 38, 243, 19, 31, 2, 189, 38, 153, 168, 40,
+ 243, 19, 31, 2, 236, 159, 234, 51, 243, 19, 86, 3, 238, 59, 64, 3, 238,
+ 59, 86, 234, 31, 64, 234, 31, 86, 59, 234, 31, 64, 59, 234, 31, 86, 231,
+ 48, 64, 231, 48, 86, 233, 60, 235, 46, 64, 233, 60, 235, 46, 86, 233, 60,
+ 3, 235, 46, 64, 233, 60, 3, 235, 46, 86, 231, 36, 235, 46, 64, 231, 36,
+ 235, 46, 86, 231, 36, 3, 235, 46, 64, 231, 36, 3, 235, 46, 86, 231, 36,
+ 236, 217, 64, 231, 36, 236, 217, 86, 231, 91, 235, 46, 64, 231, 91, 235,
+ 46, 86, 231, 91, 3, 235, 46, 64, 231, 91, 3, 235, 46, 86, 231, 87, 235,
+ 46, 64, 231, 87, 235, 46, 86, 231, 87, 3, 235, 46, 64, 231, 87, 3, 235,
+ 46, 86, 231, 87, 236, 217, 64, 231, 87, 236, 217, 86, 236, 164, 64, 236,
+ 164, 64, 238, 76, 234, 34, 86, 3, 236, 164, 237, 157, 236, 231, 64, 238,
+ 51, 240, 4, 238, 51, 218, 2, 59, 243, 19, 235, 183, 86, 238, 51, 218, 2,
+ 40, 137, 240, 0, 218, 2, 38, 137, 240, 0, 218, 2, 168, 137, 240, 0, 218,
+ 2, 189, 137, 240, 0, 218, 2, 189, 38, 236, 158, 240, 0, 218, 2, 254, 51,
+ 253, 230, 189, 40, 236, 158, 240, 0, 40, 137, 86, 238, 51, 38, 137, 86,
+ 238, 51, 238, 116, 238, 69, 238, 116, 64, 238, 51, 189, 137, 238, 116,
+ 64, 238, 51, 168, 137, 238, 116, 64, 238, 51, 189, 40, 236, 158, 236,
+ 211, 248, 113, 189, 38, 236, 158, 236, 211, 248, 113, 168, 38, 236, 158,
+ 236, 211, 248, 113, 168, 40, 236, 158, 236, 211, 248, 113, 189, 137, 238,
+ 51, 168, 137, 238, 51, 86, 168, 38, 235, 46, 86, 168, 40, 235, 46, 86,
+ 189, 40, 235, 46, 86, 189, 38, 235, 46, 64, 238, 69, 31, 2, 40, 137, 240,
+ 0, 31, 2, 38, 137, 240, 0, 31, 2, 189, 40, 236, 159, 137, 240, 0, 31, 2,
+ 168, 38, 236, 159, 137, 240, 0, 64, 31, 2, 59, 235, 180, 242, 224, 64,
+ 233, 60, 236, 152, 2, 248, 40, 233, 60, 236, 152, 2, 40, 137, 240, 0,
+ 233, 60, 236, 152, 2, 38, 137, 240, 0, 243, 22, 238, 51, 64, 31, 2, 189,
+ 40, 235, 70, 64, 31, 2, 168, 40, 235, 70, 64, 31, 2, 168, 38, 235, 70,
+ 64, 31, 2, 189, 38, 235, 70, 64, 218, 2, 189, 40, 235, 70, 64, 218, 2,
+ 168, 40, 235, 70, 64, 218, 2, 168, 38, 235, 70, 64, 218, 2, 189, 38, 235,
+ 70, 189, 40, 235, 46, 189, 38, 235, 46, 168, 40, 235, 46, 64, 240, 19,
+ 238, 59, 86, 240, 19, 238, 59, 64, 240, 19, 3, 238, 59, 86, 240, 19, 3,
+ 238, 59, 168, 38, 235, 46, 86, 254, 126, 2, 243, 251, 241, 61, 236, 135,
+ 238, 9, 241, 64, 86, 242, 229, 64, 242, 229, 234, 219, 232, 60, 248, 136,
+ 235, 172, 243, 235, 234, 110, 243, 235, 232, 120, 233, 73, 86, 234, 81,
+ 64, 234, 81, 240, 91, 248, 92, 240, 91, 66, 2, 240, 162, 240, 91, 66, 2,
+ 206, 237, 255, 238, 38, 2, 252, 128, 241, 90, 254, 96, 235, 178, 64, 244,
+ 12, 240, 119, 86, 244, 12, 240, 119, 236, 101, 224, 238, 120, 240, 135,
+ 243, 16, 238, 69, 86, 40, 236, 150, 240, 76, 86, 38, 236, 150, 240, 76,
+ 64, 40, 236, 150, 240, 76, 64, 88, 236, 150, 240, 76, 64, 38, 236, 150,
+ 240, 76, 64, 92, 236, 150, 240, 76, 247, 92, 19, 233, 129, 239, 19, 52,
+ 233, 227, 52, 235, 179, 52, 235, 185, 244, 81, 237, 228, 240, 34, 254,
+ 83, 248, 73, 243, 38, 147, 236, 53, 243, 38, 147, 234, 210, 248, 135, 19,
+ 235, 196, 243, 26, 91, 254, 139, 239, 192, 240, 185, 19, 239, 196, 246,
+ 239, 91, 254, 15, 243, 50, 238, 89, 28, 238, 139, 238, 89, 28, 243, 213,
+ 238, 89, 28, 243, 27, 238, 89, 28, 237, 48, 238, 89, 28, 243, 82, 238,
+ 89, 28, 240, 105, 238, 89, 28, 235, 102, 238, 89, 28, 240, 49, 247, 195,
+ 147, 239, 42, 64, 237, 162, 243, 39, 64, 238, 219, 243, 39, 86, 238, 219,
+ 243, 39, 64, 254, 126, 2, 243, 251, 243, 41, 238, 80, 243, 30, 251, 184,
+ 238, 80, 243, 30, 237, 208, 240, 96, 52, 240, 49, 248, 95, 52, 237, 185,
+ 239, 180, 239, 236, 237, 218, 242, 62, 241, 15, 239, 215, 239, 81, 239,
+ 17, 251, 188, 242, 179, 241, 215, 236, 98, 232, 203, 234, 99, 235, 167,
+ 239, 163, 64, 242, 252, 243, 208, 64, 242, 252, 240, 213, 64, 242, 252,
+ 244, 0, 64, 242, 252, 238, 167, 64, 242, 252, 238, 196, 64, 242, 252,
+ 243, 241, 86, 242, 252, 243, 208, 86, 242, 252, 240, 213, 86, 242, 252,
+ 244, 0, 86, 242, 252, 238, 167, 86, 242, 252, 238, 196, 86, 242, 252,
+ 243, 241, 86, 244, 22, 243, 17, 64, 243, 16, 243, 17, 64, 238, 76, 243,
+ 17, 86, 249, 41, 243, 17, 64, 244, 22, 243, 17, 86, 243, 16, 243, 17, 86,
+ 238, 76, 243, 17, 64, 249, 41, 243, 17, 254, 96, 238, 11, 238, 80, 243,
+ 9, 240, 62, 243, 9, 240, 157, 240, 62, 240, 203, 240, 157, 235, 108, 240,
+ 203, 243, 108, 248, 209, 52, 243, 108, 238, 146, 52, 243, 108, 243, 74,
+ 52, 248, 56, 129, 240, 34, 248, 43, 129, 240, 34, 235, 159, 235, 65, 91,
+ 235, 65, 12, 28, 242, 164, 235, 75, 235, 65, 12, 28, 242, 165, 235, 75,
+ 235, 65, 12, 28, 242, 166, 235, 75, 235, 65, 12, 28, 242, 167, 235, 75,
+ 235, 65, 12, 28, 242, 168, 235, 75, 235, 65, 12, 28, 242, 169, 235, 75,
+ 235, 65, 12, 28, 242, 170, 235, 75, 235, 65, 12, 28, 239, 82, 234, 221,
+ 86, 235, 159, 235, 65, 91, 237, 249, 243, 113, 91, 226, 250, 243, 113,
+ 91, 236, 74, 243, 113, 52, 235, 41, 91, 254, 2, 239, 60, 254, 2, 239, 61,
+ 254, 2, 239, 62, 254, 2, 239, 63, 254, 2, 239, 64, 254, 2, 239, 65, 64,
+ 218, 2, 53, 225, 64, 218, 2, 171, 243, 5, 86, 218, 2, 64, 53, 225, 86,
+ 218, 2, 171, 64, 243, 5, 236, 184, 28, 243, 50, 236, 184, 28, 249, 23,
+ 240, 56, 28, 238, 188, 243, 50, 240, 56, 28, 240, 198, 249, 23, 240, 56,
+ 28, 240, 198, 243, 50, 240, 56, 28, 238, 188, 249, 23, 64, 243, 173, 86,
+ 243, 173, 240, 185, 19, 246, 248, 238, 159, 238, 133, 239, 211, 244, 24,
+ 147, 232, 113, 239, 181, 237, 58, 239, 77, 245, 98, 244, 24, 147, 239,
+ 92, 249, 242, 91, 231, 138, 239, 246, 52, 200, 239, 245, 52, 238, 179,
+ 240, 96, 52, 238, 179, 248, 95, 52, 233, 212, 240, 96, 19, 248, 95, 52,
+ 248, 95, 19, 240, 96, 52, 248, 95, 2, 240, 5, 52, 248, 95, 2, 240, 5, 19,
+ 248, 95, 19, 240, 96, 52, 59, 248, 95, 2, 240, 5, 52, 163, 248, 95, 2,
+ 240, 5, 52, 240, 19, 64, 238, 51, 240, 19, 86, 238, 51, 240, 19, 3, 64,
+ 238, 51, 237, 202, 91, 239, 45, 91, 236, 137, 233, 94, 91, 239, 30, 239,
+ 79, 253, 3, 189, 243, 148, 235, 93, 86, 235, 93, 168, 243, 148, 235, 93,
+ 64, 235, 93, 235, 113, 237, 195, 52, 252, 210, 241, 89, 235, 162, 236,
+ 12, 239, 242, 243, 59, 239, 249, 243, 59, 168, 38, 238, 148, 238, 148,
+ 189, 38, 238, 148, 64, 249, 120, 86, 249, 120, 243, 53, 69, 96, 243, 53,
+ 69, 231, 37, 206, 96, 231, 37, 206, 240, 91, 206, 96, 240, 91, 206, 236,
+ 199, 17, 240, 34, 96, 17, 240, 34, 248, 35, 240, 46, 240, 34, 96, 248,
+ 35, 240, 46, 240, 34, 8, 240, 34, 236, 189, 64, 8, 240, 34, 236, 199, 8,
+ 240, 34, 239, 126, 240, 34, 248, 135, 147, 241, 74, 248, 58, 229, 58,
+ 235, 52, 248, 58, 231, 39, 235, 52, 96, 248, 58, 231, 39, 235, 52, 248,
+ 58, 233, 123, 235, 52, 86, 248, 58, 238, 74, 242, 229, 64, 248, 58, 238,
+ 74, 242, 229, 240, 148, 236, 199, 64, 242, 229, 29, 64, 242, 229, 248,
+ 35, 240, 46, 86, 242, 229, 86, 240, 46, 64, 242, 229, 236, 199, 86, 242,
+ 229, 96, 236, 199, 86, 242, 229, 236, 235, 242, 229, 236, 189, 64, 242,
+ 229, 96, 235, 52, 248, 35, 240, 46, 235, 52, 242, 254, 242, 124, 235, 52,
+ 242, 254, 238, 74, 86, 242, 229, 242, 254, 238, 74, 236, 235, 242, 229,
+ 254, 31, 238, 74, 86, 242, 229, 242, 254, 238, 74, 233, 98, 86, 242, 229,
+ 96, 242, 254, 238, 74, 233, 98, 86, 242, 229, 240, 251, 238, 74, 86, 242,
+ 229, 238, 216, 238, 74, 235, 52, 229, 58, 235, 52, 248, 35, 240, 46, 229,
+ 58, 235, 52, 96, 229, 58, 235, 52, 254, 31, 237, 30, 86, 19, 64, 235, 88,
+ 86, 235, 88, 64, 235, 88, 242, 254, 237, 30, 236, 199, 86, 235, 88, 29,
+ 248, 35, 240, 46, 242, 254, 238, 74, 242, 229, 96, 229, 58, 236, 235,
+ 235, 52, 234, 42, 247, 150, 235, 35, 234, 42, 96, 239, 23, 234, 42, 237,
+ 42, 96, 237, 42, 231, 39, 235, 52, 242, 254, 229, 58, 235, 139, 235, 52,
+ 96, 242, 254, 229, 58, 235, 139, 235, 52, 236, 189, 64, 238, 51, 168, 38,
+ 231, 103, 64, 238, 59, 189, 38, 231, 103, 64, 238, 59, 168, 38, 236, 189,
+ 64, 238, 59, 189, 38, 236, 189, 64, 238, 59, 86, 238, 76, 242, 250, 64,
+ 206, 136, 59, 125, 240, 19, 59, 125, 96, 59, 125, 96, 240, 12, 205, 242,
+ 244, 235, 51, 158, 235, 53, 96, 240, 12, 242, 244, 235, 51, 158, 235, 53,
+ 96, 45, 205, 242, 244, 235, 51, 158, 235, 53, 96, 45, 242, 244, 235, 51,
+ 158, 235, 53, 240, 95, 252, 190, 235, 91, 21, 235, 53, 96, 233, 54, 158,
+ 235, 53, 96, 243, 16, 233, 54, 158, 235, 53, 96, 86, 240, 138, 238, 120,
+ 96, 86, 243, 16, 238, 69, 240, 135, 240, 138, 238, 120, 240, 135, 243,
+ 16, 238, 69, 240, 19, 40, 233, 56, 235, 53, 240, 19, 38, 233, 56, 235,
+ 53, 240, 19, 235, 122, 40, 233, 56, 235, 53, 240, 19, 235, 122, 38, 233,
+ 56, 235, 53, 240, 19, 231, 87, 185, 238, 52, 235, 53, 240, 19, 231, 36,
+ 185, 238, 52, 235, 53, 96, 231, 87, 185, 235, 51, 158, 235, 53, 96, 231,
+ 36, 185, 235, 51, 158, 235, 53, 96, 231, 87, 185, 238, 52, 235, 53, 96,
+ 231, 36, 185, 238, 52, 235, 53, 136, 40, 236, 171, 242, 255, 238, 52,
+ 235, 53, 136, 38, 236, 171, 242, 255, 238, 52, 235, 53, 240, 19, 40, 242,
+ 225, 238, 52, 235, 53, 240, 19, 38, 242, 225, 238, 52, 235, 53, 238, 55,
+ 236, 146, 29, 26, 127, 238, 55, 236, 146, 29, 26, 111, 238, 55, 236, 146,
+ 29, 26, 166, 238, 55, 236, 146, 29, 26, 177, 238, 55, 236, 146, 29, 26,
+ 176, 238, 55, 236, 146, 29, 26, 187, 238, 55, 236, 146, 29, 26, 203, 238,
+ 55, 236, 146, 29, 26, 195, 238, 55, 236, 146, 29, 26, 202, 238, 55, 236,
+ 146, 29, 61, 248, 53, 238, 55, 29, 27, 26, 127, 238, 55, 29, 27, 26, 111,
+ 238, 55, 29, 27, 26, 166, 238, 55, 29, 27, 26, 177, 238, 55, 29, 27, 26,
+ 176, 238, 55, 29, 27, 26, 187, 238, 55, 29, 27, 26, 203, 238, 55, 29, 27,
+ 26, 195, 238, 55, 29, 27, 26, 202, 238, 55, 29, 27, 61, 248, 53, 238, 55,
+ 236, 146, 29, 27, 26, 127, 238, 55, 236, 146, 29, 27, 26, 111, 238, 55,
+ 236, 146, 29, 27, 26, 166, 238, 55, 236, 146, 29, 27, 26, 177, 238, 55,
+ 236, 146, 29, 27, 26, 176, 238, 55, 236, 146, 29, 27, 26, 187, 238, 55,
+ 236, 146, 29, 27, 26, 203, 238, 55, 236, 146, 29, 27, 26, 195, 238, 55,
+ 236, 146, 29, 27, 26, 202, 238, 55, 236, 146, 29, 27, 61, 248, 53, 96,
+ 234, 1, 77, 56, 96, 242, 228, 248, 43, 56, 96, 77, 56, 96, 242, 223, 248,
+ 43, 56, 237, 142, 242, 232, 77, 56, 96, 232, 202, 77, 56, 229, 60, 77,
+ 56, 96, 229, 60, 77, 56, 240, 55, 229, 60, 77, 56, 96, 240, 55, 229, 60,
+ 77, 56, 86, 77, 56, 238, 229, 233, 253, 77, 234, 7, 238, 229, 231, 60,
+ 77, 234, 7, 86, 77, 234, 7, 96, 86, 240, 95, 235, 45, 19, 77, 56, 96, 86,
+ 240, 95, 226, 226, 19, 77, 56, 244, 23, 86, 77, 56, 96, 229, 65, 86, 77,
+ 56, 232, 200, 64, 77, 56, 233, 215, 64, 77, 56, 233, 119, 236, 189, 64,
+ 77, 56, 232, 166, 236, 189, 64, 77, 56, 96, 168, 231, 38, 64, 77, 56, 96,
+ 189, 231, 38, 64, 77, 56, 238, 204, 168, 231, 38, 64, 77, 56, 238, 204,
+ 189, 231, 38, 64, 77, 56, 29, 96, 64, 77, 56, 231, 34, 77, 56, 229, 59,
+ 242, 228, 248, 43, 56, 229, 59, 77, 56, 229, 59, 242, 223, 248, 43, 56,
+ 96, 229, 59, 242, 228, 248, 43, 56, 96, 229, 59, 77, 56, 96, 229, 59,
+ 242, 223, 248, 43, 56, 231, 31, 77, 56, 96, 229, 56, 77, 56, 232, 112,
+ 77, 56, 96, 232, 112, 77, 56, 231, 150, 77, 56, 204, 233, 133, 240, 54,
+ 64, 236, 152, 234, 34, 3, 64, 235, 46, 231, 49, 248, 35, 238, 87, 248,
+ 35, 235, 84, 40, 237, 35, 254, 52, 234, 35, 38, 237, 35, 254, 52, 234,
+ 35, 64, 238, 76, 2, 238, 130, 248, 40, 19, 2, 248, 40, 238, 68, 147, 238,
+ 96, 236, 206, 168, 38, 240, 31, 2, 248, 40, 189, 40, 240, 31, 2, 248, 40,
+ 40, 243, 111, 243, 61, 38, 243, 111, 243, 61, 248, 37, 243, 111, 243, 61,
+ 243, 22, 88, 242, 234, 243, 22, 92, 242, 234, 40, 19, 38, 45, 234, 15,
+ 40, 19, 38, 242, 234, 40, 235, 103, 183, 38, 242, 234, 183, 40, 242, 234,
+ 88, 248, 84, 2, 218, 48, 239, 124, 238, 135, 255, 25, 163, 247, 53, 64,
+ 231, 95, 236, 164, 64, 231, 95, 238, 76, 2, 139, 243, 36, 64, 231, 95,
+ 238, 76, 2, 77, 243, 36, 64, 31, 2, 139, 243, 36, 64, 31, 2, 77, 243, 36,
+ 10, 40, 64, 31, 104, 10, 38, 64, 31, 104, 10, 40, 185, 104, 10, 38, 185,
+ 104, 10, 40, 45, 185, 104, 10, 38, 45, 185, 104, 226, 226, 235, 71, 56,
+ 235, 45, 235, 71, 56, 231, 86, 240, 178, 218, 56, 235, 62, 240, 178, 218,
+ 56, 38, 65, 2, 29, 243, 12, 183, 139, 56, 183, 77, 56, 183, 40, 38, 56,
+ 183, 139, 45, 56, 183, 77, 45, 56, 183, 40, 38, 45, 56, 183, 139, 65,
+ 248, 44, 125, 183, 77, 65, 248, 44, 125, 183, 139, 45, 65, 248, 44, 125,
+ 183, 77, 45, 65, 248, 44, 125, 183, 77, 236, 240, 56, 35, 36, 241, 33,
+ 35, 36, 239, 46, 35, 36, 239, 47, 35, 36, 237, 113, 35, 36, 239, 48, 35,
+ 36, 237, 114, 35, 36, 237, 120, 35, 36, 235, 206, 35, 36, 239, 49, 35,
+ 36, 237, 115, 35, 36, 237, 121, 35, 36, 235, 207, 35, 36, 237, 126, 35,
+ 36, 235, 212, 35, 36, 235, 227, 35, 36, 234, 113, 35, 36, 239, 50, 35,
+ 36, 237, 116, 35, 36, 237, 122, 35, 36, 235, 208, 35, 36, 237, 127, 35,
+ 36, 235, 213, 35, 36, 235, 228, 35, 36, 234, 114, 35, 36, 237, 131, 35,
+ 36, 235, 217, 35, 36, 235, 232, 35, 36, 234, 118, 35, 36, 235, 242, 35,
+ 36, 234, 128, 35, 36, 234, 148, 35, 36, 233, 138, 35, 36, 239, 51, 35,
+ 36, 237, 117, 35, 36, 237, 123, 35, 36, 235, 209, 35, 36, 237, 128, 35,
+ 36, 235, 214, 35, 36, 235, 229, 35, 36, 234, 115, 35, 36, 237, 132, 35,
+ 36, 235, 218, 35, 36, 235, 233, 35, 36, 234, 119, 35, 36, 235, 243, 35,
+ 36, 234, 129, 35, 36, 234, 149, 35, 36, 233, 139, 35, 36, 237, 135, 35,
+ 36, 235, 221, 35, 36, 235, 236, 35, 36, 234, 122, 35, 36, 235, 246, 35,
+ 36, 234, 132, 35, 36, 234, 152, 35, 36, 233, 142, 35, 36, 235, 252, 35,
+ 36, 234, 138, 35, 36, 234, 158, 35, 36, 233, 148, 35, 36, 234, 168, 35,
+ 36, 233, 158, 35, 36, 233, 173, 35, 36, 232, 134, 35, 36, 239, 52, 35,
+ 36, 237, 118, 35, 36, 237, 124, 35, 36, 235, 210, 35, 36, 237, 129, 35,
+ 36, 235, 215, 35, 36, 235, 230, 35, 36, 234, 116, 35, 36, 237, 133, 35,
+ 36, 235, 219, 35, 36, 235, 234, 35, 36, 234, 120, 35, 36, 235, 244, 35,
+ 36, 234, 130, 35, 36, 234, 150, 35, 36, 233, 140, 35, 36, 237, 136, 35,
+ 36, 235, 222, 35, 36, 235, 237, 35, 36, 234, 123, 35, 36, 235, 247, 35,
+ 36, 234, 133, 35, 36, 234, 153, 35, 36, 233, 143, 35, 36, 235, 253, 35,
+ 36, 234, 139, 35, 36, 234, 159, 35, 36, 233, 149, 35, 36, 234, 169, 35,
+ 36, 233, 159, 35, 36, 233, 174, 35, 36, 232, 135, 35, 36, 237, 138, 35,
+ 36, 235, 224, 35, 36, 235, 239, 35, 36, 234, 125, 35, 36, 235, 249, 35,
+ 36, 234, 135, 35, 36, 234, 155, 35, 36, 233, 145, 35, 36, 235, 255, 35,
+ 36, 234, 141, 35, 36, 234, 161, 35, 36, 233, 151, 35, 36, 234, 171, 35,
+ 36, 233, 161, 35, 36, 233, 176, 35, 36, 232, 137, 35, 36, 236, 2, 35, 36,
+ 234, 144, 35, 36, 234, 164, 35, 36, 233, 154, 35, 36, 234, 174, 35, 36,
+ 233, 164, 35, 36, 233, 179, 35, 36, 232, 140, 35, 36, 234, 178, 35, 36,
+ 233, 168, 35, 36, 233, 183, 35, 36, 232, 144, 35, 36, 233, 188, 35, 36,
+ 232, 149, 35, 36, 232, 155, 35, 36, 231, 129, 35, 36, 239, 53, 35, 36,
+ 237, 119, 35, 36, 237, 125, 35, 36, 235, 211, 35, 36, 237, 130, 35, 36,
+ 235, 216, 35, 36, 235, 231, 35, 36, 234, 117, 35, 36, 237, 134, 35, 36,
+ 235, 220, 35, 36, 235, 235, 35, 36, 234, 121, 35, 36, 235, 245, 35, 36,
+ 234, 131, 35, 36, 234, 151, 35, 36, 233, 141, 35, 36, 237, 137, 35, 36,
+ 235, 223, 35, 36, 235, 238, 35, 36, 234, 124, 35, 36, 235, 248, 35, 36,
+ 234, 134, 35, 36, 234, 154, 35, 36, 233, 144, 35, 36, 235, 254, 35, 36,
+ 234, 140, 35, 36, 234, 160, 35, 36, 233, 150, 35, 36, 234, 170, 35, 36,
+ 233, 160, 35, 36, 233, 175, 35, 36, 232, 136, 35, 36, 237, 139, 35, 36,
+ 235, 225, 35, 36, 235, 240, 35, 36, 234, 126, 35, 36, 235, 250, 35, 36,
+ 234, 136, 35, 36, 234, 156, 35, 36, 233, 146, 35, 36, 236, 0, 35, 36,
+ 234, 142, 35, 36, 234, 162, 35, 36, 233, 152, 35, 36, 234, 172, 35, 36,
+ 233, 162, 35, 36, 233, 177, 35, 36, 232, 138, 35, 36, 236, 3, 35, 36,
+ 234, 145, 35, 36, 234, 165, 35, 36, 233, 155, 35, 36, 234, 175, 35, 36,
+ 233, 165, 35, 36, 233, 180, 35, 36, 232, 141, 35, 36, 234, 179, 35, 36,
+ 233, 169, 35, 36, 233, 184, 35, 36, 232, 145, 35, 36, 233, 189, 35, 36,
+ 232, 150, 35, 36, 232, 156, 35, 36, 231, 130, 35, 36, 237, 140, 35, 36,
+ 235, 226, 35, 36, 235, 241, 35, 36, 234, 127, 35, 36, 235, 251, 35, 36,
+ 234, 137, 35, 36, 234, 157, 35, 36, 233, 147, 35, 36, 236, 1, 35, 36,
+ 234, 143, 35, 36, 234, 163, 35, 36, 233, 153, 35, 36, 234, 173, 35, 36,
+ 233, 163, 35, 36, 233, 178, 35, 36, 232, 139, 35, 36, 236, 4, 35, 36,
+ 234, 146, 35, 36, 234, 166, 35, 36, 233, 156, 35, 36, 234, 176, 35, 36,
+ 233, 166, 35, 36, 233, 181, 35, 36, 232, 142, 35, 36, 234, 180, 35, 36,
+ 233, 170, 35, 36, 233, 185, 35, 36, 232, 146, 35, 36, 233, 190, 35, 36,
+ 232, 151, 35, 36, 232, 157, 35, 36, 231, 131, 35, 36, 236, 5, 35, 36,
+ 234, 147, 35, 36, 234, 167, 35, 36, 233, 157, 35, 36, 234, 177, 35, 36,
+ 233, 167, 35, 36, 233, 182, 35, 36, 232, 143, 35, 36, 234, 181, 35, 36,
+ 233, 171, 35, 36, 233, 186, 35, 36, 232, 147, 35, 36, 233, 191, 35, 36,
+ 232, 152, 35, 36, 232, 158, 35, 36, 231, 132, 35, 36, 234, 182, 35, 36,
+ 233, 172, 35, 36, 233, 187, 35, 36, 232, 148, 35, 36, 233, 192, 35, 36,
+ 232, 153, 35, 36, 232, 159, 35, 36, 231, 133, 35, 36, 233, 193, 35, 36,
+ 232, 154, 35, 36, 232, 160, 35, 36, 231, 134, 35, 36, 232, 161, 35, 36,
+ 231, 135, 35, 36, 231, 136, 35, 36, 231, 64, 77, 234, 16, 65, 2, 59, 108,
+ 77, 234, 16, 65, 2, 45, 59, 108, 139, 45, 65, 2, 59, 108, 77, 45, 65, 2,
+ 59, 108, 40, 38, 45, 65, 2, 59, 108, 77, 234, 16, 65, 248, 44, 125, 139,
+ 45, 65, 248, 44, 125, 77, 45, 65, 248, 44, 125, 235, 45, 65, 2, 163, 108,
+ 226, 226, 65, 2, 163, 108, 226, 226, 240, 3, 56, 235, 45, 240, 3, 56,
+ 139, 45, 248, 63, 56, 77, 45, 248, 63, 56, 139, 240, 3, 248, 63, 56, 77,
+ 240, 3, 248, 63, 56, 77, 234, 16, 240, 3, 248, 63, 56, 77, 65, 2, 240, 4,
+ 243, 46, 226, 226, 65, 153, 125, 235, 45, 65, 153, 125, 77, 65, 2, 248,
+ 138, 2, 59, 108, 77, 65, 2, 248, 138, 2, 45, 59, 108, 77, 234, 16, 65, 2,
+ 242, 226, 77, 234, 16, 65, 2, 248, 138, 2, 59, 108, 77, 234, 16, 65, 2,
+ 248, 138, 2, 45, 59, 108, 139, 233, 64, 77, 233, 64, 139, 45, 233, 64,
+ 77, 45, 233, 64, 139, 65, 153, 86, 236, 164, 77, 65, 153, 86, 236, 164,
+ 139, 65, 248, 44, 253, 144, 153, 86, 236, 164, 77, 65, 248, 44, 253, 144,
+ 153, 86, 236, 164, 242, 223, 248, 56, 19, 242, 228, 248, 43, 56, 242,
+ 223, 248, 43, 19, 242, 228, 248, 56, 56, 242, 223, 248, 56, 65, 2, 90,
+ 242, 223, 248, 43, 65, 2, 90, 242, 228, 248, 43, 65, 2, 90, 242, 228,
+ 248, 56, 65, 2, 90, 242, 223, 248, 56, 65, 19, 242, 223, 248, 43, 56,
+ 242, 223, 248, 43, 65, 19, 242, 228, 248, 43, 56, 242, 228, 248, 43, 65,
+ 19, 242, 228, 248, 56, 56, 242, 228, 248, 56, 65, 19, 242, 223, 248, 56,
+ 56, 240, 69, 236, 159, 236, 185, 238, 105, 235, 86, 238, 105, 236, 159,
+ 236, 185, 240, 69, 235, 86, 242, 228, 248, 43, 65, 236, 185, 242, 223,
+ 248, 43, 56, 242, 223, 248, 43, 65, 236, 185, 242, 228, 248, 43, 56, 238,
+ 105, 236, 159, 236, 185, 242, 223, 248, 43, 56, 240, 69, 236, 159, 236,
+ 185, 242, 228, 248, 43, 56, 242, 223, 248, 43, 65, 236, 185, 242, 223,
+ 248, 56, 56, 242, 223, 248, 56, 65, 236, 185, 242, 223, 248, 43, 56, 248,
+ 141, 65, 236, 150, 237, 111, 225, 65, 236, 150, 77, 248, 187, 238, 111,
+ 236, 206, 65, 236, 150, 77, 248, 187, 238, 111, 234, 9, 65, 236, 150,
+ 235, 45, 248, 187, 238, 111, 234, 18, 65, 236, 150, 235, 45, 248, 187,
+ 238, 111, 233, 63, 234, 250, 253, 183, 235, 62, 56, 236, 50, 253, 183,
+ 231, 86, 56, 253, 159, 253, 183, 231, 86, 56, 240, 17, 253, 183, 231, 86,
+ 56, 253, 159, 253, 183, 235, 62, 65, 2, 240, 68, 253, 159, 253, 183, 231,
+ 86, 65, 2, 243, 12, 168, 38, 232, 98, 235, 62, 56, 168, 40, 232, 98, 231,
+ 86, 56, 231, 86, 240, 23, 218, 56, 235, 62, 240, 23, 218, 56, 77, 65, 60,
+ 242, 215, 139, 56, 139, 65, 60, 242, 215, 77, 56, 242, 215, 77, 65, 60,
+ 139, 56, 77, 65, 2, 248, 49, 46, 139, 65, 2, 248, 49, 46, 77, 65, 238,
+ 108, 206, 40, 38, 65, 238, 108, 3, 238, 51, 226, 226, 234, 16, 65, 248,
+ 44, 3, 238, 51, 40, 154, 88, 38, 154, 92, 236, 175, 40, 154, 92, 38, 154,
+ 88, 236, 175, 88, 154, 38, 92, 154, 40, 236, 175, 88, 154, 40, 92, 154,
+ 38, 236, 175, 40, 154, 88, 38, 154, 88, 236, 175, 88, 154, 38, 92, 154,
+ 38, 236, 175, 40, 154, 92, 38, 154, 92, 236, 175, 88, 154, 40, 92, 154,
+ 40, 236, 175, 139, 186, 2, 154, 88, 153, 125, 77, 186, 2, 154, 88, 153,
+ 125, 226, 226, 186, 2, 154, 38, 153, 125, 235, 45, 186, 2, 154, 38, 153,
+ 125, 139, 186, 2, 154, 92, 153, 125, 77, 186, 2, 154, 92, 153, 125, 226,
+ 226, 186, 2, 154, 40, 153, 125, 235, 45, 186, 2, 154, 40, 153, 125, 139,
+ 186, 2, 154, 88, 248, 44, 125, 77, 186, 2, 154, 88, 248, 44, 125, 226,
+ 226, 186, 2, 154, 38, 248, 44, 125, 235, 45, 186, 2, 154, 38, 248, 44,
+ 125, 139, 186, 2, 154, 92, 248, 44, 125, 77, 186, 2, 154, 92, 248, 44,
+ 125, 226, 226, 186, 2, 154, 40, 248, 44, 125, 235, 45, 186, 2, 154, 40,
+ 248, 44, 125, 139, 186, 2, 154, 88, 60, 139, 186, 2, 154, 242, 236, 226,
+ 226, 186, 2, 154, 40, 240, 45, 226, 226, 186, 2, 154, 225, 77, 186, 2,
+ 154, 88, 60, 77, 186, 2, 154, 242, 236, 235, 45, 186, 2, 154, 40, 240,
+ 45, 235, 45, 186, 2, 154, 225, 139, 186, 2, 154, 88, 60, 77, 186, 2, 154,
+ 253, 176, 139, 186, 2, 154, 92, 60, 77, 186, 2, 154, 242, 236, 77, 186,
+ 2, 154, 88, 60, 139, 186, 2, 154, 253, 176, 77, 186, 2, 154, 92, 60, 139,
+ 186, 2, 154, 242, 236, 139, 186, 2, 154, 88, 60, 183, 242, 235, 139, 186,
+ 2, 154, 92, 242, 230, 183, 242, 235, 77, 186, 2, 154, 88, 60, 183, 242,
+ 235, 77, 186, 2, 154, 92, 242, 230, 183, 242, 235, 226, 226, 186, 2, 154,
+ 40, 240, 45, 235, 45, 186, 2, 154, 225, 235, 45, 186, 2, 154, 40, 240,
+ 45, 226, 226, 186, 2, 154, 225, 38, 45, 65, 2, 238, 121, 243, 99, 240, 7,
+ 21, 60, 77, 56, 242, 219, 236, 208, 60, 77, 56, 139, 65, 60, 242, 219,
+ 235, 47, 77, 65, 60, 242, 219, 235, 47, 77, 65, 60, 240, 40, 95, 87, 235,
+ 44, 60, 139, 56, 139, 65, 238, 108, 234, 3, 232, 68, 60, 77, 56, 240, 26,
+ 60, 77, 56, 139, 65, 238, 108, 238, 87, 236, 154, 60, 139, 56, 40, 248,
+ 157, 242, 226, 38, 248, 157, 242, 226, 88, 248, 157, 242, 226, 92, 248,
+ 157, 242, 226, 240, 3, 59, 253, 144, 234, 35, 255, 97, 126, 247, 97, 255,
+ 97, 126, 249, 9, 240, 24, 40, 64, 242, 225, 104, 38, 64, 242, 225, 104,
+ 40, 64, 232, 74, 38, 64, 232, 74, 255, 97, 126, 40, 243, 11, 104, 255,
+ 97, 126, 38, 243, 11, 104, 255, 97, 126, 40, 238, 166, 104, 255, 97, 126,
+ 38, 238, 166, 104, 40, 31, 238, 52, 2, 235, 50, 38, 31, 238, 52, 2, 235,
+ 50, 40, 31, 238, 52, 2, 248, 188, 255, 22, 253, 159, 238, 67, 38, 31,
+ 238, 52, 2, 248, 188, 255, 22, 240, 17, 238, 67, 40, 31, 238, 52, 2, 248,
+ 188, 255, 22, 240, 17, 238, 67, 38, 31, 238, 52, 2, 248, 188, 255, 22,
+ 253, 159, 238, 67, 40, 185, 238, 52, 2, 248, 40, 38, 185, 238, 52, 2,
+ 248, 40, 40, 253, 183, 235, 44, 104, 38, 253, 183, 232, 68, 104, 45, 40,
+ 253, 183, 232, 68, 104, 45, 38, 253, 183, 235, 44, 104, 40, 86, 236, 171,
+ 242, 255, 104, 38, 86, 236, 171, 242, 255, 104, 240, 4, 240, 97, 59, 240,
+ 126, 242, 224, 236, 168, 185, 238, 96, 242, 220, 38, 185, 239, 240, 2,
+ 238, 59, 236, 168, 38, 185, 2, 248, 40, 185, 2, 255, 99, 238, 94, 242,
+ 241, 240, 54, 235, 109, 185, 238, 96, 242, 220, 235, 109, 185, 238, 96,
+ 253, 176, 205, 240, 54, 224, 240, 54, 185, 2, 235, 50, 224, 185, 2, 235,
+ 50, 238, 106, 185, 238, 96, 253, 176, 238, 106, 185, 238, 96, 242, 236,
+ 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 150, 88,
+ 19, 225, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236,
+ 150, 88, 19, 242, 220, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255,
+ 22, 65, 236, 150, 92, 19, 225, 236, 168, 185, 2, 248, 35, 253, 229, 240,
+ 63, 255, 22, 65, 236, 150, 92, 19, 242, 220, 236, 168, 185, 2, 248, 35,
+ 253, 229, 240, 63, 255, 22, 65, 236, 150, 38, 19, 253, 176, 236, 168,
+ 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 150, 40, 19, 253,
+ 176, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22, 65, 236, 150,
+ 38, 19, 242, 236, 236, 168, 185, 2, 248, 35, 253, 229, 240, 63, 255, 22,
+ 65, 236, 150, 40, 19, 242, 236, 224, 243, 15, 249, 160, 243, 15, 254, 30,
+ 2, 236, 163, 243, 15, 254, 30, 2, 3, 218, 48, 243, 15, 254, 30, 2, 38,
+ 65, 48, 243, 15, 254, 30, 2, 40, 65, 48, 218, 2, 163, 125, 29, 59, 125,
+ 29, 235, 105, 29, 238, 75, 236, 177, 29, 231, 49, 218, 238, 135, 255, 25,
+ 163, 253, 144, 19, 253, 159, 137, 238, 135, 255, 25, 59, 125, 218, 2,
+ 233, 39, 206, 29, 226, 231, 236, 196, 52, 88, 65, 238, 108, 238, 51, 29,
+ 64, 238, 69, 29, 238, 69, 29, 234, 3, 29, 231, 85, 218, 2, 3, 218, 153,
+ 253, 145, 225, 218, 2, 171, 163, 239, 207, 153, 253, 145, 225, 238, 84,
+ 240, 69, 236, 159, 240, 37, 238, 84, 238, 105, 236, 159, 240, 37, 238,
+ 84, 235, 52, 238, 84, 3, 238, 51, 238, 84, 238, 59, 171, 240, 116, 238,
+ 12, 236, 152, 2, 53, 48, 236, 152, 2, 235, 50, 255, 99, 255, 22, 235, 46,
+ 236, 152, 2, 240, 220, 255, 31, 238, 128, 38, 236, 152, 60, 40, 235, 46,
+ 40, 236, 152, 240, 45, 59, 125, 59, 253, 144, 240, 45, 38, 235, 46, 240,
+ 161, 2, 40, 137, 240, 0, 240, 161, 2, 38, 137, 240, 0, 86, 238, 168, 243,
+ 48, 2, 40, 137, 240, 0, 243, 48, 2, 38, 137, 240, 0, 64, 234, 39, 86,
+ 234, 39, 40, 240, 125, 240, 97, 38, 240, 125, 240, 97, 40, 45, 240, 125,
+ 240, 97, 38, 45, 240, 125, 240, 97, 234, 204, 235, 101, 254, 248, 248,
+ 59, 235, 101, 237, 180, 238, 203, 2, 59, 125, 232, 162, 235, 103, 31, 2,
+ 235, 194, 237, 229, 236, 40, 254, 143, 239, 195, 236, 170, 240, 7, 21,
+ 19, 238, 58, 235, 105, 240, 7, 21, 19, 238, 58, 236, 200, 2, 242, 219,
+ 48, 235, 89, 153, 19, 238, 58, 235, 105, 241, 138, 242, 132, 231, 83,
+ 231, 91, 236, 152, 2, 40, 137, 240, 0, 231, 91, 236, 152, 2, 38, 137,
+ 240, 0, 86, 238, 76, 2, 92, 56, 86, 236, 231, 64, 218, 2, 92, 56, 86,
+ 218, 2, 92, 56, 232, 78, 64, 238, 59, 232, 78, 86, 238, 59, 232, 78, 64,
+ 236, 164, 232, 78, 86, 236, 164, 232, 78, 64, 238, 51, 232, 78, 86, 238,
+ 51, 231, 152, 238, 75, 238, 83, 235, 47, 238, 83, 2, 236, 163, 238, 75,
+ 238, 83, 2, 163, 108, 253, 213, 236, 177, 253, 213, 238, 75, 236, 177,
+ 45, 243, 12, 240, 3, 243, 12, 231, 87, 240, 95, 185, 104, 231, 36, 240,
+ 95, 185, 104, 247, 152, 246, 87, 242, 238, 29, 53, 235, 47, 242, 238, 29,
+ 248, 49, 235, 47, 242, 238, 29, 243, 48, 235, 47, 242, 238, 243, 2, 236,
+ 208, 2, 248, 40, 242, 238, 243, 2, 236, 208, 2, 243, 12, 242, 238, 31,
+ 232, 76, 235, 47, 242, 238, 31, 243, 2, 235, 47, 171, 238, 56, 19, 235,
+ 47, 171, 238, 56, 128, 235, 47, 242, 238, 243, 48, 235, 47, 241, 247,
+ 171, 252, 192, 235, 112, 2, 235, 60, 235, 71, 236, 167, 235, 47, 241,
+ 110, 249, 134, 235, 60, 236, 167, 2, 45, 108, 236, 167, 238, 255, 2, 240,
+ 37, 233, 122, 236, 29, 231, 86, 232, 177, 248, 41, 233, 70, 2, 233, 97,
+ 249, 135, 240, 127, 243, 116, 248, 41, 233, 70, 2, 232, 98, 249, 135,
+ 240, 127, 243, 116, 248, 41, 233, 70, 161, 236, 39, 253, 145, 243, 116,
+ 236, 167, 240, 127, 134, 242, 232, 235, 47, 234, 242, 236, 167, 235, 47,
+ 236, 167, 2, 139, 65, 2, 90, 236, 167, 2, 243, 48, 52, 236, 167, 2, 231,
+ 88, 236, 167, 2, 240, 58, 236, 167, 2, 236, 163, 236, 167, 2, 235, 50,
+ 243, 61, 243, 22, 40, 236, 152, 235, 47, 255, 97, 126, 240, 144, 232,
+ 104, 255, 97, 126, 240, 144, 239, 162, 255, 97, 126, 240, 144, 233, 225,
+ 248, 49, 21, 2, 3, 218, 48, 248, 49, 21, 2, 190, 240, 2, 48, 248, 49, 21,
+ 2, 242, 219, 48, 248, 49, 21, 2, 53, 46, 248, 49, 21, 2, 242, 219, 46,
+ 248, 49, 21, 2, 235, 48, 111, 248, 49, 21, 2, 86, 235, 46, 242, 250, 21,
+ 2, 242, 244, 48, 242, 250, 21, 2, 53, 46, 242, 250, 21, 2, 238, 105, 243,
+ 5, 242, 250, 21, 2, 240, 69, 243, 5, 248, 49, 21, 255, 22, 40, 137, 238,
+ 51, 248, 49, 21, 255, 22, 38, 137, 238, 51, 242, 176, 128, 243, 38, 236,
+ 170, 231, 37, 21, 2, 53, 48, 231, 37, 21, 2, 235, 50, 234, 21, 239, 167,
+ 2, 240, 17, 239, 29, 244, 20, 236, 170, 231, 37, 21, 255, 22, 40, 137,
+ 238, 51, 231, 37, 21, 255, 22, 38, 137, 238, 51, 29, 231, 37, 21, 2, 190,
+ 238, 54, 231, 37, 21, 255, 22, 45, 238, 51, 29, 236, 196, 52, 248, 49,
+ 21, 255, 22, 235, 46, 242, 250, 21, 255, 22, 235, 46, 231, 37, 21, 255,
+ 22, 235, 46, 237, 14, 236, 170, 236, 93, 237, 14, 236, 170, 255, 97, 126,
+ 234, 246, 232, 104, 232, 115, 128, 234, 50, 232, 76, 2, 248, 40, 243, 2,
+ 2, 242, 250, 52, 243, 2, 2, 236, 163, 232, 76, 2, 236, 163, 232, 76, 2,
+ 238, 56, 248, 91, 243, 2, 2, 238, 56, 253, 227, 243, 2, 60, 231, 88, 232,
+ 76, 60, 240, 58, 243, 2, 60, 253, 144, 60, 231, 88, 232, 76, 60, 253,
+ 144, 60, 240, 58, 243, 2, 240, 45, 19, 240, 116, 2, 240, 58, 232, 76,
+ 240, 45, 19, 240, 116, 2, 231, 88, 240, 23, 243, 2, 2, 238, 214, 240, 23,
+ 232, 76, 2, 238, 214, 45, 31, 231, 88, 45, 31, 240, 58, 240, 23, 243, 2,
+ 2, 240, 220, 19, 244, 20, 236, 170, 238, 56, 19, 2, 53, 48, 238, 56, 128,
+ 2, 53, 48, 45, 238, 56, 248, 91, 45, 238, 56, 253, 227, 171, 232, 105,
+ 238, 56, 248, 91, 171, 232, 105, 238, 56, 253, 227, 238, 217, 243, 22,
+ 253, 227, 238, 217, 243, 22, 248, 91, 238, 56, 128, 233, 91, 238, 56,
+ 248, 91, 238, 56, 19, 2, 240, 1, 243, 46, 238, 56, 128, 2, 240, 1, 243,
+ 46, 238, 56, 19, 2, 163, 242, 235, 238, 56, 128, 2, 163, 242, 235, 238,
+ 56, 19, 2, 45, 236, 163, 238, 56, 19, 2, 235, 50, 238, 56, 19, 2, 45,
+ 235, 50, 3, 254, 255, 2, 235, 50, 238, 56, 128, 2, 45, 236, 163, 238, 56,
+ 128, 2, 45, 235, 50, 255, 97, 126, 241, 87, 227, 10, 255, 97, 126, 247,
+ 28, 227, 10, 240, 7, 21, 2, 53, 46, 235, 89, 2, 53, 48, 240, 3, 163, 253,
+ 144, 2, 45, 59, 108, 240, 3, 163, 253, 144, 2, 240, 3, 59, 108, 242, 219,
+ 236, 208, 2, 53, 48, 242, 219, 236, 208, 2, 240, 69, 243, 5, 238, 81,
+ 242, 250, 238, 5, 235, 192, 2, 53, 48, 240, 7, 2, 235, 52, 240, 40, 95,
+ 153, 2, 190, 238, 54, 231, 89, 95, 128, 95, 87, 240, 7, 21, 60, 248, 49,
+ 52, 248, 49, 21, 60, 240, 7, 52, 240, 7, 21, 60, 242, 219, 235, 47, 45,
+ 243, 14, 240, 32, 171, 233, 82, 240, 7, 240, 232, 204, 233, 82, 240, 7,
+ 240, 232, 240, 7, 21, 2, 171, 181, 60, 19, 171, 181, 46, 234, 5, 2, 248,
+ 58, 181, 48, 235, 44, 2, 218, 238, 94, 232, 68, 2, 218, 238, 94, 235, 44,
+ 2, 236, 156, 158, 48, 232, 68, 2, 236, 156, 158, 48, 235, 44, 128, 238,
+ 58, 95, 87, 232, 68, 128, 238, 58, 95, 87, 235, 44, 128, 238, 58, 95,
+ 153, 2, 53, 238, 94, 232, 68, 128, 238, 58, 95, 153, 2, 53, 238, 94, 235,
+ 44, 128, 238, 58, 95, 153, 2, 53, 48, 232, 68, 128, 238, 58, 95, 153, 2,
+ 53, 48, 235, 44, 128, 238, 58, 95, 153, 2, 53, 60, 225, 232, 68, 128,
+ 238, 58, 95, 153, 2, 53, 60, 242, 220, 235, 44, 128, 232, 81, 232, 68,
+ 128, 232, 81, 235, 44, 19, 233, 61, 161, 95, 87, 232, 68, 19, 233, 61,
+ 161, 95, 87, 235, 44, 19, 161, 232, 81, 232, 68, 19, 161, 232, 81, 235,
+ 44, 60, 233, 57, 95, 60, 231, 85, 232, 68, 60, 233, 57, 95, 60, 234, 3,
+ 235, 44, 60, 238, 81, 128, 240, 32, 232, 68, 60, 238, 81, 128, 240, 32,
+ 235, 44, 60, 238, 81, 60, 231, 85, 232, 68, 60, 238, 81, 60, 234, 3, 235,
+ 44, 60, 232, 68, 60, 233, 57, 240, 32, 232, 68, 60, 235, 44, 60, 233, 57,
+ 240, 32, 235, 44, 60, 238, 58, 95, 60, 232, 68, 60, 238, 58, 240, 32,
+ 232, 68, 60, 238, 58, 95, 60, 235, 44, 60, 238, 58, 240, 32, 238, 58, 95,
+ 153, 128, 234, 3, 238, 58, 95, 153, 128, 231, 85, 238, 58, 95, 153, 128,
+ 235, 44, 2, 53, 238, 94, 238, 58, 95, 153, 128, 232, 68, 2, 53, 238, 94,
+ 233, 57, 95, 153, 128, 234, 3, 233, 57, 95, 153, 128, 231, 85, 233, 57,
+ 238, 58, 95, 153, 128, 234, 3, 233, 57, 238, 58, 95, 153, 128, 231, 85,
+ 238, 81, 128, 234, 3, 238, 81, 128, 231, 85, 238, 81, 60, 235, 44, 60,
+ 240, 7, 52, 238, 81, 60, 232, 68, 60, 240, 7, 52, 45, 240, 102, 234, 3,
+ 45, 240, 102, 231, 85, 45, 240, 102, 235, 44, 2, 235, 50, 232, 68, 233,
+ 91, 234, 3, 232, 68, 240, 45, 234, 3, 235, 44, 240, 23, 255, 25, 240,
+ 163, 232, 68, 240, 23, 255, 25, 240, 163, 235, 44, 240, 23, 255, 25, 243,
+ 158, 60, 238, 58, 240, 32, 232, 68, 240, 23, 255, 25, 243, 158, 60, 238,
+ 58, 240, 32, 238, 218, 243, 127, 240, 196, 243, 127, 238, 218, 249, 1,
+ 128, 95, 87, 240, 196, 249, 1, 128, 95, 87, 240, 7, 21, 2, 244, 232, 48,
+ 236, 176, 60, 233, 61, 240, 7, 52, 236, 178, 60, 233, 61, 240, 7, 52,
+ 236, 176, 60, 233, 61, 161, 95, 87, 236, 178, 60, 233, 61, 161, 95, 87,
+ 236, 176, 60, 240, 7, 52, 236, 178, 60, 240, 7, 52, 236, 176, 60, 161,
+ 95, 87, 236, 178, 60, 161, 95, 87, 236, 176, 60, 240, 40, 95, 87, 236,
+ 178, 60, 240, 40, 95, 87, 236, 176, 60, 161, 240, 40, 95, 87, 236, 178,
+ 60, 161, 240, 40, 95, 87, 45, 235, 107, 45, 235, 111, 240, 26, 2, 248,
+ 40, 236, 154, 2, 248, 40, 240, 26, 2, 248, 49, 21, 46, 236, 154, 2, 248,
+ 49, 21, 46, 240, 26, 2, 231, 37, 21, 46, 236, 154, 2, 231, 37, 21, 46,
+ 240, 26, 147, 128, 95, 153, 2, 53, 48, 236, 154, 147, 128, 95, 153, 2,
+ 53, 48, 240, 26, 147, 60, 240, 7, 52, 236, 154, 147, 60, 240, 7, 52, 240,
+ 26, 147, 60, 242, 219, 235, 47, 236, 154, 147, 60, 242, 219, 235, 47,
+ 240, 26, 147, 60, 240, 40, 95, 87, 236, 154, 147, 60, 240, 40, 95, 87,
+ 240, 26, 147, 60, 161, 95, 87, 236, 154, 147, 60, 161, 95, 87, 31, 40,
+ 248, 35, 66, 235, 47, 31, 38, 248, 35, 66, 235, 47, 240, 23, 238, 87,
+ 240, 23, 235, 84, 240, 23, 240, 26, 128, 95, 87, 240, 23, 236, 154, 128,
+ 95, 87, 240, 26, 60, 235, 84, 236, 154, 60, 238, 87, 240, 26, 60, 238,
+ 87, 236, 154, 60, 235, 84, 236, 154, 240, 45, 238, 87, 236, 154, 240, 45,
+ 19, 240, 116, 255, 25, 248, 63, 2, 238, 87, 238, 68, 147, 238, 96, 234,
+ 9, 236, 75, 2, 254, 246, 249, 3, 233, 254, 231, 88, 237, 160, 233, 220,
+ 242, 215, 40, 242, 234, 242, 215, 92, 242, 234, 242, 215, 88, 242, 234,
+ 231, 151, 2, 193, 59, 253, 144, 240, 3, 38, 234, 15, 45, 59, 253, 144,
+ 40, 234, 15, 59, 253, 144, 45, 40, 234, 15, 45, 59, 253, 144, 45, 40,
+ 234, 15, 183, 248, 63, 248, 44, 40, 241, 234, 147, 45, 235, 63, 242, 215,
+ 92, 248, 84, 2, 236, 163, 242, 215, 88, 248, 84, 2, 235, 50, 242, 215,
+ 88, 248, 84, 60, 242, 215, 92, 242, 234, 45, 92, 242, 234, 45, 88, 242,
+ 234, 45, 240, 5, 161, 52, 224, 45, 240, 5, 161, 52, 248, 86, 161, 241,
+ 86, 2, 224, 237, 217, 240, 37, 59, 248, 41, 2, 218, 48, 59, 248, 41, 2,
+ 218, 46, 92, 248, 84, 2, 218, 46, 236, 200, 2, 163, 108, 236, 200, 2,
+ 242, 219, 235, 47, 240, 3, 59, 253, 144, 240, 159, 235, 92, 240, 3, 59,
+ 253, 144, 2, 163, 108, 240, 3, 243, 14, 235, 47, 240, 3, 240, 102, 234,
+ 3, 240, 3, 240, 102, 231, 85, 233, 57, 238, 58, 235, 44, 128, 95, 87,
+ 233, 57, 238, 58, 232, 68, 128, 95, 87, 240, 3, 238, 83, 240, 159, 235,
+ 92, 243, 22, 240, 3, 59, 253, 144, 235, 47, 45, 238, 83, 235, 47, 64, 59,
+ 125, 242, 238, 64, 59, 125, 242, 223, 248, 43, 64, 56, 242, 223, 248, 56,
+ 64, 56, 242, 228, 248, 43, 64, 56, 242, 228, 248, 56, 64, 56, 40, 38, 64,
+ 56, 139, 86, 56, 226, 226, 86, 56, 235, 45, 86, 56, 242, 223, 248, 43,
+ 86, 56, 242, 223, 248, 56, 86, 56, 242, 228, 248, 43, 86, 56, 242, 228,
+ 248, 56, 86, 56, 40, 38, 86, 56, 88, 92, 86, 56, 77, 65, 2, 253, 241,
+ 234, 9, 77, 65, 2, 253, 241, 236, 206, 139, 65, 2, 253, 241, 234, 9, 139,
+ 65, 2, 253, 241, 236, 206, 31, 2, 253, 159, 137, 240, 0, 31, 2, 240, 17,
+ 137, 240, 0, 98, 5, 1, 249, 29, 98, 5, 1, 243, 152, 98, 5, 1, 244, 45,
+ 98, 5, 1, 237, 12, 98, 5, 1, 240, 170, 98, 5, 1, 240, 254, 98, 5, 1, 237,
+ 52, 98, 5, 1, 240, 171, 98, 5, 1, 238, 235, 98, 5, 1, 243, 60, 98, 5, 1,
+ 54, 243, 60, 98, 5, 1, 71, 98, 5, 1, 238, 178, 98, 5, 1, 243, 204, 98, 5,
+ 1, 237, 21, 98, 5, 1, 236, 216, 98, 5, 1, 240, 202, 98, 5, 1, 249, 131,
+ 98, 5, 1, 238, 210, 98, 5, 1, 240, 217, 98, 5, 1, 240, 235, 98, 5, 1,
+ 238, 230, 98, 5, 1, 249, 190, 98, 5, 1, 240, 177, 98, 5, 1, 243, 193, 98,
+ 5, 1, 249, 132, 98, 5, 1, 253, 175, 98, 5, 1, 244, 14, 98, 5, 1, 248,
+ 140, 98, 5, 1, 238, 170, 98, 5, 1, 248, 46, 98, 5, 1, 243, 83, 98, 5, 1,
+ 244, 57, 98, 5, 1, 244, 56, 98, 5, 1, 238, 221, 219, 98, 5, 1, 253, 161,
+ 98, 5, 1, 3, 248, 74, 98, 5, 1, 3, 254, 136, 2, 242, 226, 98, 5, 1, 253,
+ 162, 98, 5, 1, 238, 117, 3, 248, 74, 98, 5, 1, 253, 213, 248, 74, 98, 5,
+ 1, 238, 117, 253, 213, 248, 74, 98, 5, 1, 243, 57, 98, 5, 1, 236, 215,
+ 98, 5, 1, 237, 40, 98, 5, 1, 234, 87, 67, 98, 5, 1, 237, 19, 236, 216,
+ 98, 3, 1, 249, 29, 98, 3, 1, 243, 152, 98, 3, 1, 244, 45, 98, 3, 1, 237,
+ 12, 98, 3, 1, 240, 170, 98, 3, 1, 240, 254, 98, 3, 1, 237, 52, 98, 3, 1,
+ 240, 171, 98, 3, 1, 238, 235, 98, 3, 1, 243, 60, 98, 3, 1, 54, 243, 60,
+ 98, 3, 1, 71, 98, 3, 1, 238, 178, 98, 3, 1, 243, 204, 98, 3, 1, 237, 21,
+ 98, 3, 1, 236, 216, 98, 3, 1, 240, 202, 98, 3, 1, 249, 131, 98, 3, 1,
+ 238, 210, 98, 3, 1, 240, 217, 98, 3, 1, 240, 235, 98, 3, 1, 238, 230, 98,
+ 3, 1, 249, 190, 98, 3, 1, 240, 177, 98, 3, 1, 243, 193, 98, 3, 1, 249,
+ 132, 98, 3, 1, 253, 175, 98, 3, 1, 244, 14, 98, 3, 1, 248, 140, 98, 3, 1,
+ 238, 170, 98, 3, 1, 248, 46, 98, 3, 1, 243, 83, 98, 3, 1, 244, 57, 98, 3,
+ 1, 244, 56, 98, 3, 1, 238, 221, 219, 98, 3, 1, 253, 161, 98, 3, 1, 3,
+ 248, 74, 98, 3, 1, 3, 254, 136, 2, 242, 226, 98, 3, 1, 253, 162, 98, 3,
+ 1, 238, 117, 3, 248, 74, 98, 3, 1, 253, 213, 248, 74, 98, 3, 1, 238, 117,
+ 253, 213, 248, 74, 98, 3, 1, 243, 57, 98, 3, 1, 236, 215, 98, 3, 1, 237,
+ 40, 98, 3, 1, 234, 87, 67, 98, 3, 1, 237, 19, 236, 216, 62, 5, 1, 243,
+ 141, 62, 3, 1, 243, 141, 62, 5, 1, 244, 47, 62, 3, 1, 244, 47, 62, 5, 1,
+ 240, 10, 62, 3, 1, 240, 10, 62, 5, 1, 240, 164, 62, 3, 1, 240, 164, 62,
+ 5, 1, 248, 154, 62, 3, 1, 248, 154, 62, 5, 1, 249, 167, 62, 3, 1, 249,
+ 167, 62, 5, 1, 244, 65, 62, 3, 1, 244, 65, 62, 5, 1, 243, 190, 62, 3, 1,
+ 243, 190, 62, 5, 1, 238, 226, 62, 3, 1, 238, 226, 62, 5, 1, 240, 191, 62,
+ 3, 1, 240, 191, 62, 5, 1, 243, 62, 62, 3, 1, 243, 62, 62, 5, 1, 240, 197,
+ 62, 3, 1, 240, 197, 62, 5, 1, 253, 180, 62, 3, 1, 253, 180, 62, 5, 1,
+ 253, 166, 62, 3, 1, 253, 166, 62, 5, 1, 248, 163, 62, 3, 1, 248, 163, 62,
+ 5, 1, 73, 62, 3, 1, 73, 62, 5, 1, 253, 147, 62, 3, 1, 253, 147, 62, 5, 1,
+ 253, 160, 62, 3, 1, 253, 160, 62, 5, 1, 243, 123, 62, 3, 1, 243, 123, 62,
+ 5, 1, 248, 85, 62, 3, 1, 248, 85, 62, 5, 1, 254, 74, 62, 3, 1, 254, 74,
+ 62, 5, 1, 253, 245, 62, 3, 1, 253, 245, 62, 5, 1, 248, 219, 62, 3, 1,
+ 248, 219, 62, 5, 1, 248, 69, 62, 3, 1, 248, 69, 62, 5, 1, 248, 179, 62,
+ 3, 1, 248, 179, 62, 5, 1, 235, 67, 243, 3, 62, 3, 1, 235, 67, 243, 3, 62,
+ 5, 1, 76, 62, 248, 105, 62, 3, 1, 76, 62, 248, 105, 62, 5, 1, 231, 93,
+ 248, 154, 62, 3, 1, 231, 93, 248, 154, 62, 5, 1, 235, 67, 243, 62, 62, 3,
+ 1, 235, 67, 243, 62, 62, 5, 1, 235, 67, 253, 166, 62, 3, 1, 235, 67, 253,
+ 166, 62, 5, 1, 231, 93, 253, 166, 62, 3, 1, 231, 93, 253, 166, 62, 5, 1,
+ 76, 62, 248, 179, 62, 3, 1, 76, 62, 248, 179, 62, 5, 1, 240, 121, 62, 3,
+ 1, 240, 121, 62, 5, 1, 238, 133, 243, 32, 62, 3, 1, 238, 133, 243, 32,
+ 62, 5, 1, 76, 62, 243, 32, 62, 3, 1, 76, 62, 243, 32, 62, 5, 1, 76, 62,
+ 248, 93, 62, 3, 1, 76, 62, 248, 93, 62, 5, 1, 236, 245, 243, 64, 62, 3,
+ 1, 236, 245, 243, 64, 62, 5, 1, 235, 67, 243, 28, 62, 3, 1, 235, 67, 243,
+ 28, 62, 5, 1, 76, 62, 243, 28, 62, 3, 1, 76, 62, 243, 28, 62, 5, 1, 76,
+ 62, 219, 62, 3, 1, 76, 62, 219, 62, 5, 1, 237, 18, 219, 62, 3, 1, 237,
+ 18, 219, 62, 5, 1, 76, 62, 249, 81, 62, 3, 1, 76, 62, 249, 81, 62, 5, 1,
+ 76, 62, 248, 214, 62, 3, 1, 76, 62, 248, 214, 62, 5, 1, 76, 62, 238, 115,
+ 62, 3, 1, 76, 62, 238, 115, 62, 5, 1, 76, 62, 249, 54, 62, 3, 1, 76, 62,
+ 249, 54, 62, 5, 1, 76, 62, 240, 88, 62, 3, 1, 76, 62, 240, 88, 62, 5, 1,
+ 76, 240, 43, 240, 88, 62, 3, 1, 76, 240, 43, 240, 88, 62, 5, 1, 76, 240,
+ 43, 248, 232, 62, 3, 1, 76, 240, 43, 248, 232, 62, 5, 1, 76, 240, 43,
+ 248, 178, 62, 3, 1, 76, 240, 43, 248, 178, 62, 5, 1, 76, 240, 43, 249,
+ 198, 62, 3, 1, 76, 240, 43, 249, 198, 62, 12, 249, 91, 62, 12, 255, 82,
+ 253, 160, 62, 12, 255, 29, 253, 160, 62, 12, 238, 13, 62, 12, 254, 244,
+ 253, 160, 62, 12, 254, 184, 253, 160, 62, 12, 247, 74, 243, 123, 62, 76,
+ 240, 43, 248, 37, 208, 62, 76, 240, 43, 240, 169, 236, 156, 69, 62, 76,
+ 240, 43, 237, 179, 236, 156, 69, 62, 76, 240, 43, 244, 46, 236, 213, 62,
+ 236, 155, 253, 125, 243, 7, 62, 248, 37, 208, 62, 231, 149, 236, 213, 75,
+ 3, 1, 254, 19, 75, 3, 1, 248, 195, 75, 3, 1, 248, 158, 75, 3, 1, 248,
+ 205, 75, 3, 1, 253, 202, 75, 3, 1, 249, 11, 75, 3, 1, 249, 25, 75, 3, 1,
+ 248, 253, 75, 3, 1, 253, 247, 75, 3, 1, 248, 162, 75, 3, 1, 248, 224, 75,
+ 3, 1, 248, 131, 75, 3, 1, 248, 171, 75, 3, 1, 254, 9, 75, 3, 1, 248, 236,
+ 75, 3, 1, 243, 138, 75, 3, 1, 248, 243, 75, 3, 1, 248, 134, 75, 3, 1,
+ 248, 254, 75, 3, 1, 254, 75, 75, 3, 1, 243, 115, 75, 3, 1, 243, 103, 75,
+ 3, 1, 243, 95, 75, 3, 1, 248, 242, 75, 3, 1, 243, 33, 75, 3, 1, 243, 88,
+ 75, 3, 1, 248, 100, 75, 3, 1, 248, 217, 75, 3, 1, 248, 201, 75, 3, 1,
+ 243, 87, 75, 3, 1, 249, 16, 75, 3, 1, 243, 101, 75, 3, 1, 248, 212, 75,
+ 3, 1, 253, 168, 75, 3, 1, 248, 160, 75, 3, 1, 253, 170, 75, 3, 1, 248,
+ 213, 75, 3, 1, 248, 215, 174, 1, 216, 174, 1, 253, 65, 174, 1, 247, 213,
+ 174, 1, 253, 68, 174, 1, 242, 193, 174, 1, 240, 158, 238, 157, 249, 202,
+ 174, 1, 249, 202, 174, 1, 253, 66, 174, 1, 247, 216, 174, 1, 247, 215,
+ 174, 1, 242, 192, 174, 1, 253, 79, 174, 1, 253, 67, 174, 1, 249, 20, 174,
+ 1, 240, 66, 249, 20, 174, 1, 242, 194, 174, 1, 249, 19, 174, 1, 240, 158,
+ 238, 157, 249, 19, 174, 1, 240, 66, 249, 19, 174, 1, 247, 218, 174, 1,
+ 248, 191, 174, 1, 244, 55, 174, 1, 240, 66, 244, 55, 174, 1, 249, 204,
+ 174, 1, 240, 66, 249, 204, 174, 1, 253, 189, 174, 1, 243, 135, 174, 1,
+ 238, 239, 243, 135, 174, 1, 240, 66, 243, 135, 174, 1, 253, 69, 174, 1,
+ 253, 70, 174, 1, 249, 203, 174, 1, 240, 66, 247, 217, 174, 1, 240, 66,
+ 243, 50, 174, 1, 253, 71, 174, 1, 253, 161, 174, 1, 253, 72, 174, 1, 247,
+ 219, 174, 1, 243, 134, 174, 1, 240, 66, 243, 134, 174, 1, 249, 246, 243,
+ 134, 174, 1, 253, 73, 174, 1, 247, 221, 174, 1, 247, 220, 174, 1, 249,
+ 21, 174, 1, 247, 222, 174, 1, 247, 214, 174, 1, 247, 223, 174, 1, 253,
+ 74, 174, 1, 253, 75, 174, 1, 253, 76, 174, 1, 249, 205, 174, 1, 235, 32,
+ 249, 205, 174, 1, 247, 224, 174, 49, 1, 231, 146, 69, 22, 4, 251, 202,
+ 22, 4, 251, 239, 22, 4, 252, 142, 22, 4, 252, 183, 22, 4, 247, 75, 22, 4,
+ 250, 128, 22, 4, 252, 226, 22, 4, 250, 165, 22, 4, 252, 32, 22, 4, 246,
+ 205, 22, 4, 238, 62, 254, 117, 22, 4, 253, 109, 22, 4, 250, 202, 22, 4,
+ 245, 49, 22, 4, 251, 122, 22, 4, 247, 145, 22, 4, 245, 4, 22, 4, 246,
+ 246, 22, 4, 252, 71, 22, 4, 245, 116, 22, 4, 245, 118, 22, 4, 241, 135,
+ 22, 4, 245, 117, 22, 4, 248, 66, 22, 4, 248, 251, 22, 4, 248, 249, 22, 4,
+ 247, 99, 22, 4, 247, 103, 22, 4, 249, 168, 22, 4, 248, 250, 22, 4, 250,
+ 148, 22, 4, 250, 152, 22, 4, 250, 150, 22, 4, 244, 245, 22, 4, 244, 246,
+ 22, 4, 250, 149, 22, 4, 250, 151, 22, 4, 249, 224, 22, 4, 249, 228, 22,
+ 4, 249, 226, 22, 4, 248, 15, 22, 4, 248, 19, 22, 4, 249, 225, 22, 4, 249,
+ 227, 22, 4, 244, 247, 22, 4, 244, 251, 22, 4, 244, 249, 22, 4, 241, 45,
+ 22, 4, 241, 46, 22, 4, 244, 248, 22, 4, 244, 250, 22, 4, 252, 115, 22, 4,
+ 252, 122, 22, 4, 252, 117, 22, 4, 247, 23, 22, 4, 247, 24, 22, 4, 252,
+ 116, 22, 4, 252, 118, 22, 4, 251, 175, 22, 4, 251, 179, 22, 4, 251, 177,
+ 22, 4, 246, 31, 22, 4, 246, 32, 22, 4, 251, 176, 22, 4, 251, 178, 22, 4,
+ 253, 56, 22, 4, 253, 63, 22, 4, 253, 58, 22, 4, 247, 208, 22, 4, 247,
+ 209, 22, 4, 253, 57, 22, 4, 253, 59, 22, 4, 251, 39, 22, 4, 251, 44, 22,
+ 4, 251, 42, 22, 4, 245, 136, 22, 4, 245, 137, 22, 4, 251, 40, 22, 4, 251,
+ 43, 38, 185, 232, 79, 238, 95, 38, 185, 240, 4, 232, 79, 238, 95, 40,
+ 232, 79, 104, 38, 232, 79, 104, 40, 240, 4, 232, 79, 104, 38, 240, 4,
+ 232, 79, 104, 240, 84, 231, 107, 238, 95, 240, 84, 240, 4, 231, 107, 238,
+ 95, 240, 4, 231, 100, 238, 95, 40, 231, 100, 104, 38, 231, 100, 104, 240,
+ 84, 238, 59, 40, 240, 84, 237, 26, 104, 38, 240, 84, 237, 26, 104, 236,
+ 11, 237, 92, 232, 95, 240, 176, 232, 95, 224, 240, 176, 232, 95, 231,
+ 140, 240, 4, 239, 149, 235, 45, 238, 160, 226, 226, 238, 160, 240, 4,
+ 231, 36, 240, 54, 45, 238, 106, 238, 93, 40, 170, 234, 61, 104, 38, 170,
+ 234, 61, 104, 7, 25, 239, 173, 7, 25, 240, 131, 7, 25, 240, 87, 127, 7,
+ 25, 240, 87, 111, 7, 25, 240, 87, 166, 7, 25, 239, 160, 7, 25, 248, 92,
+ 7, 25, 240, 241, 7, 25, 243, 209, 127, 7, 25, 243, 209, 111, 7, 25, 233,
+ 83, 7, 25, 244, 5, 7, 25, 3, 127, 7, 25, 3, 111, 7, 25, 248, 164, 127, 7,
+ 25, 248, 164, 111, 7, 25, 248, 164, 166, 7, 25, 248, 164, 177, 7, 25,
+ 242, 119, 7, 25, 238, 228, 7, 25, 244, 21, 127, 7, 25, 244, 21, 111, 7,
+ 25, 243, 16, 127, 7, 25, 243, 16, 111, 7, 25, 243, 59, 7, 25, 248, 244,
+ 7, 25, 241, 54, 7, 25, 248, 136, 7, 25, 243, 30, 7, 25, 240, 167, 7, 25,
+ 239, 140, 7, 25, 235, 189, 7, 25, 244, 50, 127, 7, 25, 244, 50, 111, 7,
+ 25, 243, 27, 7, 25, 254, 122, 127, 7, 25, 254, 122, 111, 7, 25, 234, 23,
+ 137, 249, 185, 240, 247, 7, 25, 248, 202, 7, 25, 249, 56, 7, 25, 243,
+ 199, 7, 25, 249, 33, 147, 240, 132, 7, 25, 249, 59, 7, 25, 240, 237, 127,
+ 7, 25, 240, 237, 111, 7, 25, 238, 164, 7, 25, 243, 122, 7, 25, 232, 72,
+ 243, 122, 7, 25, 254, 41, 127, 7, 25, 254, 41, 111, 7, 25, 254, 41, 166,
+ 7, 25, 254, 41, 177, 7, 25, 246, 65, 7, 25, 240, 225, 7, 25, 249, 151, 7,
+ 25, 249, 58, 7, 25, 249, 129, 7, 25, 243, 151, 127, 7, 25, 243, 151, 111,
+ 7, 25, 243, 222, 7, 25, 238, 202, 7, 25, 243, 97, 127, 7, 25, 243, 97,
+ 111, 7, 25, 243, 97, 166, 7, 25, 240, 245, 7, 25, 236, 255, 7, 25, 248,
+ 56, 127, 7, 25, 248, 56, 111, 7, 25, 232, 72, 248, 184, 7, 25, 234, 23,
+ 243, 8, 7, 25, 243, 8, 7, 25, 232, 72, 238, 220, 7, 25, 232, 72, 240,
+ 227, 7, 25, 243, 94, 7, 25, 232, 72, 243, 154, 7, 25, 234, 23, 244, 48,
+ 7, 25, 249, 13, 127, 7, 25, 249, 13, 111, 7, 25, 243, 156, 7, 25, 232,
+ 72, 243, 96, 7, 25, 183, 127, 7, 25, 183, 111, 7, 25, 232, 72, 243, 66,
+ 7, 25, 232, 72, 243, 178, 7, 25, 243, 227, 127, 7, 25, 243, 227, 111, 7,
+ 25, 243, 250, 7, 25, 243, 149, 7, 25, 232, 72, 240, 242, 236, 230, 7, 25,
+ 232, 72, 243, 214, 7, 25, 232, 72, 243, 82, 7, 25, 232, 72, 249, 63, 7,
+ 25, 254, 58, 127, 7, 25, 254, 58, 111, 7, 25, 254, 58, 166, 7, 25, 232,
+ 72, 248, 207, 7, 25, 243, 99, 7, 25, 232, 72, 240, 189, 7, 25, 243, 150,
+ 7, 25, 240, 181, 7, 25, 232, 72, 243, 172, 7, 25, 232, 72, 243, 85, 7,
+ 25, 232, 72, 244, 4, 7, 25, 234, 23, 240, 153, 7, 25, 234, 23, 238, 232,
+ 7, 25, 232, 72, 243, 176, 7, 25, 232, 84, 243, 93, 7, 25, 232, 72, 243,
+ 93, 7, 25, 232, 84, 240, 151, 7, 25, 232, 72, 240, 151, 7, 25, 232, 84,
+ 238, 137, 7, 25, 232, 72, 238, 137, 7, 25, 238, 125, 7, 25, 232, 84, 238,
+ 125, 7, 25, 232, 72, 238, 125, 43, 25, 127, 43, 25, 242, 224, 43, 25,
+ 248, 40, 43, 25, 240, 37, 43, 25, 239, 185, 43, 25, 90, 43, 25, 111, 43,
+ 25, 251, 195, 43, 25, 248, 131, 43, 25, 246, 41, 43, 25, 241, 95, 43, 25,
+ 195, 43, 25, 92, 248, 92, 43, 25, 241, 67, 43, 25, 249, 84, 43, 25, 240,
+ 241, 43, 25, 248, 35, 248, 92, 43, 25, 241, 204, 43, 25, 240, 210, 43,
+ 25, 247, 197, 43, 25, 242, 125, 43, 25, 38, 248, 35, 248, 92, 43, 25,
+ 241, 150, 234, 36, 43, 25, 248, 53, 43, 25, 233, 83, 43, 25, 244, 5, 43,
+ 25, 240, 131, 43, 25, 237, 243, 43, 25, 241, 6, 43, 25, 240, 201, 43, 25,
+ 234, 36, 43, 25, 240, 49, 43, 25, 238, 2, 43, 25, 253, 234, 43, 25, 255,
+ 75, 239, 198, 43, 25, 237, 153, 43, 25, 250, 123, 43, 25, 240, 253, 43,
+ 25, 241, 52, 43, 25, 247, 34, 43, 25, 245, 227, 43, 25, 240, 147, 43, 25,
+ 246, 37, 43, 25, 239, 32, 43, 25, 239, 202, 43, 25, 235, 102, 43, 25,
+ 242, 84, 43, 25, 247, 196, 43, 25, 237, 226, 43, 25, 239, 232, 43, 25,
+ 250, 207, 43, 25, 242, 215, 238, 228, 43, 25, 240, 4, 240, 131, 43, 25,
+ 183, 239, 206, 43, 25, 171, 241, 147, 43, 25, 242, 107, 43, 25, 248, 198,
+ 43, 25, 242, 120, 43, 25, 237, 80, 43, 25, 247, 121, 43, 25, 240, 138,
+ 43, 25, 237, 169, 43, 25, 245, 72, 43, 25, 243, 59, 43, 25, 239, 12, 43,
+ 25, 248, 244, 43, 25, 239, 183, 43, 25, 239, 44, 43, 25, 249, 245, 43,
+ 25, 238, 59, 43, 25, 248, 233, 43, 25, 248, 136, 43, 25, 252, 169, 43,
+ 25, 243, 30, 43, 25, 244, 37, 43, 25, 246, 35, 43, 25, 208, 43, 25, 240,
+ 167, 43, 25, 239, 247, 43, 25, 255, 48, 248, 233, 43, 25, 237, 89, 43,
+ 25, 249, 64, 43, 25, 245, 21, 43, 25, 242, 133, 43, 25, 240, 105, 43, 25,
+ 243, 27, 43, 25, 245, 22, 43, 25, 239, 67, 43, 25, 45, 206, 43, 25, 137,
+ 249, 185, 240, 247, 43, 25, 242, 115, 43, 25, 245, 89, 43, 25, 248, 202,
+ 43, 25, 249, 56, 43, 25, 236, 80, 43, 25, 243, 199, 43, 25, 241, 233, 43,
+ 25, 247, 151, 43, 25, 242, 136, 43, 25, 246, 51, 43, 25, 253, 5, 43, 25,
+ 241, 106, 43, 25, 249, 33, 147, 240, 132, 43, 25, 236, 103, 43, 25, 240,
+ 4, 247, 139, 43, 25, 240, 39, 43, 25, 247, 91, 43, 25, 245, 68, 43, 25,
+ 249, 59, 43, 25, 240, 236, 43, 25, 56, 43, 25, 242, 134, 43, 25, 239,
+ 201, 43, 25, 242, 156, 43, 25, 241, 140, 43, 25, 244, 243, 43, 25, 242,
+ 131, 43, 25, 238, 164, 43, 25, 247, 30, 43, 25, 243, 122, 43, 25, 251,
+ 111, 43, 25, 252, 14, 43, 25, 240, 225, 43, 25, 237, 156, 43, 25, 249,
+ 129, 43, 25, 248, 91, 43, 25, 246, 252, 43, 25, 248, 206, 43, 25, 241,
+ 39, 43, 25, 243, 222, 43, 25, 236, 61, 43, 25, 244, 6, 43, 25, 238, 249,
+ 43, 25, 238, 202, 43, 25, 238, 156, 43, 25, 239, 153, 43, 25, 244, 226,
+ 43, 25, 236, 108, 43, 25, 241, 63, 43, 25, 241, 142, 43, 25, 240, 245,
+ 43, 25, 239, 100, 43, 25, 241, 34, 43, 25, 249, 13, 234, 36, 43, 25, 236,
+ 255, 43, 25, 247, 194, 43, 25, 248, 184, 43, 25, 243, 8, 43, 25, 238,
+ 220, 43, 25, 239, 238, 43, 25, 244, 213, 43, 25, 252, 66, 43, 25, 239, 1,
+ 43, 25, 240, 227, 43, 25, 252, 131, 43, 25, 252, 151, 43, 25, 243, 94,
+ 43, 25, 244, 227, 43, 25, 243, 154, 43, 25, 239, 9, 43, 25, 237, 214, 43,
+ 25, 244, 48, 43, 25, 243, 156, 43, 25, 243, 133, 43, 25, 232, 132, 43,
+ 25, 238, 43, 43, 25, 243, 96, 43, 25, 243, 66, 43, 25, 243, 178, 43, 25,
+ 241, 249, 43, 25, 242, 114, 43, 25, 242, 215, 242, 139, 243, 85, 43, 25,
+ 243, 250, 43, 25, 243, 149, 43, 25, 242, 187, 43, 25, 243, 39, 43, 25,
+ 236, 230, 43, 25, 240, 242, 236, 230, 43, 25, 246, 40, 43, 25, 242, 121,
+ 43, 25, 243, 214, 43, 25, 243, 82, 43, 25, 249, 63, 43, 25, 248, 207, 43,
+ 25, 243, 99, 43, 25, 236, 27, 43, 25, 240, 189, 43, 25, 243, 150, 43, 25,
+ 247, 137, 43, 25, 245, 140, 43, 25, 241, 108, 43, 25, 233, 232, 243, 133,
+ 43, 25, 235, 117, 43, 25, 240, 181, 43, 25, 243, 172, 43, 25, 243, 85,
+ 43, 25, 244, 4, 43, 25, 243, 164, 43, 25, 240, 153, 43, 25, 245, 141, 43,
+ 25, 238, 232, 43, 25, 239, 137, 43, 25, 240, 0, 43, 25, 233, 195, 43, 25,
+ 243, 176, 43, 25, 239, 229, 43, 25, 245, 74, 43, 25, 249, 152, 43, 25,
+ 246, 176, 43, 25, 243, 93, 43, 25, 240, 151, 43, 25, 238, 137, 43, 25,
+ 238, 125, 43, 25, 241, 112, 80, 233, 55, 99, 40, 153, 225, 80, 233, 55,
+ 99, 60, 153, 46, 80, 233, 55, 99, 40, 153, 240, 1, 19, 225, 80, 233, 55,
+ 99, 60, 153, 240, 1, 19, 46, 80, 233, 55, 99, 248, 37, 236, 121, 80, 233,
+ 55, 99, 236, 204, 248, 44, 48, 80, 233, 55, 99, 236, 204, 248, 44, 46,
+ 80, 233, 55, 99, 236, 204, 248, 44, 242, 220, 80, 233, 55, 99, 236, 204,
+ 248, 44, 189, 242, 220, 80, 233, 55, 99, 236, 204, 248, 44, 189, 225, 80,
+ 233, 55, 99, 236, 204, 248, 44, 168, 242, 220, 80, 233, 55, 99, 236, 66,
+ 80, 240, 15, 80, 240, 27, 80, 248, 37, 208, 245, 69, 69, 237, 184, 234,
+ 206, 237, 44, 91, 80, 235, 77, 69, 80, 238, 171, 69, 80, 61, 242, 217,
+ 40, 185, 104, 38, 185, 104, 40, 45, 185, 104, 38, 45, 185, 104, 40, 240,
+ 31, 104, 38, 240, 31, 104, 40, 64, 240, 31, 104, 38, 64, 240, 31, 104,
+ 40, 86, 234, 11, 104, 38, 86, 234, 11, 104, 240, 142, 69, 251, 16, 69,
+ 40, 236, 171, 242, 255, 104, 38, 236, 171, 242, 255, 104, 40, 64, 234,
+ 11, 104, 38, 64, 234, 11, 104, 40, 64, 236, 171, 242, 255, 104, 38, 64,
+ 236, 171, 242, 255, 104, 40, 64, 31, 104, 38, 64, 31, 104, 248, 141, 242,
+ 235, 224, 45, 243, 117, 235, 51, 69, 45, 243, 117, 235, 51, 69, 170, 45,
+ 243, 117, 235, 51, 69, 240, 142, 158, 243, 39, 236, 166, 178, 127, 236,
+ 166, 178, 111, 236, 166, 178, 166, 236, 166, 178, 177, 236, 166, 178,
+ 176, 236, 166, 178, 187, 236, 166, 178, 203, 236, 166, 178, 195, 236,
+ 166, 178, 202, 80, 246, 42, 188, 69, 80, 240, 69, 188, 69, 80, 235, 98,
+ 188, 69, 80, 237, 151, 188, 69, 23, 240, 12, 53, 188, 69, 23, 45, 53,
+ 188, 69, 248, 103, 242, 235, 59, 248, 130, 240, 64, 69, 59, 248, 130,
+ 240, 64, 2, 240, 59, 243, 1, 69, 59, 248, 130, 240, 64, 158, 189, 243, 7,
+ 59, 248, 130, 240, 64, 2, 240, 59, 243, 1, 158, 189, 243, 7, 59, 248,
+ 130, 240, 64, 158, 168, 243, 7, 29, 240, 142, 69, 80, 145, 248, 41, 250,
+ 237, 235, 95, 91, 236, 166, 178, 248, 53, 236, 166, 178, 238, 77, 236,
+ 166, 178, 238, 101, 59, 80, 235, 77, 69, 251, 219, 69, 249, 134, 233,
+ 112, 69, 80, 34, 234, 30, 80, 137, 250, 245, 240, 15, 105, 1, 3, 67, 105,
+ 1, 67, 105, 1, 3, 71, 105, 1, 71, 105, 1, 3, 79, 105, 1, 79, 105, 1, 3,
+ 72, 105, 1, 72, 105, 1, 3, 73, 105, 1, 73, 105, 1, 201, 105, 1, 253, 139,
+ 105, 1, 253, 215, 105, 1, 254, 6, 105, 1, 253, 203, 105, 1, 253, 235,
+ 105, 1, 253, 172, 105, 1, 254, 5, 105, 1, 253, 190, 105, 1, 253, 234,
+ 105, 1, 253, 132, 105, 1, 253, 163, 105, 1, 253, 198, 105, 1, 254, 17,
+ 105, 1, 253, 211, 105, 1, 254, 18, 105, 1, 253, 210, 105, 1, 253, 228,
+ 105, 1, 253, 186, 105, 1, 253, 222, 105, 1, 253, 126, 105, 1, 253, 133,
+ 105, 1, 253, 212, 105, 1, 253, 201, 105, 1, 3, 253, 196, 105, 1, 253,
+ 196, 105, 1, 253, 232, 105, 1, 253, 195, 105, 1, 253, 200, 105, 1, 87,
+ 105, 1, 253, 225, 105, 1, 253, 131, 105, 1, 253, 166, 105, 1, 253, 150,
+ 105, 1, 253, 197, 105, 1, 253, 173, 105, 1, 219, 105, 1, 253, 141, 105,
+ 1, 253, 129, 105, 1, 253, 214, 105, 1, 254, 34, 105, 1, 253, 147, 105, 1,
+ 253, 236, 105, 1, 253, 243, 105, 1, 253, 239, 105, 1, 253, 168, 105, 1,
+ 253, 242, 105, 1, 253, 175, 105, 1, 253, 184, 105, 1, 254, 1, 105, 1,
+ 253, 208, 105, 1, 222, 105, 1, 253, 180, 105, 1, 253, 154, 105, 1, 253,
+ 206, 105, 1, 253, 181, 105, 1, 3, 216, 105, 1, 216, 105, 1, 3, 253, 161,
+ 105, 1, 253, 161, 105, 1, 3, 253, 162, 105, 1, 253, 162, 105, 1, 253,
+ 130, 105, 1, 253, 209, 105, 1, 253, 185, 105, 1, 253, 194, 105, 1, 253,
+ 160, 105, 1, 3, 253, 138, 105, 1, 253, 138, 105, 1, 253, 187, 105, 1,
+ 253, 170, 105, 1, 253, 177, 105, 1, 197, 105, 1, 254, 49, 105, 1, 3, 201,
+ 105, 1, 3, 253, 172, 50, 226, 254, 240, 59, 243, 1, 69, 50, 226, 254,
+ 233, 75, 243, 1, 69, 226, 254, 240, 59, 243, 1, 69, 226, 254, 233, 75,
+ 243, 1, 69, 105, 235, 77, 69, 105, 240, 59, 235, 77, 69, 105, 238, 112,
+ 247, 233, 226, 254, 45, 238, 93, 42, 1, 3, 67, 42, 1, 67, 42, 1, 3, 71,
+ 42, 1, 71, 42, 1, 3, 79, 42, 1, 79, 42, 1, 3, 72, 42, 1, 72, 42, 1, 3,
+ 73, 42, 1, 73, 42, 1, 201, 42, 1, 253, 139, 42, 1, 253, 215, 42, 1, 254,
+ 6, 42, 1, 253, 203, 42, 1, 253, 235, 42, 1, 253, 172, 42, 1, 254, 5, 42,
+ 1, 253, 190, 42, 1, 253, 234, 42, 1, 253, 132, 42, 1, 253, 163, 42, 1,
+ 253, 198, 42, 1, 254, 17, 42, 1, 253, 211, 42, 1, 254, 18, 42, 1, 253,
+ 210, 42, 1, 253, 228, 42, 1, 253, 186, 42, 1, 253, 222, 42, 1, 253, 126,
+ 42, 1, 253, 133, 42, 1, 253, 212, 42, 1, 253, 201, 42, 1, 3, 253, 196,
+ 42, 1, 253, 196, 42, 1, 253, 232, 42, 1, 253, 195, 42, 1, 253, 200, 42,
+ 1, 87, 42, 1, 253, 225, 42, 1, 253, 131, 42, 1, 253, 166, 42, 1, 253,
+ 150, 42, 1, 253, 197, 42, 1, 253, 173, 42, 1, 219, 42, 1, 253, 141, 42,
+ 1, 253, 129, 42, 1, 253, 214, 42, 1, 254, 34, 42, 1, 253, 147, 42, 1,
+ 253, 236, 42, 1, 253, 243, 42, 1, 253, 239, 42, 1, 253, 168, 42, 1, 253,
+ 242, 42, 1, 253, 175, 42, 1, 253, 184, 42, 1, 254, 1, 42, 1, 253, 208,
+ 42, 1, 222, 42, 1, 253, 180, 42, 1, 253, 154, 42, 1, 253, 206, 42, 1,
+ 253, 181, 42, 1, 3, 216, 42, 1, 216, 42, 1, 3, 253, 161, 42, 1, 253, 161,
+ 42, 1, 3, 253, 162, 42, 1, 253, 162, 42, 1, 253, 130, 42, 1, 253, 209,
+ 42, 1, 253, 185, 42, 1, 253, 194, 42, 1, 253, 160, 42, 1, 3, 253, 138,
+ 42, 1, 253, 138, 42, 1, 253, 187, 42, 1, 253, 170, 42, 1, 253, 177, 42,
+ 1, 197, 42, 1, 254, 49, 42, 1, 3, 201, 42, 1, 3, 253, 172, 42, 1, 253,
+ 171, 42, 1, 254, 48, 42, 1, 254, 12, 42, 1, 254, 13, 42, 240, 1, 248, 40,
+ 226, 254, 235, 138, 243, 1, 69, 42, 235, 77, 69, 42, 240, 59, 235, 77,
+ 69, 42, 238, 112, 246, 19, 155, 1, 217, 155, 1, 223, 155, 1, 173, 155, 1,
+ 255, 19, 155, 1, 209, 155, 1, 214, 155, 1, 197, 155, 1, 162, 155, 1, 210,
+ 155, 1, 255, 15, 155, 1, 192, 155, 1, 221, 155, 1, 255, 20, 155, 1, 206,
+ 155, 1, 255, 11, 155, 1, 254, 151, 155, 1, 254, 72, 155, 1, 144, 155, 1,
+ 255, 17, 155, 1, 255, 18, 155, 1, 193, 155, 1, 67, 155, 1, 73, 155, 1,
+ 72, 155, 1, 254, 36, 155, 1, 253, 149, 155, 1, 254, 89, 155, 1, 253, 151,
+ 155, 1, 254, 10, 155, 1, 254, 19, 155, 1, 253, 202, 155, 1, 248, 124,
+ 155, 1, 248, 108, 155, 1, 254, 4, 155, 1, 71, 155, 1, 79, 155, 1, 254,
+ 101, 155, 1, 179, 155, 1, 254, 26, 155, 1, 254, 168, 23, 1, 238, 99, 23,
+ 1, 232, 87, 23, 1, 232, 91, 23, 1, 240, 80, 23, 1, 232, 93, 23, 1, 232,
+ 94, 23, 1, 238, 102, 23, 1, 232, 101, 23, 1, 240, 85, 23, 1, 231, 98, 23,
+ 1, 232, 96, 23, 1, 232, 97, 23, 1, 233, 74, 23, 1, 231, 43, 23, 1, 231,
+ 42, 23, 1, 232, 85, 23, 1, 240, 78, 23, 1, 240, 83, 23, 1, 233, 79, 23,
+ 1, 233, 66, 23, 1, 243, 34, 23, 1, 234, 32, 23, 1, 240, 75, 23, 1, 240,
+ 71, 23, 1, 233, 77, 23, 1, 236, 195, 23, 1, 236, 198, 23, 1, 236, 205,
+ 23, 1, 236, 201, 23, 1, 240, 74, 23, 1, 67, 23, 1, 253, 178, 23, 1, 216,
+ 23, 1, 249, 18, 23, 1, 254, 59, 23, 1, 72, 23, 1, 249, 22, 23, 1, 253,
+ 254, 23, 1, 73, 23, 1, 253, 138, 23, 1, 249, 12, 23, 1, 253, 193, 23, 1,
+ 253, 162, 23, 1, 79, 23, 1, 249, 14, 23, 1, 253, 170, 23, 1, 253, 187,
+ 23, 1, 253, 161, 23, 1, 254, 61, 23, 1, 253, 189, 23, 1, 71, 23, 238,
+ 114, 23, 1, 233, 105, 23, 1, 231, 97, 23, 1, 233, 90, 23, 1, 231, 47, 23,
+ 1, 226, 245, 23, 1, 231, 111, 23, 1, 226, 255, 23, 1, 231, 54, 23, 1,
+ 226, 246, 23, 1, 232, 92, 23, 1, 233, 86, 23, 1, 231, 46, 23, 1, 231, 40,
+ 23, 1, 231, 109, 23, 1, 231, 110, 23, 1, 226, 243, 23, 1, 226, 244, 23,
+ 1, 232, 106, 23, 1, 231, 52, 23, 1, 231, 41, 23, 1, 226, 235, 23, 1, 232,
+ 99, 23, 1, 233, 102, 23, 1, 232, 100, 23, 1, 233, 76, 23, 1, 233, 101,
+ 23, 1, 236, 234, 23, 1, 233, 78, 23, 1, 235, 115, 23, 1, 231, 58, 23, 1,
+ 227, 0, 23, 1, 227, 9, 23, 1, 233, 104, 23, 1, 232, 102, 23, 1, 240, 255,
+ 23, 1, 238, 233, 23, 1, 244, 58, 23, 1, 238, 234, 23, 1, 241, 0, 23, 1,
+ 244, 60, 23, 1, 240, 156, 23, 1, 238, 247, 80, 234, 4, 239, 123, 69, 80,
+ 234, 4, 238, 75, 69, 80, 234, 4, 253, 125, 69, 80, 234, 4, 171, 69, 80,
+ 234, 4, 204, 69, 80, 234, 4, 248, 58, 69, 80, 234, 4, 253, 159, 69, 80,
+ 234, 4, 240, 1, 69, 80, 234, 4, 240, 17, 69, 80, 234, 4, 243, 41, 69, 80,
+ 234, 4, 240, 87, 69, 80, 234, 4, 243, 129, 69, 80, 234, 4, 240, 137, 69,
+ 80, 234, 4, 241, 148, 69, 80, 234, 4, 243, 168, 69, 80, 234, 4, 254, 111,
+ 69, 155, 1, 253, 243, 155, 1, 254, 17, 155, 1, 254, 7, 155, 1, 253, 235,
+ 155, 1, 253, 164, 155, 1, 250, 224, 155, 1, 253, 156, 155, 1, 249, 130,
+ 155, 1, 254, 177, 155, 1, 249, 238, 155, 1, 251, 105, 155, 1, 252, 254,
+ 155, 1, 254, 175, 155, 1, 252, 18, 155, 1, 244, 73, 155, 1, 244, 86, 155,
+ 1, 254, 32, 155, 1, 254, 43, 155, 1, 252, 59, 155, 1, 245, 229, 155, 30,
+ 1, 223, 155, 30, 1, 214, 155, 30, 1, 255, 15, 155, 30, 1, 192, 7, 240, 5,
+ 214, 7, 240, 5, 255, 3, 7, 240, 5, 255, 5, 7, 240, 5, 250, 137, 7, 240,
+ 5, 254, 128, 7, 240, 5, 251, 96, 7, 240, 5, 251, 93, 7, 240, 5, 254, 97,
+ 7, 240, 5, 245, 219, 7, 240, 5, 247, 134, 7, 240, 5, 251, 94, 7, 240, 5,
+ 245, 220, 7, 240, 5, 245, 202, 7, 240, 5, 251, 95, 7, 240, 5, 245, 221,
+ 7, 240, 5, 197, 42, 1, 3, 253, 203, 42, 1, 3, 253, 198, 42, 1, 3, 253,
+ 211, 42, 1, 3, 87, 42, 1, 3, 253, 150, 42, 1, 3, 219, 42, 1, 3, 253, 214,
+ 42, 1, 3, 253, 236, 42, 1, 3, 253, 168, 42, 1, 3, 253, 184, 42, 1, 3,
+ 253, 154, 42, 1, 3, 253, 130, 42, 1, 3, 253, 209, 42, 1, 3, 253, 185, 42,
+ 1, 3, 253, 194, 42, 1, 3, 253, 160, 82, 23, 238, 99, 82, 23, 240, 80, 82,
+ 23, 238, 102, 82, 23, 240, 85, 82, 23, 240, 78, 82, 23, 240, 83, 82, 23,
+ 243, 34, 82, 23, 240, 75, 82, 23, 240, 71, 82, 23, 236, 195, 82, 23, 236,
+ 198, 82, 23, 236, 205, 82, 23, 236, 201, 82, 23, 240, 74, 82, 23, 240,
+ 193, 67, 82, 23, 243, 233, 67, 82, 23, 240, 246, 67, 82, 23, 243, 254,
+ 67, 82, 23, 243, 226, 67, 82, 23, 243, 242, 67, 82, 23, 249, 164, 67, 82,
+ 23, 243, 100, 67, 82, 23, 243, 90, 67, 82, 23, 238, 169, 67, 82, 23, 238,
+ 194, 67, 82, 23, 238, 227, 67, 82, 23, 238, 206, 67, 82, 23, 243, 195,
+ 67, 82, 23, 243, 90, 79, 82, 240, 99, 99, 242, 39, 82, 240, 99, 99, 117,
+ 253, 236, 82, 110, 127, 82, 110, 111, 82, 110, 166, 82, 110, 177, 82,
+ 110, 176, 82, 110, 187, 82, 110, 203, 82, 110, 195, 82, 110, 202, 82,
+ 110, 248, 53, 82, 110, 243, 30, 82, 110, 243, 27, 82, 110, 240, 105, 82,
+ 110, 244, 52, 82, 110, 240, 199, 82, 110, 240, 49, 82, 110, 248, 136, 82,
+ 110, 240, 238, 82, 110, 243, 191, 82, 110, 237, 41, 82, 110, 243, 230,
+ 82, 110, 237, 43, 82, 110, 234, 53, 82, 110, 229, 61, 82, 110, 240, 195,
+ 82, 110, 234, 247, 82, 110, 244, 241, 82, 110, 240, 239, 82, 110, 234,
+ 66, 82, 110, 233, 84, 82, 110, 235, 140, 82, 110, 235, 116, 82, 110, 236,
+ 20, 82, 110, 242, 239, 82, 110, 244, 6, 82, 110, 240, 215, 233, 94, 52,
+ 29, 61, 240, 48, 127, 29, 61, 240, 48, 111, 29, 61, 240, 48, 166, 29, 61,
+ 240, 48, 177, 29, 61, 240, 48, 176, 29, 61, 240, 48, 187, 29, 61, 240,
+ 48, 203, 29, 61, 240, 48, 195, 29, 61, 240, 48, 202, 29, 61, 238, 101,
+ 29, 61, 240, 53, 127, 29, 61, 240, 53, 111, 29, 61, 240, 53, 166, 29, 61,
+ 240, 53, 177, 29, 61, 240, 53, 176, 29, 23, 238, 99, 29, 23, 240, 80, 29,
+ 23, 238, 102, 29, 23, 240, 85, 29, 23, 240, 78, 29, 23, 240, 83, 29, 23,
+ 243, 34, 29, 23, 240, 75, 29, 23, 240, 71, 29, 23, 236, 195, 29, 23, 236,
+ 198, 29, 23, 236, 205, 29, 23, 236, 201, 29, 23, 240, 74, 29, 23, 240,
+ 193, 67, 29, 23, 243, 233, 67, 29, 23, 240, 246, 67, 29, 23, 243, 254,
+ 67, 29, 23, 243, 226, 67, 29, 23, 243, 242, 67, 29, 23, 249, 164, 67, 29,
+ 23, 243, 100, 67, 29, 23, 243, 90, 67, 29, 23, 238, 169, 67, 29, 23, 238,
+ 194, 67, 29, 23, 238, 227, 67, 29, 23, 238, 206, 67, 29, 23, 243, 195,
+ 67, 29, 240, 99, 99, 239, 20, 29, 240, 99, 99, 241, 190, 29, 23, 243,
+ 100, 79, 240, 99, 237, 44, 91, 29, 110, 127, 29, 110, 111, 29, 110, 166,
+ 29, 110, 177, 29, 110, 176, 29, 110, 187, 29, 110, 203, 29, 110, 195, 29,
+ 110, 202, 29, 110, 248, 53, 29, 110, 243, 30, 29, 110, 243, 27, 29, 110,
+ 240, 105, 29, 110, 244, 52, 29, 110, 240, 199, 29, 110, 240, 49, 29, 110,
+ 248, 136, 29, 110, 240, 238, 29, 110, 243, 191, 29, 110, 237, 41, 29,
+ 110, 243, 230, 29, 110, 237, 43, 29, 110, 234, 53, 29, 110, 229, 61, 29,
+ 110, 240, 195, 29, 110, 239, 186, 29, 110, 246, 62, 29, 110, 239, 68, 29,
+ 110, 236, 120, 29, 110, 234, 188, 29, 110, 242, 65, 29, 110, 234, 95, 29,
+ 110, 245, 232, 29, 110, 242, 239, 29, 110, 245, 27, 29, 110, 237, 93, 29,
+ 110, 245, 146, 29, 110, 238, 129, 29, 110, 251, 207, 29, 110, 242, 220,
+ 29, 110, 225, 29, 110, 236, 59, 29, 110, 236, 91, 29, 110, 240, 239, 29,
+ 110, 234, 66, 29, 110, 233, 84, 29, 110, 235, 140, 29, 110, 235, 116, 29,
+ 110, 242, 11, 29, 61, 240, 53, 187, 29, 61, 240, 53, 203, 29, 61, 240,
+ 53, 195, 29, 61, 240, 53, 202, 29, 61, 240, 136, 29, 61, 243, 6, 127, 29,
+ 61, 243, 6, 111, 29, 61, 243, 6, 166, 29, 61, 243, 6, 177, 29, 61, 243,
+ 6, 176, 29, 61, 243, 6, 187, 29, 61, 243, 6, 203, 29, 61, 243, 6, 195,
+ 29, 61, 243, 6, 202, 29, 61, 240, 50, 80, 145, 12, 28, 237, 183, 80, 145,
+ 12, 28, 236, 19, 80, 145, 12, 28, 241, 229, 80, 145, 12, 28, 241, 12, 80,
+ 145, 12, 28, 251, 222, 80, 145, 12, 28, 245, 253, 80, 145, 12, 28, 245,
+ 252, 80, 145, 12, 28, 238, 253, 80, 145, 12, 28, 234, 252, 80, 145, 12,
+ 28, 237, 224, 80, 145, 12, 28, 236, 65, 80, 145, 12, 28, 235, 200, 31,
+ 254, 171, 31, 250, 227, 31, 254, 160, 239, 118, 236, 51, 52, 29, 42, 67,
+ 29, 42, 71, 29, 42, 79, 29, 42, 72, 29, 42, 73, 29, 42, 201, 29, 42, 253,
+ 215, 29, 42, 253, 203, 29, 42, 253, 172, 29, 42, 253, 190, 29, 42, 253,
+ 132, 29, 42, 253, 198, 29, 42, 253, 211, 29, 42, 253, 210, 29, 42, 253,
+ 186, 29, 42, 253, 126, 29, 42, 253, 212, 29, 42, 253, 196, 29, 42, 253,
+ 195, 29, 42, 87, 29, 42, 253, 131, 29, 42, 253, 166, 29, 42, 253, 150,
+ 29, 42, 253, 197, 29, 42, 253, 173, 29, 42, 219, 29, 42, 253, 214, 29,
+ 42, 253, 236, 29, 42, 253, 168, 29, 42, 253, 184, 29, 42, 222, 29, 42,
+ 253, 180, 29, 42, 253, 154, 29, 42, 253, 206, 29, 42, 253, 181, 29, 42,
+ 216, 29, 42, 253, 161, 29, 42, 253, 162, 29, 42, 253, 130, 29, 42, 253,
+ 209, 29, 42, 253, 185, 29, 42, 253, 194, 29, 42, 253, 160, 29, 42, 253,
+ 138, 29, 42, 253, 187, 29, 42, 253, 170, 29, 42, 253, 177, 31, 238, 246,
+ 31, 238, 251, 31, 241, 10, 31, 244, 68, 31, 239, 99, 31, 245, 230, 31,
+ 252, 255, 31, 236, 15, 31, 241, 91, 31, 246, 232, 31, 246, 233, 31, 241,
+ 192, 31, 237, 187, 31, 237, 188, 31, 241, 124, 31, 241, 123, 31, 245,
+ 124, 31, 241, 137, 31, 239, 112, 31, 237, 165, 31, 246, 16, 31, 233, 213,
+ 31, 232, 180, 31, 234, 214, 31, 239, 87, 31, 234, 198, 31, 234, 216, 31,
+ 237, 192, 31, 241, 196, 31, 239, 110, 31, 241, 205, 31, 237, 254, 31,
+ 236, 95, 31, 238, 7, 31, 242, 101, 31, 242, 102, 31, 241, 70, 31, 245,
+ 63, 31, 245, 73, 31, 252, 227, 31, 246, 105, 31, 242, 24, 31, 241, 146,
+ 31, 236, 67, 31, 242, 46, 31, 237, 69, 31, 234, 233, 31, 239, 161, 31,
+ 246, 251, 31, 244, 223, 31, 236, 36, 31, 239, 95, 31, 235, 184, 31, 241,
+ 170, 31, 234, 199, 31, 246, 242, 31, 239, 159, 31, 239, 93, 31, 242, 55,
+ 31, 242, 52, 31, 241, 26, 31, 239, 164, 31, 239, 11, 31, 251, 77, 31,
+ 242, 64, 31, 241, 167, 31, 245, 200, 31, 237, 197, 31, 241, 225, 31, 241,
+ 224, 31, 239, 129, 31, 237, 199, 31, 237, 210, 31, 246, 88, 31, 234, 223,
+ 31, 243, 106, 31, 237, 207, 31, 237, 206, 31, 242, 190, 31, 242, 191, 31,
+ 247, 237, 31, 237, 252, 31, 247, 32, 31, 242, 90, 31, 237, 253, 31, 247,
+ 29, 31, 236, 92, 31, 242, 183, 80, 145, 12, 28, 248, 52, 242, 217, 80,
+ 145, 12, 28, 248, 52, 127, 80, 145, 12, 28, 248, 52, 111, 80, 145, 12,
+ 28, 248, 52, 166, 80, 145, 12, 28, 248, 52, 177, 80, 145, 12, 28, 248,
+ 52, 176, 80, 145, 12, 28, 248, 52, 187, 80, 145, 12, 28, 248, 52, 203,
+ 80, 145, 12, 28, 248, 52, 195, 80, 145, 12, 28, 248, 52, 202, 80, 145,
+ 12, 28, 248, 52, 248, 53, 80, 145, 12, 28, 248, 52, 238, 91, 80, 145, 12,
+ 28, 248, 52, 238, 97, 80, 145, 12, 28, 248, 52, 235, 85, 80, 145, 12, 28,
+ 248, 52, 235, 82, 80, 145, 12, 28, 248, 52, 236, 207, 80, 145, 12, 28,
+ 248, 52, 236, 202, 80, 145, 12, 28, 248, 52, 234, 22, 80, 145, 12, 28,
+ 248, 52, 235, 81, 80, 145, 12, 28, 248, 52, 235, 83, 80, 145, 12, 28,
+ 248, 52, 238, 77, 80, 145, 12, 28, 248, 52, 233, 110, 80, 145, 12, 28,
+ 248, 52, 233, 111, 80, 145, 12, 28, 248, 52, 231, 114, 80, 145, 12, 28,
+ 248, 52, 232, 111, 31, 251, 82, 31, 253, 133, 31, 253, 151, 31, 125, 31,
+ 254, 219, 31, 254, 222, 31, 254, 156, 31, 255, 53, 236, 191, 31, 255, 53,
+ 240, 94, 31, 254, 101, 31, 254, 37, 248, 170, 239, 89, 31, 254, 37, 248,
+ 170, 239, 213, 31, 254, 37, 248, 170, 238, 21, 31, 254, 37, 248, 170,
+ 241, 232, 31, 232, 123, 31, 255, 87, 244, 79, 31, 253, 131, 31, 255, 27,
+ 67, 31, 222, 31, 201, 31, 254, 182, 31, 254, 199, 31, 254, 166, 31, 250,
+ 143, 31, 246, 7, 31, 254, 224, 31, 254, 211, 31, 255, 27, 255, 19, 31,
+ 255, 27, 210, 31, 254, 202, 31, 254, 106, 31, 254, 173, 31, 251, 147, 31,
+ 251, 230, 31, 251, 20, 31, 252, 220, 31, 255, 27, 162, 31, 254, 204, 31,
+ 254, 155, 31, 254, 186, 31, 254, 164, 31, 254, 215, 31, 255, 27, 173, 31,
+ 254, 205, 31, 254, 152, 31, 254, 187, 31, 255, 61, 236, 191, 31, 255, 52,
+ 236, 191, 31, 255, 108, 236, 191, 31, 255, 50, 236, 191, 31, 255, 61,
+ 240, 94, 31, 255, 52, 240, 94, 31, 255, 108, 240, 94, 31, 255, 50, 240,
+ 94, 31, 255, 108, 248, 59, 193, 31, 255, 108, 248, 59, 255, 99, 236, 191,
+ 31, 253, 129, 31, 251, 163, 31, 249, 115, 31, 251, 28, 31, 252, 126, 31,
+ 254, 71, 248, 59, 193, 31, 254, 71, 248, 59, 255, 99, 236, 191, 31, 254,
+ 229, 31, 254, 216, 31, 255, 27, 193, 31, 254, 206, 31, 254, 230, 31, 254,
+ 115, 31, 255, 27, 179, 31, 254, 207, 31, 254, 189, 31, 255, 84, 243, 106,
+ 31, 254, 231, 31, 254, 217, 31, 255, 27, 255, 16, 31, 254, 208, 31, 254,
+ 108, 31, 255, 85, 243, 106, 31, 255, 109, 249, 126, 31, 255, 108, 249,
+ 126, 31, 254, 32, 31, 254, 147, 31, 254, 149, 31, 254, 150, 31, 255, 105,
+ 248, 59, 254, 106, 31, 253, 224, 31, 254, 154, 31, 254, 170, 31, 219, 31,
+ 254, 97, 31, 253, 247, 31, 254, 107, 31, 255, 50, 237, 83, 31, 254, 188,
+ 31, 254, 194, 31, 254, 195, 31, 251, 203, 31, 254, 197, 31, 255, 80, 240,
+ 147, 31, 251, 233, 31, 251, 240, 31, 254, 225, 31, 254, 226, 31, 252, 75,
+ 31, 254, 228, 31, 254, 241, 31, 254, 127, 31, 255, 2, 31, 255, 110, 248,
+ 59, 173, 31, 134, 248, 59, 173, 80, 145, 12, 28, 253, 137, 127, 80, 145,
+ 12, 28, 253, 137, 111, 80, 145, 12, 28, 253, 137, 166, 80, 145, 12, 28,
+ 253, 137, 177, 80, 145, 12, 28, 253, 137, 176, 80, 145, 12, 28, 253, 137,
+ 187, 80, 145, 12, 28, 253, 137, 203, 80, 145, 12, 28, 253, 137, 195, 80,
+ 145, 12, 28, 253, 137, 202, 80, 145, 12, 28, 253, 137, 248, 53, 80, 145,
+ 12, 28, 253, 137, 238, 91, 80, 145, 12, 28, 253, 137, 238, 97, 80, 145,
+ 12, 28, 253, 137, 235, 85, 80, 145, 12, 28, 253, 137, 235, 82, 80, 145,
+ 12, 28, 253, 137, 236, 207, 80, 145, 12, 28, 253, 137, 236, 202, 80, 145,
+ 12, 28, 253, 137, 234, 22, 80, 145, 12, 28, 253, 137, 235, 81, 80, 145,
+ 12, 28, 253, 137, 235, 83, 80, 145, 12, 28, 253, 137, 238, 77, 80, 145,
+ 12, 28, 253, 137, 233, 110, 80, 145, 12, 28, 253, 137, 233, 111, 80, 145,
+ 12, 28, 253, 137, 231, 114, 80, 145, 12, 28, 253, 137, 232, 111, 80, 145,
+ 12, 28, 253, 137, 233, 45, 80, 145, 12, 28, 253, 137, 233, 255, 80, 145,
+ 12, 28, 253, 137, 232, 64, 80, 145, 12, 28, 253, 137, 232, 63, 80, 145,
+ 12, 28, 253, 137, 233, 46, 80, 145, 12, 28, 253, 137, 238, 101, 80, 145,
+ 12, 28, 253, 137, 233, 252, 31, 251, 7, 156, 28, 253, 145, 237, 94, 238,
+ 139, 156, 28, 253, 145, 236, 86, 240, 49, 156, 28, 234, 112, 255, 31,
+ 253, 145, 234, 97, 156, 28, 238, 48, 241, 113, 156, 28, 237, 51, 156, 28,
+ 235, 191, 156, 28, 253, 145, 244, 84, 156, 28, 238, 189, 235, 153, 156,
+ 28, 3, 238, 222, 156, 28, 236, 130, 156, 28, 242, 51, 156, 28, 233, 247,
+ 156, 28, 233, 201, 156, 28, 243, 58, 233, 224, 156, 28, 237, 212, 156,
+ 28, 233, 197, 156, 28, 234, 54, 156, 28, 253, 37, 255, 34, 253, 145, 237,
+ 102, 156, 28, 235, 166, 156, 28, 231, 63, 156, 28, 241, 32, 238, 27, 156,
+ 28, 241, 139, 156, 28, 236, 104, 241, 11, 156, 28, 238, 211, 156, 28,
+ 234, 208, 156, 28, 243, 58, 238, 222, 156, 28, 246, 91, 237, 0, 156, 28,
+ 243, 58, 231, 53, 156, 28, 253, 145, 238, 236, 240, 105, 156, 28, 253,
+ 145, 237, 87, 243, 27, 156, 28, 234, 207, 156, 28, 236, 9, 156, 28, 237,
+ 251, 156, 28, 243, 58, 240, 210, 156, 28, 236, 81, 156, 28, 235, 198,
+ 147, 253, 145, 240, 9, 156, 28, 253, 145, 239, 66, 156, 28, 233, 73, 156,
+ 28, 232, 189, 156, 28, 232, 128, 156, 28, 235, 201, 156, 28, 235, 127,
+ 156, 28, 231, 119, 156, 28, 241, 65, 153, 243, 224, 156, 28, 235, 124,
+ 235, 153, 156, 28, 239, 170, 239, 235, 156, 28, 233, 221, 156, 28, 253,
+ 145, 247, 193, 156, 28, 233, 231, 156, 28, 253, 145, 235, 117, 156, 28,
+ 253, 145, 237, 67, 237, 48, 156, 28, 253, 145, 238, 193, 247, 123, 235,
+ 102, 156, 28, 232, 131, 156, 28, 253, 145, 237, 203, 239, 125, 156, 28,
+ 234, 89, 156, 28, 253, 145, 236, 139, 156, 28, 253, 145, 241, 125, 243,
+ 82, 156, 28, 253, 145, 241, 188, 243, 213, 156, 28, 233, 135, 156, 28,
+ 233, 216, 156, 28, 245, 228, 242, 158, 156, 28, 3, 231, 53, 156, 28, 244,
+ 70, 233, 69, 156, 28, 241, 27, 233, 69, 6, 4, 254, 179, 6, 4, 254, 180,
+ 6, 4, 71, 6, 4, 254, 176, 6, 4, 251, 102, 6, 4, 251, 103, 6, 4, 253, 237,
+ 6, 4, 251, 101, 6, 4, 254, 20, 6, 4, 254, 144, 6, 4, 67, 6, 4, 254, 141,
+ 6, 4, 253, 1, 6, 4, 254, 252, 6, 4, 253, 0, 6, 4, 254, 67, 6, 4, 254,
+ 220, 6, 4, 73, 6, 4, 254, 120, 6, 4, 254, 161, 6, 4, 72, 6, 4, 254, 14,
+ 6, 4, 250, 125, 6, 4, 250, 126, 6, 4, 254, 34, 6, 4, 250, 124, 6, 4, 244,
+ 221, 6, 4, 244, 222, 6, 4, 250, 122, 6, 4, 244, 220, 6, 4, 250, 104, 6,
+ 4, 250, 105, 6, 4, 253, 141, 6, 4, 250, 103, 6, 4, 244, 235, 6, 4, 250,
+ 131, 6, 4, 244, 234, 6, 4, 250, 130, 6, 4, 248, 92, 6, 4, 254, 1, 6, 4,
+ 250, 129, 6, 4, 250, 119, 6, 4, 253, 242, 6, 4, 250, 116, 6, 4, 250, 133,
+ 6, 4, 250, 134, 6, 4, 253, 243, 6, 4, 250, 132, 6, 4, 244, 236, 6, 4,
+ 249, 35, 6, 4, 250, 140, 6, 4, 250, 141, 6, 4, 254, 82, 6, 4, 250, 138,
+ 6, 4, 244, 238, 6, 4, 250, 139, 6, 4, 252, 68, 6, 4, 252, 69, 6, 4, 253,
+ 147, 6, 4, 252, 67, 6, 4, 246, 250, 6, 4, 252, 65, 6, 4, 246, 249, 6, 4,
+ 252, 61, 6, 4, 252, 62, 6, 4, 253, 129, 6, 4, 252, 60, 6, 4, 247, 0, 6,
+ 4, 252, 78, 6, 4, 246, 255, 6, 4, 252, 73, 6, 4, 252, 74, 6, 4, 253, 208,
+ 6, 4, 252, 72, 6, 4, 249, 142, 6, 4, 252, 81, 6, 4, 253, 239, 6, 4, 252,
+ 79, 6, 4, 247, 1, 6, 4, 252, 80, 6, 4, 249, 144, 6, 4, 252, 84, 6, 4,
+ 254, 232, 6, 4, 252, 82, 6, 4, 247, 3, 6, 4, 252, 83, 6, 4, 244, 200, 6,
+ 4, 244, 201, 6, 4, 250, 108, 6, 4, 244, 199, 6, 4, 241, 21, 6, 4, 241,
+ 22, 6, 4, 244, 198, 6, 4, 241, 20, 6, 4, 244, 194, 6, 4, 244, 195, 6, 4,
+ 250, 106, 6, 4, 244, 193, 6, 4, 241, 24, 6, 4, 244, 205, 6, 4, 241, 23,
+ 6, 4, 244, 203, 6, 4, 244, 204, 6, 4, 250, 109, 6, 4, 244, 202, 6, 4,
+ 244, 197, 6, 4, 250, 107, 6, 4, 244, 196, 6, 4, 243, 145, 6, 4, 244, 208,
+ 6, 4, 250, 110, 6, 4, 244, 206, 6, 4, 241, 25, 6, 4, 244, 207, 6, 4, 244,
+ 210, 6, 4, 244, 211, 6, 4, 250, 111, 6, 4, 244, 209, 6, 4, 246, 110, 6,
+ 4, 246, 111, 6, 4, 252, 3, 6, 4, 246, 109, 6, 4, 242, 0, 6, 4, 243, 232,
+ 6, 4, 241, 255, 6, 4, 246, 107, 6, 4, 246, 108, 6, 4, 252, 2, 6, 4, 246,
+ 106, 6, 4, 246, 113, 6, 4, 246, 114, 6, 4, 252, 4, 6, 4, 246, 112, 6, 4,
+ 246, 117, 6, 4, 246, 118, 6, 4, 252, 5, 6, 4, 246, 115, 6, 4, 242, 1, 6,
+ 4, 246, 116, 6, 4, 246, 121, 6, 4, 246, 122, 6, 4, 252, 6, 6, 4, 246,
+ 119, 6, 4, 242, 2, 6, 4, 246, 120, 6, 4, 245, 173, 6, 4, 245, 174, 6, 4,
+ 251, 71, 6, 4, 245, 172, 6, 4, 241, 158, 6, 4, 245, 171, 6, 4, 241, 157,
+ 6, 4, 245, 169, 6, 4, 245, 170, 6, 4, 251, 70, 6, 4, 245, 168, 6, 4, 241,
+ 160, 6, 4, 245, 178, 6, 4, 241, 159, 6, 4, 245, 176, 6, 4, 245, 177, 6,
+ 4, 249, 82, 6, 4, 245, 175, 6, 4, 245, 181, 6, 4, 245, 182, 6, 4, 251,
+ 72, 6, 4, 245, 179, 6, 4, 241, 161, 6, 4, 245, 180, 6, 4, 245, 185, 6, 4,
+ 251, 73, 6, 4, 245, 183, 6, 4, 241, 162, 6, 4, 245, 184, 6, 4, 251, 237,
+ 6, 4, 251, 238, 6, 4, 253, 180, 6, 4, 251, 236, 6, 4, 246, 83, 6, 4, 251,
+ 231, 6, 4, 246, 82, 6, 4, 251, 220, 6, 4, 251, 221, 6, 4, 222, 6, 4, 251,
+ 218, 6, 4, 246, 97, 6, 4, 246, 98, 6, 4, 251, 243, 6, 4, 246, 96, 6, 4,
+ 251, 241, 6, 4, 251, 242, 6, 4, 253, 181, 6, 4, 249, 114, 6, 4, 251, 226,
+ 6, 4, 253, 206, 6, 4, 251, 246, 6, 4, 251, 247, 6, 4, 253, 154, 6, 4,
+ 251, 244, 6, 4, 246, 100, 6, 4, 251, 245, 6, 4, 251, 250, 6, 4, 251, 251,
+ 6, 4, 254, 209, 6, 4, 251, 249, 6, 4, 250, 247, 6, 4, 250, 248, 6, 4,
+ 253, 245, 6, 4, 250, 246, 6, 4, 250, 235, 6, 4, 250, 236, 6, 4, 253, 179,
+ 6, 4, 250, 234, 6, 4, 250, 251, 6, 4, 254, 63, 6, 4, 250, 250, 6, 4, 250,
+ 253, 6, 4, 250, 254, 6, 4, 254, 93, 6, 4, 250, 252, 6, 4, 245, 93, 6, 4,
+ 249, 64, 6, 4, 251, 3, 6, 4, 251, 4, 6, 4, 254, 165, 6, 4, 251, 2, 6, 4,
+ 253, 14, 6, 4, 253, 15, 6, 4, 254, 48, 6, 4, 253, 13, 6, 4, 247, 187, 6,
+ 4, 247, 188, 6, 4, 253, 12, 6, 4, 247, 186, 6, 4, 253, 8, 6, 4, 253, 9,
+ 6, 4, 253, 171, 6, 4, 253, 7, 6, 4, 253, 18, 6, 4, 253, 20, 6, 4, 254,
+ 13, 6, 4, 253, 17, 6, 4, 253, 11, 6, 4, 249, 193, 6, 4, 253, 22, 6, 4,
+ 253, 23, 6, 4, 254, 49, 6, 4, 253, 21, 6, 4, 247, 189, 6, 4, 249, 197, 6,
+ 4, 253, 27, 6, 4, 253, 28, 6, 4, 255, 1, 6, 4, 253, 25, 6, 4, 247, 190,
+ 6, 4, 253, 26, 6, 4, 250, 196, 6, 4, 250, 197, 6, 4, 253, 201, 6, 4, 250,
+ 195, 6, 4, 245, 66, 6, 4, 250, 194, 6, 4, 245, 65, 6, 4, 250, 184, 6, 4,
+ 250, 187, 6, 4, 253, 133, 6, 4, 250, 182, 6, 4, 245, 75, 6, 4, 250, 209,
+ 6, 4, 248, 40, 6, 4, 250, 205, 6, 4, 253, 225, 6, 4, 250, 204, 6, 4, 250,
+ 191, 6, 4, 253, 200, 6, 4, 250, 190, 6, 4, 250, 212, 6, 4, 250, 213, 6,
+ 4, 253, 232, 6, 4, 250, 210, 6, 4, 245, 76, 6, 4, 250, 211, 6, 4, 252,
+ 223, 6, 4, 252, 224, 6, 4, 253, 212, 6, 4, 252, 222, 6, 4, 247, 149, 6,
+ 4, 248, 139, 6, 4, 247, 148, 6, 4, 249, 174, 6, 4, 252, 212, 6, 4, 253,
+ 126, 6, 4, 252, 209, 6, 4, 247, 174, 6, 4, 247, 175, 6, 4, 252, 233, 6,
+ 4, 247, 173, 6, 4, 249, 184, 6, 4, 252, 228, 6, 4, 87, 6, 4, 249, 3, 6,
+ 4, 252, 217, 6, 4, 253, 195, 6, 4, 252, 214, 6, 4, 252, 236, 6, 4, 252,
+ 237, 6, 4, 253, 196, 6, 4, 252, 234, 6, 4, 247, 176, 6, 4, 252, 235, 6,
+ 4, 245, 47, 6, 4, 245, 48, 6, 4, 249, 51, 6, 4, 245, 46, 6, 4, 241, 77,
+ 6, 4, 245, 45, 6, 4, 241, 76, 6, 4, 245, 39, 6, 4, 245, 40, 6, 4, 248,
+ 75, 6, 4, 245, 38, 6, 4, 241, 79, 6, 4, 245, 53, 6, 4, 241, 78, 6, 4,
+ 245, 51, 6, 4, 245, 52, 6, 4, 248, 204, 6, 4, 245, 50, 6, 4, 245, 43, 6,
+ 4, 249, 50, 6, 4, 245, 42, 6, 4, 245, 55, 6, 4, 245, 56, 6, 4, 249, 52,
+ 6, 4, 245, 54, 6, 4, 241, 80, 6, 4, 243, 163, 6, 4, 246, 130, 6, 4, 246,
+ 131, 6, 4, 252, 9, 6, 4, 246, 129, 6, 4, 242, 3, 6, 4, 246, 128, 6, 4,
+ 246, 124, 6, 4, 246, 125, 6, 4, 252, 7, 6, 4, 246, 123, 6, 4, 246, 133,
+ 6, 4, 246, 134, 6, 4, 252, 10, 6, 4, 246, 132, 6, 4, 246, 127, 6, 4, 252,
+ 8, 6, 4, 246, 126, 6, 4, 246, 137, 6, 4, 246, 138, 6, 4, 252, 11, 6, 4,
+ 246, 135, 6, 4, 242, 4, 6, 4, 246, 136, 6, 4, 245, 193, 6, 4, 245, 194,
+ 6, 4, 251, 75, 6, 4, 245, 192, 6, 4, 241, 164, 6, 4, 241, 165, 6, 4, 245,
+ 191, 6, 4, 241, 163, 6, 4, 245, 187, 6, 4, 245, 188, 6, 4, 249, 83, 6, 4,
+ 245, 186, 6, 4, 241, 166, 6, 4, 245, 198, 6, 4, 245, 196, 6, 4, 245, 197,
+ 6, 4, 245, 195, 6, 4, 245, 190, 6, 4, 251, 74, 6, 4, 245, 189, 6, 4, 245,
+ 199, 6, 4, 252, 24, 6, 4, 252, 25, 6, 4, 253, 166, 6, 4, 252, 23, 6, 4,
+ 246, 155, 6, 4, 252, 21, 6, 4, 246, 154, 6, 4, 252, 1, 6, 4, 253, 131, 6,
+ 4, 251, 255, 6, 4, 246, 195, 6, 4, 252, 41, 6, 4, 246, 194, 6, 4, 248,
+ 233, 6, 4, 252, 35, 6, 4, 253, 173, 6, 4, 252, 33, 6, 4, 252, 15, 6, 4,
+ 253, 197, 6, 4, 252, 13, 6, 4, 252, 44, 6, 4, 252, 45, 6, 4, 253, 150, 6,
+ 4, 252, 42, 6, 4, 246, 196, 6, 4, 252, 43, 6, 4, 245, 155, 6, 4, 245,
+ 156, 6, 4, 251, 66, 6, 4, 245, 154, 6, 4, 241, 152, 6, 4, 245, 153, 6, 4,
+ 241, 151, 6, 4, 245, 149, 6, 4, 245, 150, 6, 4, 251, 64, 6, 4, 245, 148,
+ 6, 4, 241, 154, 6, 4, 245, 159, 6, 4, 241, 153, 6, 4, 245, 158, 6, 4,
+ 251, 67, 6, 4, 245, 157, 6, 4, 245, 152, 6, 4, 251, 65, 6, 4, 245, 151,
+ 6, 4, 245, 162, 6, 4, 245, 163, 6, 4, 251, 68, 6, 4, 245, 160, 6, 4, 241,
+ 155, 6, 4, 245, 161, 6, 4, 245, 166, 6, 4, 245, 167, 6, 4, 251, 69, 6, 4,
+ 245, 164, 6, 4, 241, 156, 6, 4, 245, 165, 6, 4, 251, 200, 6, 4, 251, 201,
+ 6, 4, 253, 251, 6, 4, 251, 198, 6, 4, 246, 49, 6, 4, 246, 50, 6, 4, 249,
+ 105, 6, 4, 246, 48, 6, 4, 251, 185, 6, 4, 251, 186, 6, 4, 253, 134, 6, 4,
+ 251, 183, 6, 4, 246, 57, 6, 4, 246, 58, 6, 4, 251, 209, 6, 4, 246, 56, 6,
+ 4, 251, 206, 6, 4, 251, 208, 6, 4, 253, 216, 6, 4, 251, 205, 6, 4, 251,
+ 191, 6, 4, 253, 250, 6, 4, 251, 189, 6, 4, 251, 212, 6, 4, 251, 213, 6,
+ 4, 254, 8, 6, 4, 251, 210, 6, 4, 246, 59, 6, 4, 251, 211, 6, 4, 251, 215,
+ 6, 4, 251, 216, 6, 4, 254, 110, 6, 4, 251, 214, 6, 4, 246, 60, 6, 4, 249,
+ 109, 6, 4, 251, 23, 6, 4, 251, 24, 6, 4, 254, 6, 6, 4, 251, 22, 6, 4,
+ 245, 122, 6, 4, 245, 123, 6, 4, 251, 21, 6, 4, 245, 121, 6, 4, 251, 10,
+ 6, 4, 251, 11, 6, 4, 253, 139, 6, 4, 251, 8, 6, 4, 245, 131, 6, 4, 245,
+ 132, 6, 4, 251, 31, 6, 4, 245, 130, 6, 4, 249, 78, 6, 4, 251, 27, 6, 4,
+ 253, 234, 6, 4, 251, 26, 6, 4, 251, 15, 6, 4, 251, 17, 6, 4, 254, 5, 6,
+ 4, 249, 69, 6, 4, 251, 34, 6, 4, 251, 35, 6, 4, 253, 235, 6, 4, 251, 32,
+ 6, 4, 245, 133, 6, 4, 251, 33, 6, 4, 249, 95, 6, 4, 251, 152, 6, 4, 253,
+ 215, 6, 4, 251, 151, 6, 4, 246, 15, 6, 4, 251, 148, 6, 4, 246, 14, 6, 4,
+ 251, 138, 6, 4, 251, 140, 6, 4, 201, 6, 4, 251, 137, 6, 4, 246, 21, 6, 4,
+ 251, 165, 6, 4, 246, 20, 6, 4, 251, 161, 6, 4, 251, 162, 6, 4, 253, 190,
+ 6, 4, 251, 160, 6, 4, 251, 143, 6, 4, 251, 144, 6, 4, 253, 172, 6, 4,
+ 251, 142, 6, 4, 251, 168, 6, 4, 251, 169, 6, 4, 253, 203, 6, 4, 251, 166,
+ 6, 4, 246, 23, 6, 4, 251, 167, 6, 4, 245, 108, 6, 4, 245, 109, 6, 4, 249,
+ 72, 6, 4, 241, 129, 6, 4, 245, 107, 6, 4, 241, 128, 6, 4, 245, 101, 6, 4,
+ 245, 102, 6, 4, 249, 70, 6, 4, 245, 100, 6, 4, 241, 131, 6, 4, 241, 132,
+ 6, 4, 243, 181, 6, 4, 241, 130, 6, 4, 245, 110, 6, 4, 245, 111, 6, 4,
+ 249, 73, 6, 4, 243, 180, 6, 4, 245, 105, 6, 4, 245, 106, 6, 4, 249, 71,
+ 6, 4, 245, 104, 6, 4, 245, 114, 6, 4, 245, 115, 6, 4, 249, 74, 6, 4, 245,
+ 112, 6, 4, 241, 133, 6, 4, 245, 113, 6, 4, 241, 238, 6, 4, 246, 72, 6, 4,
+ 246, 68, 6, 4, 246, 69, 6, 4, 251, 227, 6, 4, 246, 67, 6, 4, 241, 240, 6,
+ 4, 246, 76, 6, 4, 241, 239, 6, 4, 246, 74, 6, 4, 246, 75, 6, 4, 248, 167,
+ 6, 4, 246, 73, 6, 4, 246, 71, 6, 4, 251, 228, 6, 4, 246, 70, 6, 4, 246,
+ 79, 6, 4, 246, 80, 6, 4, 251, 229, 6, 4, 246, 77, 6, 4, 241, 241, 6, 4,
+ 246, 78, 6, 4, 243, 196, 6, 4, 245, 216, 6, 4, 251, 91, 6, 4, 245, 215,
+ 6, 4, 241, 172, 6, 4, 241, 173, 6, 4, 245, 214, 6, 4, 241, 171, 6, 4,
+ 245, 210, 6, 4, 245, 211, 6, 4, 251, 89, 6, 4, 245, 209, 6, 4, 241, 175,
+ 6, 4, 241, 176, 6, 4, 243, 198, 6, 4, 241, 174, 6, 4, 245, 217, 6, 4,
+ 245, 218, 6, 4, 251, 92, 6, 4, 243, 197, 6, 4, 245, 213, 6, 4, 251, 90,
+ 6, 4, 245, 212, 6, 4, 242, 7, 6, 4, 246, 146, 6, 4, 242, 6, 6, 4, 246,
+ 142, 6, 4, 246, 143, 6, 4, 248, 50, 6, 4, 246, 141, 6, 4, 242, 9, 6, 4,
+ 242, 10, 6, 4, 246, 153, 6, 4, 246, 151, 6, 4, 246, 152, 6, 4, 248, 172,
+ 6, 4, 246, 150, 6, 4, 246, 145, 6, 4, 252, 17, 6, 4, 246, 144, 6, 4, 251,
+ 63, 6, 4, 245, 145, 6, 4, 248, 160, 6, 4, 248, 214, 6, 4, 251, 48, 6, 4,
+ 219, 6, 4, 251, 47, 6, 4, 245, 206, 6, 4, 245, 207, 6, 4, 251, 83, 6, 4,
+ 245, 205, 6, 4, 251, 80, 6, 4, 251, 81, 6, 4, 253, 184, 6, 4, 251, 79, 6,
+ 4, 251, 55, 6, 4, 253, 168, 6, 4, 251, 53, 6, 4, 253, 30, 6, 4, 253, 31,
+ 6, 4, 253, 138, 6, 4, 253, 29, 6, 4, 247, 200, 6, 4, 253, 39, 6, 4, 247,
+ 199, 6, 4, 253, 38, 6, 4, 253, 177, 6, 4, 253, 36, 6, 4, 253, 33, 6, 4,
+ 253, 170, 6, 4, 253, 32, 6, 4, 253, 106, 6, 4, 253, 107, 6, 4, 254, 17,
+ 6, 4, 253, 105, 6, 4, 248, 10, 6, 4, 253, 104, 6, 4, 248, 9, 6, 4, 253,
+ 99, 6, 4, 253, 100, 6, 4, 253, 163, 6, 4, 253, 98, 6, 4, 248, 12, 6, 4,
+ 253, 114, 6, 4, 248, 11, 6, 4, 249, 221, 6, 4, 253, 112, 6, 4, 253, 222,
+ 6, 4, 253, 111, 6, 4, 253, 102, 6, 4, 253, 228, 6, 4, 253, 101, 6, 4,
+ 253, 115, 6, 4, 253, 116, 6, 4, 254, 18, 6, 4, 249, 222, 6, 4, 248, 13,
+ 6, 4, 249, 223, 6, 4, 253, 120, 6, 4, 253, 121, 6, 4, 255, 13, 6, 4, 253,
+ 118, 6, 4, 248, 14, 6, 4, 253, 119, 6, 4, 250, 163, 6, 4, 250, 164, 6, 4,
+ 254, 55, 6, 4, 249, 40, 6, 4, 245, 19, 6, 4, 245, 20, 6, 4, 250, 161, 6,
+ 4, 245, 18, 6, 4, 250, 146, 6, 4, 250, 147, 6, 4, 253, 152, 6, 4, 249,
+ 38, 6, 4, 245, 28, 6, 4, 250, 170, 6, 4, 243, 157, 6, 4, 250, 167, 6, 4,
+ 250, 168, 6, 4, 253, 224, 6, 4, 250, 166, 6, 4, 250, 157, 6, 4, 254, 54,
+ 6, 4, 250, 156, 6, 4, 250, 172, 6, 4, 250, 173, 6, 4, 254, 84, 6, 4, 249,
+ 43, 6, 4, 245, 29, 6, 4, 250, 171, 6, 4, 249, 48, 6, 4, 250, 176, 6, 4,
+ 254, 85, 6, 4, 249, 47, 6, 4, 245, 30, 6, 4, 250, 175, 6, 4, 248, 24, 6,
+ 4, 248, 25, 6, 4, 249, 226, 6, 4, 248, 23, 6, 4, 241, 1, 6, 4, 242, 211,
+ 6, 4, 248, 22, 6, 4, 242, 210, 6, 4, 248, 17, 6, 4, 248, 18, 6, 4, 249,
+ 224, 6, 4, 248, 16, 6, 4, 248, 27, 6, 4, 249, 227, 6, 4, 248, 26, 6, 4,
+ 248, 21, 6, 4, 249, 225, 6, 4, 248, 20, 6, 4, 248, 30, 6, 4, 249, 228, 6,
+ 4, 248, 28, 6, 4, 242, 212, 6, 4, 248, 29, 6, 4, 248, 33, 6, 4, 248, 34,
+ 6, 4, 253, 122, 6, 4, 248, 31, 6, 4, 242, 213, 6, 4, 248, 32, 6, 4, 246,
+ 219, 6, 4, 246, 220, 6, 4, 252, 49, 6, 4, 246, 218, 6, 4, 242, 34, 6, 4,
+ 246, 217, 6, 4, 242, 33, 6, 4, 246, 214, 6, 4, 246, 215, 6, 4, 252, 47,
+ 6, 4, 246, 213, 6, 4, 242, 35, 6, 4, 246, 223, 6, 4, 246, 222, 6, 4, 246,
+ 221, 6, 4, 246, 216, 6, 4, 252, 48, 6, 4, 246, 225, 6, 4, 252, 50, 6, 4,
+ 243, 239, 6, 4, 242, 36, 6, 4, 246, 224, 6, 4, 246, 228, 6, 4, 246, 229,
+ 6, 4, 252, 51, 6, 4, 246, 226, 6, 4, 242, 37, 6, 4, 246, 227, 6, 4, 252,
+ 180, 6, 4, 187, 6, 4, 253, 198, 6, 4, 252, 179, 6, 4, 247, 88, 6, 4, 252,
+ 176, 6, 4, 247, 87, 6, 4, 252, 167, 6, 4, 252, 168, 6, 4, 253, 132, 6, 4,
+ 252, 166, 6, 4, 247, 126, 6, 4, 252, 193, 6, 4, 247, 125, 6, 4, 252, 186,
+ 6, 4, 252, 188, 6, 4, 253, 186, 6, 4, 252, 185, 6, 4, 252, 172, 6, 4,
+ 253, 210, 6, 4, 252, 171, 6, 4, 252, 196, 6, 4, 252, 197, 6, 4, 253, 211,
+ 6, 4, 252, 194, 6, 4, 247, 128, 6, 4, 252, 195, 6, 4, 252, 200, 6, 4,
+ 252, 201, 6, 4, 254, 243, 6, 4, 252, 198, 6, 4, 247, 130, 6, 4, 252, 199,
+ 6, 4, 247, 108, 6, 4, 247, 109, 6, 4, 248, 249, 6, 4, 247, 107, 6, 4,
+ 242, 129, 6, 4, 247, 106, 6, 4, 242, 128, 6, 4, 247, 101, 6, 4, 247, 102,
+ 6, 4, 248, 66, 6, 4, 247, 100, 6, 4, 247, 111, 6, 4, 247, 112, 6, 4, 248,
+ 250, 6, 4, 247, 110, 6, 4, 247, 105, 6, 4, 249, 168, 6, 4, 247, 104, 6,
+ 4, 247, 114, 6, 4, 247, 115, 6, 4, 248, 251, 6, 4, 247, 113, 6, 4, 247,
+ 118, 6, 4, 247, 119, 6, 4, 252, 189, 6, 4, 247, 116, 6, 4, 242, 130, 6,
+ 4, 247, 117, 6, 4, 247, 247, 6, 4, 247, 248, 6, 4, 248, 99, 6, 4, 247,
+ 246, 6, 4, 242, 204, 6, 4, 247, 255, 6, 4, 242, 203, 6, 4, 247, 253, 6,
+ 4, 247, 254, 6, 4, 249, 218, 6, 4, 247, 252, 6, 4, 247, 250, 6, 4, 247,
+ 251, 6, 4, 248, 123, 6, 4, 247, 249, 6, 4, 248, 2, 6, 4, 248, 3, 6, 4,
+ 249, 219, 6, 4, 248, 0, 6, 4, 242, 205, 6, 4, 248, 1, 6, 4, 248, 7, 6, 4,
+ 248, 8, 6, 4, 253, 103, 6, 4, 248, 5, 6, 4, 242, 206, 6, 4, 248, 6, 6, 4,
+ 244, 255, 6, 4, 245, 0, 6, 4, 248, 57, 6, 4, 244, 254, 6, 4, 241, 57, 6,
+ 4, 241, 58, 6, 4, 245, 9, 6, 4, 241, 56, 6, 4, 245, 7, 6, 4, 245, 8, 6,
+ 4, 248, 125, 6, 4, 245, 6, 6, 4, 245, 2, 6, 4, 245, 3, 6, 4, 248, 88, 6,
+ 4, 245, 1, 6, 4, 245, 12, 6, 4, 248, 200, 6, 4, 245, 10, 6, 4, 241, 59,
+ 6, 4, 245, 11, 6, 4, 245, 16, 6, 4, 245, 17, 6, 4, 250, 160, 6, 4, 245,
+ 14, 6, 4, 241, 60, 6, 4, 245, 15, 6, 4, 247, 35, 6, 4, 248, 96, 6, 4,
+ 242, 87, 6, 4, 247, 43, 6, 4, 247, 41, 6, 4, 247, 42, 6, 4, 249, 157, 6,
+ 4, 247, 40, 6, 4, 247, 38, 6, 4, 247, 39, 6, 4, 252, 147, 6, 4, 247, 37,
+ 6, 4, 247, 46, 6, 4, 247, 47, 6, 4, 252, 148, 6, 4, 247, 44, 6, 4, 242,
+ 88, 6, 4, 247, 45, 6, 4, 247, 50, 6, 4, 247, 51, 6, 4, 252, 149, 6, 4,
+ 247, 48, 6, 4, 242, 89, 6, 4, 247, 49, 6, 4, 246, 178, 6, 4, 246, 179, 6,
+ 4, 249, 123, 6, 4, 246, 177, 6, 4, 246, 184, 6, 4, 252, 37, 6, 4, 246,
+ 183, 6, 4, 246, 181, 6, 4, 246, 182, 6, 4, 252, 36, 6, 4, 246, 180, 6, 4,
+ 246, 187, 6, 4, 246, 188, 6, 4, 252, 38, 6, 4, 246, 185, 6, 4, 242, 25,
+ 6, 4, 246, 186, 6, 4, 246, 191, 6, 4, 246, 192, 6, 4, 252, 39, 6, 4, 246,
+ 189, 6, 4, 242, 26, 6, 4, 246, 190, 6, 4, 244, 8, 6, 4, 247, 69, 6, 4,
+ 248, 46, 6, 4, 247, 68, 6, 4, 242, 110, 6, 4, 247, 79, 6, 4, 242, 109, 6,
+ 4, 247, 77, 6, 4, 247, 78, 6, 4, 248, 110, 6, 4, 244, 13, 6, 4, 247, 71,
+ 6, 4, 247, 72, 6, 4, 248, 118, 6, 4, 247, 70, 6, 4, 247, 81, 6, 4, 247,
+ 82, 6, 4, 248, 248, 6, 4, 247, 80, 6, 4, 242, 111, 6, 4, 244, 15, 6, 4,
+ 247, 85, 6, 4, 247, 86, 6, 4, 249, 163, 6, 4, 247, 83, 6, 4, 242, 112, 6,
+ 4, 247, 84, 6, 4, 249, 152, 6, 4, 252, 130, 6, 4, 253, 130, 6, 4, 248,
+ 244, 6, 4, 247, 55, 6, 4, 252, 152, 6, 4, 247, 54, 6, 4, 252, 145, 6, 4,
+ 252, 146, 6, 4, 253, 160, 6, 4, 252, 144, 6, 4, 252, 135, 6, 4, 253, 194,
+ 6, 4, 252, 133, 6, 4, 252, 155, 6, 4, 252, 156, 6, 4, 253, 185, 6, 4,
+ 252, 153, 6, 4, 247, 56, 6, 4, 252, 154, 6, 4, 252, 161, 6, 4, 252, 162,
+ 6, 4, 254, 125, 6, 4, 252, 159, 6, 4, 247, 58, 6, 4, 252, 160, 6, 4, 251,
+ 118, 6, 4, 251, 119, 6, 4, 254, 7, 6, 4, 251, 117, 6, 4, 245, 236, 6, 4,
+ 245, 237, 6, 4, 251, 116, 6, 4, 245, 235, 6, 4, 245, 255, 6, 4, 246, 0,
+ 6, 4, 251, 126, 6, 4, 245, 254, 6, 4, 248, 115, 6, 4, 251, 124, 6, 4,
+ 253, 248, 6, 4, 251, 123, 6, 4, 251, 129, 6, 4, 251, 130, 6, 4, 254, 25,
+ 6, 4, 251, 127, 6, 4, 246, 1, 6, 4, 251, 128, 6, 4, 251, 134, 6, 4, 251,
+ 135, 6, 4, 254, 181, 6, 4, 251, 132, 6, 4, 246, 2, 6, 4, 251, 133, 6, 4,
+ 252, 96, 6, 4, 252, 97, 6, 4, 254, 28, 6, 4, 252, 95, 6, 4, 247, 13, 6,
+ 4, 247, 14, 6, 4, 252, 94, 6, 4, 247, 12, 6, 4, 247, 17, 6, 4, 247, 18,
+ 6, 4, 249, 149, 6, 4, 247, 16, 6, 4, 249, 148, 6, 4, 252, 102, 6, 4, 254,
+ 45, 6, 4, 252, 101, 6, 4, 252, 109, 6, 4, 252, 111, 6, 4, 254, 29, 6, 4,
+ 252, 107, 6, 4, 247, 19, 6, 4, 252, 108, 6, 4, 252, 121, 6, 4, 252, 123,
+ 6, 4, 254, 234, 6, 4, 252, 119, 6, 4, 247, 25, 6, 4, 252, 120, 6, 4, 245,
+ 240, 6, 4, 245, 241, 6, 4, 249, 86, 6, 4, 245, 239, 6, 4, 241, 183, 6, 4,
+ 241, 184, 6, 4, 243, 202, 6, 4, 241, 182, 6, 4, 241, 186, 6, 4, 245, 245,
+ 6, 4, 241, 185, 6, 4, 245, 243, 6, 4, 245, 244, 6, 4, 249, 87, 6, 4, 245,
+ 242, 6, 4, 243, 203, 6, 4, 245, 248, 6, 4, 249, 88, 6, 4, 245, 246, 6, 4,
+ 241, 187, 6, 4, 245, 247, 6, 4, 245, 250, 6, 4, 245, 251, 6, 4, 249, 89,
+ 6, 4, 245, 249, 6, 4, 246, 159, 6, 4, 246, 160, 6, 4, 252, 26, 6, 4, 246,
+ 158, 6, 4, 242, 14, 6, 4, 242, 15, 6, 4, 246, 157, 6, 4, 242, 13, 6, 4,
+ 242, 16, 6, 4, 246, 164, 6, 4, 246, 162, 6, 4, 246, 163, 6, 4, 252, 27,
+ 6, 4, 246, 161, 6, 4, 246, 167, 6, 4, 252, 28, 6, 4, 246, 165, 6, 4, 242,
+ 17, 6, 4, 246, 166, 6, 4, 246, 170, 6, 4, 246, 171, 6, 4, 252, 29, 6, 4,
+ 246, 168, 6, 4, 242, 18, 6, 4, 246, 169, 6, 4, 246, 203, 6, 4, 246, 204,
+ 6, 4, 248, 178, 6, 4, 243, 237, 6, 4, 242, 29, 6, 4, 242, 30, 6, 4, 246,
+ 202, 6, 4, 242, 28, 6, 4, 242, 32, 6, 4, 246, 208, 6, 4, 242, 31, 6, 4,
+ 246, 206, 6, 4, 246, 207, 6, 4, 248, 133, 6, 4, 243, 238, 6, 4, 246, 210,
+ 6, 4, 246, 211, 6, 4, 249, 125, 6, 4, 246, 209, 6, 4, 253, 45, 6, 4, 253,
+ 46, 6, 4, 253, 188, 6, 4, 253, 44, 6, 4, 247, 202, 6, 4, 247, 203, 6, 4,
+ 253, 43, 6, 4, 247, 201, 6, 4, 247, 205, 6, 4, 253, 52, 6, 4, 253, 50, 6,
+ 4, 253, 51, 6, 4, 254, 133, 6, 4, 253, 48, 6, 4, 253, 62, 6, 4, 253, 64,
+ 6, 4, 255, 7, 6, 4, 253, 60, 6, 4, 247, 210, 6, 4, 253, 61, 6, 4, 249,
+ 209, 6, 4, 253, 83, 6, 4, 253, 189, 6, 4, 253, 82, 6, 4, 247, 228, 6, 4,
+ 247, 229, 6, 4, 253, 80, 6, 4, 247, 227, 6, 4, 247, 240, 6, 4, 247, 241,
+ 6, 4, 253, 88, 6, 4, 247, 239, 6, 4, 249, 211, 6, 4, 253, 86, 6, 4, 253,
+ 162, 6, 4, 253, 85, 6, 4, 253, 91, 6, 4, 253, 92, 6, 4, 253, 161, 6, 4,
+ 253, 89, 6, 4, 247, 242, 6, 4, 253, 90, 6, 4, 253, 95, 6, 4, 253, 96, 6,
+ 4, 254, 77, 6, 4, 253, 93, 6, 4, 247, 243, 6, 4, 253, 94, 6, 25, 249,
+ 148, 6, 25, 253, 251, 6, 25, 249, 95, 6, 25, 243, 237, 6, 25, 249, 47, 6,
+ 25, 248, 249, 6, 25, 243, 180, 6, 25, 249, 69, 6, 25, 253, 180, 6, 25,
+ 243, 196, 6, 25, 249, 109, 6, 25, 243, 145, 6, 25, 249, 114, 6, 25, 253,
+ 162, 6, 25, 249, 142, 6, 25, 243, 198, 6, 25, 249, 174, 6, 25, 253, 139,
+ 6, 25, 249, 222, 6, 25, 249, 48, 6, 25, 243, 163, 6, 25, 249, 35, 6, 25,
+ 243, 181, 6, 25, 243, 238, 6, 25, 253, 196, 6, 25, 254, 120, 6, 25, 243,
+ 203, 6, 25, 249, 221, 6, 25, 249, 144, 6, 25, 249, 82, 6, 25, 249, 209,
+ 6, 25, 249, 197, 6, 25, 249, 163, 6, 25, 249, 193, 6, 25, 253, 163, 6,
+ 25, 253, 248, 6, 25, 243, 239, 6, 25, 249, 89, 6, 25, 249, 78, 6, 25,
+ 243, 202, 6, 25, 253, 177, 6, 25, 253, 232, 6, 25, 244, 15, 6, 25, 249,
+ 105, 6, 25, 254, 85, 6, 25, 243, 157, 6, 25, 249, 40, 6, 25, 243, 197, 6,
+ 25, 244, 8, 6, 25, 249, 223, 6, 25, 244, 13, 6, 25, 248, 88, 6, 25, 241,
+ 1, 6, 25, 243, 232, 6, 25, 253, 172, 49, 1, 238, 85, 188, 254, 15, 243,
+ 243, 49, 1, 238, 85, 188, 248, 122, 243, 243, 49, 1, 238, 85, 188, 254,
+ 15, 240, 222, 49, 1, 238, 85, 188, 248, 122, 240, 222, 49, 1, 238, 85,
+ 188, 254, 15, 254, 29, 49, 1, 238, 85, 188, 248, 122, 254, 29, 49, 1,
+ 238, 85, 188, 254, 15, 253, 185, 49, 1, 238, 85, 188, 248, 122, 253, 185,
+ 49, 1, 234, 27, 240, 4, 188, 125, 49, 1, 200, 240, 4, 188, 125, 49, 1,
+ 254, 40, 240, 4, 188, 125, 49, 1, 170, 240, 4, 188, 125, 49, 1, 235, 87,
+ 240, 4, 188, 125, 49, 1, 234, 27, 240, 4, 235, 64, 188, 125, 49, 1, 200,
+ 240, 4, 235, 64, 188, 125, 49, 1, 254, 40, 240, 4, 235, 64, 188, 125, 49,
+ 1, 170, 240, 4, 235, 64, 188, 125, 49, 1, 235, 87, 240, 4, 235, 64, 188,
+ 125, 49, 1, 234, 27, 235, 64, 188, 125, 49, 1, 200, 235, 64, 188, 125,
+ 49, 1, 254, 40, 235, 64, 188, 125, 49, 1, 170, 235, 64, 188, 125, 49, 1,
+ 235, 87, 235, 64, 188, 125, 239, 253, 242, 214, 1, 67, 239, 253, 242,
+ 214, 1, 71, 239, 253, 242, 214, 21, 236, 10, 239, 253, 242, 214, 1, 79,
+ 239, 253, 242, 214, 1, 72, 239, 253, 242, 214, 1, 73, 239, 253, 242, 214,
+ 21, 237, 170, 239, 253, 242, 214, 1, 253, 190, 239, 253, 242, 214, 1,
+ 248, 220, 239, 253, 242, 214, 1, 253, 234, 239, 253, 242, 214, 1, 249,
+ 75, 239, 253, 242, 214, 21, 235, 61, 239, 253, 242, 214, 1, 253, 224,
+ 239, 253, 242, 214, 1, 248, 125, 239, 253, 242, 214, 1, 253, 248, 239,
+ 253, 242, 214, 1, 251, 114, 239, 253, 242, 214, 1, 249, 6, 239, 253, 242,
+ 214, 1, 243, 131, 239, 253, 242, 214, 1, 248, 204, 239, 253, 242, 214, 1,
+ 245, 44, 239, 253, 242, 214, 1, 87, 239, 253, 242, 214, 1, 248, 97, 239,
+ 253, 242, 214, 1, 253, 225, 239, 253, 242, 214, 1, 250, 193, 239, 253,
+ 242, 214, 1, 253, 173, 239, 253, 242, 214, 1, 253, 208, 239, 253, 242,
+ 214, 1, 248, 238, 239, 253, 242, 214, 1, 254, 1, 239, 253, 242, 214, 1,
+ 250, 120, 239, 253, 242, 214, 1, 253, 181, 239, 253, 242, 214, 1, 253,
+ 160, 239, 253, 242, 214, 1, 253, 216, 239, 253, 242, 214, 1, 249, 157,
+ 239, 253, 242, 214, 1, 253, 186, 239, 253, 242, 214, 1, 253, 184, 239,
+ 253, 242, 214, 33, 21, 67, 239, 253, 242, 214, 33, 21, 71, 239, 253, 242,
+ 214, 33, 21, 79, 239, 253, 242, 214, 33, 21, 72, 239, 253, 242, 214, 33,
+ 21, 253, 156, 239, 253, 242, 214, 240, 120, 238, 200, 239, 253, 242, 214,
+ 240, 120, 238, 201, 239, 253, 242, 214, 240, 120, 239, 127, 239, 253,
+ 242, 214, 240, 120, 239, 128, 7, 9, 229, 68, 7, 9, 229, 69, 7, 9, 229,
+ 70, 7, 9, 229, 71, 7, 9, 229, 72, 7, 9, 229, 73, 7, 9, 229, 74, 7, 9,
+ 229, 75, 7, 9, 229, 76, 7, 9, 229, 77, 7, 9, 229, 78, 7, 9, 229, 79, 7,
+ 9, 229, 80, 7, 9, 229, 81, 7, 9, 229, 82, 7, 9, 229, 83, 7, 9, 229, 84,
+ 7, 9, 229, 85, 7, 9, 229, 86, 7, 9, 229, 87, 7, 9, 229, 88, 7, 9, 229,
+ 89, 7, 9, 229, 90, 7, 9, 229, 91, 7, 9, 229, 92, 7, 9, 229, 93, 7, 9,
+ 229, 94, 7, 9, 229, 95, 7, 9, 229, 96, 7, 9, 229, 97, 7, 9, 229, 98, 7,
+ 9, 229, 99, 7, 9, 229, 100, 7, 9, 229, 101, 7, 9, 229, 102, 7, 9, 229,
+ 103, 7, 9, 229, 104, 7, 9, 229, 105, 7, 9, 229, 106, 7, 9, 229, 107, 7,
+ 9, 229, 108, 7, 9, 229, 109, 7, 9, 229, 110, 7, 9, 229, 111, 7, 9, 229,
+ 112, 7, 9, 229, 113, 7, 9, 229, 114, 7, 9, 229, 115, 7, 9, 229, 116, 7,
+ 9, 229, 117, 7, 9, 229, 118, 7, 9, 229, 119, 7, 9, 229, 120, 7, 9, 229,
+ 121, 7, 9, 229, 122, 7, 9, 229, 123, 7, 9, 229, 124, 7, 9, 229, 125, 7,
+ 9, 229, 126, 7, 9, 229, 127, 7, 9, 229, 128, 7, 9, 229, 129, 7, 9, 229,
+ 130, 7, 9, 229, 131, 7, 9, 229, 132, 7, 9, 229, 133, 7, 9, 229, 134, 7,
+ 9, 229, 135, 7, 9, 229, 136, 7, 9, 229, 137, 7, 9, 229, 138, 7, 9, 229,
+ 139, 7, 9, 229, 140, 7, 9, 229, 141, 7, 9, 229, 142, 7, 9, 229, 143, 7,
+ 9, 229, 144, 7, 9, 229, 145, 7, 9, 229, 146, 7, 9, 229, 147, 7, 9, 229,
+ 148, 7, 9, 229, 149, 7, 9, 229, 150, 7, 9, 229, 151, 7, 9, 229, 152, 7,
+ 9, 229, 153, 7, 9, 229, 154, 7, 9, 229, 155, 7, 9, 229, 156, 7, 9, 229,
+ 157, 7, 9, 229, 158, 7, 9, 229, 159, 7, 9, 229, 160, 7, 9, 229, 161, 7,
+ 9, 229, 162, 7, 9, 229, 163, 7, 9, 229, 164, 7, 9, 229, 165, 7, 9, 229,
+ 166, 7, 9, 229, 167, 7, 9, 229, 168, 7, 9, 229, 169, 7, 9, 229, 170, 7,
+ 9, 229, 171, 7, 9, 229, 172, 7, 9, 229, 173, 7, 9, 229, 174, 7, 9, 229,
+ 175, 7, 9, 229, 176, 7, 9, 229, 177, 7, 9, 229, 178, 7, 9, 229, 179, 7,
+ 9, 229, 180, 7, 9, 229, 181, 7, 9, 229, 182, 7, 9, 229, 183, 7, 9, 229,
+ 184, 7, 9, 229, 185, 7, 9, 229, 186, 7, 9, 229, 187, 7, 9, 229, 188, 7,
+ 9, 229, 189, 7, 9, 229, 190, 7, 9, 229, 191, 7, 9, 229, 192, 7, 9, 229,
+ 193, 7, 9, 229, 194, 7, 9, 229, 195, 7, 9, 229, 196, 7, 9, 229, 197, 7,
+ 9, 229, 198, 7, 9, 229, 199, 7, 9, 229, 200, 7, 9, 229, 201, 7, 9, 229,
+ 202, 7, 9, 229, 203, 7, 9, 229, 204, 7, 9, 229, 205, 7, 9, 229, 206, 7,
+ 9, 229, 207, 7, 9, 229, 208, 7, 9, 229, 209, 7, 9, 229, 210, 7, 9, 229,
+ 211, 7, 9, 229, 212, 7, 9, 229, 213, 7, 9, 229, 214, 7, 9, 229, 215, 7,
+ 9, 229, 216, 7, 9, 229, 217, 7, 9, 229, 218, 7, 9, 229, 219, 7, 9, 229,
+ 220, 7, 9, 229, 221, 7, 9, 229, 222, 7, 9, 229, 223, 7, 9, 229, 224, 7,
+ 9, 229, 225, 7, 9, 229, 226, 7, 9, 229, 227, 7, 9, 229, 228, 7, 9, 229,
+ 229, 7, 9, 229, 230, 7, 9, 229, 231, 7, 9, 229, 232, 7, 9, 229, 233, 7,
+ 9, 229, 234, 7, 9, 229, 235, 7, 9, 229, 236, 7, 9, 229, 237, 7, 9, 229,
+ 238, 7, 9, 229, 239, 7, 9, 229, 240, 7, 9, 229, 241, 7, 9, 229, 242, 7,
+ 9, 229, 243, 7, 9, 229, 244, 7, 9, 229, 245, 7, 9, 229, 246, 7, 9, 229,
+ 247, 7, 9, 229, 248, 7, 9, 229, 249, 7, 9, 229, 250, 7, 9, 229, 251, 7,
+ 9, 229, 252, 7, 9, 229, 253, 7, 9, 229, 254, 7, 9, 229, 255, 7, 9, 230,
+ 0, 7, 9, 230, 1, 7, 9, 230, 2, 7, 9, 230, 3, 7, 9, 230, 4, 7, 9, 230, 5,
+ 7, 9, 230, 6, 7, 9, 230, 7, 7, 9, 230, 8, 7, 9, 230, 9, 7, 9, 230, 10, 7,
+ 9, 230, 11, 7, 9, 230, 12, 7, 9, 230, 13, 7, 9, 230, 14, 7, 9, 230, 15,
+ 7, 9, 230, 16, 7, 9, 230, 17, 7, 9, 230, 18, 7, 9, 230, 19, 7, 9, 230,
+ 20, 7, 9, 230, 21, 7, 9, 230, 22, 7, 9, 230, 23, 7, 9, 230, 24, 7, 9,
+ 230, 25, 7, 9, 230, 26, 7, 9, 230, 27, 7, 9, 230, 28, 7, 9, 230, 29, 7,
+ 9, 230, 30, 7, 9, 230, 31, 7, 9, 230, 32, 7, 9, 230, 33, 7, 9, 230, 34,
+ 7, 9, 230, 35, 7, 9, 230, 36, 7, 9, 230, 37, 7, 9, 230, 38, 7, 9, 230,
+ 39, 7, 9, 230, 40, 7, 9, 230, 41, 7, 9, 230, 42, 7, 9, 230, 43, 7, 9,
+ 230, 44, 7, 9, 230, 45, 7, 9, 230, 46, 7, 9, 230, 47, 7, 9, 230, 48, 7,
+ 9, 230, 49, 7, 9, 230, 50, 7, 9, 230, 51, 7, 9, 230, 52, 7, 9, 230, 53,
+ 7, 9, 230, 54, 7, 9, 230, 55, 7, 9, 230, 56, 7, 9, 230, 57, 7, 9, 230,
+ 58, 7, 9, 230, 59, 7, 9, 230, 60, 7, 9, 230, 61, 7, 9, 230, 62, 7, 9,
+ 230, 63, 7, 9, 230, 64, 7, 9, 230, 65, 7, 9, 230, 66, 7, 9, 230, 67, 7,
+ 9, 230, 68, 7, 9, 230, 69, 7, 9, 230, 70, 7, 9, 230, 71, 7, 9, 230, 72,
+ 7, 9, 230, 73, 7, 9, 230, 74, 7, 9, 230, 75, 7, 9, 230, 76, 7, 9, 230,
+ 77, 7, 9, 230, 78, 7, 9, 230, 79, 7, 9, 230, 80, 7, 9, 230, 81, 7, 9,
+ 230, 82, 7, 9, 230, 83, 7, 9, 230, 84, 7, 9, 230, 85, 7, 9, 230, 86, 7,
+ 9, 230, 87, 7, 9, 230, 88, 7, 9, 230, 89, 7, 9, 230, 90, 7, 9, 230, 91,
+ 7, 9, 230, 92, 7, 9, 230, 93, 7, 9, 230, 94, 7, 9, 230, 95, 7, 9, 230,
+ 96, 7, 9, 230, 97, 7, 9, 230, 98, 7, 9, 230, 99, 7, 9, 230, 100, 7, 9,
+ 230, 101, 7, 9, 230, 102, 7, 9, 230, 103, 7, 9, 230, 104, 7, 9, 230, 105,
+ 7, 9, 230, 106, 7, 9, 230, 107, 7, 9, 230, 108, 7, 9, 230, 109, 7, 9,
+ 230, 110, 7, 9, 230, 111, 7, 9, 230, 112, 7, 9, 230, 113, 7, 9, 230, 114,
+ 7, 9, 230, 115, 7, 9, 230, 116, 7, 9, 230, 117, 7, 9, 230, 118, 7, 9,
+ 230, 119, 7, 9, 230, 120, 7, 9, 230, 121, 7, 9, 230, 122, 7, 9, 230, 123,
+ 7, 9, 230, 124, 7, 9, 230, 125, 7, 9, 230, 126, 7, 9, 230, 127, 7, 9,
+ 230, 128, 7, 9, 230, 129, 7, 9, 230, 130, 7, 9, 230, 131, 7, 9, 230, 132,
+ 7, 9, 230, 133, 7, 9, 230, 134, 7, 9, 230, 135, 7, 9, 230, 136, 7, 9,
+ 230, 137, 7, 9, 230, 138, 7, 9, 230, 139, 7, 9, 230, 140, 7, 9, 230, 141,
+ 7, 9, 230, 142, 7, 9, 230, 143, 7, 9, 230, 144, 7, 9, 230, 145, 7, 9,
+ 230, 146, 7, 9, 230, 147, 7, 9, 230, 148, 7, 9, 230, 149, 7, 9, 230, 150,
+ 7, 9, 230, 151, 7, 9, 230, 152, 7, 9, 230, 153, 7, 9, 230, 154, 7, 9,
+ 230, 155, 7, 9, 230, 156, 7, 9, 230, 157, 7, 9, 230, 158, 7, 9, 230, 159,
+ 7, 9, 230, 160, 7, 9, 230, 161, 7, 9, 230, 162, 7, 9, 230, 163, 7, 9,
+ 230, 164, 7, 9, 230, 165, 7, 9, 230, 166, 7, 9, 230, 167, 7, 9, 230, 168,
+ 7, 9, 230, 169, 7, 9, 230, 170, 7, 9, 230, 171, 7, 9, 230, 172, 7, 9,
+ 230, 173, 7, 9, 230, 174, 7, 9, 230, 175, 7, 9, 230, 176, 7, 9, 230, 177,
+ 7, 9, 230, 178, 7, 9, 230, 179, 7, 9, 230, 180, 7, 9, 230, 181, 7, 9,
+ 230, 182, 7, 9, 230, 183, 7, 9, 230, 184, 7, 9, 230, 185, 7, 9, 230, 186,
+ 7, 9, 230, 187, 7, 9, 230, 188, 7, 9, 230, 189, 7, 9, 230, 190, 7, 9,
+ 230, 191, 7, 9, 230, 192, 7, 9, 230, 193, 7, 9, 230, 194, 7, 9, 230, 195,
+ 7, 9, 230, 196, 7, 9, 230, 197, 7, 9, 230, 198, 7, 9, 230, 199, 7, 9,
+ 230, 200, 7, 9, 230, 201, 7, 9, 230, 202, 7, 9, 230, 203, 7, 9, 230, 204,
+ 7, 9, 230, 205, 7, 9, 230, 206, 7, 9, 230, 207, 7, 9, 230, 208, 7, 9,
+ 230, 209, 7, 9, 230, 210, 7, 9, 230, 211, 7, 9, 230, 212, 7, 9, 230, 213,
+ 7, 9, 230, 214, 7, 9, 230, 215, 7, 9, 230, 216, 7, 9, 230, 217, 7, 9,
+ 230, 218, 7, 9, 230, 219, 7, 9, 230, 220, 7, 9, 230, 221, 7, 9, 230, 222,
+ 7, 9, 230, 223, 7, 9, 230, 224, 7, 9, 230, 225, 7, 9, 230, 226, 7, 9,
+ 230, 227, 7, 9, 230, 228, 7, 9, 230, 229, 7, 9, 230, 230, 7, 9, 230, 231,
+ 7, 9, 230, 232, 7, 9, 230, 233, 7, 9, 230, 234, 7, 9, 230, 235, 7, 9,
+ 230, 236, 7, 9, 230, 237, 7, 9, 230, 238, 7, 9, 230, 239, 7, 9, 230, 240,
+ 7, 9, 230, 241, 7, 9, 230, 242, 7, 9, 230, 243, 7, 9, 230, 244, 7, 9,
+ 230, 245, 7, 9, 230, 246, 7, 9, 230, 247, 7, 9, 230, 248, 7, 9, 230, 249,
+ 7, 9, 230, 250, 7, 9, 230, 251, 7, 9, 230, 252, 7, 9, 230, 253, 7, 9,
+ 230, 254, 7, 9, 230, 255, 7, 9, 231, 0, 7, 9, 231, 1, 7, 9, 231, 2, 7, 9,
+ 231, 3, 7, 9, 231, 4, 7, 9, 231, 5, 7, 9, 231, 6, 7, 9, 231, 7, 7, 9,
+ 231, 8, 7, 9, 231, 9, 7, 9, 231, 10, 7, 9, 231, 11, 7, 9, 231, 12, 7, 9,
+ 231, 13, 7, 9, 231, 14, 7, 9, 231, 15, 7, 9, 231, 16, 7, 9, 231, 17, 7,
+ 9, 231, 18, 7, 9, 231, 19, 7, 9, 231, 20, 7, 9, 231, 21, 7, 9, 231, 22,
+ 8, 3, 18, 254, 162, 8, 3, 18, 253, 245, 8, 3, 18, 254, 163, 8, 3, 18,
+ 250, 241, 8, 3, 18, 250, 242, 8, 3, 18, 183, 255, 99, 214, 8, 3, 18, 254,
+ 242, 100, 3, 18, 254, 39, 248, 175, 100, 3, 18, 254, 39, 248, 208, 100,
+ 3, 18, 254, 39, 248, 216, 100, 3, 18, 255, 0, 248, 175, 100, 3, 18, 254,
+ 39, 249, 17, 68, 1, 254, 50, 2, 240, 187, 68, 242, 232, 231, 144, 239,
+ 241, 68, 18, 238, 126, 254, 50, 254, 50, 240, 118, 68, 1, 233, 68, 243,
+ 144, 68, 1, 248, 98, 243, 3, 68, 1, 248, 98, 240, 165, 68, 1, 248, 98,
+ 253, 168, 68, 1, 248, 98, 248, 116, 68, 1, 248, 98, 240, 139, 68, 1, 248,
+ 98, 30, 248, 166, 68, 1, 248, 98, 243, 253, 68, 1, 248, 98, 249, 175, 68,
+ 1, 233, 68, 248, 49, 52, 68, 1, 248, 102, 2, 248, 102, 248, 40, 68, 1,
+ 248, 102, 2, 254, 73, 248, 40, 68, 1, 248, 102, 2, 240, 133, 19, 248,
+ 102, 248, 40, 68, 1, 248, 102, 2, 240, 133, 19, 254, 73, 248, 40, 68, 1,
+ 83, 2, 240, 118, 68, 1, 83, 2, 238, 149, 68, 1, 83, 2, 240, 140, 68, 1,
+ 254, 53, 2, 238, 61, 68, 1, 243, 184, 2, 238, 61, 68, 1, 243, 162, 2,
+ 238, 61, 68, 1, 255, 76, 2, 240, 140, 68, 1, 254, 76, 2, 238, 61, 68, 1,
+ 247, 244, 2, 238, 61, 68, 1, 254, 247, 2, 238, 61, 68, 1, 254, 50, 2,
+ 238, 61, 68, 1, 30, 253, 135, 2, 238, 61, 68, 1, 253, 135, 2, 238, 61,
+ 68, 1, 246, 38, 2, 238, 61, 68, 1, 254, 201, 2, 238, 61, 68, 1, 254, 114,
+ 2, 238, 61, 68, 1, 242, 94, 2, 238, 61, 68, 1, 30, 255, 38, 2, 238, 61,
+ 68, 1, 255, 38, 2, 238, 61, 68, 1, 247, 161, 2, 238, 61, 68, 1, 254, 233,
+ 2, 238, 61, 68, 1, 252, 134, 2, 238, 61, 68, 1, 248, 102, 2, 238, 61, 68,
+ 1, 254, 245, 2, 238, 61, 68, 1, 254, 76, 2, 240, 188, 68, 1, 254, 53, 2,
+ 243, 70, 68, 1, 253, 135, 2, 243, 70, 68, 1, 255, 38, 2, 243, 70, 68, 18,
+ 83, 240, 139, 11, 1, 83, 244, 49, 39, 13, 11, 1, 83, 244, 49, 30, 13, 11,
+ 1, 248, 147, 39, 13, 11, 1, 248, 147, 30, 13, 11, 1, 248, 147, 54, 13,
+ 11, 1, 248, 147, 113, 13, 11, 1, 254, 44, 39, 13, 11, 1, 254, 44, 30, 13,
+ 11, 1, 254, 44, 54, 13, 11, 1, 254, 44, 113, 13, 11, 1, 243, 52, 39, 13,
+ 11, 1, 243, 52, 30, 13, 11, 1, 243, 52, 54, 13, 11, 1, 243, 52, 113, 13,
+ 11, 1, 240, 124, 39, 13, 11, 1, 240, 124, 30, 13, 11, 1, 240, 124, 54,
+ 13, 11, 1, 240, 124, 113, 13, 11, 1, 243, 75, 39, 13, 11, 1, 243, 75, 30,
+ 13, 11, 1, 243, 75, 54, 13, 11, 1, 243, 75, 113, 13, 11, 1, 248, 189, 39,
+ 13, 11, 1, 248, 189, 30, 13, 11, 1, 248, 189, 54, 13, 11, 1, 248, 189,
+ 113, 13, 11, 1, 254, 47, 39, 13, 11, 1, 254, 47, 30, 13, 11, 1, 254, 47,
+ 54, 13, 11, 1, 254, 47, 113, 13, 11, 1, 243, 69, 39, 13, 11, 1, 243, 69,
+ 30, 13, 11, 1, 243, 69, 54, 13, 11, 1, 243, 69, 113, 13, 11, 1, 248, 152,
+ 39, 13, 11, 1, 248, 152, 30, 13, 11, 1, 248, 152, 54, 13, 11, 1, 248,
+ 152, 113, 13, 11, 1, 248, 177, 39, 13, 11, 1, 248, 177, 30, 13, 11, 1,
+ 248, 177, 54, 13, 11, 1, 248, 177, 113, 13, 11, 1, 243, 47, 39, 13, 11,
+ 1, 243, 47, 30, 13, 11, 1, 243, 47, 54, 13, 11, 1, 243, 47, 113, 13, 11,
+ 1, 238, 123, 39, 13, 11, 1, 238, 123, 30, 13, 11, 1, 238, 123, 54, 13,
+ 11, 1, 238, 123, 113, 13, 11, 1, 240, 166, 39, 13, 11, 1, 240, 166, 30,
+ 13, 11, 1, 243, 161, 39, 13, 11, 1, 243, 161, 30, 13, 11, 1, 254, 87, 39,
+ 13, 11, 1, 254, 87, 30, 13, 11, 1, 249, 49, 39, 13, 11, 1, 249, 49, 30,
+ 13, 11, 1, 254, 103, 39, 13, 11, 1, 254, 103, 30, 13, 11, 1, 249, 156,
+ 39, 13, 11, 1, 249, 156, 30, 13, 11, 1, 243, 21, 39, 13, 11, 1, 243, 21,
+ 30, 13, 11, 1, 243, 21, 54, 13, 11, 1, 243, 21, 113, 13, 11, 1, 253, 246,
+ 39, 13, 11, 1, 253, 246, 30, 13, 11, 1, 253, 246, 54, 13, 11, 1, 253,
+ 246, 113, 13, 11, 1, 248, 159, 39, 13, 11, 1, 248, 159, 30, 13, 11, 1,
+ 248, 159, 54, 13, 11, 1, 248, 159, 113, 13, 11, 1, 243, 67, 39, 13, 11,
+ 1, 243, 67, 30, 13, 11, 1, 243, 67, 54, 13, 11, 1, 243, 67, 113, 13, 11,
+ 1, 198, 240, 182, 39, 13, 11, 1, 198, 240, 182, 30, 13, 11, 1, 243, 71,
+ 39, 13, 11, 1, 243, 71, 30, 13, 11, 1, 243, 71, 54, 13, 11, 1, 243, 71,
+ 113, 13, 11, 1, 253, 124, 2, 57, 60, 39, 13, 11, 1, 253, 124, 2, 57, 60,
+ 30, 13, 11, 1, 253, 124, 248, 128, 39, 13, 11, 1, 253, 124, 248, 128, 30,
+ 13, 11, 1, 253, 124, 248, 128, 54, 13, 11, 1, 253, 124, 248, 128, 113,
+ 13, 11, 1, 253, 124, 233, 65, 39, 13, 11, 1, 253, 124, 233, 65, 30, 13,
+ 11, 1, 253, 124, 233, 65, 54, 13, 11, 1, 253, 124, 233, 65, 113, 13, 11,
+ 1, 57, 240, 92, 39, 13, 11, 1, 57, 240, 92, 30, 13, 11, 1, 57, 240, 92,
+ 2, 143, 60, 39, 13, 11, 1, 57, 240, 92, 2, 143, 60, 30, 13, 11, 1, 255,
+ 44, 39, 13, 11, 1, 255, 44, 30, 13, 11, 1, 255, 44, 54, 13, 11, 1, 255,
+ 44, 113, 13, 11, 1, 132, 39, 13, 11, 1, 132, 30, 13, 11, 1, 255, 33, 39,
+ 13, 11, 1, 255, 33, 30, 13, 11, 1, 255, 36, 39, 13, 11, 1, 255, 36, 30,
+ 13, 11, 1, 132, 2, 143, 60, 39, 13, 11, 1, 255, 65, 39, 13, 11, 1, 255,
+ 65, 30, 13, 11, 1, 238, 73, 255, 33, 39, 13, 11, 1, 238, 73, 255, 33, 30,
+ 13, 11, 1, 238, 73, 255, 36, 39, 13, 11, 1, 238, 73, 255, 36, 30, 13, 11,
+ 1, 157, 39, 13, 11, 1, 157, 30, 13, 11, 1, 157, 54, 13, 11, 1, 157, 113,
+ 13, 11, 1, 240, 104, 240, 192, 238, 73, 83, 150, 54, 13, 11, 1, 240, 104,
+ 240, 192, 238, 73, 83, 150, 113, 13, 11, 18, 57, 2, 143, 60, 2, 83, 39,
+ 13, 11, 18, 57, 2, 143, 60, 2, 83, 30, 13, 11, 18, 57, 2, 143, 60, 2,
+ 255, 30, 39, 13, 11, 18, 57, 2, 143, 60, 2, 255, 30, 30, 13, 11, 18, 57,
+ 2, 143, 60, 2, 253, 220, 39, 13, 11, 18, 57, 2, 143, 60, 2, 253, 220, 30,
+ 13, 11, 18, 57, 2, 143, 60, 2, 132, 39, 13, 11, 18, 57, 2, 143, 60, 2,
+ 132, 30, 13, 11, 18, 57, 2, 143, 60, 2, 255, 33, 39, 13, 11, 18, 57, 2,
+ 143, 60, 2, 255, 33, 30, 13, 11, 18, 57, 2, 143, 60, 2, 255, 36, 39, 13,
+ 11, 18, 57, 2, 143, 60, 2, 255, 36, 30, 13, 11, 18, 57, 2, 143, 60, 2,
+ 157, 39, 13, 11, 18, 57, 2, 143, 60, 2, 157, 30, 13, 11, 18, 57, 2, 143,
+ 60, 2, 157, 54, 13, 11, 18, 240, 104, 238, 73, 57, 2, 143, 60, 2, 83,
+ 150, 39, 13, 11, 18, 240, 104, 238, 73, 57, 2, 143, 60, 2, 83, 150, 30,
+ 13, 11, 18, 240, 104, 238, 73, 57, 2, 143, 60, 2, 83, 150, 54, 13, 11, 1,
+ 243, 26, 57, 39, 13, 11, 1, 243, 26, 57, 30, 13, 11, 1, 243, 26, 57, 54,
+ 13, 11, 1, 243, 26, 57, 113, 13, 11, 18, 57, 2, 143, 60, 2, 103, 39, 13,
+ 11, 18, 57, 2, 143, 60, 2, 94, 39, 13, 11, 18, 57, 2, 143, 60, 2, 51, 39,
+ 13, 11, 18, 57, 2, 143, 60, 2, 83, 150, 39, 13, 11, 18, 57, 2, 143, 60,
+ 2, 57, 39, 13, 11, 18, 253, 136, 2, 103, 39, 13, 11, 18, 253, 136, 2, 94,
+ 39, 13, 11, 18, 253, 136, 2, 164, 39, 13, 11, 18, 253, 136, 2, 51, 39,
+ 13, 11, 18, 253, 136, 2, 83, 150, 39, 13, 11, 18, 253, 136, 2, 57, 39,
+ 13, 11, 18, 253, 127, 2, 103, 39, 13, 11, 18, 253, 127, 2, 94, 39, 13,
+ 11, 18, 253, 127, 2, 164, 39, 13, 11, 18, 253, 127, 2, 51, 39, 13, 11,
+ 18, 253, 127, 2, 83, 150, 39, 13, 11, 18, 253, 127, 2, 57, 39, 13, 11,
+ 18, 248, 70, 2, 103, 39, 13, 11, 18, 248, 70, 2, 51, 39, 13, 11, 18, 248,
+ 70, 2, 83, 150, 39, 13, 11, 18, 248, 70, 2, 57, 39, 13, 11, 18, 103, 2,
+ 94, 39, 13, 11, 18, 103, 2, 51, 39, 13, 11, 18, 94, 2, 103, 39, 13, 11,
+ 18, 94, 2, 51, 39, 13, 11, 18, 164, 2, 103, 39, 13, 11, 18, 164, 2, 94,
+ 39, 13, 11, 18, 164, 2, 51, 39, 13, 11, 18, 248, 39, 2, 103, 39, 13, 11,
+ 18, 248, 39, 2, 94, 39, 13, 11, 18, 248, 39, 2, 164, 39, 13, 11, 18, 248,
+ 39, 2, 51, 39, 13, 11, 18, 253, 157, 2, 94, 39, 13, 11, 18, 253, 157, 2,
+ 51, 39, 13, 11, 18, 253, 155, 2, 103, 39, 13, 11, 18, 253, 155, 2, 94,
+ 39, 13, 11, 18, 253, 155, 2, 164, 39, 13, 11, 18, 253, 155, 2, 51, 39,
+ 13, 11, 18, 253, 169, 2, 94, 39, 13, 11, 18, 253, 169, 2, 51, 39, 13, 11,
+ 18, 253, 255, 2, 51, 39, 13, 11, 18, 253, 158, 2, 103, 39, 13, 11, 18,
+ 253, 158, 2, 51, 39, 13, 11, 18, 242, 240, 2, 103, 39, 13, 11, 18, 242,
+ 240, 2, 51, 39, 13, 11, 18, 253, 153, 2, 103, 39, 13, 11, 18, 253, 153,
+ 2, 94, 39, 13, 11, 18, 253, 153, 2, 164, 39, 13, 11, 18, 253, 153, 2, 51,
+ 39, 13, 11, 18, 253, 153, 2, 83, 150, 39, 13, 11, 18, 253, 153, 2, 57,
+ 39, 13, 11, 18, 253, 167, 2, 94, 39, 13, 11, 18, 253, 167, 2, 51, 39, 13,
+ 11, 18, 253, 167, 2, 83, 150, 39, 13, 11, 18, 253, 167, 2, 57, 39, 13,
+ 11, 18, 253, 135, 2, 83, 39, 13, 11, 18, 253, 135, 2, 103, 39, 13, 11,
+ 18, 253, 135, 2, 94, 39, 13, 11, 18, 253, 135, 2, 164, 39, 13, 11, 18,
+ 253, 135, 2, 182, 39, 13, 11, 18, 253, 135, 2, 51, 39, 13, 11, 18, 253,
+ 135, 2, 83, 150, 39, 13, 11, 18, 253, 135, 2, 57, 39, 13, 11, 18, 182, 2,
+ 103, 39, 13, 11, 18, 182, 2, 94, 39, 13, 11, 18, 182, 2, 164, 39, 13, 11,
+ 18, 182, 2, 51, 39, 13, 11, 18, 182, 2, 83, 150, 39, 13, 11, 18, 182, 2,
+ 57, 39, 13, 11, 18, 51, 2, 103, 39, 13, 11, 18, 51, 2, 94, 39, 13, 11,
+ 18, 51, 2, 164, 39, 13, 11, 18, 51, 2, 51, 39, 13, 11, 18, 51, 2, 83,
+ 150, 39, 13, 11, 18, 51, 2, 57, 39, 13, 11, 18, 198, 2, 103, 39, 13, 11,
+ 18, 198, 2, 94, 39, 13, 11, 18, 198, 2, 164, 39, 13, 11, 18, 198, 2, 51,
+ 39, 13, 11, 18, 198, 2, 83, 150, 39, 13, 11, 18, 198, 2, 57, 39, 13, 11,
+ 18, 253, 124, 2, 103, 39, 13, 11, 18, 253, 124, 2, 51, 39, 13, 11, 18,
+ 253, 124, 2, 83, 150, 39, 13, 11, 18, 253, 124, 2, 57, 39, 13, 11, 18,
+ 57, 2, 103, 39, 13, 11, 18, 57, 2, 94, 39, 13, 11, 18, 57, 2, 164, 39,
+ 13, 11, 18, 57, 2, 51, 39, 13, 11, 18, 57, 2, 83, 150, 39, 13, 11, 18,
+ 57, 2, 57, 39, 13, 11, 18, 249, 0, 2, 233, 49, 83, 39, 13, 11, 18, 253,
+ 143, 2, 233, 49, 83, 39, 13, 11, 18, 83, 150, 2, 233, 49, 83, 39, 13, 11,
+ 18, 240, 47, 2, 237, 1, 39, 13, 11, 18, 240, 47, 2, 237, 15, 39, 13, 11,
+ 18, 240, 47, 2, 243, 40, 39, 13, 11, 18, 240, 47, 2, 243, 56, 39, 13, 11,
+ 18, 240, 47, 2, 243, 63, 39, 13, 11, 18, 240, 47, 2, 233, 49, 83, 39, 13,
+ 11, 18, 57, 2, 143, 60, 2, 253, 143, 30, 13, 11, 18, 57, 2, 143, 60, 2,
+ 248, 104, 30, 13, 11, 18, 57, 2, 143, 60, 2, 51, 30, 13, 11, 18, 57, 2,
+ 143, 60, 2, 198, 30, 13, 11, 18, 57, 2, 143, 60, 2, 83, 150, 30, 13, 11,
+ 18, 57, 2, 143, 60, 2, 57, 30, 13, 11, 18, 253, 136, 2, 253, 143, 30, 13,
+ 11, 18, 253, 136, 2, 248, 104, 30, 13, 11, 18, 253, 136, 2, 51, 30, 13,
+ 11, 18, 253, 136, 2, 198, 30, 13, 11, 18, 253, 136, 2, 83, 150, 30, 13,
+ 11, 18, 253, 136, 2, 57, 30, 13, 11, 18, 253, 127, 2, 253, 143, 30, 13,
+ 11, 18, 253, 127, 2, 248, 104, 30, 13, 11, 18, 253, 127, 2, 51, 30, 13,
+ 11, 18, 253, 127, 2, 198, 30, 13, 11, 18, 253, 127, 2, 83, 150, 30, 13,
+ 11, 18, 253, 127, 2, 57, 30, 13, 11, 18, 248, 70, 2, 253, 143, 30, 13,
+ 11, 18, 248, 70, 2, 248, 104, 30, 13, 11, 18, 248, 70, 2, 51, 30, 13, 11,
+ 18, 248, 70, 2, 198, 30, 13, 11, 18, 248, 70, 2, 83, 150, 30, 13, 11, 18,
+ 248, 70, 2, 57, 30, 13, 11, 18, 253, 153, 2, 83, 150, 30, 13, 11, 18,
+ 253, 153, 2, 57, 30, 13, 11, 18, 253, 167, 2, 83, 150, 30, 13, 11, 18,
+ 253, 167, 2, 57, 30, 13, 11, 18, 253, 135, 2, 83, 30, 13, 11, 18, 253,
+ 135, 2, 182, 30, 13, 11, 18, 253, 135, 2, 51, 30, 13, 11, 18, 253, 135,
+ 2, 83, 150, 30, 13, 11, 18, 253, 135, 2, 57, 30, 13, 11, 18, 182, 2, 51,
+ 30, 13, 11, 18, 182, 2, 83, 150, 30, 13, 11, 18, 182, 2, 57, 30, 13, 11,
+ 18, 51, 2, 83, 30, 13, 11, 18, 51, 2, 51, 30, 13, 11, 18, 198, 2, 253,
+ 143, 30, 13, 11, 18, 198, 2, 248, 104, 30, 13, 11, 18, 198, 2, 51, 30,
+ 13, 11, 18, 198, 2, 198, 30, 13, 11, 18, 198, 2, 83, 150, 30, 13, 11, 18,
+ 198, 2, 57, 30, 13, 11, 18, 83, 150, 2, 233, 49, 83, 30, 13, 11, 18, 57,
+ 2, 253, 143, 30, 13, 11, 18, 57, 2, 248, 104, 30, 13, 11, 18, 57, 2, 51,
+ 30, 13, 11, 18, 57, 2, 198, 30, 13, 11, 18, 57, 2, 83, 150, 30, 13, 11,
+ 18, 57, 2, 57, 30, 13, 11, 18, 57, 2, 143, 60, 2, 103, 54, 13, 11, 18,
+ 57, 2, 143, 60, 2, 94, 54, 13, 11, 18, 57, 2, 143, 60, 2, 164, 54, 13,
+ 11, 18, 57, 2, 143, 60, 2, 51, 54, 13, 11, 18, 57, 2, 143, 60, 2, 253,
+ 124, 54, 13, 11, 18, 253, 136, 2, 103, 54, 13, 11, 18, 253, 136, 2, 94,
+ 54, 13, 11, 18, 253, 136, 2, 164, 54, 13, 11, 18, 253, 136, 2, 51, 54,
+ 13, 11, 18, 253, 136, 2, 253, 124, 54, 13, 11, 18, 253, 127, 2, 103, 54,
+ 13, 11, 18, 253, 127, 2, 94, 54, 13, 11, 18, 253, 127, 2, 164, 54, 13,
+ 11, 18, 253, 127, 2, 51, 54, 13, 11, 18, 253, 127, 2, 253, 124, 54, 13,
+ 11, 18, 248, 70, 2, 51, 54, 13, 11, 18, 103, 2, 94, 54, 13, 11, 18, 103,
+ 2, 51, 54, 13, 11, 18, 94, 2, 103, 54, 13, 11, 18, 94, 2, 51, 54, 13, 11,
+ 18, 164, 2, 103, 54, 13, 11, 18, 164, 2, 51, 54, 13, 11, 18, 248, 39, 2,
+ 103, 54, 13, 11, 18, 248, 39, 2, 94, 54, 13, 11, 18, 248, 39, 2, 164, 54,
+ 13, 11, 18, 248, 39, 2, 51, 54, 13, 11, 18, 253, 157, 2, 94, 54, 13, 11,
+ 18, 253, 157, 2, 164, 54, 13, 11, 18, 253, 157, 2, 51, 54, 13, 11, 18,
+ 253, 155, 2, 103, 54, 13, 11, 18, 253, 155, 2, 94, 54, 13, 11, 18, 253,
+ 155, 2, 164, 54, 13, 11, 18, 253, 155, 2, 51, 54, 13, 11, 18, 253, 169,
+ 2, 94, 54, 13, 11, 18, 253, 255, 2, 51, 54, 13, 11, 18, 253, 158, 2, 103,
+ 54, 13, 11, 18, 253, 158, 2, 51, 54, 13, 11, 18, 242, 240, 2, 103, 54,
+ 13, 11, 18, 242, 240, 2, 51, 54, 13, 11, 18, 253, 153, 2, 103, 54, 13,
+ 11, 18, 253, 153, 2, 94, 54, 13, 11, 18, 253, 153, 2, 164, 54, 13, 11,
+ 18, 253, 153, 2, 51, 54, 13, 11, 18, 253, 167, 2, 94, 54, 13, 11, 18,
+ 253, 167, 2, 51, 54, 13, 11, 18, 253, 135, 2, 103, 54, 13, 11, 18, 253,
+ 135, 2, 94, 54, 13, 11, 18, 253, 135, 2, 164, 54, 13, 11, 18, 253, 135,
+ 2, 182, 54, 13, 11, 18, 253, 135, 2, 51, 54, 13, 11, 18, 182, 2, 103, 54,
+ 13, 11, 18, 182, 2, 94, 54, 13, 11, 18, 182, 2, 164, 54, 13, 11, 18, 182,
+ 2, 51, 54, 13, 11, 18, 182, 2, 253, 124, 54, 13, 11, 18, 51, 2, 103, 54,
+ 13, 11, 18, 51, 2, 94, 54, 13, 11, 18, 51, 2, 164, 54, 13, 11, 18, 51, 2,
+ 51, 54, 13, 11, 18, 198, 2, 103, 54, 13, 11, 18, 198, 2, 94, 54, 13, 11,
+ 18, 198, 2, 164, 54, 13, 11, 18, 198, 2, 51, 54, 13, 11, 18, 198, 2, 253,
+ 124, 54, 13, 11, 18, 253, 124, 2, 103, 54, 13, 11, 18, 253, 124, 2, 51,
+ 54, 13, 11, 18, 253, 124, 2, 233, 49, 83, 54, 13, 11, 18, 57, 2, 103, 54,
+ 13, 11, 18, 57, 2, 94, 54, 13, 11, 18, 57, 2, 164, 54, 13, 11, 18, 57, 2,
+ 51, 54, 13, 11, 18, 57, 2, 253, 124, 54, 13, 11, 18, 57, 2, 143, 60, 2,
+ 51, 113, 13, 11, 18, 57, 2, 143, 60, 2, 253, 124, 113, 13, 11, 18, 253,
+ 136, 2, 51, 113, 13, 11, 18, 253, 136, 2, 253, 124, 113, 13, 11, 18, 253,
+ 127, 2, 51, 113, 13, 11, 18, 253, 127, 2, 253, 124, 113, 13, 11, 18, 248,
+ 70, 2, 51, 113, 13, 11, 18, 248, 70, 2, 253, 124, 113, 13, 11, 18, 248,
+ 39, 2, 51, 113, 13, 11, 18, 248, 39, 2, 253, 124, 113, 13, 11, 18, 242,
+ 216, 2, 51, 113, 13, 11, 18, 242, 216, 2, 253, 124, 113, 13, 11, 18, 253,
+ 135, 2, 182, 113, 13, 11, 18, 253, 135, 2, 51, 113, 13, 11, 18, 182, 2,
+ 51, 113, 13, 11, 18, 198, 2, 51, 113, 13, 11, 18, 198, 2, 253, 124, 113,
+ 13, 11, 18, 57, 2, 51, 113, 13, 11, 18, 57, 2, 253, 124, 113, 13, 11, 18,
+ 240, 47, 2, 243, 40, 113, 13, 11, 18, 240, 47, 2, 243, 56, 113, 13, 11,
+ 18, 240, 47, 2, 243, 63, 113, 13, 11, 18, 253, 169, 2, 83, 150, 39, 13,
+ 11, 18, 253, 169, 2, 57, 39, 13, 11, 18, 253, 158, 2, 83, 150, 39, 13,
+ 11, 18, 253, 158, 2, 57, 39, 13, 11, 18, 242, 240, 2, 83, 150, 39, 13,
+ 11, 18, 242, 240, 2, 57, 39, 13, 11, 18, 248, 39, 2, 83, 150, 39, 13, 11,
+ 18, 248, 39, 2, 57, 39, 13, 11, 18, 242, 216, 2, 83, 150, 39, 13, 11, 18,
+ 242, 216, 2, 57, 39, 13, 11, 18, 94, 2, 83, 150, 39, 13, 11, 18, 94, 2,
+ 57, 39, 13, 11, 18, 103, 2, 83, 150, 39, 13, 11, 18, 103, 2, 57, 39, 13,
+ 11, 18, 164, 2, 83, 150, 39, 13, 11, 18, 164, 2, 57, 39, 13, 11, 18, 253,
+ 157, 2, 83, 150, 39, 13, 11, 18, 253, 157, 2, 57, 39, 13, 11, 18, 253,
+ 155, 2, 83, 150, 39, 13, 11, 18, 253, 155, 2, 57, 39, 13, 11, 18, 242,
+ 216, 2, 103, 39, 13, 11, 18, 242, 216, 2, 94, 39, 13, 11, 18, 242, 216,
+ 2, 164, 39, 13, 11, 18, 242, 216, 2, 51, 39, 13, 11, 18, 242, 216, 2,
+ 253, 143, 39, 13, 11, 18, 248, 39, 2, 253, 143, 39, 13, 11, 18, 253, 157,
+ 2, 253, 143, 39, 13, 11, 18, 253, 155, 2, 253, 143, 39, 13, 11, 18, 253,
+ 169, 2, 83, 150, 30, 13, 11, 18, 253, 169, 2, 57, 30, 13, 11, 18, 253,
+ 158, 2, 83, 150, 30, 13, 11, 18, 253, 158, 2, 57, 30, 13, 11, 18, 242,
+ 240, 2, 83, 150, 30, 13, 11, 18, 242, 240, 2, 57, 30, 13, 11, 18, 248,
+ 39, 2, 83, 150, 30, 13, 11, 18, 248, 39, 2, 57, 30, 13, 11, 18, 242, 216,
+ 2, 83, 150, 30, 13, 11, 18, 242, 216, 2, 57, 30, 13, 11, 18, 94, 2, 83,
+ 150, 30, 13, 11, 18, 94, 2, 57, 30, 13, 11, 18, 103, 2, 83, 150, 30, 13,
+ 11, 18, 103, 2, 57, 30, 13, 11, 18, 164, 2, 83, 150, 30, 13, 11, 18, 164,
+ 2, 57, 30, 13, 11, 18, 253, 157, 2, 83, 150, 30, 13, 11, 18, 253, 157, 2,
+ 57, 30, 13, 11, 18, 253, 155, 2, 83, 150, 30, 13, 11, 18, 253, 155, 2,
+ 57, 30, 13, 11, 18, 242, 216, 2, 103, 30, 13, 11, 18, 242, 216, 2, 94,
+ 30, 13, 11, 18, 242, 216, 2, 164, 30, 13, 11, 18, 242, 216, 2, 51, 30,
+ 13, 11, 18, 242, 216, 2, 253, 143, 30, 13, 11, 18, 248, 39, 2, 253, 143,
+ 30, 13, 11, 18, 253, 157, 2, 253, 143, 30, 13, 11, 18, 253, 155, 2, 253,
+ 143, 30, 13, 11, 18, 242, 216, 2, 103, 54, 13, 11, 18, 242, 216, 2, 94,
+ 54, 13, 11, 18, 242, 216, 2, 164, 54, 13, 11, 18, 242, 216, 2, 51, 54,
+ 13, 11, 18, 248, 39, 2, 253, 124, 54, 13, 11, 18, 242, 216, 2, 253, 124,
+ 54, 13, 11, 18, 253, 169, 2, 51, 54, 13, 11, 18, 248, 39, 2, 103, 113,
+ 13, 11, 18, 248, 39, 2, 94, 113, 13, 11, 18, 248, 39, 2, 164, 113, 13,
+ 11, 18, 242, 216, 2, 103, 113, 13, 11, 18, 242, 216, 2, 94, 113, 13, 11,
+ 18, 242, 216, 2, 164, 113, 13, 11, 18, 253, 169, 2, 51, 113, 13, 11, 18,
+ 253, 255, 2, 51, 113, 13, 11, 18, 83, 2, 236, 214, 30, 13, 11, 18, 83, 2,
+ 236, 214, 39, 13, 240, 206, 40, 232, 74, 240, 206, 38, 232, 74, 11, 18,
+ 253, 127, 2, 103, 2, 51, 54, 13, 11, 18, 253, 127, 2, 94, 2, 103, 30, 13,
+ 11, 18, 253, 127, 2, 94, 2, 103, 54, 13, 11, 18, 253, 127, 2, 94, 2, 51,
+ 54, 13, 11, 18, 253, 127, 2, 164, 2, 51, 54, 13, 11, 18, 253, 127, 2, 51,
+ 2, 103, 54, 13, 11, 18, 253, 127, 2, 51, 2, 94, 54, 13, 11, 18, 253, 127,
+ 2, 51, 2, 164, 54, 13, 11, 18, 103, 2, 51, 2, 94, 30, 13, 11, 18, 103, 2,
+ 51, 2, 94, 54, 13, 11, 18, 94, 2, 51, 2, 57, 30, 13, 11, 18, 94, 2, 51,
+ 2, 83, 150, 30, 13, 11, 18, 248, 39, 2, 94, 2, 103, 54, 13, 11, 18, 248,
+ 39, 2, 103, 2, 94, 54, 13, 11, 18, 248, 39, 2, 103, 2, 83, 150, 30, 13,
+ 11, 18, 248, 39, 2, 51, 2, 94, 30, 13, 11, 18, 248, 39, 2, 51, 2, 94, 54,
+ 13, 11, 18, 248, 39, 2, 51, 2, 103, 54, 13, 11, 18, 248, 39, 2, 51, 2,
+ 51, 30, 13, 11, 18, 248, 39, 2, 51, 2, 51, 54, 13, 11, 18, 253, 157, 2,
+ 94, 2, 94, 30, 13, 11, 18, 253, 157, 2, 94, 2, 94, 54, 13, 11, 18, 253,
+ 157, 2, 51, 2, 51, 30, 13, 11, 18, 242, 216, 2, 94, 2, 51, 30, 13, 11,
+ 18, 242, 216, 2, 94, 2, 51, 54, 13, 11, 18, 242, 216, 2, 103, 2, 57, 30,
+ 13, 11, 18, 242, 216, 2, 51, 2, 164, 30, 13, 11, 18, 242, 216, 2, 51, 2,
+ 164, 54, 13, 11, 18, 242, 216, 2, 51, 2, 51, 30, 13, 11, 18, 242, 216, 2,
+ 51, 2, 51, 54, 13, 11, 18, 253, 155, 2, 94, 2, 83, 150, 30, 13, 11, 18,
+ 253, 155, 2, 164, 2, 51, 30, 13, 11, 18, 253, 155, 2, 164, 2, 51, 54, 13,
+ 11, 18, 253, 169, 2, 51, 2, 94, 30, 13, 11, 18, 253, 169, 2, 51, 2, 94,
+ 54, 13, 11, 18, 253, 169, 2, 51, 2, 51, 54, 13, 11, 18, 253, 169, 2, 51,
+ 2, 57, 30, 13, 11, 18, 253, 158, 2, 103, 2, 51, 30, 13, 11, 18, 253, 158,
+ 2, 51, 2, 51, 30, 13, 11, 18, 253, 158, 2, 51, 2, 51, 54, 13, 11, 18,
+ 253, 158, 2, 51, 2, 83, 150, 30, 13, 11, 18, 242, 240, 2, 51, 2, 51, 30,
+ 13, 11, 18, 242, 240, 2, 51, 2, 57, 30, 13, 11, 18, 242, 240, 2, 51, 2,
+ 83, 150, 30, 13, 11, 18, 253, 153, 2, 164, 2, 51, 30, 13, 11, 18, 253,
+ 153, 2, 164, 2, 51, 54, 13, 11, 18, 253, 167, 2, 51, 2, 94, 30, 13, 11,
+ 18, 253, 167, 2, 51, 2, 51, 30, 13, 11, 18, 182, 2, 94, 2, 51, 30, 13,
+ 11, 18, 182, 2, 94, 2, 57, 30, 13, 11, 18, 182, 2, 94, 2, 83, 150, 30,
+ 13, 11, 18, 182, 2, 103, 2, 103, 54, 13, 11, 18, 182, 2, 103, 2, 103, 30,
+ 13, 11, 18, 182, 2, 164, 2, 51, 30, 13, 11, 18, 182, 2, 164, 2, 51, 54,
+ 13, 11, 18, 182, 2, 51, 2, 94, 30, 13, 11, 18, 182, 2, 51, 2, 94, 54, 13,
+ 11, 18, 51, 2, 94, 2, 103, 54, 13, 11, 18, 51, 2, 94, 2, 51, 54, 13, 11,
+ 18, 51, 2, 94, 2, 57, 30, 13, 11, 18, 51, 2, 103, 2, 94, 54, 13, 11, 18,
+ 51, 2, 103, 2, 51, 54, 13, 11, 18, 51, 2, 164, 2, 103, 54, 13, 11, 18,
+ 51, 2, 164, 2, 51, 54, 13, 11, 18, 51, 2, 103, 2, 164, 54, 13, 11, 18,
+ 253, 124, 2, 51, 2, 103, 54, 13, 11, 18, 253, 124, 2, 51, 2, 51, 54, 13,
+ 11, 18, 198, 2, 94, 2, 51, 54, 13, 11, 18, 198, 2, 94, 2, 83, 150, 30,
+ 13, 11, 18, 198, 2, 103, 2, 51, 30, 13, 11, 18, 198, 2, 103, 2, 51, 54,
+ 13, 11, 18, 198, 2, 103, 2, 83, 150, 30, 13, 11, 18, 198, 2, 51, 2, 57,
+ 30, 13, 11, 18, 198, 2, 51, 2, 83, 150, 30, 13, 11, 18, 57, 2, 51, 2, 51,
+ 30, 13, 11, 18, 57, 2, 51, 2, 51, 54, 13, 11, 18, 253, 136, 2, 164, 2,
+ 57, 30, 13, 11, 18, 253, 127, 2, 103, 2, 57, 30, 13, 11, 18, 253, 127, 2,
+ 103, 2, 83, 150, 30, 13, 11, 18, 253, 127, 2, 164, 2, 57, 30, 13, 11, 18,
+ 253, 127, 2, 164, 2, 83, 150, 30, 13, 11, 18, 253, 127, 2, 51, 2, 57, 30,
+ 13, 11, 18, 253, 127, 2, 51, 2, 83, 150, 30, 13, 11, 18, 103, 2, 51, 2,
+ 57, 30, 13, 11, 18, 103, 2, 94, 2, 83, 150, 30, 13, 11, 18, 103, 2, 51,
+ 2, 83, 150, 30, 13, 11, 18, 248, 39, 2, 164, 2, 83, 150, 30, 13, 11, 18,
+ 253, 157, 2, 94, 2, 57, 30, 13, 11, 18, 242, 216, 2, 94, 2, 57, 30, 13,
+ 11, 18, 253, 155, 2, 94, 2, 57, 30, 13, 11, 18, 182, 2, 103, 2, 57, 30,
+ 13, 11, 18, 182, 2, 51, 2, 57, 30, 13, 11, 18, 57, 2, 94, 2, 57, 30, 13,
+ 11, 18, 57, 2, 103, 2, 57, 30, 13, 11, 18, 57, 2, 51, 2, 57, 30, 13, 11,
+ 18, 51, 2, 51, 2, 57, 30, 13, 11, 18, 253, 167, 2, 51, 2, 57, 30, 13, 11,
+ 18, 198, 2, 94, 2, 57, 30, 13, 11, 18, 253, 167, 2, 51, 2, 94, 54, 13,
+ 11, 18, 182, 2, 94, 2, 51, 54, 13, 11, 18, 253, 158, 2, 51, 2, 57, 30,
+ 13, 11, 18, 253, 135, 2, 51, 2, 57, 30, 13, 11, 18, 198, 2, 103, 2, 94,
+ 54, 13, 11, 18, 51, 2, 164, 2, 57, 30, 13, 11, 18, 182, 2, 103, 2, 51,
+ 54, 13, 11, 18, 253, 135, 2, 51, 2, 51, 30, 13, 11, 18, 182, 2, 103, 2,
+ 51, 30, 13, 11, 18, 198, 2, 103, 2, 94, 30, 13, 11, 18, 103, 2, 94, 2,
+ 57, 30, 13, 11, 18, 94, 2, 103, 2, 57, 30, 13, 11, 18, 51, 2, 103, 2, 57,
+ 30, 13, 11, 18, 253, 153, 2, 51, 2, 57, 30, 13, 11, 18, 253, 136, 2, 94,
+ 2, 57, 30, 13, 11, 18, 253, 135, 2, 51, 2, 51, 54, 13, 11, 18, 253, 158,
+ 2, 103, 2, 51, 54, 13, 11, 18, 253, 157, 2, 51, 2, 51, 54, 13, 11, 18,
+ 248, 39, 2, 164, 2, 57, 30, 13, 11, 18, 198, 2, 103, 2, 57, 30, 13, 11,
+ 18, 244, 3, 249, 191, 255, 24, 238, 197, 248, 119, 21, 39, 13, 11, 18,
+ 252, 85, 249, 191, 255, 24, 238, 197, 248, 119, 21, 39, 13, 11, 18, 244,
+ 77, 39, 13, 11, 18, 244, 75, 39, 13, 11, 18, 237, 213, 39, 13, 11, 18,
+ 247, 64, 39, 13, 11, 18, 242, 77, 39, 13, 11, 18, 240, 107, 39, 13, 11,
+ 18, 238, 45, 39, 13, 11, 18, 244, 3, 39, 13, 11, 18, 233, 100, 240, 107,
+ 236, 140, 11, 18, 229, 46, 252, 136, 52, 11, 18, 235, 181, 235, 168, 234,
+ 93, 34, 233, 233, 34, 233, 234, 34, 233, 235, 34, 233, 236, 34, 233, 237,
+ 34, 233, 238, 34, 233, 239, 34, 233, 240, 34, 233, 241, 34, 232, 204, 34,
+ 232, 205, 34, 232, 206, 34, 232, 207, 34, 232, 208, 34, 232, 209, 34,
+ 232, 210, 232, 70, 248, 38, 28, 59, 240, 27, 232, 70, 248, 38, 28, 59,
+ 80, 240, 27, 232, 70, 248, 38, 28, 59, 80, 248, 37, 208, 232, 70, 248,
+ 38, 28, 59, 240, 24, 232, 70, 248, 38, 28, 59, 234, 14, 232, 70, 248, 38,
+ 28, 59, 233, 54, 69, 232, 70, 248, 38, 28, 59, 236, 156, 69, 232, 70,
+ 248, 38, 28, 59, 40, 64, 234, 11, 104, 232, 70, 248, 38, 28, 59, 38, 64,
+ 234, 11, 237, 79, 232, 70, 248, 38, 28, 59, 163, 235, 69, 50, 18, 40,
+ 243, 7, 50, 18, 38, 243, 7, 50, 45, 242, 219, 40, 243, 7, 50, 45, 242,
+ 219, 38, 243, 7, 232, 70, 248, 38, 28, 59, 171, 53, 238, 143, 232, 70,
+ 248, 38, 28, 59, 255, 28, 242, 235, 232, 70, 248, 38, 28, 59, 255, 23,
+ 242, 235, 232, 70, 248, 38, 28, 59, 170, 242, 224, 232, 70, 248, 38, 28,
+ 59, 248, 103, 170, 242, 224, 232, 70, 248, 38, 28, 59, 40, 232, 74, 232,
+ 70, 248, 38, 28, 59, 38, 232, 74, 232, 70, 248, 38, 28, 59, 40, 242, 225,
+ 104, 232, 70, 248, 38, 28, 59, 38, 242, 225, 104, 232, 70, 248, 38, 28,
+ 59, 40, 236, 171, 242, 255, 104, 232, 70, 248, 38, 28, 59, 38, 236, 171,
+ 242, 255, 104, 232, 70, 248, 38, 28, 59, 40, 86, 234, 11, 104, 232, 70,
+ 248, 38, 28, 59, 38, 86, 234, 11, 104, 232, 70, 248, 38, 28, 59, 40, 45,
+ 185, 104, 232, 70, 248, 38, 28, 59, 38, 45, 185, 104, 232, 70, 248, 38,
+ 28, 59, 40, 185, 104, 232, 70, 248, 38, 28, 59, 38, 185, 104, 232, 70,
+ 248, 38, 28, 59, 40, 240, 31, 104, 232, 70, 248, 38, 28, 59, 38, 240, 31,
+ 104, 232, 70, 248, 38, 28, 59, 40, 64, 240, 31, 104, 232, 70, 248, 38,
+ 28, 59, 38, 64, 240, 31, 104, 240, 221, 248, 40, 64, 240, 221, 248, 40,
+ 232, 70, 248, 38, 28, 59, 40, 31, 104, 232, 70, 248, 38, 28, 59, 38, 31,
+ 104, 240, 55, 235, 74, 234, 48, 235, 74, 248, 103, 235, 74, 45, 248, 103,
+ 235, 74, 240, 55, 170, 242, 224, 234, 48, 170, 242, 224, 248, 103, 170,
+ 242, 224, 3, 240, 27, 3, 80, 240, 27, 3, 248, 37, 208, 3, 234, 14, 3,
+ 240, 24, 3, 236, 156, 69, 3, 233, 54, 69, 3, 255, 28, 242, 235, 3, 40,
+ 232, 74, 3, 38, 232, 74, 3, 40, 242, 225, 104, 3, 38, 242, 225, 104, 3,
+ 40, 236, 171, 242, 255, 104, 3, 38, 236, 171, 242, 255, 104, 3, 61, 52,
+ 3, 234, 17, 3, 235, 52, 3, 248, 49, 52, 3, 231, 94, 3, 235, 44, 52, 3,
+ 232, 68, 52, 3, 240, 7, 52, 3, 238, 75, 236, 177, 3, 240, 114, 52, 3,
+ 238, 107, 52, 3, 234, 20, 254, 20, 11, 236, 214, 39, 13, 11, 239, 214, 2,
+ 236, 214, 48, 11, 237, 1, 39, 13, 11, 248, 138, 236, 26, 11, 237, 15, 39,
+ 13, 11, 243, 40, 39, 13, 11, 243, 40, 113, 13, 11, 243, 56, 39, 13, 11,
+ 243, 56, 113, 13, 11, 243, 63, 39, 13, 11, 243, 63, 113, 13, 11, 240, 47,
+ 39, 13, 11, 240, 47, 113, 13, 11, 244, 25, 39, 13, 11, 244, 25, 113, 13,
+ 11, 1, 143, 39, 13, 11, 1, 83, 2, 243, 42, 60, 39, 13, 11, 1, 83, 2, 243,
+ 42, 60, 30, 13, 11, 1, 83, 2, 143, 60, 39, 13, 11, 1, 83, 2, 143, 60, 30,
+ 13, 11, 1, 253, 220, 2, 143, 60, 39, 13, 11, 1, 253, 220, 2, 143, 60, 30,
+ 13, 11, 1, 83, 2, 143, 242, 230, 39, 13, 11, 1, 83, 2, 143, 242, 230, 30,
+ 13, 11, 1, 57, 2, 143, 60, 39, 13, 11, 1, 57, 2, 143, 60, 30, 13, 11, 1,
+ 57, 2, 143, 60, 54, 13, 11, 1, 57, 2, 143, 60, 113, 13, 11, 1, 83, 39,
+ 13, 11, 1, 83, 30, 13, 11, 1, 253, 136, 39, 13, 11, 1, 253, 136, 30, 13,
+ 11, 1, 253, 136, 54, 13, 11, 1, 253, 136, 113, 13, 11, 1, 253, 127, 238,
+ 144, 39, 13, 11, 1, 253, 127, 238, 144, 30, 13, 11, 1, 253, 127, 39, 13,
+ 11, 1, 253, 127, 30, 13, 11, 1, 253, 127, 54, 13, 11, 1, 253, 127, 113,
+ 13, 11, 1, 248, 70, 39, 13, 11, 1, 248, 70, 30, 13, 11, 1, 248, 70, 54,
+ 13, 11, 1, 248, 70, 113, 13, 11, 1, 103, 39, 13, 11, 1, 103, 30, 13, 11,
+ 1, 103, 54, 13, 11, 1, 103, 113, 13, 11, 1, 94, 39, 13, 11, 1, 94, 30,
+ 13, 11, 1, 94, 54, 13, 11, 1, 94, 113, 13, 11, 1, 164, 39, 13, 11, 1,
+ 164, 30, 13, 11, 1, 164, 54, 13, 11, 1, 164, 113, 13, 11, 1, 253, 199,
+ 39, 13, 11, 1, 253, 199, 30, 13, 11, 1, 249, 0, 39, 13, 11, 1, 249, 0,
+ 30, 13, 11, 1, 253, 143, 39, 13, 11, 1, 253, 143, 30, 13, 11, 1, 248,
+ 104, 39, 13, 11, 1, 248, 104, 30, 13, 11, 1, 248, 39, 39, 13, 11, 1, 248,
+ 39, 30, 13, 11, 1, 248, 39, 54, 13, 11, 1, 248, 39, 113, 13, 11, 1, 242,
+ 216, 39, 13, 11, 1, 242, 216, 30, 13, 11, 1, 242, 216, 54, 13, 11, 1,
+ 242, 216, 113, 13, 11, 1, 253, 157, 39, 13, 11, 1, 253, 157, 30, 13, 11,
+ 1, 253, 157, 54, 13, 11, 1, 253, 157, 113, 13, 11, 1, 253, 155, 39, 13,
+ 11, 1, 253, 155, 30, 13, 11, 1, 253, 155, 54, 13, 11, 1, 253, 155, 113,
+ 13, 11, 1, 253, 169, 39, 13, 11, 1, 253, 169, 30, 13, 11, 1, 253, 169,
+ 54, 13, 11, 1, 253, 169, 113, 13, 11, 1, 253, 255, 39, 13, 11, 1, 253,
+ 255, 30, 13, 11, 1, 253, 255, 54, 13, 11, 1, 253, 255, 113, 13, 11, 1,
+ 253, 158, 39, 13, 11, 1, 253, 158, 30, 13, 11, 1, 253, 158, 54, 13, 11,
+ 1, 253, 158, 113, 13, 11, 1, 242, 240, 39, 13, 11, 1, 242, 240, 30, 13,
+ 11, 1, 242, 240, 54, 13, 11, 1, 242, 240, 113, 13, 11, 1, 253, 153, 39,
+ 13, 11, 1, 253, 153, 30, 13, 11, 1, 253, 153, 54, 13, 11, 1, 253, 153,
+ 113, 13, 11, 1, 253, 167, 39, 13, 11, 1, 253, 167, 30, 13, 11, 1, 253,
+ 167, 54, 13, 11, 1, 253, 167, 113, 13, 11, 1, 253, 135, 39, 13, 11, 1,
+ 253, 135, 30, 13, 11, 1, 253, 135, 54, 13, 11, 1, 253, 135, 113, 13, 11,
+ 1, 182, 39, 13, 11, 1, 182, 30, 13, 11, 1, 182, 54, 13, 11, 1, 182, 113,
+ 13, 11, 1, 51, 39, 13, 11, 1, 51, 30, 13, 11, 1, 51, 54, 13, 11, 1, 51,
+ 113, 13, 11, 1, 198, 39, 13, 11, 1, 198, 30, 13, 11, 1, 198, 54, 13, 11,
+ 1, 198, 113, 13, 11, 1, 253, 124, 39, 13, 11, 1, 253, 124, 30, 13, 11, 1,
+ 253, 124, 54, 13, 11, 1, 253, 124, 113, 13, 11, 1, 253, 220, 39, 13, 11,
+ 1, 253, 220, 30, 13, 11, 1, 83, 150, 39, 13, 11, 1, 83, 150, 30, 13, 11,
+ 1, 57, 39, 13, 11, 1, 57, 30, 13, 11, 1, 57, 54, 13, 11, 1, 57, 113, 13,
+ 11, 18, 182, 2, 83, 2, 243, 42, 60, 39, 13, 11, 18, 182, 2, 83, 2, 243,
+ 42, 60, 30, 13, 11, 18, 182, 2, 83, 2, 143, 60, 39, 13, 11, 18, 182, 2,
+ 83, 2, 143, 60, 30, 13, 11, 18, 182, 2, 83, 2, 143, 242, 230, 39, 13, 11,
+ 18, 182, 2, 83, 2, 143, 242, 230, 30, 13, 11, 18, 182, 2, 83, 39, 13, 11,
+ 18, 182, 2, 83, 30, 13, 248, 145, 243, 81, 236, 233, 240, 15, 89, 233,
+ 54, 69, 89, 235, 51, 69, 89, 61, 52, 89, 240, 114, 52, 89, 238, 107, 52,
+ 89, 234, 17, 89, 233, 59, 89, 40, 232, 74, 89, 38, 232, 74, 89, 235, 52,
+ 89, 248, 49, 52, 89, 240, 27, 89, 231, 94, 89, 248, 37, 208, 89, 236,
+ 177, 89, 26, 242, 217, 89, 26, 127, 89, 26, 111, 89, 26, 166, 89, 26,
+ 177, 89, 26, 176, 89, 26, 187, 89, 26, 203, 89, 26, 195, 89, 26, 202, 89,
+ 240, 24, 89, 234, 14, 89, 235, 44, 52, 89, 240, 7, 52, 89, 232, 68, 52,
+ 89, 236, 156, 69, 89, 234, 20, 254, 20, 89, 8, 5, 1, 67, 89, 8, 5, 1,
+ 217, 89, 8, 5, 1, 255, 18, 89, 8, 5, 1, 209, 89, 8, 5, 1, 72, 89, 8, 5,
+ 1, 255, 19, 89, 8, 5, 1, 210, 89, 8, 5, 1, 192, 89, 8, 5, 1, 71, 89, 8,
+ 5, 1, 221, 89, 8, 5, 1, 255, 15, 89, 8, 5, 1, 162, 89, 8, 5, 1, 173, 89,
+ 8, 5, 1, 197, 89, 8, 5, 1, 73, 89, 8, 5, 1, 223, 89, 8, 5, 1, 255, 20,
+ 89, 8, 5, 1, 144, 89, 8, 5, 1, 193, 89, 8, 5, 1, 214, 89, 8, 5, 1, 79,
+ 89, 8, 5, 1, 179, 89, 8, 5, 1, 255, 16, 89, 8, 5, 1, 206, 89, 8, 5, 1,
+ 255, 14, 89, 8, 5, 1, 255, 17, 89, 40, 31, 104, 89, 238, 75, 236, 177,
+ 89, 38, 31, 104, 89, 190, 238, 54, 89, 170, 242, 224, 89, 242, 245, 238,
+ 54, 89, 8, 3, 1, 67, 89, 8, 3, 1, 217, 89, 8, 3, 1, 255, 18, 89, 8, 3, 1,
+ 209, 89, 8, 3, 1, 72, 89, 8, 3, 1, 255, 19, 89, 8, 3, 1, 210, 89, 8, 3,
+ 1, 192, 89, 8, 3, 1, 71, 89, 8, 3, 1, 221, 89, 8, 3, 1, 255, 15, 89, 8,
+ 3, 1, 162, 89, 8, 3, 1, 173, 89, 8, 3, 1, 197, 89, 8, 3, 1, 73, 89, 8, 3,
+ 1, 223, 89, 8, 3, 1, 255, 20, 89, 8, 3, 1, 144, 89, 8, 3, 1, 193, 89, 8,
+ 3, 1, 214, 89, 8, 3, 1, 79, 89, 8, 3, 1, 179, 89, 8, 3, 1, 255, 16, 89,
+ 8, 3, 1, 206, 89, 8, 3, 1, 255, 14, 89, 8, 3, 1, 255, 17, 89, 40, 242,
+ 225, 104, 89, 59, 242, 224, 89, 38, 242, 225, 104, 89, 169, 89, 40, 64,
+ 232, 74, 89, 38, 64, 232, 74, 74, 80, 248, 37, 208, 74, 40, 240, 31, 104,
+ 74, 38, 240, 31, 104, 74, 80, 240, 27, 74, 42, 240, 1, 248, 40, 74, 42,
+ 1, 253, 177, 74, 42, 1, 3, 67, 74, 42, 1, 3, 71, 74, 42, 1, 3, 79, 74,
+ 42, 1, 3, 72, 74, 42, 1, 3, 73, 74, 42, 1, 3, 216, 74, 42, 1, 3, 253,
+ 161, 74, 42, 1, 3, 253, 162, 74, 42, 1, 3, 253, 196, 74, 226, 254, 235,
+ 138, 243, 1, 69, 74, 42, 1, 67, 74, 42, 1, 71, 74, 42, 1, 79, 74, 42, 1,
+ 72, 74, 42, 1, 73, 74, 42, 1, 201, 74, 42, 1, 253, 215, 74, 42, 1, 253,
+ 203, 74, 42, 1, 253, 172, 74, 42, 1, 253, 190, 74, 42, 1, 253, 132, 74,
+ 42, 1, 253, 198, 74, 42, 1, 253, 211, 74, 42, 1, 253, 210, 74, 42, 1,
+ 253, 186, 74, 42, 1, 253, 126, 74, 42, 1, 253, 212, 74, 42, 1, 253, 196,
+ 74, 42, 1, 253, 195, 74, 42, 1, 87, 74, 42, 1, 253, 131, 74, 42, 1, 253,
+ 166, 74, 42, 1, 253, 150, 74, 42, 1, 253, 197, 74, 42, 1, 253, 173, 74,
+ 42, 1, 219, 74, 42, 1, 253, 214, 74, 42, 1, 253, 236, 74, 42, 1, 253,
+ 168, 74, 42, 1, 253, 184, 74, 42, 1, 222, 74, 42, 1, 253, 180, 74, 42, 1,
+ 253, 154, 74, 42, 1, 253, 206, 74, 42, 1, 253, 181, 74, 42, 1, 216, 74,
+ 42, 1, 253, 161, 74, 42, 1, 253, 162, 74, 42, 1, 253, 130, 74, 42, 1,
+ 253, 209, 74, 42, 1, 253, 185, 74, 42, 1, 253, 194, 74, 42, 1, 253, 160,
+ 74, 42, 1, 253, 138, 74, 42, 1, 197, 74, 42, 240, 59, 243, 1, 69, 74, 42,
+ 233, 75, 243, 1, 69, 74, 23, 238, 114, 74, 23, 1, 238, 99, 74, 23, 1,
+ 232, 87, 74, 23, 1, 232, 91, 74, 23, 1, 240, 80, 74, 23, 1, 232, 93, 74,
+ 23, 1, 232, 94, 74, 23, 1, 238, 102, 74, 23, 1, 232, 101, 74, 23, 1, 240,
+ 85, 74, 23, 1, 231, 98, 74, 23, 1, 232, 96, 74, 23, 1, 232, 97, 74, 23,
+ 1, 233, 74, 74, 23, 1, 231, 43, 74, 23, 1, 231, 42, 74, 23, 1, 232, 85,
+ 74, 23, 1, 240, 78, 74, 23, 1, 240, 83, 74, 23, 1, 233, 79, 74, 23, 1,
+ 233, 66, 74, 23, 1, 243, 34, 74, 23, 1, 234, 32, 74, 23, 1, 240, 75, 74,
+ 23, 1, 240, 71, 74, 23, 1, 233, 77, 74, 23, 1, 236, 195, 74, 23, 1, 236,
+ 198, 74, 23, 1, 236, 205, 74, 23, 1, 236, 201, 74, 23, 1, 240, 74, 74,
+ 23, 1, 67, 74, 23, 1, 253, 178, 74, 23, 1, 216, 74, 23, 1, 249, 18, 74,
+ 23, 1, 254, 59, 74, 23, 1, 72, 74, 23, 1, 249, 22, 74, 23, 1, 253, 254,
+ 74, 23, 1, 73, 74, 23, 1, 253, 138, 74, 23, 1, 249, 12, 74, 23, 1, 253,
+ 193, 74, 23, 1, 253, 162, 74, 23, 1, 79, 74, 23, 1, 249, 14, 74, 23, 1,
+ 253, 170, 74, 23, 1, 253, 187, 74, 23, 1, 253, 161, 74, 23, 1, 254, 61,
+ 74, 23, 1, 253, 189, 74, 23, 1, 71, 89, 249, 39, 52, 89, 243, 246, 52,
+ 89, 161, 52, 89, 196, 89, 240, 129, 125, 89, 254, 134, 52, 89, 254, 131,
+ 52, 74, 245, 91, 136, 235, 63, 74, 139, 56, 74, 226, 226, 56, 74, 77, 56,
+ 74, 235, 45, 56, 74, 86, 238, 59, 74, 64, 238, 51, 233, 71, 234, 4, 238,
+ 159, 233, 71, 234, 4, 234, 6, 233, 71, 234, 4, 233, 251, 242, 38, 233,
+ 99, 234, 49, 233, 99, 234, 49, 44, 41, 4, 249, 254, 67, 44, 41, 4, 250,
+ 23, 72, 44, 41, 4, 250, 15, 71, 44, 41, 4, 250, 43, 73, 44, 41, 4, 250,
+ 0, 79, 44, 41, 4, 249, 247, 253, 133, 44, 41, 4, 250, 30, 253, 200, 44,
+ 41, 4, 249, 253, 253, 201, 44, 41, 4, 250, 4, 253, 225, 44, 41, 4, 250,
+ 34, 253, 232, 44, 41, 4, 250, 39, 253, 146, 44, 41, 4, 250, 31, 254, 24,
+ 44, 41, 4, 250, 21, 253, 248, 44, 41, 4, 250, 45, 254, 25, 44, 41, 4,
+ 250, 57, 201, 44, 41, 4, 250, 29, 253, 172, 44, 41, 4, 250, 47, 253, 215,
+ 44, 41, 4, 250, 50, 253, 190, 44, 41, 4, 250, 60, 253, 203, 44, 41, 4,
+ 250, 59, 222, 44, 41, 4, 250, 3, 253, 206, 44, 41, 4, 250, 53, 253, 180,
+ 44, 41, 4, 250, 5, 253, 181, 44, 41, 4, 250, 10, 253, 154, 44, 41, 4,
+ 249, 252, 253, 131, 44, 41, 4, 250, 11, 253, 197, 44, 41, 4, 250, 17,
+ 253, 166, 44, 41, 4, 250, 35, 253, 173, 44, 41, 4, 250, 38, 253, 150, 44,
+ 41, 4, 249, 249, 253, 129, 44, 41, 4, 250, 52, 253, 175, 44, 41, 4, 250,
+ 24, 253, 147, 44, 41, 4, 250, 1, 253, 208, 44, 41, 4, 250, 33, 253, 239,
+ 44, 41, 4, 250, 6, 253, 217, 44, 41, 4, 250, 58, 254, 70, 44, 41, 4, 250,
+ 9, 254, 28, 44, 41, 4, 250, 19, 254, 45, 44, 41, 4, 250, 42, 253, 130,
+ 44, 41, 4, 250, 14, 253, 194, 44, 41, 4, 250, 36, 253, 209, 44, 41, 4,
+ 249, 248, 253, 160, 44, 41, 4, 250, 13, 253, 185, 44, 41, 4, 250, 18,
+ 253, 132, 44, 41, 4, 249, 255, 253, 210, 44, 41, 4, 250, 26, 253, 198,
+ 44, 41, 4, 250, 2, 253, 186, 44, 41, 4, 250, 40, 253, 211, 44, 41, 4,
+ 250, 41, 253, 126, 44, 41, 4, 249, 250, 253, 195, 44, 41, 4, 250, 22,
+ 253, 212, 44, 41, 4, 249, 251, 87, 44, 41, 4, 250, 49, 253, 196, 44, 41,
+ 4, 250, 37, 253, 138, 44, 41, 4, 250, 55, 253, 170, 44, 41, 4, 250, 25,
+ 253, 187, 44, 41, 4, 250, 27, 253, 177, 44, 41, 4, 250, 7, 253, 163, 44,
+ 41, 4, 250, 54, 253, 228, 44, 41, 4, 250, 8, 253, 222, 44, 41, 4, 250,
+ 12, 254, 137, 44, 41, 4, 250, 28, 254, 138, 44, 41, 4, 250, 61, 253, 151,
+ 44, 41, 4, 250, 51, 250, 215, 44, 41, 4, 250, 63, 250, 216, 44, 41, 4,
+ 250, 32, 248, 176, 44, 41, 4, 250, 16, 252, 77, 44, 41, 4, 250, 44, 252,
+ 76, 44, 41, 4, 250, 56, 252, 124, 44, 41, 4, 250, 20, 252, 125, 44, 41,
+ 4, 250, 48, 252, 141, 44, 41, 4, 250, 46, 252, 207, 44, 41, 4, 250, 62,
+ 249, 8, 44, 41, 4, 250, 64, 111, 44, 41, 12, 244, 88, 44, 41, 12, 244,
+ 89, 44, 41, 12, 244, 90, 44, 41, 12, 244, 91, 44, 41, 12, 244, 92, 44,
+ 41, 12, 244, 93, 44, 41, 12, 244, 94, 44, 41, 12, 244, 95, 44, 41, 12,
+ 244, 96, 44, 41, 12, 244, 97, 44, 41, 12, 244, 98, 44, 41, 12, 244, 99,
+ 44, 41, 12, 244, 100, 44, 41, 12, 244, 101, 44, 41, 78, 250, 65, 248,
+ 131, 44, 41, 78, 250, 66, 240, 253, 44, 41, 78, 250, 67, 243, 164, 44,
+ 41, 78, 250, 68, 241, 98, 44, 41, 78, 244, 102, 246, 63, 44, 41, 78, 244,
+ 103, 236, 106, 44, 41, 78, 244, 104, 249, 58, 44, 41, 78, 244, 105, 249,
+ 151, 44, 41, 78, 244, 106, 236, 102, 44, 41, 78, 244, 107, 237, 172, 44,
+ 41, 78, 244, 108, 252, 187, 44, 41, 78, 244, 109, 244, 225, 44, 41, 78,
+ 244, 110, 248, 202, 44, 41, 78, 244, 111, 244, 231, 44, 41, 78, 250, 69,
+ 240, 153, 44, 41, 78, 250, 70, 239, 4, 44, 41, 78, 250, 71, 242, 40, 44,
+ 41, 78, 250, 72, 242, 123, 44, 41, 78, 250, 73, 237, 99, 44, 41, 236,
+ 184, 250, 74, 246, 6, 44, 41, 236, 184, 250, 75, 239, 104, 44, 41, 78,
+ 250, 76, 249, 127, 44, 41, 78, 250, 77, 243, 133, 44, 41, 78, 244, 112,
+ 44, 41, 236, 184, 250, 78, 241, 13, 44, 41, 236, 184, 250, 79, 246, 64,
+ 44, 41, 78, 250, 80, 239, 14, 44, 41, 78, 250, 81, 243, 96, 44, 41, 78,
+ 244, 113, 44, 41, 78, 250, 82, 244, 53, 44, 41, 78, 244, 114, 44, 41, 78,
+ 244, 115, 44, 41, 78, 250, 83, 243, 8, 44, 41, 78, 244, 116, 44, 41, 78,
+ 244, 117, 44, 41, 78, 244, 118, 44, 41, 236, 184, 250, 84, 242, 163, 44,
+ 41, 78, 244, 120, 44, 41, 78, 244, 121, 44, 41, 78, 250, 85, 240, 132,
+ 44, 41, 78, 244, 122, 44, 41, 78, 244, 123, 44, 41, 78, 250, 86, 237,
+ 164, 44, 41, 78, 250, 87, 238, 248, 44, 41, 78, 244, 124, 44, 41, 78,
+ 244, 125, 44, 41, 78, 244, 126, 44, 41, 78, 244, 127, 44, 41, 78, 244,
+ 128, 44, 41, 78, 244, 129, 44, 41, 78, 244, 130, 44, 41, 78, 244, 131,
+ 44, 41, 78, 244, 132, 44, 41, 78, 250, 88, 241, 248, 44, 41, 78, 244,
+ 133, 44, 41, 78, 250, 89, 244, 37, 44, 41, 78, 244, 134, 44, 41, 78, 244,
+ 135, 44, 41, 78, 244, 136, 44, 41, 78, 244, 137, 44, 41, 78, 244, 138,
+ 44, 41, 78, 244, 139, 44, 41, 78, 244, 140, 44, 41, 78, 244, 141, 44, 41,
+ 78, 244, 142, 44, 41, 78, 244, 143, 44, 41, 78, 244, 144, 44, 41, 78,
+ 250, 90, 239, 90, 44, 41, 78, 250, 91, 234, 190, 44, 41, 78, 250, 92,
+ 237, 73, 44, 41, 78, 250, 93, 240, 236, 44, 41, 78, 250, 94, 56, 44, 41,
+ 78, 244, 171, 44, 41, 78, 250, 95, 242, 137, 44, 41, 78, 244, 172, 44,
+ 41, 78, 244, 173, 44, 41, 78, 250, 96, 239, 248, 236, 252, 44, 41, 78,
+ 250, 97, 236, 252, 44, 41, 78, 250, 98, 239, 22, 241, 116, 44, 41, 78,
+ 250, 99, 242, 184, 44, 41, 78, 244, 174, 44, 41, 78, 244, 175, 44, 41,
+ 236, 184, 250, 100, 241, 85, 44, 41, 78, 244, 176, 44, 41, 78, 244, 177,
+ 44, 41, 78, 244, 179, 44, 41, 78, 244, 180, 44, 41, 78, 244, 181, 44, 41,
+ 78, 250, 101, 245, 35, 44, 41, 78, 244, 182, 44, 41, 78, 244, 183, 44,
+ 41, 78, 244, 184, 44, 41, 78, 244, 185, 44, 41, 78, 244, 186, 44, 41, 78,
+ 240, 6, 244, 119, 44, 41, 78, 240, 6, 244, 145, 44, 41, 78, 240, 6, 244,
+ 146, 44, 41, 78, 240, 6, 244, 147, 44, 41, 78, 240, 6, 244, 148, 44, 41,
+ 78, 240, 6, 244, 149, 44, 41, 78, 240, 6, 244, 150, 44, 41, 78, 240, 6,
+ 244, 151, 44, 41, 78, 240, 6, 244, 152, 44, 41, 78, 240, 6, 244, 153, 44,
+ 41, 78, 240, 6, 244, 154, 44, 41, 78, 240, 6, 244, 155, 44, 41, 78, 240,
+ 6, 244, 156, 44, 41, 78, 240, 6, 244, 157, 44, 41, 78, 240, 6, 244, 158,
+ 44, 41, 78, 240, 6, 244, 159, 44, 41, 78, 240, 6, 244, 160, 44, 41, 78,
+ 240, 6, 244, 161, 44, 41, 78, 240, 6, 244, 162, 44, 41, 78, 240, 6, 244,
+ 163, 44, 41, 78, 240, 6, 244, 164, 44, 41, 78, 240, 6, 244, 165, 44, 41,
+ 78, 240, 6, 244, 166, 44, 41, 78, 240, 6, 244, 167, 44, 41, 78, 240, 6,
+ 244, 168, 44, 41, 78, 240, 6, 244, 169, 44, 41, 78, 240, 6, 244, 170, 44,
+ 41, 78, 240, 6, 244, 178, 44, 41, 78, 240, 6, 244, 187, 167, 248, 143,
+ 235, 95, 242, 224, 167, 248, 143, 235, 95, 248, 40, 167, 243, 53, 69,
+ 167, 61, 127, 167, 61, 111, 167, 61, 166, 167, 61, 177, 167, 61, 176,
+ 167, 61, 187, 167, 61, 203, 167, 61, 195, 167, 61, 202, 167, 61, 248, 53,
+ 167, 61, 238, 77, 167, 61, 238, 101, 167, 61, 240, 136, 167, 61, 240, 50,
+ 167, 61, 240, 234, 167, 61, 237, 38, 167, 61, 238, 182, 167, 61, 238,
+ 147, 167, 61, 253, 125, 236, 149, 167, 61, 171, 236, 149, 167, 61, 204,
+ 236, 149, 167, 61, 248, 58, 236, 149, 167, 61, 248, 48, 236, 149, 167,
+ 61, 254, 31, 236, 149, 167, 61, 243, 31, 236, 149, 167, 61, 242, 254,
+ 236, 149, 167, 61, 248, 173, 236, 149, 167, 61, 253, 125, 235, 49, 167,
+ 61, 171, 235, 49, 167, 61, 204, 235, 49, 167, 61, 248, 58, 235, 49, 167,
+ 61, 248, 48, 235, 49, 167, 61, 254, 31, 235, 49, 167, 61, 243, 31, 235,
+ 49, 167, 61, 242, 254, 235, 49, 167, 61, 248, 173, 235, 49, 167, 61, 253,
+ 219, 235, 49, 167, 61, 240, 48, 235, 49, 167, 61, 240, 53, 235, 49, 167,
+ 61, 243, 6, 235, 49, 167, 61, 243, 18, 235, 49, 167, 61, 247, 90, 235,
+ 49, 167, 61, 239, 190, 235, 49, 167, 61, 241, 92, 235, 49, 167, 61, 242,
+ 12, 235, 49, 167, 240, 106, 248, 196, 247, 183, 167, 240, 106, 243, 41,
+ 236, 188, 167, 240, 106, 240, 87, 236, 188, 167, 240, 106, 243, 129, 236,
+ 188, 167, 240, 106, 240, 137, 236, 188, 167, 254, 157, 238, 119, 243, 41,
+ 236, 188, 167, 241, 218, 238, 119, 243, 41, 236, 188, 167, 238, 119, 240,
+ 87, 236, 188, 167, 238, 119, 243, 129, 236, 188, 17, 180, 242, 227, 253,
+ 125, 237, 33, 17, 180, 242, 227, 253, 125, 243, 7, 17, 180, 242, 227,
+ 253, 125, 237, 141, 17, 180, 242, 227, 176, 17, 180, 242, 227, 240, 50,
+ 17, 180, 242, 227, 248, 48, 236, 149, 17, 180, 242, 227, 248, 48, 235,
+ 49, 17, 180, 242, 227, 243, 18, 235, 49, 17, 180, 242, 227, 248, 48, 236,
+ 192, 17, 180, 242, 227, 253, 219, 236, 192, 17, 180, 242, 227, 243, 18,
+ 236, 192, 17, 180, 242, 227, 253, 125, 238, 92, 236, 192, 17, 180, 242,
+ 227, 248, 48, 238, 92, 236, 192, 17, 180, 242, 227, 253, 125, 236, 193,
+ 236, 192, 17, 180, 242, 227, 248, 48, 236, 193, 236, 192, 17, 180, 242,
+ 227, 248, 48, 236, 187, 17, 180, 242, 227, 253, 219, 236, 187, 17, 180,
+ 242, 227, 243, 18, 236, 187, 17, 180, 242, 227, 253, 125, 238, 92, 236,
+ 187, 17, 180, 242, 227, 248, 48, 238, 92, 236, 187, 17, 180, 242, 227,
+ 253, 125, 236, 193, 236, 187, 17, 180, 242, 227, 253, 219, 236, 193, 236,
+ 187, 17, 180, 242, 227, 243, 18, 236, 193, 236, 187, 17, 180, 242, 227,
+ 253, 219, 243, 107, 17, 180, 239, 91, 253, 125, 236, 76, 17, 180, 236,
+ 179, 127, 17, 180, 234, 38, 127, 17, 180, 234, 37, 111, 17, 180, 236,
+ 179, 111, 17, 180, 237, 100, 171, 235, 121, 17, 180, 234, 37, 171, 235,
+ 121, 17, 180, 234, 19, 176, 17, 180, 234, 19, 248, 53, 17, 180, 234, 19,
+ 253, 219, 235, 96, 13, 17, 180, 234, 38, 248, 53, 17, 180, 236, 60, 248,
+ 53, 17, 180, 236, 179, 248, 53, 17, 180, 236, 179, 238, 101, 17, 180,
+ 234, 19, 240, 50, 17, 180, 234, 19, 243, 18, 235, 96, 13, 17, 180, 234,
+ 38, 240, 50, 17, 180, 236, 179, 240, 50, 17, 180, 236, 179, 253, 125,
+ 236, 149, 17, 180, 236, 179, 204, 236, 149, 17, 180, 234, 37, 248, 48,
+ 236, 149, 17, 180, 234, 19, 248, 48, 236, 149, 17, 180, 236, 179, 248,
+ 48, 236, 149, 17, 180, 235, 186, 248, 48, 236, 149, 17, 180, 241, 254,
+ 248, 48, 236, 149, 17, 180, 236, 179, 253, 125, 235, 49, 17, 180, 236,
+ 179, 248, 48, 235, 49, 17, 180, 239, 40, 248, 48, 243, 107, 17, 180, 238,
+ 16, 243, 18, 243, 107, 17, 253, 125, 137, 52, 17, 253, 125, 137, 21, 235,
+ 96, 13, 17, 171, 242, 149, 52, 17, 204, 236, 236, 52, 17, 249, 206, 52,
+ 17, 242, 140, 52, 17, 238, 180, 52, 17, 252, 57, 52, 17, 171, 243, 68,
+ 52, 17, 204, 243, 68, 52, 17, 248, 58, 243, 68, 52, 17, 248, 48, 243, 68,
+ 52, 17, 237, 209, 52, 17, 239, 111, 248, 196, 52, 17, 246, 52, 52, 17,
+ 242, 44, 52, 17, 242, 188, 52, 17, 241, 19, 52, 17, 241, 17, 52, 17, 241,
+ 141, 52, 17, 238, 33, 248, 196, 52, 17, 248, 145, 52, 76, 24, 1, 67, 76,
+ 24, 1, 253, 242, 76, 24, 1, 253, 172, 76, 24, 1, 253, 200, 76, 24, 1, 72,
+ 76, 24, 1, 254, 12, 76, 24, 1, 253, 228, 76, 24, 1, 253, 168, 76, 24, 1,
+ 248, 111, 76, 24, 1, 71, 76, 24, 1, 201, 76, 24, 1, 254, 3, 76, 24, 1,
+ 254, 22, 76, 24, 1, 253, 202, 76, 24, 1, 248, 93, 76, 24, 1, 73, 76, 24,
+ 1, 253, 175, 76, 24, 1, 248, 118, 76, 24, 1, 253, 203, 76, 24, 1, 254, 4,
+ 76, 24, 1, 254, 23, 76, 24, 1, 253, 195, 76, 24, 1, 79, 76, 24, 1, 250,
+ 223, 76, 24, 1, 249, 136, 76, 24, 1, 249, 94, 76, 24, 1, 254, 21, 76, 24,
+ 1, 250, 229, 76, 24, 1, 248, 88, 76, 24, 1, 253, 142, 76, 24, 1, 253,
+ 148, 76, 24, 178, 127, 76, 24, 178, 176, 76, 24, 178, 248, 53, 76, 24,
+ 178, 240, 50, 240, 8, 1, 244, 71, 240, 8, 1, 237, 70, 240, 8, 1, 245,
+ 120, 240, 8, 1, 245, 32, 240, 8, 1, 238, 240, 240, 8, 1, 236, 83, 240, 8,
+ 1, 245, 233, 240, 8, 1, 245, 139, 240, 8, 1, 239, 221, 240, 8, 1, 250,
+ 222, 240, 8, 1, 241, 206, 240, 8, 1, 241, 211, 240, 8, 1, 241, 226, 240,
+ 8, 1, 239, 142, 240, 8, 1, 251, 113, 240, 8, 1, 247, 184, 240, 8, 1, 236,
+ 68, 240, 8, 1, 238, 147, 240, 8, 1, 242, 75, 240, 8, 1, 242, 98, 240, 8,
+ 1, 242, 144, 240, 8, 1, 242, 185, 240, 8, 1, 241, 102, 240, 8, 1, 241,
+ 179, 240, 8, 1, 240, 190, 240, 8, 1, 242, 43, 240, 8, 1, 248, 173, 236,
+ 149, 236, 147, 1, 244, 78, 236, 147, 1, 242, 242, 236, 147, 1, 241, 122,
+ 236, 147, 1, 248, 61, 236, 147, 1, 240, 28, 236, 147, 1, 253, 184, 236,
+ 147, 1, 253, 177, 236, 147, 1, 242, 251, 236, 147, 1, 245, 201, 236, 147,
+ 1, 249, 176, 236, 147, 1, 248, 193, 236, 147, 1, 248, 116, 236, 147, 1,
+ 243, 33, 236, 147, 1, 240, 33, 236, 147, 1, 248, 166, 236, 147, 1, 245,
+ 64, 236, 147, 1, 248, 132, 236, 147, 1, 254, 18, 236, 147, 1, 242, 95,
+ 236, 147, 1, 248, 105, 236, 147, 1, 253, 239, 236, 147, 1, 247, 61, 236,
+ 147, 1, 247, 15, 236, 147, 1, 242, 76, 236, 147, 1, 239, 219, 236, 147,
+ 1, 240, 180, 236, 147, 1, 87, 236, 147, 1, 71, 236, 147, 1, 79, 236, 147,
+ 1, 248, 251, 236, 147, 248, 143, 236, 213, 76, 184, 21, 67, 76, 184, 21,
+ 71, 76, 184, 21, 79, 76, 184, 21, 201, 76, 184, 21, 253, 203, 76, 184,
+ 21, 253, 139, 76, 184, 21, 253, 235, 76, 184, 21, 253, 253, 76, 184, 21,
+ 253, 152, 76, 184, 21, 253, 146, 76, 184, 21, 254, 7, 76, 184, 21, 253,
+ 126, 76, 184, 21, 253, 196, 76, 184, 21, 253, 133, 76, 184, 21, 253, 201,
+ 76, 184, 21, 253, 232, 76, 184, 21, 248, 55, 76, 184, 21, 253, 129, 76,
+ 184, 21, 253, 141, 76, 184, 21, 253, 179, 76, 184, 21, 253, 131, 76, 184,
+ 21, 253, 150, 76, 184, 21, 222, 76, 184, 21, 253, 180, 76, 184, 21, 253,
+ 154, 76, 184, 21, 216, 76, 184, 21, 253, 171, 76, 184, 21, 254, 48, 76,
+ 184, 21, 253, 130, 76, 184, 21, 253, 185, 76, 184, 21, 253, 134, 76, 184,
+ 21, 253, 132, 76, 184, 21, 253, 163, 76, 184, 21, 248, 46, 76, 184, 21,
+ 248, 66, 76, 184, 21, 219, 76, 184, 21, 233, 118, 76, 184, 21, 231, 117,
+ 76, 184, 21, 231, 118, 76, 184, 21, 232, 66, 76, 184, 21, 234, 107, 76,
+ 184, 21, 232, 126, 76, 184, 21, 244, 189, 76, 184, 21, 237, 81, 76, 184,
+ 248, 143, 236, 213, 76, 184, 61, 127, 76, 184, 61, 111, 76, 184, 61, 248,
+ 53, 76, 184, 61, 238, 77, 76, 184, 61, 236, 149, 121, 5, 1, 183, 71, 121,
+ 5, 1, 183, 72, 121, 5, 1, 183, 67, 121, 5, 1, 183, 254, 0, 121, 5, 1,
+ 183, 73, 121, 5, 1, 183, 253, 156, 121, 5, 1, 242, 215, 71, 121, 5, 1,
+ 242, 215, 72, 121, 5, 1, 242, 215, 67, 121, 5, 1, 242, 215, 254, 0, 121,
+ 5, 1, 242, 215, 73, 121, 5, 1, 242, 215, 253, 156, 121, 5, 1, 254, 33,
+ 121, 5, 1, 254, 121, 121, 5, 1, 254, 14, 121, 5, 1, 248, 192, 121, 5, 1,
+ 192, 121, 5, 1, 248, 180, 121, 5, 1, 248, 197, 121, 5, 1, 248, 255, 121,
+ 5, 1, 248, 149, 121, 5, 1, 243, 54, 121, 5, 1, 248, 161, 121, 5, 1, 249,
+ 92, 121, 5, 1, 249, 67, 121, 5, 1, 254, 21, 121, 5, 1, 249, 10, 121, 5,
+ 1, 248, 109, 121, 5, 1, 243, 77, 121, 5, 1, 254, 23, 121, 5, 1, 248, 194,
+ 121, 5, 1, 248, 93, 121, 5, 1, 243, 139, 121, 5, 1, 254, 4, 121, 5, 1,
+ 254, 3, 121, 5, 1, 254, 22, 121, 5, 1, 253, 202, 121, 5, 1, 248, 108,
+ 121, 5, 1, 254, 42, 121, 5, 1, 254, 91, 121, 3, 1, 183, 71, 121, 3, 1,
+ 183, 72, 121, 3, 1, 183, 67, 121, 3, 1, 183, 254, 0, 121, 3, 1, 183, 73,
+ 121, 3, 1, 183, 253, 156, 121, 3, 1, 242, 215, 71, 121, 3, 1, 242, 215,
+ 72, 121, 3, 1, 242, 215, 67, 121, 3, 1, 242, 215, 254, 0, 121, 3, 1, 242,
+ 215, 73, 121, 3, 1, 242, 215, 253, 156, 121, 3, 1, 254, 33, 121, 3, 1,
+ 254, 121, 121, 3, 1, 254, 14, 121, 3, 1, 248, 192, 121, 3, 1, 192, 121,
+ 3, 1, 248, 180, 121, 3, 1, 248, 197, 121, 3, 1, 248, 255, 121, 3, 1, 248,
+ 149, 121, 3, 1, 243, 54, 121, 3, 1, 248, 161, 121, 3, 1, 249, 92, 121, 3,
+ 1, 249, 67, 121, 3, 1, 254, 21, 121, 3, 1, 249, 10, 121, 3, 1, 248, 109,
+ 121, 3, 1, 243, 77, 121, 3, 1, 254, 23, 121, 3, 1, 248, 194, 121, 3, 1,
+ 248, 93, 121, 3, 1, 243, 139, 121, 3, 1, 254, 4, 121, 3, 1, 254, 3, 121,
+ 3, 1, 254, 22, 121, 3, 1, 253, 202, 121, 3, 1, 248, 108, 121, 3, 1, 254,
+ 42, 121, 3, 1, 254, 91, 207, 1, 246, 240, 207, 1, 249, 184, 207, 1, 246,
+ 13, 207, 1, 249, 61, 207, 1, 242, 147, 207, 1, 253, 186, 207, 1, 247,
+ 127, 207, 1, 239, 25, 207, 1, 253, 77, 207, 1, 245, 204, 207, 1, 250,
+ 121, 207, 1, 245, 58, 207, 1, 251, 6, 207, 1, 253, 19, 207, 1, 247, 144,
+ 207, 1, 253, 110, 207, 1, 237, 23, 207, 1, 241, 189, 207, 1, 253, 35,
+ 207, 1, 241, 144, 207, 1, 246, 53, 207, 1, 246, 86, 207, 1, 254, 174,
+ 207, 1, 250, 221, 207, 1, 249, 241, 207, 1, 249, 234, 207, 1, 254, 9,
+ 207, 1, 244, 53, 207, 1, 248, 235, 207, 1, 254, 0, 207, 1, 247, 33, 207,
+ 1, 248, 132, 207, 1, 248, 207, 207, 1, 249, 235, 207, 1, 249, 84, 207, 1,
+ 253, 176, 207, 1, 252, 55, 207, 1, 246, 234, 207, 1, 249, 127, 207, 1,
+ 249, 244, 207, 1, 249, 240, 207, 1, 253, 227, 207, 1, 249, 236, 207, 1,
+ 250, 228, 207, 1, 241, 18, 207, 1, 248, 206, 207, 1, 251, 100, 207, 1,
+ 253, 78, 238, 50, 1, 243, 3, 238, 50, 1, 253, 141, 238, 50, 1, 253, 126,
+ 238, 50, 1, 253, 146, 238, 50, 1, 253, 253, 238, 50, 1, 248, 61, 238, 50,
+ 1, 245, 60, 238, 50, 1, 253, 130, 238, 50, 1, 253, 132, 238, 50, 1, 242,
+ 106, 238, 50, 1, 248, 76, 238, 50, 1, 244, 244, 238, 50, 1, 253, 139,
+ 238, 50, 1, 253, 179, 238, 50, 1, 247, 4, 238, 50, 1, 246, 3, 238, 50, 1,
+ 246, 34, 238, 50, 1, 246, 84, 238, 50, 1, 246, 197, 238, 50, 1, 248, 142,
+ 238, 50, 1, 219, 238, 50, 1, 216, 238, 50, 1, 67, 238, 50, 1, 72, 238,
+ 50, 1, 71, 238, 50, 1, 73, 238, 50, 1, 79, 238, 50, 1, 253, 140, 238, 50,
+ 1, 253, 164, 238, 50, 1, 253, 156, 238, 50, 26, 242, 217, 238, 50, 26,
+ 127, 238, 50, 26, 111, 238, 50, 26, 166, 238, 50, 26, 177, 238, 50, 26,
+ 176, 238, 50, 26, 187, 238, 50, 26, 203, 238, 50, 26, 195, 238, 50, 26,
+ 202, 172, 4, 67, 172, 4, 72, 172, 4, 71, 172, 4, 73, 172, 4, 79, 172, 4,
+ 253, 146, 172, 4, 253, 248, 172, 4, 201, 172, 4, 253, 172, 172, 4, 253,
+ 215, 172, 4, 253, 190, 172, 4, 253, 203, 172, 4, 253, 134, 172, 4, 253,
+ 250, 172, 4, 253, 251, 172, 4, 253, 216, 172, 4, 254, 8, 172, 4, 222,
+ 172, 4, 253, 206, 172, 4, 253, 180, 172, 4, 253, 181, 172, 4, 253, 154,
+ 172, 4, 253, 131, 172, 4, 253, 197, 172, 4, 253, 166, 172, 4, 253, 173,
+ 172, 4, 253, 150, 172, 4, 253, 129, 172, 4, 253, 175, 172, 4, 253, 147,
+ 172, 4, 253, 208, 172, 4, 253, 239, 172, 4, 253, 130, 172, 4, 253, 194,
+ 172, 4, 253, 209, 172, 4, 253, 160, 172, 4, 253, 185, 172, 4, 253, 132,
+ 172, 4, 253, 210, 172, 4, 253, 198, 172, 4, 253, 186, 172, 4, 253, 211,
+ 172, 4, 253, 126, 172, 4, 253, 195, 172, 4, 253, 212, 172, 4, 87, 172, 4,
+ 253, 196, 172, 4, 253, 138, 172, 4, 253, 170, 172, 4, 253, 187, 172, 4,
+ 253, 177, 172, 4, 253, 253, 172, 4, 254, 132, 172, 4, 253, 163, 172, 4,
+ 253, 222, 151, 1, 67, 151, 33, 21, 71, 151, 33, 21, 79, 151, 33, 21, 165,
+ 144, 151, 33, 21, 72, 151, 33, 21, 73, 151, 33, 240, 51, 69, 151, 21, 45,
+ 248, 51, 46, 151, 21, 235, 61, 151, 21, 236, 173, 151, 1, 201, 151, 1,
+ 248, 61, 151, 1, 253, 139, 151, 1, 248, 77, 151, 1, 253, 152, 151, 1,
+ 248, 57, 151, 1, 253, 146, 151, 1, 248, 78, 151, 1, 248, 71, 151, 1, 242,
+ 247, 151, 1, 248, 75, 151, 1, 242, 249, 151, 1, 248, 82, 151, 1, 253,
+ 126, 151, 1, 248, 55, 151, 1, 253, 133, 151, 1, 248, 76, 151, 1, 253,
+ 131, 151, 1, 253, 129, 151, 1, 248, 65, 151, 1, 253, 141, 151, 1, 248,
+ 81, 151, 1, 222, 151, 1, 216, 151, 1, 253, 130, 151, 1, 253, 134, 151, 1,
+ 253, 171, 151, 1, 248, 46, 151, 1, 248, 66, 151, 1, 253, 132, 151, 1,
+ 253, 163, 151, 1, 219, 151, 1, 249, 97, 151, 1, 242, 161, 151, 21, 253,
+ 144, 48, 151, 21, 241, 44, 151, 21, 53, 46, 151, 238, 72, 151, 26, 127,
+ 151, 26, 111, 151, 26, 166, 151, 26, 177, 151, 61, 248, 53, 151, 61, 238,
+ 77, 151, 61, 253, 125, 236, 149, 151, 61, 253, 125, 235, 49, 151, 233,
+ 51, 248, 40, 151, 233, 51, 3, 238, 51, 151, 233, 51, 238, 51, 151, 233,
+ 51, 237, 95, 125, 151, 233, 51, 236, 57, 151, 233, 51, 241, 220, 151,
+ 233, 51, 240, 111, 151, 233, 51, 45, 240, 111, 151, 233, 51, 241, 217,
+ 37, 20, 12, 240, 29, 37, 20, 12, 239, 37, 37, 20, 12, 232, 71, 37, 20,
+ 12, 243, 112, 232, 83, 37, 20, 12, 243, 112, 240, 73, 37, 20, 12, 240,
+ 152, 232, 83, 37, 20, 12, 240, 152, 240, 73, 37, 20, 12, 236, 44, 37, 20,
+ 12, 235, 30, 37, 20, 12, 232, 191, 37, 20, 12, 235, 43, 37, 20, 12, 236,
+ 142, 240, 73, 37, 20, 12, 236, 48, 37, 20, 12, 243, 142, 232, 83, 37, 20,
+ 12, 254, 92, 232, 83, 37, 20, 12, 238, 223, 37, 20, 12, 234, 213, 37, 20,
+ 12, 233, 116, 37, 20, 12, 234, 45, 240, 73, 37, 20, 12, 238, 20, 37, 20,
+ 12, 242, 150, 37, 20, 12, 240, 205, 235, 55, 37, 20, 12, 240, 98, 235,
+ 55, 37, 20, 12, 239, 168, 37, 20, 12, 235, 187, 37, 20, 12, 242, 175, 37,
+ 20, 12, 249, 85, 235, 55, 37, 20, 12, 238, 118, 235, 55, 37, 20, 12, 235,
+ 90, 235, 55, 37, 20, 12, 236, 96, 37, 20, 12, 236, 71, 37, 20, 12, 239,
+ 203, 235, 164, 37, 20, 12, 242, 45, 235, 55, 37, 20, 12, 239, 239, 235,
+ 55, 37, 20, 12, 236, 246, 235, 55, 37, 20, 12, 235, 165, 37, 20, 12, 238,
+ 195, 37, 20, 12, 242, 82, 37, 20, 12, 240, 207, 235, 55, 37, 20, 12, 238,
+ 29, 37, 20, 12, 231, 116, 37, 20, 12, 239, 188, 37, 20, 12, 238, 153,
+ 235, 55, 37, 20, 12, 238, 153, 251, 225, 238, 15, 37, 20, 12, 235, 132,
+ 235, 55, 37, 20, 12, 242, 146, 37, 20, 12, 241, 214, 37, 20, 12, 250,
+ 217, 37, 20, 12, 247, 158, 37, 20, 12, 238, 25, 37, 20, 12, 234, 215, 37,
+ 20, 12, 243, 142, 254, 92, 248, 64, 37, 20, 12, 240, 18, 235, 55, 37, 20,
+ 12, 234, 203, 37, 20, 12, 236, 242, 235, 55, 37, 20, 12, 241, 194, 236,
+ 132, 37, 20, 12, 236, 73, 37, 20, 12, 234, 241, 37, 20, 12, 236, 46, 37,
+ 20, 12, 236, 253, 235, 55, 37, 20, 12, 237, 246, 37, 20, 12, 233, 92,
+ 235, 55, 37, 20, 12, 233, 93, 235, 55, 37, 20, 12, 237, 177, 37, 20, 12,
+ 243, 231, 37, 20, 12, 237, 234, 37, 20, 12, 237, 190, 243, 84, 37, 20,
+ 12, 236, 242, 243, 84, 37, 20, 12, 232, 59, 37, 20, 12, 231, 139, 37, 20,
+ 12, 249, 85, 248, 64, 37, 20, 12, 240, 205, 248, 64, 37, 20, 12, 243,
+ 112, 248, 64, 37, 20, 12, 237, 235, 37, 20, 12, 236, 47, 37, 20, 12, 229,
+ 51, 37, 20, 12, 229, 47, 37, 20, 12, 237, 233, 248, 64, 37, 20, 12, 235,
+ 90, 253, 238, 248, 106, 37, 20, 12, 238, 118, 253, 238, 248, 106, 37, 20,
+ 12, 239, 252, 37, 20, 12, 234, 45, 248, 64, 37, 20, 12, 234, 44, 236,
+ 126, 248, 64, 37, 20, 12, 238, 49, 37, 20, 12, 229, 48, 37, 20, 12, 237,
+ 148, 37, 20, 12, 237, 86, 37, 20, 12, 241, 243, 245, 231, 37, 20, 12,
+ 240, 152, 248, 64, 37, 20, 12, 240, 207, 248, 64, 37, 20, 12, 236, 82,
+ 248, 64, 37, 20, 12, 239, 151, 37, 20, 12, 233, 114, 37, 20, 12, 237,
+ 196, 37, 20, 12, 233, 93, 248, 64, 37, 20, 12, 233, 92, 248, 64, 37, 20,
+ 12, 240, 172, 232, 190, 37, 20, 12, 237, 193, 37, 20, 12, 227, 12, 37,
+ 20, 12, 236, 242, 248, 64, 37, 20, 12, 233, 194, 37, 20, 12, 238, 153,
+ 248, 64, 37, 20, 12, 242, 138, 37, 20, 12, 236, 253, 248, 64, 37, 20, 12,
+ 236, 13, 37, 20, 12, 242, 100, 248, 64, 37, 20, 12, 247, 204, 238, 195,
+ 37, 20, 12, 227, 8, 37, 20, 12, 229, 53, 37, 20, 12, 231, 32, 37, 20, 12,
+ 226, 242, 37, 20, 12, 226, 233, 37, 20, 12, 231, 33, 37, 20, 12, 229, 54,
+ 37, 20, 12, 229, 66, 37, 20, 12, 231, 44, 37, 20, 12, 240, 172, 231, 44,
+ 37, 20, 12, 235, 132, 248, 64, 37, 20, 12, 233, 109, 250, 230, 37, 20,
+ 12, 233, 109, 250, 232, 37, 20, 12, 247, 143, 238, 161, 37, 20, 12, 252,
+ 218, 254, 65, 237, 63, 37, 20, 12, 234, 211, 37, 20, 12, 234, 186, 37,
+ 20, 12, 249, 208, 243, 20, 37, 20, 12, 249, 208, 248, 106, 37, 20, 12,
+ 238, 14, 37, 20, 12, 240, 194, 248, 106, 37, 20, 12, 245, 67, 235, 55,
+ 37, 20, 12, 238, 142, 235, 55, 37, 20, 12, 238, 142, 243, 84, 37, 20, 12,
+ 238, 142, 248, 64, 37, 20, 12, 236, 246, 248, 64, 37, 20, 12, 244, 83,
+ 37, 20, 12, 240, 73, 37, 20, 12, 239, 228, 37, 20, 12, 236, 128, 37, 20,
+ 12, 236, 229, 37, 20, 12, 240, 100, 250, 225, 236, 254, 37, 20, 12, 240,
+ 100, 254, 57, 236, 221, 37, 20, 12, 240, 100, 247, 159, 236, 221, 37, 20,
+ 12, 240, 100, 238, 24, 236, 221, 37, 20, 12, 240, 100, 239, 97, 236, 254,
+ 37, 20, 12, 240, 98, 253, 238, 248, 106, 37, 20, 12, 240, 98, 231, 92,
+ 235, 171, 37, 20, 12, 240, 98, 231, 92, 240, 168, 37, 20, 12, 235, 204,
+ 37, 20, 12, 236, 223, 231, 92, 236, 247, 243, 20, 37, 20, 12, 236, 223,
+ 231, 92, 236, 247, 248, 106, 37, 20, 12, 236, 223, 231, 92, 240, 168, 37,
+ 20, 12, 235, 37, 37, 20, 12, 241, 14, 37, 20, 12, 233, 209, 37, 20, 12,
+ 237, 106, 37, 20, 12, 243, 13, 249, 139, 243, 143, 37, 20, 12, 243, 13,
+ 235, 170, 37, 20, 12, 243, 13, 243, 143, 37, 20, 12, 243, 13, 239, 135,
+ 37, 20, 12, 243, 13, 246, 66, 37, 20, 12, 243, 13, 240, 184, 37, 20, 12,
+ 243, 13, 234, 196, 37, 20, 12, 243, 13, 249, 139, 240, 184, 37, 20, 12,
+ 236, 162, 240, 211, 240, 35, 37, 20, 12, 236, 162, 249, 27, 240, 211,
+ 240, 35, 37, 20, 12, 236, 162, 237, 5, 240, 35, 37, 20, 12, 236, 162,
+ 249, 27, 237, 5, 240, 35, 37, 20, 12, 236, 162, 242, 157, 240, 35, 37,
+ 20, 12, 236, 162, 235, 36, 37, 20, 12, 236, 162, 236, 241, 240, 35, 37,
+ 20, 12, 236, 162, 236, 241, 238, 198, 240, 35, 37, 20, 12, 236, 162, 238,
+ 198, 240, 35, 37, 20, 12, 236, 162, 238, 209, 240, 35, 37, 20, 12, 241,
+ 181, 240, 243, 234, 58, 37, 20, 12, 234, 44, 240, 243, 234, 58, 37, 20,
+ 12, 235, 99, 233, 40, 37, 20, 12, 235, 99, 233, 87, 37, 20, 12, 235, 99,
+ 235, 119, 37, 20, 12, 236, 162, 247, 185, 240, 35, 37, 20, 12, 236, 162,
+ 234, 240, 240, 35, 37, 20, 12, 236, 162, 238, 209, 236, 241, 240, 35, 37,
+ 20, 12, 234, 57, 255, 98, 238, 161, 37, 20, 12, 234, 57, 255, 98, 237,
+ 110, 37, 20, 12, 239, 56, 254, 65, 240, 18, 249, 196, 37, 20, 12, 236,
+ 38, 37, 20, 12, 233, 210, 37, 20, 12, 240, 18, 237, 66, 237, 103, 241,
+ 178, 37, 20, 12, 240, 18, 235, 72, 253, 129, 37, 20, 12, 240, 18, 235,
+ 72, 243, 231, 37, 20, 12, 240, 18, 251, 254, 240, 35, 37, 20, 12, 240,
+ 18, 235, 72, 253, 201, 37, 20, 12, 240, 18, 238, 150, 237, 107, 253, 201,
+ 37, 20, 12, 240, 18, 235, 72, 253, 172, 37, 20, 12, 240, 18, 235, 72,
+ 253, 222, 37, 20, 12, 240, 18, 235, 72, 255, 62, 243, 20, 37, 20, 12,
+ 240, 18, 235, 72, 255, 62, 248, 106, 37, 20, 12, 240, 18, 238, 199, 240,
+ 110, 235, 119, 37, 20, 12, 240, 18, 238, 199, 240, 110, 233, 87, 37, 20,
+ 12, 241, 105, 238, 150, 240, 110, 242, 174, 37, 20, 12, 240, 18, 238,
+ 150, 240, 110, 239, 212, 37, 20, 12, 240, 18, 239, 143, 37, 20, 12, 243,
+ 89, 242, 209, 37, 20, 12, 243, 89, 239, 109, 37, 20, 12, 243, 89, 239,
+ 200, 37, 20, 12, 240, 18, 220, 240, 90, 231, 55, 37, 20, 12, 240, 18,
+ 234, 184, 234, 91, 37, 20, 12, 240, 90, 232, 110, 37, 20, 12, 240, 72,
+ 232, 110, 37, 20, 12, 240, 72, 231, 55, 37, 20, 12, 240, 72, 248, 146,
+ 254, 57, 235, 68, 37, 20, 12, 240, 72, 233, 88, 238, 225, 235, 68, 37,
+ 20, 12, 240, 72, 235, 120, 255, 56, 235, 68, 37, 20, 12, 240, 72, 234,
+ 86, 249, 128, 235, 68, 37, 20, 12, 240, 90, 248, 146, 254, 57, 235, 68,
+ 37, 20, 12, 240, 90, 233, 88, 238, 225, 235, 68, 37, 20, 12, 240, 90,
+ 235, 120, 255, 56, 235, 68, 37, 20, 12, 240, 90, 234, 86, 249, 128, 235,
+ 68, 37, 20, 12, 240, 179, 239, 43, 37, 20, 12, 240, 179, 239, 250, 37,
+ 20, 12, 236, 212, 248, 146, 241, 242, 37, 20, 12, 236, 212, 248, 146,
+ 239, 133, 37, 20, 12, 236, 212, 240, 73, 37, 20, 12, 236, 212, 237, 47,
+ 37, 20, 12, 236, 186, 237, 47, 37, 20, 12, 236, 186, 238, 155, 237, 7,
+ 37, 20, 12, 236, 186, 238, 155, 235, 154, 37, 20, 12, 236, 186, 238, 155,
+ 233, 108, 37, 20, 12, 236, 186, 238, 250, 37, 20, 12, 236, 186, 240, 128,
+ 237, 7, 37, 20, 12, 236, 186, 240, 128, 235, 154, 37, 20, 12, 236, 186,
+ 240, 128, 233, 108, 37, 20, 12, 237, 108, 254, 167, 37, 20, 12, 235, 203,
+ 254, 10, 37, 20, 12, 238, 152, 37, 20, 12, 238, 90, 253, 129, 37, 20, 12,
+ 238, 90, 249, 196, 37, 20, 12, 238, 90, 253, 139, 37, 20, 12, 238, 90,
+ 253, 201, 37, 20, 12, 238, 90, 253, 172, 37, 20, 12, 238, 90, 253, 222,
+ 37, 20, 12, 238, 90, 253, 166, 37, 20, 12, 235, 90, 253, 238, 243, 225,
+ 37, 20, 12, 238, 118, 253, 238, 243, 225, 37, 20, 12, 235, 90, 253, 238,
+ 243, 20, 37, 20, 12, 238, 118, 253, 238, 243, 20, 37, 20, 12, 240, 194,
+ 243, 20, 37, 20, 12, 240, 98, 253, 238, 243, 20, 20, 12, 240, 12, 236,
+ 194, 20, 12, 45, 236, 194, 20, 12, 30, 236, 194, 20, 12, 238, 75, 30,
+ 236, 194, 20, 12, 240, 55, 236, 194, 20, 12, 242, 215, 236, 194, 20, 12,
+ 40, 240, 64, 52, 20, 12, 38, 240, 64, 52, 20, 12, 240, 64, 243, 5, 20,
+ 12, 253, 199, 240, 219, 20, 12, 255, 70, 244, 242, 20, 12, 240, 219, 20,
+ 12, 245, 25, 20, 12, 236, 237, 236, 21, 20, 12, 236, 237, 236, 22, 20,
+ 12, 236, 237, 236, 23, 20, 12, 237, 10, 20, 12, 239, 69, 46, 20, 12, 241,
+ 37, 69, 20, 12, 237, 82, 20, 12, 241, 35, 20, 12, 104, 20, 12, 237, 225,
+ 240, 89, 20, 12, 238, 35, 240, 89, 20, 12, 235, 34, 240, 89, 20, 12, 236,
+ 25, 240, 89, 20, 12, 236, 24, 240, 89, 20, 12, 238, 8, 240, 89, 20, 12,
+ 235, 2, 234, 55, 20, 12, 233, 204, 234, 55, 20, 12, 255, 104, 243, 37,
+ 20, 12, 255, 104, 248, 148, 240, 82, 243, 51, 20, 12, 255, 104, 248, 148,
+ 240, 82, 240, 108, 20, 12, 255, 105, 243, 37, 20, 12, 255, 112, 243, 37,
+ 20, 12, 255, 112, 248, 148, 240, 82, 243, 51, 20, 12, 255, 112, 248, 148,
+ 240, 82, 240, 108, 20, 12, 249, 57, 239, 26, 20, 12, 249, 57, 239, 27,
+ 20, 12, 45, 240, 223, 20, 12, 45, 243, 174, 20, 12, 248, 209, 253, 176,
+ 20, 12, 248, 209, 242, 236, 20, 12, 238, 146, 253, 176, 20, 12, 238, 146,
+ 242, 236, 20, 12, 243, 74, 253, 176, 20, 12, 243, 74, 242, 236, 20, 12,
+ 238, 80, 188, 240, 223, 20, 12, 238, 80, 188, 243, 174, 20, 12, 241, 66,
+ 244, 31, 20, 12, 254, 153, 244, 31, 20, 12, 240, 82, 243, 51, 20, 12,
+ 240, 82, 240, 108, 20, 12, 232, 107, 243, 51, 20, 12, 232, 107, 240, 108,
+ 20, 12, 246, 95, 242, 239, 20, 12, 244, 51, 242, 239, 20, 12, 137, 242,
+ 239, 20, 12, 238, 80, 242, 239, 20, 12, 240, 62, 242, 239, 20, 12, 235,
+ 108, 242, 239, 20, 12, 231, 112, 242, 239, 20, 12, 232, 109, 242, 239,
+ 20, 12, 253, 125, 238, 92, 231, 113, 242, 239, 20, 12, 255, 113, 235, 78,
+ 20, 12, 248, 49, 235, 78, 20, 12, 218, 255, 113, 235, 78, 20, 12, 31,
+ 236, 153, 240, 39, 20, 12, 31, 236, 153, 240, 0, 20, 12, 236, 152, 236,
+ 153, 88, 240, 39, 20, 12, 236, 152, 236, 153, 88, 240, 0, 20, 12, 236,
+ 152, 236, 153, 40, 240, 39, 20, 12, 236, 152, 236, 153, 40, 240, 0, 20,
+ 12, 236, 152, 236, 153, 38, 240, 39, 20, 12, 236, 152, 236, 153, 38, 240,
+ 0, 20, 12, 236, 152, 236, 153, 92, 240, 39, 20, 12, 236, 152, 236, 153,
+ 92, 240, 0, 20, 12, 236, 152, 236, 153, 88, 38, 240, 39, 20, 12, 236,
+ 152, 236, 153, 88, 38, 240, 0, 20, 12, 249, 113, 236, 153, 240, 39, 20,
+ 12, 249, 113, 236, 153, 240, 0, 20, 12, 231, 57, 236, 153, 92, 240, 39,
+ 20, 12, 231, 57, 236, 153, 92, 240, 0, 20, 12, 233, 56, 235, 78, 20, 12,
+ 253, 16, 235, 78, 20, 12, 236, 153, 240, 0, 20, 12, 252, 40, 235, 78, 20,
+ 12, 238, 172, 236, 153, 240, 39, 20, 12, 238, 172, 236, 153, 240, 0, 20,
+ 12, 239, 255, 20, 12, 244, 51, 243, 9, 20, 12, 137, 243, 9, 20, 12, 238,
+ 80, 243, 9, 20, 12, 240, 62, 243, 9, 20, 12, 235, 108, 243, 9, 20, 12,
+ 231, 112, 243, 9, 20, 12, 232, 109, 243, 9, 20, 12, 253, 125, 238, 92,
+ 231, 113, 243, 9, 20, 12, 50, 243, 46, 20, 12, 50, 233, 38, 243, 46, 20,
+ 12, 50, 234, 83, 20, 12, 50, 234, 84, 20, 12, 50, 234, 85, 20, 12, 236,
+ 225, 234, 83, 20, 12, 236, 225, 234, 84, 20, 12, 236, 225, 234, 85, 20,
+ 12, 50, 232, 117, 248, 40, 20, 12, 50, 239, 71, 20, 12, 50, 239, 72, 20,
+ 12, 50, 239, 73, 20, 12, 50, 239, 74, 20, 12, 50, 239, 75, 20, 12, 243,
+ 24, 243, 146, 20, 12, 253, 165, 243, 146, 20, 12, 243, 24, 248, 139, 20,
+ 12, 253, 165, 248, 139, 20, 12, 243, 24, 244, 19, 20, 12, 253, 165, 244,
+ 19, 20, 12, 243, 24, 238, 207, 20, 12, 253, 165, 238, 207, 20, 12, 50,
+ 238, 54, 20, 12, 50, 236, 105, 20, 12, 50, 239, 216, 20, 12, 50, 231, 81,
+ 20, 12, 50, 237, 201, 20, 12, 50, 227, 2, 20, 12, 50, 227, 11, 20, 12,
+ 50, 241, 221, 20, 12, 234, 46, 253, 176, 20, 12, 234, 46, 242, 236, 20,
+ 12, 50, 245, 71, 20, 12, 50, 252, 138, 20, 12, 50, 245, 90, 20, 12, 50,
+ 242, 117, 20, 12, 50, 244, 217, 20, 12, 50, 45, 238, 156, 20, 12, 50,
+ 240, 3, 238, 156, 20, 12, 232, 201, 20, 12, 239, 208, 20, 12, 255, 17,
+ 20, 12, 242, 61, 20, 12, 241, 237, 20, 12, 241, 115, 20, 12, 234, 106,
+ 20, 12, 232, 127, 20, 12, 243, 186, 249, 122, 240, 37, 20, 12, 243, 186,
+ 249, 122, 255, 51, 240, 37, 20, 12, 254, 250, 20, 12, 244, 41, 20, 12,
+ 236, 145, 244, 41, 20, 12, 249, 188, 240, 37, 20, 12, 249, 188, 253, 176,
+ 20, 12, 236, 172, 236, 111, 20, 12, 236, 172, 236, 112, 20, 12, 236, 172,
+ 236, 113, 20, 12, 236, 172, 236, 114, 20, 12, 236, 172, 236, 115, 20, 12,
+ 236, 172, 236, 116, 20, 12, 236, 172, 236, 117, 20, 12, 236, 172, 236,
+ 118, 20, 12, 236, 172, 236, 119, 20, 12, 236, 172, 235, 3, 20, 12, 236,
+ 172, 235, 4, 20, 12, 232, 168, 20, 12, 232, 186, 20, 12, 253, 165, 147,
+ 239, 204, 20, 12, 240, 112, 240, 37, 20, 12, 50, 92, 248, 198, 20, 12,
+ 50, 88, 248, 198, 20, 12, 50, 236, 34, 20, 12, 50, 252, 182, 234, 235,
+ 20, 12, 243, 114, 69, 20, 12, 243, 114, 88, 69, 20, 12, 137, 243, 114,
+ 69, 20, 12, 235, 125, 253, 176, 20, 12, 235, 125, 242, 236, 20, 12, 2,
+ 232, 165, 20, 12, 245, 34, 20, 12, 250, 181, 249, 26, 20, 12, 239, 131,
+ 20, 12, 241, 219, 20, 12, 239, 13, 20, 12, 234, 40, 240, 39, 20, 12, 234,
+ 40, 240, 0, 20, 12, 239, 138, 20, 12, 240, 200, 240, 0, 20, 12, 234, 41,
+ 240, 39, 20, 12, 234, 41, 240, 0, 20, 12, 249, 65, 240, 39, 20, 12, 249,
+ 65, 240, 0, 20, 12, 243, 217, 237, 29, 242, 239, 20, 12, 243, 217, 234,
+ 29, 242, 239, 20, 12, 241, 38, 242, 239, 20, 12, 234, 40, 242, 239, 20,
+ 12, 240, 200, 242, 239, 20, 12, 234, 41, 242, 239, 20, 12, 240, 65, 235,
+ 106, 253, 231, 234, 13, 235, 134, 20, 12, 240, 65, 235, 106, 253, 231,
+ 234, 13, 233, 85, 20, 12, 240, 65, 235, 106, 253, 231, 234, 13, 237, 29,
+ 231, 102, 20, 12, 240, 65, 233, 62, 253, 231, 234, 13, 235, 134, 20, 12,
+ 240, 65, 233, 62, 253, 231, 234, 13, 233, 85, 20, 12, 240, 65, 233, 62,
+ 253, 231, 234, 13, 234, 29, 231, 102, 20, 12, 240, 65, 233, 62, 253, 231,
+ 234, 13, 234, 29, 231, 126, 20, 12, 240, 65, 233, 62, 253, 231, 234, 13,
+ 234, 29, 231, 127, 20, 12, 241, 69, 20, 12, 235, 126, 255, 105, 243, 37,
+ 20, 12, 235, 126, 255, 112, 243, 37, 20, 12, 31, 217, 20, 12, 242, 178,
+ 20, 12, 237, 238, 20, 12, 239, 28, 20, 12, 234, 251, 20, 12, 235, 190,
+ 20, 12, 236, 129, 20, 12, 234, 237, 20, 12, 236, 77, 238, 185, 20, 12,
+ 236, 97, 238, 185, 20, 12, 238, 31, 234, 249, 20, 12, 254, 223, 233, 248,
+ 17, 242, 222, 126, 235, 146, 17, 242, 222, 126, 235, 147, 17, 242, 222,
+ 126, 236, 122, 17, 242, 222, 126, 235, 148, 17, 242, 222, 126, 235, 149,
+ 17, 242, 222, 126, 236, 123, 17, 242, 222, 126, 235, 150, 17, 242, 222,
+ 126, 235, 151, 17, 242, 222, 126, 236, 124, 17, 242, 222, 126, 235, 7,
+ 17, 242, 222, 126, 234, 67, 17, 242, 222, 126, 234, 68, 17, 242, 222,
+ 126, 234, 69, 17, 242, 222, 126, 234, 70, 17, 242, 222, 126, 235, 8, 17,
+ 242, 222, 126, 235, 9, 17, 242, 222, 126, 234, 71, 17, 242, 222, 126,
+ 234, 72, 17, 242, 222, 126, 234, 73, 17, 242, 222, 126, 235, 10, 17, 242,
+ 222, 126, 235, 11, 17, 242, 222, 126, 235, 12, 17, 242, 222, 126, 234,
+ 74, 17, 242, 222, 126, 234, 75, 17, 242, 222, 126, 234, 76, 17, 242, 222,
+ 126, 234, 77, 17, 242, 222, 126, 234, 78, 17, 242, 222, 126, 234, 79, 17,
+ 242, 222, 126, 234, 80, 17, 232, 69, 126, 235, 146, 17, 232, 69, 126,
+ 235, 147, 17, 232, 69, 126, 235, 148, 17, 232, 69, 126, 235, 149, 17,
+ 232, 69, 126, 235, 150, 17, 232, 69, 126, 235, 151, 17, 232, 69, 126,
+ 234, 67, 17, 232, 69, 126, 234, 68, 17, 232, 69, 126, 234, 69, 17, 232,
+ 69, 126, 234, 70, 17, 232, 69, 126, 234, 71, 17, 232, 69, 126, 234, 72,
+ 17, 232, 69, 126, 234, 73, 17, 232, 69, 126, 234, 74, 17, 232, 69, 126,
+ 234, 75, 17, 232, 69, 126, 235, 13, 17, 232, 69, 126, 235, 14, 17, 232,
+ 69, 126, 235, 15, 17, 232, 69, 126, 235, 16, 17, 232, 69, 126, 235, 17,
+ 17, 232, 69, 126, 235, 18, 17, 232, 69, 126, 235, 19, 17, 232, 69, 126,
+ 235, 20, 17, 232, 69, 126, 235, 21, 17, 232, 69, 126, 235, 22, 17, 232,
+ 69, 126, 235, 23, 17, 232, 69, 126, 235, 24, 17, 232, 69, 126, 235, 25,
+ 17, 232, 69, 126, 235, 26, 17, 232, 69, 126, 235, 27, 17, 232, 69, 126,
+ 235, 28, 17, 232, 69, 126, 235, 29, 17, 232, 69, 126, 234, 76, 17, 232,
+ 69, 126, 234, 77, 17, 232, 69, 126, 234, 78, 17, 232, 69, 126, 234, 79,
+ 17, 232, 69, 126, 234, 80, 50, 17, 20, 237, 49, 50, 17, 20, 234, 82, 50,
+ 17, 20, 234, 62, 17, 20, 239, 116, 236, 184, 28, 240, 49, 240, 56, 28,
+ 237, 174, 240, 49, 240, 56, 28, 245, 203, 240, 49, 240, 56, 28, 238, 181,
+ 238, 139, 240, 56, 28, 238, 181, 241, 169, 240, 56, 28, 240, 49, 120, 28,
+ 238, 129, 120, 28, 248, 37, 238, 51, 120, 28, 241, 244, 120, 28, 237, 72,
+ 120, 28, 238, 193, 240, 147, 120, 28, 232, 122, 120, 28, 238, 252, 120,
+ 28, 233, 73, 120, 28, 235, 182, 248, 235, 120, 28, 231, 123, 128, 233,
+ 136, 120, 28, 233, 137, 120, 28, 232, 67, 120, 28, 235, 127, 120, 28,
+ 232, 192, 120, 28, 240, 215, 120, 28, 237, 91, 120, 28, 238, 189, 244,
+ 188, 120, 28, 237, 51, 120, 28, 234, 54, 120, 28, 237, 55, 120, 28, 237,
+ 250, 120, 28, 233, 229, 120, 28, 245, 79, 120, 28, 251, 125, 120, 28,
+ 233, 127, 120, 28, 234, 185, 120, 28, 239, 54, 120, 28, 239, 21, 120, 28,
+ 231, 122, 120, 28, 16, 233, 230, 120, 28, 237, 230, 120, 28, 239, 115,
+ 120, 28, 234, 101, 120, 28, 237, 189, 120, 28, 234, 193, 120, 28, 236,
+ 109, 120, 28, 239, 169, 120, 28, 236, 28, 120, 28, 234, 248, 120, 28,
+ 254, 190, 128, 241, 246, 120, 28, 235, 141, 120, 28, 245, 125, 153, 243,
+ 224, 120, 28, 233, 196, 120, 28, 242, 135, 120, 28, 234, 197, 120, 28,
+ 232, 164, 120, 28, 237, 232, 120, 28, 239, 174, 120, 28, 239, 76, 120,
+ 28, 238, 40, 128, 238, 46, 120, 28, 234, 103, 120, 28, 237, 23, 120, 28,
+ 236, 16, 120, 28, 242, 171, 120, 28, 231, 125, 120, 28, 240, 23, 240,
+ 201, 120, 28, 232, 167, 120, 28, 235, 124, 253, 247, 120, 28, 237, 204,
+ 120, 28, 231, 115, 120, 28, 231, 65, 120, 28, 241, 88, 120, 28, 240, 252,
+ 120, 28, 238, 6, 120, 28, 241, 180, 120, 28, 234, 109, 120, 28, 234, 108,
+ 120, 28, 237, 109, 120, 28, 233, 199, 120, 28, 234, 253, 120, 28, 236,
+ 107, 120, 28, 236, 33, 120, 28, 233, 69, 120, 28, 237, 88, 120, 28, 237,
+ 154, 120, 28, 232, 114, 120, 28, 233, 125, 120, 28, 255, 34, 253, 145,
+ 242, 177, 120, 28, 231, 124, 120, 28, 234, 217, 120, 28, 234, 191, 10,
+ 16, 5, 67, 10, 16, 5, 217, 10, 16, 5, 255, 18, 10, 16, 5, 209, 10, 16, 5,
+ 72, 10, 16, 5, 255, 19, 10, 16, 5, 210, 10, 16, 5, 192, 10, 16, 5, 71,
+ 10, 16, 5, 221, 10, 16, 5, 255, 15, 10, 16, 5, 162, 10, 16, 5, 173, 10,
+ 16, 5, 197, 10, 16, 5, 73, 10, 16, 5, 223, 10, 16, 5, 255, 20, 10, 16, 5,
+ 144, 10, 16, 5, 193, 10, 16, 5, 214, 10, 16, 5, 79, 10, 16, 5, 179, 10,
+ 16, 5, 255, 16, 10, 16, 5, 206, 10, 16, 5, 255, 14, 10, 16, 5, 255, 17,
+ 10, 16, 3, 67, 10, 16, 3, 217, 10, 16, 3, 255, 18, 10, 16, 3, 209, 10,
+ 16, 3, 72, 10, 16, 3, 255, 19, 10, 16, 3, 210, 10, 16, 3, 192, 10, 16, 3,
+ 71, 10, 16, 3, 221, 10, 16, 3, 255, 15, 10, 16, 3, 162, 10, 16, 3, 173,
+ 10, 16, 3, 197, 10, 16, 3, 73, 10, 16, 3, 223, 10, 16, 3, 255, 20, 10,
+ 16, 3, 144, 10, 16, 3, 193, 10, 16, 3, 214, 10, 16, 3, 79, 10, 16, 3,
+ 179, 10, 16, 3, 255, 16, 10, 16, 3, 206, 10, 16, 3, 255, 14, 10, 16, 3,
+ 255, 17, 10, 24, 5, 67, 10, 24, 5, 217, 10, 24, 5, 255, 18, 10, 24, 5,
+ 209, 10, 24, 5, 72, 10, 24, 5, 255, 19, 10, 24, 5, 210, 10, 24, 5, 192,
+ 10, 24, 5, 71, 10, 24, 5, 221, 10, 24, 5, 255, 15, 10, 24, 5, 162, 10,
+ 24, 5, 173, 10, 24, 5, 197, 10, 24, 5, 73, 10, 24, 5, 223, 10, 24, 5,
+ 255, 20, 10, 24, 5, 144, 10, 24, 5, 193, 10, 24, 5, 214, 10, 24, 5, 79,
+ 10, 24, 5, 179, 10, 24, 5, 255, 16, 10, 24, 5, 206, 10, 24, 5, 255, 14,
+ 10, 24, 5, 255, 17, 10, 24, 3, 67, 10, 24, 3, 217, 10, 24, 3, 255, 18,
+ 10, 24, 3, 209, 10, 24, 3, 72, 10, 24, 3, 255, 19, 10, 24, 3, 210, 10,
+ 24, 3, 71, 10, 24, 3, 221, 10, 24, 3, 255, 15, 10, 24, 3, 162, 10, 24, 3,
+ 173, 10, 24, 3, 197, 10, 24, 3, 73, 10, 24, 3, 223, 10, 24, 3, 255, 20,
+ 10, 24, 3, 144, 10, 24, 3, 193, 10, 24, 3, 214, 10, 24, 3, 79, 10, 24, 3,
+ 179, 10, 24, 3, 255, 16, 10, 24, 3, 206, 10, 24, 3, 255, 14, 10, 24, 3,
+ 255, 17, 10, 16, 24, 5, 67, 10, 16, 24, 5, 217, 10, 16, 24, 5, 255, 18,
+ 10, 16, 24, 5, 209, 10, 16, 24, 5, 72, 10, 16, 24, 5, 255, 19, 10, 16,
+ 24, 5, 210, 10, 16, 24, 5, 192, 10, 16, 24, 5, 71, 10, 16, 24, 5, 221,
+ 10, 16, 24, 5, 255, 15, 10, 16, 24, 5, 162, 10, 16, 24, 5, 173, 10, 16,
+ 24, 5, 197, 10, 16, 24, 5, 73, 10, 16, 24, 5, 223, 10, 16, 24, 5, 255,
+ 20, 10, 16, 24, 5, 144, 10, 16, 24, 5, 193, 10, 16, 24, 5, 214, 10, 16,
+ 24, 5, 79, 10, 16, 24, 5, 179, 10, 16, 24, 5, 255, 16, 10, 16, 24, 5,
+ 206, 10, 16, 24, 5, 255, 14, 10, 16, 24, 5, 255, 17, 10, 16, 24, 3, 67,
+ 10, 16, 24, 3, 217, 10, 16, 24, 3, 255, 18, 10, 16, 24, 3, 209, 10, 16,
+ 24, 3, 72, 10, 16, 24, 3, 255, 19, 10, 16, 24, 3, 210, 10, 16, 24, 3,
+ 192, 10, 16, 24, 3, 71, 10, 16, 24, 3, 221, 10, 16, 24, 3, 255, 15, 10,
+ 16, 24, 3, 162, 10, 16, 24, 3, 173, 10, 16, 24, 3, 197, 10, 16, 24, 3,
+ 73, 10, 16, 24, 3, 223, 10, 16, 24, 3, 255, 20, 10, 16, 24, 3, 144, 10,
+ 16, 24, 3, 193, 10, 16, 24, 3, 214, 10, 16, 24, 3, 79, 10, 16, 24, 3,
+ 179, 10, 16, 24, 3, 255, 16, 10, 16, 24, 3, 206, 10, 16, 24, 3, 255, 14,
+ 10, 16, 24, 3, 255, 17, 10, 84, 5, 67, 10, 84, 5, 255, 18, 10, 84, 5,
+ 209, 10, 84, 5, 210, 10, 84, 5, 221, 10, 84, 5, 255, 15, 10, 84, 5, 197,
+ 10, 84, 5, 73, 10, 84, 5, 223, 10, 84, 5, 255, 20, 10, 84, 5, 193, 10,
+ 84, 5, 214, 10, 84, 5, 79, 10, 84, 5, 179, 10, 84, 5, 255, 16, 10, 84, 5,
+ 206, 10, 84, 5, 255, 14, 10, 84, 5, 255, 17, 10, 84, 3, 67, 10, 84, 3,
+ 217, 10, 84, 3, 255, 18, 10, 84, 3, 209, 10, 84, 3, 255, 19, 10, 84, 3,
+ 192, 10, 84, 3, 71, 10, 84, 3, 221, 10, 84, 3, 255, 15, 10, 84, 3, 162,
+ 10, 84, 3, 173, 10, 84, 3, 197, 10, 84, 3, 223, 10, 84, 3, 255, 20, 10,
+ 84, 3, 144, 10, 84, 3, 193, 10, 84, 3, 214, 10, 84, 3, 79, 10, 84, 3,
+ 179, 10, 84, 3, 255, 16, 10, 84, 3, 206, 10, 84, 3, 255, 14, 10, 84, 3,
+ 255, 17, 10, 16, 84, 5, 67, 10, 16, 84, 5, 217, 10, 16, 84, 5, 255, 18,
+ 10, 16, 84, 5, 209, 10, 16, 84, 5, 72, 10, 16, 84, 5, 255, 19, 10, 16,
+ 84, 5, 210, 10, 16, 84, 5, 192, 10, 16, 84, 5, 71, 10, 16, 84, 5, 221,
+ 10, 16, 84, 5, 255, 15, 10, 16, 84, 5, 162, 10, 16, 84, 5, 173, 10, 16,
+ 84, 5, 197, 10, 16, 84, 5, 73, 10, 16, 84, 5, 223, 10, 16, 84, 5, 255,
+ 20, 10, 16, 84, 5, 144, 10, 16, 84, 5, 193, 10, 16, 84, 5, 214, 10, 16,
+ 84, 5, 79, 10, 16, 84, 5, 179, 10, 16, 84, 5, 255, 16, 10, 16, 84, 5,
+ 206, 10, 16, 84, 5, 255, 14, 10, 16, 84, 5, 255, 17, 10, 16, 84, 3, 67,
+ 10, 16, 84, 3, 217, 10, 16, 84, 3, 255, 18, 10, 16, 84, 3, 209, 10, 16,
+ 84, 3, 72, 10, 16, 84, 3, 255, 19, 10, 16, 84, 3, 210, 10, 16, 84, 3,
+ 192, 10, 16, 84, 3, 71, 10, 16, 84, 3, 221, 10, 16, 84, 3, 255, 15, 10,
+ 16, 84, 3, 162, 10, 16, 84, 3, 173, 10, 16, 84, 3, 197, 10, 16, 84, 3,
+ 73, 10, 16, 84, 3, 223, 10, 16, 84, 3, 255, 20, 10, 16, 84, 3, 144, 10,
+ 16, 84, 3, 193, 10, 16, 84, 3, 214, 10, 16, 84, 3, 79, 10, 16, 84, 3,
+ 179, 10, 16, 84, 3, 255, 16, 10, 16, 84, 3, 206, 10, 16, 84, 3, 255, 14,
+ 10, 16, 84, 3, 255, 17, 10, 93, 5, 67, 10, 93, 5, 217, 10, 93, 5, 209,
+ 10, 93, 5, 72, 10, 93, 5, 255, 19, 10, 93, 5, 210, 10, 93, 5, 221, 10,
+ 93, 5, 255, 15, 10, 93, 5, 162, 10, 93, 5, 173, 10, 93, 5, 197, 10, 93,
+ 5, 73, 10, 93, 5, 223, 10, 93, 5, 255, 20, 10, 93, 5, 193, 10, 93, 5,
+ 214, 10, 93, 5, 79, 10, 93, 5, 179, 10, 93, 5, 255, 16, 10, 93, 5, 206,
+ 10, 93, 5, 255, 14, 10, 93, 3, 67, 10, 93, 3, 217, 10, 93, 3, 255, 18,
+ 10, 93, 3, 209, 10, 93, 3, 72, 10, 93, 3, 255, 19, 10, 93, 3, 210, 10,
+ 93, 3, 192, 10, 93, 3, 71, 10, 93, 3, 221, 10, 93, 3, 255, 15, 10, 93, 3,
+ 162, 10, 93, 3, 173, 10, 93, 3, 197, 10, 93, 3, 73, 10, 93, 3, 223, 10,
+ 93, 3, 255, 20, 10, 93, 3, 144, 10, 93, 3, 193, 10, 93, 3, 214, 10, 93,
+ 3, 79, 10, 93, 3, 179, 10, 93, 3, 255, 16, 10, 93, 3, 206, 10, 93, 3,
+ 255, 14, 10, 93, 3, 255, 17, 10, 138, 5, 67, 10, 138, 5, 217, 10, 138, 5,
+ 209, 10, 138, 5, 72, 10, 138, 5, 255, 19, 10, 138, 5, 210, 10, 138, 5,
+ 71, 10, 138, 5, 221, 10, 138, 5, 255, 15, 10, 138, 5, 162, 10, 138, 5,
+ 173, 10, 138, 5, 73, 10, 138, 5, 193, 10, 138, 5, 214, 10, 138, 5, 79,
+ 10, 138, 5, 179, 10, 138, 5, 255, 16, 10, 138, 5, 206, 10, 138, 5, 255,
+ 14, 10, 138, 3, 67, 10, 138, 3, 217, 10, 138, 3, 255, 18, 10, 138, 3,
+ 209, 10, 138, 3, 72, 10, 138, 3, 255, 19, 10, 138, 3, 210, 10, 138, 3,
+ 192, 10, 138, 3, 71, 10, 138, 3, 221, 10, 138, 3, 255, 15, 10, 138, 3,
+ 162, 10, 138, 3, 173, 10, 138, 3, 197, 10, 138, 3, 73, 10, 138, 3, 223,
+ 10, 138, 3, 255, 20, 10, 138, 3, 144, 10, 138, 3, 193, 10, 138, 3, 214,
+ 10, 138, 3, 79, 10, 138, 3, 179, 10, 138, 3, 255, 16, 10, 138, 3, 206,
+ 10, 138, 3, 255, 14, 10, 138, 3, 255, 17, 10, 16, 93, 5, 67, 10, 16, 93,
+ 5, 217, 10, 16, 93, 5, 255, 18, 10, 16, 93, 5, 209, 10, 16, 93, 5, 72,
+ 10, 16, 93, 5, 255, 19, 10, 16, 93, 5, 210, 10, 16, 93, 5, 192, 10, 16,
+ 93, 5, 71, 10, 16, 93, 5, 221, 10, 16, 93, 5, 255, 15, 10, 16, 93, 5,
+ 162, 10, 16, 93, 5, 173, 10, 16, 93, 5, 197, 10, 16, 93, 5, 73, 10, 16,
+ 93, 5, 223, 10, 16, 93, 5, 255, 20, 10, 16, 93, 5, 144, 10, 16, 93, 5,
+ 193, 10, 16, 93, 5, 214, 10, 16, 93, 5, 79, 10, 16, 93, 5, 179, 10, 16,
+ 93, 5, 255, 16, 10, 16, 93, 5, 206, 10, 16, 93, 5, 255, 14, 10, 16, 93,
+ 5, 255, 17, 10, 16, 93, 3, 67, 10, 16, 93, 3, 217, 10, 16, 93, 3, 255,
+ 18, 10, 16, 93, 3, 209, 10, 16, 93, 3, 72, 10, 16, 93, 3, 255, 19, 10,
+ 16, 93, 3, 210, 10, 16, 93, 3, 192, 10, 16, 93, 3, 71, 10, 16, 93, 3,
+ 221, 10, 16, 93, 3, 255, 15, 10, 16, 93, 3, 162, 10, 16, 93, 3, 173, 10,
+ 16, 93, 3, 197, 10, 16, 93, 3, 73, 10, 16, 93, 3, 223, 10, 16, 93, 3,
+ 255, 20, 10, 16, 93, 3, 144, 10, 16, 93, 3, 193, 10, 16, 93, 3, 214, 10,
+ 16, 93, 3, 79, 10, 16, 93, 3, 179, 10, 16, 93, 3, 255, 16, 10, 16, 93, 3,
+ 206, 10, 16, 93, 3, 255, 14, 10, 16, 93, 3, 255, 17, 10, 27, 5, 67, 10,
+ 27, 5, 217, 10, 27, 5, 255, 18, 10, 27, 5, 209, 10, 27, 5, 72, 10, 27, 5,
+ 255, 19, 10, 27, 5, 210, 10, 27, 5, 192, 10, 27, 5, 71, 10, 27, 5, 221,
+ 10, 27, 5, 255, 15, 10, 27, 5, 162, 10, 27, 5, 173, 10, 27, 5, 197, 10,
+ 27, 5, 73, 10, 27, 5, 223, 10, 27, 5, 255, 20, 10, 27, 5, 144, 10, 27, 5,
+ 193, 10, 27, 5, 214, 10, 27, 5, 79, 10, 27, 5, 179, 10, 27, 5, 255, 16,
+ 10, 27, 5, 206, 10, 27, 5, 255, 14, 10, 27, 5, 255, 17, 10, 27, 3, 67,
+ 10, 27, 3, 217, 10, 27, 3, 255, 18, 10, 27, 3, 209, 10, 27, 3, 72, 10,
+ 27, 3, 255, 19, 10, 27, 3, 210, 10, 27, 3, 192, 10, 27, 3, 71, 10, 27, 3,
+ 221, 10, 27, 3, 255, 15, 10, 27, 3, 162, 10, 27, 3, 173, 10, 27, 3, 197,
+ 10, 27, 3, 73, 10, 27, 3, 223, 10, 27, 3, 255, 20, 10, 27, 3, 144, 10,
+ 27, 3, 193, 10, 27, 3, 214, 10, 27, 3, 79, 10, 27, 3, 179, 10, 27, 3,
+ 255, 16, 10, 27, 3, 206, 10, 27, 3, 255, 14, 10, 27, 3, 255, 17, 10, 27,
+ 16, 5, 67, 10, 27, 16, 5, 217, 10, 27, 16, 5, 255, 18, 10, 27, 16, 5,
+ 209, 10, 27, 16, 5, 72, 10, 27, 16, 5, 255, 19, 10, 27, 16, 5, 210, 10,
+ 27, 16, 5, 192, 10, 27, 16, 5, 71, 10, 27, 16, 5, 221, 10, 27, 16, 5,
+ 255, 15, 10, 27, 16, 5, 162, 10, 27, 16, 5, 173, 10, 27, 16, 5, 197, 10,
+ 27, 16, 5, 73, 10, 27, 16, 5, 223, 10, 27, 16, 5, 255, 20, 10, 27, 16, 5,
+ 144, 10, 27, 16, 5, 193, 10, 27, 16, 5, 214, 10, 27, 16, 5, 79, 10, 27,
+ 16, 5, 179, 10, 27, 16, 5, 255, 16, 10, 27, 16, 5, 206, 10, 27, 16, 5,
+ 255, 14, 10, 27, 16, 5, 255, 17, 10, 27, 16, 3, 67, 10, 27, 16, 3, 217,
+ 10, 27, 16, 3, 255, 18, 10, 27, 16, 3, 209, 10, 27, 16, 3, 72, 10, 27,
+ 16, 3, 255, 19, 10, 27, 16, 3, 210, 10, 27, 16, 3, 192, 10, 27, 16, 3,
+ 71, 10, 27, 16, 3, 221, 10, 27, 16, 3, 255, 15, 10, 27, 16, 3, 162, 10,
+ 27, 16, 3, 173, 10, 27, 16, 3, 197, 10, 27, 16, 3, 73, 10, 27, 16, 3,
+ 223, 10, 27, 16, 3, 255, 20, 10, 27, 16, 3, 144, 10, 27, 16, 3, 193, 10,
+ 27, 16, 3, 214, 10, 27, 16, 3, 79, 10, 27, 16, 3, 179, 10, 27, 16, 3,
+ 255, 16, 10, 27, 16, 3, 206, 10, 27, 16, 3, 255, 14, 10, 27, 16, 3, 255,
+ 17, 10, 27, 24, 5, 67, 10, 27, 24, 5, 217, 10, 27, 24, 5, 255, 18, 10,
+ 27, 24, 5, 209, 10, 27, 24, 5, 72, 10, 27, 24, 5, 255, 19, 10, 27, 24, 5,
+ 210, 10, 27, 24, 5, 192, 10, 27, 24, 5, 71, 10, 27, 24, 5, 221, 10, 27,
+ 24, 5, 255, 15, 10, 27, 24, 5, 162, 10, 27, 24, 5, 173, 10, 27, 24, 5,
+ 197, 10, 27, 24, 5, 73, 10, 27, 24, 5, 223, 10, 27, 24, 5, 255, 20, 10,
+ 27, 24, 5, 144, 10, 27, 24, 5, 193, 10, 27, 24, 5, 214, 10, 27, 24, 5,
+ 79, 10, 27, 24, 5, 179, 10, 27, 24, 5, 255, 16, 10, 27, 24, 5, 206, 10,
+ 27, 24, 5, 255, 14, 10, 27, 24, 5, 255, 17, 10, 27, 24, 3, 67, 10, 27,
+ 24, 3, 217, 10, 27, 24, 3, 255, 18, 10, 27, 24, 3, 209, 10, 27, 24, 3,
+ 72, 10, 27, 24, 3, 255, 19, 10, 27, 24, 3, 210, 10, 27, 24, 3, 192, 10,
+ 27, 24, 3, 71, 10, 27, 24, 3, 221, 10, 27, 24, 3, 255, 15, 10, 27, 24, 3,
+ 162, 10, 27, 24, 3, 173, 10, 27, 24, 3, 197, 10, 27, 24, 3, 73, 10, 27,
+ 24, 3, 223, 10, 27, 24, 3, 255, 20, 10, 27, 24, 3, 144, 10, 27, 24, 3,
+ 193, 10, 27, 24, 3, 214, 10, 27, 24, 3, 79, 10, 27, 24, 3, 179, 10, 27,
+ 24, 3, 255, 16, 10, 27, 24, 3, 206, 10, 27, 24, 3, 255, 14, 10, 27, 24,
+ 3, 255, 17, 10, 27, 16, 24, 5, 67, 10, 27, 16, 24, 5, 217, 10, 27, 16,
+ 24, 5, 255, 18, 10, 27, 16, 24, 5, 209, 10, 27, 16, 24, 5, 72, 10, 27,
+ 16, 24, 5, 255, 19, 10, 27, 16, 24, 5, 210, 10, 27, 16, 24, 5, 192, 10,
+ 27, 16, 24, 5, 71, 10, 27, 16, 24, 5, 221, 10, 27, 16, 24, 5, 255, 15,
+ 10, 27, 16, 24, 5, 162, 10, 27, 16, 24, 5, 173, 10, 27, 16, 24, 5, 197,
+ 10, 27, 16, 24, 5, 73, 10, 27, 16, 24, 5, 223, 10, 27, 16, 24, 5, 255,
+ 20, 10, 27, 16, 24, 5, 144, 10, 27, 16, 24, 5, 193, 10, 27, 16, 24, 5,
+ 214, 10, 27, 16, 24, 5, 79, 10, 27, 16, 24, 5, 179, 10, 27, 16, 24, 5,
+ 255, 16, 10, 27, 16, 24, 5, 206, 10, 27, 16, 24, 5, 255, 14, 10, 27, 16,
+ 24, 5, 255, 17, 10, 27, 16, 24, 3, 67, 10, 27, 16, 24, 3, 217, 10, 27,
+ 16, 24, 3, 255, 18, 10, 27, 16, 24, 3, 209, 10, 27, 16, 24, 3, 72, 10,
+ 27, 16, 24, 3, 255, 19, 10, 27, 16, 24, 3, 210, 10, 27, 16, 24, 3, 192,
+ 10, 27, 16, 24, 3, 71, 10, 27, 16, 24, 3, 221, 10, 27, 16, 24, 3, 255,
+ 15, 10, 27, 16, 24, 3, 162, 10, 27, 16, 24, 3, 173, 10, 27, 16, 24, 3,
+ 197, 10, 27, 16, 24, 3, 73, 10, 27, 16, 24, 3, 223, 10, 27, 16, 24, 3,
+ 255, 20, 10, 27, 16, 24, 3, 144, 10, 27, 16, 24, 3, 193, 10, 27, 16, 24,
+ 3, 214, 10, 27, 16, 24, 3, 79, 10, 27, 16, 24, 3, 179, 10, 27, 16, 24, 3,
+ 255, 16, 10, 27, 16, 24, 3, 206, 10, 27, 16, 24, 3, 255, 14, 10, 27, 16,
+ 24, 3, 255, 17, 10, 160, 5, 67, 10, 160, 5, 217, 10, 160, 5, 255, 18, 10,
+ 160, 5, 209, 10, 160, 5, 72, 10, 160, 5, 255, 19, 10, 160, 5, 210, 10,
+ 160, 5, 192, 10, 160, 5, 71, 10, 160, 5, 221, 10, 160, 5, 255, 15, 10,
+ 160, 5, 162, 10, 160, 5, 173, 10, 160, 5, 197, 10, 160, 5, 73, 10, 160,
+ 5, 223, 10, 160, 5, 255, 20, 10, 160, 5, 144, 10, 160, 5, 193, 10, 160,
+ 5, 214, 10, 160, 5, 79, 10, 160, 5, 179, 10, 160, 5, 255, 16, 10, 160, 5,
+ 206, 10, 160, 5, 255, 14, 10, 160, 5, 255, 17, 10, 160, 3, 67, 10, 160,
+ 3, 217, 10, 160, 3, 255, 18, 10, 160, 3, 209, 10, 160, 3, 72, 10, 160, 3,
+ 255, 19, 10, 160, 3, 210, 10, 160, 3, 192, 10, 160, 3, 71, 10, 160, 3,
+ 221, 10, 160, 3, 255, 15, 10, 160, 3, 162, 10, 160, 3, 173, 10, 160, 3,
+ 197, 10, 160, 3, 73, 10, 160, 3, 223, 10, 160, 3, 255, 20, 10, 160, 3,
+ 144, 10, 160, 3, 193, 10, 160, 3, 214, 10, 160, 3, 79, 10, 160, 3, 179,
+ 10, 160, 3, 255, 16, 10, 160, 3, 206, 10, 160, 3, 255, 14, 10, 160, 3,
+ 255, 17, 10, 24, 3, 238, 70, 71, 10, 24, 3, 238, 70, 221, 10, 16, 5, 240,
+ 22, 10, 16, 5, 242, 242, 10, 16, 5, 240, 10, 10, 16, 5, 240, 28, 10, 16,
+ 5, 236, 165, 10, 16, 5, 242, 251, 10, 16, 5, 248, 87, 10, 16, 5, 240, 38,
+ 10, 16, 5, 242, 237, 10, 16, 5, 240, 41, 10, 16, 5, 240, 33, 10, 16, 5,
+ 253, 154, 10, 16, 5, 253, 150, 10, 16, 5, 253, 188, 10, 16, 5, 236, 169,
+ 10, 16, 5, 253, 147, 10, 16, 5, 248, 73, 10, 16, 5, 243, 0, 91, 10, 16,
+ 5, 240, 21, 10, 16, 5, 248, 85, 10, 16, 5, 236, 160, 10, 16, 5, 248, 68,
+ 10, 16, 5, 248, 67, 10, 16, 5, 248, 69, 10, 16, 5, 240, 20, 10, 16, 240,
+ 79, 10, 16, 3, 240, 22, 10, 16, 3, 242, 242, 10, 16, 3, 240, 10, 10, 16,
+ 3, 240, 28, 10, 16, 3, 236, 165, 10, 16, 3, 242, 251, 10, 16, 3, 248, 87,
+ 10, 16, 3, 240, 38, 10, 16, 3, 242, 237, 10, 16, 3, 240, 41, 10, 16, 3,
+ 240, 33, 10, 16, 3, 253, 154, 10, 16, 3, 253, 150, 10, 16, 3, 253, 188,
+ 10, 16, 3, 236, 169, 10, 16, 3, 253, 147, 10, 16, 3, 248, 73, 10, 16, 3,
+ 30, 240, 21, 10, 16, 3, 240, 21, 10, 16, 3, 248, 85, 10, 16, 3, 236, 160,
+ 10, 16, 3, 248, 68, 10, 16, 3, 248, 67, 10, 16, 3, 248, 69, 10, 16, 3,
+ 240, 20, 10, 16, 238, 100, 231, 90, 10, 16, 238, 57, 91, 10, 16, 243, 0,
+ 91, 10, 16, 243, 29, 91, 10, 16, 254, 11, 91, 10, 16, 253, 218, 91, 10,
+ 16, 255, 29, 91, 10, 24, 5, 240, 22, 10, 24, 5, 242, 242, 10, 24, 5, 240,
+ 10, 10, 24, 5, 240, 28, 10, 24, 5, 236, 165, 10, 24, 5, 242, 251, 10, 24,
+ 5, 248, 87, 10, 24, 5, 240, 38, 10, 24, 5, 242, 237, 10, 24, 5, 240, 41,
+ 10, 24, 5, 240, 33, 10, 24, 5, 253, 154, 10, 24, 5, 253, 150, 10, 24, 5,
+ 253, 188, 10, 24, 5, 236, 169, 10, 24, 5, 253, 147, 10, 24, 5, 248, 73,
+ 10, 24, 5, 243, 0, 91, 10, 24, 5, 240, 21, 10, 24, 5, 248, 85, 10, 24, 5,
+ 236, 160, 10, 24, 5, 248, 68, 10, 24, 5, 248, 67, 10, 24, 5, 248, 69, 10,
+ 24, 5, 240, 20, 10, 24, 240, 79, 10, 24, 3, 240, 22, 10, 24, 3, 242, 242,
+ 10, 24, 3, 240, 10, 10, 24, 3, 240, 28, 10, 24, 3, 236, 165, 10, 24, 3,
+ 242, 251, 10, 24, 3, 248, 87, 10, 24, 3, 240, 38, 10, 24, 3, 242, 237,
+ 10, 24, 3, 240, 41, 10, 24, 3, 240, 33, 10, 24, 3, 253, 154, 10, 24, 3,
+ 253, 150, 10, 24, 3, 253, 188, 10, 24, 3, 236, 169, 10, 24, 3, 253, 147,
+ 10, 24, 3, 248, 73, 10, 24, 3, 30, 240, 21, 10, 24, 3, 240, 21, 10, 24,
+ 3, 248, 85, 10, 24, 3, 236, 160, 10, 24, 3, 248, 68, 10, 24, 3, 248, 67,
+ 10, 24, 3, 248, 69, 10, 24, 3, 240, 20, 10, 24, 238, 100, 231, 90, 10,
+ 24, 238, 57, 91, 10, 24, 243, 0, 91, 10, 24, 243, 29, 91, 10, 24, 254,
+ 11, 91, 10, 24, 253, 218, 91, 10, 24, 255, 29, 91, 10, 16, 24, 5, 240,
+ 22, 10, 16, 24, 5, 242, 242, 10, 16, 24, 5, 240, 10, 10, 16, 24, 5, 240,
+ 28, 10, 16, 24, 5, 236, 165, 10, 16, 24, 5, 242, 251, 10, 16, 24, 5, 248,
+ 87, 10, 16, 24, 5, 240, 38, 10, 16, 24, 5, 242, 237, 10, 16, 24, 5, 240,
+ 41, 10, 16, 24, 5, 240, 33, 10, 16, 24, 5, 253, 154, 10, 16, 24, 5, 253,
+ 150, 10, 16, 24, 5, 253, 188, 10, 16, 24, 5, 236, 169, 10, 16, 24, 5,
+ 253, 147, 10, 16, 24, 5, 248, 73, 10, 16, 24, 5, 243, 0, 91, 10, 16, 24,
+ 5, 240, 21, 10, 16, 24, 5, 248, 85, 10, 16, 24, 5, 236, 160, 10, 16, 24,
+ 5, 248, 68, 10, 16, 24, 5, 248, 67, 10, 16, 24, 5, 248, 69, 10, 16, 24,
+ 5, 240, 20, 10, 16, 24, 240, 79, 10, 16, 24, 3, 240, 22, 10, 16, 24, 3,
+ 242, 242, 10, 16, 24, 3, 240, 10, 10, 16, 24, 3, 240, 28, 10, 16, 24, 3,
+ 236, 165, 10, 16, 24, 3, 242, 251, 10, 16, 24, 3, 248, 87, 10, 16, 24, 3,
+ 240, 38, 10, 16, 24, 3, 242, 237, 10, 16, 24, 3, 240, 41, 10, 16, 24, 3,
+ 240, 33, 10, 16, 24, 3, 253, 154, 10, 16, 24, 3, 253, 150, 10, 16, 24, 3,
+ 253, 188, 10, 16, 24, 3, 236, 169, 10, 16, 24, 3, 253, 147, 10, 16, 24,
+ 3, 248, 73, 10, 16, 24, 3, 30, 240, 21, 10, 16, 24, 3, 240, 21, 10, 16,
+ 24, 3, 248, 85, 10, 16, 24, 3, 236, 160, 10, 16, 24, 3, 248, 68, 10, 16,
+ 24, 3, 248, 67, 10, 16, 24, 3, 248, 69, 10, 16, 24, 3, 240, 20, 10, 16,
+ 24, 238, 100, 231, 90, 10, 16, 24, 238, 57, 91, 10, 16, 24, 243, 0, 91,
+ 10, 16, 24, 243, 29, 91, 10, 16, 24, 254, 11, 91, 10, 16, 24, 253, 218,
+ 91, 10, 16, 24, 255, 29, 91, 10, 27, 16, 5, 240, 22, 10, 27, 16, 5, 242,
+ 242, 10, 27, 16, 5, 240, 10, 10, 27, 16, 5, 240, 28, 10, 27, 16, 5, 236,
+ 165, 10, 27, 16, 5, 242, 251, 10, 27, 16, 5, 248, 87, 10, 27, 16, 5, 240,
+ 38, 10, 27, 16, 5, 242, 237, 10, 27, 16, 5, 240, 41, 10, 27, 16, 5, 240,
+ 33, 10, 27, 16, 5, 253, 154, 10, 27, 16, 5, 253, 150, 10, 27, 16, 5, 253,
+ 188, 10, 27, 16, 5, 236, 169, 10, 27, 16, 5, 253, 147, 10, 27, 16, 5,
+ 248, 73, 10, 27, 16, 5, 243, 0, 91, 10, 27, 16, 5, 240, 21, 10, 27, 16,
+ 5, 248, 85, 10, 27, 16, 5, 236, 160, 10, 27, 16, 5, 248, 68, 10, 27, 16,
+ 5, 248, 67, 10, 27, 16, 5, 248, 69, 10, 27, 16, 5, 240, 20, 10, 27, 16,
+ 240, 79, 10, 27, 16, 3, 240, 22, 10, 27, 16, 3, 242, 242, 10, 27, 16, 3,
+ 240, 10, 10, 27, 16, 3, 240, 28, 10, 27, 16, 3, 236, 165, 10, 27, 16, 3,
+ 242, 251, 10, 27, 16, 3, 248, 87, 10, 27, 16, 3, 240, 38, 10, 27, 16, 3,
+ 242, 237, 10, 27, 16, 3, 240, 41, 10, 27, 16, 3, 240, 33, 10, 27, 16, 3,
+ 253, 154, 10, 27, 16, 3, 253, 150, 10, 27, 16, 3, 253, 188, 10, 27, 16,
+ 3, 236, 169, 10, 27, 16, 3, 253, 147, 10, 27, 16, 3, 248, 73, 10, 27, 16,
+ 3, 30, 240, 21, 10, 27, 16, 3, 240, 21, 10, 27, 16, 3, 248, 85, 10, 27,
+ 16, 3, 236, 160, 10, 27, 16, 3, 248, 68, 10, 27, 16, 3, 248, 67, 10, 27,
+ 16, 3, 248, 69, 10, 27, 16, 3, 240, 20, 10, 27, 16, 238, 100, 231, 90,
+ 10, 27, 16, 238, 57, 91, 10, 27, 16, 243, 0, 91, 10, 27, 16, 243, 29, 91,
+ 10, 27, 16, 254, 11, 91, 10, 27, 16, 253, 218, 91, 10, 27, 16, 255, 29,
+ 91, 10, 27, 16, 24, 5, 240, 22, 10, 27, 16, 24, 5, 242, 242, 10, 27, 16,
+ 24, 5, 240, 10, 10, 27, 16, 24, 5, 240, 28, 10, 27, 16, 24, 5, 236, 165,
+ 10, 27, 16, 24, 5, 242, 251, 10, 27, 16, 24, 5, 248, 87, 10, 27, 16, 24,
+ 5, 240, 38, 10, 27, 16, 24, 5, 242, 237, 10, 27, 16, 24, 5, 240, 41, 10,
+ 27, 16, 24, 5, 240, 33, 10, 27, 16, 24, 5, 253, 154, 10, 27, 16, 24, 5,
+ 253, 150, 10, 27, 16, 24, 5, 253, 188, 10, 27, 16, 24, 5, 236, 169, 10,
+ 27, 16, 24, 5, 253, 147, 10, 27, 16, 24, 5, 248, 73, 10, 27, 16, 24, 5,
+ 243, 0, 91, 10, 27, 16, 24, 5, 240, 21, 10, 27, 16, 24, 5, 248, 85, 10,
+ 27, 16, 24, 5, 236, 160, 10, 27, 16, 24, 5, 248, 68, 10, 27, 16, 24, 5,
+ 248, 67, 10, 27, 16, 24, 5, 248, 69, 10, 27, 16, 24, 5, 240, 20, 10, 27,
+ 16, 24, 240, 79, 10, 27, 16, 24, 3, 240, 22, 10, 27, 16, 24, 3, 242, 242,
+ 10, 27, 16, 24, 3, 240, 10, 10, 27, 16, 24, 3, 240, 28, 10, 27, 16, 24,
+ 3, 236, 165, 10, 27, 16, 24, 3, 242, 251, 10, 27, 16, 24, 3, 248, 87, 10,
+ 27, 16, 24, 3, 240, 38, 10, 27, 16, 24, 3, 242, 237, 10, 27, 16, 24, 3,
+ 240, 41, 10, 27, 16, 24, 3, 240, 33, 10, 27, 16, 24, 3, 253, 154, 10, 27,
+ 16, 24, 3, 253, 150, 10, 27, 16, 24, 3, 253, 188, 10, 27, 16, 24, 3, 236,
+ 169, 10, 27, 16, 24, 3, 253, 147, 10, 27, 16, 24, 3, 248, 73, 10, 27, 16,
+ 24, 3, 30, 240, 21, 10, 27, 16, 24, 3, 240, 21, 10, 27, 16, 24, 3, 248,
+ 85, 10, 27, 16, 24, 3, 236, 160, 10, 27, 16, 24, 3, 248, 68, 10, 27, 16,
+ 24, 3, 248, 67, 10, 27, 16, 24, 3, 248, 69, 10, 27, 16, 24, 3, 240, 20,
+ 10, 27, 16, 24, 238, 100, 231, 90, 10, 27, 16, 24, 238, 57, 91, 10, 27,
+ 16, 24, 243, 0, 91, 10, 27, 16, 24, 243, 29, 91, 10, 27, 16, 24, 254, 11,
+ 91, 10, 27, 16, 24, 253, 218, 91, 10, 27, 16, 24, 255, 29, 91, 10, 16,
+ 26, 242, 217, 10, 16, 26, 127, 10, 16, 26, 111, 10, 16, 26, 166, 10, 16,
+ 26, 177, 10, 16, 26, 176, 10, 16, 26, 187, 10, 16, 26, 203, 10, 16, 26,
+ 195, 10, 16, 26, 202, 10, 138, 26, 242, 217, 10, 138, 26, 127, 10, 138,
+ 26, 111, 10, 138, 26, 166, 10, 138, 26, 177, 10, 138, 26, 176, 10, 138,
+ 26, 187, 10, 138, 26, 203, 10, 138, 26, 195, 10, 138, 26, 202, 10, 27,
+ 26, 242, 217, 10, 27, 26, 127, 10, 27, 26, 111, 10, 27, 26, 166, 10, 27,
+ 26, 177, 10, 27, 26, 176, 10, 27, 26, 187, 10, 27, 26, 203, 10, 27, 26,
+ 195, 10, 27, 26, 202, 10, 27, 16, 26, 242, 217, 10, 27, 16, 26, 127, 10,
+ 27, 16, 26, 111, 10, 27, 16, 26, 166, 10, 27, 16, 26, 177, 10, 27, 16,
+ 26, 176, 10, 27, 16, 26, 187, 10, 27, 16, 26, 203, 10, 27, 16, 26, 195,
+ 10, 27, 16, 26, 202, 10, 160, 26, 242, 217, 10, 160, 26, 127, 10, 160,
+ 26, 111, 10, 160, 26, 166, 10, 160, 26, 177, 10, 160, 26, 176, 10, 160,
+ 26, 187, 10, 160, 26, 203, 10, 160, 26, 195, 10, 160, 26, 202, 7, 9, 227,
+ 16, 7, 9, 227, 17, 7, 9, 227, 18, 7, 9, 227, 19, 7, 9, 227, 20, 7, 9,
+ 227, 21, 7, 9, 227, 22, 7, 9, 227, 23, 7, 9, 227, 24, 7, 9, 227, 25, 7,
+ 9, 227, 26, 7, 9, 227, 27, 7, 9, 227, 28, 7, 9, 227, 29, 7, 9, 227, 30,
+ 7, 9, 227, 31, 7, 9, 227, 32, 7, 9, 227, 33, 7, 9, 227, 34, 7, 9, 227,
+ 35, 7, 9, 227, 36, 7, 9, 227, 37, 7, 9, 227, 38, 7, 9, 227, 39, 7, 9,
+ 227, 40, 7, 9, 227, 41, 7, 9, 227, 42, 7, 9, 227, 43, 7, 9, 227, 44, 7,
+ 9, 227, 45, 7, 9, 227, 46, 7, 9, 227, 47, 7, 9, 227, 48, 7, 9, 227, 49,
+ 7, 9, 227, 50, 7, 9, 227, 51, 7, 9, 227, 52, 7, 9, 227, 53, 7, 9, 227,
+ 54, 7, 9, 227, 55, 7, 9, 227, 56, 7, 9, 227, 57, 7, 9, 227, 58, 7, 9,
+ 227, 59, 7, 9, 227, 60, 7, 9, 227, 61, 7, 9, 227, 62, 7, 9, 227, 63, 7,
+ 9, 227, 64, 7, 9, 227, 65, 7, 9, 227, 66, 7, 9, 227, 67, 7, 9, 227, 68,
+ 7, 9, 227, 69, 7, 9, 227, 70, 7, 9, 227, 71, 7, 9, 227, 72, 7, 9, 227,
+ 73, 7, 9, 227, 74, 7, 9, 227, 75, 7, 9, 227, 76, 7, 9, 227, 77, 7, 9,
+ 227, 78, 7, 9, 227, 79, 7, 9, 227, 80, 7, 9, 227, 81, 7, 9, 227, 82, 7,
+ 9, 227, 83, 7, 9, 227, 84, 7, 9, 227, 85, 7, 9, 227, 86, 7, 9, 227, 87,
+ 7, 9, 227, 88, 7, 9, 227, 89, 7, 9, 227, 90, 7, 9, 227, 91, 7, 9, 227,
+ 92, 7, 9, 227, 93, 7, 9, 227, 94, 7, 9, 227, 95, 7, 9, 227, 96, 7, 9,
+ 227, 97, 7, 9, 227, 98, 7, 9, 227, 99, 7, 9, 227, 100, 7, 9, 227, 101, 7,
+ 9, 227, 102, 7, 9, 227, 103, 7, 9, 227, 104, 7, 9, 227, 105, 7, 9, 227,
+ 106, 7, 9, 227, 107, 7, 9, 227, 108, 7, 9, 227, 109, 7, 9, 227, 110, 7,
+ 9, 227, 111, 7, 9, 227, 112, 7, 9, 227, 113, 7, 9, 227, 114, 7, 9, 227,
+ 115, 7, 9, 227, 116, 7, 9, 227, 117, 7, 9, 227, 118, 7, 9, 227, 119, 7,
+ 9, 227, 120, 7, 9, 227, 121, 7, 9, 227, 122, 7, 9, 227, 123, 7, 9, 227,
+ 124, 7, 9, 227, 125, 7, 9, 227, 126, 7, 9, 227, 127, 7, 9, 227, 128, 7,
+ 9, 227, 129, 7, 9, 227, 130, 7, 9, 227, 131, 7, 9, 227, 132, 7, 9, 227,
+ 133, 7, 9, 227, 134, 7, 9, 227, 135, 7, 9, 227, 136, 7, 9, 227, 137, 7,
+ 9, 227, 138, 7, 9, 227, 139, 7, 9, 227, 140, 7, 9, 227, 141, 7, 9, 227,
+ 142, 7, 9, 227, 143, 7, 9, 227, 144, 7, 9, 227, 145, 7, 9, 227, 146, 7,
+ 9, 227, 147, 7, 9, 227, 148, 7, 9, 227, 149, 7, 9, 227, 150, 7, 9, 227,
+ 151, 7, 9, 227, 152, 7, 9, 227, 153, 7, 9, 227, 154, 7, 9, 227, 155, 7,
+ 9, 227, 156, 7, 9, 227, 157, 7, 9, 227, 158, 7, 9, 227, 159, 7, 9, 227,
+ 160, 7, 9, 227, 161, 7, 9, 227, 162, 7, 9, 227, 163, 7, 9, 227, 164, 7,
+ 9, 227, 165, 7, 9, 227, 166, 7, 9, 227, 167, 7, 9, 227, 168, 7, 9, 227,
+ 169, 7, 9, 227, 170, 7, 9, 227, 171, 7, 9, 227, 172, 7, 9, 227, 173, 7,
+ 9, 227, 174, 7, 9, 227, 175, 7, 9, 227, 176, 7, 9, 227, 177, 7, 9, 227,
+ 178, 7, 9, 227, 179, 7, 9, 227, 180, 7, 9, 227, 181, 7, 9, 227, 182, 7,
+ 9, 227, 183, 7, 9, 227, 184, 7, 9, 227, 185, 7, 9, 227, 186, 7, 9, 227,
+ 187, 7, 9, 227, 188, 7, 9, 227, 189, 7, 9, 227, 190, 7, 9, 227, 191, 7,
+ 9, 227, 192, 7, 9, 227, 193, 7, 9, 227, 194, 7, 9, 227, 195, 7, 9, 227,
+ 196, 7, 9, 227, 197, 7, 9, 227, 198, 7, 9, 227, 199, 7, 9, 227, 200, 7,
+ 9, 227, 201, 7, 9, 227, 202, 7, 9, 227, 203, 7, 9, 227, 204, 7, 9, 227,
+ 205, 7, 9, 227, 206, 7, 9, 227, 207, 7, 9, 227, 208, 7, 9, 227, 209, 7,
+ 9, 227, 210, 7, 9, 227, 211, 7, 9, 227, 212, 7, 9, 227, 213, 7, 9, 227,
+ 214, 7, 9, 227, 215, 7, 9, 227, 216, 7, 9, 227, 217, 7, 9, 227, 218, 7,
+ 9, 227, 219, 7, 9, 227, 220, 7, 9, 227, 221, 7, 9, 227, 222, 7, 9, 227,
+ 223, 7, 9, 227, 224, 7, 9, 227, 225, 7, 9, 227, 226, 7, 9, 227, 227, 7,
+ 9, 227, 228, 7, 9, 227, 229, 7, 9, 227, 230, 7, 9, 227, 231, 7, 9, 227,
+ 232, 7, 9, 227, 233, 7, 9, 227, 234, 7, 9, 227, 235, 7, 9, 227, 236, 7,
+ 9, 227, 237, 7, 9, 227, 238, 7, 9, 227, 239, 7, 9, 227, 240, 7, 9, 227,
+ 241, 7, 9, 227, 242, 7, 9, 227, 243, 7, 9, 227, 244, 7, 9, 227, 245, 7,
+ 9, 227, 246, 7, 9, 227, 247, 7, 9, 227, 248, 7, 9, 227, 249, 7, 9, 227,
+ 250, 7, 9, 227, 251, 7, 9, 227, 252, 7, 9, 227, 253, 7, 9, 227, 254, 7,
+ 9, 227, 255, 7, 9, 228, 0, 7, 9, 228, 1, 7, 9, 228, 2, 7, 9, 228, 3, 7,
+ 9, 228, 4, 7, 9, 228, 5, 7, 9, 228, 6, 7, 9, 228, 7, 7, 9, 228, 8, 7, 9,
+ 228, 9, 7, 9, 228, 10, 7, 9, 228, 11, 7, 9, 228, 12, 7, 9, 228, 13, 7, 9,
+ 228, 14, 7, 9, 228, 15, 7, 9, 228, 16, 7, 9, 228, 17, 7, 9, 228, 18, 7,
+ 9, 228, 19, 7, 9, 228, 20, 7, 9, 228, 21, 7, 9, 228, 22, 7, 9, 228, 23,
+ 7, 9, 228, 24, 7, 9, 228, 25, 7, 9, 228, 26, 7, 9, 228, 27, 7, 9, 228,
+ 28, 7, 9, 228, 29, 7, 9, 228, 30, 7, 9, 228, 31, 7, 9, 228, 32, 7, 9,
+ 228, 33, 7, 9, 228, 34, 7, 9, 228, 35, 7, 9, 228, 36, 7, 9, 228, 37, 7,
+ 9, 228, 38, 7, 9, 228, 39, 7, 9, 228, 40, 7, 9, 228, 41, 7, 9, 228, 42,
+ 7, 9, 228, 43, 7, 9, 228, 44, 7, 9, 228, 45, 7, 9, 228, 46, 7, 9, 228,
+ 47, 7, 9, 228, 48, 7, 9, 228, 49, 7, 9, 228, 50, 7, 9, 228, 51, 7, 9,
+ 228, 52, 7, 9, 228, 53, 7, 9, 228, 54, 7, 9, 228, 55, 7, 9, 228, 56, 7,
+ 9, 228, 57, 7, 9, 228, 58, 7, 9, 228, 59, 7, 9, 228, 60, 7, 9, 228, 61,
+ 7, 9, 228, 62, 7, 9, 228, 63, 7, 9, 228, 64, 7, 9, 228, 65, 7, 9, 228,
+ 66, 7, 9, 228, 67, 7, 9, 228, 68, 7, 9, 228, 69, 7, 9, 228, 70, 7, 9,
+ 228, 71, 7, 9, 228, 72, 7, 9, 228, 73, 7, 9, 228, 74, 7, 9, 228, 75, 7,
+ 9, 228, 76, 7, 9, 228, 77, 7, 9, 228, 78, 7, 9, 228, 79, 7, 9, 228, 80,
+ 7, 9, 228, 81, 7, 9, 228, 82, 7, 9, 228, 83, 7, 9, 228, 84, 7, 9, 228,
+ 85, 7, 9, 228, 86, 7, 9, 228, 87, 7, 9, 228, 88, 7, 9, 228, 89, 7, 9,
+ 228, 90, 7, 9, 228, 91, 7, 9, 228, 92, 7, 9, 228, 93, 7, 9, 228, 94, 7,
+ 9, 228, 95, 7, 9, 228, 96, 7, 9, 228, 97, 7, 9, 228, 98, 7, 9, 228, 99,
+ 7, 9, 228, 100, 7, 9, 228, 101, 7, 9, 228, 102, 7, 9, 228, 103, 7, 9,
+ 228, 104, 7, 9, 228, 105, 7, 9, 228, 106, 7, 9, 228, 107, 7, 9, 228, 108,
+ 7, 9, 228, 109, 7, 9, 228, 110, 7, 9, 228, 111, 7, 9, 228, 112, 7, 9,
+ 228, 113, 7, 9, 228, 114, 7, 9, 228, 115, 7, 9, 228, 116, 7, 9, 228, 117,
+ 7, 9, 228, 118, 7, 9, 228, 119, 7, 9, 228, 120, 7, 9, 228, 121, 7, 9,
+ 228, 122, 7, 9, 228, 123, 7, 9, 228, 124, 7, 9, 228, 125, 7, 9, 228, 126,
+ 7, 9, 228, 127, 7, 9, 228, 128, 7, 9, 228, 129, 7, 9, 228, 130, 7, 9,
+ 228, 131, 7, 9, 228, 132, 7, 9, 228, 133, 7, 9, 228, 134, 7, 9, 228, 135,
+ 7, 9, 228, 136, 7, 9, 228, 137, 7, 9, 228, 138, 7, 9, 228, 139, 7, 9,
+ 228, 140, 7, 9, 228, 141, 7, 9, 228, 142, 7, 9, 228, 143, 7, 9, 228, 144,
+ 7, 9, 228, 145, 7, 9, 228, 146, 7, 9, 228, 147, 7, 9, 228, 148, 7, 9,
+ 228, 149, 7, 9, 228, 150, 7, 9, 228, 151, 7, 9, 228, 152, 7, 9, 228, 153,
+ 7, 9, 228, 154, 7, 9, 228, 155, 7, 9, 228, 156, 7, 9, 228, 157, 7, 9,
+ 228, 158, 7, 9, 228, 159, 7, 9, 228, 160, 7, 9, 228, 161, 7, 9, 228, 162,
+ 7, 9, 228, 163, 7, 9, 228, 164, 7, 9, 228, 165, 7, 9, 228, 166, 7, 9,
+ 228, 167, 7, 9, 228, 168, 7, 9, 228, 169, 7, 9, 228, 170, 7, 9, 228, 171,
+ 7, 9, 228, 172, 7, 9, 228, 173, 7, 9, 228, 174, 7, 9, 228, 175, 7, 9,
+ 228, 176, 7, 9, 228, 177, 7, 9, 228, 178, 7, 9, 228, 179, 7, 9, 228, 180,
+ 7, 9, 228, 181, 7, 9, 228, 182, 7, 9, 228, 183, 7, 9, 228, 184, 7, 9,
+ 228, 185, 7, 9, 228, 186, 7, 9, 228, 187, 7, 9, 228, 188, 7, 9, 228, 189,
+ 7, 9, 228, 190, 7, 9, 228, 191, 7, 9, 228, 192, 7, 9, 228, 193, 7, 9,
+ 228, 194, 7, 9, 228, 195, 7, 9, 228, 196, 7, 9, 228, 197, 7, 9, 228, 198,
+ 7, 9, 228, 199, 7, 9, 228, 200, 7, 9, 228, 201, 7, 9, 228, 202, 7, 9,
+ 228, 203, 7, 9, 228, 204, 7, 9, 228, 205, 7, 9, 228, 206, 7, 9, 228, 207,
+ 7, 9, 228, 208, 7, 9, 228, 209, 7, 9, 228, 210, 7, 9, 228, 211, 7, 9,
+ 228, 212, 7, 9, 228, 213, 7, 9, 228, 214, 7, 9, 228, 215, 7, 9, 228, 216,
+ 7, 9, 228, 217, 7, 9, 228, 218, 7, 9, 228, 219, 7, 9, 228, 220, 7, 9,
+ 228, 221, 7, 9, 228, 222, 7, 9, 228, 223, 7, 9, 228, 224, 7, 9, 228, 225,
+ 7, 9, 228, 226, 7, 9, 228, 227, 7, 9, 228, 228, 7, 9, 228, 229, 7, 9,
+ 228, 230, 7, 9, 228, 231, 7, 9, 228, 232, 7, 9, 228, 233, 7, 9, 228, 234,
+ 7, 9, 228, 235, 7, 9, 228, 236, 7, 9, 228, 237, 7, 9, 228, 238, 7, 9,
+ 228, 239, 7, 9, 228, 240, 7, 9, 228, 241, 7, 9, 228, 242, 7, 9, 228, 243,
+ 7, 9, 228, 244, 7, 9, 228, 245, 7, 9, 228, 246, 7, 9, 228, 247, 7, 9,
+ 228, 248, 7, 9, 228, 249, 7, 9, 228, 250, 7, 9, 228, 251, 7, 9, 228, 252,
+ 7, 9, 228, 253, 7, 9, 228, 254, 7, 9, 228, 255, 7, 9, 229, 0, 7, 9, 229,
+ 1, 7, 9, 229, 2, 7, 9, 229, 3, 7, 9, 229, 4, 7, 9, 229, 5, 7, 9, 229, 6,
+ 7, 9, 229, 7, 7, 9, 229, 8, 7, 9, 229, 9, 7, 9, 229, 10, 7, 9, 229, 11,
+ 7, 9, 229, 12, 7, 9, 229, 13, 7, 9, 229, 14, 7, 9, 229, 15, 7, 9, 229,
+ 16, 7, 9, 229, 17, 7, 9, 229, 18, 7, 9, 229, 19, 7, 9, 229, 20, 7, 9,
+ 229, 21, 7, 9, 229, 22, 7, 9, 229, 23, 7, 9, 229, 24, 7, 9, 229, 25, 7,
+ 9, 229, 26, 7, 9, 229, 27, 7, 9, 229, 28, 7, 9, 229, 29, 7, 9, 229, 30,
+ 7, 9, 229, 31, 7, 9, 229, 32, 7, 9, 229, 33, 7, 9, 229, 34, 7, 9, 229,
+ 35, 7, 9, 229, 36, 7, 9, 229, 37, 7, 9, 229, 38, 7, 9, 229, 39, 7, 9,
+ 229, 40, 7, 9, 229, 41, 7, 9, 229, 42, 7, 9, 229, 43, 7, 9, 229, 44, 7,
+ 9, 229, 45, 237, 194, 249, 173, 97, 240, 15, 97, 233, 54, 69, 97, 235,
+ 51, 69, 97, 61, 52, 97, 240, 114, 52, 97, 238, 107, 52, 97, 234, 17, 97,
+ 233, 59, 97, 40, 232, 74, 97, 38, 232, 74, 97, 235, 52, 97, 248, 49, 52,
+ 97, 240, 27, 97, 231, 94, 97, 248, 37, 208, 97, 236, 177, 97, 26, 242,
+ 217, 97, 26, 127, 97, 26, 111, 97, 26, 166, 97, 26, 177, 97, 26, 176, 97,
+ 26, 187, 97, 26, 203, 97, 26, 195, 97, 26, 202, 97, 240, 24, 97, 234, 14,
+ 97, 235, 44, 52, 97, 240, 7, 52, 97, 232, 68, 52, 97, 236, 156, 69, 97,
+ 234, 20, 254, 20, 97, 8, 5, 1, 67, 97, 8, 5, 1, 217, 97, 8, 5, 1, 255,
+ 18, 97, 8, 5, 1, 209, 97, 8, 5, 1, 72, 97, 8, 5, 1, 255, 19, 97, 8, 5, 1,
+ 210, 97, 8, 5, 1, 192, 97, 8, 5, 1, 71, 97, 8, 5, 1, 221, 97, 8, 5, 1,
+ 255, 15, 97, 8, 5, 1, 162, 97, 8, 5, 1, 173, 97, 8, 5, 1, 197, 97, 8, 5,
+ 1, 73, 97, 8, 5, 1, 223, 97, 8, 5, 1, 255, 20, 97, 8, 5, 1, 144, 97, 8,
+ 5, 1, 193, 97, 8, 5, 1, 214, 97, 8, 5, 1, 79, 97, 8, 5, 1, 179, 97, 8, 5,
+ 1, 255, 16, 97, 8, 5, 1, 206, 97, 8, 5, 1, 255, 14, 97, 8, 5, 1, 255, 17,
+ 97, 40, 31, 104, 97, 238, 75, 236, 177, 97, 38, 31, 104, 97, 190, 238,
+ 54, 97, 170, 242, 224, 97, 242, 245, 238, 54, 97, 8, 3, 1, 67, 97, 8, 3,
+ 1, 217, 97, 8, 3, 1, 255, 18, 97, 8, 3, 1, 209, 97, 8, 3, 1, 72, 97, 8,
+ 3, 1, 255, 19, 97, 8, 3, 1, 210, 97, 8, 3, 1, 192, 97, 8, 3, 1, 71, 97,
+ 8, 3, 1, 221, 97, 8, 3, 1, 255, 15, 97, 8, 3, 1, 162, 97, 8, 3, 1, 173,
+ 97, 8, 3, 1, 197, 97, 8, 3, 1, 73, 97, 8, 3, 1, 223, 97, 8, 3, 1, 255,
+ 20, 97, 8, 3, 1, 144, 97, 8, 3, 1, 193, 97, 8, 3, 1, 214, 97, 8, 3, 1,
+ 79, 97, 8, 3, 1, 179, 97, 8, 3, 1, 255, 16, 97, 8, 3, 1, 206, 97, 8, 3,
+ 1, 255, 14, 97, 8, 3, 1, 255, 17, 97, 40, 242, 225, 104, 97, 59, 242,
+ 224, 97, 38, 242, 225, 104, 97, 169, 241, 43, 249, 173, 34, 232, 211, 34,
+ 232, 212, 34, 232, 213, 34, 232, 214, 34, 232, 215, 34, 232, 216, 34,
+ 232, 217, 34, 232, 218, 34, 232, 219, 34, 232, 220, 34, 232, 221, 34,
+ 232, 222, 34, 232, 223, 34, 232, 224, 34, 232, 225, 34, 232, 226, 34,
+ 232, 227, 34, 232, 228, 34, 232, 229, 34, 232, 230, 34, 232, 231, 34,
+ 232, 232, 34, 232, 233, 34, 232, 234, 34, 232, 235, 34, 232, 236, 34,
+ 232, 237, 34, 232, 238, 34, 232, 239, 34, 232, 240, 34, 232, 241, 34,
+ 232, 242, 34, 232, 243, 34, 232, 244, 34, 232, 245, 34, 232, 246, 34,
+ 232, 247, 34, 232, 248, 34, 232, 249, 34, 232, 250, 34, 232, 251, 34,
+ 232, 252, 34, 232, 253, 34, 232, 254, 34, 232, 255, 34, 233, 0, 34, 233,
+ 1, 34, 233, 2, 34, 233, 3, 34, 233, 4, 34, 233, 5, 34, 233, 6, 34, 233,
+ 7, 34, 233, 8, 34, 233, 9, 34, 233, 10, 34, 233, 11, 34, 233, 12, 34,
+ 233, 13, 34, 233, 14, 34, 233, 15, 34, 233, 16, 34, 233, 17, 34, 233, 18,
+ 34, 233, 19, 34, 233, 20, 34, 233, 21, 34, 233, 22, 34, 233, 23, 34, 233,
+ 24, 34, 233, 25, 34, 233, 26, 34, 233, 27, 34, 233, 28, 34, 233, 29, 34,
+ 233, 30, 34, 233, 31, 34, 233, 32, 34, 233, 33, 34, 233, 34, 34, 233, 35,
+ 34, 233, 36, 34, 233, 37, 34, 231, 153, 34, 231, 154, 34, 231, 155, 34,
+ 231, 156, 34, 231, 157, 34, 231, 158, 34, 231, 159, 34, 231, 160, 34,
+ 231, 161, 34, 231, 162, 34, 231, 163, 34, 231, 164, 34, 231, 165, 34,
+ 231, 166, 34, 231, 167, 34, 231, 168, 34, 231, 169, 34, 231, 170, 34,
+ 231, 171, 34, 231, 172, 34, 231, 173, 34, 231, 174, 34, 231, 175, 34,
+ 231, 176, 34, 231, 177, 34, 231, 178, 34, 231, 179, 34, 231, 180, 34,
+ 231, 181, 34, 231, 182, 34, 231, 183, 34, 231, 184, 34, 231, 185, 34,
+ 231, 186, 34, 231, 187, 34, 231, 188, 34, 231, 189, 34, 231, 190, 34,
+ 231, 191, 34, 231, 192, 34, 231, 193, 34, 231, 194, 34, 231, 195, 34,
+ 231, 196, 34, 231, 197, 34, 231, 198, 34, 231, 199, 34, 231, 200, 34,
+ 231, 201, 34, 231, 202, 34, 231, 203, 34, 231, 204, 34, 231, 205, 34,
+ 231, 206, 34, 231, 207, 34, 231, 208, 34, 231, 209, 34, 231, 210, 34,
+ 231, 211, 34, 231, 212, 34, 231, 213, 34, 231, 214, 34, 231, 215, 34,
+ 231, 216, 34, 231, 217, 34, 231, 218, 34, 231, 219, 34, 231, 220, 34,
+ 231, 221, 34, 231, 222, 34, 231, 223, 34, 231, 224, 34, 231, 225, 34,
+ 231, 226, 34, 231, 227, 34, 231, 228, 34, 231, 229, 34, 231, 230, 34,
+ 231, 231, 34, 231, 232, 34, 231, 233, 34, 231, 234, 34, 231, 235, 34,
+ 231, 236, 34, 231, 237, 34, 231, 238, 34, 231, 239, 34, 231, 240, 34,
+ 231, 241, 34, 231, 242, 34, 231, 243, 34, 231, 244, 34, 231, 245, 34,
+ 231, 246, 34, 231, 247, 34, 231, 248, 34, 231, 249, 34, 231, 250, 34,
+ 231, 251, 34, 231, 252, 34, 231, 253, 34, 231, 254, 34, 231, 255, 34,
+ 232, 0, 34, 232, 1, 34, 232, 2, 34, 232, 3, 34, 232, 4, 34, 232, 5, 34,
+ 232, 6, 34, 232, 7, 34, 232, 8, 34, 232, 9, 34, 232, 10, 34, 232, 11, 34,
+ 232, 12, 34, 232, 13, 34, 232, 14, 34, 232, 15, 34, 232, 16, 34, 232, 17,
+ 34, 232, 18, 34, 232, 19, 34, 232, 20, 34, 232, 21, 34, 232, 22, 34, 232,
+ 23, 34, 232, 24, 34, 232, 25, 34, 232, 26, 34, 232, 27, 34, 232, 28, 34,
+ 232, 29, 34, 232, 30, 34, 232, 31, 34, 232, 32, 34, 232, 33, 34, 232, 34,
+ 34, 232, 35, 34, 232, 36, 34, 232, 37, 34, 232, 38, 34, 232, 39, 34, 232,
+ 40, 34, 232, 41, 34, 232, 42, 34, 232, 43, 34, 232, 44, 34, 232, 45, 34,
+ 232, 46, 34, 232, 47, 34, 232, 48, 34, 232, 49, 34, 232, 50, 34, 232, 51,
+ 34, 232, 52, 34, 232, 53,
+};
+
+static unsigned char phrasebook_offset1[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 16, 16, 16, 16,
+ 16, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 16, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 16, 16, 16, 16, 108, 16, 109, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 110, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 16, 16, 128,
+ 129, 130, 131, 16, 16, 16, 16, 16, 16, 132, 16, 16, 16, 133, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 134, 135, 136,
+ 137, 138, 16, 139, 16, 140, 141, 142, 143, 144, 145, 146, 147, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 148, 149,
+ 150, 151, 152, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 153, 16, 154, 155,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16,
+};
+
+static unsigned int phrasebook_offset2[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 32,
+ 34, 36, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72,
+ 75, 78, 82, 86, 90, 95, 99, 103, 108, 112, 116, 120, 124, 129, 133, 137,
+ 141, 145, 149, 154, 158, 162, 166, 170, 174, 179, 183, 188, 193, 196,
+ 200, 203, 206, 209, 213, 217, 221, 226, 230, 234, 239, 243, 247, 251,
+ 255, 260, 264, 268, 272, 276, 280, 285, 289, 293, 297, 301, 305, 310,
+ 314, 319, 324, 328, 331, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 340, 345,
+ 348, 351, 354, 357, 360, 363, 364, 367, 373, 380, 382, 386, 389, 390,
+ 393, 396, 399, 402, 406, 409, 412, 416, 418, 421, 427, 434, 442, 450,
+ 457, 462, 468, 474, 481, 487, 493, 501, 506, 514, 520, 526, 533, 539,
+ 545, 551, 558, 564, 569, 576, 582, 588, 595, 601, 607, 610, 616, 622,
+ 628, 635, 641, 648, 653, 659, 665, 671, 678, 684, 690, 698, 703, 711,
+ 717, 723, 730, 736, 742, 748, 755, 761, 766, 773, 779, 785, 792, 798,
+ 804, 807, 813, 819, 825, 832, 838, 845, 850, 857, 863, 869, 876, 883,
+ 890, 897, 904, 911, 919, 927, 935, 943, 951, 959, 967, 975, 982, 989,
+ 995, 1001, 1008, 1015, 1022, 1029, 1036, 1043, 1050, 1057, 1065, 1073,
+ 1081, 1089, 1097, 1105, 1113, 1121, 1129, 1137, 1144, 1151, 1157, 1163,
+ 1169, 1175, 1182, 1189, 1196, 1203, 1210, 1216, 1221, 1226, 1234, 1242,
+ 1250, 1258, 1263, 1270, 1277, 1285, 1293, 1301, 1309, 1319, 1329, 1336,
+ 1343, 1350, 1357, 1365, 1373, 1381, 1389, 1400, 1405, 1410, 1416, 1422,
+ 1429, 1436, 1443, 1450, 1455, 1460, 1467, 1474, 1482, 1490, 1498, 1506,
+ 1513, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592, 1600,
+ 1607, 1614, 1620, 1626, 1632, 1638, 1645, 1652, 1660, 1668, 1675, 1682,
+ 1689, 1696, 1704, 1712, 1720, 1728, 1735, 1742, 1749, 1757, 1765, 1773,
+ 1781, 1786, 1792, 1798, 1805, 1812, 1817, 1822, 1828, 1835, 1842, 1848,
+ 1855, 1863, 1871, 1877, 1882, 1887, 1893, 1900, 1907, 1914, 1919, 1924,
+ 1929, 1935, 1942, 1949, 1956, 1963, 1968, 1976, 1986, 1994, 2001, 2008,
+ 2013, 2018, 2025, 2032, 2036, 2041, 2046, 2051, 2058, 2067, 2074, 2081,
+ 2090, 2097, 2104, 2109, 2116, 2123, 2130, 2137, 2144, 2149, 2156, 2163,
+ 2171, 2176, 2181, 2186, 2196, 2200, 2206, 2212, 2218, 2224, 2232, 2245,
+ 2253, 2258, 2267, 2272, 2277, 2286, 2291, 2298, 2305, 2312, 2319, 2326,
+ 2333, 2340, 2347, 2356, 2365, 2374, 2383, 2393, 2403, 2412, 2421, 2426,
+ 2435, 2444, 2453, 2462, 2469, 2476, 2483, 2490, 2498, 2506, 2514, 2522,
+ 2529, 2536, 2545, 2554, 2562, 2570, 2578, 2583, 2593, 2598, 2605, 2612,
+ 2617, 2622, 2629, 2636, 2646, 2656, 2663, 2670, 2679, 2688, 2695, 2702,
+ 2711, 2720, 2727, 2734, 2743, 2752, 2759, 2766, 2775, 2784, 2791, 2798,
+ 2807, 2816, 2824, 2832, 2842, 2852, 2859, 2866, 2875, 2884, 2893, 2902,
+ 2911, 2920, 2925, 2930, 2938, 2946, 2956, 2964, 2969, 2974, 2981, 2988,
+ 2995, 3002, 3009, 3016, 3025, 3034, 3043, 3052, 3059, 3066, 3075, 3084,
+ 3091, 3098, 3106, 3114, 3122, 3128, 3135, 3142, 3148, 3155, 3162, 3169,
+ 3178, 3188, 3198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3204, 3209,
+ 3214, 3220, 3226, 3232, 3240, 3248, 3255, 3260, 3265, 3272, 3278, 3285,
+ 3294, 3303, 3312, 3319, 3324, 3329, 3334, 3341, 3346, 3353, 3360, 3366,
+ 3371, 3376, 3385, 3393, 3402, 3407, 3412, 3422, 3429, 3437, 3446, 3451,
+ 3457, 3463, 3470, 3475, 3480, 3490, 3498, 3507, 3515, 3523, 3532, 3537,
+ 3544, 3551, 3556, 3568, 3576, 3584, 3589, 3598, 3603, 3608, 3615, 3620,
+ 3626, 3632, 3638, 3647, 3655, 3660, 3668, 3673, 3681, 3688, 3694, 3700,
+ 3705, 3713, 3721, 3726, 3734, 3740, 3745, 3752, 3760, 3769, 3776, 3783,
+ 3793, 3800, 3807, 3817, 3824, 3831, 3838, 3844, 3850, 3859, 3871, 3875,
+ 3882, 3886, 3890, 3895, 3903, 3910, 3915, 3920, 3924, 3929, 3934, 3938,
+ 3943, 3949, 3955, 3960, 3966, 3971, 3976, 3981, 3986, 3991, 3993, 3998,
+ 4001, 4007, 4013, 4019, 4023, 4030, 4037, 4043, 4050, 4058, 4066, 4071,
+ 4076, 4081, 4086, 4088, 4090, 4093, 4095, 4097, 4102, 4107, 4113, 4118,
+ 4122, 4126, 4130, 4137, 4143, 4148, 4154, 4159, 4165, 4173, 4181, 4185,
+ 4189, 4194, 4200, 4206, 4212, 4218, 4223, 4231, 4240, 4249, 4253, 4259,
+ 4266, 4273, 4280, 4287, 4291, 4297, 4302, 4307, 4312, 4316, 4318, 4320,
+ 4323, 4326, 4329, 4331, 4335, 4339, 4345, 4348, 4353, 4359, 4365, 4368,
+ 4373, 4378, 4382, 4387, 4392, 4398, 4404, 4409, 4414, 4418, 4421, 4427,
+ 4432, 4437, 4442, 4447, 4453, 4459, 4462, 4466, 4470, 4474, 4477, 4480,
+ 4485, 4489, 4496, 4500, 4505, 4509, 4515, 4519, 4523, 4527, 4532, 4537,
+ 4544, 4550, 4557, 4563, 4569, 4575, 4578, 4582, 4586, 4589, 4593, 4598,
+ 4603, 4607, 4611, 4617, 4621, 4625, 4630, 4636, 4640, 4645, 4649, 4655,
+ 4660, 4665, 4670, 4675, 4681, 4684, 4688, 4693, 4698, 4707, 4713, 4717,
+ 4721, 4726, 4730, 4735, 4739, 4742, 4747, 4750, 4756, 4761, 4766, 4771,
+ 4776, 4781, 4786, 4792, 4797, 4802, 4807, 4812, 4817, 4822, 0, 0, 0, 0,
+ 4827, 4830, 0, 0, 0, 0, 4834, 0, 0, 0, 4837, 0, 0, 0, 0, 0, 4841, 4844,
+ 4849, 4856, 4861, 4869, 4877, 0, 4885, 0, 4893, 4901, 4908, 4919, 4924,
+ 4929, 4934, 4939, 4944, 4949, 4954, 4959, 4964, 4969, 4974, 4979, 4984,
+ 4989, 4994, 4999, 0, 5004, 5009, 5014, 5019, 5024, 5029, 5034, 5039,
+ 5047, 5055, 5062, 5070, 5078, 5086, 5097, 5102, 5107, 5112, 5117, 5122,
+ 5127, 5132, 5137, 5142, 5147, 5152, 5157, 5162, 5167, 5172, 5177, 5182,
+ 5188, 5193, 5198, 5203, 5208, 5213, 5218, 5223, 5231, 5239, 5247, 5255,
+ 0, 5262, 5266, 5270, 5277, 5287, 5297, 5301, 5305, 5309, 5315, 5322,
+ 5326, 5331, 5335, 5340, 5344, 5349, 5353, 5358, 5363, 5368, 5373, 5378,
+ 5383, 5388, 5393, 5398, 5403, 5408, 5413, 5418, 5423, 5428, 5432, 5436,
+ 5442, 5446, 5451, 5457, 5464, 5469, 5474, 5481, 5486, 5491, 5498, 5506,
+ 5515, 5525, 5532, 5537, 5542, 5547, 5554, 5559, 5565, 5570, 5575, 5580,
+ 5585, 5590, 5595, 5601, 5607, 5612, 5616, 5621, 5626, 5631, 5636, 5641,
+ 5646, 5651, 5655, 5661, 5665, 5670, 5675, 5680, 5684, 5689, 5694, 5699,
+ 5704, 5708, 5713, 5717, 5722, 5727, 5732, 5737, 5743, 5748, 5754, 5758,
+ 5763, 5767, 5771, 5776, 5781, 5786, 5791, 5796, 5801, 5806, 5810, 5816,
+ 5820, 5825, 5830, 5835, 5839, 5844, 5849, 5854, 5859, 5863, 5868, 5872,
+ 5877, 5882, 5887, 5892, 5898, 5903, 5909, 5913, 5918, 5922, 5929, 5934,
+ 5939, 5944, 5951, 5956, 5962, 5967, 5972, 5977, 5982, 5987, 5992, 5998,
+ 6004, 6009, 6014, 6019, 6024, 6029, 6035, 6041, 6048, 6055, 6064, 6073,
+ 6080, 6087, 6096, 6105, 6110, 6115, 6120, 6125, 6130, 6135, 6140, 6145,
+ 6156, 6167, 6172, 6177, 6184, 6191, 6198, 6205, 6210, 6215, 6220, 6225,
+ 6229, 6233, 6237, 6242, 0, 6247, 6254, 6259, 6268, 6277, 6283, 6289,
+ 6297, 6305, 6313, 6321, 6328, 6335, 6344, 6353, 6361, 6369, 6377, 6385,
+ 6393, 6401, 6409, 6417, 6424, 6431, 6437, 6443, 6451, 6459, 6466, 6473,
+ 6482, 6491, 6497, 6503, 6511, 6519, 6527, 6535, 6541, 6547, 6555, 6563,
+ 6571, 6579, 6586, 6593, 6601, 6609, 6617, 6625, 6630, 6635, 6642, 6649,
+ 6659, 6669, 6673, 6681, 6689, 6696, 6703, 6711, 6719, 6726, 6733, 6741,
+ 6749, 6756, 6763, 6771, 0, 6779, 6786, 6793, 6799, 6805, 6811, 6817,
+ 6825, 6833, 6838, 6843, 6850, 6857, 6864, 6871, 6878, 6885, 6892, 6899,
+ 6905, 6911, 6917, 6923, 6929, 6935, 6941, 6947, 6955, 6963, 6969, 6975,
+ 6981, 6987, 6993, 6999, 7006, 7013, 7020, 7027, 7035, 7043, 7050, 0, 0,
+ 0, 0, 0, 0, 7057, 7064, 7071, 7078, 7085, 7092, 7099, 7106, 7113, 7120,
+ 7127, 7134, 7141, 7148, 7155, 7162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7169,
+ 7174, 7179, 7184, 7189, 7194, 7199, 7204, 7209, 7213, 7218, 7223, 7228,
+ 7233, 7238, 7243, 7248, 7253, 7258, 7263, 7268, 7273, 7278, 7283, 7288,
+ 7293, 7298, 7303, 7308, 7313, 7318, 7323, 7328, 7333, 7338, 7343, 7348,
+ 7353, 0, 0, 7358, 7365, 7368, 7372, 7376, 7379, 7383, 0, 7387, 7392,
+ 7397, 7402, 7407, 7412, 7417, 7422, 7427, 7431, 7436, 7441, 7446, 7451,
+ 7456, 7461, 7466, 7471, 7476, 7481, 7486, 7491, 7496, 7501, 7506, 7511,
+ 7516, 7521, 7526, 7531, 7536, 7541, 7546, 7551, 7556, 7561, 7566, 7571,
+ 7576, 0, 7583, 7587, 0, 0, 0, 0, 0, 0, 7590, 7595, 7600, 7605, 7612,
+ 7619, 7624, 7629, 7634, 7639, 7644, 7649, 7654, 7661, 7666, 7673, 7680,
+ 7685, 7692, 7697, 7702, 7707, 7714, 7719, 7724, 7731, 7740, 7745, 7750,
+ 7755, 7760, 7766, 7771, 7778, 7785, 7792, 7797, 7802, 7807, 7812, 7817,
+ 0, 7822, 7827, 7835, 7840, 7845, 7850, 7855, 7862, 7869, 7876, 7881,
+ 7886, 7893, 0, 0, 0, 0, 0, 0, 0, 0, 7900, 7904, 7908, 7912, 7916, 7920,
+ 7924, 7928, 7932, 7936, 7940, 7945, 7949, 7953, 7958, 7962, 7967, 7971,
+ 7975, 7979, 7984, 7988, 7993, 7997, 8001, 8005, 8009, 0, 0, 0, 0, 0,
+ 8013, 8020, 8028, 8035, 8040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8045,
+ 8048, 8052, 8057, 0, 0, 0, 0, 0, 0, 0, 8061, 8064, 8067, 8072, 8078,
+ 8082, 8090, 8096, 8102, 8110, 8114, 0, 0, 0, 0, 0, 8119, 0, 0, 8122,
+ 8129, 0, 8133, 8137, 8144, 8150, 8157, 8163, 8169, 8173, 8177, 8183,
+ 8187, 8191, 8195, 8199, 8203, 8207, 8211, 8215, 8219, 8223, 8227, 8231,
+ 8235, 8239, 8243, 8247, 0, 0, 0, 0, 0, 8251, 8254, 8258, 8262, 8266,
+ 8270, 8274, 8278, 8282, 8286, 8291, 8295, 8298, 8301, 8304, 8307, 8310,
+ 8313, 8316, 8319, 8323, 8326, 8329, 8334, 8339, 8344, 8347, 8354, 8363,
+ 8368, 8372, 0, 8379, 8384, 8388, 8392, 8396, 8400, 8404, 8408, 8412,
+ 8416, 8420, 8424, 8429, 8434, 8441, 8447, 8453, 8459, 8464, 8472, 8480,
+ 8485, 8491, 8497, 8503, 8509, 8513, 8517, 8521, 8528, 8538, 8542, 8546,
+ 8550, 8556, 8564, 8568, 8572, 8579, 8583, 8587, 8591, 8598, 8605, 8617,
+ 8621, 8625, 8629, 8639, 8648, 8652, 8659, 8666, 8673, 8682, 8693, 8701,
+ 8705, 8714, 8725, 8733, 8746, 8754, 8762, 8770, 8778, 8784, 8793, 8800,
+ 8804, 8812, 8816, 8823, 8831, 8835, 8841, 8848, 8855, 8859, 8867, 8871,
+ 8878, 8882, 8890, 8894, 8902, 8908, 8914, 8921, 8928, 8934, 8939, 8943,
+ 8949, 8956, 8962, 8969, 8976, 8982, 8991, 8999, 9006, 9012, 9016, 9019,
+ 9023, 9029, 9037, 9041, 9047, 9053, 9059, 9066, 9069, 9076, 9081, 9089,
+ 9093, 9097, 9109, 9121, 9127, 9133, 9138, 9144, 9149, 9155, 9165, 9172,
+ 9181, 9191, 9197, 9202, 9207, 9211, 9215, 9220, 9225, 9231, 9238, 9245,
+ 9256, 9261, 9269, 9277, 9284, 9290, 9296, 9302, 9308, 9314, 9320, 9326,
+ 9332, 9338, 9345, 9352, 9359, 9365, 9373, 9381, 9387, 9393, 9399, 9404,
+ 9409, 9413, 9420, 9426, 9435, 9443, 9446, 9451, 9456, 0, 9461, 9465,
+ 9469, 9475, 9479, 9483, 9489, 9493, 9501, 9505, 9509, 9513, 9517, 9521,
+ 9527, 9531, 9537, 9541, 9545, 9549, 9553, 9557, 9562, 9565, 9569, 9574,
+ 9578, 9582, 9586, 9590, 9594, 9599, 9604, 9609, 9613, 9617, 9622, 9626,
+ 9630, 9635, 9639, 9643, 9650, 9657, 9661, 9665, 9670, 9674, 9678, 9681,
+ 9686, 9689, 9692, 9697, 9702, 9706, 9710, 9716, 9722, 9725, 0, 0, 9728,
+ 9734, 9740, 9746, 9756, 9768, 9780, 9797, 9809, 9820, 9827, 9834, 9845,
+ 9860, 9871, 9877, 9886, 9894, 9906, 9916, 9924, 9936, 9943, 9951, 9963,
+ 9969, 9975, 9982, 9989, 9995, 10000, 10010, 10017, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10027, 10031, 10035, 10039, 10043,
+ 10047, 10051, 10055, 10059, 10063, 10067, 10071, 10075, 10079, 10083,
+ 10087, 10091, 10095, 10099, 10103, 10107, 10111, 10115, 10119, 10123,
+ 10127, 10131, 10135, 10139, 10143, 10147, 10151, 10155, 10158, 10162,
+ 10166, 10170, 10174, 10178, 10181, 10184, 10187, 10190, 10193, 10196,
+ 10199, 10202, 10205, 10208, 10211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10215, 10219, 10223, 10227, 10232, 10235, 10239, 10242, 10246,
+ 10249, 10253, 10257, 10261, 10266, 10271, 10274, 10278, 10283, 10288,
+ 10291, 10295, 10298, 10302, 10306, 10310, 10314, 10318, 10322, 10326,
+ 10330, 10334, 10338, 10342, 10346, 10350, 10354, 10358, 10362, 10366,
+ 10370, 10374, 10378, 10382, 10386, 10390, 10394, 10397, 10400, 10404,
+ 10408, 10412, 10416, 10420, 10424, 10428, 10432, 10436, 0, 0, 10439,
+ 10443, 10447, 10452, 10456, 10461, 10465, 10470, 10475, 10481, 10487,
+ 10493, 10497, 10502, 10508, 10514, 10518, 10523, 0, 0, 10527, 10530,
+ 10536, 10542, 10547, 0, 0, 0, 10552, 10556, 10560, 10564, 10568, 10572,
+ 10576, 10580, 10584, 10589, 10594, 10599, 10605, 10608, 10612, 10616,
+ 10619, 10622, 10625, 10628, 10631, 10634, 10637, 10640, 10643, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10647, 0, 0, 0, 10652, 10656, 10660, 0, 10664,
+ 10667, 10671, 10674, 10678, 10681, 10685, 10689, 0, 0, 10693, 10696, 0,
+ 0, 10700, 10703, 10707, 10710, 10714, 10718, 10722, 10726, 10730, 10734,
+ 10738, 10742, 10746, 10750, 10754, 10758, 10762, 10766, 10770, 10774,
+ 10778, 10782, 0, 10786, 10790, 10794, 10798, 10802, 10805, 10808, 0,
+ 10812, 0, 0, 0, 10816, 10820, 10824, 10828, 0, 0, 10831, 10835, 10839,
+ 10844, 10848, 10853, 10857, 10862, 10867, 0, 0, 10873, 10877, 0, 0,
+ 10882, 10886, 10891, 10895, 0, 0, 0, 0, 0, 0, 0, 0, 10901, 0, 0, 0, 0,
+ 10907, 10911, 0, 10915, 10919, 10924, 10929, 10934, 0, 0, 10940, 10944,
+ 10947, 10950, 10953, 10956, 10959, 10962, 10965, 10968, 10971, 10980,
+ 10988, 10992, 10996, 11002, 11008, 11014, 11020, 11035, 11042, 0, 0, 0,
+ 0, 0, 0, 11045, 11051, 11055, 0, 11059, 11062, 11066, 11069, 11073,
+ 11076, 0, 0, 0, 0, 11080, 11084, 0, 0, 11088, 11092, 11096, 11099, 11103,
+ 11107, 11111, 11115, 11119, 11123, 11127, 11131, 11135, 11139, 11143,
+ 11147, 11151, 11155, 11159, 11163, 11167, 11171, 0, 11175, 11179, 11183,
+ 11187, 11191, 11194, 11197, 0, 11201, 11205, 0, 11209, 11213, 0, 11217,
+ 11221, 0, 0, 11224, 0, 11228, 11233, 11237, 11242, 11246, 0, 0, 0, 0,
+ 11251, 11256, 0, 0, 11261, 11266, 11271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 11275, 11279, 11283, 11287, 0, 11291, 0, 0, 0, 0, 0, 0, 0, 11295, 11299,
+ 11302, 11305, 11308, 11311, 11314, 11317, 11320, 11323, 11326, 11329,
+ 11332, 11335, 11338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11343, 11347,
+ 11351, 0, 11355, 11358, 11362, 11365, 11369, 11372, 11376, 11380, 11384,
+ 0, 11389, 11392, 11396, 0, 11401, 11404, 11408, 11411, 11415, 11419,
+ 11423, 11427, 11431, 11435, 11439, 11443, 11447, 11451, 11455, 11459,
+ 11463, 11467, 11471, 11475, 11479, 11483, 0, 11487, 11491, 11495, 11499,
+ 11503, 11506, 11509, 0, 11513, 11517, 0, 11521, 11525, 11529, 11533,
+ 11537, 0, 0, 11540, 11544, 11548, 11553, 11557, 11562, 11566, 11571,
+ 11576, 11582, 0, 11588, 11592, 11597, 0, 11603, 11607, 11612, 0, 0,
+ 11616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11619, 11624, 11629,
+ 11634, 0, 0, 11640, 11644, 11647, 11650, 11653, 11656, 11659, 11662,
+ 11665, 11668, 0, 11671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 11675, 11679, 11683, 0, 11687, 11690, 11694, 11697, 11701, 11704, 11708,
+ 11712, 0, 0, 11716, 11719, 0, 0, 11723, 11726, 11730, 11733, 11737,
+ 11741, 11745, 11749, 11753, 11757, 11761, 11765, 11769, 11773, 11777,
+ 11781, 11785, 11789, 11793, 11797, 11801, 11805, 0, 11809, 11813, 11817,
+ 11821, 11825, 11828, 11831, 0, 11835, 11839, 0, 11843, 11847, 11851,
+ 11855, 11859, 0, 0, 11862, 11866, 11870, 11875, 11879, 11884, 11888,
+ 11893, 0, 0, 0, 11898, 11902, 0, 0, 11907, 11911, 11916, 0, 0, 0, 0, 0,
+ 0, 0, 0, 11920, 11926, 0, 0, 0, 0, 11932, 11936, 0, 11940, 11944, 11949,
+ 0, 0, 0, 0, 11954, 11958, 11961, 11964, 11967, 11970, 11973, 11976,
+ 11979, 11982, 11985, 11988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 11992, 11996, 0, 12000, 12003, 12007, 12010, 12014, 12017, 0, 0, 0,
+ 12021, 12024, 12028, 0, 12032, 12035, 12039, 12043, 0, 0, 0, 12046,
+ 12050, 0, 12054, 0, 12058, 12062, 0, 0, 0, 12066, 12070, 0, 0, 0, 12074,
+ 12078, 12082, 0, 0, 0, 12086, 12089, 12092, 12096, 12100, 12104, 12108,
+ 12112, 12116, 12120, 12124, 12128, 0, 0, 0, 0, 12131, 12136, 12140,
+ 12145, 12149, 0, 0, 0, 12154, 12158, 12163, 0, 12168, 12172, 12177,
+ 12182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12192, 12196, 12199, 12202, 12205, 12208, 12211, 12214, 12217,
+ 12220, 12223, 12227, 12233, 12239, 12243, 12247, 12251, 12255, 12259,
+ 12264, 12268, 0, 0, 0, 0, 0, 0, 12271, 12275, 12279, 0, 12283, 12286,
+ 12290, 12293, 12297, 12300, 12304, 12308, 0, 12312, 12315, 12319, 0,
+ 12323, 12326, 12330, 12334, 12337, 12341, 12345, 12349, 12353, 12357,
+ 12361, 12365, 12369, 12373, 12377, 12381, 12385, 12389, 12393, 12397,
+ 12401, 12405, 12409, 0, 12413, 12417, 12421, 12425, 12429, 12432, 12435,
+ 12439, 12443, 12447, 0, 12451, 12455, 12459, 12463, 12467, 0, 0, 0, 0,
+ 12470, 12475, 12479, 12484, 12488, 12493, 12498, 0, 12504, 12508, 12513,
+ 0, 12518, 12522, 12527, 12532, 0, 0, 0, 0, 0, 0, 0, 12536, 12540, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12546, 12551, 0, 0, 0, 0, 12556, 12560, 12563,
+ 12566, 12569, 12572, 12575, 12578, 12581, 12584, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12587, 12591, 0, 12595, 12598, 12602,
+ 12605, 12609, 12612, 12616, 12620, 0, 12624, 12627, 12631, 0, 12635,
+ 12638, 12642, 12646, 12649, 12653, 12657, 12661, 12665, 12669, 12673,
+ 12677, 12681, 12685, 12689, 12693, 12697, 12701, 12705, 12709, 12713,
+ 12717, 12721, 0, 12725, 12729, 12733, 12737, 12741, 12744, 12747, 12751,
+ 12755, 12759, 0, 12763, 12767, 12771, 12775, 12779, 0, 0, 12782, 12786,
+ 12790, 12795, 12799, 12804, 12808, 12813, 12818, 0, 12824, 12828, 12833,
+ 0, 12838, 12842, 12847, 12852, 0, 0, 0, 0, 0, 0, 0, 12856, 12860, 0, 0,
+ 0, 0, 0, 0, 0, 12866, 0, 12870, 12875, 0, 0, 0, 0, 12880, 12884, 12887,
+ 12890, 12893, 12896, 12899, 12902, 12905, 12908, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12911, 12915, 0, 12919, 12922, 12926,
+ 12929, 12933, 12936, 12940, 12944, 0, 12948, 12951, 12955, 0, 12959,
+ 12962, 12966, 12970, 12973, 12977, 12981, 12985, 12989, 12993, 12997,
+ 13001, 13005, 13009, 13013, 13017, 13021, 13025, 13029, 13033, 13037,
+ 13041, 13045, 0, 13049, 13053, 13057, 13061, 13065, 13068, 13071, 13075,
+ 13079, 13083, 13087, 13091, 13095, 13099, 13103, 13107, 0, 0, 0, 0,
+ 13110, 13115, 13119, 13124, 13128, 13133, 0, 0, 13138, 13142, 13147, 0,
+ 13152, 13156, 13161, 13166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13170, 0, 0, 0, 0,
+ 0, 0, 0, 0, 13176, 13181, 0, 0, 0, 0, 13186, 13190, 13193, 13196, 13199,
+ 13202, 13205, 13208, 13211, 13214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13217, 13221, 0, 13225, 13229, 13233, 13237, 13241, 13245,
+ 13249, 13253, 13257, 13261, 13265, 13269, 13273, 13277, 13281, 13285,
+ 13289, 13293, 0, 0, 0, 13297, 13303, 13309, 13315, 13321, 13327, 13333,
+ 13339, 13345, 13351, 13357, 13363, 13371, 13377, 13383, 13389, 13395,
+ 13401, 13407, 13413, 13419, 13425, 13431, 13437, 0, 13443, 13449, 13455,
+ 13461, 13467, 13473, 13477, 13483, 13487, 0, 13491, 0, 0, 13497, 13501,
+ 13507, 13513, 13519, 13523, 13529, 0, 0, 0, 13533, 0, 0, 0, 0, 13537,
+ 13542, 13549, 13556, 13563, 13570, 0, 13577, 0, 13584, 13589, 13594,
+ 13601, 13608, 13617, 13628, 13637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13642, 13649, 13656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13661, 13667, 13673, 13679, 13685, 13691, 13697, 13703, 13709, 13715,
+ 13721, 13727, 13733, 13739, 13745, 13750, 13756, 13762, 13768, 13774,
+ 13780, 13785, 13791, 13797, 13803, 13809, 13815, 13821, 13827, 13833,
+ 13839, 13845, 13851, 13856, 13862, 13868, 13872, 13878, 13882, 13888,
+ 13894, 13900, 13906, 13912, 13918, 13923, 13929, 13933, 13938, 13944,
+ 13950, 13956, 13961, 13967, 13973, 13979, 13984, 13990, 0, 0, 0, 0,
+ 13994, 14000, 14005, 14011, 14016, 14024, 14032, 14036, 14040, 14044,
+ 14050, 14056, 14062, 14068, 14072, 14076, 14080, 14084, 14088, 14091,
+ 14094, 14097, 14100, 14103, 14106, 14109, 14112, 14115, 14119, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14123, 14127, 0, 14133, 0, 0, 14139, 14143,
+ 0, 14147, 0, 0, 14153, 0, 0, 0, 0, 0, 0, 14157, 14161, 14164, 14170, 0,
+ 14176, 14180, 14184, 14188, 14194, 14200, 14206, 0, 14212, 14216, 14220,
+ 0, 14226, 0, 14232, 0, 0, 14236, 14242, 0, 14248, 14251, 14257, 14260,
+ 14264, 14271, 14276, 14281, 14285, 14290, 14295, 14300, 14304, 0, 14309,
+ 14316, 14322, 0, 0, 14328, 14332, 14337, 14341, 14346, 0, 14351, 0,
+ 14356, 14362, 14368, 14374, 14380, 14384, 0, 0, 14387, 14391, 14394,
+ 14397, 14400, 14403, 14406, 14409, 14412, 14415, 0, 0, 14418, 14423, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14428, 14432, 14443, 14458, 14473, 14483,
+ 14494, 14507, 14518, 14524, 14532, 14542, 14548, 14556, 14560, 14566,
+ 14572, 14580, 14590, 14598, 14611, 14617, 14625, 14633, 14645, 14653,
+ 14661, 14669, 14677, 14685, 14693, 14701, 14711, 14715, 14718, 14721,
+ 14724, 14727, 14730, 14733, 14736, 14739, 14742, 14746, 14750, 14754,
+ 14758, 14762, 14766, 14770, 14774, 14778, 14783, 14789, 14799, 14813,
+ 14823, 14829, 14835, 14843, 14851, 14859, 14867, 14873, 14879, 14882,
+ 14886, 14890, 14894, 14898, 14902, 14906, 0, 14910, 14914, 14918, 14922,
+ 14926, 14930, 14934, 14938, 14942, 14946, 14950, 14954, 14958, 14962,
+ 14966, 14970, 14973, 14977, 14981, 14985, 14989, 14993, 14997, 15001,
+ 15005, 15008, 15012, 15016, 15020, 15024, 15028, 15031, 15034, 15038, 0,
+ 0, 0, 0, 0, 0, 15044, 15049, 15053, 15058, 15062, 15067, 15072, 15078,
+ 15083, 15089, 15093, 15098, 15102, 15107, 15117, 15123, 15128, 15134,
+ 15144, 15150, 15154, 15158, 15164, 15170, 15178, 15184, 15192, 0, 0, 0,
+ 0, 15200, 15204, 15209, 15214, 15219, 15224, 15229, 15234, 0, 15239,
+ 15244, 15249, 15254, 15259, 15264, 15269, 15274, 15279, 15284, 15289,
+ 15294, 15299, 15304, 15309, 15314, 15318, 15323, 15328, 15333, 15338,
+ 15343, 15348, 15353, 15358, 15362, 15367, 15372, 15377, 15382, 15387,
+ 15391, 15395, 15400, 15407, 15413, 0, 15420, 15427, 15440, 15447, 15454,
+ 15462, 15470, 15476, 15482, 15488, 15498, 15504, 15510, 15520, 15530, 0,
+ 0, 15540, 15548, 15560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 15572, 15575, 15579, 15583, 15587, 15591, 15595, 15599,
+ 15603, 15607, 15611, 15615, 15619, 15623, 15627, 15631, 15635, 15639,
+ 15643, 15647, 15651, 15655, 15659, 15663, 15667, 15671, 15674, 15677,
+ 15681, 15685, 15689, 15693, 15696, 15700, 0, 15703, 15706, 15710, 15713,
+ 15717, 0, 15720, 15723, 0, 15727, 15732, 15736, 15741, 15745, 15750,
+ 15754, 0, 0, 0, 15759, 15763, 15767, 15771, 0, 0, 0, 0, 0, 0, 15775,
+ 15779, 15782, 15785, 15788, 15791, 15794, 15797, 15800, 15803, 15806,
+ 15812, 15816, 15820, 15824, 15828, 15832, 15836, 15840, 15844, 15849,
+ 15853, 15858, 15863, 15869, 15874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15880, 15885, 15890, 15895, 15900, 15905,
+ 15910, 15915, 15920, 15925, 15930, 15935, 15940, 15945, 15950, 15955,
+ 15960, 15965, 15970, 15975, 15980, 15985, 15990, 15995, 16000, 16005,
+ 16010, 16015, 16020, 16025, 16030, 16035, 16040, 16045, 16050, 16055,
+ 16060, 16065, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16070, 16074, 16078, 16082,
+ 16086, 16090, 16094, 16098, 16102, 16106, 16110, 16114, 16118, 16122,
+ 16126, 16130, 16134, 16138, 16142, 16146, 16150, 16154, 16158, 16162,
+ 16166, 16170, 16174, 16178, 16182, 16186, 16190, 16194, 16198, 16202,
+ 16206, 16210, 16214, 16218, 16222, 16226, 16230, 16234, 16239, 16243,
+ 16248, 0, 0, 0, 16253, 16257, 16261, 16265, 16269, 16273, 16277, 16281,
+ 16285, 16289, 16293, 16297, 16301, 16305, 16309, 16313, 16317, 16321,
+ 16325, 16329, 16333, 16337, 16341, 16345, 16349, 16353, 16357, 16361,
+ 16365, 16369, 16373, 16377, 16381, 16385, 16389, 16393, 16397, 16401,
+ 16405, 16409, 16413, 16417, 16421, 16425, 16429, 16433, 16437, 16441,
+ 16445, 16449, 16453, 16457, 16461, 16465, 16469, 16473, 16477, 16481,
+ 16485, 16489, 16493, 16497, 16501, 16505, 16509, 16513, 16517, 16521,
+ 16525, 16529, 16533, 16537, 16541, 16545, 16549, 16553, 16557, 16561,
+ 16565, 16569, 16573, 16577, 16581, 16585, 16589, 16593, 16597, 16601,
+ 16605, 16609, 0, 0, 0, 0, 0, 16613, 16617, 16621, 16624, 16628, 16631,
+ 16635, 16639, 16642, 16646, 16650, 16653, 16657, 16661, 16665, 16669,
+ 16672, 16676, 16680, 16684, 16688, 16692, 16696, 16699, 16703, 16707,
+ 16711, 16715, 16719, 16723, 16727, 16731, 16735, 16739, 16743, 16747,
+ 16751, 16755, 16759, 16763, 16767, 16771, 16775, 16779, 16783, 16787,
+ 16791, 16795, 16799, 16803, 16807, 16811, 16815, 16819, 16823, 16827,
+ 16831, 16835, 16839, 16843, 16847, 16851, 16855, 16859, 16863, 16867,
+ 16871, 16875, 0, 0, 0, 0, 0, 16879, 16883, 16887, 16891, 16895, 16899,
+ 16903, 16907, 16911, 16915, 16919, 16923, 16927, 16931, 16935, 16939,
+ 16943, 16947, 16951, 16955, 16959, 16963, 16967, 16971, 16975, 16979,
+ 16983, 16987, 16991, 16995, 16999, 17003, 17007, 17011, 17015, 17019,
+ 17023, 17027, 17031, 17035, 17039, 17043, 17047, 17051, 17055, 17059,
+ 17063, 17067, 17071, 17075, 17079, 17083, 17087, 17091, 17095, 17099,
+ 17103, 17107, 17111, 17115, 17119, 17123, 17127, 17131, 17135, 17139,
+ 17143, 17147, 17151, 17155, 17159, 17163, 17167, 17171, 17175, 17179,
+ 17183, 17187, 17191, 17195, 17199, 17203, 0, 0, 0, 0, 0, 0, 17207, 17210,
+ 17214, 17218, 17222, 17226, 17230, 17234, 17238, 17242, 17246, 17250,
+ 17254, 17258, 17262, 17266, 17270, 17274, 17278, 17282, 17286, 17290,
+ 17294, 17298, 17302, 17305, 17309, 17313, 17317, 17321, 17325, 17329,
+ 17333, 17337, 17341, 17345, 17349, 17353, 17357, 17361, 17365, 17369,
+ 17373, 17377, 17381, 17385, 17389, 17393, 17397, 17401, 17405, 17409,
+ 17413, 17417, 17421, 17425, 17429, 17433, 17437, 17441, 17445, 17449,
+ 17453, 17457, 17461, 17465, 17469, 17473, 17477, 17481, 17485, 17489,
+ 17493, 0, 17497, 17501, 17505, 17509, 0, 0, 17513, 17517, 17521, 17525,
+ 17529, 17533, 17537, 0, 17541, 0, 17545, 17549, 17553, 17557, 0, 0,
+ 17561, 17565, 17569, 17573, 17577, 17581, 17585, 17589, 17593, 17597,
+ 17601, 17605, 17609, 17613, 17617, 17621, 17625, 17629, 17633, 17637,
+ 17641, 17645, 17649, 17652, 17656, 17660, 17664, 17668, 17672, 17676,
+ 17680, 17684, 17688, 17692, 17696, 17700, 17704, 17708, 17712, 17716,
+ 17720, 0, 17724, 17728, 17732, 17736, 0, 0, 17740, 17744, 17748, 17752,
+ 17756, 17760, 17764, 17768, 17772, 17776, 17780, 17784, 17788, 17792,
+ 17796, 17800, 17804, 17809, 17814, 17819, 17825, 17831, 17836, 17841,
+ 17847, 17850, 17854, 17858, 17862, 17866, 17870, 17874, 17878, 0, 17882,
+ 17886, 17890, 17894, 0, 0, 17898, 17902, 17906, 17910, 17914, 17918,
+ 17922, 0, 17926, 0, 17930, 17934, 17938, 17942, 0, 0, 17946, 17950,
+ 17954, 17958, 17962, 17966, 17970, 17974, 17978, 17983, 17988, 17993,
+ 17999, 18005, 18010, 0, 18015, 18019, 18023, 18027, 18031, 18035, 18039,
+ 18043, 18047, 18051, 18055, 18059, 18063, 18067, 18071, 18075, 18079,
+ 18082, 18086, 18090, 18094, 18098, 18102, 18106, 18110, 18114, 18118,
+ 18122, 18126, 18130, 18134, 18138, 18142, 18146, 18150, 18154, 18158,
+ 18162, 18166, 18170, 18174, 18178, 18182, 18186, 18190, 18194, 18198,
+ 18202, 18206, 18210, 18214, 18218, 18222, 18226, 18230, 18234, 18238, 0,
+ 18242, 18246, 18250, 18254, 0, 0, 18258, 18262, 18266, 18270, 18274,
+ 18278, 18282, 18286, 18290, 18294, 18298, 18302, 18306, 18310, 18314,
+ 18318, 18322, 18326, 18330, 18334, 18338, 18342, 18346, 18350, 18354,
+ 18358, 18362, 18366, 18370, 18374, 18378, 18382, 18386, 18390, 18394,
+ 18398, 18402, 18406, 18410, 18414, 18418, 18422, 18426, 18430, 18434,
+ 18438, 18442, 18446, 18450, 18454, 18458, 18462, 18466, 18470, 18474,
+ 18478, 18482, 18486, 18490, 18494, 18498, 18502, 18506, 18510, 18514,
+ 18518, 18522, 0, 0, 0, 0, 18526, 18531, 18535, 18538, 18542, 18545,
+ 18548, 18551, 18556, 18560, 18565, 18568, 18571, 18574, 18577, 18580,
+ 18583, 18586, 18589, 18592, 18596, 18600, 18604, 18608, 18612, 18616,
+ 18620, 18624, 18628, 18632, 0, 0, 0, 18638, 18644, 18648, 18652, 18656,
+ 18662, 18666, 18670, 18674, 18680, 18684, 18688, 18692, 18698, 18702,
+ 18706, 18710, 18716, 18722, 18728, 18736, 18742, 18748, 18754, 18760,
+ 18766, 0, 0, 0, 0, 0, 0, 18772, 18775, 18778, 18781, 18784, 18787, 18790,
+ 18794, 18797, 18801, 18805, 18809, 18813, 18817, 18820, 18824, 18828,
+ 18832, 18836, 18840, 18844, 18848, 18852, 18856, 18860, 18864, 18867,
+ 18871, 18875, 18879, 18883, 18887, 18891, 18895, 18899, 18903, 18907,
+ 18911, 18915, 18919, 18923, 18927, 18931, 18935, 18939, 18943, 18946,
+ 18950, 18954, 18958, 18962, 18966, 18970, 18974, 18978, 18982, 18986,
+ 18990, 18994, 18998, 19002, 19006, 19010, 19014, 19018, 19022, 19026,
+ 19030, 19034, 19038, 19042, 19046, 19050, 19054, 19058, 19062, 19066,
+ 19070, 19074, 19078, 19081, 19085, 19089, 19093, 19097, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 19101, 19104, 19108, 19111, 19115, 19118, 19122, 19128,
+ 19133, 19137, 19140, 19144, 19148, 19153, 19157, 19162, 19166, 19171,
+ 19175, 19180, 19184, 19189, 19195, 19199, 19204, 19208, 19213, 19219,
+ 19223, 19229, 19234, 19238, 19242, 19250, 19258, 19265, 19270, 19275,
+ 19284, 19291, 19298, 19303, 19309, 19313, 19317, 19321, 19325, 19329,
+ 19333, 19337, 19341, 19345, 19349, 19355, 19360, 19365, 19369, 19373,
+ 19377, 19382, 19386, 19391, 19395, 19400, 19404, 19409, 19413, 19418,
+ 19422, 19427, 19431, 19436, 19442, 19445, 19449, 19453, 19457, 19461,
+ 19465, 19469, 19472, 19476, 19482, 19487, 19492, 19496, 19500, 19504,
+ 19509, 19513, 19518, 19522, 19527, 19530, 19534, 19538, 19543, 19547,
+ 19552, 19556, 19561, 19567, 19570, 19574, 19578, 19582, 19586, 19590,
+ 19594, 19598, 19602, 19606, 19610, 19616, 19619, 19623, 19627, 19632,
+ 19636, 19641, 19645, 19650, 19654, 19659, 19663, 19668, 19672, 19677,
+ 19681, 19686, 19692, 19696, 19700, 19706, 19712, 19718, 19724, 19728,
+ 19732, 19736, 19740, 19744, 19748, 19754, 19758, 19762, 19766, 19771,
+ 19775, 19780, 19784, 19789, 19793, 19798, 19802, 19807, 19811, 19816,
+ 19820, 19825, 19831, 19835, 19841, 19845, 19849, 19853, 19857, 19861,
+ 19865, 19871, 19874, 19878, 19882, 19887, 19891, 19896, 19900, 19905,
+ 19909, 19914, 19918, 19923, 19927, 19932, 19936, 19941, 19947, 19950,
+ 19954, 19958, 19963, 19968, 19972, 19976, 19980, 19984, 19988, 19992,
+ 19998, 20002, 20006, 20010, 20015, 20019, 20024, 20028, 20033, 20039,
+ 20042, 20047, 20051, 20055, 20059, 20063, 20067, 20071, 20075, 20081,
+ 20085, 20089, 20093, 20098, 20102, 20107, 20111, 20116, 20120, 20125,
+ 20129, 20134, 20138, 20143, 20147, 20152, 20155, 20159, 20163, 20167,
+ 20171, 20175, 20179, 20183, 20187, 20193, 20197, 20201, 20205, 20210,
+ 20214, 20219, 20223, 20228, 20232, 20237, 20241, 20246, 20250, 20255,
+ 20259, 20264, 20270, 20273, 20278, 20282, 20287, 20293, 20299, 20305,
+ 20311, 20317, 20323, 20329, 20333, 20337, 20341, 20345, 20349, 20353,
+ 20357, 20361, 20366, 20370, 20375, 20379, 20384, 20388, 20393, 20397,
+ 20402, 20406, 20411, 20415, 20420, 20424, 20428, 20432, 20436, 20440,
+ 20444, 20448, 20454, 20457, 20461, 20465, 20470, 20474, 20479, 20483,
+ 20488, 20492, 20497, 20501, 20506, 20510, 20515, 20519, 20524, 20530,
+ 20534, 20540, 20545, 20551, 20555, 20561, 20566, 20570, 20574, 20578,
+ 20582, 20586, 20591, 20595, 20599, 20604, 20608, 20613, 20616, 20620,
+ 20624, 20628, 20632, 20636, 20640, 20644, 20648, 20652, 20656, 20660,
+ 20665, 20669, 20673, 20679, 20683, 20689, 20693, 20699, 20703, 20707,
+ 20711, 20715, 20719, 20724, 20728, 20732, 20736, 20740, 20744, 20748,
+ 20752, 20756, 20760, 20764, 20770, 20776, 20782, 20788, 20794, 20799,
+ 20805, 20810, 20815, 20819, 20823, 20827, 20831, 20835, 20839, 20843,
+ 20847, 20851, 20855, 20859, 20863, 20867, 20872, 20877, 20882, 20887,
+ 20891, 20895, 20899, 20903, 20907, 20911, 20915, 20919, 20923, 20929,
+ 20935, 20941, 20947, 20953, 20959, 20965, 20971, 20977, 20981, 20985,
+ 20989, 20993, 20997, 21001, 21005, 21011, 21017, 21023, 21029, 21035,
+ 21041, 21047, 21053, 21058, 21063, 21068, 21073, 21078, 21084, 21090,
+ 21096, 21102, 21108, 21114, 21120, 21126, 21132, 21138, 21144, 21149,
+ 21155, 21161, 21167, 21172, 21177, 21182, 21187, 21192, 21197, 21202,
+ 21207, 21212, 21217, 21222, 21227, 21232, 21237, 21242, 21247, 21252,
+ 21257, 21262, 21267, 21272, 21277, 21282, 21287, 21292, 21297, 21302,
+ 21307, 21312, 21317, 21322, 21327, 21332, 21337, 21342, 21347, 21352,
+ 21357, 21362, 21367, 21372, 21377, 21382, 21386, 21391, 21396, 21401,
+ 21406, 21411, 21416, 21421, 21426, 21431, 21436, 21441, 21446, 21451,
+ 21456, 21461, 21466, 21471, 21476, 21481, 21486, 21491, 21496, 21501,
+ 21506, 21511, 21516, 21521, 21526, 21531, 21536, 21540, 21545, 21550,
+ 21555, 21560, 21565, 21569, 21574, 21580, 21585, 21590, 21595, 21600,
+ 21606, 21611, 21616, 21621, 21626, 21631, 21636, 21641, 21646, 21651,
+ 21656, 21661, 21666, 21671, 21676, 21681, 21686, 21691, 21696, 21701,
+ 21706, 21711, 21716, 21721, 21726, 21731, 21736, 21741, 21746, 21751,
+ 21756, 21761, 21766, 21771, 21776, 21781, 21786, 21791, 21796, 21801,
+ 21806, 21811, 21816, 21821, 21826, 21832, 21837, 21842, 21847, 21852,
+ 21857, 21862, 21867, 21872, 21877, 21882, 21887, 21892, 21897, 21902,
+ 21907, 21912, 21917, 21922, 21927, 21932, 21937, 21942, 21947, 21952,
+ 21957, 21962, 21967, 21972, 21977, 21982, 21987, 21992, 21997, 22002,
+ 22007, 22012, 22017, 22022, 22027, 22031, 22035, 22039, 22043, 22047,
+ 22051, 22055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22059, 22064, 22069, 22074,
+ 22079, 22084, 22089, 22094, 22099, 22104, 22109, 22114, 22119, 22124,
+ 22129, 22134, 22139, 22144, 22149, 22154, 22159, 22164, 22169, 22174,
+ 22179, 22184, 22189, 22194, 22199, 0, 0, 0, 22205, 22215, 22218, 22225,
+ 22229, 22233, 22237, 22245, 22249, 22254, 22259, 22264, 22268, 22273,
+ 22278, 22281, 22285, 22289, 22298, 22302, 22306, 22312, 22315, 22319,
+ 22326, 22330, 22338, 22343, 22348, 22353, 22358, 22367, 22372, 22376,
+ 22385, 22388, 22393, 22397, 22403, 22408, 22414, 22421, 22427, 22432,
+ 22439, 22444, 22448, 22452, 22461, 22466, 22469, 22478, 22483, 22487,
+ 22491, 22498, 22505, 22510, 22515, 22524, 22528, 22532, 22536, 22543,
+ 22550, 22554, 22558, 22562, 22566, 22570, 22574, 22578, 22582, 22586,
+ 22590, 22593, 22598, 22603, 22608, 22612, 22616, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 22620, 22624, 22628, 22632, 22636, 22641, 22646,
+ 22651, 22656, 22661, 22666, 22671, 22675, 0, 22679, 22684, 22689, 22694,
+ 22698, 22703, 22708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22713, 22717,
+ 22721, 22725, 22729, 22734, 22739, 22744, 22749, 22754, 22759, 22764,
+ 22768, 22772, 22777, 22782, 22787, 22792, 22796, 22801, 22806, 22811,
+ 22817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22822, 22826, 22830, 22834, 22838,
+ 22843, 22848, 22853, 22858, 22863, 22868, 22873, 22877, 22881, 22886,
+ 22891, 22896, 22901, 22905, 22910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 22915, 22919, 22923, 22927, 22931, 22936, 22941, 22946, 22951, 22956,
+ 22961, 22966, 22970, 0, 22974, 22979, 22984, 0, 22989, 22994, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 22999, 23002, 23006, 23010, 23014, 23018, 23022,
+ 23026, 23030, 23034, 23038, 23042, 23046, 23050, 23054, 23058, 23062,
+ 23066, 23069, 23073, 23077, 23081, 23085, 23089, 23093, 23097, 23101,
+ 23105, 23109, 23113, 23117, 23121, 23125, 23128, 23132, 23136, 23142,
+ 23148, 23154, 23160, 23166, 23172, 23178, 23184, 23190, 23196, 23202,
+ 23208, 23214, 23220, 23229, 23238, 23244, 23250, 23256, 23261, 23265,
+ 23270, 23275, 23280, 23284, 23289, 23294, 23299, 23303, 23308, 23312,
+ 23317, 23322, 23327, 23332, 23336, 23340, 23344, 23348, 23352, 23356,
+ 23360, 23364, 23368, 23372, 23378, 23382, 23386, 23390, 23394, 23398,
+ 23406, 23412, 23416, 23422, 23426, 23432, 23436, 0, 0, 23440, 23444,
+ 23447, 23450, 23453, 23456, 23459, 23462, 23465, 23468, 0, 0, 0, 0, 0, 0,
+ 23471, 23479, 23487, 23495, 23503, 23511, 23519, 23527, 23535, 23543, 0,
+ 0, 0, 0, 0, 0, 23551, 23554, 23557, 23560, 23564, 23567, 23572, 23579,
+ 23587, 23592, 23598, 23601, 23608, 23615, 23622, 0, 23626, 23630, 23633,
+ 23636, 23639, 23642, 23645, 23648, 23651, 23654, 0, 0, 0, 0, 0, 0, 23657,
+ 23660, 23663, 23666, 23669, 23672, 23676, 23680, 23684, 23688, 23692,
+ 23696, 23700, 23704, 23708, 23711, 23715, 23719, 23723, 23727, 23731,
+ 23735, 23739, 23742, 23746, 23750, 23754, 23757, 23761, 23765, 23769,
+ 23773, 23777, 23781, 23785, 23789, 23796, 23801, 23806, 23811, 23816,
+ 23822, 23828, 23834, 23840, 23846, 23852, 23858, 23863, 23869, 23875,
+ 23881, 23887, 23893, 23898, 23904, 23909, 23915, 23921, 23927, 23933,
+ 23939, 23944, 23949, 23955, 23961, 23966, 23972, 23977, 23983, 23988,
+ 23994, 24000, 24006, 24012, 24018, 24024, 24030, 24036, 24042, 24048,
+ 24054, 24060, 24066, 24071, 24076, 24082, 24088, 0, 0, 0, 0, 0, 0, 0, 0,
+ 24094, 24103, 24112, 24120, 24128, 24138, 24146, 24155, 24162, 24169,
+ 24176, 24184, 24192, 24200, 24208, 24216, 24224, 24232, 24240, 24248,
+ 24256, 24264, 24272, 24280, 24288, 24298, 24308, 24318, 24328, 24338,
+ 24348, 24358, 24368, 24378, 24388, 24398, 24408, 24418, 24428, 24436,
+ 24444, 24454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24462, 24467,
+ 24470, 24474, 24478, 24482, 24486, 24490, 24494, 24498, 24502, 24506,
+ 24510, 24514, 24518, 24522, 24526, 24530, 24534, 24538, 24542, 24545,
+ 24548, 24552, 24556, 24560, 24564, 24568, 24572, 0, 0, 0, 24575, 24579,
+ 24583, 24587, 24592, 24597, 24602, 24607, 24611, 24615, 24619, 24624, 0,
+ 0, 0, 0, 24629, 24633, 24638, 24643, 24648, 24653, 24658, 24662, 24667,
+ 24672, 24676, 24680, 0, 0, 0, 0, 24684, 0, 0, 0, 24688, 24692, 24696,
+ 24700, 24703, 24706, 24709, 24712, 24715, 24718, 24721, 24724, 24727,
+ 24732, 24738, 24744, 24750, 24756, 24761, 24767, 24773, 24779, 24785,
+ 24791, 24796, 24802, 24808, 24813, 24819, 24825, 24831, 24837, 24842,
+ 24847, 24853, 24859, 24864, 24870, 24875, 24881, 24886, 24892, 0, 0,
+ 24898, 24904, 24910, 24916, 24922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 24928, 24935, 24942, 24948, 24955, 24962, 24968, 24975, 24982, 24989,
+ 24996, 25002, 25009, 25016, 25022, 25029, 25036, 25043, 25050, 25057,
+ 25064, 25071, 25078, 25084, 25091, 25098, 25104, 25111, 25118, 25125,
+ 25132, 25139, 25146, 25152, 25159, 25166, 25172, 25179, 25186, 25193,
+ 25200, 25207, 0, 0, 0, 0, 0, 0, 25214, 25222, 25229, 25236, 25242, 25249,
+ 25255, 25262, 25268, 25275, 25282, 25289, 25296, 25303, 25310, 25317,
+ 25324, 25331, 25337, 25344, 25350, 25356, 25363, 25369, 25375, 25381, 0,
+ 0, 0, 0, 0, 0, 25387, 25393, 25398, 25403, 25408, 25413, 25418, 25423,
+ 25428, 25433, 0, 0, 0, 0, 25438, 25444, 25450, 25454, 25460, 25466,
+ 25472, 25478, 25484, 25490, 25496, 25502, 25508, 25514, 25520, 25526,
+ 25532, 25538, 25544, 25548, 25554, 25560, 25566, 25572, 25578, 25584,
+ 25590, 25596, 25602, 25608, 25614, 25620, 25626, 25632, 25638, 25642,
+ 25647, 25652, 25657, 25662, 25667, 25671, 25676, 25681, 25686, 25691,
+ 25696, 25701, 25706, 25711, 25716, 25720, 25725, 25730, 25735, 25740,
+ 25744, 25748, 25753, 25758, 25763, 25768, 0, 0, 25774, 25778, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25785, 25790,
+ 25796, 25802, 25809, 25815, 25820, 25826, 25831, 25838, 25843, 25848,
+ 25854, 25862, 25867, 25873, 25878, 25885, 25891, 25899, 25907, 25913,
+ 25919, 25926, 25933, 25938, 25944, 25950, 25955, 25960, 25966, 25974,
+ 25981, 25986, 25992, 25998, 26004, 26012, 26016, 26022, 26028, 26034,
+ 26040, 26046, 26052, 26056, 26061, 26065, 26071, 26075, 26079, 26084,
+ 26088, 26092, 26096, 26100, 26105, 26109, 26113, 26117, 26122, 26126,
+ 26131, 26135, 26139, 26143, 26147, 26152, 26156, 26161, 26166, 26172,
+ 26176, 26180, 26184, 26189, 26195, 26202, 26206, 26211, 26216, 26220,
+ 26225, 26229, 26235, 26242, 26249, 26253, 26257, 26261, 26267, 26272,
+ 26276, 26281, 26286, 26292, 26297, 26303, 26308, 26314, 26320, 26326,
+ 26332, 26339, 26346, 26353, 26360, 26367, 26372, 26380, 26389, 26398,
+ 26407, 26416, 26425, 26434, 26446, 26455, 26464, 26473, 26478, 26483,
+ 26489, 26497, 26504, 26511, 26518, 26525, 26532, 26540, 26549, 26558,
+ 26567, 26576, 26585, 26594, 26603, 26612, 26621, 26630, 26639, 26648,
+ 26657, 26666, 26674, 26682, 26693, 26701, 26711, 26722, 26731, 26739,
+ 26749, 26758, 26766, 26775, 26781, 26786, 26794, 26799, 26806, 26811,
+ 26820, 26825, 26830, 26836, 26841, 26846, 26853, 26861, 26870, 26879,
+ 26884, 26891, 26901, 26909, 26918, 26923, 26929, 26934, 26941, 26946,
+ 26955, 26960, 26965, 26970, 26977, 26982, 26987, 26996, 27004, 27009,
+ 27014, 27021, 27028, 27032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27036,
+ 27044, 27052, 27059, 27066, 27073, 27080, 27088, 27096, 27106, 27116,
+ 27124, 27132, 27140, 27148, 27157, 27166, 27174, 27182, 27190, 27198,
+ 27207, 27216, 27225, 27234, 27241, 27248, 27256, 27264, 27274, 27284,
+ 27292, 27300, 27307, 27314, 27322, 27330, 27338, 27346, 27353, 27360,
+ 27368, 27376, 27385, 27394, 27402, 27410, 27419, 27428, 27435, 27442,
+ 27450, 27458, 27467, 27476, 27484, 27492, 27503, 27514, 27523, 27532,
+ 27540, 27548, 27555, 27562, 27570, 27578, 27586, 27594, 27602, 27610,
+ 27618, 27626, 27635, 27644, 27652, 27660, 27669, 27678, 27687, 27696,
+ 27705, 27714, 27723, 27732, 27739, 27746, 27754, 27762, 27770, 27778,
+ 27786, 27794, 27805, 27816, 27825, 27834, 27842, 27850, 27858, 27866,
+ 27877, 27888, 27899, 27910, 27922, 27934, 27942, 27950, 27958, 27966,
+ 27975, 27984, 27992, 28000, 28008, 28016, 28024, 28032, 28039, 28046,
+ 28055, 28064, 28073, 28082, 28089, 28096, 28104, 28112, 28119, 28126,
+ 28133, 28140, 28147, 28154, 28162, 28170, 28178, 28186, 28194, 28202,
+ 28209, 28216, 28224, 28232, 28240, 28248, 28256, 28264, 28273, 28282,
+ 28291, 28298, 28307, 28316, 28325, 0, 0, 0, 0, 28334, 28341, 28348,
+ 28356, 28364, 28372, 28380, 28388, 28396, 28406, 28416, 28424, 28432,
+ 28441, 28450, 28459, 28468, 28477, 28486, 28497, 28508, 28517, 28526,
+ 28536, 28546, 28553, 28560, 28568, 28576, 28582, 28588, 28596, 28604,
+ 28612, 28620, 28630, 28640, 28648, 28656, 28665, 28674, 28682, 28690,
+ 28697, 28704, 28711, 28718, 28726, 28734, 28742, 28750, 28758, 28766,
+ 28776, 28786, 28794, 28802, 28811, 28820, 28829, 28838, 28847, 28856,
+ 28867, 28878, 28887, 28896, 28906, 28916, 28923, 28930, 28938, 28946,
+ 28955, 28964, 28973, 28982, 28993, 29004, 29013, 29022, 29032, 29042,
+ 29049, 29056, 29064, 29072, 29081, 29090, 29097, 0, 0, 0, 0, 0, 0, 29104,
+ 29111, 29118, 29126, 29134, 29142, 29150, 29159, 29168, 29175, 29182,
+ 29190, 29198, 29206, 29214, 29223, 29232, 29240, 29248, 29257, 29266,
+ 29275, 0, 0, 29284, 29292, 29300, 29309, 29318, 29327, 0, 0, 29336,
+ 29344, 29352, 29361, 29370, 29379, 29388, 29398, 29408, 29416, 29424,
+ 29433, 29442, 29451, 29460, 29470, 29480, 29488, 29496, 29505, 29514,
+ 29523, 29532, 29542, 29552, 29560, 29568, 29577, 29586, 29595, 29604,
+ 29614, 29624, 29632, 29640, 29649, 29658, 29667, 0, 0, 29676, 29684,
+ 29692, 29701, 29710, 29719, 0, 0, 29728, 29736, 29744, 29753, 29762,
+ 29771, 29780, 29790, 0, 29800, 0, 29808, 0, 29817, 0, 29826, 29836,
+ 29843, 29850, 29858, 29866, 29874, 29882, 29891, 29900, 29907, 29914,
+ 29922, 29930, 29938, 29946, 29955, 29964, 29970, 29976, 29983, 29990,
+ 29997, 30004, 30011, 30018, 30025, 30032, 30039, 30046, 30052, 0, 0,
+ 30058, 30067, 30076, 30088, 30100, 30112, 30124, 30136, 30148, 30157,
+ 30166, 30178, 30190, 30202, 30214, 30226, 30238, 30248, 30258, 30271,
+ 30284, 30297, 30310, 30323, 30336, 30346, 30356, 30369, 30382, 30395,
+ 30408, 30421, 30434, 30443, 30452, 30464, 30476, 30488, 30500, 30512,
+ 30524, 30533, 30542, 30554, 30566, 30578, 30590, 30602, 30614, 30621,
+ 30627, 30637, 30644, 0, 30654, 30661, 30671, 30678, 30684, 30690, 30696,
+ 30703, 30706, 30709, 30712, 30715, 30721, 30732, 30740, 0, 30751, 30759,
+ 30770, 30777, 30784, 30791, 30798, 30806, 30810, 30814, 30819, 30827,
+ 30834, 30844, 0, 0, 30854, 30862, 30873, 30881, 30888, 30895, 0, 30902,
+ 30906, 30910, 30915, 30923, 30930, 30940, 30950, 30958, 30966, 30974,
+ 30985, 30993, 31000, 31007, 31014, 31022, 31027, 31032, 0, 0, 31034,
+ 31044, 31051, 0, 31061, 31068, 31078, 31085, 31092, 31098, 31104, 31111,
+ 31113, 0, 31116, 31120, 31124, 31128, 31132, 31136, 31140, 31144, 31148,
+ 31152, 31156, 31160, 31166, 31172, 31178, 31181, 31184, 31186, 31190,
+ 31194, 31198, 31202, 31204, 31208, 31212, 31218, 31224, 31231, 31238,
+ 31243, 31248, 31254, 31260, 31262, 31265, 31267, 31271, 31276, 31280,
+ 31283, 31287, 31291, 31295, 31299, 31303, 31309, 31313, 31317, 31323,
+ 31328, 31335, 31337, 31340, 31344, 31347, 31351, 31356, 31358, 31366,
+ 31374, 31377, 31381, 31383, 31385, 31387, 31390, 31396, 31398, 31402,
+ 31406, 31413, 31420, 31424, 31429, 31434, 31439, 31443, 31447, 31451,
+ 31454, 31457, 31461, 31468, 31473, 31477, 31481, 31486, 31490, 31494,
+ 31499, 31504, 31508, 31512, 31516, 31518, 31523, 31528, 31532, 31536,
+ 31540, 0, 0, 0, 0, 0, 0, 31544, 31550, 31556, 31563, 31570, 31575, 31580,
+ 31584, 0, 0, 31590, 31593, 31596, 31599, 31602, 31605, 31608, 31613,
+ 31617, 31622, 31627, 31632, 31638, 31642, 31645, 31648, 31651, 31654,
+ 31657, 31660, 31663, 31666, 31669, 31674, 31678, 31683, 31688, 0, 31693,
+ 31699, 31705, 31711, 31717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31724,
+ 31727, 31730, 31733, 31738, 31741, 31744, 31747, 31750, 31753, 31756,
+ 31760, 31763, 31766, 31769, 31772, 31775, 31780, 31783, 31786, 31789,
+ 31792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 31795, 31799, 31803, 31810, 31818, 31823, 31828, 31832,
+ 31836, 31841, 31848, 31855, 31859, 31864, 31869, 31874, 31879, 31885,
+ 31890, 31895, 31900, 31909, 31916, 31923, 31927, 31932, 31938, 31943, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31950, 31954,
+ 31961, 31965, 31969, 31974, 31978, 31982, 31986, 31988, 31992, 31995,
+ 31998, 32002, 32005, 32009, 32018, 32021, 32025, 32028, 32031, 32037,
+ 32040, 32043, 32049, 32052, 32055, 32059, 32062, 32066, 32069, 32073,
+ 32075, 32078, 32081, 32085, 32087, 32091, 32094, 32097, 32102, 32107,
+ 32113, 32116, 32119, 32122, 32127, 32130, 32133, 32136, 32140, 32144,
+ 32147, 32150, 32152, 32155, 32158, 32161, 32165, 32170, 32173, 32177,
+ 32181, 32185, 32189, 32194, 32198, 32202, 32206, 32211, 32215, 32219,
+ 32223, 32227, 32231, 32235, 32238, 0, 0, 0, 0, 0, 0, 32241, 32249, 32256,
+ 32264, 32271, 32278, 32286, 32294, 32302, 32310, 32317, 32325, 32333,
+ 32338, 32342, 32346, 32350, 32354, 32358, 32362, 32366, 32370, 32374,
+ 32379, 32384, 32389, 32394, 32401, 32408, 32415, 32420, 32425, 32430,
+ 32435, 32440, 32445, 32450, 32455, 32460, 32466, 32472, 32478, 32484,
+ 32492, 32500, 32508, 32518, 32525, 32532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 32540, 32542, 32545, 32547, 32550, 32553, 32556, 32561, 32566,
+ 32571, 32576, 32580, 32584, 32588, 32592, 32597, 32603, 32608, 32614,
+ 32619, 32624, 32629, 32635, 32640, 32646, 32652, 32656, 32660, 32665,
+ 32670, 32675, 32680, 32685, 32693, 32701, 32709, 32717, 32724, 32732,
+ 32739, 32746, 32754, 32765, 32771, 32777, 32783, 32789, 32796, 32803,
+ 32809, 32815, 32822, 32829, 32835, 32843, 32849, 32854, 32860, 32865,
+ 32871, 32878, 32885, 32890, 32896, 32901, 32904, 32908, 32911, 32915,
+ 32919, 32923, 32929, 32935, 32941, 32947, 32951, 32955, 32959, 32963,
+ 32969, 32975, 32979, 32984, 32988, 32993, 32997, 33001, 33004, 33008,
+ 33011, 33015, 33022, 33030, 33041, 33052, 33057, 33066, 33073, 33081,
+ 33089, 33093, 33099, 33107, 33111, 33116, 33121, 33127, 33133, 33139,
+ 33146, 33150, 33154, 33159, 33162, 33164, 33168, 33172, 33179, 33183,
+ 33185, 33187, 33191, 33198, 33203, 33209, 33218, 33225, 33230, 33234,
+ 33238, 33242, 33245, 33248, 33251, 33255, 33259, 33263, 33267, 33271,
+ 33274, 33278, 33282, 33285, 33287, 33290, 33292, 33296, 33300, 33302,
+ 33307, 33310, 33314, 33318, 33322, 33324, 33326, 33328, 33331, 33335,
+ 33339, 33343, 33347, 33351, 33357, 33363, 33365, 33367, 33369, 33371,
+ 33374, 33376, 33380, 33382, 33386, 33388, 33393, 33397, 33401, 33403,
+ 33406, 33410, 33415, 33419, 33428, 33438, 33442, 33447, 33453, 33456,
+ 33460, 33463, 33468, 33472, 33478, 33482, 33493, 33501, 33505, 33509,
+ 33515, 33519, 33522, 33524, 33527, 33531, 33535, 33541, 33545, 33549,
+ 33552, 33555, 33559, 33564, 33569, 33574, 33580, 33586, 33593, 33600,
+ 33604, 33608, 33610, 33614, 33617, 33620, 33628, 33636, 33642, 33648,
+ 33657, 33666, 33671, 33676, 33684, 33692, 33694, 33696, 33701, 33706,
+ 33712, 33718, 33723, 33728, 33732, 33736, 33742, 33748, 33754, 33760,
+ 33770, 33780, 33787, 33794, 33796, 33800, 33804, 33809, 33814, 33821,
+ 33828, 33831, 33834, 33837, 33840, 33843, 33848, 33852, 33857, 33862,
+ 33865, 33868, 33872, 33876, 33880, 33885, 33888, 33891, 33894, 33897,
+ 33899, 33901, 33903, 33905, 33913, 33921, 33926, 33929, 33934, 33944,
+ 33950, 33956, 33962, 33970, 33978, 33989, 33993, 33997, 33999, 34005,
+ 34007, 34009, 34011, 34013, 34018, 34021, 34027, 34033, 34037, 34041,
+ 34045, 34048, 34052, 34056, 34058, 34067, 34076, 34081, 34086, 34091,
+ 34097, 34103, 34106, 34109, 34112, 34115, 34117, 34122, 34127, 34132,
+ 34138, 34144, 34151, 34158, 34163, 34168, 34173, 34178, 34186, 34194,
+ 34202, 34210, 34218, 34226, 34234, 34242, 34250, 34258, 34265, 34276,
+ 34285, 34299, 34302, 34307, 34313, 34319, 34326, 34340, 34355, 34361,
+ 34367, 34374, 34380, 34388, 34394, 34407, 34421, 34426, 34432, 34439,
+ 34442, 34445, 34447, 34450, 34453, 34455, 34457, 34461, 34464, 34467,
+ 34470, 34473, 34478, 34483, 34488, 34493, 34496, 34499, 34501, 34503,
+ 34505, 34509, 34513, 34517, 34523, 34526, 34528, 34530, 34535, 34540,
+ 34545, 34550, 34555, 34560, 34562, 34564, 34573, 34577, 34583, 34592,
+ 34594, 34598, 34602, 34609, 34613, 34615, 34619, 34621, 34625, 34629,
+ 34633, 34635, 34637, 34639, 34644, 34651, 34658, 34665, 34672, 34679,
+ 34686, 34692, 34698, 34704, 34710, 34717, 34724, 34731, 34738, 34744,
+ 34750, 34757, 34764, 34770, 34778, 34785, 34793, 34800, 34808, 34815,
+ 34823, 34831, 34838, 34846, 34853, 34861, 34868, 34876, 34883, 34890,
+ 34897, 34904, 34910, 34918, 34925, 34931, 34938, 34945, 34951, 34957,
+ 34963, 34968, 34976, 34984, 34990, 34996, 35002, 35008, 35013, 35019,
+ 35026, 35034, 35041, 35048, 35055, 35060, 35065, 35070, 35076, 35083,
+ 35090, 35096, 35101, 35105, 35113, 35119, 35122, 35130, 35133, 35138,
+ 35143, 35146, 35149, 35157, 35160, 35165, 35168, 35175, 35180, 35187,
+ 35190, 35193, 35196, 35201, 35206, 35209, 35212, 35220, 35223, 35228,
+ 35235, 35239, 35243, 35248, 35253, 35258, 35263, 35268, 35273, 35278,
+ 35283, 35290, 35296, 35303, 35310, 35316, 35323, 35330, 35339, 35346,
+ 35352, 35359, 35368, 35375, 35379, 35384, 35395, 35406, 35410, 35414,
+ 35418, 35422, 35433, 35437, 35442, 35447, 35452, 35457, 35462, 35467,
+ 35476, 35485, 35493, 35503, 35513, 35521, 35531, 35541, 35549, 35559,
+ 35569, 35577, 35585, 35595, 35605, 35608, 35611, 35614, 35619, 35623,
+ 35630, 35638, 35646, 35655, 35662, 35666, 35670, 35674, 35678, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 35680, 35684, 35691, 35698, 35705, 35712,
+ 35716, 35720, 35724, 35728, 35733, 35739, 35744, 35750, 35756, 35762,
+ 35768, 35776, 35783, 35790, 35797, 35804, 35810, 35816, 35825, 35829,
+ 35836, 35840, 35844, 35850, 35856, 35862, 35868, 35872, 35876, 35879,
+ 35883, 35887, 35894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 35901, 35904, 35908, 35912, 35918, 35924, 35930,
+ 35938, 35945, 35949, 35957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35962, 35965, 35968, 35971, 35974, 35977, 35980, 35983,
+ 35986, 35989, 35993, 35997, 36001, 36005, 36009, 36013, 36017, 36021,
+ 36025, 36029, 36033, 36036, 36039, 36042, 36045, 36048, 36051, 36054,
+ 36057, 36060, 36064, 36068, 36072, 36076, 36080, 36084, 36088, 36092,
+ 36096, 36100, 36104, 36110, 36115, 36120, 36126, 36132, 36138, 36144,
+ 36150, 36156, 36162, 36168, 36174, 36180, 36186, 36192, 36198, 36204,
+ 36210, 36216, 36222, 36227, 36232, 36238, 36243, 36248, 36254, 36259,
+ 36264, 36269, 36274, 36280, 36285, 36290, 36295, 36300, 36305, 36311,
+ 36316, 36321, 36326, 36331, 36336, 36342, 36347, 36353, 36359, 36364,
+ 36369, 36375, 36380, 36385, 36391, 36396, 36401, 36406, 36411, 36417,
+ 36422, 36427, 36432, 36437, 36442, 36448, 36453, 36458, 36463, 36468,
+ 36473, 36479, 36484, 36490, 36496, 36501, 36506, 36512, 36517, 36522,
+ 36528, 36533, 36538, 36543, 36548, 36554, 36559, 36564, 36569, 36574,
+ 36579, 36585, 36590, 36595, 36600, 36605, 36610, 36616, 36621, 36627,
+ 36633, 36637, 36643, 36649, 36655, 36661, 36667, 36673, 36679, 36685,
+ 36691, 36697, 36701, 36705, 36709, 36713, 36717, 36721, 36725, 36729,
+ 36733, 36738, 36744, 36749, 36754, 36759, 36764, 36773, 36782, 36791,
+ 36800, 36809, 36818, 36827, 36836, 36842, 36850, 36858, 36864, 36871,
+ 36879, 36887, 36894, 36900, 36908, 36916, 36922, 36929, 36937, 36945,
+ 36952, 36958, 36966, 36975, 36984, 36992, 37001, 37010, 37016, 37023,
+ 37031, 37040, 37049, 37057, 37066, 37075, 37082, 37089, 37098, 37107,
+ 37115, 37123, 37132, 37141, 37148, 37155, 37164, 37173, 37181, 37189,
+ 37198, 37207, 37214, 37221, 37230, 37239, 37247, 37256, 37265, 37273,
+ 37283, 37293, 37303, 37313, 37322, 37331, 37340, 37349, 37356, 37364,
+ 37372, 37380, 37388, 37393, 37398, 37407, 37415, 37421, 37430, 37438,
+ 37445, 37454, 37462, 37468, 37477, 37485, 37492, 37501, 37509, 37515,
+ 37524, 37532, 37539, 37548, 37556, 37563, 37572, 37580, 37587, 37596,
+ 37604, 37611, 37619, 37628, 37637, 37645, 37656, 37666, 37673, 37678,
+ 37683, 37687, 37692, 37697, 37702, 37706, 37711, 37718, 37726, 37733,
+ 37741, 37745, 37752, 37759, 37765, 37769, 37776, 37782, 37789, 37793,
+ 37800, 37806, 37813, 37817, 37823, 37830, 37837, 37841, 37844, 37848,
+ 37852, 37859, 37866, 37871, 37875, 37880, 37890, 37897, 37908, 37918,
+ 37922, 37930, 37940, 37943, 37946, 37953, 37961, 37966, 37971, 37979,
+ 37988, 37997, 38005, 38009, 38013, 38016, 38019, 38023, 38027, 38030,
+ 38033, 38038, 38043, 38049, 38055, 38060, 38065, 38071, 38077, 38082,
+ 38087, 38092, 38097, 38103, 38109, 38114, 38119, 38125, 38131, 38136,
+ 38141, 38144, 38147, 38156, 38158, 38160, 38163, 38167, 38172, 38174,
+ 38177, 38183, 38189, 38195, 38201, 38209, 38221, 38226, 38231, 38235,
+ 38240, 38247, 38254, 38262, 38270, 38278, 38286, 38290, 38294, 38299,
+ 38304, 38309, 38314, 38317, 38323, 38329, 38338, 38347, 38355, 38363,
+ 38372, 38381, 38385, 38392, 38399, 38406, 38413, 38420, 38427, 38434,
+ 38441, 38445, 38449, 38453, 38458, 38463, 38469, 38475, 38479, 38485,
+ 38487, 38489, 38491, 38493, 38496, 38499, 38501, 38503, 38505, 38509,
+ 38513, 38515, 38517, 38520, 38523, 38527, 38533, 38538, 38540, 38547,
+ 38551, 38556, 38561, 38563, 38572, 38578, 38584, 38590, 38596, 38602,
+ 38608, 38613, 38616, 38619, 38622, 38624, 38626, 38630, 38634, 38639,
+ 38644, 38649, 38652, 38656, 38661, 38664, 38668, 38673, 38678, 38683,
+ 38688, 38693, 38698, 38703, 38708, 38713, 38718, 38723, 38728, 38734,
+ 38740, 38746, 38748, 38751, 38753, 38756, 38758, 38760, 38762, 38764,
+ 38766, 38768, 38770, 38772, 38774, 38776, 38778, 38780, 38782, 38784,
+ 38786, 38788, 38790, 38795, 38800, 38805, 38810, 38815, 38820, 38825,
+ 38830, 38835, 38840, 38845, 38850, 38855, 38860, 38865, 38870, 38875,
+ 38880, 38885, 38890, 38894, 38898, 38902, 38908, 38914, 38919, 38924,
+ 38929, 38934, 38939, 38944, 38952, 38960, 38968, 38976, 38984, 38992,
+ 39000, 39008, 39014, 39019, 39024, 39029, 39032, 39036, 39040, 39044,
+ 39048, 39052, 39056, 39061, 39067, 39073, 39080, 39085, 39090, 39097,
+ 39104, 39111, 39118, 39121, 39124, 39129, 39131, 39135, 39140, 39142,
+ 39144, 39146, 39148, 39153, 39156, 0, 0, 0, 39158, 39161, 39165, 39170,
+ 39175, 39183, 39189, 39195, 39207, 39214, 39221, 39226, 39231, 39237,
+ 39240, 39243, 39248, 39250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39254, 39259, 39262,
+ 39267, 0, 39270, 39275, 39279, 39281, 0, 0, 39283, 39287, 39291, 39295,
+ 39297, 39301, 39304, 39307, 39310, 39314, 39317, 39321, 39324, 39328,
+ 39333, 39337, 39343, 39350, 39353, 39359, 39364, 39368, 39373, 39379,
+ 39385, 39392, 39398, 39405, 0, 39412, 39419, 39423, 39430, 39436, 39441,
+ 39447, 39451, 39456, 39459, 39465, 39471, 39478, 39486, 39493, 39502,
+ 39512, 39519, 39525, 39529, 39537, 39542, 39551, 39554, 39557, 39566,
+ 39577, 39584, 39586, 39592, 39597, 39599, 39602, 39606, 39614, 0, 39623,
+ 0, 39628, 39635, 39642, 39649, 0, 0, 0, 39656, 0, 39663, 39666, 39670,
+ 39673, 39684, 39694, 39704, 0, 0, 39713, 39722, 39728, 39736, 39740,
+ 39748, 39752, 39760, 39767, 39774, 39783, 39792, 39801, 39810, 39819,
+ 39828, 39836, 39844, 39854, 39864, 39873, 39882, 39889, 39896, 39903,
+ 39910, 39917, 39924, 39931, 39938, 39945, 39953, 39959, 39965, 39971,
+ 39977, 39983, 39989, 39995, 40001, 40007, 40014, 40022, 40030, 40038,
+ 40046, 40054, 40062, 40070, 40078, 40086, 40095, 0, 0, 0, 40100, 40106,
+ 40109, 40115, 40121, 40126, 40130, 40135, 40141, 40148, 40151, 40158,
+ 40165, 40169, 40178, 40187, 40192, 40198, 40203, 40208, 40215, 40222,
+ 40229, 40236, 0, 40244, 40252, 40257, 40261, 40268, 40272, 40279, 40287,
+ 40292, 40300, 40304, 40309, 40313, 40318, 0, 40322, 40327, 40336, 40338,
+ 40342, 40346, 40353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40360, 40368, 40372,
+ 40379, 40386, 40393, 40398, 40403, 40409, 40414, 40419, 40425, 40430,
+ 40433, 40437, 40441, 40447, 40456, 40461, 40470, 40479, 40485, 40491,
+ 40496, 40501, 40505, 40509, 40514, 0, 0, 0, 0, 40519, 40524, 40529,
+ 40535, 40541, 40547, 40550, 40553, 40557, 40561, 40565, 40570, 40576,
+ 40582, 40589, 40596, 40601, 40605, 40609, 40613, 40617, 40621, 40625,
+ 40629, 40633, 40637, 40641, 40645, 40649, 40653, 40657, 40661, 40665,
+ 40669, 40673, 40677, 40681, 40685, 40689, 40693, 40697, 40701, 40705,
+ 40709, 40713, 40717, 40721, 40725, 40729, 40733, 40737, 40741, 40745,
+ 40749, 40753, 40757, 40761, 40765, 40769, 40773, 40777, 40781, 40785,
+ 40789, 40793, 40797, 40801, 40805, 40809, 40813, 40817, 40821, 40825,
+ 40829, 40833, 40837, 40841, 40845, 40849, 40853, 40857, 40861, 40865,
+ 40869, 40873, 40877, 40881, 40885, 40889, 40893, 40897, 40901, 40905,
+ 40909, 40913, 40917, 40921, 40925, 40929, 40933, 40937, 40941, 40945,
+ 40949, 40953, 40957, 40961, 40965, 40969, 40973, 40977, 40981, 40985,
+ 40989, 40993, 40997, 41001, 41005, 41009, 41013, 41017, 41021, 41025,
+ 41029, 41033, 41037, 41041, 41045, 41049, 41053, 41057, 41061, 41065,
+ 41069, 41073, 41077, 41081, 41085, 41089, 41093, 41097, 41101, 41105,
+ 41109, 41113, 41117, 41121, 41125, 41129, 41133, 41137, 41141, 41145,
+ 41149, 41153, 41157, 41161, 41165, 41169, 41173, 41177, 41181, 41185,
+ 41189, 41193, 41197, 41201, 41205, 41209, 41213, 41217, 41221, 41225,
+ 41229, 41233, 41237, 41241, 41245, 41249, 41253, 41257, 41261, 41265,
+ 41269, 41273, 41277, 41281, 41285, 41289, 41293, 41297, 41301, 41305,
+ 41309, 41313, 41317, 41321, 41325, 41329, 41333, 41337, 41341, 41345,
+ 41349, 41353, 41357, 41361, 41365, 41369, 41373, 41377, 41381, 41385,
+ 41389, 41393, 41397, 41401, 41405, 41409, 41413, 41417, 41421, 41425,
+ 41429, 41433, 41437, 41441, 41445, 41449, 41453, 41457, 41461, 41465,
+ 41469, 41473, 41477, 41481, 41485, 41489, 41493, 41497, 41501, 41505,
+ 41509, 41513, 41517, 41521, 41525, 41529, 41533, 41537, 41541, 41545,
+ 41549, 41553, 41557, 41561, 41565, 41569, 41573, 41577, 41581, 41585,
+ 41589, 41593, 41597, 41601, 41605, 41609, 41613, 41617, 41621, 41625,
+ 41632, 41640, 41646, 41652, 41659, 41666, 41672, 41678, 41684, 41690,
+ 41695, 41700, 41705, 41710, 41716, 41722, 41730, 41737, 41742, 41747,
+ 41755, 41764, 41771, 41781, 41792, 41795, 41798, 41802, 41806, 41812,
+ 41818, 41828, 41838, 41848, 41858, 41865, 41872, 41879, 41886, 41897,
+ 41908, 41919, 41930, 41940, 41950, 41962, 41974, 41985, 41996, 42008,
+ 42020, 42028, 42038, 42048, 42059, 42070, 42077, 42084, 42091, 42098,
+ 42108, 42118, 42125, 42132, 42138, 42144, 42151, 42158, 42165, 42171,
+ 42177, 42182, 42190, 42200, 42208, 42216, 42224, 42232, 42240, 42248,
+ 42256, 42264, 42271, 42278, 42286, 42294, 42301, 42308, 42316, 42324,
+ 42332, 42340, 42349, 42358, 42366, 42374, 42383, 42392, 42404, 42418,
+ 42430, 42444, 42456, 42468, 42480, 42492, 42501, 42511, 42520, 42530,
+ 42544, 42558, 42566, 42572, 42579, 42586, 42593, 42600, 42605, 42611,
+ 42616, 42621, 42627, 42632, 42637, 42642, 42647, 42652, 42659, 42664,
+ 42671, 42676, 42681, 42685, 42689, 42696, 42703, 42710, 42717, 42724,
+ 42731, 42744, 42757, 42770, 42783, 42790, 42797, 42803, 42809, 42816,
+ 42823, 42830, 42837, 42841, 42846, 42853, 42860, 42867, 42873, 42877,
+ 42884, 42891, 42894, 42897, 42901, 42906, 42913, 42920, 42938, 42957,
+ 42975, 42994, 43013, 43032, 43051, 43070, 43075, 43082, 43090, 43098,
+ 43106, 43110, 43113, 43116, 43121, 43124, 43142, 43147, 43153, 43159,
+ 43163, 43166, 43169, 43172, 43180, 43190, 43198, 43206, 43210, 43215,
+ 43219, 43224, 43229, 43234, 43240, 43249, 43256, 43263, 43271, 43278,
+ 43285, 43288, 43295, 43302, 43305, 43308, 43313, 43318, 43324, 43330,
+ 43334, 43340, 43347, 43351, 43357, 43361, 43365, 43373, 43385, 43393,
+ 43397, 43399, 43408, 43417, 43423, 43426, 43431, 43436, 43441, 43446,
+ 43451, 43456, 43461, 43466, 43468, 43474, 43479, 43486, 43490, 43496,
+ 43499, 43503, 43509, 43515, 43517, 43519, 43525, 43532, 43539, 43548,
+ 43557, 43564, 43571, 43577, 43583, 43589, 43594, 43599, 43605, 43611,
+ 43616, 43623, 43627, 43631, 43644, 43657, 43668, 43677, 43683, 43690,
+ 43696, 43701, 43706, 43711, 43716, 43718, 43725, 43732, 43739, 43746,
+ 43753, 43761, 43768, 43774, 43781, 43788, 43795, 43802, 43808, 43816,
+ 43824, 43833, 43842, 43849, 43855, 43861, 43870, 43874, 43883, 43892,
+ 43900, 43908, 43912, 43919, 43926, 43933, 43937, 43943, 43950, 43955,
+ 43960, 43966, 43971, 43976, 43983, 43990, 43995, 44000, 44008, 44016,
+ 44026, 44036, 44043, 44050, 44054, 44058, 44070, 44076, 44082, 44087,
+ 44092, 44099, 44106, 44112, 44118, 44127, 44135, 44143, 44150, 44157,
+ 44164, 44170, 44177, 44183, 44190, 44197, 44204, 44211, 44217, 44222,
+ 44231, 44241, 44248, 44257, 44263, 44268, 44273, 44281, 44287, 44294,
+ 44301, 44309, 44314, 44321, 44328, 44339, 44346, 44352, 44358, 44365,
+ 44372, 44379, 44386, 44397, 44408, 44418, 44428, 44439, 44451, 44456,
+ 44461, 44469, 44477, 44483, 44489, 44498, 44507, 44515, 44523, 44531,
+ 44539, 44549, 44559, 44573, 44587, 44594, 44601, 44612, 44623, 44630,
+ 44637, 44646, 44655, 44660, 44665, 44674, 44683, 44688, 44693, 44701,
+ 44707, 44713, 44721, 44729, 44742, 44755, 44759, 44763, 44770, 44777,
+ 44784, 44792, 44800, 44808, 44816, 44822, 44828, 44834, 44840, 44847,
+ 44854, 44862, 44870, 44873, 44876, 44881, 44886, 44893, 44900, 44907,
+ 44914, 44923, 44932, 44939, 44946, 44954, 44962, 44970, 44978, 44985,
+ 44992, 44999, 45006, 45010, 45014, 45021, 45028, 45033, 45038, 45043,
+ 45048, 45054, 45068, 45075, 45082, 45086, 45088, 45090, 45095, 45100,
+ 45105, 45109, 45117, 45124, 45131, 45139, 45151, 45159, 45167, 45178,
+ 45182, 45186, 45191, 45197, 45208, 45214, 45220, 45226, 45231, 45238,
+ 45247, 45255, 45261, 45267, 45273, 45282, 45291, 45299, 45308, 45313,
+ 45316, 45321, 45327, 45333, 45339, 45345, 45349, 45352, 45356, 45360,
+ 45366, 45372, 45378, 45384, 45388, 45392, 45399, 45406, 45413, 45420,
+ 45427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45434, 45439, 45444, 45449,
+ 45454, 45459, 45464, 45469, 45474, 45479, 45484, 45490, 45494, 45499,
+ 45504, 45509, 45514, 45519, 45524, 45529, 45534, 45539, 45544, 45549,
+ 45554, 45559, 45564, 45569, 45574, 45579, 45584, 45589, 45594, 45599,
+ 45604, 45610, 45615, 45621, 45630, 45635, 45643, 45650, 45659, 45664,
+ 45669, 45674, 45680, 0, 45687, 45692, 45697, 45702, 45707, 45712, 45717,
+ 45722, 45727, 45732, 45737, 45743, 45747, 45752, 45757, 45762, 45767,
+ 45772, 45777, 45782, 45787, 45792, 45797, 45802, 45807, 45812, 45817,
+ 45822, 45827, 45832, 45837, 45842, 45847, 45852, 45857, 45863, 45868,
+ 45874, 45883, 45888, 45896, 45903, 45912, 45917, 45922, 45927, 45933, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 45940, 45945, 45950, 45955, 45960, 45965, 45970,
+ 45975, 45980, 45985, 45990, 45995, 46000, 46005, 46010, 46015, 46020,
+ 46025, 46030, 46035, 46040, 46045, 46050, 46055, 46060, 46065, 46070,
+ 46075, 46080, 46085, 46090, 46094, 46098, 46103, 46108, 46113, 46118,
+ 46123, 46128, 46133, 46138, 46143, 46148, 46153, 46158, 46163, 46168,
+ 46173, 46178, 46183, 46188, 46195, 46202, 46209, 46216, 46223, 46230,
+ 46237, 46244, 46251, 46258, 46265, 46272, 46279, 46286, 46291, 46296,
+ 46303, 46310, 46317, 46324, 46331, 46338, 46345, 46352, 46359, 46366,
+ 46373, 46380, 46386, 46392, 46398, 46404, 46411, 46418, 46425, 46432,
+ 46439, 46446, 46453, 46460, 46467, 46474, 46482, 46490, 46498, 46506,
+ 46514, 46522, 46530, 46538, 46542, 46548, 46554, 46558, 46564, 46570, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46576, 46583, 46592, 46601, 46609,
+ 46616, 46620, 46625, 46630, 46635, 46640, 46645, 46650, 46655, 46660,
+ 46665, 46670, 46675, 46680, 46685, 46690, 46695, 46700, 46705, 46710,
+ 46715, 46720, 46725, 46730, 46735, 46740, 46745, 46750, 46755, 46760,
+ 46765, 46770, 46775, 46780, 46785, 46790, 46795, 46800, 46805, 46810, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 46815, 46818, 46822, 46826, 46830, 46834,
+ 46842, 46846, 46850, 46854, 46858, 46862, 46866, 46870, 46874, 46880,
+ 46884, 46888, 46896, 46902, 46906, 46910, 46914, 46920, 46924, 46930,
+ 46934, 46938, 46944, 46950, 46954, 46958, 46962, 46968, 46974, 46978,
+ 46982, 46986, 46990, 46994, 47000, 47006, 47010, 47014, 47018, 47022,
+ 47026, 47030, 47034, 47038, 47042, 47046, 47050, 47056, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 47060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47066,
+ 47070, 47074, 47078, 47082, 47086, 47090, 47094, 47098, 47102, 47106,
+ 47112, 47116, 47120, 47124, 47128, 47132, 47136, 47140, 47144, 47148,
+ 47152, 47156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47160, 47164, 47168, 47172,
+ 47176, 47180, 47184, 0, 47188, 47192, 47196, 47200, 47204, 47208, 47212,
+ 0, 47216, 47220, 47224, 47228, 47232, 47236, 47240, 0, 47244, 47248,
+ 47252, 47256, 47260, 47264, 47268, 0, 47272, 47276, 47280, 47284, 47288,
+ 47292, 47296, 0, 47300, 47304, 47308, 47312, 47316, 47320, 47324, 0,
+ 47328, 47332, 47336, 47340, 47344, 47348, 47352, 0, 47356, 47360, 47364,
+ 47368, 47372, 47376, 47380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47384, 47390,
+ 47398, 47402, 47406, 47412, 47418, 47424, 47432, 47438, 47442, 47446,
+ 47450, 47456, 47462, 47466, 47468, 47472, 47477, 47479, 47483, 47487,
+ 47491, 47497, 0, 0, 0, 0, 47502, 47507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47512, 47516, 47520, 47525,
+ 47530, 47535, 47539, 47543, 47547, 47552, 47557, 47561, 47565, 47569,
+ 47573, 47578, 47583, 47588, 47593, 47597, 47601, 47606, 47611, 47616,
+ 47621, 47625, 0, 47629, 47633, 47637, 47641, 47645, 47649, 47653, 47658,
+ 47663, 47667, 47672, 47677, 47686, 47690, 47694, 47698, 47705, 47709,
+ 47714, 47719, 47723, 47727, 47733, 47738, 47743, 47748, 47753, 47757,
+ 47761, 47765, 47769, 47773, 47778, 47783, 47787, 47791, 47796, 47801,
+ 47806, 47810, 47814, 47819, 47824, 47830, 47836, 47840, 47846, 47852,
+ 47856, 47862, 47868, 47873, 47878, 47882, 47888, 47892, 47896, 47902,
+ 47908, 47913, 47918, 47922, 47926, 47934, 47940, 47946, 47952, 47957,
+ 47962, 47967, 47973, 47977, 47983, 47987, 47991, 47997, 48003, 48009,
+ 48015, 48021, 48027, 48033, 48039, 48045, 48051, 48057, 48063, 48067,
+ 48073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48079, 48082, 48086, 48090,
+ 48094, 48098, 48101, 48104, 48108, 48112, 48116, 48120, 48123, 48128,
+ 48132, 48136, 48140, 48146, 48150, 48154, 48158, 48162, 48169, 48175,
+ 48179, 48183, 48187, 48191, 48195, 48199, 48203, 48207, 48211, 48215,
+ 48219, 48225, 48229, 48233, 48237, 48241, 48245, 48249, 48253, 48257,
+ 48261, 48265, 48269, 48273, 48277, 48281, 48285, 48289, 48295, 48301,
+ 48306, 48311, 48315, 48319, 48323, 48327, 48331, 48335, 48339, 48343,
+ 48347, 48351, 48355, 48359, 48363, 48367, 48371, 48375, 48379, 48383,
+ 48387, 48391, 48395, 48398, 48402, 48406, 48412, 48416, 48420, 48424,
+ 48428, 48432, 48436, 48440, 48444, 48448, 48455, 48459, 48463, 48467,
+ 48471, 48475, 48479, 48483, 48487, 48491, 48495, 48499, 48503, 48510,
+ 48514, 48520, 48524, 48528, 48532, 48536, 48540, 48543, 48547, 48551,
+ 48555, 48559, 48563, 48567, 48571, 48575, 48579, 48583, 48587, 48591,
+ 48595, 48599, 48603, 48607, 48611, 48615, 48619, 48623, 48627, 48631,
+ 48635, 48639, 48643, 48647, 48651, 48655, 48659, 48663, 48667, 48671,
+ 48677, 48681, 48685, 48689, 48693, 48697, 48701, 48705, 48709, 48713,
+ 48717, 48721, 48725, 48729, 48733, 48737, 48741, 48745, 48749, 48753,
+ 48757, 48761, 48765, 48769, 48773, 48777, 48781, 48785, 48793, 48797,
+ 48801, 48805, 48809, 48813, 48819, 48823, 48827, 48831, 48835, 48839,
+ 48843, 48847, 48851, 48855, 48859, 48863, 48867, 48871, 48877, 48881,
+ 48885, 48889, 48893, 48897, 48901, 48905, 48909, 48913, 48917, 48921,
+ 48925, 48929, 48933, 48937, 48941, 48945, 48949, 48953, 48957, 48961, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 48965, 48972, 48979, 48989, 48999, 49007, 49016, 49025, 49035, 49046,
+ 49056, 49067, 0, 0, 0, 0, 49073, 49076, 49079, 49083, 49086, 49093,
+ 49097, 49101, 49105, 49108, 49111, 49115, 49119, 49123, 49127, 49132,
+ 49137, 49142, 49147, 49150, 49153, 49159, 49165, 49170, 49175, 49182,
+ 49189, 49193, 49197, 49201, 49208, 49214, 49221, 49226, 49230, 49234,
+ 49238, 49242, 49246, 49250, 49254, 49258, 49262, 49267, 49272, 49277,
+ 49282, 49288, 49293, 49297, 49303, 49314, 49323, 49337, 49346, 49350,
+ 49359, 49364, 49369, 49374, 49379, 49382, 49387, 49391, 0, 49397, 49401,
+ 49404, 49408, 49411, 49415, 49418, 49422, 49425, 49429, 49432, 49435,
+ 49439, 49443, 49447, 49451, 49455, 49459, 49463, 49467, 49471, 49475,
+ 49479, 49483, 49487, 49491, 49495, 49499, 49503, 49507, 49511, 49515,
+ 49519, 49523, 49527, 49532, 49536, 49540, 49544, 49548, 49551, 49555,
+ 49559, 49563, 49567, 49571, 49575, 49578, 49582, 49586, 49590, 49594,
+ 49598, 49602, 49606, 49610, 49614, 49618, 49622, 49626, 49630, 49634,
+ 49637, 49641, 49645, 49649, 49653, 49657, 49660, 49665, 49669, 49674,
+ 49678, 49682, 49686, 49690, 49694, 49698, 49703, 49707, 49711, 49715,
+ 49719, 49722, 49726, 49730, 0, 0, 49735, 49743, 49751, 49758, 49765,
+ 49769, 49775, 49780, 49785, 49789, 49792, 49796, 49799, 49803, 49806,
+ 49810, 49813, 49817, 49820, 49823, 49827, 49831, 49835, 49839, 49843,
+ 49847, 49851, 49855, 49859, 49863, 49867, 49871, 49875, 49879, 49883,
+ 49887, 49891, 49895, 49899, 49903, 49907, 49911, 49915, 49920, 49924,
+ 49928, 49932, 49936, 49939, 49943, 49947, 49951, 49955, 49959, 49963,
+ 49966, 49970, 49974, 49978, 49982, 49986, 49990, 49994, 49998, 50002,
+ 50006, 50010, 50014, 50018, 50022, 50025, 50029, 50033, 50037, 50041,
+ 50045, 50048, 50053, 50057, 50062, 50066, 50070, 50074, 50078, 50082,
+ 50086, 50091, 50095, 50099, 50103, 50107, 50110, 50114, 50118, 50123,
+ 50127, 50131, 50135, 50139, 50144, 50151, 50155, 50161, 0, 0, 0, 0, 0,
+ 50166, 50169, 50172, 50175, 50179, 50182, 50185, 50188, 50191, 50194,
+ 50198, 50201, 50204, 50208, 50211, 50215, 50219, 50223, 50226, 50230,
+ 50234, 50237, 50240, 50243, 50246, 50250, 50254, 50258, 50262, 50266,
+ 50270, 50274, 50278, 50282, 50286, 50289, 50292, 50296, 50299, 50303, 0,
+ 0, 0, 0, 50307, 50311, 50315, 50319, 50323, 50327, 50331, 50335, 50339,
+ 50343, 50347, 50351, 50355, 50359, 50363, 50367, 50371, 50375, 50379,
+ 50383, 50387, 50391, 50395, 50399, 50403, 50407, 50411, 50415, 50419,
+ 50423, 50427, 50430, 50434, 50437, 50441, 50445, 50448, 50452, 50456,
+ 50459, 50463, 50467, 50471, 50475, 50478, 50482, 50486, 50490, 50494,
+ 50498, 50502, 50505, 50508, 50512, 50516, 50520, 50524, 50528, 50532,
+ 50536, 50540, 50544, 50548, 50552, 50556, 50560, 50564, 50568, 50572,
+ 50576, 50580, 50584, 50588, 50592, 50596, 50600, 50604, 50608, 50612,
+ 50616, 50620, 50624, 50628, 50632, 50636, 50640, 50644, 50648, 50652,
+ 50656, 50660, 50664, 50668, 50672, 0, 50676, 50682, 50688, 50694, 50699,
+ 50704, 50710, 50716, 50722, 50728, 50734, 50740, 50746, 50752, 50758,
+ 50764, 50770, 50774, 50778, 50782, 50786, 50790, 50794, 50798, 50802,
+ 50806, 50810, 50814, 50818, 50822, 50826, 50830, 50834, 50838, 50842,
+ 50846, 50850, 50854, 50858, 50863, 0, 0, 0, 0, 0, 0, 0, 0, 50867, 50871,
+ 50876, 50881, 50886, 50891, 50896, 50901, 50906, 50911, 50916, 50921,
+ 50926, 50931, 50936, 50941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50945, 50950, 50955,
+ 50960, 50964, 50969, 50973, 50978, 50983, 50988, 50993, 50998, 51003,
+ 51008, 51013, 51018, 51023, 51027, 51031, 51035, 51039, 51043, 51047,
+ 51051, 51055, 51059, 51063, 51067, 51071, 51075, 51079, 51084, 51089,
+ 51094, 51099, 51104, 51109, 51114, 51119, 51124, 51129, 51134, 51139,
+ 51144, 51149, 51154, 51160, 0, 51167, 51170, 51173, 51176, 51179, 51182,
+ 51185, 51188, 51191, 51194, 51198, 51202, 51206, 51210, 51214, 51218,
+ 51222, 51226, 51230, 51234, 51238, 51242, 51246, 51250, 51254, 51258,
+ 51262, 51266, 51270, 51274, 51278, 51282, 51286, 51290, 51294, 51298, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51302, 51305, 51310, 51315, 51320,
+ 51325, 51330, 51335, 51340, 51345, 51350, 51354, 51359, 51364, 51369,
+ 51374, 51379, 51383, 51387, 51391, 51395, 51399, 51403, 51407, 51411,
+ 51415, 51419, 51423, 51427, 51431, 51435, 51440, 51445, 51450, 51455,
+ 51460, 51465, 51470, 51475, 51480, 51485, 51490, 51495, 51500, 51505,
+ 51511, 51517, 51522, 51527, 51530, 51533, 51536, 51539, 51542, 51545,
+ 51548, 51551, 51554, 51558, 51562, 51566, 51570, 51574, 51578, 51582,
+ 51586, 51590, 51594, 51598, 51602, 51606, 51610, 51614, 51618, 51622,
+ 51626, 51630, 51634, 51638, 51642, 51646, 51650, 51654, 51658, 51662,
+ 51666, 51670, 51674, 51678, 51681, 51685, 51689, 51693, 51697, 51701,
+ 51705, 51709, 51713, 51718, 51723, 51728, 51733, 51737, 51742, 51747,
+ 51752, 51757, 51762, 51767, 51772, 51777, 51782, 51786, 51792, 51798,
+ 51804, 51810, 51816, 51822, 51828, 51834, 51840, 51846, 51852, 51858,
+ 51861, 51864, 51867, 51872, 51875, 51878, 51881, 51884, 51887, 51890,
+ 51894, 51898, 51902, 51906, 51910, 51914, 51918, 51922, 51926, 51930,
+ 51934, 51938, 51942, 51945, 51949, 51953, 51957, 51961, 51965, 51968,
+ 51972, 51976, 51980, 51984, 51987, 51991, 51995, 51999, 52003, 52006,
+ 52010, 52014, 52018, 52022, 52026, 52030, 52034, 52038, 52042, 52046, 0,
+ 52050, 52053, 52056, 52059, 52062, 52065, 52068, 52071, 52074, 52077,
+ 52080, 52083, 52086, 52089, 52092, 52095, 52098, 52101, 52104, 52107,
+ 52110, 52113, 52116, 52119, 52122, 52125, 52128, 52131, 52134, 52137,
+ 52140, 52143, 52146, 52149, 52152, 52155, 52158, 52161, 52164, 52167,
+ 52170, 52173, 52176, 52179, 52182, 52185, 52188, 52191, 52194, 52197,
+ 52200, 52203, 52206, 52209, 52212, 52215, 52218, 52221, 52224, 52227,
+ 52230, 52233, 52236, 52239, 52242, 52245, 52248, 52251, 52254, 52257,
+ 52260, 52263, 52266, 52269, 52272, 52275, 52278, 52281, 52284, 52287,
+ 52290, 52293, 52296, 52299, 52302, 52305, 52308, 52311, 52314, 52322,
+ 52329, 52336, 52343, 52350, 52357, 52364, 52371, 52378, 52385, 52393,
+ 52401, 52409, 52417, 52425, 52433, 52441, 52449, 52457, 52465, 52473,
+ 52481, 52489, 52497, 52505, 52508, 52511, 52514, 52516, 52519, 52522,
+ 52525, 52530, 52535, 52538, 52545, 52552, 52559, 52566, 52569, 52574,
+ 52577, 52581, 52583, 52585, 52588, 52591, 52594, 52597, 52600, 52603,
+ 52606, 52611, 52615, 52618, 52621, 52624, 52627, 52630, 52633, 52636,
+ 52640, 52643, 52646, 52649, 52652, 52655, 52659, 52662, 52665, 52668,
+ 52673, 52678, 52683, 52688, 52693, 52698, 52703, 52708, 52714, 52723,
+ 52726, 52729, 52732, 52735, 52738, 52744, 52753, 52756, 52759, 52763,
+ 52766, 52769, 52772, 52776, 52779, 52782, 52787, 52790, 52793, 52798,
+ 52801, 52804, 52809, 52814, 52819, 52822, 52825, 52828, 52831, 52838,
+ 52841, 52844, 52847, 52849, 52852, 52855, 52858, 52863, 52866, 52869,
+ 52872, 52875, 52878, 52883, 52886, 52889, 52892, 52895, 52898, 52901,
+ 52904, 52907, 52910, 52916, 52921, 52928, 52935, 52942, 52949, 52956,
+ 52963, 52970, 52977, 52984, 52992, 53000, 53008, 53016, 53024, 53032,
+ 53040, 53048, 53056, 53064, 53072, 53080, 53088, 53096, 53104, 53112,
+ 53120, 53128, 53136, 53144, 53152, 53160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 53163, 53171, 53179, 53189, 53195, 53199, 53203, 53209,
+ 53215, 53220, 53224, 53228, 53232, 53236, 53242, 53246, 53250, 53254,
+ 53264, 53268, 53272, 53278, 53282, 53288, 53292, 53296, 53302, 53308,
+ 53314, 53322, 53330, 53334, 53338, 53342, 53348, 53352, 53361, 53367,
+ 53371, 53375, 53379, 53383, 53387, 53391, 53398, 53404, 53410, 53414,
+ 53420, 53424, 53430, 53438, 53448, 53452, 53460, 53464, 53470, 53478,
+ 53486, 53490, 53494, 53500, 53505, 53511, 53517, 53521, 53525, 53528,
+ 53532, 53536, 53540, 53544, 53548, 53552, 53556, 53559, 53563, 53567,
+ 53571, 53575, 53579, 53583, 53586, 53590, 53594, 53597, 53601, 53605,
+ 53609, 53613, 53617, 53621, 53625, 53629, 53633, 53637, 53641, 53645,
+ 53649, 53653, 53657, 53661, 53665, 53669, 53673, 53677, 53681, 53685,
+ 53689, 53693, 53697, 53701, 53705, 53709, 53713, 53717, 53721, 53725,
+ 53729, 53733, 53737, 53741, 53745, 53749, 53753, 53757, 53761, 53765,
+ 53769, 53773, 53777, 53781, 53785, 53789, 53793, 53797, 53801, 53805,
+ 53809, 53813, 53817, 53821, 53825, 53829, 53833, 53837, 53841, 53845,
+ 53849, 53853, 53857, 53861, 53865, 53869, 53873, 53877, 53881, 53885,
+ 53889, 53893, 53897, 53901, 53905, 53909, 53913, 53917, 53921, 53925,
+ 53929, 53933, 53937, 53941, 53945, 53949, 53953, 53957, 53961, 53965,
+ 53969, 53973, 53977, 53981, 53985, 53989, 53993, 53997, 54001, 54005,
+ 54009, 54013, 54017, 54021, 54025, 54029, 54033, 54037, 54041, 54045,
+ 54049, 54053, 54057, 54061, 54065, 54069, 54073, 54077, 54081, 54085,
+ 54089, 54093, 54097, 54101, 54105, 54109, 54113, 54117, 54121, 54125,
+ 54129, 54133, 54137, 54141, 54145, 54149, 54153, 54157, 54161, 54165,
+ 54169, 54173, 54177, 54181, 54185, 54189, 54193, 54197, 54201, 54205,
+ 54209, 54213, 54217, 54221, 54225, 54229, 54233, 54237, 54241, 54245,
+ 54248, 54252, 54256, 54260, 54264, 54268, 54272, 54276, 54280, 54284,
+ 54288, 54292, 54296, 54300, 54304, 54308, 54312, 54316, 54320, 54324,
+ 54328, 54332, 54336, 54340, 54344, 54348, 54352, 54356, 54360, 54364,
+ 54368, 54372, 54376, 54380, 54384, 54388, 54392, 54396, 54400, 54404,
+ 54408, 54412, 54416, 54420, 54424, 54428, 54432, 54436, 54440, 54444,
+ 54448, 54452, 54456, 54460, 54464, 54468, 54472, 54476, 54480, 54484,
+ 54488, 54492, 54496, 54500, 54504, 54508, 54512, 54516, 54520, 54524,
+ 54528, 54532, 54536, 54540, 54544, 54548, 54552, 54556, 54560, 54564,
+ 54568, 54572, 54576, 54580, 54584, 54588, 54592, 54596, 54600, 54604,
+ 54608, 54612, 54616, 54620, 54624, 54628, 54632, 54636, 54640, 54644,
+ 54648, 54652, 54656, 54660, 54664, 54668, 54672, 54676, 54680, 54684,
+ 54688, 54692, 54696, 54700, 54704, 54708, 54711, 54715, 54719, 54723,
+ 54727, 54731, 54735, 54739, 54743, 54747, 54751, 54755, 54759, 54763,
+ 54767, 54771, 54775, 54779, 54783, 54787, 54791, 54795, 54799, 54803,
+ 54807, 54811, 54815, 54819, 54823, 54827, 54831, 54835, 54839, 54843,
+ 54847, 54851, 54855, 54859, 54863, 54867, 54871, 54875, 54879, 54883,
+ 54887, 54891, 54895, 54899, 54903, 54907, 54911, 54915, 54919, 54923,
+ 54927, 54931, 54935, 54939, 54943, 54947, 54951, 54955, 54959, 54963,
+ 54967, 54971, 54975, 54979, 54983, 54987, 54991, 54995, 54999, 55003,
+ 55007, 55011, 55015, 55019, 55023, 55027, 55031, 55035, 55039, 55043,
+ 55047, 55051, 55055, 55059, 55063, 55067, 55071, 55075, 55079, 55083,
+ 55087, 55091, 55095, 55099, 55103, 55107, 55111, 55115, 55119, 55123,
+ 55127, 55131, 55135, 55139, 55143, 55147, 55151, 55155, 55159, 55163,
+ 55167, 55171, 55175, 55179, 55183, 55187, 55191, 55195, 55199, 55203,
+ 55207, 55211, 55215, 55219, 55223, 55227, 55231, 55235, 55239, 55243,
+ 55247, 55251, 55255, 55259, 55263, 55267, 55271, 55275, 55279, 55283,
+ 55287, 55291, 55295, 55299, 55303, 55307, 55311, 55315, 55319, 55323,
+ 55327, 55331, 55335, 55339, 55343, 55347, 55351, 55355, 55359, 55363,
+ 55367, 55371, 55375, 55379, 55383, 55387, 55391, 55395, 55399, 55403,
+ 55407, 55411, 55415, 55419, 55423, 55427, 55431, 55435, 55439, 55443,
+ 55447, 55451, 55455, 55459, 55463, 55467, 55471, 55475, 55479, 55483,
+ 55487, 55491, 55495, 55499, 55503, 55507, 55511, 55515, 55519, 55523,
+ 55527, 55531, 55535, 55539, 55543, 55547, 55551, 55555, 55559, 55563,
+ 55566, 55570, 55574, 55578, 55582, 55586, 55590, 55594, 55598, 55602,
+ 55606, 55610, 55614, 55618, 55622, 55626, 55630, 55634, 55638, 55642,
+ 55646, 55650, 55654, 55658, 55662, 55666, 55670, 55674, 55678, 55682,
+ 55686, 55690, 55694, 55698, 55702, 55706, 55710, 55714, 55718, 55722,
+ 55726, 55730, 55734, 55738, 55742, 55746, 55750, 55754, 55758, 55762,
+ 55766, 55770, 55774, 55778, 55782, 55786, 55790, 55794, 55798, 55802,
+ 55806, 55810, 55814, 55818, 55822, 55826, 55830, 55834, 55838, 55842,
+ 55846, 55850, 55854, 55858, 55862, 55866, 55870, 55874, 55878, 55882,
+ 55886, 55890, 55894, 55898, 55902, 55906, 55910, 55914, 55918, 55922,
+ 55926, 55930, 55934, 55938, 55942, 55946, 55950, 55954, 55958, 55962,
+ 55966, 55970, 55974, 55978, 55982, 55986, 55990, 55994, 55998, 56002,
+ 56006, 56010, 56014, 56018, 56021, 56025, 56029, 56033, 56037, 56041,
+ 56045, 56049, 56053, 56057, 56061, 56065, 56069, 56073, 56077, 56081,
+ 56085, 56089, 56093, 56097, 56101, 56105, 56109, 56113, 56117, 56121,
+ 56125, 56129, 56133, 56137, 56141, 56145, 56149, 56153, 56157, 56161,
+ 56165, 56169, 56173, 56177, 56181, 56185, 56189, 56193, 56197, 56201,
+ 56205, 56209, 56213, 56217, 56221, 56225, 56229, 56233, 56237, 56241,
+ 56245, 56249, 56253, 56257, 56261, 56265, 56269, 56273, 56277, 56281,
+ 56285, 56289, 56293, 56297, 56301, 56305, 56309, 56313, 56317, 56321,
+ 56325, 56329, 56333, 56337, 56341, 56345, 56349, 56353, 56357, 56361,
+ 56365, 56369, 56373, 56377, 56381, 56385, 56389, 56393, 56397, 56401,
+ 56405, 56409, 56413, 56417, 56421, 56425, 56429, 56433, 56437, 56441,
+ 56445, 56449, 56453, 56457, 56461, 56465, 56469, 56473, 56477, 56481,
+ 56485, 56489, 56493, 56497, 56501, 56505, 56509, 56513, 56517, 56521,
+ 56525, 56529, 56533, 56537, 56541, 56545, 56549, 56553, 56557, 56561,
+ 56565, 56569, 56573, 56577, 56581, 56585, 56589, 56593, 56597, 56601,
+ 56605, 56609, 56613, 56617, 56621, 56624, 56628, 56632, 56636, 56640,
+ 56644, 56648, 56652, 56656, 56660, 56664, 56668, 56672, 56676, 56680,
+ 56684, 56688, 56692, 56696, 56700, 56704, 56708, 56712, 56716, 56720,
+ 56724, 56728, 56732, 56736, 56740, 56744, 56748, 56752, 56756, 56760,
+ 56764, 56768, 56772, 56776, 56780, 56784, 56788, 56792, 56796, 56800,
+ 56804, 56808, 56812, 56816, 56820, 56824, 56828, 56832, 56836, 56840,
+ 56844, 56848, 56852, 56856, 56860, 56864, 56868, 56872, 56876, 56880,
+ 56884, 56888, 56892, 56896, 56900, 56904, 56908, 56912, 56916, 56920,
+ 56924, 56928, 56932, 56936, 56940, 56944, 56948, 56952, 56956, 56960,
+ 56964, 56968, 56972, 56976, 56980, 56984, 56988, 56992, 56996, 57000,
+ 57004, 57008, 57012, 57016, 57020, 57024, 57028, 57032, 57036, 57040,
+ 57044, 57048, 57052, 57056, 57060, 57064, 57068, 57072, 57076, 57080,
+ 57084, 57088, 57092, 57096, 57100, 57104, 57108, 57112, 57116, 57120,
+ 57124, 57128, 57132, 57136, 57140, 57144, 57148, 57152, 57156, 57160,
+ 57164, 57168, 57172, 57176, 57180, 57184, 57188, 57192, 57196, 57200,
+ 57204, 57208, 57212, 57216, 57220, 57224, 57228, 57232, 57236, 57240,
+ 57244, 57248, 57252, 57256, 57260, 57264, 57268, 57272, 57276, 57280,
+ 57284, 57288, 57292, 57296, 57300, 57304, 57308, 57312, 57316, 57320,
+ 57324, 57328, 57332, 57336, 57340, 57344, 57348, 57352, 57356, 57360,
+ 57364, 57368, 57372, 57376, 57380, 57384, 57388, 57392, 57396, 57400,
+ 57404, 57408, 57412, 57416, 57420, 57424, 57428, 57432, 57436, 57440,
+ 57444, 57448, 57452, 57456, 57460, 57464, 57468, 57472, 57476, 57480,
+ 57484, 57488, 57492, 57496, 57500, 57504, 57508, 57512, 57516, 57520,
+ 57524, 57528, 57532, 57536, 57540, 57544, 57548, 57552, 57556, 57560,
+ 57564, 57568, 57572, 57576, 57580, 57584, 57588, 57592, 57596, 57600,
+ 57604, 57608, 57612, 57616, 57620, 57624, 57628, 57632, 57636, 57640,
+ 57644, 57648, 57652, 57656, 57660, 57664, 57668, 57672, 57676, 57680,
+ 57684, 57688, 57692, 57696, 57700, 57704, 57708, 57712, 57716, 57720,
+ 57724, 57728, 57732, 57736, 57740, 57744, 57748, 57752, 57756, 57760,
+ 57764, 57768, 57772, 57776, 57780, 57784, 57788, 57792, 57796, 57800,
+ 57804, 57808, 57812, 57816, 57820, 57824, 57828, 57832, 57836, 57840,
+ 57844, 57848, 57852, 57856, 57860, 57864, 57868, 57872, 57876, 57880,
+ 57884, 57888, 57892, 57896, 57900, 57904, 57908, 57912, 57916, 57920,
+ 57924, 57928, 57932, 57936, 57940, 57944, 57948, 57952, 57956, 57960,
+ 57964, 57968, 57972, 57976, 57980, 57984, 57988, 57992, 57996, 58000,
+ 58004, 58008, 58012, 58016, 58020, 58024, 58028, 58032, 58036, 58040,
+ 58044, 58048, 58052, 58056, 58060, 58064, 58068, 58072, 58076, 58080,
+ 58084, 58088, 58092, 58096, 58100, 58104, 58108, 58112, 58116, 58120,
+ 58124, 58128, 58132, 58136, 58140, 58144, 58148, 58152, 58156, 58160,
+ 58164, 0, 0, 0, 58168, 58172, 58176, 58180, 58184, 58188, 58192, 58196,
+ 58200, 58204, 58208, 58212, 58216, 58220, 58224, 58228, 58232, 58236,
+ 58240, 58244, 58248, 58252, 58256, 58260, 58264, 58268, 58272, 58276,
+ 58280, 58284, 58288, 58292, 58296, 58300, 58304, 58308, 58312, 58316,
+ 58320, 58324, 58328, 58332, 58336, 58340, 58344, 58348, 58352, 58356,
+ 58360, 58364, 58368, 58372, 58376, 58380, 58384, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 58388, 58397, 58406, 58415, 58424, 58433, 58442, 58451, 58460, 58468,
+ 58475, 58483, 58490, 58498, 58508, 58517, 58527, 58536, 58546, 58554,
+ 58561, 58569, 58576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58584, 58590, 58596,
+ 58603, 58609, 58615, 58621, 58628, 58635, 58642, 58649, 58656, 58663,
+ 58670, 58677, 58684, 58691, 58698, 58705, 58712, 58719, 58725, 58732,
+ 58739, 58746, 58753, 58760, 58767, 58774, 58781, 58788, 58795, 58802,
+ 58809, 58816, 58823, 58830, 58837, 58844, 58851, 58859, 58867, 58875,
+ 58883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58891, 58895, 58899, 58903,
+ 58907, 58911, 58915, 58919, 58923, 58927, 58931, 58935, 58939, 58943,
+ 58947, 58951, 58955, 58959, 58963, 58967, 58971, 58975, 58979, 58983,
+ 58987, 58991, 58995, 58999, 59003, 59007, 59011, 59015, 59019, 59023,
+ 59027, 59031, 59035, 59039, 59043, 59047, 59051, 59055, 59059, 59063,
+ 59067, 59071, 59075, 59079, 59083, 59087, 59091, 59095, 59099, 59103,
+ 59107, 59111, 59115, 59119, 59123, 59127, 59131, 59135, 59139, 59143,
+ 59147, 59151, 59155, 59159, 59163, 59167, 59171, 59175, 59179, 59183,
+ 59187, 59191, 59195, 59199, 59203, 59207, 59211, 59215, 59219, 59223,
+ 59227, 59231, 59235, 59239, 59243, 59247, 59251, 59255, 59259, 59263,
+ 59267, 59271, 59275, 59279, 59283, 59287, 59291, 59295, 59299, 59303,
+ 59307, 59311, 59315, 59319, 59323, 59327, 59331, 59335, 59339, 59343,
+ 59347, 59351, 59355, 59359, 59363, 59367, 59371, 59375, 59379, 59383,
+ 59387, 59391, 59395, 59399, 59403, 59407, 59411, 59415, 59419, 59423,
+ 59427, 59431, 59435, 59439, 59443, 59447, 59451, 59455, 59459, 59463,
+ 59467, 59471, 59475, 59479, 59483, 59487, 59491, 59495, 59499, 59503,
+ 59507, 59511, 59515, 59519, 59523, 59527, 59531, 59535, 59539, 59543,
+ 59547, 59551, 59555, 59559, 59563, 59567, 59571, 59575, 59579, 59583,
+ 59587, 59591, 59595, 59599, 59603, 59607, 59611, 59615, 59619, 59623,
+ 59627, 59631, 59635, 59639, 59643, 59647, 59651, 59655, 59659, 59663,
+ 59667, 59671, 59675, 59679, 59683, 59687, 59691, 59695, 59699, 59703,
+ 59707, 59711, 59715, 59719, 59723, 59727, 59731, 59735, 59739, 59743,
+ 59747, 59751, 59755, 59759, 59763, 59767, 59771, 59775, 59779, 59783,
+ 59787, 59791, 59795, 59799, 59803, 59807, 59811, 59815, 59819, 59823,
+ 59827, 59831, 59835, 59839, 59843, 59847, 59851, 59855, 59859, 59863,
+ 59867, 59871, 59875, 59879, 59883, 59887, 59891, 59895, 59899, 59903,
+ 59907, 59911, 59915, 59919, 59923, 59927, 59931, 59935, 59939, 59943,
+ 59947, 59951, 59955, 59959, 59963, 59967, 59971, 59975, 59979, 59983,
+ 59987, 59991, 59995, 59999, 60003, 60007, 60011, 60015, 60019, 60023,
+ 60027, 60031, 60035, 60039, 60043, 60047, 60051, 60055, 60059, 60063,
+ 60067, 60071, 60075, 60079, 60083, 60087, 60091, 60095, 0, 0, 60099,
+ 60103, 60107, 60111, 60115, 60119, 60123, 60127, 60131, 60135, 60139,
+ 60143, 60147, 60151, 60155, 60159, 60163, 60167, 60171, 60175, 60179,
+ 60183, 60187, 60191, 60195, 60199, 60203, 60207, 60211, 60215, 60219,
+ 60223, 60227, 60231, 60235, 60239, 60243, 60247, 60251, 60255, 60259,
+ 60263, 60267, 60271, 60275, 60279, 60283, 60287, 60291, 60295, 60299,
+ 60303, 60307, 60311, 60315, 60319, 60323, 60327, 60331, 0, 0, 0, 0, 0,
+ 60335, 60339, 60343, 60347, 60351, 60355, 60359, 60363, 60367, 60371,
+ 60375, 60379, 60383, 60387, 60391, 60395, 60399, 60403, 60407, 60411,
+ 60415, 60419, 60423, 60427, 60431, 60435, 60439, 60443, 60447, 60451,
+ 60455, 60459, 60463, 60467, 60471, 60475, 60479, 60483, 60487, 60491,
+ 60495, 60499, 60503, 60507, 60511, 60515, 60519, 60523, 60527, 60531,
+ 60535, 60539, 60543, 60547, 60551, 60555, 60559, 60563, 60567, 60571,
+ 60575, 60579, 60583, 60587, 60591, 60595, 60599, 60603, 60607, 60611,
+ 60615, 60619, 60623, 60627, 60631, 60635, 60639, 60643, 60647, 60651,
+ 60655, 60659, 60663, 60667, 60671, 60675, 60679, 60683, 60687, 60691,
+ 60695, 60699, 60703, 60707, 60711, 60715, 60719, 60723, 60727, 60731,
+ 60735, 60739, 60743, 60747, 60751, 60755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 60759, 60764, 60769, 60774, 60779, 60784, 60791, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 60796, 60803, 60810, 60817, 60824, 0, 0, 0, 0, 0,
+ 60831, 60838, 60845, 60855, 60861, 60867, 60873, 60879, 60885, 60891,
+ 60898, 60904, 60910, 60917, 60926, 60935, 60947, 60959, 60965, 60971,
+ 60977, 60984, 60991, 60998, 61005, 61012, 0, 61019, 61026, 61033, 61041,
+ 61048, 0, 61055, 0, 61062, 61069, 0, 61076, 61084, 0, 61091, 61098,
+ 61105, 61112, 61119, 61126, 61133, 61140, 61147, 61154, 61159, 61166,
+ 61173, 61179, 61185, 61191, 61197, 61203, 61209, 61215, 61221, 61227,
+ 61233, 61239, 61245, 61251, 61257, 61263, 61269, 61275, 61281, 61287,
+ 61293, 61299, 61305, 61311, 61317, 61323, 61329, 61335, 61341, 61347,
+ 61353, 61359, 61365, 61371, 61377, 61383, 61389, 61395, 61401, 61407,
+ 61413, 61419, 61425, 61431, 61437, 61443, 61449, 61455, 61461, 61467,
+ 61473, 61479, 61485, 61491, 61497, 61503, 61509, 61515, 61521, 61527,
+ 61533, 61539, 61545, 61551, 61557, 61563, 61569, 61575, 61581, 61587,
+ 61593, 61599, 61605, 61611, 61617, 61623, 61629, 61636, 61643, 61649,
+ 61655, 61661, 61667, 61676, 61685, 61693, 61701, 61709, 61717, 61725,
+ 61733, 61741, 61749, 61756, 61763, 61773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 61783, 61789, 61795, 61801, 61807, 61812, 61817, 61823, 61829, 61835,
+ 61841, 61849, 61855, 61861, 61869, 61877, 61885, 61893, 61898, 61903,
+ 61908, 61913, 61925, 61937, 61947, 61957, 61968, 61979, 61990, 62001,
+ 62011, 62021, 62032, 62043, 62054, 62065, 62075, 62085, 62095, 62110,
+ 62125, 62140, 62147, 62154, 62161, 62168, 62178, 62188, 62198, 62209,
+ 62219, 62227, 62235, 62243, 62251, 62260, 62268, 62276, 62284, 62292,
+ 62300, 62309, 62317, 62325, 62333, 62342, 62350, 62357, 62364, 62371,
+ 62378, 62385, 62392, 62399, 62407, 62415, 62423, 62431, 62439, 62447,
+ 62455, 62463, 62471, 62479, 62487, 62495, 62503, 62511, 62519, 62527,
+ 62535, 62543, 62551, 62559, 62567, 62576, 62584, 62592, 62600, 62609,
+ 62617, 62625, 62633, 62641, 62649, 62657, 62665, 62674, 62682, 62689,
+ 62696, 62703, 62710, 62718, 62725, 62732, 62739, 62746, 62753, 62761,
+ 62768, 62775, 62782, 62789, 62796, 62804, 62811, 62819, 62827, 62836,
+ 62844, 62851, 62858, 62865, 62872, 62880, 62887, 62897, 62907, 62917,
+ 62926, 62935, 62944, 62953, 62962, 62972, 62983, 62994, 63004, 63014,
+ 63025, 63035, 63044, 63053, 63061, 63069, 63078, 63086, 63095, 63104,
+ 63112, 63120, 63129, 63137, 63146, 63155, 63163, 63171, 63180, 63188,
+ 63197, 63205, 63214, 63222, 63230, 63238, 63246, 63255, 63263, 63270,
+ 63278, 63285, 63292, 63299, 63307, 63315, 63322, 63329, 63337, 63344,
+ 63354, 63362, 63370, 63377, 63384, 63392, 63399, 63409, 63419, 63429,
+ 63439, 63450, 63458, 63466, 63474, 63482, 63491, 63499, 63507, 63515,
+ 63523, 63532, 63540, 63547, 63554, 63561, 63568, 63575, 63582, 63590,
+ 63598, 63606, 63614, 63622, 63630, 63638, 63646, 63654, 63662, 63670,
+ 63678, 63686, 63694, 63702, 63710, 63718, 63726, 63734, 63742, 63750,
+ 63758, 63766, 63774, 63782, 63790, 63798, 63806, 63813, 63820, 63827,
+ 63834, 63842, 63849, 63856, 63863, 63870, 63877, 63884, 63891, 63898,
+ 63906, 63914, 63922, 63932, 63939, 63946, 63953, 63960, 63968, 63978,
+ 63989, 63997, 64006, 64014, 64023, 64031, 64040, 64048, 64057, 64065,
+ 64074, 64082, 64090, 64097, 64104, 64112, 64119, 64127, 64136, 64145,
+ 64154, 64163, 64171, 64180, 64188, 64197, 64205, 64214, 64222, 64231,
+ 64239, 64247, 64254, 64262, 64269, 64277, 64284, 64293, 64301, 64310,
+ 64318, 64326, 64334, 64342, 64350, 64359, 64368, 64377, 64386, 64395,
+ 64403, 64412, 64420, 64429, 64437, 64446, 64454, 64463, 64471, 64479,
+ 64486, 64494, 64501, 64509, 64516, 64525, 64533, 64542, 64550, 64558,
+ 64566, 64574, 64582, 64591, 64600, 64609, 64618, 64626, 64634, 64642,
+ 64650, 64659, 64668, 64676, 64684, 64692, 64700, 64708, 64716, 64724,
+ 64732, 64740, 64748, 64756, 64761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 64766, 64776, 64786, 64796, 64806, 64816, 64826, 64836, 64846,
+ 64855, 64864, 64873, 64883, 64893, 64903, 64914, 64924, 64934, 64944,
+ 64954, 64964, 64974, 64984, 64994, 65004, 65014, 65024, 65034, 65044,
+ 65054, 65064, 65075, 65085, 65095, 65105, 65115, 65125, 65135, 65145,
+ 65155, 65165, 65176, 65186, 65196, 65207, 65217, 65227, 65237, 65247,
+ 65256, 65265, 65275, 65284, 65293, 65302, 65311, 65320, 65329, 65338,
+ 65347, 65356, 65365, 65374, 65383, 0, 0, 65392, 65401, 65411, 65421,
+ 65430, 65440, 65449, 65458, 65468, 65477, 65487, 65496, 65505, 65515,
+ 65525, 65536, 65546, 65557, 65567, 65578, 65587, 65597, 65607, 65618,
+ 65628, 65638, 65648, 65657, 65666, 65675, 65684, 65693, 65702, 65712,
+ 65721, 65731, 65740, 65750, 65760, 65769, 65778, 65787, 65797, 65806,
+ 65815, 65824, 65833, 65842, 65852, 65862, 65872, 65882, 65892, 65902, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65911, 65926, 65941, 65947,
+ 65953, 65959, 65965, 65971, 65977, 65983, 65989, 65997, 66001, 66004, 0,
+ 0, 66012, 66015, 66018, 66021, 66024, 66027, 66030, 66033, 66036, 66039,
+ 66042, 66045, 66048, 66051, 66054, 66057, 66060, 66068, 66077, 66087,
+ 66095, 66103, 66112, 66121, 66132, 66144, 0, 0, 0, 0, 0, 0, 66153, 66158,
+ 66163, 66170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66177, 66187, 66197,
+ 66207, 66216, 66227, 66236, 66245, 66255, 66265, 66277, 66289, 66300,
+ 66311, 66321, 66331, 66340, 66349, 66359, 66369, 66380, 66391, 66395,
+ 66400, 66409, 66418, 66422, 66426, 66430, 66435, 66440, 66445, 66450,
+ 66453, 66457, 0, 66461, 66464, 66467, 66471, 66475, 66480, 66484, 66488,
+ 66493, 66498, 66505, 66512, 66515, 66518, 66521, 66525, 66528, 66532,
+ 66536, 0, 66540, 66545, 66549, 66553, 0, 0, 0, 0, 66558, 66563, 66570,
+ 66575, 66580, 0, 66585, 66590, 66595, 66600, 66605, 66610, 66615, 66620,
+ 66625, 66630, 66635, 66640, 66649, 66658, 66666, 66674, 66683, 66692,
+ 66701, 66710, 66718, 66726, 66734, 66742, 66747, 66752, 66758, 66764,
+ 66770, 66776, 66784, 66792, 66798, 66804, 66810, 66816, 66822, 66828,
+ 66834, 66840, 66845, 66850, 66855, 66860, 66865, 66870, 66875, 66880,
+ 66885, 66890, 66895, 66900, 66906, 66912, 66918, 66924, 66930, 66936,
+ 66942, 66948, 66954, 66960, 66966, 66972, 66978, 66984, 66990, 66996,
+ 67002, 67008, 67014, 67020, 67026, 67032, 67038, 67044, 67050, 67056,
+ 67062, 67068, 67074, 67080, 67086, 67092, 67098, 67104, 67110, 67116,
+ 67122, 67128, 67134, 67140, 67146, 67152, 67158, 67164, 67170, 67176,
+ 67182, 67188, 67194, 67200, 67206, 67212, 67217, 67222, 67227, 67232,
+ 67237, 67242, 67247, 67252, 67257, 67262, 67267, 67272, 67278, 67284,
+ 67290, 67296, 67302, 67308, 67314, 67320, 67325, 67330, 67335, 67340,
+ 67351, 67362, 67372, 67382, 67393, 67404, 67411, 0, 0, 67418, 0, 67426,
+ 67430, 67434, 67437, 67441, 67445, 67448, 67451, 67455, 67459, 67462,
+ 67466, 67469, 67472, 67476, 67479, 67483, 67486, 67489, 67492, 67495,
+ 67498, 67501, 67504, 67507, 67510, 67513, 67516, 67520, 67524, 67528,
+ 67532, 67537, 67542, 67547, 67553, 67558, 67563, 67569, 67574, 67579,
+ 67584, 67589, 67595, 67600, 67605, 67610, 67615, 67620, 67626, 67631,
+ 67636, 67641, 67646, 67651, 67657, 67662, 67668, 67674, 67678, 67683,
+ 67687, 67691, 67695, 67700, 67705, 67710, 67716, 67721, 67726, 67732,
+ 67737, 67742, 67747, 67752, 67758, 67763, 67768, 67773, 67778, 67783,
+ 67789, 67794, 67799, 67804, 67809, 67814, 67820, 67825, 67831, 67837,
+ 67842, 67846, 67851, 67853, 67858, 67863, 67868, 67873, 67878, 67882,
+ 67888, 67893, 67898, 67903, 67908, 67913, 67918, 67923, 67929, 67935,
+ 67941, 67949, 67953, 67957, 67961, 67965, 67969, 67973, 67978, 67983,
+ 67988, 67993, 67998, 68003, 68008, 68013, 68018, 68023, 68028, 68033,
+ 68038, 68042, 68047, 68052, 68057, 68062, 68067, 68071, 68076, 68081,
+ 68086, 68091, 68095, 68100, 68105, 68110, 68115, 68119, 68124, 68129,
+ 68134, 68139, 68144, 68149, 68154, 68159, 68163, 68170, 68177, 68181,
+ 68186, 68191, 68196, 68201, 68206, 68211, 68216, 68221, 68226, 68231,
+ 68236, 68241, 68246, 68251, 68256, 68261, 68266, 68271, 68276, 68281,
+ 68286, 68291, 68296, 68301, 68306, 68311, 68316, 68321, 68326, 0, 0, 0,
+ 68331, 68335, 68340, 68344, 68349, 68354, 0, 0, 68358, 68363, 68368,
+ 68372, 68377, 68382, 0, 0, 68387, 68392, 68396, 68401, 68406, 68411, 0,
+ 0, 68416, 68421, 68426, 0, 0, 0, 68430, 68434, 68438, 68441, 68443,
+ 68447, 68451, 0, 68455, 68461, 68464, 68468, 68471, 68475, 68479, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68483, 68489, 68495, 68501, 68507, 0, 0, 68511,
+ 68517, 68523, 68529, 68535, 68541, 68548, 68555, 68562, 68569, 68576,
+ 68583, 0, 68590, 68597, 68604, 68610, 68617, 68624, 68631, 68638, 68644,
+ 68651, 68658, 68665, 68672, 68679, 68686, 68693, 68700, 68707, 68714,
+ 68721, 68728, 68735, 68742, 68749, 68756, 68763, 0, 68770, 68777, 68784,
+ 68791, 68798, 68805, 68812, 68819, 68826, 68833, 68840, 68847, 68854,
+ 68861, 68867, 68874, 68881, 68888, 68895, 0, 68902, 68909, 0, 68916,
+ 68923, 68930, 68937, 68944, 68951, 68958, 68965, 68972, 68979, 68986,
+ 68993, 69000, 69007, 69014, 0, 0, 69020, 69025, 69030, 69035, 69040,
+ 69045, 69050, 69055, 69060, 69065, 69070, 69075, 69080, 69085, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 69090, 69097, 69104, 69111, 69118, 69125, 69132,
+ 69139, 69146, 69153, 69160, 69167, 69174, 69181, 69188, 69195, 69202,
+ 69209, 69216, 69223, 69231, 69239, 69246, 69253, 69258, 69266, 69274,
+ 69281, 69288, 69293, 69300, 69305, 69310, 69317, 69322, 69327, 69332,
+ 69340, 69345, 69350, 69357, 69362, 69367, 69374, 69381, 69386, 69391,
+ 69396, 69401, 69406, 69411, 69416, 69421, 69426, 69433, 69438, 69445,
+ 69450, 69455, 69460, 69465, 69470, 69475, 69480, 69485, 69490, 69495,
+ 69500, 69507, 69514, 69521, 69528, 69534, 69539, 69546, 69551, 69556,
+ 69565, 69572, 69581, 69588, 69593, 69598, 69606, 69611, 69616, 69621,
+ 69626, 69631, 69638, 69643, 69648, 69653, 69658, 69663, 69670, 69677,
+ 69684, 69691, 69698, 69705, 69712, 69719, 69726, 69733, 69740, 69747,
+ 69754, 69761, 69768, 69775, 69782, 69789, 69796, 69803, 69810, 69817,
+ 69824, 69831, 69838, 69845, 69852, 69859, 0, 0, 0, 0, 0, 69866, 69873,
+ 69880, 0, 0, 0, 0, 69884, 69887, 69890, 69893, 69896, 69899, 69902,
+ 69905, 69908, 69911, 69915, 69919, 69923, 69927, 69931, 69935, 69939,
+ 69943, 69947, 69953, 69958, 69963, 69969, 69975, 69981, 69987, 69993,
+ 69999, 70005, 70010, 70015, 70021, 70027, 70033, 70039, 70045, 70051,
+ 70057, 70063, 70069, 70075, 70081, 70087, 70093, 70099, 0, 0, 0, 70105,
+ 70112, 70119, 70126, 70133, 70140, 70149, 70158, 70165, 70172, 70180,
+ 70188, 70196, 70201, 70207, 70215, 70223, 70231, 70239, 70247, 70255,
+ 70265, 70275, 70285, 70295, 70303, 70311, 70319, 70329, 70339, 70349,
+ 70359, 70369, 70377, 70385, 70390, 70395, 70400, 70405, 70412, 70419,
+ 70424, 70430, 70439, 70445, 70451, 70457, 70463, 70469, 70478, 70484,
+ 70490, 70498, 70505, 70513, 70521, 70529, 70537, 70545, 70553, 70561,
+ 70569, 70577, 70582, 70590, 70595, 70600, 70604, 70608, 70612, 70616,
+ 70621, 70626, 70632, 70638, 70642, 70648, 70652, 70656, 70660, 70664,
+ 70668, 70672, 70678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 70682, 70686, 70691, 70696, 70701, 70705, 70710, 70715,
+ 70720, 70725, 70729, 70733, 70738, 70743, 70748, 70753, 70757, 70762,
+ 70767, 70772, 70777, 70782, 70787, 70791, 70796, 70801, 70806, 70811,
+ 70816, 70821, 70826, 0, 70831, 70835, 70839, 70844, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 70849, 70854, 70859, 70864, 70869, 70874, 70879, 70884,
+ 70889, 70894, 70899, 70904, 70909, 70914, 70919, 70924, 70929, 70934,
+ 70939, 70944, 70949, 70954, 70959, 70964, 70969, 70974, 70979, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 70986, 70991, 70996, 71001, 71006, 71011, 71016, 71021, 71026,
+ 71031, 71036, 71041, 71046, 71051, 71056, 71061, 71066, 71071, 71076,
+ 71081, 71086, 71091, 71096, 71101, 71106, 71111, 71116, 71120, 71124,
+ 71128, 0, 71133, 71139, 71143, 71147, 71151, 71155, 71160, 71165, 71170,
+ 71175, 71180, 71185, 71190, 71195, 71200, 71205, 71210, 71215, 71220,
+ 71225, 71230, 71235, 71240, 71245, 71249, 71254, 71259, 71263, 71268,
+ 71273, 71278, 71283, 71288, 71293, 71298, 71303, 71308, 0, 0, 0, 0,
+ 71312, 71317, 71322, 71327, 71332, 71337, 71342, 71347, 71352, 71358,
+ 71362, 71366, 71371, 71376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 71381, 71386, 71391, 71396, 71402, 71407, 71413, 71419, 71425,
+ 71431, 71438, 71444, 71451, 71456, 71461, 71466, 71471, 71475, 71480,
+ 71485, 71490, 71495, 71500, 71505, 71510, 71515, 71520, 71525, 71530,
+ 71535, 71540, 71545, 71550, 71555, 71560, 71565, 71570, 71575, 71580,
+ 71585, 71590, 71595, 71600, 71605, 71611, 71616, 71622, 71628, 71634,
+ 71640, 71647, 71653, 71660, 71665, 71670, 71675, 71680, 71684, 71689,
+ 71694, 71699, 71704, 71709, 71714, 71719, 71724, 71729, 71734, 71739,
+ 71744, 71749, 71754, 71759, 71764, 71769, 71774, 71779, 71784, 71789,
+ 71794, 71799, 71803, 71807, 71811, 71815, 71819, 71823, 71827, 71831,
+ 71835, 71839, 71843, 71847, 71851, 71855, 71859, 71863, 71867, 71871,
+ 71875, 71879, 71883, 71887, 71891, 71895, 71899, 71903, 71907, 71911,
+ 71915, 71919, 71923, 71927, 71931, 71935, 71939, 71943, 71947, 71951,
+ 71955, 71959, 71963, 71967, 71971, 71975, 71979, 71983, 71987, 71991,
+ 71996, 72001, 72006, 72011, 72016, 72021, 72026, 72031, 72036, 72041,
+ 72046, 72051, 72056, 72061, 72066, 72071, 72076, 72081, 72086, 72091,
+ 72095, 72099, 72103, 72107, 72111, 72115, 72119, 72124, 72129, 0, 0,
+ 72134, 72139, 72143, 72147, 72151, 72155, 72159, 72163, 72167, 72171, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72175, 72178, 72181, 72184, 72187,
+ 72190, 0, 0, 72194, 0, 72198, 72201, 72205, 72209, 72213, 72217, 72221,
+ 72225, 72229, 72233, 72237, 72240, 72244, 72248, 72252, 72256, 72260,
+ 72264, 72268, 72272, 72276, 72280, 72284, 72288, 72292, 72296, 72300,
+ 72304, 72308, 72312, 72316, 72320, 72324, 72328, 72332, 72336, 72340,
+ 72344, 72348, 72351, 72355, 72359, 72363, 72367, 0, 72371, 72375, 0, 0,
+ 0, 72379, 0, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 72387, 72390, 72394, 72398, 0, 72403, 72407, 0, 0, 0, 0, 0, 72411, 72416,
+ 72422, 72426, 72430, 72433, 72437, 72441, 0, 72445, 72449, 72453, 0,
+ 72457, 72461, 72465, 72469, 72473, 72477, 72481, 72485, 72489, 72493,
+ 72497, 72501, 72505, 72509, 72513, 72517, 72520, 72523, 72527, 72531,
+ 72535, 72539, 72543, 72547, 72551, 72554, 72558, 0, 0, 0, 0, 72562,
+ 72567, 72571, 0, 0, 0, 0, 72575, 72578, 72581, 72584, 72587, 72590,
+ 72594, 72598, 72604, 0, 0, 0, 0, 0, 0, 0, 0, 72610, 72615, 72621, 72626,
+ 72632, 72637, 72642, 72647, 72653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 72658, 72663, 72668, 72673, 72680, 72687, 72694, 72701, 72706,
+ 72711, 72716, 72721, 72728, 72733, 72740, 72747, 72752, 72757, 72762,
+ 72769, 72774, 72779, 72786, 72793, 72798, 72803, 72808, 72815, 72822,
+ 72829, 72834, 72839, 72846, 72853, 72860, 72867, 72872, 72877, 72882,
+ 72889, 72894, 72899, 72904, 72911, 72920, 72927, 72932, 72937, 72942,
+ 72947, 72952, 72957, 72966, 72973, 72978, 72985, 72992, 72997, 73002,
+ 73007, 73014, 73019, 73026, 73033, 73038, 73043, 73048, 73055, 73062,
+ 73067, 73072, 73079, 73086, 73093, 73098, 73103, 73108, 73113, 73120,
+ 73129, 73138, 73143, 73150, 73159, 73164, 73169, 73174, 73179, 73186,
+ 73193, 73200, 73207, 73212, 73217, 73222, 73229, 73236, 73243, 73248,
+ 73253, 73260, 73265, 73272, 73277, 73284, 73289, 73296, 73303, 73308,
+ 73313, 73318, 73323, 73328, 73333, 73338, 73343, 73348, 73355, 73362,
+ 73369, 73376, 73383, 73392, 73397, 73402, 73409, 73416, 73421, 73428,
+ 73435, 73442, 73449, 73456, 73463, 73468, 73473, 73478, 73483, 73488,
+ 73497, 73506, 73515, 73524, 73533, 73542, 73551, 73560, 73565, 73576,
+ 73587, 73596, 73601, 73606, 73611, 73616, 73625, 73632, 73639, 73646,
+ 73653, 73660, 73667, 73676, 73685, 73696, 73705, 73716, 73725, 73732,
+ 73741, 73752, 73761, 73770, 73779, 73788, 73795, 73802, 73809, 73818,
+ 73827, 73838, 73847, 73856, 73867, 73872, 73877, 73888, 73897, 73906,
+ 73915, 73924, 73935, 73944, 73953, 73964, 73975, 73986, 73997, 74008,
+ 74019, 74026, 74033, 74040, 74047, 74057, 74066, 74073, 74080, 74087,
+ 74098, 74109, 74120, 74131, 74142, 74153, 74164, 74175, 74182, 74189,
+ 74198, 74207, 74214, 74221, 74228, 74237, 74246, 74255, 74262, 74271,
+ 74280, 74289, 74296, 74303, 74308, 74315, 74322, 74329, 74336, 74343,
+ 74350, 74357, 74366, 74375, 74384, 74393, 74400, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 74409, 74415, 74420, 74425, 74432, 74438, 74444, 74450, 74456,
+ 74462, 74468, 74474, 74478, 74482, 74488, 74494, 74500, 74504, 74509,
+ 74514, 74518, 74522, 74525, 74531, 74537, 74543, 74549, 74555, 74561,
+ 74567, 74573, 74579, 74589, 74599, 74605, 74611, 74621, 74631, 74637, 0,
+ 0, 0, 74643, 74648, 74653, 74659, 74665, 74671, 74677, 74683, 74689,
+ 74696, 74703, 74709, 74715, 74721, 74727, 74733, 74739, 74745, 74751,
+ 74756, 74762, 74768, 74774, 74780, 74786, 74796, 74802, 74808, 74815,
+ 74822, 74829, 74838, 74847, 74856, 74865, 74874, 74883, 74892, 74901,
+ 74911, 74921, 74929, 74937, 74946, 74955, 74961, 74967, 74973, 74979,
+ 74987, 74995, 74999, 75005, 75010, 75016, 75022, 75028, 75034, 75040,
+ 75050, 75055, 75062, 75067, 75072, 75077, 75083, 75089, 75095, 75102,
+ 75107, 75112, 75117, 75122, 75127, 75133, 75139, 75145, 75151, 75157,
+ 75163, 75169, 75175, 75180, 75185, 75190, 75195, 75200, 75205, 75210,
+ 75215, 75221, 75227, 75232, 75237, 75242, 75247, 75252, 75258, 75265,
+ 75269, 75273, 75277, 75281, 75285, 75289, 75293, 75297, 75305, 75315,
+ 75319, 75323, 75329, 75335, 75341, 75347, 75353, 75359, 75365, 75371,
+ 75377, 75383, 75389, 75395, 75401, 75407, 75411, 75415, 75422, 75428,
+ 75434, 75440, 75445, 75452, 75457, 75463, 75469, 75475, 75481, 75486,
+ 75490, 75496, 75500, 75504, 75508, 75514, 75520, 75524, 75530, 75536,
+ 75542, 75548, 75554, 75562, 75570, 75576, 75582, 75588, 75594, 75606,
+ 75618, 75632, 75644, 75656, 75670, 75684, 75698, 75702, 75710, 75718,
+ 75722, 75726, 75730, 75734, 75738, 75742, 75746, 75750, 75756, 75762,
+ 75768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75774, 75780, 75786, 75792, 75798,
+ 75804, 75810, 75816, 75822, 75828, 75834, 75840, 75846, 75852, 75858,
+ 75864, 75870, 75876, 75882, 75888, 75894, 75900, 75906, 75912, 75918,
+ 75924, 75930, 75936, 75942, 75948, 75954, 75960, 75966, 75972, 75978,
+ 75984, 75990, 75996, 76002, 76008, 76014, 76020, 76026, 76032, 76038,
+ 76044, 76050, 76056, 76062, 76068, 76074, 76080, 76086, 76092, 76098,
+ 76104, 76110, 76116, 76122, 76128, 76134, 76140, 76146, 76152, 76158,
+ 76164, 76170, 76175, 76180, 76185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76189,
+ 76194, 76201, 76208, 76215, 76222, 76227, 76231, 76237, 76241, 76245,
+ 76251, 76255, 76259, 76263, 76269, 76276, 76280, 76284, 76288, 76292,
+ 76296, 76300, 76306, 76310, 76314, 76318, 76322, 76326, 76330, 76334,
+ 76338, 76342, 76346, 76350, 76354, 76359, 76363, 76367, 76371, 76375,
+ 76379, 76383, 76387, 76391, 76395, 76402, 76406, 76413, 76417, 76421,
+ 76425, 76429, 76433, 76437, 76441, 76448, 76452, 76456, 76460, 76464,
+ 76468, 76474, 76478, 76484, 76488, 76492, 76496, 76500, 76504, 76508,
+ 76512, 76516, 76520, 76524, 76528, 76532, 76536, 76540, 76544, 76548,
+ 76552, 76556, 76560, 76568, 76572, 76576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 76580, 76584, 76588, 76593, 76597, 76601, 76606,
+ 76610, 76614, 76618, 76622, 76627, 76631, 76635, 76639, 76643, 76647,
+ 76652, 76656, 76660, 76664, 76668, 76672, 76677, 76681, 76686, 76691,
+ 76695, 76699, 76704, 76708, 76712, 76717, 76721, 76725, 76729, 76733,
+ 76738, 76742, 76746, 76750, 76754, 76758, 76763, 76767, 76771, 76775,
+ 76779, 76783, 76788, 76792, 76797, 76802, 76806, 76810, 76815, 76819,
+ 76823, 76828, 76832, 76836, 76840, 76844, 76849, 76853, 76857, 76861,
+ 76865, 76869, 76874, 76878, 76882, 76886, 76890, 76894, 76899, 76903,
+ 76908, 76913, 76917, 76921, 76926, 76930, 76934, 76939, 0, 76943, 76947,
+ 76951, 76956, 76960, 76964, 76968, 76972, 76976, 76981, 76985, 76989,
+ 76993, 76997, 77001, 77006, 77010, 77015, 77020, 77025, 77030, 77036,
+ 77041, 77046, 77052, 77057, 77062, 77067, 77072, 77078, 77083, 77088,
+ 77093, 77098, 77103, 77109, 77114, 77119, 77124, 77129, 77134, 77140,
+ 77145, 77151, 77157, 77162, 77167, 77173, 77178, 77183, 77189, 77194,
+ 77199, 77204, 77209, 77215, 77220, 77225, 77230, 77235, 77240, 77246,
+ 77251, 77256, 77261, 77266, 77271, 77277, 77282, 77288, 77294, 0, 77298,
+ 77303, 0, 0, 77307, 0, 0, 77311, 77315, 0, 0, 77320, 77324, 77328, 77332,
+ 0, 77337, 77341, 77345, 77349, 77353, 77358, 77362, 77367, 77372, 77376,
+ 77380, 77385, 0, 77389, 0, 77394, 77398, 77402, 77406, 77411, 77415,
+ 77419, 0, 77423, 77427, 77432, 77436, 77440, 77444, 77448, 77452, 77457,
+ 77461, 77466, 77471, 77476, 77481, 77487, 77492, 77497, 77503, 77508,
+ 77513, 77518, 77523, 77529, 77534, 77539, 77544, 77549, 77554, 77560,
+ 77565, 77570, 77575, 77580, 77585, 77591, 77596, 77602, 77608, 77613,
+ 77618, 77624, 77629, 77634, 77640, 77645, 77650, 77655, 77660, 77666,
+ 77671, 77676, 77681, 77686, 77691, 77697, 77702, 77707, 77712, 77717,
+ 77722, 77728, 77733, 77739, 77745, 77749, 0, 77753, 77757, 77761, 77766,
+ 0, 0, 77770, 77774, 77779, 77783, 77787, 77791, 77795, 77799, 0, 77804,
+ 77808, 77812, 77816, 77820, 77825, 77829, 0, 77834, 77838, 77842, 77847,
+ 77851, 77855, 77860, 77864, 77868, 77872, 77876, 77881, 77885, 77889,
+ 77893, 77897, 77901, 77906, 77910, 77914, 77918, 77922, 77926, 77931,
+ 77935, 77940, 77945, 77949, 0, 77953, 77957, 77961, 77966, 0, 77970,
+ 77974, 77978, 77983, 77987, 0, 77991, 0, 0, 0, 77995, 77999, 78003,
+ 78007, 78011, 78016, 78020, 0, 78025, 78029, 78033, 78038, 78042, 78046,
+ 78051, 78055, 78059, 78063, 78067, 78072, 78076, 78080, 78084, 78088,
+ 78092, 78097, 78101, 78105, 78109, 78113, 78117, 78122, 78126, 78131,
+ 78136, 78141, 78146, 78152, 78157, 78162, 78168, 78173, 78178, 78183,
+ 78188, 78194, 78199, 78204, 78209, 78214, 78219, 78225, 78230, 78235,
+ 78240, 78245, 78250, 78256, 78261, 78267, 78273, 78278, 78283, 78289,
+ 78294, 78299, 78305, 78310, 78315, 78320, 78325, 78331, 78336, 78341,
+ 78346, 78351, 78356, 78362, 78367, 78372, 78377, 78382, 78387, 78393,
+ 78398, 78404, 78410, 78414, 78418, 78423, 78427, 78431, 78436, 78440,
+ 78444, 78448, 78452, 78457, 78461, 78465, 78469, 78473, 78477, 78482,
+ 78486, 78490, 78494, 78498, 78502, 78507, 78511, 78516, 78521, 78525,
+ 78529, 78534, 78538, 78542, 78547, 78551, 78555, 78559, 78563, 78568,
+ 78572, 78576, 78580, 78584, 78588, 78593, 78597, 78601, 78605, 78609,
+ 78613, 78618, 78622, 78627, 78632, 78637, 78642, 78648, 78653, 78658,
+ 78664, 78669, 78674, 78679, 78684, 78690, 78695, 78700, 78705, 78710,
+ 78715, 78721, 78726, 78731, 78736, 78741, 78746, 78752, 78757, 78763,
+ 78769, 78774, 78779, 78785, 78790, 78795, 78801, 78806, 78811, 78816,
+ 78821, 78827, 78832, 78837, 78842, 78847, 78852, 78858, 78863, 78868,
+ 78873, 78878, 78883, 78889, 78894, 78900, 78906, 78911, 78916, 78922,
+ 78927, 78932, 78938, 78943, 78948, 78953, 78958, 78964, 78969, 78974,
+ 78979, 78984, 78989, 78995, 79000, 79005, 79010, 79015, 79020, 79026,
+ 79031, 79037, 79043, 79048, 79053, 79059, 79064, 79069, 79075, 79080,
+ 79085, 79090, 79095, 79101, 79106, 79111, 79116, 79121, 79126, 79132,
+ 79137, 79142, 79147, 79152, 79157, 79163, 79168, 79174, 79180, 79186,
+ 79192, 79199, 79205, 79211, 79218, 79224, 79230, 79236, 79242, 79249,
+ 79255, 79261, 79267, 79273, 79279, 79286, 79292, 79298, 79304, 79310,
+ 79316, 79323, 79329, 79336, 79343, 79349, 79355, 79362, 79368, 79374,
+ 79381, 79387, 79393, 79399, 79405, 79412, 79418, 79424, 79430, 79436,
+ 79442, 79449, 79455, 79461, 79467, 79473, 79479, 79486, 79492, 79499,
+ 79506, 79510, 79514, 79519, 79523, 79527, 79532, 79536, 79540, 79544,
+ 79548, 79553, 79557, 79561, 79565, 79569, 79573, 79578, 79582, 79586,
+ 79590, 79594, 79598, 79603, 79607, 79612, 79617, 79621, 79625, 79630,
+ 79634, 79638, 79643, 79647, 79651, 79655, 79659, 79664, 79668, 79672,
+ 79676, 79680, 79684, 79689, 79693, 79697, 79701, 79705, 79709, 79714,
+ 79718, 79723, 79728, 79734, 0, 0, 79740, 79745, 79750, 79755, 79760,
+ 79765, 79770, 79775, 79780, 79785, 79790, 79795, 79800, 79805, 79810,
+ 79815, 79820, 79825, 79831, 79836, 79841, 79846, 79851, 79856, 79861,
+ 79866, 79870, 79875, 79880, 79885, 79890, 79895, 79900, 79905, 79910,
+ 79915, 79920, 79925, 79930, 79935, 79940, 79945, 79950, 79955, 79961,
+ 79966, 79971, 79976, 79981, 79986, 79991, 79996, 80002, 80007, 80012,
+ 80017, 80022, 80027, 80032, 80037, 80042, 80047, 80052, 80057, 80062,
+ 80067, 80072, 80077, 80082, 80087, 80092, 80097, 80102, 80107, 80112,
+ 80117, 80123, 80128, 80133, 80138, 80143, 80148, 80153, 80158, 80162,
+ 80167, 80172, 80177, 80182, 80187, 80192, 80197, 80202, 80207, 80212,
+ 80217, 80222, 80227, 80232, 80237, 80242, 80247, 80253, 80258, 80263,
+ 80268, 80273, 80278, 80283, 80288, 80294, 80299, 80304, 80309, 80314,
+ 80319, 80324, 80330, 80336, 80342, 80348, 80354, 80360, 80366, 80372,
+ 80378, 80384, 80390, 80396, 80402, 80408, 80414, 80420, 80426, 80433,
+ 80439, 80445, 80451, 80457, 80463, 80469, 80475, 80480, 80486, 80492,
+ 80498, 80504, 80510, 80516, 80522, 80528, 80534, 80540, 80546, 80552,
+ 80558, 80564, 80570, 80576, 80582, 80589, 80595, 80601, 80607, 80613,
+ 80619, 80625, 80631, 80638, 80644, 80650, 80656, 80662, 80668, 80674,
+ 80680, 80686, 80692, 80698, 80704, 80710, 80716, 80722, 80728, 80734,
+ 80740, 80746, 80752, 80758, 80764, 80770, 80776, 80783, 80789, 80795,
+ 80801, 80807, 80813, 80819, 80825, 80830, 80836, 80842, 80848, 80854,
+ 80860, 80866, 80872, 80878, 80884, 80890, 80896, 80902, 80908, 80914,
+ 80920, 80926, 80932, 80939, 80945, 80951, 80957, 80963, 80969, 80975,
+ 80981, 80988, 80994, 81000, 81006, 81012, 81018, 81024, 81031, 81038,
+ 81045, 81052, 81059, 81066, 81073, 81080, 81087, 81094, 81101, 81108,
+ 81115, 81122, 81129, 81136, 81143, 81151, 81158, 81165, 81172, 81179,
+ 81186, 81193, 81200, 81206, 81213, 81220, 81227, 81234, 81241, 81248,
+ 81255, 81262, 81269, 81276, 81283, 81290, 81297, 81304, 81311, 81318,
+ 81325, 81333, 81340, 81347, 81354, 81361, 81368, 81375, 81382, 81390,
+ 81397, 81404, 81411, 81418, 81425, 0, 0, 0, 0, 81432, 81437, 81441,
+ 81445, 81449, 81453, 81457, 81461, 81465, 81469, 81473, 81478, 81482,
+ 81486, 81490, 81494, 81498, 81502, 81506, 81510, 81514, 81519, 81523,
+ 81527, 81531, 81535, 81539, 81543, 81547, 81551, 81555, 81561, 81566,
+ 81571, 81576, 81581, 81586, 81591, 81596, 81601, 81606, 81611, 81615,
+ 81619, 81623, 81627, 81631, 81635, 81639, 81643, 81647, 81651, 81655,
+ 81659, 81663, 81667, 81671, 81675, 81679, 81683, 81687, 81691, 81695,
+ 81699, 81703, 81707, 81711, 81715, 81719, 81723, 81727, 81731, 81735,
+ 81739, 81743, 81747, 81751, 81755, 81759, 81763, 81767, 81771, 81775,
+ 81779, 81783, 81787, 81791, 81795, 81799, 81803, 81807, 81811, 81815,
+ 81819, 81823, 81827, 81831, 81835, 81839, 81843, 81847, 81851, 81855,
+ 81859, 81863, 81867, 81871, 81875, 81879, 81883, 81887, 81891, 81895,
+ 81899, 81903, 81907, 81911, 81915, 81919, 81923, 81927, 81931, 81935,
+ 81939, 81943, 81947, 81951, 81955, 81959, 81963, 81967, 81971, 81975,
+ 81979, 81983, 81987, 81991, 81995, 81999, 82003, 82007, 82011, 82015,
+ 82019, 82023, 82027, 82031, 82035, 82039, 82043, 82047, 82051, 82055,
+ 82059, 82063, 82067, 82071, 82075, 82079, 82083, 82087, 82091, 82095,
+ 82099, 82103, 82107, 82111, 82115, 82119, 82123, 82127, 82131, 82135,
+ 82139, 82143, 82147, 82151, 82155, 82159, 82163, 82167, 82171, 82175,
+ 82179, 82183, 82187, 82191, 82195, 82199, 82203, 82207, 82211, 82215,
+ 82219, 82223, 82227, 82231, 82235, 82239, 82243, 82247, 82251, 82255,
+ 82259, 82263, 82267, 82271, 82275, 82279, 82283, 82287, 82291, 82295,
+ 82299, 82303, 82307, 82311, 82315, 82319, 82323, 82327, 82331, 82335,
+ 82339, 82343, 82347, 82351, 82355, 82359, 82363, 82367, 82371, 82375,
+ 82379, 82383, 82387, 82391, 82395, 82399, 82403, 82407, 82411, 82415,
+ 82419, 82423, 82427, 82431, 82435, 82439, 82443, 82447, 82451, 82455,
+ 82459, 82463, 82467, 82471, 82475, 82479, 82483, 82487, 82491, 82495,
+ 82499, 82503, 82507, 82511, 82515, 82519, 82523, 82527, 82531, 82535,
+ 82539, 82543, 82547, 82551, 82555, 82559, 82563, 82567, 82571, 82575,
+ 82579, 82583, 82587, 82591, 82595, 82599, 82603, 82607, 82611, 82615,
+ 82619, 82623, 82627, 82631, 82635, 82639, 82643, 82647, 82651, 82655,
+ 82659, 82663, 82667, 82671, 82675, 82679, 82683, 82687, 82691, 82695,
+ 82699, 82703, 82707, 82711, 82715, 82719, 82723, 82727, 82731, 82735,
+ 82739, 82743, 82747, 82751, 82755, 82759, 82763, 82767, 82771, 82775,
+ 82779, 82783, 82787, 82791, 82795, 82799, 82803, 82807, 82811, 82815,
+ 82819, 82823, 82827, 82831, 82835, 82839, 82843, 82847, 82851, 82855,
+ 82859, 82863, 82867, 82871, 82875, 82879, 82883, 82887, 82891, 82895,
+ 82899, 82903, 82907, 82911, 82915, 82919, 82923, 82927, 82931, 82935,
+ 82939, 82943, 82947, 82951, 82955, 82959, 82963, 82967, 82971, 82975,
+ 82979, 82983, 82987, 82991, 82995, 82999, 83003, 83007, 83011, 83015,
+ 83019, 83023, 83027, 83031, 83035, 83039, 83043, 83047, 83051, 83055,
+ 83059, 83063, 83067, 83071, 83075, 83079, 83083, 83087, 83091, 83095,
+ 83099, 83103, 83107, 83111, 83115, 83119, 83123, 83127, 83131, 83135,
+ 83139, 83143, 83147, 83151, 83155, 83159, 83163, 83167, 83171, 83175,
+ 83179, 83183, 83187, 83191, 83195, 83199, 83203, 83207, 83211, 83215,
+ 83219, 83223, 83227, 83231, 83235, 83239, 83243, 83247, 83251, 83255,
+ 83259, 83263, 83267, 83271, 83275, 83279, 83283, 83287, 83291, 83295,
+ 83299, 83303, 83307, 83311, 83315, 83319, 83323, 83327, 83331, 83335,
+ 83339, 83343, 83347, 83351, 83355, 83359, 83363, 83367, 83371, 83375,
+ 83379, 83383, 83387, 83391, 83395, 83399, 83403, 83407, 83411, 83415,
+ 83419, 83423, 83427, 83431, 83435, 83439, 83443, 83447, 83451, 83455,
+ 83459, 83463, 83467, 83471, 83475, 83479, 83483, 83487, 83491, 83495,
+ 83499, 83503, 83507, 83511, 83515, 83519, 83523, 83527, 83531, 83535,
+ 83539, 83543, 83547, 83551, 83555, 83559, 83563, 83567, 83571, 83575,
+ 83579, 83583, 83587, 83591, 83595, 83599, 83603, 83607, 83611, 83615,
+ 83619, 83623, 83627, 83631, 83635, 83639, 83643, 83647, 83651, 83655,
+ 83659, 83663, 83667, 83671, 83675, 83679, 83683, 83687, 83691, 83695,
+ 83699, 83703, 83707, 83711, 83715, 83719, 83723, 83727, 83731, 83735,
+ 83739, 83743, 83747, 83751, 83755, 83759, 83763, 83767, 83771, 83775,
+ 83779, 83783, 83787, 83791, 83795, 83799, 83803, 83807, 83811, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 83819, 83822, 83826, 83830, 83833, 83837, 83841,
+ 83844, 83847, 83851, 83855, 83858, 83862, 83865, 83868, 83872, 83875,
+ 83879, 83882, 83885, 83888, 83891, 83894, 83897, 83900, 83903, 83906,
+ 83909, 83912, 83916, 83920, 83924, 83928, 83933, 83938, 83943, 83949,
+ 83954, 83959, 83965, 83970, 83975, 83980, 83985, 83991, 83996, 84001,
+ 84006, 84011, 84016, 84022, 84027, 84032, 84037, 84042, 84047, 84053,
+ 84058, 84064, 84070, 84074, 84079, 84083, 84087, 84091, 84096, 84101,
+ 84106, 84112, 84117, 84122, 84128, 84133, 84138, 84143, 84148, 84154,
+ 84159, 84164, 84169, 84174, 84179, 84185, 84190, 84195, 84200, 84205,
+ 84210, 84216, 84221, 84227, 84233, 84238, 84242, 84247, 84249, 84253,
+ 84256, 84259, 84262, 84265, 84268, 84271, 84274, 84277, 84280, 84283,
+ 84286, 84289, 84292, 84295, 84298, 84301, 84304, 84307, 84310, 84313,
+ 84316, 84319, 84322, 84325, 84328, 84331, 84334, 84337, 84340, 84343,
+ 84346, 84349, 84352, 84355, 84358, 84361, 84364, 84367, 84370, 84373,
+ 84376, 84379, 84382, 84385, 84388, 84391, 84394, 84397, 84400, 84403,
+ 84406, 84409, 84412, 84415, 84418, 84421, 84424, 84427, 84430, 84433,
+ 84436, 84439, 84442, 84445, 84448, 84451, 84454, 84457, 84460, 84463,
+ 84466, 84469, 84472, 84475, 84478, 84481, 84484, 84487, 84490, 84493,
+ 84496, 84499, 84502, 84505, 84508, 84511, 84514, 84517, 84520, 84523,
+ 84526, 84529, 84532, 84535, 84538, 84541, 84544, 84547, 84550, 84553,
+ 84556, 84559, 84562, 84565, 84568, 84571, 84574, 84577, 84580, 84583,
+ 84586, 84589, 84592, 84595, 84598, 84601, 84604, 84607, 84610, 84613,
+ 84616, 84619, 84622, 84625, 84628, 84631, 84634, 84637, 84640, 84643,
+ 84646, 84649, 84652, 84655, 84658, 84661, 84664, 84667, 84670, 84673,
+ 84676, 84679, 84682, 84685, 84688, 84691, 84694, 84697, 84700, 84703,
+ 84706, 84709, 84712, 84715, 84718, 84721, 84724, 84727, 84730, 84733,
+ 84736, 84739, 84742, 84745, 84748, 84751, 84754, 84757, 84760, 84763,
+ 84766, 84769, 84772, 84775, 84778, 84781, 84784, 84787, 84790, 84793,
+ 84796, 84799, 84802, 84805, 84808, 84811, 84814, 84817, 84820, 84823,
+ 84826, 84829, 84832, 84835, 84838, 84841, 84844, 84847, 84850, 84853,
+ 84856, 84859, 84862, 84865, 84868, 84871, 84874, 84877, 84880, 84883,
+ 84886, 84889, 84892, 84895, 84898, 84901, 84904, 84907, 84910, 84913,
+ 84916, 84919, 84922, 84925, 84928, 84931, 84934, 84937, 84940, 84943,
+ 84946, 84949, 84952, 84955, 84958, 84961, 84964, 84967, 84970, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+/* name->code dictionary */
+static unsigned int code_hash[] = {
+ 120470, 4851, 118860, 43024, 0, 66306, 7929, 64584, 9518, 6609, 120203,
+ 42166, 11319, 1097, 917856, 12064, 41730, 596, 8570, 66517, 12650, 8651,
+ 41728, 12738, 41835, 12995, 41202, 1373, 0, 11403, 5816, 119067, 64810,
+ 1000, 120676, 11951, 41140, 1209, 9717, 195073, 118972, 1073, 194579,
+ 65470, 41138, 8851, 917962, 64500, 12167, 1115, 8874, 9794, 194660,
+ 917846, 120753, 12237, 3966, 41603, 6587, 9290, 65222, 41600, 9231,
+ 120183, 2959, 1457, 3535, 195021, 42179, 63860, 41538, 6671, 8618, 42175,
+ 3404, 64661, 5148, 41737, 1759, 917565, 119974, 65257, 118949, 12290,
+ 66577, 120019, 9386, 12312, 10151, 8205, 118818, 5131, 917899, 9627,
+ 65930, 9834, 3055, 9852, 1944, 1248, 10148, 11398, 119990, 64543, 12701,
+ 119204, 9348, 603, 917851, 65327, 119998, 63781, 65111, 3350, 66576,
+ 64318, 917828, 8154, 3390, 119985, 41817, 119956, 64603, 66328, 65668,
+ 120013, 3400, 120015, 6041, 65020, 41899, 66446, 8002, 8562, 4364, 63991,
+ 4043, 8712, 64134, 7813, 11297, 120759, 10124, 7526, 8601, 6069, 10143,
+ 4814, 12041, 1418, 10885, 12673, 118961, 65307, 9660, 2764, 13012, 4571,
+ 5704, 120483, 119946, 12078, 2970, 5457, 5440, 8857, 917898, 118803,
+ 2843, 5355, 41599, 118883, 119004, 5194, 11657, 119362, 3486, 65324,
+ 12472, 10123, 65167, 194738, 10717, 8714, 2637, 64629, 8460, 10682, 8476,
+ 10602, 800, 917613, 66506, 65673, 1019, 64335, 11631, 8465, 12289, 64144,
+ 762, 13172, 10681, 8488, 5412, 10906, 1353, 194636, 41351, 41823, 5828,
+ 8206, 120166, 8933, 1601, 9072, 858, 13302, 12458, 120774, 8090, 5418,
+ 12452, 120081, 9483, 3351, 120602, 64510, 10817, 917939, 41539, 2750,
+ 11570, 556, 41855, 41246, 65564, 11277, 65892, 2760, 10620, 12195, 7608,
+ 65809, 64156, 5498, 9998, 41536, 64151, 63876, 9242, 3459, 8997, 11787,
+ 64153, 64152, 65734, 120184, 4839, 6615, 68115, 1874, 119016, 4975, 4635,
+ 295, 64124, 64123, 6050, 64898, 917804, 7600, 7590, 63903, 9036, 63901,
+ 19941, 3971, 66609, 119195, 2952, 64116, 6287, 8031, 2725, 63899, 63898,
+ 5482, 667, 12332, 1177, 6086, 12322, 11027, 5172, 41617, 64102, 7859,
+ 1945, 64099, 9815, 10453, 19934, 63882, 7997, 8555, 63878, 63877, 8705,
+ 64097, 64096, 9571, 528, 9172, 120170, 9828, 41723, 63875, 41578, 11460,
+ 7432, 63854, 41913, 9056, 195005, 6188, 64593, 6155, 10806, 446, 6494,
+ 64065, 41318, 63850, 63, 41878, 63846, 2972, 9455, 6639, 64064, 63849,
+ 63848, 63847, 1176, 120649, 8302, 8276, 63842, 4178, 13208, 13188, 10948,
+ 10041, 8105, 4333, 9855, 64112, 1105, 4180, 5388, 12094, 65879, 65197,
+ 7714, 63890, 5443, 7768, 5538, 9987, 194803, 118932, 1678, 917611, 552,
+ 9560, 64077, 10785, 8996, 4992, 4471, 12080, 9159, 10171, 63861, 10486,
+ 5540, 63858, 41781, 281, 63863, 12075, 42041, 64646, 5174, 120337, 3589,
+ 1388, 3123, 43018, 1077, 13272, 8408, 11531, 120387, 43042, 9223, 195029,
+ 65318, 42773, 119117, 42105, 1116, 13274, 43049, 3663, 43050, 1112,
+ 119122, 8686, 8881, 5334, 42108, 119937, 13087, 64091, 9322, 194701,
+ 6509, 64095, 5327, 8111, 19907, 41877, 3478, 7583, 6199, 2903, 195093,
+ 3001, 1158, 8745, 11329, 4741, 63866, 4737, 4370, 4846, 41616, 4742,
+ 41335, 4118, 1797, 64600, 805, 65691, 46, 12070, 8760, 298, 65452, 12212,
+ 120123, 65174, 63836, 32, 5965, 65469, 11495, 12225, 3665, 63837, 64793,
+ 65330, 41336, 4305, 66360, 8083, 917590, 119333, 63821, 4412, 63819,
+ 63818, 12244, 5227, 9047, 12283, 4181, 4752, 9029, 4634, 560, 5643, 8226,
+ 6181, 63812, 13247, 63810, 63790, 3639, 63815, 10122, 63813, 6047, 7937,
+ 63961, 780, 206, 42008, 4936, 7498, 1098, 19923, 120205, 1093, 9882,
+ 3016, 4869, 63932, 917554, 63929, 3546, 1605, 65058, 6182, 65566, 13176,
+ 8400, 11343, 63920, 917550, 5471, 2984, 5314, 9287, 5473, 44, 194667,
+ 194682, 13169, 5290, 5283, 1695, 63827, 1088, 5961, 1900, 1084, 1085,
+ 63829, 1083, 6581, 5576, 917793, 64184, 4263, 1092, 4754, 8947, 5252,
+ 120431, 65253, 64183, 917819, 7908, 11011, 120390, 6579, 194878, 2965,
+ 119177, 8808, 64710, 1089, 7761, 41641, 42119, 12355, 63889, 940, 5787,
+ 9992, 63938, 5057, 64679, 12463, 2994, 5054, 41694, 65794, 9664, 41026,
+ 1437, 9399, 658, 3497, 12920, 7486, 660, 5060, 666, 9022, 5532, 118941,
+ 5533, 5059, 4727, 6118, 222, 979, 3884, 12459, 7488, 5773, 978, 120163,
+ 7489, 41619, 10239, 12465, 917761, 118902, 64411, 13271, 1707, 120319,
+ 12461, 63895, 63949, 63948, 63947, 3376, 6038, 63943, 63942, 63894,
+ 65323, 194944, 65508, 7776, 64278, 2379, 8703, 63893, 64668, 801, 8125,
+ 1690, 63919, 63918, 63917, 2369, 65042, 12844, 65800, 119235, 5486, 2334,
+ 64893, 4463, 5483, 10207, 917608, 2367, 5484, 63909, 264, 2375, 8060,
+ 6194, 5485, 1844, 64035, 9061, 5534, 10672, 4502, 13178, 253, 118819,
+ 1823, 8800, 10746, 7912, 0, 10256, 6192, 194946, 42771, 11576, 119616,
+ 725, 4550, 13257, 120800, 118944, 12892, 917868, 64087, 41775, 8413,
+ 194805, 120146, 5693, 10397, 120440, 13209, 5074, 5073, 120438, 8983,
+ 120525, 41132, 66586, 5072, 19964, 6198, 11614, 65731, 196, 13206, 3111,
+ 64725, 4929, 12445, 0, 119074, 194646, 66606, 6628, 1076, 11294, 1436,
+ 4934, 64415, 41323, 7543, 195098, 12807, 63907, 63906, 4548, 4329, 6113,
+ 4979, 3048, 4423, 41320, 194963, 10515, 6218, 8971, 5071, 65583, 3642,
+ 1430, 5070, 10042, 118835, 3987, 5068, 7619, 3255, 3493, 917952, 8905,
+ 10735, 120134, 41635, 3378, 4531, 1245, 9105, 66311, 4921, 4481, 3771,
+ 65544, 2710, 41693, 64084, 41724, 64709, 41682, 41690, 120120, 4922, 325,
+ 992, 120305, 4925, 1628, 0, 9526, 4920, 65262, 948, 10783, 120208, 4930,
+ 917570, 4462, 194855, 4933, 5339, 6115, 65359, 4928, 917603, 4457,
+ 120506, 65290, 42163, 722, 5684, 8678, 12637, 65624, 5689, 8753, 1509,
+ 120180, 5468, 9511, 194968, 65183, 1672, 6205, 5832, 6310, 5686, 194931,
+ 64800, 64536, 120713, 41475, 50, 917926, 9871, 120115, 1679, 11982,
+ 10759, 41883, 66468, 3183, 13259, 4448, 119225, 401, 6427, 64930, 64763,
+ 5761, 342, 8553, 1151, 8143, 67589, 11983, 64384, 624, 65443, 42014,
+ 119630, 5078, 12501, 5656, 120168, 5076, 118870, 8812, 119170, 11538,
+ 685, 9025, 1524, 8003, 66467, 5539, 8087, 12971, 120101, 9894, 1252,
+ 12925, 194611, 4636, 194615, 118985, 8053, 9732, 917983, 5080, 13121,
+ 5036, 5035, 118968, 12277, 65904, 194780, 8074, 275, 12158, 194594, 8741,
+ 4432, 120610, 5033, 120668, 64605, 4836, 3888, 473, 65584, 8502, 120250,
+ 1873, 1087, 12499, 917808, 63844, 12345, 3601, 1922, 6409, 64965, 65422,
+ 12502, 120683, 12505, 66321, 66477, 9489, 119140, 3432, 4384, 63964,
+ 6094, 41530, 8815, 12851, 64753, 119950, 1676, 1154, 3857, 1205, 5030,
+ 917917, 13100, 12958, 10519, 9622, 194674, 64723, 4421, 10592, 0, 495,
+ 119007, 10544, 7983, 118882, 10749, 64186, 8494, 11980, 10979, 41710,
+ 947, 64187, 437, 41709, 10969, 65894, 7613, 9465, 13290, 4795, 4997,
+ 64306, 8826, 11486, 4999, 120611, 8626, 4590, 4711, 120255, 65037, 2739,
+ 19942, 8044, 40964, 251, 12686, 7895, 4395, 119927, 119926, 119929, 1779,
+ 6600, 6601, 41543, 5325, 642, 65830, 8880, 7685, 120071, 66729, 6234,
+ 13229, 625, 8187, 9990, 1113, 194643, 7915, 1104, 120176, 8179, 10655,
+ 195043, 9316, 10980, 2489, 1082, 8150, 1359, 194645, 194726, 119304,
+ 119555, 5042, 5041, 42769, 12084, 8049, 7509, 194806, 6458, 120182,
+ 119575, 4761, 10506, 4766, 1616, 1273, 120187, 8795, 118876, 194835,
+ 63957, 9232, 1138, 10483, 12677, 41545, 12881, 3239, 65517, 119558,
+ 66614, 119111, 42128, 3484, 64545, 11778, 11572, 8503, 5122, 41527, 5040,
+ 4924, 119014, 119085, 120201, 120748, 5039, 41926, 8303, 8282, 5038,
+ 65736, 10003, 7427, 65611, 120586, 1686, 120190, 9359, 11467, 3664,
+ 65921, 8238, 6662, 66472, 119329, 3863, 126, 4835, 68119, 120605, 13245,
+ 4309, 7744, 63867, 119846, 119023, 13184, 63870, 65431, 569, 8136,
+ 119010, 711, 1633, 120583, 63869, 4762, 1103, 194560, 12281, 4765, 41331,
+ 1006, 13040, 4760, 1550, 8201, 10871, 917990, 1102, 5031, 118904, 66671,
+ 64499, 11546, 13042, 337, 194781, 65781, 65678, 12279, 1111, 65780,
+ 119900, 4707, 194635, 5008, 7883, 8822, 7880, 4522, 8255, 5512, 13010,
+ 119232, 8304, 64313, 11611, 5906, 1119, 13039, 13038, 64910, 2455, 64734,
+ 13008, 41652, 4385, 12492, 11020, 6499, 64775, 119161, 13009, 160, 68110,
+ 120679, 64262, 5052, 64031, 5821, 6186, 41792, 42770, 5051, 65773, 1429,
+ 64573, 5050, 302, 388, 12058, 735, 6637, 1079, 3867, 5708, 12726, 119879,
+ 9117, 5706, 10679, 5513, 6666, 4005, 0, 5510, 10991, 120454, 65458, 2470,
+ 917581, 13305, 1925, 65760, 194914, 41924, 10092, 5048, 5047, 41532,
+ 10058, 917559, 119999, 9070, 12049, 3339, 8089, 1106, 639, 65764, 63967,
+ 3340, 3109, 3653, 4599, 10799, 6674, 10605, 917585, 1476, 648, 1754,
+ 11001, 3233, 864, 41782, 10164, 8972, 41865, 3530, 9750, 120690, 11024,
+ 6656, 5192, 4338, 5046, 8512, 63770, 13199, 8967, 1236, 5045, 12012,
+ 13189, 7986, 5044, 120102, 7440, 13128, 5043, 9553, 1590, 63777, 63776,
+ 9669, 12341, 8654, 8402, 63779, 1583, 4740, 13260, 3586, 13276, 11444,
+ 120306, 67634, 119606, 41523, 13296, 517, 12922, 11354, 11700, 41528,
+ 123, 65454, 12393, 11394, 41997, 10531, 7784, 13194, 1334, 11978, 4479,
+ 1126, 65586, 120663, 195061, 8520, 3925, 917621, 8069, 4357, 42154, 489,
+ 120450, 119836, 8848, 6476, 8450, 43044, 11926, 41557, 1145, 63788, 7910,
+ 63785, 63784, 754, 8711, 6183, 8183, 120741, 8928, 65166, 7952, 10747,
+ 125, 9235, 64861, 64207, 12689, 66445, 10779, 10990, 3523, 1074, 13258,
+ 9536, 8477, 11014, 4427, 10517, 63757, 7726, 11325, 19922, 267, 1349,
+ 10713, 1371, 12149, 195003, 2458, 63753, 6201, 41084, 41074, 4266, 10652,
+ 6483, 41077, 3402, 9050, 3398, 8140, 42084, 6260, 3391, 41075, 2476,
+ 41956, 11988, 3898, 10625, 10201, 10988, 11524, 63794, 10367, 12521,
+ 10431, 13014, 6289, 1068, 6673, 12523, 12945, 12524, 12438, 7950, 10804,
+ 13233, 12082, 4386, 9053, 12473, 2793, 12475, 704, 195020, 6195, 9530,
+ 6660, 12232, 194892, 64159, 5681, 12629, 4595, 63760, 792, 65538, 13004,
+ 9897, 8742, 195013, 64947, 65448, 63744, 12948, 64787, 7588, 63748, 1693,
+ 63746, 63745, 5055, 9883, 4287, 1090, 4902, 1131, 11665, 194602, 4558,
+ 1816, 9523, 41712, 168, 194897, 4898, 63857, 6157, 12960, 4901, 1821,
+ 13191, 12170, 3500, 3139, 791, 9162, 12485, 10306, 119001, 64200, 13006,
+ 64433, 8354, 10033, 941, 12037, 7557, 65570, 10565, 8234, 64559, 8228,
+ 8424, 10246, 64193, 12811, 65925, 3946, 42764, 8057, 41990, 673, 194853,
+ 64357, 917971, 194799, 9547, 288, 8752, 120820, 2448, 10025, 10267, 2918,
+ 2452, 65300, 41529, 8729, 64726, 2790, 7845, 3793, 194715, 4408, 4122,
+ 11568, 41535, 8723, 10709, 10087, 119302, 731, 42109, 11548, 2438, 64587,
+ 65396, 119169, 1175, 13256, 1282, 373, 119172, 5396, 8653, 8557, 7723, 0,
+ 3330, 120278, 41952, 917566, 5273, 8248, 5269, 3304, 5202, 2404, 5267,
+ 119357, 1627, 65549, 5277, 12963, 5371, 6189, 4125, 1826, 12133, 65241,
+ 8260, 1271, 917589, 195006, 64643, 9035, 3864, 12707, 4631, 3879, 118785,
+ 68125, 4166, 164, 9331, 7567, 7459, 119568, 10212, 5384, 41882, 67647,
+ 64346, 0, 68159, 917822, 41388, 120518, 12005, 12666, 13175, 13207, 8706,
+ 5552, 10172, 700, 5929, 5553, 12978, 120384, 5356, 7499, 8563, 41888,
+ 3180, 917818, 917960, 5554, 971, 12344, 8724, 194608, 6665, 63874,
+ 120275, 2866, 8517, 11455, 13190, 64632, 120227, 5555, 10045, 12882,
+ 13275, 120672, 41522, 11480, 9143, 6668, 41525, 120539, 195035, 656,
+ 118808, 43034, 4577, 12229, 8715, 68133, 194613, 120261, 4269, 64813,
+ 119163, 41609, 10476, 950, 118980, 3932, 41450, 68140, 66683, 68130,
+ 120014, 11974, 118884, 369, 119096, 41784, 66459, 5097, 4935, 9848,
+ 64216, 10293, 4796, 10317, 3651, 10127, 120603, 10269, 5102, 5101, 66628,
+ 9064, 8138, 120455, 404, 5100, 1439, 12093, 1247, 8092, 119330, 5099,
+ 1831, 1441, 4793, 3063, 650, 12292, 746, 120165, 120769, 7461, 12018,
+ 9031, 12182, 10115, 9078, 8545, 4422, 4708, 3799, 3268, 64556, 9118,
+ 119127, 2676, 7750, 4374, 64398, 6190, 1364, 64589, 8038, 68121, 9857,
+ 120638, 9858, 195033, 64170, 12129, 13174, 8481, 12412, 6202, 64380,
+ 10920, 10872, 2365, 7841, 120059, 5108, 5107, 11010, 13210, 6176, 65561,
+ 5541, 41785, 41171, 11291, 5284, 4372, 207, 194904, 4275, 119930, 854,
+ 68147, 120189, 12965, 384, 5103, 10404, 10340, 10702, 1556, 488, 13236,
+ 12937, 10017, 9733, 13187, 10014, 7844, 41373, 13198, 5203, 120517,
+ 13232, 5106, 349, 4863, 41371, 10965, 41367, 5105, 11721, 12861, 4398,
+ 5104, 5672, 304, 1096, 120557, 0, 932, 12441, 6567, 238, 65681, 4318,
+ 10452, 19905, 8032, 13243, 13237, 12719, 67640, 66570, 64814, 64884,
+ 119872, 10670, 8597, 1178, 64017, 9864, 13195, 8803, 309, 6622, 8151,
+ 10858, 64961, 7722, 12553, 10459, 12568, 12066, 12549, 66590, 12570,
+ 9712, 41417, 41496, 194943, 9805, 4965, 13150, 10538, 19944, 41401,
+ 120252, 120164, 6191, 6261, 119342, 119341, 11965, 1957, 10420, 982,
+ 2756, 9370, 2720, 12357, 41455, 2925, 118817, 13056, 3222, 13212, 10116,
+ 41644, 10105, 10378, 41581, 10834, 118793, 64407, 5242, 41963, 64476,
+ 1694, 8216, 10814, 67598, 7781, 6306, 64568, 917916, 120738, 11793,
+ 42057, 7594, 64598, 120325, 64799, 3475, 64206, 2479, 9709, 3632, 120322,
+ 10698, 65616, 3648, 3907, 10297, 67639, 3636, 19928, 2979, 8837, 8286,
+ 1843, 3936, 119052, 11699, 41347, 65119, 13235, 3640, 41248, 120579,
+ 4379, 13239, 12692, 7969, 12927, 66353, 194951, 12703, 120509, 41846,
+ 2529, 734, 10808, 65146, 42083, 9872, 957, 42055, 1846, 66367, 12181,
+ 9634, 120310, 9988, 12991, 1670, 5740, 119597, 10072, 5379, 120318,
+ 41163, 41157, 785, 8236, 194812, 9027, 63897, 13267, 64383, 64688, 925,
+ 41955, 120541, 41773, 41071, 9586, 120312, 41984, 9217, 6151, 12110,
+ 120689, 65572, 64580, 4016, 13265, 13264, 381, 12386, 6100, 42077,
+ 120768, 5808, 5184, 8200, 12967, 10810, 5612, 4583, 19943, 5860, 67633,
+ 64575, 194842, 812, 3615, 65284, 5178, 194929, 119015, 9825, 5188, 9698,
+ 7814, 120063, 10692, 1166, 64429, 41921, 924, 9756, 12359, 119258,
+ 194843, 2442, 10703, 120696, 67632, 8012, 5674, 12353, 119561, 12361,
+ 5677, 67626, 66657, 40972, 12453, 41920, 5673, 12751, 5676, 8542, 12694,
+ 118978, 2468, 1294, 41294, 3336, 3883, 64388, 1727, 194680, 64054, 3605,
+ 119632, 195015, 12034, 8718, 3550, 736, 7806, 4505, 2715, 806, 5826,
+ 41884, 5813, 64279, 65391, 5841, 5837, 64731, 12702, 3105, 2405, 5838,
+ 5796, 120604, 65259, 5793, 5735, 5866, 5797, 1432, 5865, 12143, 7956,
+ 598, 66448, 41886, 2480, 120152, 19952, 9037, 5671, 5537, 12749, 67601,
+ 10932, 41359, 1211, 847, 65690, 9529, 11799, 12318, 120766, 43026, 5645,
+ 10622, 41391, 194967, 64378, 6566, 917913, 5650, 11358, 119102, 13110,
+ 194834, 9624, 194928, 8284, 65896, 2748, 1554, 194733, 4035, 6492, 66504,
+ 4265, 2929, 3977, 65344, 12051, 836, 5698, 2488, 194634, 4582, 66514,
+ 5644, 10292, 12926, 8046, 7528, 8372, 11707, 65116, 119206, 11439, 13201,
+ 1374, 64878, 12742, 41013, 10568, 41374, 4030, 2869, 120776, 41015,
+ 65897, 2785, 400, 12597, 42051, 120540, 64477, 6661, 5659, 9884, 4759,
+ 118906, 390, 10266, 41349, 1170, 3473, 7718, 118962, 1609, 902, 917855,
+ 120062, 66352, 11661, 8122, 5712, 66308, 8004, 1887, 9540, 10278, 2554,
+ 5158, 5714, 41136, 194970, 64351, 807, 66652, 120793, 64677, 976, 5511,
+ 6146, 65518, 771, 10954, 41356, 9673, 11412, 11026, 41143, 8676, 7904,
+ 5579, 953, 451, 119560, 5578, 12635, 11491, 9724, 194697, 118881, 9524,
+ 7490, 118789, 1440, 3379, 10310, 7487, 12561, 471, 7484, 7482, 3795,
+ 7480, 7479, 7478, 7477, 6501, 7475, 64900, 7473, 7472, 2474, 7470, 6546,
+ 93, 10615, 10213, 8128, 12551, 10049, 8171, 3544, 194628, 6017, 65311,
+ 383, 120216, 13306, 10533, 7870, 63884, 5187, 119991, 1456, 120217,
+ 42164, 64217, 194702, 5232, 917994, 19961, 2472, 41005, 120699, 8710,
+ 6019, 4256, 119959, 4980, 8860, 9640, 10028, 12845, 66607, 13182, 65121,
+ 120685, 120308, 10631, 65126, 7972, 118928, 8066, 119623, 7900, 8316,
+ 11309, 11273, 119040, 64211, 120309, 64212, 10347, 445, 119029, 195074,
+ 12931, 64927, 8330, 65783, 66597, 64213, 64366, 64369, 8814, 3902, 64607,
+ 1770, 194723, 12836, 64208, 64552, 65821, 4584, 9684, 120714, 917944,
+ 10866, 65792, 1118, 7464, 194989, 8964, 1081, 7436, 64565, 8162, 9342,
+ 5996, 119245, 4903, 64332, 41386, 5162, 41007, 1330, 64486, 40995, 12209,
+ 12047, 41384, 194789, 195067, 1848, 4334, 65352, 9880, 64066, 10674,
+ 5522, 195014, 61, 120157, 195065, 3633, 41980, 65162, 41234, 12089,
+ 65871, 9771, 66685, 13251, 41959, 64749, 6262, 2784, 195040, 9334, 8126,
+ 66483, 64967, 7975, 441, 194591, 917599, 11608, 4884, 40999, 120269,
+ 120334, 10495, 6313, 10890, 119354, 65834, 8324, 7855, 2345, 67599, 463,
+ 64737, 194821, 119607, 3117, 5460, 119356, 1193, 10056, 1148, 12396,
+ 13252, 7829, 42173, 118994, 7743, 917981, 13248, 5499, 63763, 118960,
+ 9034, 6039, 120544, 5663, 119182, 41018, 65683, 10338, 2482, 1471,
+ 120086, 120077, 66370, 12378, 41966, 41970, 3084, 12374, 10903, 6638,
+ 10422, 911, 2460, 120499, 11944, 12376, 41032, 40996, 120614, 12380,
+ 5520, 64473, 10869, 5870, 64670, 13310, 2603, 12326, 539, 10826, 65105,
+ 917932, 3853, 11949, 64901, 120260, 64883, 10722, 41810, 8659, 120090,
+ 12474, 66721, 5857, 65342, 2478, 119120, 4162, 7942, 4260, 12953, 42028,
+ 120089, 12470, 64941, 11798, 2742, 12476, 1891, 10946, 9101, 5000, 66647,
+ 12302, 3018, 12942, 5748, 194584, 7771, 6161, 917934, 8796, 0, 6412,
+ 118986, 8519, 13146, 41973, 12906, 9422, 10333, 2882, 4366, 119123,
+ 12843, 4520, 917810, 65626, 10648, 118898, 4014, 12842, 194724, 12015,
+ 13117, 8275, 3893, 66362, 5810, 12210, 195071, 42147, 11536, 13292,
+ 65685, 12938, 10427, 9154, 3844, 63934, 9755, 1110, 6612, 10892, 8231,
+ 10775, 6473, 41968, 783, 10219, 3591, 41969, 917997, 2453, 8518, 3620,
+ 11466, 12443, 4556, 10349, 10413, 194569, 41159, 3202, 8599, 10510, 4382,
+ 66482, 195002, 10842, 687, 9177, 8902, 63950, 1840, 41751, 12400, 120177,
+ 4883, 285, 4723, 41917, 9788, 4459, 64158, 1634, 41958, 9155, 240, 9786,
+ 65082, 41919, 8579, 9743, 7981, 13134, 118878, 4508, 64178, 41999, 11328,
+ 119817, 65589, 63887, 3081, 11463, 120080, 119051, 119353, 10445, 41720,
+ 194662, 120229, 2614, 9024, 64620, 1729, 119840, 64289, 65221, 63883,
+ 65466, 64852, 64509, 41447, 63916, 64855, 41203, 5001, 41879, 11355,
+ 4121, 5003, 884, 41214, 63879, 4943, 5150, 7500, 5278, 7773, 643, 3086,
+ 118912, 64652, 120068, 58, 194621, 6167, 66656, 63872, 6594, 66366,
+ 11295, 41495, 3624, 43036, 118901, 64655, 2721, 9616, 63988, 19929,
+ 11296, 10500, 10440, 9611, 4264, 119303, 194657, 7738, 41857, 11446,
+ 12638, 64522, 3435, 3094, 12916, 9754, 66314, 4437, 41292, 8899, 12748,
+ 42058, 9517, 11518, 917889, 65360, 120700, 119047, 63956, 4306, 41380,
+ 11995, 63960, 9591, 8323, 10217, 67602, 11469, 120578, 12456, 2723,
+ 120061, 5088, 5086, 917783, 8524, 7752, 11397, 2880, 0, 194669, 2872,
+ 1386, 65034, 3498, 4378, 65039, 4270, 12392, 65036, 7853, 6633, 12101,
+ 5822, 5230, 194573, 710, 917790, 11663, 1666, 8161, 371, 12013, 63891,
+ 42092, 119103, 415, 63851, 63892, 11708, 42096, 5183, 1877, 7538, 7924,
+ 2927, 4324, 6608, 4472, 1244, 331, 194858, 12683, 10662, 64678, 4756,
+ 63831, 65852, 10730, 7691, 10331, 65320, 41964, 6238, 8938, 8628, 6043,
+ 118801, 64895, 1604, 9565, 10539, 120814, 41220, 13032, 120519, 120193,
+ 10032, 8750, 12373, 63828, 11992, 1351, 194868, 8698, 12190, 3622, 1930,
+ 65237, 9621, 10463, 63981, 4967, 13031, 1966, 2330, 195099, 3657, 120498,
+ 65202, 6000, 4347, 4416, 42098, 11009, 10694, 8099, 402, 41916, 13147,
+ 41912, 42100, 12217, 9695, 1897, 7562, 3515, 5170, 11805, 11796, 676,
+ 6259, 41742, 65558, 41870, 65553, 3536, 65093, 9752, 63902, 6162, 10532,
+ 66490, 10113, 41829, 65886, 5159, 12422, 41832, 439, 66640, 119611,
+ 11280, 12481, 2325, 40970, 41830, 120647, 917799, 5145, 12486, 65018,
+ 66516, 5409, 8976, 120051, 12336, 4135, 9685, 341, 2727, 4129, 3539,
+ 66616, 11530, 41736, 7913, 5405, 63859, 4131, 41267, 64721, 63865, 4133,
+ 63864, 210, 4600, 8082, 3254, 4137, 119205, 119853, 119062, 194577,
+ 120534, 4591, 65077, 64671, 194671, 3355, 9508, 3393, 561, 5723, 195,
+ 64261, 3377, 12497, 41269, 917545, 13135, 917993, 8368, 119224, 41499,
+ 917798, 11435, 917920, 41498, 120628, 1379, 246, 12603, 9680, 3788, 2924,
+ 42168, 12812, 8728, 64906, 119213, 8917, 120645, 301, 64765, 3969, 64964,
+ 9575, 64562, 40966, 9652, 64919, 42064, 42086, 120542, 194728, 8491,
+ 194962, 41876, 63772, 3182, 327, 120323, 9042, 118827, 917776, 42169,
+ 4755, 194684, 64660, 11443, 12431, 8668, 12434, 608, 600, 5999, 1219,
+ 3934, 9494, 11483, 917919, 1726, 1015, 64686, 8212, 11395, 64202, 13160,
+ 7759, 65363, 485, 43037, 65291, 8811, 927, 42102, 194979, 12436, 9351,
+ 7778, 64379, 7496, 65335, 7491, 1208, 7495, 64757, 9337, 64362, 917778,
+ 11348, 12235, 9021, 194949, 917830, 120066, 19914, 3742, 8758, 9648,
+ 64617, 63834, 9150, 63835, 1117, 13037, 2594, 63809, 10691, 12052, 6550,
+ 10469, 65212, 11265, 2546, 119216, 213, 65309, 10554, 3972, 917972,
+ 194678, 64194, 6554, 12416, 11914, 5452, 8230, 64197, 41951, 12418,
+ 42049, 3882, 8532, 2713, 1573, 9650, 42136, 4596, 66339, 1406, 120041,
+ 40990, 194593, 12414, 8287, 4143, 120378, 10489, 1143, 4141, 9682, 12415,
+ 1508, 42763, 8779, 10569, 8725, 120783, 65045, 11724, 119064, 4145,
+ 64872, 65751, 66613, 119576, 8027, 41505, 9171, 9550, 11400, 12518,
+ 65178, 65397, 6528, 10740, 65753, 64816, 10998, 66333, 12955, 10596,
+ 2888, 119572, 65033, 7715, 3881, 41487, 12118, 67622, 2878, 5390, 64167,
+ 3009, 41476, 41489, 63765, 3007, 1448, 2975, 10429, 3889, 8521, 5083,
+ 5082, 7503, 5235, 803, 194590, 3014, 5081, 8986, 11002, 10632, 11934,
+ 11452, 1332, 64802, 3929, 4597, 65532, 64767, 1791, 5191, 9288, 9657,
+ 2892, 10577, 6031, 555, 64173, 0, 194927, 12367, 42170, 11540, 63930,
+ 629, 1924, 119880, 11270, 64162, 5858, 8462, 8005, 12365, 1784, 1361,
+ 118939, 12369, 7905, 67644, 5077, 194668, 10880, 63927, 5075, 120065,
+ 9371, 65075, 41193, 11007, 1625, 10997, 917907, 1342, 66684, 64171, 3434,
+ 4843, 4506, 195060, 5266, 120521, 5272, 4482, 4507, 9578, 63923, 66319,
+ 7979, 64381, 9831, 64417, 65529, 461, 7984, 41972, 4504, 444, 42145,
+ 9127, 5276, 43021, 118922, 120179, 119638, 11349, 12848, 5177, 41324,
+ 12055, 8722, 120805, 1197, 65512, 1149, 4114, 409, 4383, 8900, 8948,
+ 7684, 3492, 721, 10182, 9108, 119005, 195041, 11954, 119191, 12993,
+ 40963, 3099, 917979, 65088, 41087, 119834, 12587, 66643, 120374, 12036,
+ 194736, 65123, 41576, 8152, 120721, 64428, 12227, 8578, 5995, 7573,
+ 41575, 2922, 63946, 63944, 11493, 194883, 2670, 4167, 194873, 11723,
+ 120025, 65173, 68154, 13023, 938, 917954, 195044, 11737, 9721, 118937,
+ 41017, 9606, 8504, 4024, 41063, 11411, 12334, 65231, 4153, 11911, 10793,
+ 5250, 12407, 3395, 4404, 6056, 12401, 11490, 5775, 42005, 41607, 68183,
+ 41091, 12205, 1344, 8870, 194744, 4940, 4735, 7683, 1167, 12822, 4983,
+ 120554, 861, 64907, 120045, 120458, 65149, 63896, 120651, 12039, 10559,
+ 11956, 119841, 118892, 9472, 4282, 6631, 120188, 12816, 9596, 7618,
+ 12710, 64147, 11579, 4101, 0, 64704, 5992, 7616, 65828, 64422, 1004,
+ 9632, 120185, 853, 0, 12627, 10953, 194681, 5016, 65619, 120441, 11300,
+ 9491, 9686, 5890, 917914, 7558, 12712, 195077, 65627, 10718, 13154, 3461,
+ 9139, 64756, 194990, 119151, 65628, 0, 13227, 12585, 6669, 119152, 12177,
+ 41708, 12860, 41098, 10015, 10838, 4900, 10352, 120742, 10061, 5903,
+ 4119, 5140, 209, 64002, 11520, 9702, 11702, 8277, 9245, 13048, 4927,
+ 4138, 41093, 65286, 64412, 2410, 993, 41025, 13054, 12394, 120020,
+ 917579, 68162, 12685, 64938, 65475, 10781, 41230, 64299, 5010, 1680,
+ 9107, 118809, 10659, 3600, 10968, 120027, 1336, 41518, 194796, 5896,
+ 119838, 5993, 2819, 12950, 12706, 12966, 1893, 120462, 63915, 917768,
+ 8184, 272, 1363, 8793, 8411, 63908, 41502, 3077, 983, 68118, 1512,
+ 119941, 1190, 4109, 1335, 841, 5888, 41358, 9836, 9544, 120021, 41481,
+ 8313, 7832, 65515, 3090, 2409, 817, 1664, 1850, 66690, 3079, 4731, 10118,
+ 66629, 64541, 12033, 1255, 11689, 9247, 64350, 66633, 12389, 66610,
+ 195078, 41996, 11526, 63985, 5864, 1147, 11690, 5835, 1551, 66625, 5480,
+ 7858, 11653, 4116, 11688, 66634, 1094, 194, 12384, 118987, 8180, 41686,
+ 12313, 41531, 63904, 13273, 6114, 10898, 195082, 64578, 8247, 507, 91,
+ 7545, 10695, 10952, 7534, 10896, 10036, 7857, 6067, 774, 65915, 2744,
+ 119815, 5994, 12539, 41420, 41601, 8359, 65264, 6028, 66511, 13167,
+ 120277, 7719, 119875, 2486, 7893, 41059, 162, 5436, 917583, 119809, 9687,
+ 64956, 6304, 65457, 6051, 120495, 5262, 5904, 66658, 12681, 194710,
+ 194616, 12406, 12219, 3652, 10537, 917946, 10492, 64550, 6549, 279,
+ 195030, 119978, 64619, 12403, 1489, 120771, 4132, 4899, 3899, 1007,
+ 42124, 4976, 2343, 4103, 19946, 120806, 10750, 1345, 120355, 120801,
+ 12859, 8956, 4098, 65267, 5861, 65559, 11999, 12151, 64804, 194856,
+ 12645, 5146, 11320, 64730, 64174, 41094, 492, 8685, 12974, 41060, 67613,
+ 41551, 5147, 2582, 11470, 64538, 7444, 1928, 118998, 9594, 5991, 10862,
+ 67609, 2527, 194809, 197, 2799, 8241, 64181, 65348, 65874, 194840, 64179,
+ 767, 4127, 120464, 10138, 119808, 0, 8897, 63911, 41553, 8357, 4124,
+ 1799, 65371, 42148, 194663, 12954, 120231, 65340, 1123, 963, 2434, 10120,
+ 12405, 41339, 2493, 398, 392, 9723, 6407, 119011, 7945, 64935, 4402,
+ 7570, 12402, 65926, 41392, 8414, 12408, 41265, 65713, 406, 120326, 9164,
+ 12411, 0, 4560, 6623, 4961, 64494, 1575, 64682, 5438, 165, 9993, 41467,
+ 63953, 8064, 9093, 9599, 9147, 118831, 63958, 4987, 9148, 2399, 4096, 53,
+ 10944, 12368, 65435, 119192, 8178, 64149, 3367, 12910, 10884, 727, 65272,
+ 119238, 5805, 1947, 11527, 194589, 42176, 12370, 11655, 1705, 5411, 8898,
+ 118810, 12372, 120642, 195023, 8017, 65287, 8813, 12366, 10963, 6066,
+ 1329, 4909, 3052, 9220, 66464, 4904, 66666, 10803, 1365, 9253, 42757,
+ 41264, 7462, 120712, 119350, 119814, 1499, 66727, 8055, 120803, 8740,
+ 5398, 63962, 13120, 8924, 917764, 5988, 3660, 12017, 11781, 9476, 8788,
+ 1357, 42113, 65743, 3629, 8774, 13005, 119082, 3628, 120172, 64394, 1933,
+ 3469, 1567, 42116, 11969, 64809, 2928, 4905, 2487, 851, 3121, 1804, 3311,
+ 67615, 9114, 194880, 12083, 9315, 4822, 4906, 3852, 2847, 6675, 3236,
+ 11317, 1251, 7777, 41852, 7951, 1198, 9132, 120767, 12274, 510, 10259,
+ 9865, 65686, 4561, 6018, 1398, 917869, 12276, 66487, 19931, 119061,
+ 11406, 8167, 12127, 41932, 840, 120300, 2443, 10918, 10410, 120338, 1001,
+ 9241, 1927, 333, 41930, 120272, 8144, 8034, 10680, 119598, 66663, 64199,
+ 12867, 64198, 6678, 7769, 7519, 12621, 65150, 8904, 518, 4764, 65165,
+ 41168, 13204, 4387, 857, 10530, 65369, 12736, 120724, 41044, 66458,
+ 11543, 9358, 67594, 42078, 5136, 1968, 19937, 66605, 1337, 10581, 1629,
+ 4533, 796, 66494, 6490, 194921, 12038, 119338, 12664, 195037, 65461,
+ 9798, 6120, 478, 1948, 68128, 10962, 952, 6016, 195055, 195088, 9512,
+ 4276, 1206, 3619, 41638, 13263, 3843, 8142, 8853, 3361, 41795, 490,
+ 10715, 3436, 65011, 63841, 12817, 9847, 6676, 3930, 12854, 13240, 6154,
+ 9551, 65354, 65346, 784, 65357, 334, 64797, 1453, 7541, 8940, 120329,
+ 8500, 10428, 10364, 64715, 778, 4317, 10004, 7989, 64676, 3227, 119583,
+ 67606, 120514, 120684, 10855, 13102, 41702, 10309, 6672, 10277, 194958,
+ 66691, 41624, 5415, 9613, 9001, 4526, 3462, 65215, 64520, 41020, 6664,
+ 66701, 42056, 9759, 64957, 3963, 120304, 8114, 1469, 65244, 65381, 41744,
+ 4988, 66453, 118956, 9598, 904, 352, 194760, 1451, 1356, 8453, 4134,
+ 120377, 917802, 1619, 9703, 41745, 3955, 8575, 119180, 1201, 64732,
+ 12846, 917980, 41860, 11919, 64962, 41550, 5289, 13144, 8511, 9460, 823,
+ 9675, 12305, 5940, 226, 2649, 12387, 1253, 13183, 65766, 500, 64521,
+ 9081, 1658, 11936, 64735, 65761, 8702, 11606, 64784, 9785, 42123, 64783,
+ 194619, 917779, 5152, 8935, 7533, 119101, 5304, 119820, 616, 4323, 64666,
+ 4684, 65103, 120613, 65735, 65339, 10560, 6048, 4763, 4112, 118935,
+ 10870, 5260, 5328, 65129, 326, 9681, 4475, 917933, 10771, 2876, 194915,
+ 119935, 6035, 41398, 41192, 9802, 13261, 120532, 453, 41396, 917564,
+ 6481, 12140, 9572, 41937, 10392, 10328, 40998, 7704, 66432, 120317, 9800,
+ 4123, 917900, 42103, 41000, 7854, 119239, 6487, 8334, 64061, 10344, 9808,
+ 11271, 5394, 4126, 12800, 9521, 9589, 41200, 41306, 4425, 119856, 10464,
+ 63802, 64769, 1288, 64514, 11528, 63984, 12173, 679, 64012, 41914, 5850,
+ 758, 7536, 10796, 4474, 10742, 10693, 64006, 1587, 64005, 10541, 64581,
+ 65490, 1369, 12134, 119050, 7927, 64009, 1139, 64030, 64026, 64029, 8970,
+ 64948, 4430, 195016, 10774, 4514, 66434, 12421, 8194, 194765, 1852, 3057,
+ 65483, 8893, 64032, 12542, 12973, 65341, 120497, 41206, 7925, 12423,
+ 10475, 917572, 3496, 1352, 10933, 7707, 9102, 627, 42034, 6158, 8327,
+ 64497, 65605, 6040, 917592, 10129, 64863, 9336, 11696, 5730, 1018, 7798,
+ 64474, 64259, 1682, 64290, 7820, 42756, 12951, 119873, 7746, 1492, 0,
+ 8288, 12563, 10728, 5127, 11285, 65509, 5495, 4273, 11577, 9644, 10849,
+ 1833, 2999, 120612, 64373, 120471, 185, 65085, 6023, 169, 5497, 7535,
+ 8085, 917909, 65717, 9749, 8224, 6131, 1949, 4117, 7847, 120489, 119982,
+ 5321, 66355, 65765, 9313, 2589, 64408, 1689, 7802, 4683, 120167, 12303,
+ 64667, 66704, 1184, 0, 815, 8273, 120807, 6049, 120530, 4027, 834,
+ 119833, 1803, 64683, 1503, 8995, 120653, 917924, 5731, 1381, 2387, 64511,
+ 12430, 8289, 10981, 12654, 2881, 65514, 917600, 9601, 332, 9668, 9766,
+ 5142, 2407, 65618, 66601, 6036, 64881, 4026, 8645, 64789, 2887, 6489,
+ 3526, 6298, 119136, 64475, 4833, 1834, 65621, 8572, 6021, 10940, 65249,
+ 119848, 8662, 65739, 119604, 2652, 7463, 11539, 10784, 120720, 64391,
+ 166, 19913, 8635, 9706, 10623, 408, 1828, 195084, 13298, 194889, 7426,
+ 8168, 6280, 12324, 7607, 10639, 66713, 4832, 64557, 41643, 6279, 12508,
+ 8713, 10690, 9161, 41645, 1620, 6645, 646, 66726, 66711, 42129, 609,
+ 11555, 3472, 8697, 41086, 119594, 4343, 6212, 917557, 11413, 5809, 1950,
+ 239, 119021, 637, 65785, 41592, 43029, 917539, 120285, 194837, 3247,
+ 120754, 12985, 12696, 65213, 66668, 65260, 12929, 10983, 712, 120291,
+ 119337, 41567, 65592, 194969, 120171, 119852, 120178, 119137, 1506, 8285,
+ 65617, 4509, 65608, 12651, 12216, 64628, 40988, 11961, 6204, 41727, 7494,
+ 64341, 2396, 41703, 41493, 13062, 41757, 355, 9719, 3886, 9814, 63912,
+ 68123, 65444, 996, 42075, 64880, 43045, 65199, 194810, 8655, 8222,
+ 194839, 7939, 10342, 64720, 3178, 68184, 120552, 5907, 19932, 3976,
+ 917849, 42161, 9471, 5833, 11966, 12555, 5969, 5699, 12562, 12550, 9488,
+ 40982, 8489, 0, 1488, 194829, 13149, 119997, 9799, 5265, 66612, 1563,
+ 11487, 9619, 12464, 119210, 120758, 118952, 41704, 5803, 7797, 6070,
+ 10006, 41181, 465, 6082, 13078, 9692, 194745, 12567, 8116, 795, 66480,
+ 7843, 12462, 3607, 10831, 10046, 9612, 42153, 8218, 9485, 66714, 120301,
+ 12468, 8607, 1008, 65322, 3306, 66485, 65138, 6057, 508, 120264, 1766,
+ 11282, 11996, 1820, 4547, 0, 638, 6083, 120160, 12308, 0, 2305, 917595,
+ 64777, 9470, 4345, 6659, 65236, 4818, 6085, 9899, 65207, 3915, 41634,
+ 5382, 41639, 119591, 6235, 119060, 4028, 1787, 19920, 41979, 120786,
+ 3249, 1768, 1130, 12328, 501, 42016, 10601, 43023, 6503, 65294, 7742,
+ 63992, 13280, 41922, 6505, 118925, 5310, 9475, 66716, 120810, 6500, 5526,
+ 65049, 11408, 65889, 8568, 119818, 11449, 9678, 5403, 120311, 9869,
+ 63780, 1771, 12460, 8936, 120631, 118832, 64903, 10760, 119115, 9158,
+ 66567, 120259, 119025, 120582, 5410, 5783, 10365, 8403, 5400, 11594,
+ 120295, 5027, 9326, 10491, 119348, 4831, 120698, 5028, 5587, 66492, 7540,
+ 5026, 4923, 65086, 8981, 12382, 8931, 120755, 1415, 8866, 917785, 65513,
+ 10461, 12103, 119602, 8642, 5029, 42766, 1580, 3598, 120067, 41070,
+ 10053, 120819, 6663, 119325, 6026, 41515, 118796, 64592, 1716, 1461, 910,
+ 11907, 620, 41001, 3658, 41541, 119980, 66728, 7617, 5024, 12888, 41003,
+ 68180, 5025, 11529, 41514, 64561, 5703, 119124, 41517, 41504, 41519,
+ 66473, 9726, 119160, 5849, 623, 781, 670, 10660, 5769, 613, 6105, 11584,
+ 477, 1268, 65275, 8906, 592, 1578, 2636, 64404, 10815, 11619, 8225,
+ 119578, 654, 6451, 653, 652, 7721, 647, 7869, 633, 120224, 42152, 64361,
+ 12480, 6119, 829, 39, 12487, 19950, 120399, 65865, 6616, 65672, 12489,
+ 9667, 391, 5550, 194870, 482, 917886, 1203, 120345, 1813, 64544, 41311,
+ 9503, 120623, 2877, 120249, 64135, 1675, 4939, 5315, 194801, 64128,
+ 10070, 10595, 13293, 4576, 42094, 12808, 119569, 4277, 40997, 4039,
+ 120429, 64472, 368, 13036, 3960, 65460, 8406, 68176, 120121, 66679, 3958,
+ 12132, 1849, 194564, 270, 13086, 10714, 194617, 11929, 11959, 917824,
+ 64657, 41608, 3618, 65009, 9069, 6273, 5156, 364, 9595, 929, 67616,
+ 42035, 707, 1555, 41725, 8691, 66435, 224, 41662, 68164, 9332, 4966,
+ 194977, 917538, 4578, 64513, 3841, 194647, 65922, 10732, 13074, 850,
+ 4972, 9356, 12820, 2909, 63968, 1286, 10166, 8682, 11544, 10203, 9608,
+ 12815, 7730, 11962, 41540, 12507, 1196, 0, 66471, 777, 10020, 4375,
+ 41372, 6641, 525, 12198, 120443, 8763, 120526, 41628, 533, 11931, 8658,
+ 120743, 41520, 2705, 65010, 13126, 9838, 4377, 8559, 7765, 119925, 8280,
+ 13193, 2701, 11666, 8679, 5767, 1576, 7735, 9809, 8353, 11513, 41960,
+ 42007, 66452, 10889, 1748, 7757, 65265, 120226, 12803, 66493, 2718, 4168,
+ 3061, 13308, 63764, 6596, 1179, 4440, 194759, 7694, 363, 8896, 63768,
+ 3485, 12987, 41586, 64908, 120332, 41149, 1591, 6593, 64625, 10192,
+ 64143, 66455, 13053, 10013, 5630, 194622, 120686, 9492, 10390, 13083,
+ 12833, 5543, 41327, 1640, 12495, 630, 120091, 3138, 10996, 41127, 1043,
+ 120674, 12498, 10090, 917568, 917609, 313, 65543, 8615, 119144, 12540,
+ 493, 41426, 5750, 1717, 9417, 479, 9405, 11268, 0, 9398, 9403, 3520,
+ 8426, 12490, 63855, 65185, 12586, 12493, 5815, 10707, 1002, 12491,
+ 194884, 12934, 631, 66474, 64922, 13161, 41303, 917957, 10546, 67635,
+ 65711, 11600, 65786, 2797, 13107, 65599, 306, 714, 3058, 8507, 65576,
+ 66700, 119961, 120731, 120694, 11607, 65591, 64711, 68166, 7909, 9157,
+ 4569, 63758, 63805, 13297, 7603, 40986, 180, 244, 11542, 12898, 12494,
+ 12674, 8244, 362, 65776, 64145, 8037, 194830, 11535, 120680, 4882, 5185,
+ 64866, 5521, 4885, 5519, 42155, 10302, 4880, 10104, 1027, 1360, 248,
+ 12424, 10523, 1446, 4319, 41646, 991, 5189, 63754, 10494, 65777, 1722,
+ 1870, 120151, 470, 9427, 65271, 5523, 194716, 64527, 4579, 120446, 9549,
+ 12511, 10549, 12514, 9661, 66486, 12000, 9602, 8623, 65172, 120042,
+ 119855, 13095, 12512, 11615, 13041, 6150, 9846, 659, 6098, 0, 1174,
+ 10334, 194592, 8311, 12510, 63856, 12107, 120341, 12513, 9284, 12471,
+ 120733, 12330, 917571, 63853, 119854, 2323, 65288, 2319, 6293, 12477,
+ 118807, 2311, 194661, 4415, 237, 6281, 917902, 0, 9010, 2309, 7897, 8173,
+ 64894, 12469, 7483, 118979, 1736, 10609, 3894, 12228, 9397, 10987, 3383,
+ 9396, 9393, 693, 9130, 314, 9389, 6209, 9387, 9388, 4932, 3842, 9383,
+ 5332, 12204, 9285, 10436, 8185, 41808, 1751, 273, 8165, 13166, 2313,
+ 65449, 7948, 9236, 8544, 4528, 2584, 6301, 41880, 6133, 10484, 9463,
+ 917823, 9339, 7943, 3757, 3147, 195092, 12420, 10421, 120488, 2310,
+ 41112, 2326, 9382, 2565, 9380, 7596, 7921, 9375, 9376, 1683, 9374, 2567,
+ 8596, 12444, 4044, 41274, 12527, 8210, 120756, 1023, 474, 12331, 0,
+ 42032, 8744, 726, 9839, 120313, 5005, 120383, 41276, 42030, 5007, 12522,
+ 9835, 65442, 4951, 634, 12213, 10895, 65492, 274, 120236, 1858, 4744,
+ 4746, 917852, 9548, 65899, 403, 120117, 12503, 9610, 8068, 8197, 63996,
+ 699, 42000, 41665, 1819, 10496, 13007, 42182, 7581, 13262, 194649, 41667,
+ 12506, 10840, 1923, 13084, 12500, 64507, 12509, 64393, 10507, 120692,
+ 10589, 6464, 41047, 2996, 1937, 41931, 12990, 8084, 4047, 3608, 8281,
+ 65016, 1107, 68101, 9076, 8862, 120636, 293, 9369, 64766, 64791, 7803,
+ 13222, 65416, 10579, 8560, 8546, 11553, 12678, 4803, 9043, 1739, 1941,
+ 498, 64471, 1713, 119091, 12529, 8042, 11407, 2344, 12528, 6297, 2414,
+ 64139, 66710, 3231, 11716, 6422, 9902, 65156, 12530, 2537, 969, 41429,
+ 12658, 13034, 6165, 13035, 917620, 6632, 4719, 469, 119240, 4363, 5211,
+ 8914, 119299, 119334, 1772, 1435, 64876, 2969, 6046, 64812, 6208, 64101,
+ 5746, 12215, 119332, 4931, 1951, 8612, 119363, 9607, 917904, 338, 118797,
+ 5061, 10675, 41106, 10767, 1491, 8115, 65459, 11941, 10139, 8227, 8270,
+ 1218, 12126, 41993, 12168, 6642, 63808, 12889, 1622, 41108, 4486, 41995,
+ 1075, 1958, 10925, 41992, 41506, 118975, 10249, 64122, 10257, 41569,
+ 10273, 120327, 7692, 12669, 8008, 120320, 330, 8566, 65083, 9046, 41117,
+ 41126, 12532, 120648, 64131, 3508, 7794, 119943, 64129, 9645, 64662,
+ 10770, 3669, 3968, 64115, 66644, 13028, 120302, 12537, 194802, 64120,
+ 65720, 12536, 2350, 13029, 6583, 120072, 12116, 13030, 66678, 4527, 1588,
+ 12538, 8409, 65718, 10683, 41670, 787, 9502, 4948, 12484, 4032, 118940,
+ 7449, 65399, 6207, 120536, 6117, 65401, 8412, 65247, 7438, 8734, 644,
+ 9769, 41657, 10149, 3659, 9533, 184, 1553, 10827, 12488, 65382, 10502,
+ 41556, 12623, 65474, 2354, 120214, 8220, 118856, 6295, 901, 41510, 7953,
+ 118826, 5157, 4020, 63811, 11927, 66584, 13079, 194959, 41687, 64303,
+ 120735, 7520, 848, 9868, 65620, 6424, 194714, 65916, 66495, 64094,
+ 118926, 7877, 2352, 41826, 120726, 64576, 11289, 1407, 10911, 65607,
+ 13026, 120503, 7941, 11715, 8362, 8903, 9777, 66715, 1871, 5869, 8636,
+ 120290, 1343, 65160, 12649, 9325, 13025, 6283, 11738, 12643, 194623,
+ 65181, 11741, 8543, 10051, 9216, 8263, 11279, 41258, 8625, 118840, 11290,
+ 10477, 3136, 8733, 11582, 8315, 13022, 8772, 64588, 0, 6152, 41456, 5477,
+ 6629, 10112, 19916, 13020, 66723, 8675, 120324, 194766, 67600, 120351,
+ 10978, 8029, 6091, 120350, 4485, 3335, 64591, 3590, 9776, 41397, 66578,
+ 5215, 194750, 3333, 1632, 63900, 3588, 3342, 9341, 5363, 12957, 12725,
+ 68113, 63852, 64076, 223, 64079, 1611, 13246, 13018, 65835, 63792, 65245,
+ 3337, 1171, 11275, 11736, 41097, 1805, 6482, 41423, 64113, 11945, 8708,
+ 13046, 8838, 425, 4025, 5013, 41868, 120235, 2392, 13047, 4530, 120105,
+ 10617, 1213, 119233, 120103, 797, 118814, 7888, 13050, 120349, 64387,
+ 4115, 65557, 65862, 65587, 3277, 8929, 4947, 41055, 195072, 64276, 426,
+ 66497, 13045, 8251, 10136, 7751, 120109, 8371, 119253, 1224, 12806, 8768,
+ 13044, 10701, 1764, 3101, 64469, 8480, 1078, 9757, 65223, 41057, 65567,
+ 120572, 8663, 9312, 4413, 4539, 3787, 42160, 9222, 67617, 9165, 1572,
+ 9092, 12593, 41961, 2346, 12724, 8958, 66653, 9646, 3773, 41825, 1293,
+ 7947, 12003, 120228, 13043, 8056, 2454, 5349, 208, 194718, 65869, 64849,
+ 65888, 8816, 10699, 6408, 0, 7825, 5661, 917587, 12595, 3603, 41109,
+ 2398, 3548, 1157, 64291, 8638, 68167, 917821, 3115, 194771, 11321,
+ 118787, 8235, 4405, 10086, 4876, 194808, 195085, 119256, 65430, 10624,
+ 6079, 12646, 10764, 8158, 41561, 41472, 998, 13051, 13105, 3143, 120156,
+ 194673, 41559, 1896, 7882, 13052, 118948, 5665, 530, 65814, 11269,
+ 120566, 12002, 64526, 5742, 5664, 4692, 8979, 12310, 4007, 5004, 11330,
+ 7896, 751, 6595, 3382, 63959, 66373, 13231, 11533, 64874, 4732, 6311,
+ 194936, 11596, 63976, 1626, 63977, 10110, 64056, 41705, 6420, 6598,
+ 64327, 6599, 2795, 4910, 65308, 118825, 119328, 6275, 6597, 41699, 8340,
+ 119335, 3229, 6423, 42774, 11019, 65390, 5407, 12823, 2331, 41678, 42026,
+ 6137, 2336, 7524, 194816, 66720, 42759, 8339, 1921, 120003, 19927,
+ 195038, 822, 64870, 9903, 4284, 119593, 194648, 43010, 12841, 9229,
+ 10956, 41255, 12607, 5311, 1795, 965, 3521, 10587, 5774, 8325, 917931,
+ 65403, 917915, 1854, 10794, 119250, 10057, 6294, 3144, 64780, 5280,
+ 65019, 4344, 12905, 41610, 6076, 748, 12385, 768, 535, 442, 9507, 194641,
+ 119346, 10556, 2475, 12388, 4889, 8968, 6071, 3593, 64093, 4804, 2342,
+ 917797, 1800, 120098, 4894, 467, 4890, 120342, 64644, 120707, 4893, 8421,
+ 12433, 10666, 4888, 502, 64080, 64615, 41490, 120142, 12043, 10119, 316,
+ 65878, 10230, 65191, 41297, 64924, 64086, 64746, 2332, 4860, 412, 65728,
+ 11997, 12432, 9583, 8058, 5546, 8019, 194597, 66561, 63750, 12203, 5544,
+ 2355, 8913, 65725, 4875, 10613, 66692, 12137, 5548, 9344, 6250, 7944,
+ 65582, 13104, 6077, 12383, 64519, 119132, 11301, 3134, 119339, 65696,
+ 4669, 917812, 917789, 194894, 3050, 63839, 10319, 119075, 10383, 118842,
+ 4592, 11008, 10809, 194800, 4691, 6543, 9345, 621, 917597, 120055, 4328,
+ 10734, 120032, 64631, 917906, 7804, 19904, 10811, 8457, 10545, 4914,
+ 10271, 3786, 8886, 4917, 66461, 64914, 7923, 3716, 5464, 9996, 8508,
+ 2361, 7971, 8195, 194706, 9566, 7682, 3722, 8086, 41707, 10845, 545,
+ 2312, 40977, 10050, 10874, 8305, 8859, 41458, 40980, 65110, 13202,
+ 195028, 12582, 9119, 2787, 7920, 41521, 4021, 6288, 7985, 119349, 5653,
+ 65802, 10891, 7698, 5658, 410, 41552, 1802, 12220, 4913, 120466, 41659,
+ 41671, 1827, 917894, 64396, 41668, 9077, 2327, 8810, 11422, 120372,
+ 12705, 3860, 10756, 9239, 8821, 6153, 2867, 119118, 42158, 698, 120359,
+ 8749, 10356, 12698, 64858, 361, 12641, 845, 194599, 41560, 11970, 4562,
+ 63756, 2926, 119566, 4099, 66439, 194695, 7936, 120303, 611, 68124, 4716,
+ 118891, 41382, 119207, 7686, 120568, 194595, 68178, 120543, 118875,
+ 119612, 6291, 5462, 10823, 41669, 9734, 65455, 9071, 4655, 4151, 13295,
+ 0, 66632, 839, 42162, 7695, 8769, 65246, 10737, 119194, 4859, 64467,
+ 65504, 4826, 64157, 41090, 917837, 6647, 64727, 66447, 63845, 2700,
+ 12576, 7842, 12839, 120825, 804, 2699, 66596, 10542, 2985, 119222, 64806,
+ 8271, 10091, 11915, 9468, 119312, 9827, 64106, 119311, 286, 12323,
+ 118830, 11481, 118942, 119305, 1425, 35, 119229, 65084, 66694, 41210,
+ 64432, 8482, 119113, 6090, 5032, 7812, 10534, 7894, 664, 119588, 5034,
+ 4272, 65211, 40967, 40965, 42024, 12704, 13294, 66589, 64869, 6032,
+ 120367, 9129, 7430, 917922, 119609, 68112, 194813, 5244, 6130, 65714,
+ 41161, 5518, 4174, 1879, 8189, 968, 12222, 1169, 434, 11541, 66573, 6034,
+ 9739, 64744, 12574, 118867, 194995, 524, 118990, 118934, 788, 120433,
+ 12679, 64506, 64150, 1663, 10419, 8574, 41227, 118805, 12346, 12855,
+ 64848, 41030, 10415, 41562, 120599, 65623, 118850, 64571, 0, 19939,
+ 67614, 959, 8885, 12564, 64333, 118855, 9469, 5195, 5445, 9355, 64323,
+ 42151, 4644, 8989, 221, 310, 41253, 41564, 8010, 119301, 4962, 63766,
+ 8855, 10054, 6497, 9091, 917544, 9012, 19958, 12088, 41002, 13215, 65047,
+ 10451, 64260, 374, 120153, 816, 64634, 120148, 120054, 41934, 3873, 8367,
+ 917784, 64608, 4715, 6101, 11987, 41936, 194572, 4879, 12723, 65089,
+ 11683, 307, 120416, 9585, 5374, 64286, 1462, 10235, 41390, 8627, 65579,
+ 12119, 65028, 13024, 1929, 120426, 12142, 8611, 12236, 41419, 194618,
+ 66507, 12982, 64374, 5378, 194666, 64295, 41421, 917838, 741, 10083,
+ 119309, 65026, 821, 65350, 2498, 5800, 10755, 2992, 1760, 8124, 4469,
+ 2324, 828, 3611, 119084, 757, 1185, 120271, 531, 120728, 10628, 119020,
+ 120437, 7999, 8204, 3614, 2827, 9696, 10942, 7713, 2348, 4354, 10904,
+ 4380, 19936, 7833, 10573, 5320, 41240, 862, 3000, 10301, 1810, 3673,
+ 5137, 9525, 64569, 9354, 65622, 0, 7566, 10121, 64940, 120716, 66693,
+ 12824, 13066, 3062, 7970, 64741, 12608, 194600, 5871, 41160, 9700, 12580,
+ 917591, 65748, 119811, 3967, 7898, 13137, 8775, 64560, 12713, 2963, 9090,
+ 8410, 4454, 723, 1734, 966, 4449, 917815, 64594, 2456, 231, 2320, 120225,
+ 339, 4968, 120535, 40989, 8075, 1230, 120795, 8047, 3597, 9761, 10584,
+ 41542, 65404, 1290, 66358, 8352, 917874, 5687, 66698, 3840, 1584, 119963,
+ 6045, 0, 10498, 9704, 64136, 64138, 10992, 7537, 12311, 8660, 120357,
+ 8365, 8643, 65029, 119049, 4483, 1709, 64399, 7466, 6080, 13092, 64140,
+ 1746, 6072, 8667, 12121, 65604, 13140, 11414, 65031, 2531, 4480, 120765,
+ 64141, 1226, 1259, 7517, 10394, 41231, 10897, 120257, 605, 67619, 641,
+ 5219, 12342, 64100, 41500, 41129, 311, 11453, 6221, 9075, 120358, 5466,
+ 10877, 118868, 11451, 120737, 4535, 2667, 4271, 65406, 64188, 345, 41410,
+ 10829, 41198, 195027, 41407, 64104, 5037, 41131, 1776, 8422, 11266,
+ 64103, 41508, 4660, 323, 65305, 917813, 6649, 1295, 120010, 4625, 2563,
+ 4630, 247, 119135, 119870, 12338, 4651, 2668, 6657, 194941, 13223, 11933,
+ 2519, 119973, 41903, 41079, 5053, 194787, 5049, 119924, 11335, 706, 7754,
+ 7727, 8738, 4031, 6278, 5009, 9672, 649, 5514, 118920, 66702, 10280,
+ 12670, 1013, 41218, 3877, 705, 41591, 8755, 194900, 1183, 4184, 8268,
+ 65918, 65301, 8157, 9736, 64503, 65418, 118921, 4747, 4712, 43013, 11913,
+ 4718, 194632, 10837, 5141, 10614, 65733, 7962, 12211, 9837, 65831, 64722,
+ 119008, 5719, 65706, 9773, 119068, 119147, 1857, 65547, 4626, 8464, 859,
+ 194795, 4629, 8499, 6059, 41134, 4624, 7818, 8535, 119914, 65179, 7805,
+ 64805, 11488, 12242, 41011, 120220, 64119, 10558, 917955, 917918, 118950,
+ 8492, 8250, 8459, 120597, 1788, 1579, 10766, 64117, 195050, 8048, 9543,
+ 9028, 120522, 64516, 65849, 13185, 1285, 64114, 120777, 8240, 8684, 8170,
+ 6102, 41762, 5298, 12625, 5294, 65204, 42013, 3940, 41597, 119917,
+ 917873, 9816, 8665, 65851, 11436, 12630, 1653, 64669, 10153, 120601,
+ 6166, 118791, 118989, 41377, 5292, 66673, 65046, 1939, 913, 3970, 64599,
+ 12455, 1793, 66637, 120162, 118837, 6643, 8211, 65263, 0, 194703, 64127,
+ 64081, 119125, 3514, 13219, 9569, 10865, 11958, 5263, 13286, 64126, 5500,
+ 10022, 65387, 65500, 65384, 5322, 980, 66354, 10008, 5324, 66600, 3784,
+ 41614, 64751, 6230, 194767, 63885, 10085, 3360, 8098, 11523, 6634, 41734,
+ 10096, 41613, 8072, 119321, 119322, 41821, 1249, 7783, 41731, 12032,
+ 8237, 63840, 64899, 12395, 7425, 12818, 120565, 10462, 41150, 194574,
+ 9795, 66680, 64664, 13213, 194601, 120222, 41152, 194679, 9249, 6565,
+ 7808, 1829, 120479, 11670, 4358, 65315, 6670, 11426, 194865, 120223,
+ 12391, 1710, 12160, 10168, 8777, 9781, 49, 6627, 66708, 6258, 8269,
+ 120594, 9741, 194923, 5649, 119100, 315, 12813, 1643, 119988, 12397,
+ 3470, 8884, 65175, 41099, 65314, 13299, 1378, 65163, 1072, 120607,
+ 118802, 3066, 6576, 119300, 120002, 65675, 1080, 41293, 8787, 194828,
+ 1101, 41618, 120001, 8405, 0, 12632, 1086, 1869, 42088, 7680, 8847,
+ 10805, 65884, 12639, 3380, 8123, 1091, 6121, 7977, 4501, 12665, 8119,
+ 12998, 66309, 917927, 1494, 11693, 3127, 194567, 64945, 12930, 1394,
+ 119230, 65872, 12363, 5345, 9789, 2998, 9527, 120659, 64582, 12977,
+ 12309, 42090, 3861, 10635, 12939, 12404, 12413, 42003, 2495, 5848, 8726,
+ 5570, 1881, 12410, 41722, 1012, 8100, 7890, 120296, 11298, 10649, 5569,
+ 6229, 1593, 65319, 6063, 619, 65128, 65080, 6053, 65602, 4120, 65337,
+ 64372, 9160, 917928, 119214, 11776, 9366, 9016, 42006, 6055, 3870, 4279,
+ 2500, 10757, 1507, 8497, 8602, 65316, 13021, 65334, 65333, 11694, 65331,
+ 42059, 42061, 9080, 120099, 9128, 64480, 5571, 3674, 9740, 9121, 4371,
+ 5798, 10408, 42085, 10107, 4106, 41989, 65313, 42074, 63999, 11326, 0,
+ 10233, 13098, 65813, 41239, 10094, 195026, 8182, 0, 119831, 68152, 11947,
+ 9803, 5847, 1505, 9131, 65161, 4615, 12695, 41988, 41250, 12175, 917864,
+ 19966, 119582, 7809, 120626, 120445, 562, 8120, 6590, 194565, 13033,
+ 64738, 3219, 68097, 10664, 1366, 1037, 67623, 4551, 65545, 68131, 66334,
+ 10637, 4568, 549, 1570, 10478, 2835, 12517, 557, 9457, 5952, 64649,
+ 41056, 12519, 41004, 119307, 2825, 66636, 10825, 8079, 2821, 41046, 0,
+ 42071, 12111, 3927, 13071, 12515, 452, 5271, 5492, 64718, 2831, 10604,
+ 10144, 11465, 5212, 5493, 41120, 8916, 13027, 9747, 12019, 41332, 1618,
+ 12069, 917584, 1668, 10430, 917766, 5853, 1187, 10363, 1121, 12956,
+ 120656, 119107, 11314, 3240, 12060, 12194, 65180, 41631, 11591, 5323,
+ 8166, 4557, 6415, 2707, 8309, 1623, 65297, 41052, 571, 2697, 4918, 11339,
+ 4912, 2695, 11598, 65048, 66438, 8864, 64755, 64798, 10736, 2693, 12125,
+ 7615, 12826, 1164, 194583, 6411, 1035, 41067, 119142, 7881, 701, 9758,
+ 3489, 119296, 7469, 11569, 5248, 12218, 120538, 6303, 3796, 41123, 65688,
+ 3994, 11421, 10457, 9991, 41128, 64485, 5792, 12347, 9873, 42171, 2855,
+ 7994, 64762, 6104, 65351, 6591, 9340, 9532, 1589, 119226, 296, 3246,
+ 7906, 2879, 41981, 41620, 64942, 7815, 65855, 120482, 917817, 66457,
+ 10585, 12579, 1496, 747, 6416, 942, 2378, 10960, 11618, 5299, 0, 9320,
+ 5449, 1232, 8139, 6216, 41431, 917970, 11409, 5295, 66624, 64392, 1223,
+ 1642, 174, 120824, 11612, 4161, 2374, 120546, 8475, 3212, 66313, 3211,
+ 194576, 5286, 119297, 0, 64142, 9728, 3846, 8070, 5536, 6636, 7705,
+ 11942, 11305, 12136, 3309, 67612, 66377, 41491, 66325, 4986, 12189,
+ 41653, 1280, 1241, 917537, 4257, 8496, 67608, 6220, 9004, 65411, 65203,
+ 41513, 41650, 120791, 194578, 120608, 12914, 12884, 194575, 9890, 6078,
+ 10237, 917943, 1475, 64917, 11979, 6084, 118900, 41064, 41061, 9635,
+ 12600, 3256, 41236, 42039, 0, 6469, 65377, 8727, 10654, 4679, 41237,
+ 64073, 64867, 6531, 65285, 65329, 64069, 10640, 3248, 2613, 3261, 9015,
+ 119829, 66568, 3635, 64337, 41651, 41241, 64944, 3494, 6449, 6555, 10588,
+ 66588, 120581, 194783, 67597, 635, 13139, 65898, 65613, 65312, 5447,
+ 68108, 194826, 64382, 4010, 7445, 8600, 41915, 65804, 4176, 41105, 5812,
+ 65820, 6232, 65891, 68142, 194588, 318, 5302, 195022, 6538, 4335, 3649,
+ 3941, 41122, 41110, 3634, 64892, 9113, 1954, 12155, 7866, 120297, 11402,
+ 11733, 64296, 120138, 66470, 2849, 66375, 66697, 7938, 11728, 1761, 4586,
+ 65379, 350, 10930, 119090, 509, 194792, 119603, 9365, 66687, 542, 5133,
+ 41680, 64551, 9500, 11534, 1514, 11668, 65823, 5453, 65533, 64921,
+ 119967, 2496, 8493, 944, 9368, 3890, 1624, 1438, 8817, 120592, 10818,
+ 41947, 1220, 120828, 63931, 1194, 3242, 1571, 9555, 8598, 11457, 6169,
+ 943, 564, 2798, 312, 194999, 11532, 66363, 120161, 8877, 269, 3495, 6272,
+ 9617, 1460, 8988, 120660, 4891, 195031, 10641, 0, 41119, 41416, 917602,
+ 4173, 120289, 63786, 120574, 12895, 64955, 41418, 11357, 119022, 120286,
+ 41415, 6296, 9582, 193, 12188, 917835, 64680, 11428, 1730, 2457, 4493,
+ 2314, 8427, 1362, 9822, 7703, 8840, 5807, 119054, 120451, 8534, 6658,
+ 4426, 917796, 41612, 42758, 11497, 7874, 8681, 5220, 120281, 13136,
+ 119825, 2416, 3310, 10972, 63886, 379, 119215, 13220, 63787, 120449,
+ 3223, 5517, 1284, 8041, 4549, 120475, 5240, 9811, 10012, 3096, 65239,
+ 42768, 43040, 8515, 8688, 12866, 64146, 3294, 9501, 119631, 1272, 65485,
+ 7564, 64654, 7467, 65210, 1467, 10158, 10040, 5288, 9519, 41861, 8132,
+ 64090, 118899, 12193, 66615, 65493, 3215, 917863, 7710, 1610, 65114,
+ 12307, 63881, 65682, 66465, 5181, 5275, 120195, 228, 8637, 1501, 66676,
+ 3789, 5179, 11471, 6225, 10765, 11474, 1725, 66603, 8196, 9352, 12042,
+ 42752, 917543, 9537, 3961, 5762, 1967, 2605, 4500, 63873, 8104, 4981,
+ 7474, 3405, 64862, 11667, 10414, 9821, 8141, 9559, 2600, 1557, 7589,
+ 64851, 64549, 3237, 8631, 2545, 10466, 8541, 917616, 194747, 41866,
+ 917973, 120430, 42762, 7481, 0, 1650, 262, 1637, 10958, 7901, 3238,
+ 41945, 65556, 41941, 3308, 65158, 10860, 8614, 65220, 7527, 120624,
+ 41943, 6419, 120244, 45, 6401, 120022, 8106, 4128, 10065, 64083, 4494,
+ 9590, 4012, 10395, 917762, 9084, 4537, 8737, 64089, 11004, 695, 739, 696,
+ 7611, 2620, 42755, 194913, 9227, 7506, 179, 5098, 691, 738, 2853, 7512,
+ 7515, 3868, 688, 119009, 690, 2548, 737, 974, 2801, 119837, 10854,
+ 119012, 10034, 3985, 8783, 65860, 9362, 10177, 120247, 4682, 118869,
+ 12809, 6406, 4685, 3158, 10879, 4389, 4680, 923, 41863, 3851, 292, 13002,
+ 119845, 119844, 3221, 1763, 64468, 4612, 119851, 119850, 12999, 41219,
+ 11718, 41314, 10782, 3637, 12996, 119141, 11717, 63922, 10594, 3228,
+ 11712, 64624, 120405, 10967, 2731, 194721, 9651, 651, 3891, 7696, 66706,
+ 2337, 1735, 120630, 917891, 4177, 11283, 9089, 66312, 64695, 120580,
+ 11438, 1860, 2654, 7580, 1856, 7497, 7584, 194722, 66356, 10914, 3458,
+ 3208, 12975, 8498, 119121, 8949, 3065, 9450, 120472, 1569, 63888, 12534,
+ 12124, 7690, 119254, 12533, 120251, 6418, 4543, 41471, 917629, 64674,
+ 42180, 194881, 0, 10859, 917615, 41544, 41689, 63789, 12282, 64909, 6646,
+ 11790, 8108, 8850, 9238, 5066, 8561, 4573, 13108, 6421, 12791, 119849, 0,
+ 8257, 12891, 8778, 10630, 12900, 917992, 10950, 8314, 6459, 12790, 8804,
+ 65092, 41153, 12792, 11342, 42018, 1744, 12789, 10366, 12317, 10137,
+ 67610, 13164, 10723, 967, 120253, 64546, 12690, 41307, 3257, 65550, 9862,
+ 1845, 2974, 10446, 11315, 0, 278, 10580, 10089, 870, 66569, 3499, 8609,
+ 42149, 876, 871, 877, 6002, 878, 42015, 879, 120336, 4563, 65176, 41308,
+ 7591, 65306, 867, 9520, 872, 8646, 868, 873, 119868, 11514, 869, 874,
+ 63989, 1940, 875, 790, 220, 65193, 194845, 10678, 10044, 41589, 5429,
+ 13082, 194585, 6403, 5707, 10393, 120005, 120267, 42067, 41890, 5433,
+ 10657, 7911, 120266, 1547, 9775, 3959, 119316, 5425, 4977, 2467, 5317,
+ 5423, 4611, 63843, 8040, 5069, 9679, 4182, 119244, 4676, 120501, 41073,
+ 4418, 2510, 4628, 10208, 12989, 118784, 10399, 1851, 12186, 119574,
+ 11908, 120254, 9360, 9083, 13180, 41764, 11601, 12837, 8829, 7711, 64423,
+ 12115, 67636, 12377, 41281, 8809, 41647, 365, 12056, 10857, 917831,
+ 41716, 65395, 41228, 119865, 5516, 2845, 7717, 4588, 41717, 63830, 544,
+ 12045, 2433, 917897, 5515, 3352, 65373, 64377, 65437, 793, 65194, 194740,
+ 305, 567, 119002, 842, 66627, 8208, 917556, 41695, 1647, 118877, 5608,
+ 63824, 65407, 818, 5337, 119143, 13278, 65597, 9638, 8061, 8735, 12483,
+ 120468, 13003, 6667, 10973, 66359, 1372, 118858, 7556, 4969, 1254, 11264,
+ 989, 64257, 118862, 65228, 6060, 65266, 4326, 2840, 64601, 13068, 194985,
+ 65242, 3245, 5768, 65601, 949, 119351, 194893, 6148, 8605, 2651, 119634,
+ 64570, 917912, 119563, 194888, 65106, 120418, 41451, 63871, 41796, 1269,
+ 6530, 63868, 41777, 6414, 5144, 3226, 655, 752, 4431, 4331, 7452, 3285,
+ 41834, 5279, 12908, 10336, 8312, 41754, 12091, 671, 250, 7434, 618, 668,
+ 610, 6428, 7431, 1152, 5256, 640, 41229, 7448, 1067, 255, 3905, 65196,
+ 9493, 65588, 41014, 10795, 194791, 194741, 120421, 917772, 10653, 41272,
+ 195001, 13287, 917805, 6560, 9019, 118943, 195052, 65409, 987, 64410,
+ 5527, 2768, 10684, 3365, 5135, 118924, 12796, 11953, 120412, 65732, 5139,
+ 346, 11334, 6305, 12609, 4675, 5168, 5530, 5210, 917774, 4627, 8253,
+ 5208, 1136, 65433, 120587, 5218, 7976, 118864, 11963, 3244, 5529, 0,
+ 194742, 917794, 5432, 64258, 4041, 8784, 2357, 11521, 5528, 229, 42140,
+ 65876, 12350, 65848, 119881, 12241, 119197, 4000, 7429, 7428, 665, 7424,
+ 3206, 7770, 7884, 64853, 0, 65838, 194779, 211, 2509, 7790, 10470, 7861,
+ 3220, 9156, 64050, 450, 8951, 5214, 10432, 8118, 5450, 10768, 1233, 4661,
+ 5852, 8984, 66338, 41802, 1708, 1839, 40985, 2623, 10927, 1701, 195064,
+ 2388, 4698, 41761, 1066, 8361, 4701, 41758, 5444, 2617, 64889, 8267,
+ 66645, 65610, 194642, 7516, 118958, 2625, 8801, 3053, 4340, 120139, 3631,
+ 10955, 7850, 120292, 8416, 119977, 4008, 65507, 12644, 12660, 8232,
+ 12156, 194807, 194624, 41069, 41719, 65812, 12099, 4310, 4336, 6252, 713,
+ 41068, 7990, 3990, 119203, 65113, 64638, 5017, 13145, 4489, 118959,
+ 42138, 1030, 5358, 64577, 9513, 10196, 9357, 194764, 1773, 10250, 10258,
+ 2712, 1635, 7745, 1410, 12077, 64650, 94, 1880, 120149, 194731, 8908,
+ 559, 118879, 12862, 194984, 10752, 4892, 10876, 64537, 6542, 8732, 8472,
+ 5777, 1757, 759, 4696, 2586, 65248, 8945, 8466, 3641, 5419, 41803, 42062,
+ 67596, 118806, 120344, 3668, 65754, 8610, 12226, 7592, 856, 2340, 936,
+ 13289, 64478, 66631, 1459, 65747, 10499, 2962, 19953, 2321, 1504, 10465,
+ 41312, 8921, 120548, 7529, 65154, 64525, 41901, 63814, 4113, 2949, 2372,
+ 336, 194774, 2958, 12152, 5348, 682, 2395, 65252, 13291, 7513, 10593,
+ 1703, 4013, 64764, 8033, 120064, 65152, 9810, 6534, 4150, 12970, 8318,
+ 41790, 10109, 41893, 2360, 41794, 12858, 120493, 3999, 3777, 65629, 1965,
+ 9796, 2411, 11336, 799, 195097, 10276, 10308, 10372, 41714, 8501, 63833,
+ 2317, 10260, 41317, 65767, 5417, 917969, 10384, 120073, 9353, 917546,
+ 7753, 2351, 6655, 64489, 6569, 13119, 119812, 41287, 119236, 230, 11293,
+ 12009, 119813, 4855, 4165, 8746, 5441, 9654, 10288, 10320, 65665, 855,
+ 120396, 6109, 4784, 12337, 13270, 7786, 10098, 41147, 194570, 63769, 680,
+ 6274, 10312, 1181, 19915, 3174, 13127, 120011, 64822, 41887, 41444, 4862,
+ 9735, 6537, 119237, 66650, 3914, 41037, 10828, 9007, 12961, 41039,
+ 118861, 9033, 6231, 289, 65302, 4694, 11420, 4690, 120654, 42760, 194898,
+ 4693, 63816, 40987, 4667, 4688, 120591, 8828, 194637, 65763, 1246, 3110,
+ 19940, 12197, 11021, 4749, 917895, 43035, 921, 218, 64868, 1520, 242,
+ 4786, 1566, 8217, 8932, 64653, 7834, 10088, 6548, 118908, 64681, 5313,
+ 951, 8888, 64534, 4816, 7604, 43032, 4009, 194694, 194717, 65440, 41549,
+ 119069, 12340, 119138, 119887, 4689, 119888, 4048, 120158, 119209, 6507,
+ 1646, 41755, 119891, 4040, 194734, 65118, 68134, 2579, 119905, 3177,
+ 8207, 9099, 4107, 120130, 119894, 662, 120706, 9244, 66623, 13059, 10084,
+ 120339, 65669, 65836, 10179, 41929, 3399, 9851, 40991, 8739, 9059, 0,
+ 7687, 64637, 8854, 40993, 52, 13241, 6475, 917901, 120444, 1777, 9151,
+ 1137, 118914, 749, 65169, 120584, 5385, 3978, 65842, 120283, 11592, 5989,
+ 65827, 10170, 65013, 6544, 41685, 64702, 119365, 8425, 41684, 917780,
+ 519, 10369, 11740, 1585, 194987, 9888, 422, 1500, 10305, 986, 41170,
+ 3666, 5781, 5599, 3098, 2494, 120202, 4861, 0, 64334, 63986, 6558, 64818,
+ 41221, 42165, 8961, 252, 10243, 10245, 63936, 917505, 120398, 194707,
+ 63751, 9478, 2508, 9060, 119587, 202, 10761, 119114, 1242, 12899, 120447,
+ 11734, 63940, 11730, 917937, 9593, 10543, 2403, 12979, 64609, 0, 9787,
+ 2504, 9784, 41024, 7764, 42076, 9514, 64132, 5859, 119259, 2858, 8298,
+ 12333, 65040, 65478, 9691, 4971, 12992, 2753, 1936, 917877, 8456, 2751,
+ 12662, 2763, 8953, 42104, 10731, 7774, 4780, 9792, 63990, 194753, 194871,
+ 194693, 118927, 2856, 10019, 47, 10482, 2823, 4365, 120629, 917551, 3647,
+ 7899, 2602, 8417, 65903, 917558, 41135, 118824, 4033, 118854, 194761,
+ 172, 194720, 212, 41137, 1889, 12320, 6545, 64623, 917859, 7597, 8915,
+ 2759, 945, 3732, 120230, 917567, 5344, 194851, 1291, 11485, 9062, 119252,
+ 9531, 13155, 8505, 64479, 12062, 119018, 64703, 65487, 42065, 10900,
+ 10370, 1263, 3720, 12048, 63935, 64292, 41524, 64692, 12652, 6099, 41534,
+ 64133, 63933, 64426, 299, 65540, 118859, 63951, 3524, 12933, 8831, 65752,
+ 8674, 3075, 119890, 8245, 917867, 12624, 120559, 1673, 4811, 63928, 5845,
+ 9338, 3046, 65414, 2581, 4001, 41811, 9820, 64098, 12187, 5551, 68114,
+ 5984, 63791, 120687, 4393, 10566, 68182, 8680, 65555, 118851, 2588, 5422,
+ 65900, 43028, 3491, 2471, 917626, 2883, 2749, 63921, 195054, 7492, 7740,
+ 119355, 119134, 675, 120551, 63924, 194568, 7502, 6219, 63926, 65726,
+ 41232, 9329, 63925, 7610, 219, 63945, 41330, 692, 65200, 120775, 9240,
+ 3181, 9688, 119816, 1222, 65775, 8262, 11785, 64530, 0, 64610, 3092,
+ 12092, 9615, 7453, 120128, 8013, 119857, 120456, 195019, 8895, 5253,
+ 65774, 5458, 917816, 922, 65923, 119318, 11338, 194930, 3218, 12618,
+ 63997, 120469, 11664, 8962, 8569, 9641, 11932, 12202, 3214, 120461, 9604,
+ 12053, 3207, 120465, 63826, 1901, 63939, 120141, 63825, 2844, 3205,
+ 41974, 41286, 12139, 65666, 64708, 119580, 3358, 2606, 119364, 3104,
+ 2608, 11496, 1173, 10901, 5308, 120079, 290, 917988, 11779, 2862, 2792,
+ 64498, 66371, 378, 2610, 66591, 65079, 6552, 65372, 66707, 37, 64195,
+ 120154, 1814, 64860, 3209, 118843, 120804, 10638, 9768, 64648, 917984,
+ 66372, 7606, 2591, 2837, 4341, 41403, 64105, 42159, 5233, 65270, 64792,
+ 120794, 3570, 9112, 119948, 863, 9490, 63761, 1685, 595, 12715, 118871,
+ 1292, 6222, 65705, 3654, 66638, 9637, 120268, 2535, 6541, 119181, 10656,
+ 120246, 3243, 9014, 5606, 63762, 538, 11006, 5602, 7807, 8073, 6547,
+ 10629, 8203, 63994, 3056, 8458, 41778, 8495, 8762, 10508, 917552, 779,
+ 9818, 64367, 2465, 3463, 8193, 65721, 9730, 8695, 4738, 11322, 5811,
+ 4346, 64904, 194735, 504, 64321, 10899, 8982, 119954, 0, 0, 782, 4867,
+ 10883, 1262, 64771, 732, 3737, 194954, 1548, 13151, 120589, 1832, 5604,
+ 5611, 41141, 7460, 4376, 64612, 11991, 3745, 41738, 10011, 1502, 65712,
+ 194670, 3869, 11937, 5702, 3655, 1783, 119899, 5728, 120564, 13285,
+ 42174, 11918, 9603, 5724, 5254, 5727, 7724, 119573, 119901, 764, 5129,
+ 120655, 120460, 10597, 7579, 5614, 5893, 6223, 11720, 42073, 11423,
+ 119863, 64409, 119862, 4792, 917770, 1964, 6559, 11726, 12146, 65378,
+ 10687, 43019, 119629, 894, 300, 65744, 10037, 12223, 118936, 1478, 9783,
+ 2562, 2607, 64740, 64830, 0, 11652, 917627, 11777, 41780, 6132, 64946,
+ 5096, 5095, 2863, 3424, 0, 10454, 68146, 5094, 10093, 4369, 13156, 12306,
+ 5401, 5093, 119909, 12004, 65251, 5092, 526, 11327, 41295, 5091, 176,
+ 41691, 8985, 4104, 119911, 6285, 1215, 11985, 5744, 12272, 9832, 65590,
+ 3713, 13218, 41191, 119343, 8980, 118988, 12293, 8844, 7433, 11794,
+ 42036, 4278, 1737, 8987, 12917, 195068, 9074, 4348, 9335, 7760, 118991,
+ 6553, 10339, 5255, 1786, 661, 120126, 5475, 917876, 41854, 68102, 194754,
+ 12419, 1160, 1267, 68143, 41217, 65858, 10018, 360, 67586, 3621, 64635,
+ 5863, 3137, 11345, 6562, 12928, 41216, 1228, 2616, 119190, 64401, 65234,
+ 10745, 1714, 3135, 120637, 120143, 0, 3142, 119186, 119995, 10819, 64163,
+ 6577, 65772, 64, 1470, 194566, 10291, 6227, 2826, 41749, 66433, 119864,
+ 6163, 9708, 13250, 0, 42011, 41224, 8603, 12206, 5839, 1702, 1240, 41461,
+ 6286, 119882, 5834, 66451, 3858, 119089, 1765, 12086, 42001, 1600, 13228,
+ 64729, 0, 8401, 120520, 11310, 9282, 8882, 118929, 10479, 2570, 2852,
+ 5367, 4601, 120818, 64075, 1234, 6540, 13115, 66310, 12667, 194686, 5002,
+ 10147, 12935, 917601, 194965, 118829, 194672, 8163, 6551, 12727, 120744,
+ 120533, 41289, 0, 13129, 2864, 8977, 602, 10435, 9395, 41675, 119554,
+ 2765, 64540, 41279, 120414, 65924, 0, 119922, 66662, 119220, 10887,
+ 65206, 118963, 64920, 66593, 63914, 12150, 263, 120012, 41288, 917982,
+ 9633, 10886, 119042, 7831, 12067, 10381, 917978, 11484, 8076, 43048,
+ 8290, 8291, 43051, 65833, 11616, 2596, 10852, 10285, 13113, 120711,
+ 42019, 2393, 8766, 9087, 750, 65232, 41574, 10163, 11015, 63913, 10441,
+ 5954, 10225, 4314, 65856, 198, 917956, 730, 41441, 7819, 120199, 917555,
+ 13165, 1720, 63905, 8619, 678, 6529, 68122, 41654, 3751, 917769, 119923,
+ 4262, 1798, 709, 917841, 1354, 1876, 13152, 6557, 3892, 8137, 10449,
+ 120035, 120428, 41470, 245, 41045, 11456, 41233, 64801, 120315, 497,
+ 6136, 5953, 65677, 7796, 41235, 65434, 42045, 9804, 8449, 432, 1281,
+ 64355, 65393, 64339, 10677, 604, 7511, 9120, 1859, 65541, 10460, 3425,
+ 917870, 65782, 2836, 8797, 8490, 9052, 64888, 120206, 2356, 95, 64786,
+ 1738, 120415, 194654, 2832, 64640, 9670, 6096, 917871, 64918, 65151,
+ 10063, 2822, 12199, 4436, 194852, 2566, 11971, 12090, 13064, 1065, 1331,
+ 119097, 0, 2576, 12708, 41142, 5090, 5089, 120263, 9505, 67595, 514,
+ 41692, 319, 2921, 11659, 9477, 5772, 12968, 5087, 118822, 41310, 96,
+ 2580, 0, 10522, 41223, 5085, 1463, 41342, 11346, 5293, 10550, 64389,
+ 3733, 3772, 13090, 12054, 4748, 12482, 64300, 12575, 13091, 63982,
+ 194794, 6677, 7601, 119078, 41413, 64419, 118953, 195086, 195100, 66648,
+ 118945, 64597, 10939, 6106, 65757, 1270, 1132, 120746, 4534, 41270,
+ 66655, 9224, 65574, 66331, 64761, 917881, 3671, 8510, 120695, 65770,
+ 41275, 120823, 917935, 10807, 7963, 42012, 119877, 568, 65227, 6187,
+ 13109, 3854, 41479, 13141, 9715, 66696, 8258, 13253, 4185, 41334, 65148,
+ 8871, 42, 8509, 0, 4102, 120258, 7458, 118995, 65863, 2353, 6308, 41604,
+ 7457, 2611, 7456, 41021, 120563, 194631, 66336, 8045, 11550, 12946, 4484,
+ 8747, 118976, 11789, 41065, 5557, 11990, 9737, 13216, 3747, 9467, 5291,
+ 8878, 1691, 41226, 7451, 7435, 10146, 10905, 9086, 64566, 697, 194675,
+ 628, 7454, 12594, 65261, 10468, 4546, 7731, 65256, 12010, 0, 120598,
+ 3805, 64304, 64293, 120284, 9844, 68111, 6307, 19949, 0, 7544, 12166,
+ 64697, 10516, 120074, 10152, 12648, 10354, 0, 7602, 5785, 41309, 9764,
+ 41316, 65877, 194640, 13230, 41299, 5559, 119835, 8704, 2397, 5556, 9877,
+ 66368, 13122, 9011, 191, 9630, 41837, 42040, 5506, 119842, 120697, 64850,
+ 41072, 12598, 8845, 41577, 194790, 10002, 8889, 6533, 11620, 41570,
+ 41838, 683, 396, 41580, 12526, 917610, 12901, 12351, 65115, 343, 7552,
+ 120553, 41360, 9898, 10481, 4559, 0, 1956, 118857, 917836, 64048, 1724,
+ 1210, 119323, 9412, 3739, 6263, 1886, 194869, 3964, 6592, 38, 8533, 9234,
+ 10947, 65073, 13063, 194752, 1778, 3956, 65091, 42070, 6563, 119324,
+ 8743, 8369, 11739, 10941, 12467, 65722, 5547, 66618, 120432, 120513,
+ 8175, 8843, 284, 2429, 934, 5696, 917996, 173, 65560, 8652, 12699, 11650,
+ 1750, 120709, 4394, 65056, 1807, 6613, 12606, 64528, 5889, 63783, 917949,
+ 64714, 41848, 11516, 12162, 12120, 12478, 1721, 7767, 7891, 65864, 10563,
+ 2583, 4512, 63973, 2462, 7693, 1837, 10434, 3855, 8107, 41337, 63972,
+ 4952, 65413, 64405, 5504, 41340, 3975, 65715, 65716, 65420, 12672, 3798,
+ 2703, 194709, 64347, 9349, 9774, 41847, 1127, 455, 41095, 3962, 10100,
+ 3483, 41101, 3954, 6457, 4513, 9104, 3503, 7688, 41298, 1468, 65386,
+ 1864, 41851, 63970, 41446, 2540, 7736, 41080, 41849, 917619, 4320, 3224,
+ 12909, 9705, 41565, 8604, 118903, 1510, 11306, 6149, 3887, 11393, 1411,
+ 2824, 194708, 10106, 8770, 1403, 120811, 1347, 9631, 8671, 65737, 4283,
+ 64074, 119936, 8640, 13124, 258, 1654, 41408, 8858, 65738, 42139, 3741,
+ 42761, 4042, 4581, 2873, 11617, 11522, 120114, 8549, 10861, 194784,
+ 41673, 64829, 1733, 4392, 2568, 10786, 63983, 67629, 376, 41486, 9221,
+ 64871, 119907, 8823, 41222, 12857, 6217, 7965, 4896, 64911, 10154,
+ 119108, 41350, 8301, 118823, 7446, 1684, 64501, 10974, 458, 41199,
+ 917562, 917576, 194798, 11916, 340, 119000, 12298, 10864, 119918, 12288,
+ 120287, 4388, 1493, 10521, 7553, 4097, 194971, 13080, 11656, 65808, 6610,
+ 6030, 8059, 3210, 13131, 119073, 194827, 13301, 8794, 41278, 41629,
+ 12154, 119131, 9461, 64658, 1186, 41571, 6625, 617, 9464, 12691, 3675,
+ 5207, 63955, 5213, 118896, 833, 41348, 41568, 917775, 3253, 63954, 41088,
+ 8630, 6062, 41440, 5596, 5545, 119313, 933, 1341, 9842, 5217, 194886,
+ 8942, 40962, 194730, 68126, 9905, 2635, 64504, 65130, 12620, 7493,
+ 917577, 7835, 41434, 9002, 19918, 194770, 64558, 194974, 9716, 19954,
+ 5651, 5990, 900, 5784, 194775, 9317, 119057, 3612, 4011, 64376, 41953,
+ 5389, 7864, 917548, 65336, 2839, 5600, 3903, 65609, 10447, 3749, 1207,
+ 7569, 194980, 3501, 194685, 64705, 4403, 19962, 1124, 5597, 195009,
+ 119921, 9321, 4429, 65810, 120515, 119072, 1719, 7598, 546, 9671, 1125,
+ 4399, 9542, 472, 7716, 8452, 5488, 41946, 42025, 194903, 5491, 3602,
+ 8328, 41182, 2604, 41949, 5490, 41183, 5489, 8522, 10287, 684, 6300,
+ 194777, 2854, 119586, 4390, 454, 7823, 65750, 9875, 7593, 65338, 119310,
+ 120625, 64487, 8478, 9881, 2394, 2575, 3415, 3746, 11016, 8648, 66515,
+ 65421, 43047, 119092, 11989, 65142, 418, 65025, 66378, 10295, 8249,
+ 10391, 41752, 4565, 6640, 41449, 2598, 513, 120763, 6586, 8656, 65826,
+ 1024, 11621, 7961, 120809, 8941, 917563, 4554, 11681, 9023, 11682,
+ 120788, 10176, 10964, 119315, 11437, 9509, 0, 1036, 12850, 917787, 1723,
+ 120577, 9049, 41185, 41579, 2444, 11680, 10705, 11686, 118792, 65224,
+ 63804, 740, 63963, 120113, 118874, 120681, 5300, 10407, 9459, 194739,
+ 1875, 66466, 7856, 8121, 10438, 5524, 41698, 2860, 12157, 5238, 120797,
+ 5690, 5743, 10424, 12065, 65805, 7578, 65859, 195051, 8875, 8694, 9506,
+ 13254, 5575, 12847, 2413, 68099, 119340, 962, 12176, 1122, 317, 9040,
+ 119116, 1582, 119251, 1920, 41477, 10173, 827, 10801, 195096, 118798,
+ 120401, 5223, 496, 10439, 4313, 5226, 12602, 7860, 120627, 906, 7758,
+ 2842, 6405, 5224, 5487, 798, 5692, 12801, 7791, 1153, 5695, 12100, 64627,
+ 8054, 9174, 120131, 5691, 287, 866, 233, 4642, 66574, 11556, 7514, 66436,
+ 65140, 42089, 8830, 9008, 120417, 10524, 41175, 42079, 7587, 65709, 5296,
+ 120505, 10688, 10663, 917814, 3302, 66478, 6437, 6516, 6515, 6514, 6513,
+ 6512, 41798, 3920, 8690, 119590, 41201, 12122, 4580, 6568, 6116, 1785,
+ 41965, 120635, 3021, 42004, 5138, 120129, 194587, 41998, 41867, 4540,
+ 41179, 194804, 6200, 11462, 5134, 42021, 322, 4643, 5132, 42010, 194988,
+ 43008, 5143, 64875, 8790, 917807, 65594, 64604, 6626, 8869, 66510, 64400,
+ 42060, 19908, 9878, 194814, 41133, 10270, 10286, 10318, 10382, 65671,
+ 4110, 120507, 11286, 10929, 64277, 3234, 66703, 13058, 8617, 41982, 6025,
+ 120736, 12805, 8767, 194580, 194690, 9597, 41283, 5201, 120293, 6215,
+ 12714, 6214, 13101, 65282, 120490, 65268, 120504, 64524, 120215, 187, 0,
+ 10059, 10511, 4963, 9767, 789, 1749, 7441, 64574, 9901, 320, 41948,
+ 41833, 194831, 3049, 41139, 6471, 9449, 10081, 10528, 42121, 118894,
+ 120562, 4960, 5549, 119359, 65882, 8485, 4671, 1189, 905, 480, 10985,
+ 10240, 10610, 5414, 3064, 1745, 4286, 5421, 5427, 9554, 119077, 66357,
+ 65465, 6653, 8806, 42047, 9442, 6213, 9443, 9436, 7867, 11613, 6236,
+ 42052, 195070, 2406, 119858, 11430, 4566, 348, 5474, 3801, 3103, 10406,
+ 5246, 5236, 64395, 195059, 5200, 64305, 41739, 41733, 64518, 10931,
+ 13181, 41402, 395, 5391, 5198, 8786, 9428, 41259, 5196, 120037, 2691,
+ 42009, 5205, 41244, 5562, 917578, 118973, 41262, 66364, 64421, 119615,
+ 41251, 9126, 435, 3979, 12014, 12893, 8093, 9079, 3203, 192, 119912,
+ 3385, 41266, 64430, 5383, 10294, 10326, 65741, 5738, 9574, 2666, 119861,
+ 5361, 831, 419, 8256, 10716, 7872, 64583, 66688, 1260, 3149, 5359, 7766,
+ 6432, 7914, 5357, 916, 769, 2624, 5364, 64739, 6433, 5563, 547, 1943,
+ 6439, 5560, 4994, 487, 119553, 4497, 3754, 120082, 120615, 9039, 10619,
+ 41776, 194797, 8716, 41622, 40983, 64072, 41516, 0, 9319, 195024, 41376,
+ 11610, 3232, 12185, 119928, 119331, 65905, 119347, 41889, 64071, 8634,
+ 1161, 41895, 118804, 9701, 8622, 41385, 120403, 65612, 120588, 669, 5679,
+ 41362, 43011, 64210, 11921, 42087, 5678, 120750, 66489, 41364, 460,
+ 64636, 41352, 41361, 194824, 41366, 0, 3356, 6178, 917, 7799, 118812,
+ 64068, 7782, 9044, 4974, 677, 119916, 7577, 64189, 41507, 1216, 12504,
+ 11952, 3349, 194683, 12296, 8927, 4739, 3738, 5802, 120474, 5683, 10368,
+ 120661, 491, 1549, 119621, 194659, 0, 5682, 6206, 8670, 9891, 5680,
+ 64297, 10001, 7586, 65580, 1449, 10241, 3768, 65255, 3776, 9095, 7741,
+ 12684, 41885, 1046, 120547, 5567, 2717, 4620, 5171, 5564, 41967, 41908,
+ 41786, 5565, 12819, 12578, 64743, 65708, 5169, 5566, 3465, 64694, 3175,
+ 11904, 1537, 119155, 5176, 5942, 8468, 4871, 10361, 10425, 65697, 65698,
+ 41991, 1128, 65920, 10548, 9711, 10647, 9408, 9409, 9410, 457, 3662,
+ 9413, 1934, 9415, 9416, 8802, 9418, 8909, 9420, 9421, 5897, 9423, 5165,
+ 5126, 9889, 8043, 8950, 65694, 8955, 3374, 9400, 9401, 9402, 8939, 9404,
+ 3507, 9406, 9407, 119241, 19925, 9499, 10035, 183, 65078, 2631, 119308,
+ 10636, 41130, 64958, 3996, 120650, 64675, 1667, 41584, 65486, 41582,
+ 6580, 4332, 64825, 10741, 10726, 12912, 11281, 5899, 8101, 3610, 12085,
+ 41748, 574, 955, 120092, 5340, 5350, 41058, 5446, 63799, 10875, 64796,
+ 5442, 65692, 12437, 9782, 5451, 12896, 3616, 64857, 917959, 3874, 7708,
+ 64370, 5505, 65867, 10345, 10409, 65603, 11909, 65687, 43015, 41038,
+ 120719, 120561, 4447, 8536, 64701, 65143, 66661, 120194, 724, 42048,
+ 1455, 205, 917593, 10351, 64618, 8571, 4175, 6588, 119059, 120380, 939,
+ 41355, 4743, 119154, 5503, 8021, 64622, 119150, 9819, 41357, 8011, 6088,
+ 5507, 12044, 190, 120282, 10026, 4356, 8188, 1191, 13106, 4417, 10329,
+ 5476, 8991, 195008, 7827, 120361, 5829, 8550, 67627, 5592, 2919, 64925,
+ 2675, 5595, 917967, 7918, 4367, 194626, 65554, 5478, 1728, 5594, 120710,
+ 178, 12972, 5590, 10727, 13067, 118909, 65254, 917941, 9731, 120600,
+ 64633, 917987, 12113, 13065, 118863, 9252, 12278, 4652, 119041, 12349,
+ 65907, 194704, 120688, 12887, 10551, 10710, 194833, 195017, 64663,
+ 120570, 41804, 5199, 9497, 1120, 11429, 8333, 1444, 9486, 7554, 13142,
+ 4538, 65096, 1442, 6177, 5894, 917833, 11910, 13224, 8278, 5591, 4034,
+ 9452, 65389, 3334, 64003, 41747, 10708, 194571, 8677, 118828, 1651, 9350,
+ 8861, 120040, 8836, 1142, 12747, 4396, 10928, 66705, 8922, 8856, 66611,
+ 4002, 119188, 10442, 10676, 3344, 11012, 64963, 10813, 2592, 12853,
+ 120242, 66642, 3438, 6536, 7871, 120239, 65516, 12321, 68141, 118890,
+ 120389, 10007, 11784, 9588, 10126, 4700, 11308, 41994, 65801, 8661,
+ 41721, 66572, 12240, 119876, 4973, 5573, 12588, 9629, 40981, 119176,
+ 118981, 5006, 64328, 42002, 64754, 41766, 8825, 13016, 195062, 0, 10346,
+ 6107, 42093, 9243, 2464, 194677, 6108, 3372, 335, 6247, 64689, 438, 4510,
+ 5765, 8721, 119878, 4036, 6092, 11654, 65914, 8876, 10303, 8096, 10284,
+ 3354, 10268, 119830, 9289, 8689, 10316, 3876, 10335, 9725, 42044, 11783,
+ 917893, 119581, 8050, 120030, 195025, 11603, 194820, 120053, 6589, 843,
+ 120419, 119260, 120770, 195053, 10117, 66560, 41902, 12829, 6312, 215,
+ 1963, 13225, 13192, 1953, 9579, 7550, 1256, 3910, 13015, 6242, 41329,
+ 9662, 41257, 41900, 3366, 10700, 8805, 1742, 5542, 9333, 8202, 120459,
+ 120232, 41611, 65895, 120159, 120385, 499, 118846, 8593, 119627, 917974,
+ 41169, 1712, 5932, 8097, 41642, 11519, 119562, 11967, 1775, 65296, 41243,
+ 118957, 5662, 416, 9458, 64687, 6470, 195081, 66675, 10984, 64386, 64672,
+ 65274, 12880, 195083, 41172, 41254, 64758, 120669, 41062, 194825, 9006,
+ 65446, 565, 41760, 5794, 201, 2662, 9419, 11332, 8254, 41726, 10975,
+ 120173, 1021, 65131, 1022, 4108, 3880, 8023, 1200, 12243, 194991, 5282,
+ 7507, 41881, 11545, 5891, 64406, 3343, 1636, 67587, 1885, 65024, 3896,
+ 195056, 9674, 2947, 99, 98, 97, 120571, 64414, 4049, 8221, 64085, 3381,
+ 194978, 7892, 120705, 10777, 194687, 5867, 3913, 66376, 66722, 64315,
+ 8039, 1265, 4316, 6309, 118815, 12969, 12596, 66595, 11791, 12541, 5593,
+ 67585, 5998, 9163, 12300, 6061, 64854, 119, 118, 117, 116, 8930, 122,
+ 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, 102, 101, 100,
+ 107, 106, 105, 104, 6436, 194788, 534, 41212, 119599, 1536, 12114,
+ 120381, 64287, 64936, 64324, 6020, 12716, 10561, 10075, 475, 118888,
+ 13266, 9144, 64590, 917580, 118887, 65749, 10645, 1212, 5079, 119619,
+ 8134, 8483, 2913, 6624, 4908, 1866, 1639, 119189, 194762, 8923, 1645,
+ 12059, 64505, 917977, 194664, 41503, 4817, 5935, 1250, 194727, 8174,
+ 9600, 9856, 9859, 7916, 9861, 5343, 5258, 1882, 1892, 11304, 10882, 405,
+ 11454, 4659, 12343, 657, 12610, 4970, 4461, 1134, 1838, 1454, 41242,
+ 6477, 4468, 5987, 65803, 9762, 4456, 5206, 10720, 194625, 10480, 41718,
+ 5818, 194773, 8264, 10229, 260, 645, 119827, 7609, 40973, 4821, 4466,
+ 120500, 5824, 984, 119027, 8791, 5851, 5705, 7729, 41166, 10591, 41797,
+ 119983, 65438, 66580, 119984, 42101, 41404, 1165, 7879, 4451, 11401,
+ 194849, 11284, 119987, 66566, 41909, 43014, 2791, 9363, 9552, 3375, 8641,
+ 5900, 7539, 7889, 2722, 194854, 13173, 2381, 11602, 10994, 10529, 10773,
+ 11574, 8644, 11581, 12425, 10661, 10856, 9614, 194917, 41478, 11571,
+ 10064, 8308, 10748, 66695, 11005, 4868, 119162, 1952, 41406, 8455, 10082,
+ 11575, 8467, 12577, 12721, 5182, 12183, 6145, 41759, 64929, 4465, 42120,
+ 12135, 5732, 4464, 7728, 3922, 977, 4458, 120043, 120545, 64770, 119556,
+ 3353, 344, 917963, 41626, 1395, 41939, 65832, 5776, 8558, 786, 65153,
+ 120191, 64340, 119352, 10202, 120084, 41027, 7612, 10132, 64413, 120087,
+ 12840, 119119, 119913, 119314, 119139, 63862, 41896, 8657, 194996, 8594,
+ 10204, 195049, 120477, 120069, 65819, 1399, 41375, 120056, 917938, 8852,
+ 64492, 241, 68135, 4907, 194757, 9738, 194975, 9727, 7851, 119196, 10951,
+ 4439, 11588, 119199, 65008, 9085, 65853, 41911, 9327, 6160, 917594, 8650,
+ 64865, 8088, 64933, 41910, 118872, 65217, 3965, 120050, 194713, 0, 13300,
+ 65902, 66654, 65491, 65145, 9041, 65847, 65017, 7504, 4420, 9900, 6410,
+ 7501, 11278, 65825, 9577, 120047, 13217, 8748, 65415, 0, 9867, 9066,
+ 12924, 11993, 917829, 2626, 7762, 10902, 7510, 119577, 41526, 64285,
+ 10472, 2995, 120704, 12907, 41184, 2371, 194994, 10038, 259, 1009,
+ 118838, 2402, 2333, 6440, 194768, 12050, 65125, 0, 12417, 65380, 9103,
+ 10181, 3148, 65873, 6434, 7779, 10198, 194952, 9479, 6029, 65325, 65157,
+ 9689, 41261, 119175, 8993, 8613, 0, 41167, 3368, 606, 41492, 7697, 10228,
+ 41596, 1890, 194769, 6027, 8370, 4322, 41661, 7991, 66512, 10578, 119168,
+ 41465, 41054, 2735, 41664, 120330, 63778, 65273, 1287, 65408, 6635,
+ 66659, 6164, 194563, 41273, 917951, 65027, 41271, 9576, 65043, 3347,
+ 4160, 5154, 917541, 3794, 66564, 9175, 11925, 7709, 9088, 3743, 65099,
+ 1396, 4572, 7546, 3847, 66327, 65081, 4985, 1615, 672, 809, 12980, 63806,
+ 0, 65218, 5799, 41615, 65072, 1577, 194934, 65875, 5928, 4525, 10658,
+ 65911, 1266, 10180, 120702, 6129, 12622, 9347, 917986, 6532, 64424,
+ 41048, 7789, 773, 19933, 1539, 283, 64416, 66374, 532, 917800, 120049,
+ 41115, 3051, 5862, 3370, 120789, 43033, 5439, 3250, 8153, 0, 66649, 9510,
+ 120279, 64647, 9541, 118916, 41066, 64706, 194612, 43038, 3505, 8707,
+ 9466, 11479, 8537, 120802, 3626, 3471, 194860, 915, 194689, 6686, 119584,
+ 120238, 5011, 42754, 120723, 41906, 65569, 119128, 119552, 64365, 119886,
+ 3225, 68161, 4433, 5186, 194957, 41933, 1443, 4381, 9829, 65124, 10926,
+ 194746, 195076, 64879, 10562, 194751, 65476, 64579, 66456, 10021, 5160,
+ 1387, 65495, 6103, 118923, 41480, 12786, 195000, 217, 119898, 11714,
+ 12466, 10443, 10789, 41158, 41460, 1630, 120782, 41483, 65818, 12565,
+ 41700, 10077, 12890, 5931, 194732, 9283, 7700, 41252, 6042, 65499,
+ 119637, 41249, 512, 2990, 917786, 120240, 6413, 917985, 632, 12940,
+ 194875, 41296, 9545, 41291, 5957, 120353, 8926, 3511, 41282, 5923, 10400,
+ 10174, 12073, 760, 5386, 4274, 5786, 10633, 120531, 5056, 119860, 417,
+ 41474, 120773, 11022, 9812, 5934, 4460, 66583, 119231, 64877, 65410,
+ 64481, 194692, 194705, 10937, 194748, 120218, 10509, 65829, 917540, 2953,
+ 5819, 1801, 12835, 194942, 120484, 194743, 65910, 41985, 8867, 702,
+ 120410, 1237, 10274, 4552, 65447, 119966, 194961, 1375, 12106, 120815,
+ 10264, 1755, 9065, 9228, 10376, 1163, 2951, 7840, 64336, 13282, 10252,
+ 120033, 3384, 120703, 10167, 830, 194656, 65425, 10769, 8451, 41368,
+ 12520, 9753, 120147, 8944, 194882, 120248, 10473, 2908, 119614, 19965,
+ 43025, 10299, 65041, 12097, 64733, 12952, 4441, 10503, 917839, 41430,
+ 9330, 194859, 6614, 411, 10315, 9676, 4996, 120213, 13281, 10009, 7865,
+ 2730, 10388, 9677, 5428, 118993, 3364, 7565, 12828, 41711, 118816, 65463,
+ 9535, 216, 10332, 1401, 119895, 622, 65095, 885, 64772, 1602, 4467,
+ 41405, 852, 119635, 12108, 41328, 484, 65187, 41051, 12071, 9609, 9806,
+ 41008, 3338, 120796, 572, 10411, 2736, 10255, 10263, 10279, 2794, 8807,
+ 64491, 10330, 4315, 5222, 5381, 119058, 917995, 5193, 5125, 5456, 5509,
+ 41177, 917832, 9534, 195042, 64431, 1603, 3430, 118982, 10298, 120407,
+ 917885, 981, 41176, 4330, 994, 65841, 1824, 10908, 917879, 41681, 41683,
+ 5921, 65600, 2597, 3957, 5922, 64547, 65784, 674, 119839, 194945, 2946,
+ 5354, 5251, 4406, 5307, 3759, 10131, 8364, 5123, 1433, 5281, 5469, 5121,
+ 5924, 5920, 65758, 5130, 64606, 66481, 119624, 8418, 7576, 1221, 2733, 0,
+ 742, 5216, 2893, 10772, 65276, 5937, 3468, 2553, 9230, 5939, 3997,
+ 195091, 8363, 120677, 2993, 7772, 3916, 10289, 64613, 1141, 41706, 8159,
+ 718, 7572, 973, 9666, 120718, 3235, 2415, 5938, 119620, 8018, 12448,
+ 120556, 9592, 10337, 194918, 917622, 11729, 120727, 8719, 1202, 195080,
+ 64651, 12983, 118970, 12165, 119095, 63747, 9067, 3260, 8077, 65388,
+ 68179, 8419, 63773, 65419, 63774, 194986, 63775, 10725, 10433, 64496,
+ 194861, 1431, 41843, 66565, 10821, 4359, 12804, 12192, 8229, 1235, 3307,
+ 11472, 120617, 3146, 4544, 9009, 8551, 118820, 1740, 194749, 7575, 985,
+ 2724, 13076, 65233, 12068, 119949, 515, 10141, 119944, 9539, 8785, 4476,
+ 119146, 10959, 12655, 8907, 13226, 4589, 4521, 64205, 9141, 64645, 10665,
+ 2741, 41572, 6197, 1370, 10101, 41573, 64294, 3931, 194924, 120585, 6184,
+ 8606, 3303, 11968, 11786, 9473, 13103, 63771, 8879, 11593, 66508, 4478,
+ 917588, 41735, 65837, 717, 10754, 4477, 120376, 814, 42066, 119962,
+ 63767, 1780, 41031, 119958, 41387, 819, 10611, 9694, 11955, 65919,
+ 119953, 41111, 9462, 119071, 7788, 4847, 65542, 6578, 8338, 7523, 120666,
+ 1581, 6535, 7525, 3346, 430, 64698, 66699, 575, 268, 194940, 4945, 66463,
+ 4950, 12918, 9456, 8336, 5936, 43017, 5964, 8337, 13081, 308, 917964,
+ 7522, 64309, 41746, 4949, 118946, 443, 11658, 4944, 5467, 65885, 5926,
+ 1862, 6044, 65392, 8820, 4946, 119247, 9038, 7887, 65667, 7830, 11651,
+ 13093, 2698, 41144, 65742, 12072, 41753, 11590, 41304, 824, 120095, 8595,
+ 65225, 42141, 11415, 4673, 41354, 4678, 13283, 12697, 65059, 12381, 3488,
+ 5933, 5481, 3490, 1199, 65014, 8356, 12297, 119153, 1955, 12375, 3102,
+ 10474, 4672, 118849, 119821, 5531, 119823, 119826, 66332, 8835, 4674,
+ 119006, 5831, 194932, 64896, 12379, 8025, 119947, 64542, 1855, 11957,
+ 5472, 64425, 7852, 119867, 64951, 120467, 11445, 2745, 5470, 65171, 9124,
+ 119110, 4654, 65289, 291, 120762, 12688, 10525, 4649, 65209, 11797,
+ 12647, 4648, 4640, 64713, 10224, 64902, 6246, 64950, 7828, 4650, 41464,
+ 917624, 119086, 4653, 7822, 120331, 12923, 65674, 8669, 194655, 10729,
+ 43031, 5778, 6302, 2716, 194606, 12680, 119130, 1417, 10916, 917569,
+ 6441, 8547, 2711, 11552, 120798, 64953, 7992, 12429, 41907, 4662, 65453,
+ 120408, 9149, 9146, 599, 4641, 9179, 64819, 63782, 4656, 10130, 41469,
+ 7811, 40994, 12426, 4646, 5967, 865, 3725, 5713, 5814, 4645, 42033,
+ 120422, 41756, 13132, 64728, 9026, 10833, 64673, 1659, 919, 41935, 1671,
+ 11459, 3054, 9219, 9744, 1661, 7605, 4622, 119087, 10140, 9713, 12427,
+ 41938, 66674, 9045, 2306, 10485, 19926, 6068, 10612, 10401, 4617, 119596,
+ 120463, 41462, 4616, 10518, 10423, 10359, 66491, 5958, 917842, 9564,
+ 4618, 826, 65577, 4321, 4621, 195048, 41313, 522, 5368, 1808, 7848,
+ 194992, 5366, 12201, 5372, 10913, 12668, 917781, 4391, 64331, 2696,
+ 120155, 11003, 4638, 64490, 1790, 66304, 167, 10921, 9791, 917631, 9840,
+ 5376, 1835, 5335, 10313, 41370, 4633, 64320, 10265, 1180, 4632, 43009,
+ 5387, 5333, 64256, 12903, 41, 5331, 1792, 11928, 41548, 5338, 4637,
+ 120373, 5971, 4289, 120393, 385, 4152, 2585, 194605, 10909, 3126, 1427,
+ 65551, 10957, 5970, 3431, 64890, 10358, 7531, 4758, 917573, 1608, 2738,
+ 7443, 10455, 4753, 917854, 11344, 65729, 6240, 5231, 119013, 12147,
+ 65216, 6248, 0, 2593, 8463, 7810, 65807, 5229, 4757, 65192, 66581, 2728,
+ 4411, 64563, 65235, 5234, 41124, 120424, 9580, 10066, 9746, 119559, 2622,
+ 6033, 13061, 8016, 41196, 8954, 64831, 65189, 2632, 12390, 10108, 1011,
+ 5574, 1853, 2709, 65139, 5577, 42091, 41165, 393, 12450, 8965, 11458,
+ 42177, 5316, 917940, 171, 5941, 5572, 68127, 5312, 12531, 5525, 5330,
+ 5319, 10043, 65710, 42080, 8937, 63798, 12454, 7548, 42132, 12063,
+ 917991, 64343, 3230, 0, 10350, 10644, 5209, 297, 5721, 12109, 8415, 8632,
+ 10102, 11267, 120219, 2497, 5720, 960, 1692, 42146, 4610, 8696, 4292,
+ 64760, 4609, 10512, 4614, 541, 194890, 5287, 5309, 2503, 119243, 1762,
+ 4647, 56, 10743, 5844, 41381, 601, 4613, 10194, 4663, 1899, 4608, 2507,
+ 11025, 5190, 67628, 63759, 68145, 11405, 8892, 120348, 67620, 66639,
+ 2734, 5782, 420, 64368, 63795, 41649, 10797, 5960, 63797, 8992, 65293,
+ 41238, 1782, 12814, 8959, 12525, 10686, 41383, 5501, 41842, 3650, 7442,
+ 120749, 359, 4183, 119957, 6239, 12787, 41256, 329, 66582, 12573, 120452,
+ 7437, 9346, 41188, 13196, 7439, 42167, 3767, 5737, 5380, 4865, 195047,
+ 1155, 120434, 5736, 4368, 64724, 63749, 68137, 5601, 5739, 41023, 4866,
+ 9985, 7987, 41928, 1172, 64572, 917596, 6253, 120365, 6650, 5603, 41666,
+ 4473, 64148, 4870, 65901, 65347, 41799, 65345, 8199, 195007, 5347,
+ 119063, 9280, 4864, 10398, 4144, 119633, 120567, 6245, 120478, 2732,
+ 5598, 745, 4555, 5341, 119847, 4777, 7821, 5351, 120747, 119589, 41950,
+ 120729, 120210, 3097, 63817, 5966, 120363, 4778, 120596, 10863, 1660,
+ 4781, 66460, 271, 41940, 65370, 8577, 65368, 12653, 65366, 10216, 4782,
+ 10000, 65362, 65361, 11912, 12325, 11323, 8717, 41583, 65355, 4776,
+ 65353, 11492, 8700, 761, 13168, 10575, 10426, 917905, 120150, 10362,
+ 11272, 1715, 4849, 8242, 9561, 194982, 195090, 10607, 120511, 120675,
+ 5963, 66563, 41509, 4916, 4850, 380, 1607, 466, 4853, 194905, 4854,
+ 917625, 5164, 41096, 1350, 5124, 64420, 120354, 5362, 8471, 2708, 64716,
+ 7946, 3785, 234, 19963, 120481, 41268, 4848, 2530, 41636, 4798, 1225,
+ 6630, 65684, 10458, 120595, 8576, 5197, 195087, 2704, 4794, 8329, 63823,
+ 8322, 4797, 66326, 5725, 2694, 2595, 3363, 2439, 65104, 5607, 41089, 303,
+ 41162, 119044, 2665, 2437, 917791, 9817, 4844, 8764, 13013, 8934, 65398,
+ 917929, 4492, 120347, 9843, 2441, 10739, 65090, 1188, 119327, 1100, 2451,
+ 2714, 41081, 2912, 194817, 4937, 65746, 753, 3572, 10023, 4959, 11722,
+ 9248, 65815, 9729, 11725, 65190, 119094, 2726, 3107, 194658, 4941, 7996,
+ 10995, 9140, 1408, 5261, 41412, 9068, 181, 119819, 4942, 43043, 4938,
+ 41341, 972, 5259, 4004, 64185, 4142, 5257, 194712, 120529, 4964, 5264,
+ 9538, 64177, 64176, 41225, 64182, 63800, 64180, 11396, 9482, 4873, 3265,
+ 1822, 194867, 12601, 41078, 3865, 261, 5927, 7568, 118931, 118930,
+ 917858, 10696, 9830, 6073, 389, 10467, 6255, 6075, 4872, 282, 194633,
+ 3125, 9567, 195012, 4878, 5459, 4874, 119046, 9557, 3474, 64774, 120356,
+ 11494, 6081, 9563, 9411, 11017, 13017, 11940, 41033, 65928, 10788, 64190,
+ 8751, 10385, 120273, 7816, 9414, 4665, 12628, 4670, 119871, 41555,
+ 120485, 9642, 10912, 958, 12959, 3082, 119112, 4666, 0, 4915, 917896,
+ 2891, 5856, 12096, 5163, 4664, 10836, 1817, 66724, 12231, 41554, 10564,
+ 7450, 13077, 42099, 4400, 9697, 3606, 10275, 8925, 10371, 10307, 1063,
+ 10227, 11410, 9772, 4541, 6299, 1389, 64203, 64201, 9823, 42081, 12941,
+ 19906, 10520, 118839, 119557, 12301, 64192, 10505, 10878, 42772, 64196,
+ 12172, 41814, 1017, 64175, 523, 505, 1447, 846, 0, 41813, 917827, 8608,
+ 120537, 65482, 2543, 12163, 3108, 9745, 4529, 64166, 64165, 64164, 7919,
+ 120639, 1641, 64168, 64949, 8966, 10251, 10247, 5908, 715, 64161, 64160,
+ 7542, 1699, 10943, 10763, 120379, 11352, 550, 10169, 11515, 64385, 66579,
+ 3766, 64856, 5780, 9504, 6611, 257, 10373, 13153, 12061, 10261, 10253,
+ 6404, 2599, 9433, 6496, 1552, 5930, 66664, 11476, 11447, 3128, 4789,
+ 5067, 4911, 3760, 1718, 9438, 8827, 1146, 5065, 41435, 4352, 68136, 2435,
+ 41839, 5064, 5326, 120453, 3778, 1809, 8873, 7824, 19919, 5062, 1264,
+ 64817, 765, 11697, 3764, 8473, 64092, 8469, 3933, 12947, 4564, 7954,
+ 917908, 10375, 917872, 119902, 64768, 194983, 41012, 5225, 63910, 42130,
+ 7903, 5151, 194862, 64121, 64685, 5626, 2569, 66498, 3800, 65424, 119859,
+ 917575, 5353, 5625, 10894, 954, 8022, 1010, 41043, 65456, 41438, 41439,
+ 9904, 10711, 4593, 119564, 119003, 2590, 5629, 13309, 7551, 10325, 5632,
+ 10471, 120038, 64759, 42054, 5166, 5628, 120031, 970, 120029, 4772, 2400,
+ 5627, 64130, 120018, 12885, 3119, 63998, 10961, 3060, 203, 9986, 917574,
+ 64344, 636, 11698, 120652, 63832, 42111, 11701, 120448, 554, 64137, 8320,
+ 64275, 8863, 120442, 42042, 1477, 63803, 194864, 120792, 5694, 7689,
+ 42142, 9323, 4325, 3047, 3937, 175, 194815, 3169, 64016, 64781, 912,
+ 1243, 4536, 5431, 6652, 120058, 6244, 65839, 120480, 3935, 120665, 1129,
+ 917936, 11950, 5392, 68177, 7846, 64024, 5397, 120008, 12046, 12599,
+ 3845, 4490, 5395, 6556, 5393, 354, 7530, 11977, 41029, 8366, 119183,
+ 7756, 3901, 65484, 51, 626, 41602, 5895, 9568, 64057, 456, 120333, 8145,
+ 1168, 9251, 9082, 119964, 9854, 4311, 3866, 8818, 41512, 119952, 118865,
+ 10324, 3918, 5377, 3797, 1644, 10405, 9658, 4140, 13057, 42029, 42037,
+ 9030, 813, 119945, 41454, 4146, 195036, 5360, 2466, 236, 195032, 119942,
+ 6249, 42117, 5898, 120670, 41457, 119148, 5855, 1969, 2384, 988, 119106,
+ 12838, 64483, 917834, 10341, 10552, 65479, 5854, 120397, 10583, 118933,
+ 119989, 119940, 10416, 11981, 3872, 119361, 64014, 120725, 6093, 9748,
+ 2838, 119939, 65843, 170, 120516, 13143, 4169, 118847, 13311, 6058, 6448,
+ 10553, 1662, 65295, 917782, 64342, 5892, 120822, 10178, 42106, 66, 65,
+ 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83,
+ 86, 85, 88, 87, 90, 89, 4736, 10357, 64155, 849, 1704, 8556, 120402,
+ 9659, 64926, 1743, 120512, 9556, 9496, 4503, 11353, 9647, 7876, 68132,
+ 120575, 3928, 11948, 65283, 10706, 63975, 65427, 4842, 6438, 66509, 9109,
+ 4841, 1289, 4171, 12008, 6251, 3923, 1490, 2447, 65539, 119187, 10907,
+ 5245, 119218, 10114, 64000, 9790, 4845, 8332, 10582, 119622, 4840, 5675,
+ 254, 1747, 65429, 4825, 10626, 8918, 10281, 5716, 64004, 65799, 120576,
+ 19955, 917989, 8080, 118895, 367, 1472, 120386, 6687, 4829, 64693, 5905,
+ 12339, 8919, 9515, 4435, 118992, 11023, 119109, 4830, 9134, 41365, 64125,
+ 41978, 1412, 4594, 1391, 10536, 7720, 4824, 7775, 120425, 120392, 1888,
+ 1960, 3140, 66449, 7960, 41836, 41844, 6052, 6064, 54, 1428, 12214,
+ 68098, 6211, 7699, 358, 66592, 10557, 11442, 10758, 8223, 65759, 4261,
+ 12642, 194844, 120343, 120400, 120496, 119053, 41858, 119055, 64118,
+ 194902, 64554, 10574, 3878, 4017, 12827, 1752, 65195, 12962, 41118, 3924,
+ 10199, 118965, 64966, 119019, 120107, 65664, 41116, 720, 324, 194964,
+ 41977, 12057, 11917, 1464, 41343, 4721, 7974, 64353, 8957, 66484, 64488,
+ 120371, 9853, 64041, 195058, 12740, 12640, 4722, 917617, 917820, 0, 4725,
+ 9690, 4726, 194756, 41173, 119843, 118969, 5204, 119248, 67588, 67605,
+ 4015, 3995, 8052, 476, 3714, 10073, 3595, 10232, 10999, 1382, 64209,
+ 12636, 64215, 64214, 1656, 41831, 8130, 8672, 8832, 8720, 3908, 1452,
+ 13111, 64523, 64067, 194926, 8552, 12398, 41845, 3849, 120657, 195063,
+ 9778, 468, 612, 42150, 55, 65546, 917911, 64515, 1674, 118951, 5823,
+ 120276, 1114, 42110, 540, 120052, 119017, 12516, 41743, 3938, 120057,
+ 65417, 64316, 120060, 11340, 820, 41741, 6292, 65303, 7955, 6452, 4713,
+ 3359, 7800, 41566, 65177, 6226, 353, 719, 9656, 9474, 64742, 41986, 4532,
+ 65412, 42114, 10868, 4717, 2349, 5902, 66450, 1884, 9481, 64070, 65400,
+ 3623, 8155, 1195, 3942, 4714, 9625, 41151, 194653, 5012, 12006, 917604,
+ 12074, 12409, 42027, 4360, 12964, 6454, 1229, 63793, 66437, 41344,
+ 917880, 8539, 65100, 120508, 4809, 9623, 4788, 120299, 64885, 64745,
+ 120207, 65405, 65032, 13075, 194866, 5365, 4545, 8901, 8000, 2492, 4813,
+ 65432, 917999, 5925, 4808, 64330, 9649, 41154, 65030, 5128, 4038, 12718,
+ 4810, 64859, 12794, 64928, 1648, 5435, 3522, 11303, 414, 10236, 65439,
+ 12709, 6456, 120494, 65120, 11905, 41082, 65243, 12581, 10374, 5175,
+ 63796, 68181, 10254, 63820, 9751, 10262, 64088, 41363, 3919, 607, 194698,
+ 120288, 9018, 5270, 10314, 10282, 65477, 6564, 64310, 40976, 8265, 7737,
+ 120752, 40975, 5840, 65436, 10162, 40978, 41632, 8454, 42072, 42038, 387,
+ 119098, 12737, 120294, 2550, 917910, 42069, 118971, 6442, 3525, 66617,
+ 9860, 64641, 41590, 5619, 41346, 13157, 375, 7455, 66444, 5616, 8531,
+ 11473, 42753, 119202, 9454, 5615, 194652, 2315, 120830, 1938, 5455,
+ 64752, 808, 5568, 11347, 119198, 1026, 5620, 65593, 120787, 11350, 5617,
+ 10893, 9225, 64639, 12902, 9145, 64595, 1338, 120352, 119178, 9863,
+ 12161, 2587, 64553, 120274, 6455, 6037, 12834, 3974, 7998, 10290, 10888,
+ 3083, 10322, 2316, 12348, 64027, 41036, 120369, 66442, 12552, 65606,
+ 119822, 12739, 5373, 120784, 64700, 3762, 1445, 40961, 65304, 11986,
+ 120708, 40960, 917923, 3780, 7485, 5779, 64952, 10402, 12011, 3906, 9707,
+ 10603, 8326, 0, 65498, 3763, 11468, 5618, 194688, 3779, 120078, 9324,
+ 118852, 63822, 9073, 66585, 64302, 10704, 280, 4787, 917861, 68138,
+ 13072, 1894, 41180, 120111, 9570, 64020, 8699, 2689, 7878, 65426, 65793,
+ 42135, 41824, 2551, 10456, 6453, 10200, 3998, 65229, 66562, 503, 194691,
+ 4470, 2690, 118853, 7780, 5369, 41954, 5249, 1652, 772, 8756, 8310,
+ 65428, 3487, 64873, 3585, 1688, 194956, 119159, 41822, 194874, 6468,
+ 41904, 9720, 41697, 41319, 13125, 10650, 5836, 12358, 4668, 4355, 9048,
+ 1465, 10850, 3943, 19947, 41205, 41315, 41488, 120827, 119613, 5352,
+ 12362, 12435, 8839, 41053, 3266, 7785, 12356, 8616, 12104, 917875, 65625,
+ 11450, 194755, 3638, 5420, 3897, 3216, 195011, 2358, 4018, 8633, 2850,
+ 13304, 9639, 65445, 0, 41263, 2561, 63807, 3542, 120023, 12076, 5303,
+ 8078, 12676, 64418, 6276, 1706, 194785, 41819, 41422, 12943, 11464,
+ 10792, 41484, 194607, 10847, 41050, 8872, 860, 13099, 118844, 194819,
+ 118886, 6435, 10830, 194935, 615, 10668, 7574, 917582, 10504, 9779, 3625,
+ 43016, 41409, 66651, 41425, 65087, 9178, 8789, 41427, 4022, 64531, 11804,
+ 118889, 11288, 41424, 917598, 118811, 41820, 195010, 65292, 4812, 1261,
+ 120340, 3911, 12102, 119179, 1033, 64939, 64642, 917921, 3904, 65822,
+ 10514, 3275, 65226, 917961, 13123, 10846, 11392, 41321, 66513, 12138,
+ 10989, 119048, 6233, 10598, 449, 2669, 903, 118997, 2920, 9636, 65240,
+ 10738, 118897, 9367, 593, 41085, 3917, 64172, 11732, 64307, 120457,
+ 41448, 3596, 119832, 0, 9763, 64082, 8819, 8113, 124, 12981, 41113, 232,
+ 12234, 120646, 9168, 65811, 10820, 194895, 64053, 9094, 1769, 41715,
+ 2463, 119065, 1064, 13307, 41976, 1538, 19924, 0, 120476, 7862, 7795,
+ 1474, 8516, 4828, 1258, 7561, 12744, 11585, 1878, 9498, 0, 2911, 120094,
+ 41178, 3939, 64823, 8846, 8943, 12617, 41174, 2650, 4491, 1961, 41463,
+ 11525, 11292, 1959, 775, 66488, 41732, 41016, 6074, 9618, 64827, 1511,
+ 3613, 66440, 4259, 41436, 3656, 19930, 64533, 41019, 12428, 68160, 11333,
+ 6243, 8514, 8513, 9054, 1613, 41828, 119360, 65531, 194879, 68139,
+ 194877, 67604, 5741, 10145, 8865, 6402, 119099, 5788, 7917, 64808, 65730,
+ 7733, 64359, 4998, 120375, 119904, 65494, 917968, 4268, 41247, 120524,
+ 120370, 3871, 8036, 10881, 9111, 10621, 41696, 65462, 67584, 10993,
+ 120745, 9765, 120368, 195089, 11648, 42118, 10321, 65281, 41587, 10949,
+ 194644, 42107, 917607, 917860, 5416, 10802, 41164, 66318, 65298, 65723,
+ 5685, 118845, 12633, 7928, 10848, 8094, 41595, 118821, 6474, 794, 65909,
+ 12656, 10355, 64665, 5274, 1665, 41598, 3993, 119165, 64512, 40971, 536,
+ 189, 12611, 119234, 194651, 2859, 4838, 63838, 4834, 2338, 195075,
+ 119145, 4837, 41944, 770, 41452, 811, 1687, 41042, 66620, 120730, 64427,
+ 64326, 40969, 10526, 3895, 5406, 40968, 1339, 11731, 120473, 10193, 3116,
+ 7747, 119185, 8020, 10843, 11554, 12825, 0, 8266, 41006, 12371, 2871,
+ 64614, 41245, 999, 119129, 64567, 12745, 2663, 64586, 119636, 64191,
+ 68096, 10150, 65367, 64308, 1522, 597, 4775, 10917, 12571, 10448, 12583,
+ 12560, 12558, 12556, 12584, 1741, 65097, 1227, 4783, 12566, 11013, 12554,
+ 120558, 10812, 1586, 4978, 195046, 3078, 1402, 5285, 9391, 40984, 9379,
+ 9372, 394, 3088, 6284, 917966, 41663, 3991, 9377, 120785, 9237, 424,
+ 41648, 41208, 120366, 9384, 41076, 1830, 120816, 8647, 41656, 8246,
+ 120307, 917948, 195039, 41840, 119605, 2377, 41676, 64864, 12572, 11318,
+ 12557, 12559, 5479, 2796, 1003, 2373, 9446, 9447, 9448, 48, 194920, 9480,
+ 481, 2359, 9125, 9439, 9440, 9441, 548, 9153, 9444, 9445, 9430, 9431,
+ 9432, 397, 9434, 9435, 3984, 9437, 195057, 1614, 9424, 9425, 9426, 6651,
+ 1358, 9429, 428, 9620, 9655, 917760, 10982, 9096, 1333, 65170, 407, 6425,
+ 917630, 917763, 5955, 66320, 1108, 5804, 11976, 8554, 41466, 64782, 3926,
+ 9057, 11434, 8798, 120734, 917857, 1392, 1883, 7476, 5986, 5985, 8065,
+ 41326, 10353, 7468, 0, 917866, 4407, 6502, 4019, 119595, 118919, 8448,
+ 8219, 41688, 1812, 12675, 12659, 41793, 194823, 119167, 42172, 42068,
+ 6054, 10697, 2386, 119810, 9170, 10642, 3909, 64585, 10296, 41763,
+ 119171, 10977, 42082, 4164, 1049, 195045, 65707, 11943, 41806, 8709,
+ 10606, 3921, 12275, 64691, 12936, 8994, 1038, 118966, 8470, 65695, 0,
+ 577, 119585, 8773, 10733, 36, 194793, 5153, 41805, 13097, 194782, 763,
+ 8736, 1414, 64495, 9683, 194841, 66681, 120831, 2536, 119951, 66330,
+ 119625, 8621, 8963, 12852, 3031, 120034, 41345, 66317, 182, 66315, 64402,
+ 65562, 10210, 120492, 9058, 366, 120764, 9892, 961, 63755, 6426, 4570,
+ 11478, 3106, 65917, 41284, 1696, 41189, 4003, 12105, 68109, 5766, 12802,
+ 3264, 8824, 13268, 917801, 10936, 63980, 11287, 6128, 119083, 19956,
+ 10923, 2322, 12797, 65506, 8300, 65861, 917536, 41285, 3547, 120144,
+ 8112, 119600, 41459, 41369, 6089, 13000, 43027, 12117, 4170, 1029, 10540,
+ 12315, 9063, 65101, 119979, 744, 120821, 12897, 3792, 4926, 917623, 6065,
+ 3551, 194598, 118800, 4623, 41186, 41816, 4598, 41818, 12795, 5968, 7922,
+ 12614, 10851, 8523, 6179, 119066, 6180, 1863, 4710, 194981, 5956, 11972,
+ 41290, 65552, 4705, 716, 177, 120739, 4704, 12360, 120270, 64719, 161,
+ 9020, 3362, 119931, 4706, 10646, 66594, 64788, 4709, 7518, 8754, 19909,
+ 120237, 120245, 119164, 68144, 7508, 9136, 1700, 4401, 41280, 194711,
+ 8974, 2308, 119910, 10634, 41791, 2318, 8506, 66361, 8198, 42022, 1005,
+ 937, 118996, 4734, 2870, 41277, 12319, 66619, 5404, 4729, 3667, 235,
+ 1384, 4728, 41049, 120420, 120644, 120017, 8109, 65505, 119920, 4730,
+ 447, 13186, 1513, 4733, 8664, 63978, 65219, 119221, 12911, 9665, 1383,
+ 8565, 2469, 119866, 12663, 6156, 68117, 917586, 7993, 4288, 119828, 2674,
+ 13238, 11922, 41145, 41468, 3510, 13234, 41148, 8683, 5605, 42095, 10497,
+ 12221, 1380, 12314, 41146, 118964, 11441, 13197, 3512, 120682, 9495,
+ 8103, 194596, 5959, 65184, 11780, 41563, 11586, 120028, 41925, 13205,
+ 13211, 5801, 41923, 119344, 120316, 1283, 11924, 4779, 7988, 3719, 4006,
+ 3271, 19957, 64038, 8355, 118799, 8842, 64747, 3804, 13070, 11557, 3875,
+ 5962, 1095, 64371, 3599, 65880, 5827, 120411, 7787, 120140, 41378, 7465,
+ 64493, 12207, 4773, 11684, 64034, 119565, 917865, 12785, 42043, 64943,
+ 66677, 917965, 42046, 9742, 521, 65136, 10800, 41473, 8404, 66725, 483,
+ 0, 1450, 12986, 928, 11605, 65441, 917882, 10599, 120435, 3989, 10971,
+ 120016, 5771, 9841, 6539, 12145, 118983, 10074, 194778, 9807, 3769,
+ 41190, 3973, 12821, 4575, 9573, 7982, 429, 8849, 118967, 65573, 41771,
+ 1796, 118918, 64887, 6417, 8164, 41301, 3502, 120382, 194912, 64959,
+ 4919, 10590, 5825, 7755, 68165, 0, 64548, 12661, 1621, 10214, 10418,
+ 41962, 65868, 41971, 1409, 11551, 1617, 3112, 10824, 5015, 1390, 64403,
+ 194976, 421, 1756, 5846, 66476, 8666, 120132, 7595, 120360, 7555, 3630,
+ 5408, 2817, 1214, 12883, 120124, 10218, 41769, 3168, 194916, 42134, 7957,
+ 2370, 2846, 1056, 119070, 12798, 118910, 120314, 1836, 8757, 65850,
+ 12327, 3740, 119028, 5622, 65374, 41765, 2341, 3944, 8484, 8474, 120817,
+ 6135, 3118, 8461, 41942, 12153, 5621, 12799, 8127, 8975, 9451, 7571,
+ 13073, 12169, 10618, 681, 194562, 703, 120812, 3272, 8781, 12894, 120527,
+ 11709, 119601, 4815, 42053, 6561, 8279, 8776, 64954, 3276, 917976, 6290,
+ 4267, 120104, 41325, 65021, 11706, 917825, 12171, 10047, 9710, 3262,
+ 194604, 194939, 119200, 42020, 118788, 163, 576, 9895, 1655, 5842, 12479,
+ 3122, 10417, 7793, 65581, 9328, 64352, 10039, 6003, 12569, 5623, 120026,
+ 5717, 3986, 120634, 42023, 8912, 64555, 12604, 64078, 65700, 3627, 4523,
+ 64934, 11595, 8540, 11498, 8887, 4574, 41040, 2459, 64886, 13060, 41041,
+ 8946, 10348, 10412, 5718, 120088, 10450, 8147, 13221, 66329, 9999, 3765,
+ 119885, 68153, 1606, 12178, 686, 3093, 119126, 4619, 10600, 6654, 7712,
+ 64826, 4312, 41918, 65689, 10128, 11923, 4023, 41892, 5763, 120335, 4827,
+ 2401, 12810, 8792, 120346, 4455, 7826, 433, 64824, 66660, 2499, 41812,
+ 12886, 65375, 11973, 13089, 4293, 10300, 10161, 10396, 12196, 66322,
+ 66630, 194901, 119319, 3010, 5817, 65719, 1458, 3120, 9797, 9643, 119317,
+ 4984, 10389, 66682, 9100, 9017, 120364, 120243, 1061, 4699, 9115, 3509,
+ 0, 486, 4290, 9896, 12291, 120620, 194887, 1045, 120204, 5631, 10380,
+ 9626, 2380, 0, 194863, 120678, 2376, 8486, 120618, 9824, 2335, 4362,
+ 12174, 194909, 2366, 1025, 195101, 12634, 120760, 65423, 41443, 120732,
+ 917847, 11713, 1774, 1523, 917561, 5058, 41445, 65762, 65310, 8567,
+ 41442, 3988, 0, 64882, 1847, 917947, 10403, 8564, 65385, 65076, 65117,
+ 120413, 194811, 65908, 12616, 65887, 6256, 119628, 12671, 194933, 10206,
+ 118974, 917792, 2673, 11960, 5820, 9318, 4488, 119567, 7926, 65358,
+ 10444, 42137, 9893, 2754, 9850, 41437, 4487, 12722, 41957, 1032, 65530,
+ 1711, 12984, 43039, 3114, 614, 120691, 13116, 64923, 120790, 926, 120640,
+ 65670, 64204, 194848, 194676, 10832, 120362, 1050, 7549, 41035, 11583,
+ 9314, 41801, 119088, 120616, 520, 10437, 9558, 8331, 917806, 3091, 41034,
+ 917887, 2307, 8360, 10097, 65768, 321, 41028, 12750, 917903, 65563,
+ 120241, 120262, 2861, 10360, 10095, 0, 66307, 440, 1861, 13085, 9233,
+ 120265, 64532, 43041, 119158, 12123, 13133, 3859, 10570, 41660, 8209,
+ 65778, 118841, 10910, 120423, 1521, 7875, 41658, 10487, 120606, 5760,
+ 13011, 743, 4414, 119571, 118873, 65769, 5243, 9849, 5239, 65771, 10778,
+ 1405, 5237, 917878, 65112, 10103, 5247, 4769, 42063, 5508, 120829, 5764,
+ 11792, 3513, 3008, 9378, 120395, 194960, 10125, 65364, 41103, 9394, 6485,
+ 1397, 64795, 65365, 119093, 4770, 120590, 9392, 8731, 7471, 12079,
+ 120619, 11316, 9122, 194725, 4774, 3019, 9997, 11549, 194919, 1099,
+ 10215, 65565, 1340, 9390, 66717, 41453, 464, 4281, 4768, 9385, 64470,
+ 1346, 4995, 65679, 12087, 9780, 423, 1818, 65144, 66665, 8272, 917844,
+ 66324, 12904, 3087, 64960, 10111, 19967, 64707, 0, 9584, 8214, 194998,
+ 12159, 12626, 9106, 118907, 40979, 5806, 64750, 64517, 8243, 9123, 5709,
+ 0, 265, 10922, 13255, 12605, 917628, 2752, 64626, 120256, 1434, 59, 5637,
+ 11573, 0, 64897, 68129, 19951, 10379, 66305, 119345, 41809, 10283, 41983,
+ 7547, 64684, 1156, 8009, 3305, 3782, 511, 12496, 63752, 1014, 64360,
+ 11906, 120125, 10835, 10157, 65536, 1400, 10323, 10685, 7702, 41211,
+ 10387, 4453, 2440, 3758, 1150, 10547, 5700, 19910, 65349, 65383, 2339,
+ 64019, 5697, 41156, 6617, 9116, 119227, 0, 462, 41841, 10493, 3862, 8129,
+ 917958, 120404, 12864, 6644, 9845, 64794, 8261, 5701, 9722, 9581, 1385,
+ 1426, 119992, 41125, 41872, 194620, 11404, 6493, 119896, 13288, 120108,
+ 5167, 120717, 1681, 12184, 1204, 3755, 11935, 7748, 8213, 3286, 8911,
+ 64712, 10744, 65356, 990, 5647, 5726, 64915, 10377, 118947, 11477, 5646,
+ 65044, 11018, 2851, 3945, 120096, 120119, 4373, 194948, 12997, 9587,
+ 1789, 1020, 120097, 3100, 41497, 5648, 64748, 13162, 119336, 10205, 3545,
+ 8190, 10016, 64616, 917890, 6506, 64312, 66669, 2368, 63993, 4419, 65727,
+ 66469, 3439, 1825, 1192, 119166, 8891, 3080, 118836, 2347, 5430, 1140,
+ 8990, 2848, 10159, 41859, 120212, 249, 917777, 9173, 12191, 1815, 194832,
+ 890, 8883, 3267, 728, 42144, 995, 120633, 4410, 1041, 10576, 8102, 10099,
+ 10343, 19945, 8091, 558, 120110, 12273, 13163, 19938, 12112, 12446,
+ 41389, 64482, 65214, 5375, 10142, 8548, 8215, 3129, 6134, 12913, 9005,
+ 41856, 13242, 64891, 7725, 11938, 11662, 119326, 8624, 5173, 19959, 527,
+ 120701, 41894, 10327, 6277, 10608, 10010, 9879, 917612, 3540, 41672, 835,
+ 2329, 120813, 12238, 13001, 7849, 12245, 5426, 4258, 63987, 41787, 5424,
+ 12016, 8283, 120808, 5434, 194561, 194937, 8067, 6144, 194758, 10311,
+ 118977, 1404, 3095, 11432, 120211, 3464, 494, 4819, 119608, 65098, 570,
+ 956, 3672, 13112, 1498, 120100, 65857, 119184, 431, 10029, 65159, 195066,
+ 8761, 41537, 13171, 13096, 194953, 65108, 118911, 9516, 1044, 5268, 0,
+ 4954, 194972, 4450, 11795, 11547, 64358, 11946, 356, 3477, 227, 10488,
+ 13214, 382, 11418, 12295, 120641, 11475, 917845, 3020, 11537, 6484, 2541,
+ 917998, 12364, 11337, 65568, 1057, 566, 9110, 119104, 2743, 64931, 63965,
+ 64338, 9097, 66571, 41305, 8782, 3006, 776, 2524, 1592, 8573, 917843,
+ 10924, 65164, 63941, 41593, 4397, 8952, 3856, 66505, 119892, 5872, 6495,
+ 120510, 6486, 41155, 1698, 13177, 12830, 5413, 3953, 1053, 19917, 65094,
+ 11448, 4339, 1052, 1051, 459, 1060, 917853, 66479, 65299, 65703, 5228,
+ 119955, 7868, 689, 6508, 4163, 120757, 8639, 66641, 43022, 65510, 1162,
+ 12130, 2671, 65806, 8095, 64375, 7521, 42178, 4553, 195034, 0, 12299,
+ 41433, 195004, 19921, 64298, 11424, 64169, 4567, 41891, 1926, 66646,
+ 119056, 4820, 8110, 10935, 64690, 194665, 5830, 119212, 1377, 119889,
+ 4897, 12932, 9250, 8693, 4438, 194947, 917560, 1753, 11331, 6147, 11431,
+ 64621, 8833, 120671, 0, 6504, 41428, 64596, 10719, 43012, 1898, 1413,
+ 194763, 65394, 802, 12141, 917953, 5561, 6648, 10671, 2528, 41774, 41379,
+ 9169, 838, 5669, 64484, 844, 5014, 65854, 256, 0, 5583, 41987, 120280,
+ 41399, 5580, 65464, 2923, 10853, 5582, 10048, 65699, 13069, 5795, 13158,
+ 66598, 65702, 6087, 65701, 41322, 12180, 65704, 120662, 194850, 194582,
+ 8894, 5370, 64055, 118917, 1638, 10966, 12200, 194630, 118848, 5733,
+ 67631, 64288, 194966, 8172, 42017, 5729, 10844, 8319, 6498, 9760, 0,
+ 120106, 1238, 200, 120555, 1062, 119993, 118893, 118905, 917606, 195069,
+ 1070, 9361, 917942, 6095, 3394, 120664, 3015, 120609, 41827, 4037, 7763,
+ 6400, 65186, 66626, 7817, 1841, 11276, 12976, 65724, 372, 1669, 10776,
+ 63937, 7701, 41585, 64397, 119211, 1732, 276, 41862, 2828, 33, 65326,
+ 41768, 6491, 65332, 41588, 914, 427, 8071, 3538, 3900, 65321, 41864,
+ 1031, 6257, 7614, 41869, 120826, 120573, 2328, 12399, 1071, 41400, 65537,
+ 13249, 10841, 41627, 5301, 1047, 195094, 5734, 8960, 11312, 8001, 10651,
+ 119970, 65012, 9663, 66441, 12304, 41621, 5711, 12921, 12098, 65571,
+ 9166, 12164, 5710, 64363, 65585, 65168, 12447, 10571, 917975, 119617,
+ 119246, 64611, 5558, 917888, 5715, 10915, 120118, 12007, 3670, 2761,
+ 11975, 64811, 3074, 5722, 194876, 8629, 120632, 11307, 4499, 2757, 4496,
+ 9718, 120116, 8910, 10689, 120391, 12717, 65451, 11782, 194822, 66316,
+ 194729, 41630, 41640, 65596, 917840, 11416, 4280, 13118, 8765, 12784,
+ 7792, 1393, 917542, 8701, 6585, 8487, 8233, 917788, 119874, 6683, 120009,
+ 4495, 12144, 2841, 12543, 119320, 1473, 10490, 64329, 118984, 65467,
+ 120006, 6488, 357, 1048, 41100, 917809, 41104, 65122, 8035, 1054, 917950,
+ 1040, 65450, 5454, 4434, 1069, 195095, 13019, 194906, 119261, 5084,
+ 65402, 119133, 9693, 12354, 733, 10762, 41677, 41102, 4353, 41674, 1059,
+ 9218, 1731, 917883, 120528, 120000, 120643, 41679, 8299, 11994, 118833,
+ 64390, 194922, 5155, 11599, 12743, 42122, 6480, 65740, 41779, 0, 3587,
+ 12131, 41432, 10986, 66602, 9605, 64807, 12788, 43020, 41767, 3371,
+ 917549, 13114, 8771, 1479, 41022, 194950, 1109, 11000, 120740, 64508,
+ 9770, 9246, 12230, 63801, 8868, 399, 65137, 41783, 41772, 64045, 11742,
+ 2755, 551, 917803, 10156, 4857, 9874, 4428, 2544, 65074, 194614, 120209,
+ 917811, 194786, 351, 5747, 12179, 194603, 7978, 41092, 118954, 120502,
+ 10791, 19935, 10712, 65015, 120667, 563, 64815, 120722, 9013, 5588, 57,
+ 0, 10386, 65269, 119043, 5585, 65881, 2549, 694, 66712, 9876, 5584, 8358,
+ 64717, 10238, 65279, 10919, 277, 7980, 119298, 41815, 120233, 41800,
+ 5589, 41807, 2664, 12793, 5586, 1574, 10513, 11356, 2525, 4852, 5749,
+ 917765, 41605, 64696, 119306, 1039, 9801, 10155, 5745, 188, 8135, 6450,
+ 10055, 66604, 9055, 41853, 4858, 5657, 194700, 436, 4771, 194639, 2786,
+ 5654, 4856, 8051, 120799, 119026, 194891, 5652, 10945, 194581, 120761,
+ 12280, 3661, 7863, 118834, 119933, 41302, 66608, 64699, 5402, 10234,
+ 5843, 11939, 5655, 42157, 195079, 3157, 1055, 194955, 917553, 3504,
+ 64785, 118790, 10822, 5149, 41927, 10226, 41871, 13159, 3594, 10272,
+ 10304, 40, 12657, 594, 10244, 386, 9453, 8834, 10816, 118866, 3467,
+ 41010, 119579, 3331, 946, 10231, 1495, 8131, 13179, 119045, 9562, 4304,
+ 65927, 8160, 120234, 63974, 64529, 64656, 63995, 1348, 12239, 64013,
+ 5666, 13303, 10555, 120751, 119919, 7599, 10798, 65230, 13269, 10195,
+ 119932, 7732, 41905, 9793, 0, 6097, 5668, 8780, 4982, 119883, 5670,
+ 63969, 120298, 12741, 2672, 3735, 5667, 13138, 119915, 9484, 10724,
+ 13203, 119024, 65258, 66496, 4361, 9487, 64314, 9286, 1497, 120169, 1932,
+ 12442, 6193, 3571, 11984, 917945, 7973, 119157, 64821, 11964, 12613,
+ 7873, 11399, 119219, 553, 13049, 41533, 194857, 3604, 65912, 4587, 66709,
+ 120048, 66667, 12746, 1962, 120083, 194696, 5633, 11660, 66337, 7559,
+ 120593, 64905, 12856, 5437, 65208, 10669, 6443, 7964, 63971, 9135, 199,
+ 10976, 4105, 63880, 120622, 120181, 65816, 12148, 13148, 7560, 66686,
+ 9226, 120439, 11669, 6472, 5634, 4524, 12720, 4724, 67625, 8407, 66323,
+ 12224, 119201, 194938, 5221, 64348, 328, 7886, 41701, 5448, 5636, 6680,
+ 5329, 194650, 5638, 6679, 7940, 119076, 118938, 65182, 5635, 3373, 2986,
+ 118880, 194629, 3437, 119358, 6203, 9833, 12693, 11920, 8274, 194838,
+ 11685, 1657, 41558, 119610, 7585, 5639, 2954, 5660, 5640, 65376, 194818,
+ 65102, 19960, 66475, 5297, 41637, 13284, 6112, 7968, 41625, 194737,
+ 194699, 118955, 11705, 5642, 0, 64630, 42181, 4342, 11710, 67630, 1677,
+ 64803, 4585, 5641, 8259, 10643, 1058, 2719, 119570, 194638, 194993, 1144,
+ 5868, 120436, 10867, 11302, 13277, 4308, 2539, 917848, 7505, 543, 64916,
+ 64736, 2547, 10209, 66670, 65317, 5399, 19911, 917850, 41633, 7902,
+ 64932, 9000, 12233, 11299, 66499, 1865, 119618, 5613, 194772, 12994,
+ 65057, 5610, 0, 6228, 4307, 3482, 42133, 10787, 194609, 2997, 506, 5609,
+ 41194, 12863, 194776, 12316, 41195, 2412, 8169, 8186, 8841, 9522, 516,
+ 13130, 41197, 917795, 34, 64007, 10030, 5306, 1612, 66622, 42765, 11704,
+ 65756, 12001, 10211, 119869, 64564, 66365, 65147, 6584, 7749, 120175,
+ 65693, 1758, 413, 10667, 4677, 120197, 9133, 1935, 11517, 1042, 120196,
+ 64779, 1931, 10248, 6185, 64776, 1217, 10242, 708, 825, 118913, 65680,
+ 12294, 41207, 119903, 9138, 2534, 810, 12631, 194911, 120491, 4424,
+ 119255, 4895, 1239, 2364, 11313, 119149, 3403, 119193, 194610, 64364,
+ 63952, 65250, 10027, 8998, 194627, 917771, 9152, 194896, 67592, 2980,
+ 755, 41850, 931, 3433, 13170, 12615, 1594, 42767, 11274, 67603, 12944,
+ 41623, 8730, 41353, 11587, 67611, 4337, 65188, 41394, 918, 119223, 935,
+ 7681, 65676, 377, 41393, 11649, 120621, 2477, 64301, 66454, 917826,
+ 194899, 65201, 9528, 65155, 573, 19912, 7907, 11417, 120186, 194885,
+ 65328, 10673, 119217, 119938, 67607, 11482, 1781, 5496, 3357, 62, 1649,
+ 120549, 964, 119242, 64535, 41009, 917773, 11589, 65035, 194872, 65038,
+ 917605, 64602, 67618, 65840, 11580, 12711, 66575, 4542, 65779, 8423,
+ 3348, 448, 119173, 2991, 9364, 120036, 997, 7949, 120772, 12849, 11341,
+ 11440, 3073, 9866, 9714, 11692, 4657, 12988, 4658, 6478, 12335, 119228,
+ 41975, 6241, 2818, 4877, 2385, 5463, 41897, 4172, 10052, 4409, 8373,
+ 10873, 12095, 65745, 5346, 120328, 194925, 6237, 5461, 64058, 9176,
+ 11597, 40974, 64937, 64828, 11419, 120406, 766, 1257, 917547, 10970,
+ 2408, 3251, 64154, 3274, 5465, 41501, 2461, 120523, 120321, 5342, 8317,
+ 120394, 68163, 3263, 120046, 8673, 194719, 3270, 64539, 11489, 118999,
+ 120388, 66672, 120560, 5535, 9142, 195018, 756, 8687, 10938, 120658,
+ 66443, 1182, 2542, 186, 917862, 119156, 5770, 529, 42115, 12612, 12949,
+ 10586, 10790, 10839, 8920, 5241, 6479, 41713, 120427, 41594, 225, 11578,
+ 5688, 41300, 41204, 119105, 118794, 10721, 41209, 9254, 42097, 1794,
+ 41875, 65238, 5624, 266, 120221, 67637, 41873, 3617, 11324, 41494,
+ 119824, 8420, 13088, 65755, 1872, 41338, 3734, 7734, 120174, 5502, 65890,
+ 4452, 41260, 917767, 0, 4511, 5161, 10572, 917614, 11425, 42050, 64349,
+ 41083, 917884, 917925, 63979, 9003, 8192, 120039, 5305, 9653, 10616,
+ 1697, 9546, 917930, 194847, 119174, 41482, 65205, 10031, 64063, 9870,
+ 12535, 8620, 65824, 5581, 8799, 42131, 42031, 64062, 1028, 64060, 64059,
+ 837, 10567, 119960, 41606, 3176, 64773, 11427, 2902, 64043, 64042, 41740,
+ 3609, 120550, 13200, 832, 64044, 42156, 10076, 64040, 64039, 12919, 1034,
+ 3392, 10753, 5180, 64033, 41395, 65468, 11691, 64037, 64036, 41898, 4291,
+ 63966, 64015, 41114, 243, 8479, 64354, 6024, 11351, 12128, 194908, 3476,
+ 8973, 8538, 64011, 64010, 64008, 4285, 4800, 7706, 41750, 11604, 2538,
+ 11609, 204, 7563, 4802, 4111, 8239, 9098, 4805, 64001, 214, 7885, 42143,
+ 8321, 65893, 12208, 4767, 9343, 64049, 41729, 119986, 1133, 19948, 64052,
+ 64051, 41187, 8692, 6022, 11788, 10005, 12329, 41333, 120569, 43, 1942,
+ 12682, 1016, 41107, 12619, 41121, 3885, 92, 64023, 64022, 64021, 6582,
+ 43030, 12451, 64025, 9167, 41485, 12035, 119208, 6254, 10501, 64018,
+ 8890, 12457, 66587, 194836, 7582, 64778, 118915, 118813, 66635, 120044,
+ 66621, 7995, 8759, 41411, 13094, 12449, 7532, 41414, 65109, 3179, 13279,
+ 4720, 10165, 917618, 119249, 120673, 10751, 9051, 12915, 65913, 10535,
+ 917892, 4993, 194586, 6168, 10934, 1946, 294, 41874, 5494, 4639, 65929,
+ 12040, 6196, 4498, 194907, 64028, 8146, 41789, 41788, 2960, 118786,
+ 118795, 8969, 119884, 10197, 66599, 67621, 2950, 11998, 6210, 11433, 370,
+ 3549, 64790, 7801, 4953, 11461, 64356, 194973, 3297, 9699, 120693, 1135,
+ 12700, 7447, 5063, 3517, 2964, 119257, 0, 2552, 41546, 60, 10627, 8649,
+ 8252, 729, 67624, 119934, 6682, 120007, 43046, 41770, 41547, 9032, 64820,
+ 65906, 65817, 41215, 119897, 65883, 12832, 119592, 8081, 3761, 3537,
+ 119908, 9137, 119906, 8999, 65343, 3850, 3466, 4327, 120112, 9373, 66369,
+ 908, 6282, 6681, 9813, 194997, 41655, 537, 41511, 4179, 8978, 41213,
+ 65866, 1842, 10527, 120409, 9628, 3848, 12081, 9826, 64502, 1767, 5336,
+ 120200, 64659, 663, 194846, 10780, 0, 3059, 120024, 119626, 120198,
+ 66689, 347, 42112, 40992, 4100, 920, 1811, 1355, 7739, 65198, 3592,
+ 10078, 5318, 194910, 65578, 8592, 65870, 6224, 120192, 9381, 13244,
+ 64345, 118885, 9281, 3296, 12865, 120715, 1895,
+};
+
+#define code_magic 47
+#define code_size 16384
+#define code_poly 16427
diff --git a/sys/src/cmd/python/Modules/xxmodule.c b/sys/src/cmd/python/Modules/xxmodule.c
new file mode 100644
index 000000000..ea66eefa0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/xxmodule.c
@@ -0,0 +1,376 @@
+
+/* Use this file as a template to start implementing a module that
+ also declares object types. All occurrences of 'Xxo' should be changed
+ to something reasonable for your objects. After that, all other
+ occurrences of 'xx' should be changed to something reasonable for your
+ module. If your module is named foo your sourcefile should be named
+ foomodule.c.
+
+ You will probably want to delete all references to 'x_attr' and add
+ your own types of attributes instead. Maybe you want to name your
+ local variables other than 'self'. If your object type is needed in
+ other files, you'll have to create a file "foobarobject.h"; see
+ intobject.h for an example. */
+
+/* Xxo objects */
+
+#include "Python.h"
+
+static PyObject *ErrorObject;
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *x_attr; /* Attributes dictionary */
+} XxoObject;
+
+static PyTypeObject Xxo_Type;
+
+#define XxoObject_Check(v) ((v)->ob_type == &Xxo_Type)
+
+static XxoObject *
+newXxoObject(PyObject *arg)
+{
+ XxoObject *self;
+ self = PyObject_New(XxoObject, &Xxo_Type);
+ if (self == NULL)
+ return NULL;
+ self->x_attr = NULL;
+ return self;
+}
+
+/* Xxo methods */
+
+static void
+Xxo_dealloc(XxoObject *self)
+{
+ Py_XDECREF(self->x_attr);
+ PyObject_Del(self);
+}
+
+static PyObject *
+Xxo_demo(XxoObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":demo"))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef Xxo_methods[] = {
+ {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
+ PyDoc_STR("demo() -> None")},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+Xxo_getattr(XxoObject *self, char *name)
+{
+ if (self->x_attr != NULL) {
+ PyObject *v = PyDict_GetItemString(self->x_attr, name);
+ if (v != NULL) {
+ Py_INCREF(v);
+ return v;
+ }
+ }
+ return Py_FindMethod(Xxo_methods, (PyObject *)self, name);
+}
+
+static int
+Xxo_setattr(XxoObject *self, char *name, PyObject *v)
+{
+ if (self->x_attr == NULL) {
+ self->x_attr = PyDict_New();
+ if (self->x_attr == NULL)
+ return -1;
+ }
+ if (v == NULL) {
+ int rv = PyDict_DelItemString(self->x_attr, name);
+ if (rv < 0)
+ PyErr_SetString(PyExc_AttributeError,
+ "delete non-existing Xxo attribute");
+ return rv;
+ }
+ else
+ return PyDict_SetItemString(self->x_attr, name, v);
+}
+
+static PyTypeObject Xxo_Type = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "xxmodule.Xxo", /*tp_name*/
+ sizeof(XxoObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)Xxo_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)Xxo_getattr, /*tp_getattr*/
+ (setattrfunc)Xxo_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+/* --------------------------------------------------------------------- */
+
+/* Function of two integers returning integer */
+
+PyDoc_STRVAR(xx_foo_doc,
+"foo(i,j)\n\
+\n\
+Return the sum of i and j.");
+
+static PyObject *
+xx_foo(PyObject *self, PyObject *args)
+{
+ long i, j;
+ long res;
+ if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
+ return NULL;
+ res = i+j; /* XXX Do something here */
+ return PyInt_FromLong(res);
+}
+
+
+/* Function of no arguments returning new Xxo object */
+
+static PyObject *
+xx_new(PyObject *self, PyObject *args)
+{
+ XxoObject *rv;
+
+ if (!PyArg_ParseTuple(args, ":new"))
+ return NULL;
+ rv = newXxoObject(args);
+ if (rv == NULL)
+ return NULL;
+ return (PyObject *)rv;
+}
+
+/* Example with subtle bug from extensions manual ("Thin Ice"). */
+
+static PyObject *
+xx_bug(PyObject *self, PyObject *args)
+{
+ PyObject *list, *item;
+
+ if (!PyArg_ParseTuple(args, "O:bug", &list))
+ return NULL;
+
+ item = PyList_GetItem(list, 0);
+ /* Py_INCREF(item); */
+ PyList_SetItem(list, 1, PyInt_FromLong(0L));
+ PyObject_Print(item, stdout, 0);
+ printf("\n");
+ /* Py_DECREF(item); */
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* Test bad format character */
+
+static PyObject *
+xx_roj(PyObject *self, PyObject *args)
+{
+ PyObject *a;
+ long b;
+ if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* ---------- */
+
+static PyTypeObject Str_Type = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "xxmodule.Str", /*tp_name*/
+ 0, /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ &PyString_Type, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+/* ---------- */
+
+static PyObject *
+null_richcompare(PyObject *self, PyObject *other, int op)
+{
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyTypeObject Null_Type = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "xxmodule.Null", /*tp_name*/
+ 0, /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ null_richcompare, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ &PyBaseObject_Type, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ PyType_GenericNew, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+
+/* ---------- */
+
+
+/* List of functions defined in the module */
+
+static PyMethodDef xx_methods[] = {
+ {"roj", xx_roj, METH_VARARGS,
+ PyDoc_STR("roj(a,b) -> None")},
+ {"foo", xx_foo, METH_VARARGS,
+ xx_foo_doc},
+ {"new", xx_new, METH_VARARGS,
+ PyDoc_STR("new() -> new Xx object")},
+ {"bug", xx_bug, METH_VARARGS,
+ PyDoc_STR("bug(o) -> None")},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"This is a template module just for instruction.");
+
+/* Initialization function for the module (*must* be called initxx) */
+
+PyMODINIT_FUNC
+initxx(void)
+{
+ PyObject *m;
+
+ /* Finalize the type object including setting type of the new type
+ * object; doing it here is required for portability to Windows
+ * without requiring C++. */
+ if (PyType_Ready(&Xxo_Type) < 0)
+ return;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule3("xx", xx_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ /* Add some symbolic constants to the module */
+ if (ErrorObject == NULL) {
+ ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
+ if (ErrorObject == NULL)
+ return;
+ }
+ Py_INCREF(ErrorObject);
+ PyModule_AddObject(m, "error", ErrorObject);
+
+ /* Add Str */
+ if (PyType_Ready(&Str_Type) < 0)
+ return;
+ PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
+
+ /* Add Null */
+ if (PyType_Ready(&Null_Type) < 0)
+ return;
+ PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
+}
diff --git a/sys/src/cmd/python/Modules/xxsubtype.c b/sys/src/cmd/python/Modules/xxsubtype.c
new file mode 100644
index 000000000..88ce6c5bb
--- /dev/null
+++ b/sys/src/cmd/python/Modules/xxsubtype.c
@@ -0,0 +1,299 @@
+#include "Python.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(xxsubtype__doc__,
+"xxsubtype is an example module showing how to subtype builtin types from C.\n"
+"test_descr.py in the standard test suite requires it in order to complete.\n"
+"If you don't care about the examples, and don't intend to run the Python\n"
+"test suite, you can recompile Python without Modules/xxsubtype.c.");
+
+/* We link this module statically for convenience. If compiled as a shared
+ library instead, some compilers don't allow addresses of Python objects
+ defined in other libraries to be used in static initializers here. The
+ DEFERRED_ADDRESS macro is used to tag the slots where such addresses
+ appear; the module init function must fill in the tagged slots at runtime.
+ The argument is for documentation -- the macro ignores it.
+*/
+#define DEFERRED_ADDRESS(ADDR) 0
+
+/* spamlist -- a list subtype */
+
+typedef struct {
+ PyListObject list;
+ int state;
+} spamlistobject;
+
+static PyObject *
+spamlist_getstate(spamlistobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":getstate"))
+ return NULL;
+ return PyInt_FromLong(self->state);
+}
+
+static PyObject *
+spamlist_setstate(spamlistobject *self, PyObject *args)
+{
+ int state;
+
+ if (!PyArg_ParseTuple(args, "i:setstate", &state))
+ return NULL;
+ self->state = state;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *result = PyTuple_New(3);
+
+ if (result != NULL) {
+ if (self == NULL)
+ self = Py_None;
+ if (kw == NULL)
+ kw = Py_None;
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(result, 0, self);
+ Py_INCREF(args);
+ PyTuple_SET_ITEM(result, 1, args);
+ Py_INCREF(kw);
+ PyTuple_SET_ITEM(result, 2, kw);
+ }
+ return result;
+}
+
+static PyMethodDef spamlist_methods[] = {
+ {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
+ PyDoc_STR("getstate() -> state")},
+ {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
+ PyDoc_STR("setstate(state)")},
+ /* These entries differ only in the flags; they are used by the tests
+ in test.test_descr. */
+ {"classmeth", (PyCFunction)spamlist_specialmeth,
+ METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+ PyDoc_STR("classmeth(*args, **kw)")},
+ {"staticmeth", (PyCFunction)spamlist_specialmeth,
+ METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ PyDoc_STR("staticmeth(*args, **kw)")},
+ {NULL, NULL},
+};
+
+static int
+spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
+{
+ if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
+ return -1;
+ self->state = 0;
+ return 0;
+}
+
+static PyObject *
+spamlist_state_get(spamlistobject *self)
+{
+ return PyInt_FromLong(self->state);
+}
+
+static PyGetSetDef spamlist_getsets[] = {
+ {"state", (getter)spamlist_state_get, NULL,
+ PyDoc_STR("an int variable for demonstration purposes")},
+ {0}
+};
+
+static PyTypeObject spamlist_type = {
+ PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+ 0,
+ "xxsubtype.spamlist",
+ sizeof(spamlistobject),
+ 0,
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ spamlist_methods, /* tp_methods */
+ 0, /* tp_members */
+ spamlist_getsets, /* tp_getset */
+ DEFERRED_ADDRESS(&PyList_Type), /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)spamlist_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+/* spamdict -- a dict subtype */
+
+typedef struct {
+ PyDictObject dict;
+ int state;
+} spamdictobject;
+
+static PyObject *
+spamdict_getstate(spamdictobject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":getstate"))
+ return NULL;
+ return PyInt_FromLong(self->state);
+}
+
+static PyObject *
+spamdict_setstate(spamdictobject *self, PyObject *args)
+{
+ int state;
+
+ if (!PyArg_ParseTuple(args, "i:setstate", &state))
+ return NULL;
+ self->state = state;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef spamdict_methods[] = {
+ {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
+ PyDoc_STR("getstate() -> state")},
+ {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
+ PyDoc_STR("setstate(state)")},
+ {NULL, NULL},
+};
+
+static int
+spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
+{
+ if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
+ return -1;
+ self->state = 0;
+ return 0;
+}
+
+static PyMemberDef spamdict_members[] = {
+ {"state", T_INT, offsetof(spamdictobject, state), READONLY,
+ PyDoc_STR("an int variable for demonstration purposes")},
+ {0}
+};
+
+static PyTypeObject spamdict_type = {
+ PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+ 0,
+ "xxsubtype.spamdict",
+ sizeof(spamdictobject),
+ 0,
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ spamdict_methods, /* tp_methods */
+ spamdict_members, /* tp_members */
+ 0, /* tp_getset */
+ DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)spamdict_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+static PyObject *
+spam_bench(PyObject *self, PyObject *args)
+{
+ PyObject *obj, *name, *res;
+ int n = 1000;
+ time_t t0, t1;
+
+ if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
+ return NULL;
+ t0 = clock();
+ while (--n >= 0) {
+ res = PyObject_GetAttr(obj, name);
+ if (res == NULL)
+ return NULL;
+ Py_DECREF(res);
+ }
+ t1 = clock();
+ return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
+}
+
+static PyMethodDef xxsubtype_functions[] = {
+ {"bench", spam_bench, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+PyMODINIT_FUNC
+initxxsubtype(void)
+{
+ PyObject *m;
+
+ /* Fill in deferred data addresses. This must be done before
+ PyType_Ready() is called. Note that PyType_Ready() automatically
+ initializes the ob.ob_type field to &PyType_Type if it's NULL,
+ so it's not necessary to fill in ob_type first. */
+ spamdict_type.tp_base = &PyDict_Type;
+ if (PyType_Ready(&spamdict_type) < 0)
+ return;
+
+ spamlist_type.tp_base = &PyList_Type;
+ if (PyType_Ready(&spamlist_type) < 0)
+ return;
+
+ m = Py_InitModule3("xxsubtype",
+ xxsubtype_functions,
+ xxsubtype__doc__);
+ if (m == NULL)
+ return;
+
+ if (PyType_Ready(&spamlist_type) < 0)
+ return;
+ if (PyType_Ready(&spamdict_type) < 0)
+ return;
+
+ Py_INCREF(&spamlist_type);
+ if (PyModule_AddObject(m, "spamlist",
+ (PyObject *) &spamlist_type) < 0)
+ return;
+
+ Py_INCREF(&spamdict_type);
+ if (PyModule_AddObject(m, "spamdict",
+ (PyObject *) &spamdict_type) < 0)
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/yuv.h b/sys/src/cmd/python/Modules/yuv.h
new file mode 100644
index 000000000..738c4e50c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/yuv.h
@@ -0,0 +1,99 @@
+
+#ifndef Py_YUV_H
+#define Py_YUV_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SVideo YUV 4:1:1 format.
+ *
+ * 4 consecutive quadwords describe 8 pixels on 2 lines, as depicted
+ * below. An array of (width/4) of the below structure describes 2
+ * scan lines.
+ *
+ * +-------------------+
+ * | 00 | 01 | 02 | 03 | . . .
+ * +-------------------+
+ * | 10 | 11 | 12 | 13 | . . .
+ * +-------------------+
+ */
+struct yuv411 {
+ struct {
+ unsigned int dummy:8;
+ unsigned int y0:8;
+ unsigned int u0:2;
+ unsigned int v0:2;
+ unsigned int y1:8;
+ unsigned int u1:2;
+ unsigned int v1:2;
+ } v[4];
+};
+
+#define YUV411_Y00(y) (y).v[0].y0
+#define YUV411_Y01(y) (y).v[1].y0
+#define YUV411_Y02(y) (y).v[2].y0
+#define YUV411_Y03(y) (y).v[3].y0
+#define YUV411_Y10(y) (y).v[0].y1
+#define YUV411_Y11(y) (y).v[1].y1
+#define YUV411_Y12(y) (y).v[2].y1
+#define YUV411_Y13(y) (y).v[3].y1
+#define YUV411_U00(y) ((y).v[0].u0<<6|(y).v[1].u0<<4|(y).v[2].u0<<2|(y).v[3].u0)
+#define YUV411_U01(y) YUV411_U00(y)
+#define YUV411_U02(y) YUV411_U00(y)
+#define YUV411_U03(y) YUV411_U00(y)
+#define YUV411_U10(y) ((y).v[0].u1<<6|(y).v[1].u1<<4|(y).v[2].u1<<2|(y).v[3].u1)
+#define YUV411_U11(y) YUV411_U10(y)
+#define YUV411_U12(y) YUV411_U10(y)
+#define YUV411_U13(y) YUV411_U10(y)
+#define YUV411_V00(y) ((y).v[0].v0<<6|(y).v[1].v0<<4|(y).v[2].v0<<2|(y).v[3].v0)
+#define YUV411_V01(y) YUV411_V00(y)
+#define YUV411_V02(y) YUV411_V00(y)
+#define YUV411_V03(y) YUV411_V00(y)
+#define YUV411_V10(y) ((y).v[0].v1<<6|(y).v[1].v1<<4|(y).v[2].v1<<2|(y).v[3].v1)
+#define YUV411_V11(y) YUV411_V10(y)
+#define YUV411_V12(y) YUV411_V10(y)
+#define YUV411_V13(y) YUV411_V10(y)
+
+/*
+ * Compression Library YUV 4:2:2 format.
+ *
+ * 1 longword describes 2 pixels.
+ *
+ * +-------+
+ * | 0 | 1 |
+ * +-------+
+ */
+struct yuv422 {
+ unsigned int u:8;
+ unsigned int y0:8;
+ unsigned int v:8;
+ unsigned int y1:8;
+};
+#define YUV422_Y0(y) (y).y0
+#define YUV422_Y1(y) (y).y1
+#define YUV422_U0(y) (y).u
+#define YUV422_U1(y) (y).u
+#define YUV422_V0(y) (y).v
+#define YUV422_V1(y) (y).v
+
+/*
+ * Compression library YUV 4:2:2 Duplicate Chroma format.
+ *
+ * This is like the previous format, but the U and V values are
+ * duplicated vertically (and hence there is some redundancy in the
+ * data). With other words, lines 2*n and 2*n+1 have the same U and V
+ * values but different Y values.
+ */
+
+/*
+ * Conversion functions.
+ */
+void yuv_sv411_to_cl422dc(int, void *, void *, int, int);
+void yuv_sv411_to_cl422dc_quartersize(int, void *, void *, int, int);
+void yuv_sv411_to_cl422dc_sixteenthsize(int, void *, void *, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_YUV_H */
diff --git a/sys/src/cmd/python/Modules/yuvconvert.c b/sys/src/cmd/python/Modules/yuvconvert.c
new file mode 100644
index 000000000..e5333d9c3
--- /dev/null
+++ b/sys/src/cmd/python/Modules/yuvconvert.c
@@ -0,0 +1,118 @@
+
+#include "yuv.h"
+
+void
+yuv_sv411_to_cl422dc(int invert, void *data, void *yuv, int width, int height)
+{
+ struct yuv411 *in = data;
+ struct yuv422 *out_even = yuv;
+ struct yuv422 *out_odd = out_even + width / 2;
+ int i, j; /* counters */
+
+ for (i = height / 2; i--; ) {
+ for (j = width / 4; j--; ) {
+ YUV422_Y0(*out_even) = YUV411_Y00(*in);
+ YUV422_U0(*out_even) = YUV411_U00(*in);
+ YUV422_V0(*out_even) = YUV411_V00(*in);
+ YUV422_Y1(*out_even) = YUV411_Y01(*in);
+ out_even++;
+ YUV422_Y0(*out_even) = YUV411_Y02(*in);
+ YUV422_U0(*out_even) = YUV411_U02(*in);
+ YUV422_V0(*out_even) = YUV411_V02(*in);
+ YUV422_Y1(*out_even) = YUV411_Y03(*in);
+ out_even++;
+ YUV422_Y0(*out_odd) = YUV411_Y10(*in);
+ YUV422_U0(*out_odd) = YUV411_U10(*in);
+ YUV422_V0(*out_odd) = YUV411_V10(*in);
+ YUV422_Y1(*out_odd) = YUV411_Y11(*in);
+ out_odd++;
+ YUV422_Y0(*out_odd) = YUV411_Y12(*in);
+ YUV422_U0(*out_odd) = YUV411_U12(*in);
+ YUV422_V0(*out_odd) = YUV411_V12(*in);
+ YUV422_Y1(*out_odd) = YUV411_Y13(*in);
+ out_odd++;
+ in++;
+ }
+ out_even += width / 2;
+ out_odd += width / 2;
+ }
+}
+
+void
+yuv_sv411_to_cl422dc_quartersize(int invert, void *data, void *yuv,
+ int width, int height)
+{
+ int w4 = width / 4; /* quarter of width is used often */
+ struct yuv411 *in_even = data;
+ struct yuv411 *in_odd = in_even + w4;
+ struct yuv422 *out_even = yuv;
+ struct yuv422 *out_odd = out_even + w4;
+ int i, j; /* counters */
+ int u, v; /* U and V values */
+
+ for (i = height / 4; i--; ) {
+ for (j = w4; j--; ) {
+ u = YUV411_U00(*in_even);
+ v = YUV411_V00(*in_even);
+
+ YUV422_Y0(*out_even) = YUV411_Y00(*in_even);
+ YUV422_U0(*out_even) = u;
+ YUV422_V0(*out_even) = v;
+ YUV422_Y1(*out_even) = YUV411_Y02(*in_even);
+
+ YUV422_Y0(*out_odd) = YUV411_Y10(*in_odd);
+ YUV422_U0(*out_odd) = u;
+ YUV422_V0(*out_odd) = v;
+ YUV422_Y1(*out_odd) = YUV411_Y12(*in_odd);
+
+ in_even++;
+ in_odd++;
+ out_even++;
+ out_odd++;
+ }
+ in_even += w4;
+ in_odd += w4;
+ out_even += w4;
+ out_odd += w4;
+ }
+}
+
+void
+yuv_sv411_to_cl422dc_sixteenthsize(int invert, void *data, void *yuv,
+ int width, int height)
+{
+ int w4_3 = 3 * width / 4; /* three quarters of width is used often */
+ int w8 = width / 8; /* and so is one eighth */
+ struct yuv411 *in_even = data;
+ struct yuv411 *in_odd = in_even + width / 2;
+ struct yuv422 *out_even = yuv;
+ struct yuv422 *out_odd = out_even + w8;
+ int i, j; /* counters */
+ int u, v; /* U and V values */
+
+ for (i = height / 8; i--; ) {
+ for (j = w8; j--; ) {
+ u = YUV411_U00(in_even[0]);
+ v = YUV411_V00(in_even[0]);
+
+ YUV422_Y0(*out_even) = YUV411_Y00(in_even[0]);
+ YUV422_U0(*out_even) = u;
+ YUV422_V0(*out_even) = v;
+ YUV422_Y1(*out_even) = YUV411_Y00(in_even[1]);
+
+ YUV422_Y0(*out_odd) = YUV411_Y00(in_odd[0]);
+ YUV422_U0(*out_odd) = u;
+ YUV422_V0(*out_odd) = v;
+ YUV422_Y1(*out_odd) = YUV411_Y00(in_even[1]);
+
+ in_even += 2;
+ in_odd += 2;
+ out_even++;
+ out_odd++;
+ }
+ in_even += w4_3;
+ in_odd += w4_3;
+ out_even += w8;
+ out_odd += w8;
+ }
+}
diff --git a/sys/src/cmd/python/Modules/zipimport.c b/sys/src/cmd/python/Modules/zipimport.c
new file mode 100644
index 000000000..69b28813c
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zipimport.c
@@ -0,0 +1,1191 @@
+#include "Python.h"
+#include "structmember.h"
+#include "osdefs.h"
+#include "marshal.h"
+#include <time.h>
+
+
+#define IS_SOURCE 0x0
+#define IS_BYTECODE 0x1
+#define IS_PACKAGE 0x2
+
+struct st_zip_searchorder {
+ char suffix[14];
+ int type;
+};
+
+/* zip_searchorder defines how we search for a module in the Zip
+ archive: we first search for a package __init__, then for
+ non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
+ are swapped by initzipimport() if we run in optimized mode. Also,
+ '/' is replaced by SEP there. */
+static struct st_zip_searchorder zip_searchorder[] = {
+ {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
+ {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
+ {"/__init__.py", IS_PACKAGE | IS_SOURCE},
+ {".pyc", IS_BYTECODE},
+ {".pyo", IS_BYTECODE},
+ {".py", IS_SOURCE},
+ {"", 0}
+};
+
+/* zipimporter object definition and support */
+
+typedef struct _zipimporter ZipImporter;
+
+struct _zipimporter {
+ PyObject_HEAD
+ PyObject *archive; /* pathname of the Zip archive */
+ PyObject *prefix; /* file prefix: "a/sub/directory/" */
+ PyObject *files; /* dict with file info {path: toc_entry} */
+};
+
+static PyObject *ZipImportError;
+static PyObject *zip_directory_cache = NULL;
+
+/* forward decls */
+static PyObject *read_directory(char *archive);
+static PyObject *get_data(char *archive, PyObject *toc_entry);
+static PyObject *get_module_code(ZipImporter *self, char *fullname,
+ int *p_ispackage, char **p_modpath);
+
+
+#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
+
+
+/* zipimporter.__init__
+ Split the "subdirectory" from the Zip archive path, lookup a matching
+ entry in sys.path_importer_cache, fetch the file directory from there
+ if found, or else read it from the archive. */
+static int
+zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
+{
+ char *path, *p, *prefix, buf[MAXPATHLEN+2];
+ size_t len;
+
+ if (!_PyArg_NoKeywords("zipimporter()", kwds))
+ return -1;
+
+ if (!PyArg_ParseTuple(args, "s:zipimporter",
+ &path))
+ return -1;
+
+ len = strlen(path);
+ if (len == 0) {
+ PyErr_SetString(ZipImportError, "archive path is empty");
+ return -1;
+ }
+ if (len >= MAXPATHLEN) {
+ PyErr_SetString(ZipImportError,
+ "archive path too long");
+ return -1;
+ }
+ strcpy(buf, path);
+
+#ifdef ALTSEP
+ for (p = buf; *p; p++) {
+ if (*p == ALTSEP)
+ *p = SEP;
+ }
+#endif
+
+ path = NULL;
+ prefix = NULL;
+ for (;;) {
+#ifndef RISCOS
+ struct stat statbuf;
+ int rv;
+
+ rv = stat(buf, &statbuf);
+ if (rv == 0) {
+ /* it exists */
+ if (S_ISREG(statbuf.st_mode))
+ /* it's a file */
+ path = buf;
+ break;
+ }
+#else
+ if (object_exists(buf)) {
+ /* it exists */
+ if (isfile(buf))
+ /* it's a file */
+ path = buf;
+ break;
+ }
+#endif
+ /* back up one path element */
+ p = strrchr(buf, SEP);
+ if (prefix != NULL)
+ *prefix = SEP;
+ if (p == NULL)
+ break;
+ *p = '\0';
+ prefix = p;
+ }
+ if (path != NULL) {
+ PyObject *files;
+ files = PyDict_GetItemString(zip_directory_cache, path);
+ if (files == NULL) {
+ files = read_directory(buf);
+ if (files == NULL)
+ return -1;
+ if (PyDict_SetItemString(zip_directory_cache, path,
+ files) != 0)
+ return -1;
+ }
+ else
+ Py_INCREF(files);
+ self->files = files;
+ }
+ else {
+ PyErr_SetString(ZipImportError, "not a Zip file");
+ return -1;
+ }
+
+ if (prefix == NULL)
+ prefix = "";
+ else {
+ prefix++;
+ len = strlen(prefix);
+ if (prefix[len-1] != SEP) {
+ /* add trailing SEP */
+ prefix[len] = SEP;
+ prefix[len + 1] = '\0';
+ }
+ }
+
+ self->archive = PyString_FromString(buf);
+ if (self->archive == NULL)
+ return -1;
+
+ self->prefix = PyString_FromString(prefix);
+ if (self->prefix == NULL)
+ return -1;
+
+ return 0;
+}
+
+/* GC support. */
+static int
+zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ Py_VISIT(self->files);
+ return 0;
+}
+
+static void
+zipimporter_dealloc(ZipImporter *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->archive);
+ Py_XDECREF(self->prefix);
+ Py_XDECREF(self->files);
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+zipimporter_repr(ZipImporter *self)
+{
+ char buf[500];
+ char *archive = "???";
+ char *prefix = "";
+
+ if (self->archive != NULL && PyString_Check(self->archive))
+ archive = PyString_AsString(self->archive);
+ if (self->prefix != NULL && PyString_Check(self->prefix))
+ prefix = PyString_AsString(self->prefix);
+ if (prefix != NULL && *prefix)
+ PyOS_snprintf(buf, sizeof(buf),
+ "<zipimporter object \"%.300s%c%.150s\">",
+ archive, SEP, prefix);
+ else
+ PyOS_snprintf(buf, sizeof(buf),
+ "<zipimporter object \"%.300s\">",
+ archive);
+ return PyString_FromString(buf);
+}
+
+/* return fullname.split(".")[-1] */
+static char *
+get_subname(char *fullname)
+{
+ char *subname = strrchr(fullname, '.');
+ if (subname == NULL)
+ subname = fullname;
+ else
+ subname++;
+ return subname;
+}
+
+/* Given a (sub)modulename, write the potential file path in the
+ archive (without extension) to the path buffer. Return the
+ length of the resulting string. */
+static int
+make_filename(char *prefix, char *name, char *path)
+{
+ size_t len;
+ char *p;
+
+ len = strlen(prefix);
+
+ /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
+ if (len + strlen(name) + 13 >= MAXPATHLEN) {
+ PyErr_SetString(ZipImportError, "path too long");
+ return -1;
+ }
+
+ strcpy(path, prefix);
+ strcpy(path + len, name);
+ for (p = path + len; *p; p++) {
+ if (*p == '.')
+ *p = SEP;
+ }
+ len += strlen(name);
+ assert(len < INT_MAX);
+ return (int)len;
+}
+
+enum zi_module_info {
+ MI_ERROR,
+ MI_NOT_FOUND,
+ MI_MODULE,
+ MI_PACKAGE
+};
+
+/* Return some information about a module. */
+static enum zi_module_info
+get_module_info(ZipImporter *self, char *fullname)
+{
+ char *subname, path[MAXPATHLEN + 1];
+ int len;
+ struct st_zip_searchorder *zso;
+
+ subname = get_subname(fullname);
+
+ len = make_filename(PyString_AsString(self->prefix), subname, path);
+ if (len < 0)
+ return MI_ERROR;
+
+ for (zso = zip_searchorder; *zso->suffix; zso++) {
+ strcpy(path + len, zso->suffix);
+ if (PyDict_GetItemString(self->files, path) != NULL) {
+ if (zso->type & IS_PACKAGE)
+ return MI_PACKAGE;
+ else
+ return MI_MODULE;
+ }
+ }
+ return MI_NOT_FOUND;
+}
+
+/* Check whether we can satisfy the import of the module named by
+ 'fullname'. Return self if we can, None if we can't. */
+static PyObject *
+zipimporter_find_module(PyObject *obj, PyObject *args)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ PyObject *path = NULL;
+ char *fullname;
+ enum zi_module_info mi;
+
+ if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
+ &fullname, &path))
+ return NULL;
+
+ mi = get_module_info(self, fullname);
+ if (mi == MI_ERROR)
+ return NULL;
+ if (mi == MI_NOT_FOUND) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+/* Load and return the module named by 'fullname'. */
+static PyObject *
+zipimporter_load_module(PyObject *obj, PyObject *args)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ PyObject *code, *mod, *dict;
+ char *fullname, *modpath;
+ int ispackage;
+
+ if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
+ &fullname))
+ return NULL;
+
+ code = get_module_code(self, fullname, &ispackage, &modpath);
+ if (code == NULL)
+ return NULL;
+
+ mod = PyImport_AddModule(fullname);
+ if (mod == NULL) {
+ Py_DECREF(code);
+ return NULL;
+ }
+ dict = PyModule_GetDict(mod);
+
+ /* mod.__loader__ = self */
+ if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
+ goto error;
+
+ if (ispackage) {
+ /* add __path__ to the module *before* the code gets
+ executed */
+ PyObject *pkgpath, *fullpath;
+ char *prefix = PyString_AsString(self->prefix);
+ char *subname = get_subname(fullname);
+ int err;
+
+ fullpath = PyString_FromFormat("%s%c%s%s",
+ PyString_AsString(self->archive),
+ SEP,
+ *prefix ? prefix : "",
+ subname);
+ if (fullpath == NULL)
+ goto error;
+
+ pkgpath = Py_BuildValue("[O]", fullpath);
+ Py_DECREF(fullpath);
+ if (pkgpath == NULL)
+ goto error;
+ err = PyDict_SetItemString(dict, "__path__", pkgpath);
+ Py_DECREF(pkgpath);
+ if (err != 0)
+ goto error;
+ }
+ mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
+ Py_DECREF(code);
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("import %s # loaded from Zip %s\n",
+ fullname, modpath);
+ return mod;
+error:
+ Py_DECREF(code);
+ Py_DECREF(mod);
+ return NULL;
+}
+
+/* Return a bool signifying whether the module is a package or not. */
+static PyObject *
+zipimporter_is_package(PyObject *obj, PyObject *args)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ char *fullname;
+ enum zi_module_info mi;
+
+ if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
+ &fullname))
+ return NULL;
+
+ mi = get_module_info(self, fullname);
+ if (mi == MI_ERROR)
+ return NULL;
+ if (mi == MI_NOT_FOUND) {
+ PyErr_Format(ZipImportError, "can't find module '%.200s'",
+ fullname);
+ return NULL;
+ }
+ return PyBool_FromLong(mi == MI_PACKAGE);
+}
+
+static PyObject *
+zipimporter_get_data(PyObject *obj, PyObject *args)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ char *path;
+#ifdef ALTSEP
+ char *p, buf[MAXPATHLEN + 1];
+#endif
+ PyObject *toc_entry;
+ Py_ssize_t len;
+
+ if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
+ return NULL;
+
+#ifdef ALTSEP
+ if (strlen(path) >= MAXPATHLEN) {
+ PyErr_SetString(ZipImportError, "path too long");
+ return NULL;
+ }
+ strcpy(buf, path);
+ for (p = buf; *p; p++) {
+ if (*p == ALTSEP)
+ *p = SEP;
+ }
+ path = buf;
+#endif
+ len = PyString_Size(self->archive);
+ if ((size_t)len < strlen(path) &&
+ strncmp(path, PyString_AsString(self->archive), len) == 0 &&
+ path[len] == SEP) {
+ path = path + len + 1;
+ }
+
+ toc_entry = PyDict_GetItemString(self->files, path);
+ if (toc_entry == NULL) {
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
+ return NULL;
+ }
+ return get_data(PyString_AsString(self->archive), toc_entry);
+}
+
+static PyObject *
+zipimporter_get_code(PyObject *obj, PyObject *args)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ char *fullname;
+
+ if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
+ return NULL;
+
+ return get_module_code(self, fullname, NULL, NULL);
+}
+
+static PyObject *
+zipimporter_get_source(PyObject *obj, PyObject *args)
+{
+ ZipImporter *self = (ZipImporter *)obj;
+ PyObject *toc_entry;
+ char *fullname, *subname, path[MAXPATHLEN+1];
+ int len;
+ enum zi_module_info mi;
+
+ if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
+ return NULL;
+
+ mi = get_module_info(self, fullname);
+ if (mi == MI_ERROR)
+ return NULL;
+ if (mi == MI_NOT_FOUND) {
+ PyErr_Format(ZipImportError, "can't find module '%.200s'",
+ fullname);
+ return NULL;
+ }
+ subname = get_subname(fullname);
+
+ len = make_filename(PyString_AsString(self->prefix), subname, path);
+ if (len < 0)
+ return NULL;
+
+ if (mi == MI_PACKAGE) {
+ path[len] = SEP;
+ strcpy(path + len + 1, "__init__.py");
+ }
+ else
+ strcpy(path + len, ".py");
+
+ toc_entry = PyDict_GetItemString(self->files, path);
+ if (toc_entry != NULL)
+ return get_data(PyString_AsString(self->archive), toc_entry);
+
+ /* we have the module, but no source */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(doc_find_module,
+"find_module(fullname, path=None) -> self or None.\n\
+\n\
+Search for a module specified by 'fullname'. 'fullname' must be the\n\
+fully qualified (dotted) module name. It returns the zipimporter\n\
+instance itself if the module was found, or None if it wasn't.\n\
+The optional 'path' argument is ignored -- it's there for compatibility\n\
+with the importer protocol.");
+
+PyDoc_STRVAR(doc_load_module,
+"load_module(fullname) -> module.\n\
+\n\
+Load the module specified by 'fullname'. 'fullname' must be the\n\
+fully qualified (dotted) module name. It returns the imported\n\
+module, or raises ZipImportError if it wasn't found.");
+
+PyDoc_STRVAR(doc_get_data,
+"get_data(pathname) -> string with file data.\n\
+\n\
+Return the data associated with 'pathname'. Raise IOError if\n\
+the file wasn't found.");
+
+PyDoc_STRVAR(doc_is_package,
+"is_package(fullname) -> bool.\n\
+\n\
+Return True if the module specified by fullname is a package.\n\
+Raise ZipImportError is the module couldn't be found.");
+
+PyDoc_STRVAR(doc_get_code,
+"get_code(fullname) -> code object.\n\
+\n\
+Return the code object for the specified module. Raise ZipImportError\n\
+is the module couldn't be found.");
+
+PyDoc_STRVAR(doc_get_source,
+"get_source(fullname) -> source string.\n\
+\n\
+Return the source code for the specified module. Raise ZipImportError\n\
+is the module couldn't be found, return None if the archive does\n\
+contain the module, but has no source for it.");
+
+static PyMethodDef zipimporter_methods[] = {
+ {"find_module", zipimporter_find_module, METH_VARARGS,
+ doc_find_module},
+ {"load_module", zipimporter_load_module, METH_VARARGS,
+ doc_load_module},
+ {"get_data", zipimporter_get_data, METH_VARARGS,
+ doc_get_data},
+ {"get_code", zipimporter_get_code, METH_VARARGS,
+ doc_get_code},
+ {"get_source", zipimporter_get_source, METH_VARARGS,
+ doc_get_source},
+ {"is_package", zipimporter_is_package, METH_VARARGS,
+ doc_is_package},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyMemberDef zipimporter_members[] = {
+ {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
+ {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
+ {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
+ {NULL}
+};
+
+PyDoc_STRVAR(zipimporter_doc,
+"zipimporter(archivepath) -> zipimporter object\n\
+\n\
+Create a new zipimporter instance. 'archivepath' must be a path to\n\
+a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n\
+a valid Zip archive.");
+
+#define DEFERRED_ADDRESS(ADDR) 0
+
+static PyTypeObject ZipImporter_Type = {
+ PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
+ 0,
+ "zipimport.zipimporter",
+ sizeof(ZipImporter),
+ 0, /* tp_itemsize */
+ (destructor)zipimporter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)zipimporter_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ zipimporter_doc, /* tp_doc */
+ zipimporter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ zipimporter_methods, /* tp_methods */
+ zipimporter_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)zipimporter_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* implementation */
+
+/* Given a buffer, return the long that is represented by the first
+ 4 bytes, encoded as little endian. This partially reimplements
+ marshal.c:r_long() */
+static long
+get_long(unsigned char *buf) {
+ long x;
+ x = buf[0];
+ x |= (long)buf[1] << 8;
+ x |= (long)buf[2] << 16;
+ x |= (long)buf[3] << 24;
+#if SIZEOF_LONG > 4
+ /* Sign extension for 64-bit machines */
+ x |= -(x & 0x80000000L);
+#endif
+ return x;
+}
+
+/*
+ read_directory(archive) -> files dict (new reference)
+
+ Given a path to a Zip archive, build a dict, mapping file names
+ (local to the archive, using SEP as a separator) to toc entries.
+
+ A toc_entry is a tuple:
+
+ (__file__, # value to use for __file__, available for all files
+ compress, # compression kind; 0 for uncompressed
+ data_size, # size of compressed data on disk
+ file_size, # size of decompressed data
+ file_offset, # offset of file header from start of archive
+ time, # mod time of file (in dos format)
+ date, # mod data of file (in dos format)
+ crc, # crc checksum of the data
+ )
+
+ Directories can be recognized by the trailing SEP in the name,
+ data_size and file_offset are 0.
+*/
+static PyObject *
+read_directory(char *archive)
+{
+ PyObject *files = NULL;
+ FILE *fp;
+ long compress, crc, data_size, file_size, file_offset, date, time;
+ long header_offset, name_size, header_size, header_position;
+ long i, l, count;
+ size_t length;
+ char path[MAXPATHLEN + 5];
+ char name[MAXPATHLEN + 5];
+ char *p, endof_central_dir[22];
+ long arc_offset; /* offset from beginning of file to start of zip-archive */
+
+ if (strlen(archive) > MAXPATHLEN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Zip path name is too long");
+ return NULL;
+ }
+ strcpy(path, archive);
+
+ fp = fopen(archive, "rb");
+ if (fp == NULL) {
+ PyErr_Format(ZipImportError, "can't open Zip file: "
+ "'%.200s'", archive);
+ return NULL;
+ }
+ fseek(fp, -22, SEEK_END);
+ header_position = ftell(fp);
+ if (fread(endof_central_dir, 1, 22, fp) != 22) {
+ fclose(fp);
+ PyErr_Format(ZipImportError, "can't read Zip file: "
+ "'%.200s'", archive);
+ return NULL;
+ }
+ if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
+ /* Bad: End of Central Dir signature */
+ fclose(fp);
+ PyErr_Format(ZipImportError, "not a Zip file: "
+ "'%.200s'", archive);
+ return NULL;
+ }
+
+ header_size = get_long((unsigned char *)endof_central_dir + 12);
+ header_offset = get_long((unsigned char *)endof_central_dir + 16);
+ arc_offset = header_position - header_offset - header_size;
+ header_offset += arc_offset;
+
+ files = PyDict_New();
+ if (files == NULL)
+ goto error;
+
+ length = (long)strlen(path);
+ path[length] = SEP;
+
+ /* Start of Central Directory */
+ count = 0;
+ for (;;) {
+ PyObject *t;
+ int err;
+
+ fseek(fp, header_offset, 0); /* Start of file header */
+ l = PyMarshal_ReadLongFromFile(fp);
+ if (l != 0x02014B50)
+ break; /* Bad: Central Dir File Header */
+ fseek(fp, header_offset + 10, 0);
+ compress = PyMarshal_ReadShortFromFile(fp);
+ time = PyMarshal_ReadShortFromFile(fp);
+ date = PyMarshal_ReadShortFromFile(fp);
+ crc = PyMarshal_ReadLongFromFile(fp);
+ data_size = PyMarshal_ReadLongFromFile(fp);
+ file_size = PyMarshal_ReadLongFromFile(fp);
+ name_size = PyMarshal_ReadShortFromFile(fp);
+ header_size = 46 + name_size +
+ PyMarshal_ReadShortFromFile(fp) +
+ PyMarshal_ReadShortFromFile(fp);
+ fseek(fp, header_offset + 42, 0);
+ file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
+ if (name_size > MAXPATHLEN)
+ name_size = MAXPATHLEN;
+
+ p = name;
+ for (i = 0; i < name_size; i++) {
+ *p = (char)getc(fp);
+ if (*p == '/')
+ *p = SEP;
+ p++;
+ }
+ *p = 0; /* Add terminating null byte */
+ header_offset += header_size;
+
+ strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
+
+ t = Py_BuildValue("siiiiiii", path, compress, data_size,
+ file_size, file_offset, time, date, crc);
+ if (t == NULL)
+ goto error;
+ err = PyDict_SetItemString(files, name, t);
+ Py_DECREF(t);
+ if (err != 0)
+ goto error;
+ count++;
+ }
+ fclose(fp);
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("# zipimport: found %ld names in %s\n",
+ count, archive);
+ return files;
+error:
+ fclose(fp);
+ Py_XDECREF(files);
+ return NULL;
+}
+
+/* Return the zlib.decompress function object, or NULL if zlib couldn't
+ be imported. The function is cached when found, so subsequent calls
+ don't import zlib again. Returns a *borrowed* reference.
+ XXX This makes zlib.decompress immortal. */
+static PyObject *
+get_decompress_func(void)
+{
+ static PyObject *decompress = NULL;
+
+ if (decompress == NULL) {
+ PyObject *zlib;
+ static int importing_zlib = 0;
+
+ if (importing_zlib != 0)
+ /* Someone has a zlib.py[co] in their Zip file;
+ let's avoid a stack overflow. */
+ return NULL;
+ importing_zlib = 1;
+ zlib = PyImport_ImportModule("zlib"); /* import zlib */
+ importing_zlib = 0;
+ if (zlib != NULL) {
+ decompress = PyObject_GetAttrString(zlib,
+ "decompress");
+ Py_DECREF(zlib);
+ }
+ else
+ PyErr_Clear();
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("# zipimport: zlib %s\n",
+ zlib != NULL ? "available": "UNAVAILABLE");
+ }
+ return decompress;
+}
+
+/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
+ data as a new reference. */
+static PyObject *
+get_data(char *archive, PyObject *toc_entry)
+{
+ PyObject *raw_data, *data = NULL, *decompress;
+ char *buf;
+ FILE *fp;
+ int err;
+ Py_ssize_t bytes_read = 0;
+ long l;
+ char *datapath;
+ long compress, data_size, file_size, file_offset;
+ long time, date, crc;
+
+ if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
+ &data_size, &file_size, &file_offset, &time,
+ &date, &crc)) {
+ return NULL;
+ }
+
+ fp = fopen(archive, "rb");
+ if (!fp) {
+ PyErr_Format(PyExc_IOError,
+ "zipimport: can not open file %s", archive);
+ return NULL;
+ }
+
+ /* Check to make sure the local file header is correct */
+ fseek(fp, file_offset, 0);
+ l = PyMarshal_ReadLongFromFile(fp);
+ if (l != 0x04034B50) {
+ /* Bad: Local File Header */
+ PyErr_Format(ZipImportError,
+ "bad local file header in %s",
+ archive);
+ fclose(fp);
+ return NULL;
+ }
+ fseek(fp, file_offset + 26, 0);
+ l = 30 + PyMarshal_ReadShortFromFile(fp) +
+ PyMarshal_ReadShortFromFile(fp); /* local header size */
+ file_offset += l; /* Start of file data */
+
+ raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
+ data_size : data_size + 1);
+ if (raw_data == NULL) {
+ fclose(fp);
+ return NULL;
+ }
+ buf = PyString_AsString(raw_data);
+
+ err = fseek(fp, file_offset, 0);
+ if (err == 0)
+ bytes_read = fread(buf, 1, data_size, fp);
+ fclose(fp);
+ if (err || bytes_read != data_size) {
+ PyErr_SetString(PyExc_IOError,
+ "zipimport: can't read data");
+ Py_DECREF(raw_data);
+ return NULL;
+ }
+
+ if (compress != 0) {
+ buf[data_size] = 'Z'; /* saw this in zipfile.py */
+ data_size++;
+ }
+ buf[data_size] = '\0';
+
+ if (compress == 0) /* data is not compressed */
+ return raw_data;
+
+ /* Decompress with zlib */
+ decompress = get_decompress_func();
+ if (decompress == NULL) {
+ PyErr_SetString(ZipImportError,
+ "can't decompress data; "
+ "zlib not available");
+ goto error;
+ }
+ data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
+error:
+ Py_DECREF(raw_data);
+ return data;
+}
+
+/* Lenient date/time comparison function. The precision of the mtime
+ in the archive is lower than the mtime stored in a .pyc: we
+ must allow a difference of at most one second. */
+static int
+eq_mtime(time_t t1, time_t t2)
+{
+ time_t d = t1 - t2;
+ if (d < 0)
+ d = -d;
+ /* dostime only stores even seconds, so be lenient */
+ return d <= 1;
+}
+
+/* Given the contents of a .py[co] file in a buffer, unmarshal the data
+ and return the code object. Return None if it the magic word doesn't
+ match (we do this instead of raising an exception as we fall back
+ to .py if available and we don't want to mask other errors).
+ Returns a new reference. */
+static PyObject *
+unmarshal_code(char *pathname, PyObject *data, time_t mtime)
+{
+ PyObject *code;
+ char *buf = PyString_AsString(data);
+ Py_ssize_t size = PyString_Size(data);
+
+ if (size <= 9) {
+ PyErr_SetString(ZipImportError,
+ "bad pyc data");
+ return NULL;
+ }
+
+ if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("# %s has bad magic\n",
+ pathname);
+ Py_INCREF(Py_None);
+ return Py_None; /* signal caller to try alternative */
+ }
+
+ if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
+ mtime)) {
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("# %s has bad mtime\n",
+ pathname);
+ Py_INCREF(Py_None);
+ return Py_None; /* signal caller to try alternative */
+ }
+
+ code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
+ if (code == NULL)
+ return NULL;
+ if (!PyCode_Check(code)) {
+ Py_DECREF(code);
+ PyErr_Format(PyExc_TypeError,
+ "compiled module %.200s is not a code object",
+ pathname);
+ return NULL;
+ }
+ return code;
+}
+
+/* Replace any occurances of "\r\n?" in the input string with "\n".
+ This converts DOS and Mac line endings to Unix line endings.
+ Also append a trailing "\n" to be compatible with
+ PyParser_SimpleParseFile(). Returns a new reference. */
+static PyObject *
+normalize_line_endings(PyObject *source)
+{
+ char *buf, *q, *p = PyString_AsString(source);
+ PyObject *fixed_source;
+
+ if (!p)
+ return NULL;
+
+ /* one char extra for trailing \n and one for terminating \0 */
+ buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
+ if (buf == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "zipimport: no memory to allocate "
+ "source buffer");
+ return NULL;
+ }
+ /* replace "\r\n?" by "\n" */
+ for (q = buf; *p != '\0'; p++) {
+ if (*p == '\r') {
+ *q++ = '\n';
+ if (*(p + 1) == '\n')
+ p++;
+ }
+ else
+ *q++ = *p;
+ }
+ *q++ = '\n'; /* add trailing \n */
+ *q = '\0';
+ fixed_source = PyString_FromString(buf);
+ PyMem_Free(buf);
+ return fixed_source;
+}
+
+/* Given a string buffer containing Python source code, compile it
+ return and return a code object as a new reference. */
+static PyObject *
+compile_source(char *pathname, PyObject *source)
+{
+ PyObject *code, *fixed_source;
+
+ fixed_source = normalize_line_endings(source);
+ if (fixed_source == NULL)
+ return NULL;
+
+ code = Py_CompileString(PyString_AsString(fixed_source), pathname,
+ Py_file_input);
+ Py_DECREF(fixed_source);
+ return code;
+}
+
+/* Convert the date/time values found in the Zip archive to a value
+ that's compatible with the time stamp stored in .pyc files. */
+static time_t
+parse_dostime(int dostime, int dosdate)
+{
+ struct tm stm;
+
+ stm.tm_sec = (dostime & 0x1f) * 2;
+ stm.tm_min = (dostime >> 5) & 0x3f;
+ stm.tm_hour = (dostime >> 11) & 0x1f;
+ stm.tm_mday = dosdate & 0x1f;
+ stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
+ stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
+ stm.tm_isdst = -1; /* wday/yday is ignored */
+
+ return mktime(&stm);
+}
+
+/* Given a path to a .pyc or .pyo file in the archive, return the
+ modifictaion time of the matching .py file, or 0 if no source
+ is available. */
+static time_t
+get_mtime_of_source(ZipImporter *self, char *path)
+{
+ PyObject *toc_entry;
+ time_t mtime = 0;
+ Py_ssize_t lastchar = strlen(path) - 1;
+ char savechar = path[lastchar];
+ path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
+ toc_entry = PyDict_GetItemString(self->files, path);
+ if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
+ PyTuple_Size(toc_entry) == 8) {
+ /* fetch the time stamp of the .py file for comparison
+ with an embedded pyc time stamp */
+ int time, date;
+ time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
+ date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
+ mtime = parse_dostime(time, date);
+ }
+ path[lastchar] = savechar;
+ return mtime;
+}
+
+/* Return the code object for the module named by 'fullname' from the
+ Zip archive as a new reference. */
+static PyObject *
+get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
+ time_t mtime, PyObject *toc_entry)
+{
+ PyObject *data, *code;
+ char *modpath;
+ char *archive = PyString_AsString(self->archive);
+
+ if (archive == NULL)
+ return NULL;
+
+ data = get_data(archive, toc_entry);
+ if (data == NULL)
+ return NULL;
+
+ modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
+
+ if (isbytecode) {
+ code = unmarshal_code(modpath, data, mtime);
+ }
+ else {
+ code = compile_source(modpath, data);
+ }
+ Py_DECREF(data);
+ return code;
+}
+
+/* Get the code object assoiciated with the module specified by
+ 'fullname'. */
+static PyObject *
+get_module_code(ZipImporter *self, char *fullname,
+ int *p_ispackage, char **p_modpath)
+{
+ PyObject *toc_entry;
+ char *subname, path[MAXPATHLEN + 1];
+ int len;
+ struct st_zip_searchorder *zso;
+
+ subname = get_subname(fullname);
+
+ len = make_filename(PyString_AsString(self->prefix), subname, path);
+ if (len < 0)
+ return NULL;
+
+ for (zso = zip_searchorder; *zso->suffix; zso++) {
+ PyObject *code = NULL;
+
+ strcpy(path + len, zso->suffix);
+ if (Py_VerboseFlag > 1)
+ PySys_WriteStderr("# trying %s%c%s\n",
+ PyString_AsString(self->archive),
+ SEP, path);
+ toc_entry = PyDict_GetItemString(self->files, path);
+ if (toc_entry != NULL) {
+ time_t mtime = 0;
+ int ispackage = zso->type & IS_PACKAGE;
+ int isbytecode = zso->type & IS_BYTECODE;
+
+ if (isbytecode)
+ mtime = get_mtime_of_source(self, path);
+ if (p_ispackage != NULL)
+ *p_ispackage = ispackage;
+ code = get_code_from_data(self, ispackage,
+ isbytecode, mtime,
+ toc_entry);
+ if (code == Py_None) {
+ /* bad magic number or non-matching mtime
+ in byte code, try next */
+ Py_DECREF(code);
+ continue;
+ }
+ if (code != NULL && p_modpath != NULL)
+ *p_modpath = PyString_AsString(
+ PyTuple_GetItem(toc_entry, 0));
+ return code;
+ }
+ }
+ PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
+ return NULL;
+}
+
+
+/* Module init */
+
+PyDoc_STRVAR(zipimport_doc,
+"zipimport provides support for importing Python modules from Zip archives.\n\
+\n\
+This module exports three objects:\n\
+- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
+- ZipImportError: exception raised by zipimporter objects. It's a\n\
+ subclass of ImportError, so it can be caught as ImportError, too.\n\
+- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
+ info dicts, as used in zipimporter._files.\n\
+\n\
+It is usually not needed to use the zipimport module explicitly; it is\n\
+used by the builtin import mechanism for sys.path items that are paths\n\
+to Zip archives.");
+
+PyMODINIT_FUNC
+initzipimport(void)
+{
+ PyObject *mod;
+
+ if (PyType_Ready(&ZipImporter_Type) < 0)
+ return;
+
+ /* Correct directory separator */
+ zip_searchorder[0].suffix[0] = SEP;
+ zip_searchorder[1].suffix[0] = SEP;
+ zip_searchorder[2].suffix[0] = SEP;
+ if (Py_OptimizeFlag) {
+ /* Reverse *.pyc and *.pyo */
+ struct st_zip_searchorder tmp;
+ tmp = zip_searchorder[0];
+ zip_searchorder[0] = zip_searchorder[1];
+ zip_searchorder[1] = tmp;
+ tmp = zip_searchorder[3];
+ zip_searchorder[3] = zip_searchorder[4];
+ zip_searchorder[4] = tmp;
+ }
+
+ mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
+ NULL, PYTHON_API_VERSION);
+ if (mod == NULL)
+ return;
+
+ ZipImportError = PyErr_NewException("zipimport.ZipImportError",
+ PyExc_ImportError, NULL);
+ if (ZipImportError == NULL)
+ return;
+
+ Py_INCREF(ZipImportError);
+ if (PyModule_AddObject(mod, "ZipImportError",
+ ZipImportError) < 0)
+ return;
+
+ Py_INCREF(&ZipImporter_Type);
+ if (PyModule_AddObject(mod, "zipimporter",
+ (PyObject *)&ZipImporter_Type) < 0)
+ return;
+
+ zip_directory_cache = PyDict_New();
+ if (zip_directory_cache == NULL)
+ return;
+ Py_INCREF(zip_directory_cache);
+ if (PyModule_AddObject(mod, "_zip_directory_cache",
+ zip_directory_cache) < 0)
+ return;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/ChangeLog b/sys/src/cmd/python/Modules/zlib/ChangeLog
new file mode 100644
index 000000000..7f6869d32
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/ChangeLog
@@ -0,0 +1,855 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+ compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Added zran.c example of compressed data random access to examples
+ directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+ ENOUGH and MAXD -- this repairs a possible security vulnerability for
+ invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
+ discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+ [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+ Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/sys/src/cmd/python/Modules/zlib/FAQ b/sys/src/cmd/python/Modules/zlib/FAQ
new file mode 100644
index 000000000..441d910da
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/FAQ
@@ -0,0 +1,339 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://www.zlib.org which may have more recent information.
+The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+ Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+ The zlib sources can be compiled without change to produce a DLL.
+ See the file win32/DLL_FAQ.txt in the zlib distribution.
+ Pointers to the precompiled DLL are found in the zlib web site at
+ http://www.zlib.org.
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+ See
+ * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
+ * contrib/visual-basic.txt in the zlib distribution
+ * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+ Make sure that before the call of compress, the length of the compressed
+ buffer is equal to the total size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+ Before making the call, make sure that avail_in and avail_out are not
+ zero. When setting the parameter flush equal to Z_FINISH, also make sure
+ that avail_out is big enough to allow processing all pending input.
+ Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
+ inflate() can be made with more input or output space. A Z_BUF_ERROR
+ may in fact be unavoidable depending on how the functions are used, since
+ it is not possible to tell whether or not there is more output pending
+ when strm.avail_out returns with zero.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+ It's in zlib.h for the moment, and Francis S. Lin has converted it to a
+ web page zlib.html. Volunteers to transform this to Unix-style man pages,
+ please contact us (zlib@gzip.org). Examples of zlib usage are in the files
+ example.c and minigzip.c.
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+ Because we would like to keep zlib as a very small and simple
+ package. zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage of
+ zlib. Please try to reproduce the problem with a small program and send
+ the corresponding source to us at zlib@gzip.org . Do not send
+ multi-megabyte data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+ If "make test" produces something like
+
+ example.o(.text+0x154): undefined reference to `gzputc'
+
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+ See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+
+12. Can zlib handle .Z files?
+
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+ make clean
+ ./configure -s
+ make
+
+14. How do I install a shared zlib library on Unix?
+
+ After the above, then:
+
+ make install
+
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to it.
+
+15. I have a question about OttoPDF.
+
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+ Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
+ To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip
+ formats use the same compressed data format internally, but have different
+ headers and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+ The gzip format was designed to retain the directory information about
+ a single file, such as the name and last modification date. The zlib
+ format on the other hand was designed for in-memory and communication
+ channel applications, and has a much more compact header and trailer and
+ uses a faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode
+ the gzip format using inflateInit2(). Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's Init functions allow
+ for the application to provide custom memory allocation routines.
+
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+ Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+ No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+
+ Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+ It should. It has been tested on 64-bit machines, and has no dependence
+ on any data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+ No. The PKWare DCL uses a completely different compressed data format
+ than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+ No, not without some preparation. If when compressing you periodically
+ use Z_FULL_FLUSH, carefully write all the pending data at those points,
+ and keep an index of those locations, then you can start decompression
+ at those points. You have to be careful to not use Z_FULL_FLUSH too
+ often, since it can significantly degrade compression.
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+ We don't know for sure. We have heard occasional reports of success on
+ these systems. If you do use it on one of these, please provide us with
+ a report, instructions, and patches that we can reference when we get
+ these questions. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at
+ to understand the deflate format?
+
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+
+ http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+ The word "may" appears several times above since there is a 4 GB limit
+ only if the compiler's "long" type is 32 bits. If the compiler's "long"
+ type is 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+ The only one that we are aware of is potentially in gzprintf(). If zlib
+ is compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of a 4K string space, other than the caller of
+ gzprintf() assuring that the output will not exceed 4K. On the other
+ hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
+ normally be the case, then there is no vulnerability. The ./configure
+ script will display warnings if an insecure variation of sprintf() will
+ be used by gzprintf(). Also the zlibCompileFlags() function will return
+ information on what variant of sprintf() is used by gzprintf().
+
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ find a portable implementation here:
+
+ http://www.ijs.si/software/snprintf/
+
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability.
+
+34. Is there a Java version of zlib?
+
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://www.zlib.org/
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly. So now, we simply make sure that the code always
+ works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+ performing a conditional jump that depends on an uninitialized value.
+ Isn't that a bug?
+
+ No. That is intentional for performance reasons, and the output of
+ deflate is not affected. This only started showing up recently since
+ zlib 1.2.x uses malloc() by default for allocations, whereas earlier
+ versions used calloc(), which zeros out the allocated memory.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+ zlib doesn't support encryption. The original PKZIP encryption is very weak
+ and can be broken with freely available programs. To get strong encryption,
+ use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
+ For PKZIP compatible "encryption", look at http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion
+ with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specficiation in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats.
+ In any case, the compression improvements are so modest compared to other
+ more modern approaches, that it's not worth the effort to implement.
+
+41. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+
+ No. Go away. Shoo.
diff --git a/sys/src/cmd/python/Modules/zlib/INDEX b/sys/src/cmd/python/Modules/zlib/INDEX
new file mode 100644
index 000000000..0587e5902
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/INDEX
@@ -0,0 +1,51 @@
+ChangeLog history of changes
+FAQ Frequently Asked Questions about zlib
+INDEX this file
+Makefile makefile for Unix (generated by configure)
+Makefile.in makefile for Unix (template for configure)
+README guess what
+algorithm.txt description of the (de)compression algorithm
+configure configure script for Unix
+zconf.in.h template for zconf.h (used by configure)
+
+amiga/ makefiles for Amiga SAS C
+as400/ makefiles for IBM AS/400
+msdos/ makefiles for MSDOS
+old/ makefiles for various architectures and zlib documentation
+ files that have not yet been updated for zlib 1.2.x
+projects/ projects for various Integrated Development Environments
+qnx/ makefiles for QNX
+win32/ makefiles for Windows
+
+ zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+ private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzio.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+ source files for sample programs:
+example.c
+minigzip.c
+
+ unsupported contribution by third parties
+See contrib/README.contrib
diff --git a/sys/src/cmd/python/Modules/zlib/Makefile b/sys/src/cmd/python/Modules/zlib/Makefile
new file mode 100644
index 000000000..2fd6e45c4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/Makefile
@@ -0,0 +1,154 @@
+# Makefile for zlib
+# Copyright (C) 1995-2005 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+# ./configure; make test
+# The call of configure is optional if you don't have special requirements
+# If you wish to build zlib as a shared library, use: ./configure -s
+
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+# make install
+# To install in $HOME instead of /usr/local, use:
+# make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+LDFLAGS=libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+LIBS=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.3
+SHAREDLIBM=libz.so.1
+
+AR=ar rc
+RANLIB=ranlib
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+ zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example$(EXE) minigzip$(EXE)
+
+check: test
+test: all
+ @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ echo hello world | ./minigzip | ./minigzip -d || \
+ echo ' *** minigzip test FAILED ***' ; \
+ if ./example; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; \
+ fi
+
+libz.a: $(OBJS) $(OBJA)
+ $(AR) $@ $(OBJS) $(OBJA)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c _match.s
+ mv _match.o match.o
+ rm -f _match.s
+
+$(SHAREDLIBV): $(OBJS)
+ $(LDSHARED) -o $@ $(OBJS)
+ rm -f $(SHAREDLIB) $(SHAREDLIBM)
+ ln -s $@ $(SHAREDLIB)
+ ln -s $@ $(SHAREDLIBM)
+
+example$(EXE): example.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+install: $(LIBS)
+ -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
+ -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
+ -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
+ -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
+ cp zlib.h zconf.h $(includedir)
+ chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
+ cp $(LIBS) $(libdir)
+ cd $(libdir); chmod 755 $(LIBS)
+ -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
+ cd $(libdir); if test -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIB) $(SHAREDLIBM); \
+ ln -s $(SHAREDLIBV) $(SHAREDLIB); \
+ ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
+ (ldconfig || true) >/dev/null 2>&1; \
+ fi
+ cp zlib.3 $(man3dir)
+ chmod 644 $(man3dir)/zlib.3
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+uninstall:
+ cd $(includedir); \
+ cd $(libdir); rm -f libz.a; \
+ if test -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+ fi
+ cd $(man3dir); rm -f zlib.3
+
+mostlyclean: clean
+clean:
+ rm -f *.o *~ example$(EXE) minigzip$(EXE) \
+ libz.* foo.gz so_locations \
+ _match.s maketree contrib/infback9/*.o
+
+maintainer-clean: distclean
+distclean: clean
+ cp -p Makefile.in Makefile
+ cp -p zconf.in.h zconf.h
+ rm -f .DS_Store
+
+tags:
+ etags *.[ch]
+
+depend:
+ makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/sys/src/cmd/python/Modules/zlib/Makefile.in b/sys/src/cmd/python/Modules/zlib/Makefile.in
new file mode 100644
index 000000000..2fd6e45c4
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/Makefile.in
@@ -0,0 +1,154 @@
+# Makefile for zlib
+# Copyright (C) 1995-2005 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+# ./configure; make test
+# The call of configure is optional if you don't have special requirements
+# If you wish to build zlib as a shared library, use: ./configure -s
+
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+# make install
+# To install in $HOME instead of /usr/local, use:
+# make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+LDFLAGS=libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+LIBS=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.3
+SHAREDLIBM=libz.so.1
+
+AR=ar rc
+RANLIB=ranlib
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+ zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example$(EXE) minigzip$(EXE)
+
+check: test
+test: all
+ @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ echo hello world | ./minigzip | ./minigzip -d || \
+ echo ' *** minigzip test FAILED ***' ; \
+ if ./example; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; \
+ fi
+
+libz.a: $(OBJS) $(OBJA)
+ $(AR) $@ $(OBJS) $(OBJA)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c _match.s
+ mv _match.o match.o
+ rm -f _match.s
+
+$(SHAREDLIBV): $(OBJS)
+ $(LDSHARED) -o $@ $(OBJS)
+ rm -f $(SHAREDLIB) $(SHAREDLIBM)
+ ln -s $@ $(SHAREDLIB)
+ ln -s $@ $(SHAREDLIBM)
+
+example$(EXE): example.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+install: $(LIBS)
+ -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
+ -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
+ -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
+ -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
+ cp zlib.h zconf.h $(includedir)
+ chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
+ cp $(LIBS) $(libdir)
+ cd $(libdir); chmod 755 $(LIBS)
+ -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
+ cd $(libdir); if test -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIB) $(SHAREDLIBM); \
+ ln -s $(SHAREDLIBV) $(SHAREDLIB); \
+ ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
+ (ldconfig || true) >/dev/null 2>&1; \
+ fi
+ cp zlib.3 $(man3dir)
+ chmod 644 $(man3dir)/zlib.3
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+uninstall:
+ cd $(includedir); \
+ cd $(libdir); rm -f libz.a; \
+ if test -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+ fi
+ cd $(man3dir); rm -f zlib.3
+
+mostlyclean: clean
+clean:
+ rm -f *.o *~ example$(EXE) minigzip$(EXE) \
+ libz.* foo.gz so_locations \
+ _match.s maketree contrib/infback9/*.o
+
+maintainer-clean: distclean
+distclean: clean
+ cp -p Makefile.in Makefile
+ cp -p zconf.in.h zconf.h
+ rm -f .DS_Store
+
+tags:
+ etags *.[ch]
+
+depend:
+ makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/sys/src/cmd/python/Modules/zlib/README b/sys/src/cmd/python/Modules/zlib/README
new file mode 100644
index 000000000..758cc5002
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/README
@@ -0,0 +1,125 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.3 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install". For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.3 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+ installed before testing (do "make install" before "make test"), since the
+ library location is specified in the library.
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
diff --git a/sys/src/cmd/python/Modules/zlib/adler32.c b/sys/src/cmd/python/Modules/zlib/adler32.c
new file mode 100644
index 000000000..007ba2627
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/adler32.c
@@ -0,0 +1,149 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+# define MOD(a) \
+ do { \
+ if (a >= (BASE << 16)) a -= (BASE << 16); \
+ if (a >= (BASE << 15)) a -= (BASE << 15); \
+ if (a >= (BASE << 14)) a -= (BASE << 14); \
+ if (a >= (BASE << 13)) a -= (BASE << 13); \
+ if (a >= (BASE << 12)) a -= (BASE << 12); \
+ if (a >= (BASE << 11)) a -= (BASE << 11); \
+ if (a >= (BASE << 10)) a -= (BASE << 10); \
+ if (a >= (BASE << 9)) a -= (BASE << 9); \
+ if (a >= (BASE << 8)) a -= (BASE << 8); \
+ if (a >= (BASE << 7)) a -= (BASE << 7); \
+ if (a >= (BASE << 6)) a -= (BASE << 6); \
+ if (a >= (BASE << 5)) a -= (BASE << 5); \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD4(a) \
+ do { \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD4(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ rem = (unsigned)(len2 % BASE);
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 > BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
diff --git a/sys/src/cmd/python/Modules/zlib/algorithm.txt b/sys/src/cmd/python/Modules/zlib/algorithm.txt
new file mode 100644
index 000000000..b022dde31
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/algorithm.txt
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data. The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length). Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes. (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast. The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code. It gets that many bits from the
+stream, and looks it up in the table. The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table. If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code. However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table. What inflate() does is
+simply to make the number of bits in the first table a variable, and then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits. Also the distance trees have 30 possible
+values, and the size of the first table is six bits. Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like. You are correct that it's not a Huffman tree. It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol. The
+symbol could be as short as one bit or as long as 15 bits. If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits. For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits. Again, there are duplicated
+entries as needed. The idea is that most of the time the symbol will be short
+and there will only be one table look up. (That's whole idea behind data
+compression in the first place.) For the less frequent long symbols, there
+will be two lookups. If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient. For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble. Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is? The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols. At the
+other extreme, you could make a new table for every bit in the code. In fact,
+that's essentially a Huffman tree. But then you spend two much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble. Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed. That's compared to 64 entries for a single table. Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table). Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol. That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on. For inflate, the
+meaning of a particular symbol is often more than just a letter. It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value. Or it might be the special end-of-block code. The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://www.ietf.org/rfc/rfc1951.txt
diff --git a/sys/src/cmd/python/Modules/zlib/compress.c b/sys/src/cmd/python/Modules/zlib/compress.c
new file mode 100644
index 000000000..df04f0148
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/compress.c
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/configure b/sys/src/cmd/python/Modules/zlib/configure
new file mode 100755
index 000000000..d7ffdc345
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/configure
@@ -0,0 +1,459 @@
+#!/bin/sh
+# configure script for zlib. This script is needed only if
+# you wish to build a shared library and your system supports them,
+# of if you need special compiler, flags or install directory.
+# Otherwise, you can just use directly "make test; make install"
+#
+# To create a shared library, use "configure --shared"; by default a static
+# library is created. If the primitive shared library support provided here
+# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
+#
+# To impose specific compiler or flags or install directory, use for example:
+# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+# LDSHARED is the command to be used to create a shared library
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+LIBS=libz.a
+LDFLAGS="-L. ${LIBS}"
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
+AR=${AR-"ar rc"}
+RANLIB=${RANLIB-"ranlib"}
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=0
+gcc=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+
+while test $# -ge 1
+do
+case "$1" in
+ -h* | --h*)
+ echo 'usage:'
+ echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]'
+ echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]'
+ exit 0;;
+ -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+ -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+ -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+ -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;;
+ -p* | --p*) prefix="$2"; shift; shift;;
+ -e* | --e*) exec_prefix="$2"; shift; shift;;
+ -l* | --l*) libdir="$2"; shift; shift;;
+ -i* | --i*) includedir="$2"; shift; shift;;
+ -s* | --s*) shared=1; shift;;
+ *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;;
+ esac
+done
+
+test=ztest$$
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for gcc...
+cc=${CC-gcc}
+cflags=${CFLAGS-"-O3"}
+# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
+case "$cc" in
+ *gcc*) gcc=1;;
+esac
+
+if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
+ CC="$cc"
+ SFLAGS=${CFLAGS-"-fPIC -O3"}
+ CFLAGS="$cflags"
+ case `(uname -s || echo unknown) 2>/dev/null` in
+ Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};;
+ CYGWIN* | Cygwin* | cygwin* | OS/2* )
+ EXE='.exe';;
+ QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+ # (alain.bonnefoy@icbt.com)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};;
+ HP-UX*)
+ LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ ia64)
+ shared_ext='.so'
+ SHAREDLIB='libz.so';;
+ *)
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl';;
+ esac;;
+ Darwin*) shared_ext='.dylib'
+ SHAREDLIB=libz$shared_ext
+ SHAREDLIBV=libz.$VER$shared_ext
+ SHAREDLIBM=libz.$VER1$shared_ext
+ LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};;
+ *) LDSHARED=${LDSHARED-"$cc -shared"};;
+ esac
+else
+ # find system name and corresponding cc options
+ CC=${CC-cc}
+ case `(uname -sr || echo unknown) 2>/dev/null` in
+ HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
+ CFLAGS=${CFLAGS-"-O"}
+# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+ LDSHARED=${LDSHARED-"ld -b"}
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ ia64)
+ shared_ext='.so'
+ SHAREDLIB='libz.so';;
+ *)
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl';;
+ esac;;
+ IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+ CFLAGS=${CFLAGS-"-ansi -O2"}
+ LDSHARED=${LDSHARED-"cc -shared"};;
+ OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};;
+ OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDSHARED=${LDSHARED-"cc -shared"};;
+ QNX*) SFLAGS=${CFLAGS-"-4 -O"}
+ CFLAGS=${CFLAGS-"-4 -O"}
+ LDSHARED=${LDSHARED-"cc"}
+ RANLIB=${RANLIB-"true"}
+ AR="cc -A";;
+ SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+ CFLAGS=${CFLAGS-"-O3"}
+ LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
+ SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
+ CFLAGS=${CFLAGS-"-fast -xcg89"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+ CFLAGS=${CFLAGS-"-O2"}
+ LDSHARED=${LDSHARED-"ld"};;
+ SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
+ CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
+ LDSHARED=${LDSHARED-"cc -xarch=v9b"};;
+ UNIX_System_V\ 4.2.0)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ UNIX_SV\ 4.2MP)
+ SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ OpenUNIX\ 5)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ AIX*) # Courtesy of dbakker@arrayasolutions.com
+ SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ LDSHARED=${LDSHARED-"xlc -G"};;
+ # send working options for other systems to support@gzip.org
+ *) SFLAGS=${CFLAGS-"-O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -shared"};;
+ esac
+fi
+
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+
+if test $shared -eq 1; then
+ echo Checking for shared library support...
+ # we must test in two steps (cc then ld), required at least on SunOS 4.x
+ if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
+ test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
+ CFLAGS="$SFLAGS"
+ LIBS="$SHAREDLIBV"
+ echo Building shared library $SHAREDLIBV with $CC.
+ elif test -z "$old_cc" -a -z "$old_cflags"; then
+ echo No shared library support.
+ shared=0;
+ else
+ echo 'No shared library support; try without defining CC and CFLAGS'
+ shared=0;
+ fi
+fi
+if test $shared -eq 0; then
+ LDSHARED="$CC"
+ echo Building static library $LIBS version $VER with $CC.
+else
+ LDFLAGS="-L. ${SHAREDLIBV}"
+fi
+
+cat > $test.c <<EOF
+#include <unistd.h>
+int main() { return 0; }
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h
+ echo "Checking for unistd.h... Yes."
+else
+ cp -p zconf.in.h zconf.h
+ echo "Checking for unistd.h... No."
+fi
+
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+
+int main()
+{
+#ifndef STDC
+ choke me
+#endif
+
+ return 0;
+}
+EOF
+
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()"
+
+ cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(char *fmt, ...)
+{
+ char buf[20];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return 0;
+}
+
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+ echo "Checking for vsnprintf() in stdio.h... Yes."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(char *fmt, ...)
+{
+ int n;
+ char buf[20];
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of vsnprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+ echo "Checking for return value of vsnprintf()... No."
+ echo " WARNING: apparently vsnprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ else
+ CFLAGS="$CFLAGS -DNO_vsnprintf"
+ echo "Checking for vsnprintf() in stdio.h... No."
+ echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
+ echo " can build but will be open to possible buffer-overflow security"
+ echo " vulnerabilities."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(char *fmt, ...)
+{
+ int n;
+ char buf[20];
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vsprintf(buf, fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of vsprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+ echo "Checking for return value of vsprintf()... No."
+ echo " WARNING: apparently vsprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ fi
+else
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()"
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+ char buf[20];
+
+ snprintf(buf, sizeof(buf), "%s", "foo");
+ return 0;
+}
+
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+ echo "Checking for snprintf() in stdio.h... Yes."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+ char buf[20];
+
+ return snprintf(buf, sizeof(buf), "%s", "foo");
+}
+
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of snprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_snprintf_void"
+ echo "Checking for return value of snprintf()... No."
+ echo " WARNING: apparently snprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ else
+ CFLAGS="$CFLAGS -DNO_snprintf"
+ echo "Checking for snprintf() in stdio.h... No."
+ echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
+ echo " can build but will be open to possible buffer-overflow security"
+ echo " vulnerabilities."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+ char buf[20];
+
+ return sprintf(buf, "%s", "foo");
+}
+
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of sprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_sprintf_void"
+ echo "Checking for return value of sprintf()... No."
+ echo " WARNING: apparently sprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ fi
+fi
+
+cat >$test.c <<EOF
+#include <errno.h>
+int main() { return 0; }
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for errno.h... Yes."
+else
+ echo "Checking for errno.h... No."
+ CFLAGS="$CFLAGS -DNO_ERRNO_H"
+fi
+
+cat > $test.c <<EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+caddr_t hello() {
+ return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0);
+}
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ CFLAGS="$CFLAGS -DUSE_MMAP"
+ echo Checking for mmap support... Yes.
+else
+ echo Checking for mmap support... No.
+fi
+
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+ *ASMV*)
+ if test "`nm $test.o | grep _hello`" = ""; then
+ CPP="$CPP -DNO_UNDERLINE"
+ echo Checking for underline in external names... No.
+ else
+ echo Checking for underline in external names... Yes.
+ fi;;
+esac
+
+rm -f $test.[co] $test $test$shared_ext
+
+# udpate Makefile
+sed < Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^CPP *=/s#=.*#=$CPP#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^LIBS *=/s#=.*#=$LIBS#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+" > Makefile
diff --git a/sys/src/cmd/python/Modules/zlib/crc32.c b/sys/src/cmd/python/Modules/zlib/crc32.c
new file mode 100644
index 000000000..f658a9ef5
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/crc32.c
@@ -0,0 +1,423 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+# ifdef STDC /* need ANSI C limits.h to determine sizes */
+# include <limits.h>
+# define BYFOUR
+# if (UINT_MAX == 0xffffffffUL)
+ typedef unsigned int u4;
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+ typedef unsigned long u4;
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+ typedef unsigned short u4;
+# else
+# undef BYFOUR /* can't find a four-byte integer type! */
+# endif
+# endif
+# endif
+# endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+ (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ unsigned long c;
+ int n, k;
+ unsigned long poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0UL;
+ for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ poly |= 1UL << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = REV(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = REV(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const unsigned long FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ u4 endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = (u4)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = REV((u4)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case */
+ if (len2 == 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/crc32.h b/sys/src/cmd/python/Modules/zlib/crc32.h
new file mode 100644
index 000000000..8053b6117
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/sys/src/cmd/python/Modules/zlib/deflate.c b/sys/src/cmd/python/Modules/zlib/deflate.c
new file mode 100644
index 000000000..29ce1f64a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/deflate.c
@@ -0,0 +1,1736 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->wrap = wrap;
+ s->gzhead = Z_NULL;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->wrap == 2 ||
+ (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ return Z_STREAM_ERROR;
+
+ s = strm->state;
+ if (s->wrap)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+ z_streamp strm;
+ gz_headerp head;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ strm->state->bi_valid = bits;
+ strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+ z_streamp strm;
+ int good_length;
+ int max_lazy;
+ int nice_length;
+ int max_chain;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = good_length;
+ s->max_lazy_match = max_lazy;
+ s->nice_match = nice_length;
+ s->max_chain_length = max_chain;
+ return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong destLen;
+
+ /* conservative upper bound */
+ destLen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+ /* if can't get parameters, return conservative bound */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return destLen;
+
+ /* if not default parameters, return conservative bound */
+ s = strm->state;
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return destLen;
+
+ /* default settings: return tight bound for that case */
+ return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+#ifdef GZIP
+ if (s->wrap == 2) {
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
+ }
+ else
+#endif
+ {
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ }
+ }
+#ifdef GZIP
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+
+ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size)
+ break;
+ }
+ put_byte(s, s->gzhead->extra[s->gzindex]);
+ s->gzindex++;
+ }
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (s->gzindex == s->gzhead->extra_len) {
+ s->gzindex = 0;
+ s->status = NAME_STATE;
+ }
+ }
+ else
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0) {
+ s->gzindex = 0;
+ s->status = COMMENT_STATE;
+ }
+ }
+ else
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0)
+ s->status = HCRC_STATE;
+ }
+ else
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size)
+ flush_pending(strm);
+ if (s->pending + 2 <= s->pending_buf_size) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+ }
+ }
+ else
+ s->status = BUSY_STATE;
+ }
+#endif
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE &&
+ status != EXTRA_STATE &&
+ status != NAME_STATE &&
+ status != COMMENT_STATE &&
+ status != HCRC_STATE &&
+ status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ zmemcpy(dest, source, sizeof(z_stream));
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ zmemcpy(ds, ss, sizeof(deflate_state));
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, strm->next_in, len);
+ }
+#endif
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ /* %%% avoid this when Z_RLE */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+#ifdef FASTEST
+ if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
+ (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#else
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#endif
+ /* longest_match() or longest_match_fast() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+ /* longest_match() or longest_match_fast() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
+
+#if 0
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt run; /* length of run */
+ uInt max; /* maximum length of run */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan; /* scan for end of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest encodable run.
+ */
+ if (s->lookahead < MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ run = 0;
+ if (s->strstart > 0) { /* if there is a previous byte, that is */
+ max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ scan = s->window + s->strstart - 1;
+ prev = *scan++;
+ do {
+ if (*scan++ != prev)
+ break;
+ } while (++run < max);
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (run >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, run);
+ _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+ s->lookahead -= run;
+ s->strstart += run;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif
diff --git a/sys/src/cmd/python/Modules/zlib/deflate.h b/sys/src/cmd/python/Modules/zlib/deflate.h
new file mode 100644
index 000000000..05a5ab3a2
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/deflate.h
@@ -0,0 +1,331 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2004 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define EXTRA_STATE 69
+#define NAME_STATE 73
+#define COMMENT_STATE 91
+#define HCRC_STATE 103
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ uInt pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ uInt gzindex; /* where in extra, name, or comment */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/sys/src/cmd/python/Modules/zlib/example.c b/sys/src/cmd/python/Modules/zlib/example.c
new file mode 100644
index 000000000..6c8a0ee76
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/example.c
@@ -0,0 +1,565 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+ const char *fname; /* compressed file name */
+ Byte *uncompr;
+ uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+ int err;
+ int len = (int)strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char*)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ if (gzungetc(' ', file) != ' ') {
+ fprintf(stderr, "gzungetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, (int)uncomprLen);
+ if (strlen((char*)uncompr) != 7) { /* " hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello + 6)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+ }
+
+ gzclose(file);
+#endif
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uInt len = (uInt)strlen(hello)+1;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+ ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ uncompr, uncomprLen);
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ free(compr);
+ free(uncompr);
+
+ return 0;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/gzio.c b/sys/src/cmd/python/Modules/zlib/gzio.c
new file mode 100644
index 000000000..7e90f4928
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/gzio.c
@@ -0,0 +1,1026 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef Z_BUFSIZE
+# ifdef MAXSEG_64K
+# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+# else
+# define Z_BUFSIZE 16384
+# endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+# define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#ifdef __MVS__
+# pragma map (fdopen , "\174\174FDOPEN")
+ FILE *fdopen(int, const char *);
+#endif
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+ z_stream stream;
+ int z_err; /* error code for last stream operation */
+ int z_eof; /* set if end of input file */
+ FILE *file; /* .gz file */
+ Byte *inbuf; /* input buffer */
+ Byte *outbuf; /* output buffer */
+ uLong crc; /* crc32 of uncompressed data */
+ char *msg; /* error message */
+ char *path; /* path name for debugging only */
+ int transparent; /* 1 if input file is not a .gz file */
+ char mode; /* 'w' or 'r' */
+ z_off_t start; /* start of compressed data in file (header skipped) */
+ z_off_t in; /* bytes into deflate or inflate */
+ z_off_t out; /* bytes out of deflate or inflate */
+ int back; /* one character push-back */
+ int last; /* true if push-back is last character */
+} gz_stream;
+
+
+local gzFile gz_open OF((const char *path, const char *mode, int fd));
+local int do_flush OF((gzFile file, int flush));
+local int get_byte OF((gz_stream *s));
+local void check_header OF((gz_stream *s));
+local int destroy OF((gz_stream *s));
+local void putLong OF((FILE *file, uLong x));
+local uLong getLong OF((gz_stream *s));
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+ or path name (if fd == -1).
+ gz_open returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+ const char *path;
+ const char *mode;
+ int fd;
+{
+ int err;
+ int level = Z_DEFAULT_COMPRESSION; /* compression level */
+ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+ char *p = (char*)mode;
+ gz_stream *s;
+ char fmode[80]; /* copy of mode, without the compression level */
+ char *m = fmode;
+
+ if (!path || !mode) return Z_NULL;
+
+ s = (gz_stream *)ALLOC(sizeof(gz_stream));
+ if (!s) return Z_NULL;
+
+ s->stream.zalloc = (alloc_func)0;
+ s->stream.zfree = (free_func)0;
+ s->stream.opaque = (voidpf)0;
+ s->stream.next_in = s->inbuf = Z_NULL;
+ s->stream.next_out = s->outbuf = Z_NULL;
+ s->stream.avail_in = s->stream.avail_out = 0;
+ s->file = NULL;
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->in = 0;
+ s->out = 0;
+ s->back = EOF;
+ s->crc = crc32(0L, Z_NULL, 0);
+ s->msg = NULL;
+ s->transparent = 0;
+
+ s->path = (char*)ALLOC(strlen(path)+1);
+ if (s->path == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ strcpy(s->path, path); /* do this early for debugging */
+
+ s->mode = '\0';
+ do {
+ if (*p == 'r') s->mode = 'r';
+ if (*p == 'w' || *p == 'a') s->mode = 'w';
+ if (*p >= '0' && *p <= '9') {
+ level = *p - '0';
+ } else if (*p == 'f') {
+ strategy = Z_FILTERED;
+ } else if (*p == 'h') {
+ strategy = Z_HUFFMAN_ONLY;
+ } else if (*p == 'R') {
+ strategy = Z_RLE;
+ } else {
+ *m++ = *p; /* copy the mode */
+ }
+ } while (*p++ && m != fmode + sizeof(fmode));
+ if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateInit2(&(s->stream), level,
+ Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+ /* windowBits is passed < 0 to suppress zlib header */
+
+ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+ if (err != Z_OK || s->outbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ } else {
+ s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+ err = inflateInit2(&(s->stream), -MAX_WBITS);
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+ * present after the compressed stream.
+ */
+ if (err != Z_OK || s->inbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+
+ errno = 0;
+ s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+ if (s->file == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ if (s->mode == 'w') {
+ /* Write a very simple .gz header:
+ */
+ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+ Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+ s->start = 10L;
+ /* We use 10L instead of ftell(s->file) to because ftell causes an
+ * fflush on some systems. This version of the library doesn't use
+ * start anyway in write mode, so this initialization is not
+ * necessary.
+ */
+ } else {
+ check_header(s); /* skip the .gz header */
+ s->start = ftell(s->file) - s->stream.avail_in;
+ }
+
+ return (gzFile)s;
+}
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+ Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+ to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ char name[46]; /* allow for up to 128-bit integers */
+
+ if (fd < 0) return (gzFile)Z_NULL;
+ sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+ return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ /* Make room to allow flushing */
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+
+ return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+ gz_stream *s;
+{
+ if (s->z_eof) return EOF;
+ if (s->stream.avail_in == 0) {
+ errno = 0;
+ s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) s->z_err = Z_ERRNO;
+ return EOF;
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->stream.avail_in--;
+ return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+ Check the gzip header of a gz_stream opened for reading. Set the stream
+ mode to transparent if the gzip magic header is not present; set s->err
+ to Z_DATA_ERROR if the magic header is present but the rest of the header
+ is incorrect.
+ IN assertion: the stream s has already been created sucessfully;
+ s->stream.avail_in is zero for the first time, but may be non-zero
+ for concatenated .gz files.
+*/
+local void check_header(s)
+ gz_stream *s;
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Assure two bytes in the buffer so we can peek ahead -- handle case
+ where first byte of header is at the end of the buffer after the last
+ gzip segment */
+ len = s->stream.avail_in;
+ if (len < 2) {
+ if (len) s->inbuf[0] = s->stream.next_in[0];
+ errno = 0;
+ len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+ if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
+ s->stream.avail_in += len;
+ s->stream.next_in = s->inbuf;
+ if (s->stream.avail_in < 2) {
+ s->transparent = s->stream.avail_in;
+ return;
+ }
+ }
+
+ /* Peek ahead to check the gzip magic header */
+ if (s->stream.next_in[0] != gz_magic[0] ||
+ s->stream.next_in[1] != gz_magic[1]) {
+ s->transparent = 1;
+ return;
+ }
+ s->stream.avail_in -= 2;
+ s->stream.next_in += 2;
+
+ /* Check the rest of the gzip header */
+ method = get_byte(s);
+ flags = get_byte(s);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ s->z_err = Z_DATA_ERROR;
+ return;
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(s);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(s);
+ len += ((uInt)get_byte(s))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(s) != EOF) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) (void)get_byte(s);
+ }
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+ Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+ gz_stream *s;
+{
+ int err = Z_OK;
+
+ if (!s) return Z_STREAM_ERROR;
+
+ TRYFREE(s->msg);
+
+ if (s->stream.state != NULL) {
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateEnd(&(s->stream));
+#endif
+ } else if (s->mode == 'r') {
+ err = inflateEnd(&(s->stream));
+ }
+ }
+ if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+ if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+ err = Z_ERRNO;
+ }
+ if (s->z_err < 0) err = s->z_err;
+
+ TRYFREE(s->inbuf);
+ TRYFREE(s->outbuf);
+ TRYFREE(s->path);
+ TRYFREE(s);
+ return err;
+}
+
+/* ===========================================================================
+ Reads the given number of uncompressed bytes from the compressed file.
+ gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+ Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+ if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+ if (s->z_err == Z_STREAM_END) return 0; /* EOF */
+
+ next_out = (Byte*)buf;
+ s->stream.next_out = (Bytef*)buf;
+ s->stream.avail_out = len;
+
+ if (s->stream.avail_out && s->back != EOF) {
+ *next_out++ = s->back;
+ s->stream.next_out++;
+ s->stream.avail_out--;
+ s->back = EOF;
+ s->out++;
+ start++;
+ if (s->last) {
+ s->z_err = Z_STREAM_END;
+ return 1;
+ }
+ }
+
+ while (s->stream.avail_out != 0) {
+
+ if (s->transparent) {
+ /* Copy first the lookahead bytes: */
+ uInt n = s->stream.avail_in;
+ if (n > s->stream.avail_out) n = s->stream.avail_out;
+ if (n > 0) {
+ zmemcpy(s->stream.next_out, s->stream.next_in, n);
+ next_out += n;
+ s->stream.next_out = next_out;
+ s->stream.next_in += n;
+ s->stream.avail_out -= n;
+ s->stream.avail_in -= n;
+ }
+ if (s->stream.avail_out > 0) {
+ s->stream.avail_out -=
+ (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
+ }
+ len -= s->stream.avail_out;
+ s->in += len;
+ s->out += len;
+ if (len == 0) s->z_eof = 1;
+ return (int)len;
+ }
+ if (s->stream.avail_in == 0 && !s->z_eof) {
+
+ errno = 0;
+ s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->in += s->stream.avail_in;
+ s->out += s->stream.avail_out;
+ s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+ s->in -= s->stream.avail_in;
+ s->out -= s->stream.avail_out;
+
+ if (s->z_err == Z_STREAM_END) {
+ /* Check CRC and original size */
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+ start = s->stream.next_out;
+
+ if (getLong(s) != s->crc) {
+ s->z_err = Z_DATA_ERROR;
+ } else {
+ (void)getLong(s);
+ /* The uncompressed length returned by above getlong() may be
+ * different from s->out in case of concatenated .gz files.
+ * Check for such files:
+ */
+ check_header(s);
+ if (s->z_err == Z_OK) {
+ inflateReset(&(s->stream));
+ s->crc = crc32(0L, Z_NULL, 0);
+ }
+ }
+ }
+ if (s->z_err != Z_OK || s->z_eof) break;
+ }
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+ if (len == s->stream.avail_out &&
+ (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
+ return -1;
+ return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ unsigned char c;
+
+ return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+ Push one byte back onto the stream.
+*/
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
+ s->back = c;
+ s->out--;
+ s->last = (s->z_err == Z_STREAM_END);
+ if (s->last) s->z_err = Z_OK;
+ s->z_eof = 0;
+ return c;
+}
+
+
+/* ===========================================================================
+ Reads bytes from the compressed file until len-1 characters are
+ read, or a newline character is read and transferred to buf, or an
+ end-of-file condition is encountered. The string is then terminated
+ with a null character.
+ gzgets returns buf, or Z_NULL in case of error.
+
+ The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ char *b = buf;
+ if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+ while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+ *buf = '\0';
+ return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_GZCOMPRESS
+/* ===========================================================================
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.next_in = (Bytef*)buf;
+ s->stream.avail_in = len;
+
+ while (s->stream.avail_in != 0) {
+
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ s->in += s->stream.avail_in;
+ s->out += s->stream.avail_out;
+ s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+ s->in -= s->stream.avail_in;
+ s->out -= s->stream.avail_out;
+ if (s->z_err != Z_OK) break;
+ }
+ s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+ return (int)(len - s->stream.avail_in);
+}
+
+
+/* ===========================================================================
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ va_list va;
+ int len;
+
+ buf[sizeof(buf) - 1] = 0;
+ va_start(va, format);
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(buf, format, va);
+ va_end(va);
+ for (len = 0; len < sizeof(buf); len++)
+ if (buf[len] == 0) break;
+# else
+ len = vsprintf(buf, format, va);
+ va_end(va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+ len = strlen(buf);
+# else
+ len = vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+# endif
+#endif
+ if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+ return 0;
+ return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ int len;
+
+ buf[sizeof(buf) - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < sizeof(buf); len++)
+ if (buf[len] == 0) break;
+# else
+ len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(buf);
+# else
+ len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+ if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+ return 0;
+ return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+ return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+ gzFile file;
+ const char *s;
+{
+ return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+ gzFile file;
+ int flush;
+{
+ uInt len;
+ int done = 0;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.avail_in = 0; /* should be zero already anyway */
+
+ for (;;) {
+ len = Z_BUFSIZE - s->stream.avail_out;
+
+ if (len != 0) {
+ if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+ s->z_err = Z_ERRNO;
+ return Z_ERRNO;
+ }
+ s->stream.next_out = s->outbuf;
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ if (done) break;
+ s->out += s->stream.avail_out;
+ s->z_err = deflate(&(s->stream), flush);
+ s->out -= s->stream.avail_out;
+
+ /* Ignore the second of two consecutive flushes: */
+ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+ /* deflate has finished flushing only when it hasn't used up
+ * all the available space in the output buffer:
+ */
+ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+ if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+ }
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_stream *s = (gz_stream*)file;
+ int err = do_flush (file, flush);
+
+ if (err) return err;
+ fflush(s->file);
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_GZCOMPRESS */
+
+/* ===========================================================================
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error.
+ SEEK_END is not implemented, returns error.
+ In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || whence == SEEK_END ||
+ s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+ return -1L;
+ }
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ return -1L;
+#else
+ if (whence == SEEK_SET) {
+ offset -= s->in;
+ }
+ if (offset < 0) return -1L;
+
+ /* At this point, offset is the number of zero bytes to write. */
+ if (s->inbuf == Z_NULL) {
+ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+ if (s->inbuf == Z_NULL) return -1L;
+ zmemzero(s->inbuf, Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ uInt size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+ size = gzwrite(file, s->inbuf, size);
+ if (size == 0) return -1L;
+
+ offset -= size;
+ }
+ return s->in;
+#endif
+ }
+ /* Rest of function is for reading only */
+
+ /* compute absolute position */
+ if (whence == SEEK_CUR) {
+ offset += s->out;
+ }
+ if (offset < 0) return -1L;
+
+ if (s->transparent) {
+ /* map to fseek */
+ s->back = EOF;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+ s->in = s->out = offset;
+ return offset;
+ }
+
+ /* For a negative seek, rewind and use positive seek */
+ if (offset >= s->out) {
+ offset -= s->out;
+ } else if (gzrewind(file) < 0) {
+ return -1L;
+ }
+ /* offset is now the number of bytes to skip. */
+
+ if (offset != 0 && s->outbuf == Z_NULL) {
+ s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+ if (s->outbuf == Z_NULL) return -1L;
+ }
+ if (offset && s->back != EOF) {
+ s->back = EOF;
+ s->out++;
+ offset--;
+ if (s->last) s->z_err = Z_STREAM_END;
+ }
+ while (offset > 0) {
+ int size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (int)offset;
+
+ size = gzread(file, s->outbuf, (uInt)size);
+ if (size <= 0) return -1L;
+ offset -= size;
+ }
+ return s->out;
+}
+
+/* ===========================================================================
+ Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return -1;
+
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->back = EOF;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ s->crc = crc32(0L, Z_NULL, 0);
+ if (!s->transparent) (void)inflateReset(&s->stream);
+ s->in = 0;
+ s->out = 0;
+ return fseek(s->file, s->start, SEEK_SET);
+}
+
+/* ===========================================================================
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+ gzFile file;
+{
+ return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ /* With concatenated compressed files that can have embedded
+ * crc trailers, z_eof is no longer the only/best indicator of EOF
+ * on a gz_stream. Handle end-of-stream error explicitly here.
+ */
+ if (s == NULL || s->mode != 'r') return 0;
+ if (s->z_eof) return 1;
+ return s->z_err == Z_STREAM_END;
+}
+
+/* ===========================================================================
+ Returns 1 if reading and doing so transparently, otherwise zero.
+*/
+int ZEXPORT gzdirect (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return 0;
+ return s->transparent;
+}
+
+/* ===========================================================================
+ Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+ FILE *file;
+ uLong x;
+{
+ int n;
+ for (n = 0; n < 4; n++) {
+ fputc((int)(x & 0xff), file);
+ x >>= 8;
+ }
+}
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets z_err in case
+ of error.
+*/
+local uLong getLong (s)
+ gz_stream *s;
+{
+ uLong x = (uLong)get_byte(s);
+ int c;
+
+ x += ((uLong)get_byte(s))<<8;
+ x += ((uLong)get_byte(s))<<16;
+ c = get_byte(s);
+ if (c == EOF) s->z_err = Z_DATA_ERROR;
+ x += ((uLong)c)<<24;
+ return x;
+}
+
+/* ===========================================================================
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return Z_STREAM_ERROR;
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ return Z_STREAM_ERROR;
+#else
+ if (do_flush (file, Z_FINISH) != Z_OK)
+ return destroy((gz_stream*)file);
+
+ putLong (s->file, s->crc);
+ putLong (s->file, (uLong)(s->in & 0xffffffff));
+#endif
+ }
+ return destroy((gz_stream*)file);
+}
+
+#ifdef STDC
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
+/* ===========================================================================
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+const char * ZEXPORT gzerror (file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ char *m;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) {
+ *errnum = Z_STREAM_ERROR;
+ return (const char*)ERR_MSG(Z_STREAM_ERROR);
+ }
+ *errnum = s->z_err;
+ if (*errnum == Z_OK) return (const char*)"";
+
+ m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+ if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+ TRYFREE(s->msg);
+ s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+ if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
+ strcpy(s->msg, s->path);
+ strcat(s->msg, ": ");
+ strcat(s->msg, m);
+ return (const char*)s->msg;
+}
+
+/* ===========================================================================
+ Clear the error and end-of-file flags, and do the same for the real file.
+*/
+void ZEXPORT gzclearerr (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return;
+ if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
+ s->z_eof = 0;
+ clearerr(s->file);
+}
diff --git a/sys/src/cmd/python/Modules/zlib/infback.c b/sys/src/cmd/python/Modules/zlib/infback.c
new file mode 100644
index 000000000..455dbc9ee
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/infback.c
@@ -0,0 +1,623 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->dmax = 32768U;
+ state->wbits = windowBits;
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->write = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+
+ /* process literal */
+ if (this.op == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/inffast.c b/sys/src/cmd/python/Modules/zlib/inffast.c
new file mode 100644
index 000000000..bbee92ed1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inffast.c
@@ -0,0 +1,318 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *in; /* local strm->next_in */
+ unsigned char FAR *last; /* while in < last, enough input available */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code this; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ write = state->write;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ PUP(out) = (unsigned char)(this.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ from = window - OFF;
+ if (write == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (write < op) { /* wrap around window */
+ from += wsize + write - op;
+ op -= write;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (write < len) { /* some from start of window */
+ op = write;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += write - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ this = dcode[this.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ this = lcode[this.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and write == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/sys/src/cmd/python/Modules/zlib/inffast.h b/sys/src/cmd/python/Modules/zlib/inffast.h
new file mode 100644
index 000000000..1e88d2d97
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/sys/src/cmd/python/Modules/zlib/inffixed.h b/sys/src/cmd/python/Modules/zlib/inffixed.h
new file mode 100644
index 000000000..75ed4b597
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications. It
+ is part of the implementation of the compression library and
+ is subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/sys/src/cmd/python/Modules/zlib/inflate.c b/sys/src/cmd/python/Modules/zlib/inflate.c
new file mode 100644
index 000000000..792fdee8e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inflate.c
@@ -0,0 +1,1368 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ strm->adler = 1; /* to support ill-conceived Java test suite */
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->wsize = 0;
+ state->whave = 0;
+ state->write = 0;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ if (windowBits < 0) {
+ state->wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48) windowBits &= 15;
+#endif
+ }
+ if (windowBits < 8 || windowBits > 15) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ return Z_STREAM_ERROR;
+ }
+ state->wbits = (unsigned)windowBits;
+ state->window = Z_NULL;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+ state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+ struct inflate_state FAR *state;
+ unsigned copy, dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->write = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ copy = out - strm->avail_out;
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ state->write = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->write;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, strm->next_out - copy, copy);
+ state->write = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->write += dist;
+ if (state->write == state->wsize) state->write = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = REVERSE(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ break;
+ }
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+ if ((int)(this.op) == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ state->mode = LIT;
+ break;
+ }
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ if (state->offset > state->whave + out - left) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->write) {
+ copy -= state->write;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->write - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ REVERSE(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+ if (updatewindow(strm, out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long id;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary id */
+ if (state->mode == DICT) {
+ id = adler32(0L, Z_NULL, 0);
+ id = adler32(id, dictionary, dictLength);
+ if (id != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window */
+ if (updatewindow(strm, strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ if (dictLength > state->wsize) {
+ zmemcpy(state->window, dictionary + dictLength - state->wsize,
+ state->wsize);
+ state->whave = state->wsize;
+ }
+ else {
+ zmemcpy(state->window + state->wsize - dictLength, dictionary,
+ dictLength);
+ state->whave = dictLength;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy(dest, source, sizeof(z_stream));
+ zmemcpy(copy, state, sizeof(struct inflate_state));
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/inflate.h b/sys/src/cmd/python/Modules/zlib/inflate.h
new file mode 100644
index 000000000..07bd3e78a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inflate.h
@@ -0,0 +1,115 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN, /* i: waiting for length/lit code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+ NAME -> COMMENT -> HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or CHECK
+ STORED -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+};
diff --git a/sys/src/cmd/python/Modules/zlib/inftrees.c b/sys/src/cmd/python/Modules/zlib/inftrees.c
new file mode 100644
index 000000000..8a9c13ff0
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inftrees.c
@@ -0,0 +1,329 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)1;
+ this.val = (unsigned short)0;
+ *(*table)++ = this; /* make a table to force an error */
+ *(*table)++ = this;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked when a LENS table is being made
+ against the space in *table, ENOUGH, minus the maximum space needed by
+ the worst case distance code, MAXD. This should never happen, but the
+ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+ This assumes that when type == LENS, bits == 9.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /*
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & mask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/inftrees.h b/sys/src/cmd/python/Modules/zlib/inftrees.h
new file mode 100644
index 000000000..b1104c87e
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1444 code structures (852 for length/literals
+ and 592 for distances, the latter actually the result of an
+ exhaustive search). The true maximum is not known, but the value
+ below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/sys/src/cmd/python/Modules/zlib/make_vms.com b/sys/src/cmd/python/Modules/zlib/make_vms.com
new file mode 100644
index 000000000..c2a1fb54b
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/make_vms.com
@@ -0,0 +1,461 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$! <zinser@zinser.no-ip.info or zinser@sysdev.deutsche-boerse.com>
+$!
+$ on error then goto err_exit
+$!
+$!
+$! Just some general constants...
+$!
+$ true = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ SAY = "WRITE SYS$OUTPUT"
+$!
+$! Setup variables holding "config" information
+$!
+$ Make = ""
+$ name = "Zlib"
+$ version = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file = "zlib.h"
+$ ccopt = ""
+$ lopts = ""
+$ linkonly = false
+$ optfile = name + ".opt"
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ axp = f$getsyi("HW_MODEL").ge.1024
+$ s_case = false
+$! Check for MMK/MMS
+$!
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$!
+$!
+$ gosub find_version
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ if its_decc
+$ then
+$ ccopt = "/prefix=all" + ccopt
+$ if f$trnlnm("SYS") .eqs. ""
+$ then
+$ if axp
+$ then
+$ define sys sys$library:
+$ else
+$ ccopt = "/decc" + ccopt
+$ define sys decc$library_include:
+$ endif
+$ endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$ then
+$ dele example.obj;*,minigzip.obj;*
+$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+ adler32.c zlib.h zconf.h
+$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+ compress.c zlib.h zconf.h
+$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+ crc32.c zlib.h zconf.h
+$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+ deflate.c deflate.h zutil.h zlib.h zconf.h
+$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" -
+ gzio.c zutil.h zlib.h zconf.h
+$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+ infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+ inffast.c zutil.h zlib.h zconf.h inffast.h
+$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+ inflate.c zutil.h zlib.h zconf.h infblock.h
+$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+ inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+ trees.c deflate.h zutil.h zlib.h zconf.h
+$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+ uncompr.c zlib.h zconf.h
+$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+ zutil.c zutil.h zlib.h zconf.h
+$ write sys$output "Building Zlib ..."
+$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$ write sys$output "Building example..."
+$ CALL MAKE example.OBJ "CC ''CCOPT' example" -
+ example.c zlib.h zconf.h
+$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$ if f$search("x11vms:xvmsutils.olb") .nes. ""
+$ then
+$ write sys$output "Building minigzip..."
+$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
+ minigzip.c zlib.h zconf.h
+$ call make minigzip.exe -
+ "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" -
+ minigzip.obj libz.olb
+$ endif
+$ else
+$ gosub crea_mms
+$ SAY "Make ''name' ''version' with ''Make' "
+$ 'make'
+$ endif
+$!
+$! Alpha gets a shareable image
+$!
+$ If axp
+$ Then
+$ gosub crea_olist
+$ write sys$output "Creating libzshr.exe"
+$ call anal_obj_axp modules.opt _link.opt
+$ if s_case
+$ then
+$ open/append optf modules.opt
+$ write optf "case_sensitive=YES"
+$ close optf
+$ endif
+$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt
+$ endif
+$ write sys$output "Zlib build completed"
+$ exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8 What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$ Argument = P'arg
+$ If Argument .Eqs. "" Then Goto Exit
+$ El=0
+$Loop2:
+$ File = F$Element(El," ",Argument)
+$ If File .Eqs. " " Then Goto Endl
+$ AFile = ""
+$Loop3:
+$ OFile = AFile
+$ AFile = F$Search(File)
+$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$ Goto Loop3
+$NextEL:
+$ El = El + 1
+$ Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$ cparm = f$edit(p'i',"upcase")
+$ if cparm .eqs. "DEBUG"
+$ then
+$ ccopt = ccopt + "/noopt/deb"
+$ lopts = lopts + "/deb"
+$ endif
+$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ ccopt = ccopt + f$extract(start,len,cparm)
+$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+ then s_case = true
+$ endif
+$ if cparm .eqs. "LINK" then linkonly = true
+$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ lopts = lopts + f$extract(start,len,cparm)
+$ endif
+$ if f$locate("CC=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ cc_com = f$extract(start,len,cparm)
+ if (cc_com .nes. "DECC") .and. -
+ (cc_com .nes. "VAXC") .and. -
+ (cc_com .nes. "GNUC")
+$ then
+$ write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$ write sys$output "Use DECC, VAXC, or GNUC instead"
+$ else
+$ if cc_com .eqs. "DECC" then its_decc = true
+$ if cc_com .eqs. "VAXC" then its_vaxc = true
+$ if cc_com .eqs. "GNUC" then its_gnuc = true
+$ endif
+$ endif
+$ if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ mmks = f$extract(start,len,cparm)
+$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$ then
+$ make = mmks
+$ else
+$ write sys$output "Unsupported make choice ''mmks' ignored"
+$ write sys$output "Use MMK or MMS instead"
+$ endif
+$ endif
+$ i = i + 1
+$ goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$ if its_decc then write sys$output "CC compiler check ... Compaq C"
+$ if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$ if its_gnuc then write sys$output "CC compiler check ... GNU C"
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+# <zinser@zinser.no-ip.info or zinser@sysdev.deutsche-boerse.com>
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj, infback.obj\
+ deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+ inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ copy sys$input: out
+$ deck
+
+all : example.exe minigzip.exe libz.olb
+ @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+ @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+ link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+ link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+ delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj : crc32.c zutil.h zlib.h zconf.h
+deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj : example.c zlib.h zconf.h
+gzio.obj : gzio.c zutil.h zlib.h zconf.h
+inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : minigzip.c zlib.h zconf.h
+trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : uncompr.c zlib.h zconf.h
+zutil.obj : zutil.c zutil.h zlib.h zconf.h
+infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check = "OBJS ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$ write mod f$parse(srcfil,,,"NAME"), ".obj"
+$ i = i + 1
+$ goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$ version = 'f$element(2," ",rec)'
+$ goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Analyze Object files for OpenVMS AXP to extract Procedure and Data
+$! information to build a symbol vector for a shareable image
+$! All the "brains" of this logic was suggested by Hartmut Becker
+$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me
+$! (zinser@decus.de), so if you do have problem reports please do not
+$! bother Hartmut/HP, but get in touch with me
+$!
+$ ANAL_OBJ_AXP: Subroutine
+$ V = 'F$Verify(0)
+$ SAY := "WRITE_ SYS$OUTPUT"
+$
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$ SAY "ANAL_OBJ_AXP-E-NOSUCHFILE: Error, inputfile ''p1' not available"
+$ goto exit_aa
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$ SAY "ANAL_OBJ_AXP: Error, no output file provided"
+$ goto exit_aa
+$ ENDIF
+$
+$ open/read in 'p1
+$ create a.tmp
+$ open/append atmp a.tmp
+$ loop:
+$ read/end=end_loop in line
+$ f= f$search(line)
+$ if f .eqs. ""
+$ then
+$ write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'"
+$ goto loop
+$ endif
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ anal/obj/gsd 'f /out=x.tmp
+$ open/read xtmp x.tmp
+$ XLOOP:
+$ read/end=end_xloop xtmp xline
+$ xline = f$edit(xline,"compress")
+$ write atmp xline
+$ goto xloop
+$ END_XLOOP:
+$ close xtmp
+$ goto loop
+$ end_loop:
+$ close in
+$ close atmp
+$ if f$search("a.tmp") .eqs. "" -
+ then $ exit
+$ ! all global definitions
+$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp
+$ ! all procedures
+$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp
+$ search c.tmp "symbol:"/out=d.tmp
+$ define/user sys$output nl:
+$ edito/edt/command=sys$input d.tmp
+sub/symbol: "/symbol_vector=(/whole
+sub/"/=PROCEDURE)/whole
+exit
+$ ! all data
+$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp
+$ search e.tmp "symbol:"/out=f.tmp
+$ define/user sys$output nl:
+$ edito/edt/command=sys$input f.tmp
+sub/symbol: "/symbol_vector=(/whole
+sub/"/=DATA)/whole
+exit
+$ sort/nodupl d.tmp,f.tmp 'p2'
+$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;*
+$ if f$search("x.tmp") .nes. "" -
+ then $ delete x.tmp;*
+$!
+$ EXIT_AA:
+$ if V then set verify
+$ endsubroutine
+$!------------------------------------------------------------------------------
diff --git a/sys/src/cmd/python/Modules/zlib/minigzip.c b/sys/src/cmd/python/Modules/zlib/minigzip.c
new file mode 100644
index 000000000..4524b96a1
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/minigzip.c
@@ -0,0 +1,322 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef USE_MMAP
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+# define unlink delete
+# define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+# define unlink remove
+# define GZ_SUFFIX "-gz"
+# define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fileno */
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+ extern int unlink OF((const char *));
+#endif
+
+#ifndef GZ_SUFFIX
+# define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN 16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+# define local static
+ /* Needed for systems with limitation on stack size. */
+#else
+# define local
+#endif
+
+char *prog;
+
+void error OF((const char *msg));
+void gz_compress OF((FILE *in, gzFile out));
+#ifdef USE_MMAP
+int gz_compress_mmap OF((FILE *in, gzFile out));
+#endif
+void gz_uncompress OF((gzFile in, FILE *out));
+void file_compress OF((char *file, char *mode));
+void file_uncompress OF((char *file));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+ const char *msg;
+{
+ fprintf(stderr, "%s: %s\n", prog, msg);
+ exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+ FILE *in;
+ gzFile out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+#ifdef USE_MMAP
+ /* Try first compressing with mmap. If mmap fails (minigzip used in a
+ * pipe), use the normal fread loop.
+ */
+ if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+ for (;;) {
+ len = (int)fread(buf, 1, sizeof(buf), in);
+ if (ferror(in)) {
+ perror("fread");
+ exit(1);
+ }
+ if (len == 0) break;
+
+ if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+ }
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+ FILE *in;
+ gzFile out;
+{
+ int len;
+ int err;
+ int ifd = fileno(in);
+ caddr_t buf; /* mmap'ed buffer for the entire input file */
+ off_t buf_len; /* length of the input file */
+ struct stat sb;
+
+ /* Determine the size of the file, needed for mmap: */
+ if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+ buf_len = sb.st_size;
+ if (buf_len <= 0) return Z_ERRNO;
+
+ /* Now do the actual mmap: */
+ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+ if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+ /* Compress the whole file at once: */
+ len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+ if (len != (int)buf_len) error(gzerror(out, &err));
+
+ munmap(buf, buf_len);
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+ return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+ gzFile in;
+ FILE *out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+ for (;;) {
+ len = gzread(in, buf, sizeof(buf));
+ if (len < 0) error (gzerror(in, &err));
+ if (len == 0) break;
+
+ if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+ error("failed fwrite");
+ }
+ }
+ if (fclose(out)) error("failed fclose");
+
+ if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+ char *file;
+ char *mode;
+{
+ local char outfile[MAX_NAME_LEN];
+ FILE *in;
+ gzFile out;
+
+ strcpy(outfile, file);
+ strcat(outfile, GZ_SUFFIX);
+
+ in = fopen(file, "rb");
+ if (in == NULL) {
+ perror(file);
+ exit(1);
+ }
+ out = gzopen(outfile, mode);
+ if (out == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+ exit(1);
+ }
+ gz_compress(in, out);
+
+ unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+ char *file;
+{
+ local char buf[MAX_NAME_LEN];
+ char *infile, *outfile;
+ FILE *out;
+ gzFile in;
+ uInt len = (uInt)strlen(file);
+
+ strcpy(buf, file);
+
+ if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+ infile = file;
+ outfile = buf;
+ outfile[len-3] = '\0';
+ } else {
+ outfile = file;
+ infile = buf;
+ strcat(infile, GZ_SUFFIX);
+ }
+ in = gzopen(infile, "rb");
+ if (in == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+ exit(1);
+ }
+ out = fopen(outfile, "wb");
+ if (out == NULL) {
+ perror(file);
+ exit(1);
+ }
+
+ gz_uncompress(in, out);
+
+ unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ * -d : decompress
+ * -f : compress with Z_FILTERED
+ * -h : compress with Z_HUFFMAN_ONLY
+ * -r : compress with Z_RLE
+ * -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int uncompr = 0;
+ gzFile file;
+ char outmode[20];
+
+ strcpy(outmode, "wb6 ");
+
+ prog = argv[0];
+ argc--, argv++;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "-d") == 0)
+ uncompr = 1;
+ else if (strcmp(*argv, "-f") == 0)
+ outmode[3] = 'f';
+ else if (strcmp(*argv, "-h") == 0)
+ outmode[3] = 'h';
+ else if (strcmp(*argv, "-r") == 0)
+ outmode[3] = 'R';
+ else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+ (*argv)[2] == 0)
+ outmode[2] = (*argv)[1];
+ else
+ break;
+ argc--, argv++;
+ }
+ if (outmode[3] == ' ')
+ outmode[3] = 0;
+ if (argc == 0) {
+ SET_BINARY_MODE(stdin);
+ SET_BINARY_MODE(stdout);
+ if (uncompr) {
+ file = gzdopen(fileno(stdin), "rb");
+ if (file == NULL) error("can't gzdopen stdin");
+ gz_uncompress(file, stdout);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+ gz_compress(stdin, file);
+ }
+ } else {
+ do {
+ if (uncompr) {
+ file_uncompress(*argv);
+ } else {
+ file_compress(*argv, outmode);
+ }
+ } while (argv++, --argc);
+ }
+ return 0;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/trees.c b/sys/src/cmd/python/Modules/zlib/trees.c
new file mode 100644
index 000000000..395e4e168
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/trees.c
@@ -0,0 +1,1219 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2005 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is binary or text */
+ if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+ set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n;
+
+ for (n = 0; n < 9; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ if (n == 9)
+ for (n = 14; n < 32; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/sys/src/cmd/python/Modules/zlib/trees.h b/sys/src/cmd/python/Modules/zlib/trees.h
new file mode 100644
index 000000000..72facf900
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/sys/src/cmd/python/Modules/zlib/uncompr.c b/sys/src/cmd/python/Modules/zlib/uncompr.c
new file mode 100644
index 000000000..b59e3d0de
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/uncompr.c
@@ -0,0 +1,61 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/sys/src/cmd/python/Modules/zlib/zconf.h b/sys/src/cmd/python/Modules/zlib/zconf.h
new file mode 100644
index 000000000..03a9431c8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/zconf.h
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/sys/src/cmd/python/Modules/zlib/zconf.in.h b/sys/src/cmd/python/Modules/zlib/zconf.in.h
new file mode 100644
index 000000000..03a9431c8
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/zconf.in.h
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/sys/src/cmd/python/Modules/zlib/zlib.3 b/sys/src/cmd/python/Modules/zlib/zlib.3
new file mode 100644
index 000000000..90b816287
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/zlib.3
@@ -0,0 +1,159 @@
+.TH ZLIB 3 "18 July 2005"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms will be added later
+and will have the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+(for example if an input file is mmap'ed),
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I example.c
+and
+.IR minigzip.c .
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source,
+and are concerned primarily with bug fixes and portability enhancements.
+.LP
+A Java implementation of
+.I zlib
+is available in the Java Development Kit 1.1:
+.IP
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://www.cpan.org/modules/by-module/Compress/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://www.python.org/doc/lib/module-zlib.html
+.LP
+A
+.I zlib
+binding for
+.IR tcl (1),
+written by Andreas Kupries (a.kupries@westend.com),
+is availlable at:
+.IP
+http://www.westend.com/~kupries/doc/trf/man/man.html
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/unzip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+web site.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at either of these locations:
+.IP
+http://www.zlib.org
+.br
+http://www.gzip.org/zlib/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
+.br
+http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
+.br
+http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
+.LP
+These documents are also available in other formats from:
+.IP
+ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+.LP
+Mark Nelson (markn@ieee.org) wrote an article about
+.I zlib
+for the Jan. 1997 issue of Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://www.gzip.org/zlib/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.3
+Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/sys/src/cmd/python/Modules/zlib/zlib.h b/sys/src/cmd/python/Modules/zlib/zlib.h
new file mode 100644
index 000000000..022817927
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/zlib.h
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.3, July 18th, 2005
+
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumualte before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ the value returned by deflateBound (see below). If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+ Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+ if and when it gets to the next deflate block boundary. When decoding the
+ zlib or gzip format, this will cause inflate() to return immediately after
+ the header and before the first block. When doing a raw inflate, inflate()
+ will go ahead and process the first block, and will return when it gets to
+ the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64
+ if inflate() is currently decoding the last block in the deflate stream,
+ plus 128 if inflate() returned immediately after decoding an end-of-block
+ code or decoding the complete header up to just before the first byte of the
+ deflate stream. The end-of-block will not be indicated until all of the
+ uncompressed data from that block has been written to strm->next_out. The
+ number of unused bits may in general be greater than seven, except when
+ bit 7 of data_type is set, in which case the number of unused bits will be
+ less than eight.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster approach
+ may be used for the single inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. Any information
+ contained in the gzip header is not retained, so applications that need that
+ information should instead use raw inflate, see inflateInit2() below, or
+ inflateBack() and perform their own processing of the gzip header and
+ trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may then
+ call inflateSync() to look for a good compression block if a partial recovery
+ of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero),
+ no header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+ Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+ parameter only affects the compression ratio but not the correctness of the
+ compressed output even if it is not set appropriately. Z_FIXED prevents the
+ use of dynamic Huffman codes, allowing for a simpler decoder for special
+ applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front. In addition, the
+ current implementation of deflate will use at most the window size minus
+ 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit()
+ or deflateInit2(). This would be used to allocate an output buffer
+ for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the
+ bits leftover from a previous deflate stream when appending to it. As such,
+ this function can only be used for raw deflate, and must be used before the
+ first deflate() call after a deflateInit2() or deflateReset(). bits must be
+ less than or equal to 16, and that many of the least significant bits of
+ value will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
+ a crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+ is set to null if there is no error message. inflateInit2 does not perform
+ any decompression apart from reading the zlib header if present: this will
+ be done by inflate(). (So next_in and avail_in may be modified, but next_out
+ and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called
+ immediately after inflateInit2() or inflateReset() and before any call of
+ inflate() to set the dictionary. The application must insure that the
+ dictionary that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK can be used to
+ force inflate() to return immediately after header processing is complete
+ and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When
+ any of extra, name, or comment are not Z_NULL and the respective field is
+ not present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+ be allocated, or Z_VERSION_ERROR if the version of the library does not
+ match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free
+ the allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects
+ only the raw deflate stream to decompress. This is different from the
+ normal behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format
+ error in the deflate stream (in which case strm->msg is set to indicate the
+ nature of the error), or Z_STREAM_ERROR if the stream was not properly
+ initialized. In the case of Z_BUF_ERROR, an input or output error can be
+ distinguished using strm->next_in which will be Z_NULL only if in() returned
+ an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+ out() returning non-zero. (in() will always be called before out(), so
+ strm->next_in is assured to be defined if out() returns non-zero.) Note
+ that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least the value returned
+ by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before
+ a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h", or 'R' for run-length encoding
+ as in "wb1R". (See the description of deflateInit2 for more information
+ about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error). The number of
+ uncompressed bytes written is limited to 4095. The caller should assure that
+ this limit is not exceeded. If it is exceeded, then gzprintf() will return
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read again later.
+ Only one character of push-back is allowed. gzungetc() returns the
+ character pushed, or -1 on failure. gzungetc() will fail if a
+ character has been pushed but not read yet, or if c is -1. The pushed
+ character will be discarded if the stream is repositioned with gzseek()
+ or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns 1 if file is being read directly without decompression, otherwise
+ zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+/*
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is NULL, this function returns the required initial
+ value for the for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/sys/src/cmd/python/Modules/zlib/zutil.c b/sys/src/cmd/python/Modules/zlib/zutil.c
new file mode 100644
index 000000000..d55f5948a
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/zutil.c
@@ -0,0 +1,318 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch (sizeof(uInt)) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch (sizeof(uLong)) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (sizeof(voidpf)) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (sizeof(z_off_t)) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#ifdef STDC
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/sys/src/cmd/python/Modules/zlib/zutil.h b/sys/src/cmd/python/Modules/zlib/zutil.h
new file mode 100644
index 000000000..b7d5eff81
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlib/zutil.h
@@ -0,0 +1,269 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+# ifndef _WIN32_WCE
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+# ifdef _WIN32_WCE
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used. We rename it to
+ * avoid conflict with other libraries that use the same workaround.
+ */
+# define errno z_errno
+# endif
+ extern int errno;
+#else
+# ifndef _WIN32_WCE
+# include <errno.h>
+# endif
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+# ifdef M_I86
+ #include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+ /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+ /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+#endif
+#ifdef VMS
+# define NO_vsnprintf
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
diff --git a/sys/src/cmd/python/Modules/zlibmodule.c b/sys/src/cmd/python/Modules/zlibmodule.c
new file mode 100644
index 000000000..da31e8b28
--- /dev/null
+++ b/sys/src/cmd/python/Modules/zlibmodule.c
@@ -0,0 +1,1027 @@
+/* zlibmodule.c -- gzip-compatible data compression */
+/* See http://www.gzip.org/zlib/ */
+
+/* Windows users: read Python's PCbuild\readme.txt */
+
+
+#include "Python.h"
+#include "zlib.h"
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+
+/* #defs ripped off from _tkinter.c, even though the situation here is much
+ simpler, because we don't have to worry about waiting for Tcl
+ events! And, since zlib itself is threadsafe, we don't need to worry
+ about re-entering zlib functions.
+
+ N.B.
+
+ Since ENTER_ZLIB and LEAVE_ZLIB only need to be called on functions
+ that modify the components of preexisting de/compress objects, it
+ could prove to be a performance gain on multiprocessor machines if
+ there was an de/compress object-specific lock. However, for the
+ moment the ENTER_ZLIB and LEAVE_ZLIB calls are global for ALL
+ de/compress objects.
+ */
+
+static PyThread_type_lock zlib_lock = NULL; /* initialized on module load */
+
+#define ENTER_ZLIB \
+ Py_BEGIN_ALLOW_THREADS \
+ PyThread_acquire_lock(zlib_lock, 1); \
+ Py_END_ALLOW_THREADS
+
+#define LEAVE_ZLIB \
+ PyThread_release_lock(zlib_lock);
+
+#else
+
+#define ENTER_ZLIB
+#define LEAVE_ZLIB
+
+#endif
+
+/* The following parameters are copied from zutil.h, version 0.95 */
+#define DEFLATED 8
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+#define DEF_WBITS MAX_WBITS
+
+/* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */
+#define DEFAULTALLOC (16*1024)
+#define PyInit_zlib initzlib
+
+static PyTypeObject Comptype;
+static PyTypeObject Decomptype;
+
+static PyObject *ZlibError;
+
+typedef struct
+{
+ PyObject_HEAD
+ z_stream zst;
+ PyObject *unused_data;
+ PyObject *unconsumed_tail;
+ int is_initialised;
+} compobject;
+
+static void
+zlib_error(z_stream zst, int err, char *msg)
+{
+ if (zst.msg == Z_NULL)
+ PyErr_Format(ZlibError, "Error %d %s", err, msg);
+ else
+ PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zst.msg);
+}
+
+PyDoc_STRVAR(compressobj__doc__,
+"compressobj([level]) -- Return a compressor object.\n"
+"\n"
+"Optional arg level is the compression level, in 1-9.");
+
+PyDoc_STRVAR(decompressobj__doc__,
+"decompressobj([wbits]) -- Return a decompressor object.\n"
+"\n"
+"Optional arg wbits is the window buffer size.");
+
+static compobject *
+newcompobject(PyTypeObject *type)
+{
+ compobject *self;
+ self = PyObject_New(compobject, type);
+ if (self == NULL)
+ return NULL;
+ self->is_initialised = 0;
+ self->unused_data = PyString_FromString("");
+ if (self->unused_data == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->unconsumed_tail = PyString_FromString("");
+ if (self->unconsumed_tail == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ return self;
+}
+
+PyDoc_STRVAR(compress__doc__,
+"compress(string[, level]) -- Returned compressed string.\n"
+"\n"
+"Optional arg level is the compression level, in 1-9.");
+
+static PyObject *
+PyZlib_compress(PyObject *self, PyObject *args)
+{
+ PyObject *ReturnVal = NULL;
+ Byte *input, *output;
+ int length, level=Z_DEFAULT_COMPRESSION, err;
+ z_stream zst;
+
+ /* require Python string object, optional 'level' arg */
+ if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level))
+ return NULL;
+
+ zst.avail_out = length + length/1000 + 12 + 1;
+
+ output = (Byte*)malloc(zst.avail_out);
+ if (output == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory to compress data");
+ return NULL;
+ }
+
+ /* Past the point of no return. From here on out, we need to make sure
+ we clean up mallocs & INCREFs. */
+
+ zst.zalloc = (alloc_func)NULL;
+ zst.zfree = (free_func)Z_NULL;
+ zst.next_out = (Byte *)output;
+ zst.next_in = (Byte *)input;
+ zst.avail_in = length;
+ err = deflateInit(&zst, level);
+
+ switch(err) {
+ case(Z_OK):
+ break;
+ case(Z_MEM_ERROR):
+ PyErr_SetString(PyExc_MemoryError,
+ "Out of memory while compressing data");
+ goto error;
+ case(Z_STREAM_ERROR):
+ PyErr_SetString(ZlibError,
+ "Bad compression level");
+ goto error;
+ default:
+ deflateEnd(&zst);
+ zlib_error(zst, err, "while compressing data");
+ goto error;
+ }
+
+ Py_BEGIN_ALLOW_THREADS;
+ err = deflate(&zst, Z_FINISH);
+ Py_END_ALLOW_THREADS;
+
+ if (err != Z_STREAM_END) {
+ zlib_error(zst, err, "while compressing data");
+ deflateEnd(&zst);
+ goto error;
+ }
+
+ err=deflateEnd(&zst);
+ if (err == Z_OK)
+ ReturnVal = PyString_FromStringAndSize((char *)output,
+ zst.total_out);
+ else
+ zlib_error(zst, err, "while finishing compression");
+
+ error:
+ free(output);
+
+ return ReturnVal;
+}
+
+PyDoc_STRVAR(decompress__doc__,
+"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n"
+"\n"
+"Optional arg wbits is the window buffer size. Optional arg bufsize is\n"
+"the initial output buffer size.");
+
+static PyObject *
+PyZlib_decompress(PyObject *self, PyObject *args)
+{
+ PyObject *result_str;
+ Byte *input;
+ int length, err;
+ int wsize=DEF_WBITS, r_strlen=DEFAULTALLOC;
+ z_stream zst;
+
+ if (!PyArg_ParseTuple(args, "s#|ii:decompress",
+ &input, &length, &wsize, &r_strlen))
+ return NULL;
+
+ if (r_strlen <= 0)
+ r_strlen = 1;
+
+ zst.avail_in = length;
+ zst.avail_out = r_strlen;
+
+ if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen)))
+ return NULL;
+
+ zst.zalloc = (alloc_func)NULL;
+ zst.zfree = (free_func)Z_NULL;
+ zst.next_out = (Byte *)PyString_AS_STRING(result_str);
+ zst.next_in = (Byte *)input;
+ err = inflateInit2(&zst, wsize);
+
+ switch(err) {
+ case(Z_OK):
+ break;
+ case(Z_MEM_ERROR):
+ PyErr_SetString(PyExc_MemoryError,
+ "Out of memory while decompressing data");
+ goto error;
+ default:
+ inflateEnd(&zst);
+ zlib_error(zst, err, "while preparing to decompress data");
+ goto error;
+ }
+
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ err=inflate(&zst, Z_FINISH);
+ Py_END_ALLOW_THREADS
+
+ switch(err) {
+ case(Z_STREAM_END):
+ break;
+ case(Z_BUF_ERROR):
+ /*
+ * If there is at least 1 byte of room according to zst.avail_out
+ * and we get this error, assume that it means zlib cannot
+ * process the inflate call() due to an error in the data.
+ */
+ if (zst.avail_out > 0) {
+ PyErr_Format(ZlibError, "Error %i while decompressing data",
+ err);
+ inflateEnd(&zst);
+ goto error;
+ }
+ /* fall through */
+ case(Z_OK):
+ /* need more memory */
+ if (_PyString_Resize(&result_str, r_strlen << 1) < 0) {
+ inflateEnd(&zst);
+ goto error;
+ }
+ zst.next_out = (unsigned char *)PyString_AS_STRING(result_str) \
+ + r_strlen;
+ zst.avail_out = r_strlen;
+ r_strlen = r_strlen << 1;
+ break;
+ default:
+ inflateEnd(&zst);
+ zlib_error(zst, err, "while decompressing data");
+ goto error;
+ }
+ } while (err != Z_STREAM_END);
+
+ err = inflateEnd(&zst);
+ if (err != Z_OK) {
+ zlib_error(zst, err, "while finishing data decompression");
+ goto error;
+ }
+
+ _PyString_Resize(&result_str, zst.total_out);
+ return result_str;
+
+ error:
+ Py_XDECREF(result_str);
+ return NULL;
+}
+
+static PyObject *
+PyZlib_compressobj(PyObject *selfptr, PyObject *args)
+{
+ compobject *self;
+ int level=Z_DEFAULT_COMPRESSION, method=DEFLATED;
+ int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err;
+
+ if (!PyArg_ParseTuple(args, "|iiiii:compressobj", &level, &method, &wbits,
+ &memLevel, &strategy))
+ return NULL;
+
+ self = newcompobject(&Comptype);
+ if (self==NULL)
+ return(NULL);
+ self->zst.zalloc = (alloc_func)NULL;
+ self->zst.zfree = (free_func)Z_NULL;
+ self->zst.next_in = NULL;
+ self->zst.avail_in = 0;
+ err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy);
+ switch(err) {
+ case (Z_OK):
+ self->is_initialised = 1;
+ return (PyObject*)self;
+ case (Z_MEM_ERROR):
+ Py_DECREF(self);
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory for compression object");
+ return NULL;
+ case(Z_STREAM_ERROR):
+ Py_DECREF(self);
+ PyErr_SetString(PyExc_ValueError, "Invalid initialization option");
+ return NULL;
+ default:
+ zlib_error(self->zst, err, "while creating compression object");
+ Py_DECREF(self);
+ return NULL;
+ }
+}
+
+static PyObject *
+PyZlib_decompressobj(PyObject *selfptr, PyObject *args)
+{
+ int wbits=DEF_WBITS, err;
+ compobject *self;
+ if (!PyArg_ParseTuple(args, "|i:decompressobj", &wbits))
+ return NULL;
+
+ self = newcompobject(&Decomptype);
+ if (self == NULL)
+ return(NULL);
+ self->zst.zalloc = (alloc_func)NULL;
+ self->zst.zfree = (free_func)Z_NULL;
+ self->zst.next_in = NULL;
+ self->zst.avail_in = 0;
+ err = inflateInit2(&self->zst, wbits);
+ switch(err) {
+ case (Z_OK):
+ self->is_initialised = 1;
+ return (PyObject*)self;
+ case(Z_STREAM_ERROR):
+ Py_DECREF(self);
+ PyErr_SetString(PyExc_ValueError, "Invalid initialization option");
+ return NULL;
+ case (Z_MEM_ERROR):
+ Py_DECREF(self);
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory for decompression object");
+ return NULL;
+ default:
+ zlib_error(self->zst, err, "while creating decompression object");
+ Py_DECREF(self);
+ return NULL;
+ }
+}
+
+static void
+Comp_dealloc(compobject *self)
+{
+ if (self->is_initialised)
+ deflateEnd(&self->zst);
+ Py_XDECREF(self->unused_data);
+ Py_XDECREF(self->unconsumed_tail);
+ PyObject_Del(self);
+}
+
+static void
+Decomp_dealloc(compobject *self)
+{
+ if (self->is_initialised)
+ inflateEnd(&self->zst);
+ Py_XDECREF(self->unused_data);
+ Py_XDECREF(self->unconsumed_tail);
+ PyObject_Del(self);
+}
+
+PyDoc_STRVAR(comp_compress__doc__,
+"compress(data) -- Return a string containing data compressed.\n"
+"\n"
+"After calling this function, some of the input data may still\n"
+"be stored in internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.");
+
+
+static PyObject *
+PyZlib_objcompress(compobject *self, PyObject *args)
+{
+ int err, inplen, length = DEFAULTALLOC;
+ PyObject *RetVal;
+ Byte *input;
+ unsigned long start_total_out;
+
+ if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen))
+ return NULL;
+
+ if (!(RetVal = PyString_FromStringAndSize(NULL, length)))
+ return NULL;
+
+ ENTER_ZLIB
+
+ start_total_out = self->zst.total_out;
+ self->zst.avail_in = inplen;
+ self->zst.next_in = input;
+ self->zst.avail_out = length;
+ self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);
+
+ Py_BEGIN_ALLOW_THREADS
+ err = deflate(&(self->zst), Z_NO_FLUSH);
+ Py_END_ALLOW_THREADS
+
+ /* while Z_OK and the output buffer is full, there might be more output,
+ so extend the output buffer and try again */
+ while (err == Z_OK && self->zst.avail_out == 0) {
+ if (_PyString_Resize(&RetVal, length << 1) < 0)
+ goto error;
+ self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+ + length;
+ self->zst.avail_out = length;
+ length = length << 1;
+
+ Py_BEGIN_ALLOW_THREADS
+ err = deflate(&(self->zst), Z_NO_FLUSH);
+ Py_END_ALLOW_THREADS
+ }
+ /* We will only get Z_BUF_ERROR if the output buffer was full but
+ there wasn't more output when we tried again, so it is not an error
+ condition.
+ */
+
+ if (err != Z_OK && err != Z_BUF_ERROR) {
+ zlib_error(self->zst, err, "while compressing");
+ Py_DECREF(RetVal);
+ RetVal = NULL;
+ goto error;
+ }
+ _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
+
+ error:
+ LEAVE_ZLIB
+ return RetVal;
+}
+
+PyDoc_STRVAR(decomp_decompress__doc__,
+"decompress(data, max_length) -- Return a string containing the decompressed\n"
+"version of the data.\n"
+"\n"
+"After calling this function, some of the input data may still be stored in\n"
+"internal buffers for later processing.\n"
+"Call the flush() method to clear these buffers.\n"
+"If the max_length parameter is specified then the return value will be\n"
+"no longer than max_length. Unconsumed input data will be stored in\n"
+"the unconsumed_tail attribute.");
+
+static PyObject *
+PyZlib_objdecompress(compobject *self, PyObject *args)
+{
+ int err, inplen, old_length, length = DEFAULTALLOC;
+ int max_length = 0;
+ PyObject *RetVal;
+ Byte *input;
+ unsigned long start_total_out;
+
+ if (!PyArg_ParseTuple(args, "s#|i:decompress", &input,
+ &inplen, &max_length))
+ return NULL;
+ if (max_length < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "max_length must be greater than zero");
+ return NULL;
+ }
+
+ /* limit amount of data allocated to max_length */
+ if (max_length && length > max_length)
+ length = max_length;
+ if (!(RetVal = PyString_FromStringAndSize(NULL, length)))
+ return NULL;
+
+ ENTER_ZLIB
+
+ start_total_out = self->zst.total_out;
+ self->zst.avail_in = inplen;
+ self->zst.next_in = input;
+ self->zst.avail_out = length;
+ self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);
+
+ Py_BEGIN_ALLOW_THREADS
+ err = inflate(&(self->zst), Z_SYNC_FLUSH);
+ Py_END_ALLOW_THREADS
+
+ /* While Z_OK and the output buffer is full, there might be more output.
+ So extend the output buffer and try again.
+ */
+ while (err == Z_OK && self->zst.avail_out == 0) {
+ /* If max_length set, don't continue decompressing if we've already
+ reached the limit.
+ */
+ if (max_length && length >= max_length)
+ break;
+
+ /* otherwise, ... */
+ old_length = length;
+ length = length << 1;
+ if (max_length && length > max_length)
+ length = max_length;
+
+ if (_PyString_Resize(&RetVal, length) < 0)
+ goto error;
+ self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+ + old_length;
+ self->zst.avail_out = length - old_length;
+
+ Py_BEGIN_ALLOW_THREADS
+ err = inflate(&(self->zst), Z_SYNC_FLUSH);
+ Py_END_ALLOW_THREADS
+ }
+
+ /* Not all of the compressed data could be accommodated in the output buffer
+ of specified size. Return the unconsumed tail in an attribute.*/
+ if(max_length) {
+ Py_DECREF(self->unconsumed_tail);
+ self->unconsumed_tail = PyString_FromStringAndSize((char *)self->zst.next_in,
+ self->zst.avail_in);
+ if(!self->unconsumed_tail) {
+ Py_DECREF(RetVal);
+ RetVal = NULL;
+ goto error;
+ }
+ }
+
+ /* The end of the compressed data has been reached, so set the
+ unused_data attribute to a string containing the remainder of the
+ data in the string. Note that this is also a logical place to call
+ inflateEnd, but the old behaviour of only calling it on flush() is
+ preserved.
+ */
+ if (err == Z_STREAM_END) {
+ Py_XDECREF(self->unused_data); /* Free original empty string */
+ self->unused_data = PyString_FromStringAndSize(
+ (char *)self->zst.next_in, self->zst.avail_in);
+ if (self->unused_data == NULL) {
+ Py_DECREF(RetVal);
+ goto error;
+ }
+ /* We will only get Z_BUF_ERROR if the output buffer was full
+ but there wasn't more output when we tried again, so it is
+ not an error condition.
+ */
+ } else if (err != Z_OK && err != Z_BUF_ERROR) {
+ zlib_error(self->zst, err, "while decompressing");
+ Py_DECREF(RetVal);
+ RetVal = NULL;
+ goto error;
+ }
+
+ _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
+
+ error:
+ LEAVE_ZLIB
+
+ return RetVal;
+}
+
+PyDoc_STRVAR(comp_flush__doc__,
+"flush( [mode] ) -- Return a string containing any remaining compressed data.\n"
+"\n"
+"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n"
+"default value used when mode is not specified is Z_FINISH.\n"
+"If mode == Z_FINISH, the compressor object can no longer be used after\n"
+"calling the flush() method. Otherwise, more data can still be compressed.");
+
+static PyObject *
+PyZlib_flush(compobject *self, PyObject *args)
+{
+ int err, length = DEFAULTALLOC;
+ PyObject *RetVal;
+ int flushmode = Z_FINISH;
+ unsigned long start_total_out;
+
+ if (!PyArg_ParseTuple(args, "|i:flush", &flushmode))
+ return NULL;
+
+ /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in
+ doing any work at all; just return an empty string. */
+ if (flushmode == Z_NO_FLUSH) {
+ return PyString_FromStringAndSize(NULL, 0);
+ }
+
+ if (!(RetVal = PyString_FromStringAndSize(NULL, length)))
+ return NULL;
+
+ ENTER_ZLIB
+
+ start_total_out = self->zst.total_out;
+ self->zst.avail_in = 0;
+ self->zst.avail_out = length;
+ self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);
+
+ Py_BEGIN_ALLOW_THREADS
+ err = deflate(&(self->zst), flushmode);
+ Py_END_ALLOW_THREADS
+
+ /* while Z_OK and the output buffer is full, there might be more output,
+ so extend the output buffer and try again */
+ while (err == Z_OK && self->zst.avail_out == 0) {
+ if (_PyString_Resize(&RetVal, length << 1) < 0)
+ goto error;
+ self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+ + length;
+ self->zst.avail_out = length;
+ length = length << 1;
+
+ Py_BEGIN_ALLOW_THREADS
+ err = deflate(&(self->zst), flushmode);
+ Py_END_ALLOW_THREADS
+ }
+
+ /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
+ various data structures. Note we should only get Z_STREAM_END when
+ flushmode is Z_FINISH, but checking both for safety*/
+ if (err == Z_STREAM_END && flushmode == Z_FINISH) {
+ err = deflateEnd(&(self->zst));
+ if (err != Z_OK) {
+ zlib_error(self->zst, err, "from deflateEnd()");
+ Py_DECREF(RetVal);
+ RetVal = NULL;
+ goto error;
+ }
+ else
+ self->is_initialised = 0;
+
+ /* We will only get Z_BUF_ERROR if the output buffer was full
+ but there wasn't more output when we tried again, so it is
+ not an error condition.
+ */
+ } else if (err!=Z_OK && err!=Z_BUF_ERROR) {
+ zlib_error(self->zst, err, "while flushing");
+ Py_DECREF(RetVal);
+ RetVal = NULL;
+ goto error;
+ }
+
+ _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
+
+ error:
+ LEAVE_ZLIB
+
+ return RetVal;
+}
+
+#ifdef HAVE_ZLIB_COPY
+PyDoc_STRVAR(comp_copy__doc__,
+"copy() -- Return a copy of the compression object.");
+
+static PyObject *
+PyZlib_copy(compobject *self)
+{
+ compobject *retval = NULL;
+ int err;
+
+ retval = newcompobject(&Comptype);
+ if (!retval) return NULL;
+
+ /* Copy the zstream state
+ * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe
+ */
+ ENTER_ZLIB
+ err = deflateCopy(&retval->zst, &self->zst);
+ switch(err) {
+ case(Z_OK):
+ break;
+ case(Z_STREAM_ERROR):
+ PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");
+ goto error;
+ case(Z_MEM_ERROR):
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory for compression object");
+ goto error;
+ default:
+ zlib_error(self->zst, err, "while copying compression object");
+ goto error;
+ }
+
+ Py_INCREF(self->unused_data);
+ Py_INCREF(self->unconsumed_tail);
+ Py_XDECREF(retval->unused_data);
+ Py_XDECREF(retval->unconsumed_tail);
+ retval->unused_data = self->unused_data;
+ retval->unconsumed_tail = self->unconsumed_tail;
+
+ /* Mark it as being initialized */
+ retval->is_initialised = 1;
+
+ LEAVE_ZLIB
+ return (PyObject *)retval;
+
+error:
+ LEAVE_ZLIB
+ Py_XDECREF(retval);
+ return NULL;
+}
+
+PyDoc_STRVAR(decomp_copy__doc__,
+"copy() -- Return a copy of the decompression object.");
+
+static PyObject *
+PyZlib_uncopy(compobject *self)
+{
+ compobject *retval = NULL;
+ int err;
+
+ retval = newcompobject(&Decomptype);
+ if (!retval) return NULL;
+
+ /* Copy the zstream state
+ * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe
+ */
+ ENTER_ZLIB
+ err = inflateCopy(&retval->zst, &self->zst);
+ switch(err) {
+ case(Z_OK):
+ break;
+ case(Z_STREAM_ERROR):
+ PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");
+ goto error;
+ case(Z_MEM_ERROR):
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory for decompression object");
+ goto error;
+ default:
+ zlib_error(self->zst, err, "while copying decompression object");
+ goto error;
+ }
+
+ Py_INCREF(self->unused_data);
+ Py_INCREF(self->unconsumed_tail);
+ Py_XDECREF(retval->unused_data);
+ Py_XDECREF(retval->unconsumed_tail);
+ retval->unused_data = self->unused_data;
+ retval->unconsumed_tail = self->unconsumed_tail;
+
+ /* Mark it as being initialized */
+ retval->is_initialised = 1;
+
+ LEAVE_ZLIB
+ return (PyObject *)retval;
+
+error:
+ LEAVE_ZLIB
+ Py_XDECREF(retval);
+ return NULL;
+}
+#endif
+
+PyDoc_STRVAR(decomp_flush__doc__,
+"flush( [length] ) -- Return a string containing any remaining\n"
+"decompressed data. length, if given, is the initial size of the\n"
+"output buffer.\n"
+"\n"
+"The decompressor object can no longer be used after this call.");
+
+static PyObject *
+PyZlib_unflush(compobject *self, PyObject *args)
+{
+ int err, length = DEFAULTALLOC;
+ PyObject * retval = NULL;
+ unsigned long start_total_out;
+
+ if (!PyArg_ParseTuple(args, "|i:flush", &length))
+ return NULL;
+ if (!(retval = PyString_FromStringAndSize(NULL, length)))
+ return NULL;
+
+
+ ENTER_ZLIB
+
+ start_total_out = self->zst.total_out;
+ self->zst.avail_out = length;
+ self->zst.next_out = (Byte *)PyString_AS_STRING(retval);
+
+ Py_BEGIN_ALLOW_THREADS
+ err = inflate(&(self->zst), Z_FINISH);
+ Py_END_ALLOW_THREADS
+
+ /* while Z_OK and the output buffer is full, there might be more output,
+ so extend the output buffer and try again */
+ while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) {
+ if (_PyString_Resize(&retval, length << 1) < 0)
+ goto error;
+ self->zst.next_out = (Byte *)PyString_AS_STRING(retval) + length;
+ self->zst.avail_out = length;
+ length = length << 1;
+
+ Py_BEGIN_ALLOW_THREADS
+ err = inflate(&(self->zst), Z_FINISH);
+ Py_END_ALLOW_THREADS
+ }
+
+ /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
+ various data structures. Note we should only get Z_STREAM_END when
+ flushmode is Z_FINISH */
+ if (err == Z_STREAM_END) {
+ err = inflateEnd(&(self->zst));
+ self->is_initialised = 0;
+ if (err != Z_OK) {
+ zlib_error(self->zst, err, "from inflateEnd()");
+ Py_DECREF(retval);
+ retval = NULL;
+ goto error;
+ }
+ }
+ _PyString_Resize(&retval, self->zst.total_out - start_total_out);
+
+error:
+
+ LEAVE_ZLIB
+
+ return retval;
+}
+
+static PyMethodDef comp_methods[] =
+{
+ {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS,
+ comp_compress__doc__},
+ {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS,
+ comp_flush__doc__},
+#ifdef HAVE_ZLIB_COPY
+ {"copy", (PyCFunction)PyZlib_copy, METH_NOARGS,
+ comp_copy__doc__},
+#endif
+ {NULL, NULL}
+};
+
+static PyMethodDef Decomp_methods[] =
+{
+ {"decompress", (binaryfunc)PyZlib_objdecompress, METH_VARARGS,
+ decomp_decompress__doc__},
+ {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS,
+ decomp_flush__doc__},
+#ifdef HAVE_ZLIB_COPY
+ {"copy", (PyCFunction)PyZlib_uncopy, METH_NOARGS,
+ decomp_copy__doc__},
+#endif
+ {NULL, NULL}
+};
+
+static PyObject *
+Comp_getattr(compobject *self, char *name)
+{
+ /* No ENTER/LEAVE_ZLIB is necessary because this fn doesn't touch
+ internal data. */
+
+ return Py_FindMethod(comp_methods, (PyObject *)self, name);
+}
+
+static PyObject *
+Decomp_getattr(compobject *self, char *name)
+{
+ PyObject * retval;
+
+ ENTER_ZLIB
+
+ if (strcmp(name, "unused_data") == 0) {
+ Py_INCREF(self->unused_data);
+ retval = self->unused_data;
+ } else if (strcmp(name, "unconsumed_tail") == 0) {
+ Py_INCREF(self->unconsumed_tail);
+ retval = self->unconsumed_tail;
+ } else
+ retval = Py_FindMethod(Decomp_methods, (PyObject *)self, name);
+
+ LEAVE_ZLIB
+
+ return retval;
+}
+
+PyDoc_STRVAR(adler32__doc__,
+"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n"
+"\n"
+"An optional starting value can be specified. The returned checksum is\n"
+"an integer.");
+
+static PyObject *
+PyZlib_adler32(PyObject *self, PyObject *args)
+{
+ uLong adler32val = adler32(0L, Z_NULL, 0);
+ Byte *buf;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#|k:adler32", &buf, &len, &adler32val))
+ return NULL;
+ adler32val = adler32(adler32val, buf, len);
+ return PyInt_FromLong(adler32val);
+}
+
+PyDoc_STRVAR(crc32__doc__,
+"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n"
+"\n"
+"An optional starting value can be specified. The returned checksum is\n"
+"an integer.");
+
+static PyObject *
+PyZlib_crc32(PyObject *self, PyObject *args)
+{
+ uLong crc32val = crc32(0L, Z_NULL, 0);
+ Byte *buf;
+ int len;
+ if (!PyArg_ParseTuple(args, "s#|k:crc32", &buf, &len, &crc32val))
+ return NULL;
+ crc32val = crc32(crc32val, buf, len);
+ return PyInt_FromLong(crc32val);
+}
+
+
+static PyMethodDef zlib_methods[] =
+{
+ {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,
+ adler32__doc__},
+ {"compress", (PyCFunction)PyZlib_compress, METH_VARARGS,
+ compress__doc__},
+ {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS,
+ compressobj__doc__},
+ {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,
+ crc32__doc__},
+ {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS,
+ decompress__doc__},
+ {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS,
+ decompressobj__doc__},
+ {NULL, NULL}
+};
+
+static PyTypeObject Comptype = {
+ PyObject_HEAD_INIT(0)
+ 0,
+ "zlib.Compress",
+ sizeof(compobject),
+ 0,
+ (destructor)Comp_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)Comp_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+};
+
+static PyTypeObject Decomptype = {
+ PyObject_HEAD_INIT(0)
+ 0,
+ "zlib.Decompress",
+ sizeof(compobject),
+ 0,
+ (destructor)Decomp_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)Decomp_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+};
+
+PyDoc_STRVAR(zlib_module_documentation,
+"The functions in this module allow compression and decompression using the\n"
+"zlib library, which is based on GNU zip.\n"
+"\n"
+"adler32(string[, start]) -- Compute an Adler-32 checksum.\n"
+"compress(string[, level]) -- Compress string, with compression level in 1-9.\n"
+"compressobj([level]) -- Return a compressor object.\n"
+"crc32(string[, start]) -- Compute a CRC-32 checksum.\n"
+"decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n"
+"decompressobj([wbits]) -- Return a decompressor object.\n"
+"\n"
+"'wbits' is window buffer size.\n"
+"Compressor objects support compress() and flush() methods; decompressor\n"
+"objects support decompress() and flush().");
+
+PyMODINIT_FUNC
+PyInit_zlib(void)
+{
+ PyObject *m, *ver;
+ Comptype.ob_type = &PyType_Type;
+ Decomptype.ob_type = &PyType_Type;
+ m = Py_InitModule4("zlib", zlib_methods,
+ zlib_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
+ if (ZlibError != NULL) {
+ Py_INCREF(ZlibError);
+ PyModule_AddObject(m, "error", ZlibError);
+ }
+ PyModule_AddIntConstant(m, "MAX_WBITS", MAX_WBITS);
+ PyModule_AddIntConstant(m, "DEFLATED", DEFLATED);
+ PyModule_AddIntConstant(m, "DEF_MEM_LEVEL", DEF_MEM_LEVEL);
+ PyModule_AddIntConstant(m, "Z_BEST_SPEED", Z_BEST_SPEED);
+ PyModule_AddIntConstant(m, "Z_BEST_COMPRESSION", Z_BEST_COMPRESSION);
+ PyModule_AddIntConstant(m, "Z_DEFAULT_COMPRESSION", Z_DEFAULT_COMPRESSION);
+ PyModule_AddIntConstant(m, "Z_FILTERED", Z_FILTERED);
+ PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY);
+ PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY);
+
+ PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH);
+ PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH);
+ PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH);
+ PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH);
+
+ ver = PyString_FromString(ZLIB_VERSION);
+ if (ver != NULL)
+ PyModule_AddObject(m, "ZLIB_VERSION", ver);
+
+ PyModule_AddStringConstant(m, "__version__", "1.0");
+
+#ifdef WITH_THREAD
+ zlib_lock = PyThread_allocate_lock();
+#endif /* WITH_THREAD */
+}